Re: [Solved] Re: Windows registry PermissionError

2022-05-13 Thread Mike Dewhirst

On 13/05/2022 4:37 pm, Eryk Sun wrote:

On 5/13/22, Mike Dewhirst  wrote:

On 13/05/2022 4:14 pm, Eryk Sun wrote:

Since self.connect() is always called, you should document that the
initial hkey parameter has to be one of the following predefined key
handles:

  HKEY_LOCAL_MACHINE
  HKEY_USERS

I'm targeting HKEY_CURRENT_USER so I assume HK_USERS includes that.

Using HKEY_CURRENT_USER with RegConnectRegistryW() to access a remote
registry isn't well defined and not documented as supported. If it
works at all, the API probably just opens a subkey of the remote
HKEY_USERS based on the string SID (security identifier string) of the
current user. That may fail as not found since user SIDs are unique to
machines, unless it's on a domain.

Bear in mind that the remote registry service is running on the remote
machine as SYSTEM (S-1-5-18) in the non-interactive services session.
If it literally accessed its "current user", then it would open
"HKEY_USERS\S-1-5-18".
In that case, I'll remove 'computer' as a parameter and lock it in as 
None. I'll document why and if I ever need to access a remote registry 
I'll do some research along the lines you suggest.


My case demands execution of this code via login script for end-user 
configuration after the IT department has done a bulk installation 
rollout. One of key items is ComputerName which is in HKLM and needs to 
be in HKCU for whichever user logs in. The application looks in HKCU for 
a unique Device Reference and ComputerName suffices and is attractive 
because it is also the asset number of the machine.



--
Signed email is an absolute defence against phishing. This email has
been signed with my private key. If you import my public key you can
automatically decrypt my signature and be sure it came from me. Just
ask and I'll send it to you. Your email software can handle signing.



OpenPGP_signature
Description: OpenPGP digital signature
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: [Solved] Re: Windows registry PermissionError

2022-05-13 Thread Eryk Sun
On 5/13/22, Mike Dewhirst  wrote:
> On 13/05/2022 4:14 pm, Eryk Sun wrote:
>> Since self.connect() is always called, you should document that the
>> initial hkey parameter has to be one of the following predefined key
>> handles:
>>
>>  HKEY_LOCAL_MACHINE
>>  HKEY_USERS
>
> I'm targeting HKEY_CURRENT_USER so I assume HK_USERS includes that.

Using HKEY_CURRENT_USER with RegConnectRegistryW() to access a remote
registry isn't well defined and not documented as supported. If it
works at all, the API probably just opens a subkey of the remote
HKEY_USERS based on the string SID (security identifier string) of the
current user. That may fail as not found since user SIDs are unique to
machines, unless it's on a domain.

Bear in mind that the remote registry service is running on the remote
machine as SYSTEM (S-1-5-18) in the non-interactive services session.
If it literally accessed its "current user", then it would open
"HKEY_USERS\S-1-5-18".
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: [Solved] Re: Windows registry PermissionError

2022-05-13 Thread Mike Dewhirst

On 13/05/2022 4:14 pm, Eryk Sun wrote:

Since self.connect() is always called, you should document that the
initial hkey parameter has to be one of the following predefined key
handles:

 HKEY_LOCAL_MACHINE
 HKEY_USERS


I'm targeting HKEY_CURRENT_USER so I assume HK_USERS includes that.

Thanks again Eryk

Cheers

mike


 HKEY_PERFORMANCE_DATA

WinAPI RegConnectRegistryW() only matters when the target computer is
a different machine, in which case an RPC proxy handle is returned.



--
Signed email is an absolute defence against phishing. This email has
been signed with my private key. If you import my public key you can
automatically decrypt my signature and be sure it came from me. Just
ask and I'll send it to you. Your email software can handle signing.



OpenPGP_signature
Description: OpenPGP digital signature
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: [Solved] Re: Windows registry PermissionError

2022-05-13 Thread Eryk Sun
Since self.connect() is always called, you should document that the
initial hkey parameter has to be one of the following predefined key
handles:

HKEY_LOCAL_MACHINE
HKEY_USERS
HKEY_PERFORMANCE_DATA

WinAPI RegConnectRegistryW() only matters when the target computer is
a different machine, in which case an RPC proxy handle is returned.
-- 
https://mail.python.org/mailman/listinfo/python-list


[Solved] Re: Windows registry PermissionError

2022-05-12 Thread Mike Dewhirst

Eryk

Many thanks. It is working perfectly now. See below for the reworked code.

Cheers

Mike

On 13/05/2022 1:42 pm, Eryk Sun wrote:

On 5/12/22, Mike Dewhirst  wrote:

  access=wr.KEY_ALL_ACCESS + wr.KEY_WRITE,


