Disable registry redirection to Wow6432Node in Python - python

I'm trying to access registry keys under HKEY_LOCAL_MAHINE\SOFTWARE... on a 64 bits system. I have following code but judging by the results it gets redirected to Wow6432Node even though I have _winreg.DisableReflectionKey(_winreg.OpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE")) in my code.
import _winreg
import wmi
c = wmi.WMI(computer="localhost", namespace="root/default").StdRegProv
_winreg.DisableReflectionKey(_winreg.OpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE"))
result, names = c.EnumKey(hDefKey=_winreg.HKEY_LOCAL_MACHINE, sSubKeyName="SOFTWARE")
print names
_winreg.EnableReflectionKey(_winreg.OpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE"))
I have read the following case but it seems that the solution described there doesn't work for either the author or for me:
How can I turn off registry redirection on Python?
Also checked _winreg documentation, but there are no specific examples and I have no idea what I'm doing wrong. Any ideas? Sorry, I didn't have permission to comment in the existing case and had to open a new one.

It looks like "_winreg.KEY_READ | _winreg.KEY_WOW64_64KEY" does the job. To be more precise you need to open the key this way:
_winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, "SOFTWARE", 0, _winreg.KEY_READ | _winreg.KEY_WOW64_64KEY)
I got this working when accessing the localhost registry. However, I still haven't figured out how to connect to remote registry on the domain. Trying to use _winreg.ConnectRegistry, but keep getting access denied error.

Related

Python: change permissions (take ownership and full control) of registry keys to modify them

I would like to loop through all the registry keys and subkeys in a hive, find the value containing a specified string and replace it by a new one (I am adapting this code using winreg)
So far my code works on the keys whose ownership is Administrator and for which Administrator has full control but not on the other keys.
I could set the permissions of all my keys so that Administrator has full control but I would like to avoid that. Instead, I would like to only change the permissions of the keys that match the specified string. After the value is modified the permissions should be set back to what they were.
I have seen this answer from 2012 but I would like to avoid installing a software for that.
Since nobody answered this question I thought I should share my solution for setting permissions on given keys using the pywin32 library:
import win32con as con
import win32api
import ntsecuritycon as ntc
import pywintypes
import win32security
key = win32api.RegOpenKey(con.HKEY_LOCAL_MACHINE, 'Software\\MyKey', 0, con.KEY_ALL_ACCESS)
ksd = win32api.RegGetKeySecurity(key, con.DACL_SECURITY_INFORMATION)
acl = pywintypes.ACL()
acl.AddAccessAllowedAce(ntc.GENERIC_ALL, win32security.ConvertStringSidToSid('S-1-5-18'))
acl.AddAccessAllowedAce(ntc.GENERIC_ALL, win32security.ConvertStringSidToSid('S-1-5-32-544'))
ksd.SetDacl(True, acl, False)
win32api.RegSetKeySecurity(key, con.DACL_SECURITY_INFORMATION, ksd)
This will set the HKLM\SOFTWARE\MyKey key permission to FULL CONTROL for SYSTEM and Administrators but no other group will have read or write access. Note that the ksd variable has the original ACL in it until we run .SetDacl() on it, so if you want to write back the original permissions after the operation, just back that up to another variable like ksd_bac first, and then run win32api.RegSetKeySecurity(key, con.DACL_SECURITY_INFORMATION, ksd_bac) after the operation.

Unable to fetch and display files using snakebite

I'm trying out snakebite. I started the following client:
from snakebite.client import Client
client = Client("my.host.com", 8020, effective_user='datascientist')
First, I tried to list the users directory:
for x in client.ls(['/user/datascientist']):
print x
This worked nicely and printed couple of dictionaries; one for each item in the directory. One of the items is a file foobar.txt which I'd like to see. To that end, I believe I should use Client.cat:
for cat in client.cat(['/user/datascientist/da-foobar.txt',]):
print(cat)
for item in cat:
print(item)
However, this didn't work. I got the following error message:
ConnectionFailureException: Failure to connect to data node at (10.XXX.YYY.ZZZ:50010)
What am I doing wrongly?
BTW: using PyWebHdfsClient from pywebhdfs.webhdfs I managed to see the file by starting a client with the same address but with port 50070. I don't know whether this is relevant or not.
Edit 1: I also tried to use snakebite.client.Client.text and got the same error. I guess this is not surprising.
BTW, the file's content is my file is this\ntest file.
I found a/the solution. It seems like the listing operation can be accomplished on the name-node alone. In contrast, the printing of the text file needs to access the data-nodes! By instantiating the client as follows
client = Client("stage-gap-namenode-2.srv.glispa.com", 8020, effective_user='datascientist',
use_datanode_hostname=True)
the cat operation works as it is not using the internal IP, but the hostname. I summarized a minimal example.

Find desktop folder in a custom location? [duplicate]

I have this small program and it needs to create a small .txt file in their 'My Documents' Folder. Here's the code I have for that:
textfile=open('C:\Users\MYNAME\Documents','w')
lines=['stuff goes here']
textfile.writelines(lines)
textfile.close()
The problem is that if other people use it, how do I change the MYNAME to their account name?
Use os.path.expanduser(path), see http://docs.python.org/library/os.path.html
e.g. expanduser('~/filename')
This works on both Unix and Windows, according to the docs.
Edit: forward slash due to Sven's comment.
This works without any extra libs:
import ctypes.wintypes
CSIDL_PERSONAL = 5 # My Documents
SHGFP_TYPE_CURRENT = 0 # Get current, not default value
buf= ctypes.create_unicode_buffer(ctypes.wintypes.MAX_PATH)
ctypes.windll.shell32.SHGetFolderPathW(None, CSIDL_PERSONAL, None, SHGFP_TYPE_CURRENT, buf)
print(buf.value)
Also works if documents location and/or default save location is changed by user.
On Windows, you can use something similar what is shown in the accepted answer to the question: Python, get windows special folders for currently logged-in user.
For the My Documents folder path, useshellcon.CSIDL_PERSONALin the shell.SHGetFolderPath() function call instead of shellcon.CSIDL_MYPICTURES.
So, assuming you have the PyWin32 extensions1 installed, this might work (see caveat in Update section below):
>>> from win32com.shell import shell, shellcon
>>> shell.SHGetFolderPath(0, shellcon.CSIDL_PERSONAL, None, 0)
u'<path\\to\\folder>'
Update: I just read something that said that CSIDL_PERSONAL won't return the correct folder if the user has changed the default save folder in the Win7 Documents library. This is referring to what you can do in library's Properties dialog:
The checkmark means that the path is set as the default save location.
I currently am unware of a way to call the SHLoadLibraryFromKnownFolder() function through PyWin32 (there currently isn't a shell.SHLoadLibraryFromKnownFolder. However it should be possible to do so using the ctypes module.
1Installers for the latest versions of the Python for Windows Extensions are currently available from: http://sourceforge.net/projects/pywin32

Read registry value with python problems

I feel like I am taking crazy pills. So for security on an api at work I am using, I have to read 2 things from the registry, that I then pass to suds. The problem is with reading the registry values. No matter what I do, I get "Error2 the system cannot find the file specified". I know that the registry file is there, yet it won't let me read it. I have tried the code below on 2 different 2008 r2 servers. On one windows 7 box, I am able to read the values...but only on one machine. Below is the code, with the actual directory I need changed(to protect anonymity)
from _winreg import *
key = OpenKey(HKEY_LOCAL_MACHINE, r"Software\a\b", 0, KEY_ALL_ACCESS)
devguid = QueryValueEx(key, "DeviceID")
devid = QueryValueEx(key, "DeviceGUID")
devnm = socket.gethostname()
If I change the directory to something other than \a\b, it works fine. I have verified that the permissions on these directories are the exact same as directories I can read from.
Also, I can run the following command from cmd and get the output I need:
reg query HKLM\software\a\b /v DeviceGUID
But when I run it from a python script, it says cannot find file specified.
import os
cmd = "reg query HKEY_LOCAL_MACHINE\software\a\b /v DeviceGUID"
a = os.system(cmd)
print a
Running my script as admin or anything doesn't help. For some reason, python is unable to try and ready registry....
First of all you do need to make sure that your backslashes are suitably escaped, or use raw strings as per the first code sample. I'm going to assume that you've done that.
The most likely explanation is that you use 32 bit Python on a 64 bit system. And so are subject to the registry redirector serving up the 32 bit view of the registry.
Either use 64 bit Python, or specifically open they key with a 64 bit view. Do the latter by specifying the KEY_WOW64_64KEY flag.

Finding the user's "My Documents" path

I have this small program and it needs to create a small .txt file in their 'My Documents' Folder. Here's the code I have for that:
textfile=open('C:\Users\MYNAME\Documents','w')
lines=['stuff goes here']
textfile.writelines(lines)
textfile.close()
The problem is that if other people use it, how do I change the MYNAME to their account name?
Use os.path.expanduser(path), see http://docs.python.org/library/os.path.html
e.g. expanduser('~/filename')
This works on both Unix and Windows, according to the docs.
Edit: forward slash due to Sven's comment.
This works without any extra libs:
import ctypes.wintypes
CSIDL_PERSONAL = 5 # My Documents
SHGFP_TYPE_CURRENT = 0 # Get current, not default value
buf= ctypes.create_unicode_buffer(ctypes.wintypes.MAX_PATH)
ctypes.windll.shell32.SHGetFolderPathW(None, CSIDL_PERSONAL, None, SHGFP_TYPE_CURRENT, buf)
print(buf.value)
Also works if documents location and/or default save location is changed by user.
On Windows, you can use something similar what is shown in the accepted answer to the question: Python, get windows special folders for currently logged-in user.
For the My Documents folder path, useshellcon.CSIDL_PERSONALin the shell.SHGetFolderPath() function call instead of shellcon.CSIDL_MYPICTURES.
So, assuming you have the PyWin32 extensions1 installed, this might work (see caveat in Update section below):
>>> from win32com.shell import shell, shellcon
>>> shell.SHGetFolderPath(0, shellcon.CSIDL_PERSONAL, None, 0)
u'<path\\to\\folder>'
Update: I just read something that said that CSIDL_PERSONAL won't return the correct folder if the user has changed the default save folder in the Win7 Documents library. This is referring to what you can do in library's Properties dialog:
The checkmark means that the path is set as the default save location.
I currently am unware of a way to call the SHLoadLibraryFromKnownFolder() function through PyWin32 (there currently isn't a shell.SHLoadLibraryFromKnownFolder. However it should be possible to do so using the ctypes module.
1Installers for the latest versions of the Python for Windows Extensions are currently available from: http://sourceforge.net/projects/pywin32

Categories