Cross-user registry values - windows

I'd come to this conclusion through experience and various things I've read on this internet, but in stating it to a co-worker, it seems illogical. Can you verify the following statement is true, or provide a counter to it?
On Vista/Win7, two standard (non-elevated users) cannot read/write the same location in the registry.

On Vista/Win7, two standard (non-elevated users) cannot read/write the same location in the registry.
This is a false statment
On Vista/Win7, two standard (non-elevated users) cannot write the same location in the registry in the default configuration.
But this is true. By default, users only have write access to their own hive (HKEY_CURRENT_USER) and read access to the machine hive (HKEY_LOCAL_MACHINE).
If you want to configure a location where any user can read and write, you can certainly do by configuring a key's ACL, as #Dark Falcon said. A good place for this is somewhere inside your application's key in HKEY_LOCAL_MACHINE, and at install time (when your installer has elevated privileges to do so).

That would be incorrect. A registry key can have an ACL specified which allows any user, elevated or not, to write to it. By default, I am not aware of any keys which have this configured, but it certainly is possible.

Related

How to read HKCU Registry key of another user in admin on powershell?

I have a powershell script that runs automatically thanks to a taskscheduler and its purpose is to take the version of all the softwares of the system in order to make a list and to quickly have an overview of the versions that are outdated. The problem is that in order for it to run at any time, the script is assigned to the SYSTEM user. However, some applications are only assigned to one user and SYSTEM cannot find them in its HKCU key.
So the question is, how can I list all the content?
Thanks in advance
You will need to load their hive first
REG LOAD HKEY_Users\johnshive "C:\Users\john\NTUSER.DAT"
You can then address their hive via powershell e.g.
Get-ChildItem -Path Registry::HKEY_USERS\johnshive
If the person is logged on, you have to go into HKU and find all registry keys that end in "_Classes". Then remove the "_Classes" from the end of those keys and that is the list of possible keys that belong to the user. If there is only one, and you know the person is logged on, then that is probably their key. But if there is more than one, then you have mostly empty ghost copy/copies where windows failed to fully unload it. Afaik, the ghost copies will not have the subkey "Volatile Environment" with the value "USERNAME", but I have suspicion that this isn't a true statement. I've had PsLoggedon.exe report two users logged on, but only later did I learn PsLoggedon.exe uses HKU to find who is logged on (not sure what subkeys and values it uses).
But if the user is not logged on, don't even go down that road unless you are a very detailed oriented person. If you load their registry hive, do your work, and forget to unload their registry hive, you will lock their registry hive file, Windows will think the profile is corrupt, build a new user profile, user will log in finding Documents folder empty and think their files are gone. I did a lot of experiments injecting mapped network drives into registry hive files of test users before I ever did that on an actual user profile.

How to get EVERY user token on a PC for SHGetKnownFolderPath?

I'm working on a System Service project with SYSTEM privilege (cleaning utility)... It does not interactive with any user interface.
My goal is to check files in "Desktop" and "AppData" folders for any user that exists on the PC.
I'm using NetUserEnum() to get the user list on the PC. Then I want to get the path of each user's Desktop and AppData with SHGetKnownFolderPath(), but I can't find a way to get each user's access token for SHGetKnownFolderPath(). Without a token defined in SHGetKnownFolderPath(), it returns the path for SYSTEM and not specific users.
Q1. How can I get the token of each user for SHGetKnownFolderPath()?
Q2. If no answer for Q1, is there any documented way to get the desktop & appdata path of each user in the PC?
I understand this can be achieved with dirty way ---> Registry key with some string replacement. However, the Registry key method is undocumented, which may easily break in future updates to Windows.
Edit Update:
#RaymondChen Thanks for pointing out that some user profiles may not exist. Also,
About Q1 : #Remy Lebeau provides a solution with LogonUser/Ex(),login to each user with their credentials,might be the only answer that fits the need of Q1.
About Q2 : There might have no documented way to achieve this. The only method might have to stick with Windows Registry (Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders) , as #Remy Lebeau and #Olaf Hess said. I tried to dig more information on Microsoft Community Forum and I got Microsoft would never allow access other users' profile with their native API for security reason. They do not provide APIs that can possibly violate the security rules. Each user profile can only access by its credentials.
btw, I totally understand that "Cleaning utility" aka "Windows-breaking tool", especially when the tool is not being well codded(ex. compatibility problem). For the sake of avoiding to make it become a totally Windows-Destroyer, I tried to use more documented API as possible.
For Windows Vista with SP1 / Server 2008 and better you can query the existing user profiles using the WMI class Win32_UserProfile. This allows you to retrieve the profile path and check whether it is a local or roaming profile and to get status information. The rest (retrieving the paths to APPDATA, DESKTOP, etc.) is likely going to involve reading values straight from the registry (HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders or HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders).

