HKLM registry doubt - windows

My application updates some registry fields related to licensing under HKLM. This is for accessing the information for all users in the system. This makes us to make our application run as administrator. Is there any other location in registry where I can keep information which can be accessed by all users?

Registry HKLM and folder %ALLUSERSPROFILE% are accessible to all users, but meant for writing to at install time (as admin).
Registry HKCU and folder %APPDATA% are accessible to current user and meant for writing to at any time.
Why are you modifying licensing info (shared by all users) during run and not just during install?

You could place as an (e.g.) XML document in the file system under a shared folder instead of the Registry.
E.g. System.Environment.SpecialFolder.CommonDocuments or CommonApplicationData.

No there is not. If you have to make a modification that will affect/be visible to all users, you have to deal with UAC or elevate your application on startup. This is part of the design of UAC. If, however, you were to write to a file you could grant all users access to that file without UAC interference.
If, however, you are only reading the registry, you can do this without elevating your security rights. Therefore, if you write once to the registry and then just read it later, you can do so when only elevating your privileges once.
Here is an article on playing nice with UAC:
http://msdn.microsoft.com/en-us/magazine/cc163486.aspx

I'd make your installer precreate the registry entries (it runs as admin typically), and open up their permissions using GetSecurityInfo and SetSecurityInfo. Then your app can write to them without any special perms.

Related

Writing into administrator's HKCU from standard user

I have a installer created in visual studio 2010 which writes into HKCU of registry. It requires administrative privilege during both installation and running.
Now when I am installing it with administrative privilege, from a standard account the registry entries are written into standard user's HKCU registry part. But when I am running it with administrative privilege,it is reading from administrator's registry HKCU.
After lot of searching I came to the conclusion that when you run a program with elevated privilege, It searches for the elevated user's HKCU. But why same thing is not happening during Installation as I have administrative privilege at that time also.
According to another stack overflow question, opposite thing is happening, i.e. Elevated installation writes to admin's HKCU. Can anyone help me how to achieve that workaround.
[Note: I am aware that changing the code to read and write from HKLM ,rather than using HKCU may be best solution for this ,but not for me .Because recently it was changed from HKLM for another big issue and cannot be reverted.]
Now when I am installing it with administrative privilege,
How do you actually start the installation? Do you have an EXE wrapper over your MSI and launch it with the command "Run as administrator"? Is that wrapper launching the MSI latter on during the installation?
Normally, if an MSI is launched by an elevated process (be it the EXE wrapper or a an elevated cmd.exe) the per-user data (registry and files) are redirected to the locations of the new user (i.e. the admin under which now the installer is running). So your registry entries should be created also under the administrator's HKCU hive and your application should find them when launched as an admin.
As a side discussion, is not really recommended to have an application load entries from HKCU but run it directly elevated, things can get confusing. If you want your app to run as admin, then you should install it per-machine and use the appropriate file and registry locations. What was the bug that made you guys switch to per-user installation? (maybe we can help with a better solution)

How can I have my installer write to the HKCU registry tree?

My installer requires admin privileges. During installation some values are written to the HKCU tree of the registry of the currently logged on user. However, when this user account is a so called standard account, the user has to specify credentials for an administrator account when the installer starts. The values are then written to the HKCU tree pertaining to this admin account instead of the HKCU of the currently logged on user.
The same problem arises when the installer wants to write some data to the local AppData and wants to create a shortcut on the desktop.
How do I circumvent this?
This happens because you are using a per-machine installation which writes data in a per-user location (HKEY_CURRENT_USER).
The correct approach is to use either a per-user installation with only per-user locations or a per-machine installation with only per-machine locations (HKEY_LOCAL_MACHINE instead of HKEY_CURRENT_USER).
If you are asking for admin rights it normally means you are doing a system-wide/machine install for all users. When creating this type of installer it is not a good idea to write to HKCU or %USERPROFILE%, not just because you can end up performing actions for "the wrong user" but you also end up initializing the install for just that one user and not all users.
What I recommend is that you write this common data to HKLM\Software\YourCompany\YourApp\CommonData and/or <CSIDL_COMMON_APPDATA|CSIDL_PROGRAM_FILES>\YourCompany\YourApp\CommonData and then import this data in your application the first time a user run's it.
You might also want to consider creating a per-user installer (like Chrome) but this means you can only write to HKCU and %USERPROFILE%!

how to prevent application to be uninstalled by a user (w/o admin rights)?