import winreg as wr class Registry: def __init__(self, computer=None, 
hkey=None, sub_key=None): self.computer = computer self.key = hkey 
self.sub_key = sub_key def connect(self): return 
wr.ConnectRegistry(self.computer, self.key) def select(self, 
access=None): with self.connect() as hkey: return wr.OpenKeyEx(key=hkey, 
sub_key=self.sub_key, access=access) def count(self): access = 
wr.KEY_QUERY_VALUE return wr.QueryInfoKey(self.select(access=access)) 
def query(self, vname, access=None): if access is None: access = 
wr.KEY_READ | wr.KEY_WOW64_32KEY return 
wr.QueryValueEx(self.select(access=access), vname) def setvalue(self, 
vname, value, access=None): if access is None: access = wr.KEY_SET_VALUE 
with self.select(access=access) as hkey: return wr.SetValueEx(hkey, 
vname, 0, wr.REG_SZ, value) if __name__ == "__main__": lmregistry = 
Registry( hkey=wr.HKEY_LOCAL_MACHINE, sub_key=r"SOFTWARE\XXX 
Technology\AppName", ) print(f"\n{lmregistry.sub_key}") anz = 
lmregistry.query('Country')[0] print(f"\n{anz}") db = 
lmregistry.query('Database')[0] print(f"\n{db}") devref = 
lmregistry.query('v135')[0] print(f"\n{devref}") orgid = 
lmregistry.query('v136')[0] print(f"\n{orgid}") curegistry = Registry( 
hkey=wr.HKEY_CURRENT_USER, sub_key=r"SOFTWARE\XXX Technology\AppName", ) 
print(f"\n{curegistry.sub_key}") anz = curegistry.query('Country')[0] 
print(f"\n{anz}") db = curegistry.query('Database')[0] print(f"\n{db}") 
devref = curegistry.query('v135')[0] print(f"\n{devref}") orgid = 
curegistry.query('v136')[0] print(f"\n{orgid}") 
curegistry.setvalue('Country', 'nz') curegistry.setvalue('Database', 
'2022.2') curegistry.setvalue('v135', 'Asus10') 
curegistry.setvalue('v136', orgid.replace('ALL', 'Most')) anz = 
curegistry.query('Country')[0] print(f"\n{anz}") db = 
curegistry.query('Database')[0] print(f"\n{db}") devref = 
curegistry.query('v135')[0] print(f"\n{devref}") orgid = 
curegistry.query('v136')[0] print(f"\n{orgid}")


Again, many thanks for putting so much effort into educating me.

Cheers

Mike

The access parameter is a bit mask of access rights that combine via
bitwise OR (|), not via arithmetic addition.

KEY_ALL_ACCESS (0x000F_003F) is a superset of KEY_WRITE (0x0002_0006):

 KEY_WRITE = (
 READ_CONTROL   | # 0x0002_
 KEY_SET_VALUE  | # 0x_0002
 KEY_CREATE_SUB_KEY | # 0x_0004
 )# 0x0002_0006

 KEY_ALL_ACCESS = (
 DELETE | # 0x0001_
 READ_CONTROL   | # 0x0002_
 WRITE_DAC  | # 0x0004_
 WRITE_OWNER| # 0x0008_
 KEY_QUERY_VALUE| # 0x_0001
 KEY_SET_VALUE  | # 0x_0002
 KEY_CREATE_SUB_KEY | # 0x_0004
 KEY_ENUMERATE_SUB_KEYS | # 0x_0008
 KEY_NOTIFY | # 0x_0010
 KEY_CREATE_LINK| # 0x_0020
 )# 0x000F_003F

The result of the arithmetic addition `KEY_ALL_ACCESS + KEY_WRITE` is
0x0011_0045, which is wrong and meaningless. Registry key objects do
not support SYNCHRONIZE (0x0010_) access; DELETE (0x0001_)
access isn't needed; 0x_0040 is not a supported key right;
KEY_CREATE_SUB_KEY (0x_0004) access isn't needed; and
KEY_QUERY_VALUE (0x_0001) isn't sufficient.

You should limit the requested access to the specific access rights
that are required for querying and setting values in the key:

 access=(wr.KEY_QUERY_VALUE | wr.KEY_SET_VALUE)


 def setvalue(self, vname, value):
return wr.SetValueEx(self.select(), vname, 0, 1, value)

You shouldn't hard code the value of the data type constant. Use
wr.REG_SZ instead of 1.

The return value of self.select() is a winreg PyHKEY object that wraps
the OS handle for the key object. You're relying on implicit closing
of this handle based on referencing counting. It's cleaner to use it
in a `with` statement, as you would for a file object returned by
open(). For example:

 with self.select() as hkey:
 wr.SetValueEx(hkey, vname, 0, wr.REG_SZ, value)


  lmregistry = Registry(
  hkey=wr.HKEY_LOCAL_MACHINE,
  sub_key="SOFTWARE\WOW6432Node\XXX Technology\AppName",

You really shouldn't open the "WOW6432Node" key directly. It is an
implementation detail of the WOW64 subsystem that runs 32-bit
applications on a 64-bit system. If you need to operate on the
registry keys of 32-bit applications from a native 64-bit process,
open the normal path using the access right KEY_WOW64_32KEY
(0x_0200). For example:

 hkey = wr.HKEY_LOCAL_MACHINE
 subkey = r"SOFTWARE\XXX Technology\AppName"
 access = (
 wr.KEY_QUERY_VALUE |