How to make an application GPO aware?

I'm writing an application in Delphi 2010, and I'd like to provide the option to the administrator to configure it via Group Policy. Any recommendations on good ways to make my application GPO aware? Note, I am only looking to create a computer based GPO, not user.
My current solution involves simply first determining if any values have been written to the registry at HKLM\software\policies\MyProgram. If they have, I assume that GPO has been applied and I use this location to read configuration.
If nothing exists at the above registry location, I proceed to reading configuration at the standard location, whether that's an INI file, or another reg key does not matter. At this point, I make the assumption in the program that group policies are not being used.
Would anyone suggest a better way to make this application GPO aware?
It's not that you have to be group policy aware, it's that the group policy has to be aware of the registry keys your program uses.
The purpose of custom Group Policy Templates is to have a user-interface for managing a custom set of registry keys used by a particular program. The domain administrator sets the policy to the desired values, and the policy is pushed out to machines on the domain.
In your case, the custom policy template will define the corresponding HKLM registry keys that your program uses. You can now trust that the values stored in:
HKLM\Software\MickSoftware\My Program 2010
are what the administrator has desired be there.
Note: The following "policy" registry locations are non-persistent:
HKEY_LOCAL_MACHINE\SOFTWARE\Policies
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies
HKEY_CURRENT_USER\SOFTWARE\Policies
HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies
"This means that when you log off the computer or when you shut down the computer, the policy settings are removed."
So it seems to me you want to store your registry values where you normally store them, e.g.:
HKLM\Software\Avatar Software Creations\HelpDesk\DatabaseServer
ServerName: REG_SZ = "lithium"
UserID: REG_SZ = "helpdesk"
Password: REG_SZ = "aSBsb3ZlIHlvdSBLaXJzdGVuIFNoZWxieSBHdXllcg=="

Required Registry location common to all users to avoid registry virtualisation in Vista

In Vista standard user can no more create or write to keys under HKLM\Software. So to port the code according to Vista standards in to which key i should write the application configuration data. Same way like %AllUsers%/AppData for folders. My main requirement is I should avoid writting to HKLM\Software, but the key location should be common to all users under registry.
Thanks,
F
The registry is a secure-able object.
i.e. you can, during the administrative install, alter the ACL of a key you create, to create an all users read / write key in HKLM.
That said, Users\public\AppData might not work they way you think. The ACLs on that folder allow read by all users, but only creators can write. Which means you still can't have two users editing the same documents.

Where to store Registry data for All Users

I would like to share a small amount of data between All Users in the Windows Registry. For shared read and write access between any user that logs into the machine or a service on the machine. Is there a location where this can be done? I have tried using "HKEY_USERS\.DEFAULT\Software\" but this seems to be blocked by the Vista UAC rules.
You can put all users data in HKEY_LOCAL_MACHINE hive, but you'll need to adjust the permissions on the key to in order to make it writable by all users, as your question states.
HKEY_LOCAL_MACHINE should be the place to store data between users. There's a good, short explanation here about which folders/hives are used for what.

Resources