I need to forbid to uninstall an application (not a service!) by a user w/o some special rights. How to do this? installation will be done by domain administrator
thanks for your time
[EDIT] also I need to prevent removing the application from windows startup
[EDIT1] to clarify: application is simple and is installed in its folder and added to windows startup (actually to HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run registry). What I need exactly is to forbid to remove this folder and this registry key, for ordinal users, not for local admins.
[updated]
the file location is easy. That is simple revoking write permission on the folder and all its subfolders and files for Builtin\Users, and giving Builtin\Administrators full permmision. You can set this via the Explorer, properties-> permissions or commandline wise with cacls (or icalcs if you're on win7)
The regkey is on my win7 box already only readable (not writeable) by Users and read/write by local admins (regedit -> Context menu -> Persmissions).
If it still doesn't behave like you want figure out what groups a normal user is in (also domain groups) and then check how those groups are propagated to the local machine.
And as sugested by Ben in the comments, you might start a new question on Server Fault.
[end update]
[before edite response]
I doubt you can disallow the uninstall of 'one' application. By means of a Group Policy you can "Pohibit removal of updates"
(in GPedit.msc under Computer Config/Admin templates/windows components/windows installer)
The Group Policy is set by a domain admin and is enforced across the domain so it doesn't require 'persmissions'. But you need off course to also prevent local admins from editing the local group policy.
Another more daunting option would be to use a group policy in the Software Rectriction part of Security Settings. Here you can enter a path policy for the name of the msi or exe file that you do not want to be run.
Both require validating/testing to prevent that to much restriction prevent everybody from starting anything...
If an application requires administrative rights to be installed, then non-administrators will not have permission to remove it.
If the users have local administrative rights, then you can't prevent anything.

Changing registry without admin rights

I thought I needed admin rights for changing registry (I get errors if my app doesn't have such). Maybe only some part of the registry require admin rights.
Could you give some information? I need to store my app data somewhere without admin rights.
You need administrative privileges to write to locations that are shared by multiple users.
In the filesystem, this means folders like \WINDOWS or \Program Files.
In the registry, this means all of the hives which aren't per-user.
Therefore, you can only write to HKEY_CURRENT_USER.
Specifically, you should write to HKCU\Software\Your Company.
Log in as a normal non-admin user. Open up regedit, right-click on the top level keys and examine the permissions for each, you'll see which ones you can write to as a user. Basically, it's just HKEY_CURRENT_USER as SLaks says.
HKEY_LOCAL_MACHINE is off limits, for instance. You can write to HKEY_USERS/your users SID, because HKCU is basically an image of that.

Windows 7 elevated registry access

I'm working on an installer for our application. The installer makes some changes to the HKEY_CURRENT_USER\Software\Company\AppName registry key, which the application then looks for the first time it runs. The application then does different things based on the registry keys it finds.
This works great, until you try to install the application as a user account (i.e. non-administrator) on windows 7 (and maybe Vista, I haven't tested that yet).
When the user tries to install the application, Windows elevates to the administrator account's credentials. This means that any changes to HKCU in the registry are made to the administrator's registry, not the launching user's registry. Thus, the keys are not visible to the application when it launches for the first time under the user's account.
We can't be the only people whose installer needs to communicate with the app it installs. Is there no way to reliably use the registry to do this?
We can't rely on the user launching the app after he installs it, so passing the information as a command-line parameter isn't a viable solution. The only way I can see to do it is to have the installer invoke a utility as the original user, which gets or sets the registry key itself; this seems to be a bit of a silly hoop to have to jump through.
Edit: The application needs to delete the keys after it's used them, so I can't just put them in HKEY_LOCAL_MACHINE.
There are 2 recommended approaches for what you want:
Use a per-user installation which
doesn't require Administrator
privileges. You will be able to use
HKEY_CURRENT_USER, but your product
is not installed for all users.
Use a per-machine installation which requires Administrator privileges. In this case you need to redesign your application so it reads its settings from a configuration file. HKEY_CURRENT_USER should be used only when saving user-specific settings, not for global application settings.
Basically, if your application is per-machine, it should use HKEY_LOCAL_MACHINE or a configuration file. If it's per-user, you can use HKEY_CURRENT_USER. Any other combination has limitations and will not work the way you need.
If you need your application's information to be available to all users, use the HKEY_LOCAL_MACHINE hive.
EDIT - 2 alternatives:
Change the security of your registry
keys to allow users to edit/delete
them,
Use the ProgramData directory (instead of the registry) to store
the data.

Resources