views:

1288

answers:

5

I've several long-standing apps written in Delphi that persist their settings in the registry. I've used HKEY_LOCAL_MACHINE for 'hard' settings such as configuration preferences and HKEY_CURRENT_USER for 'soft' info such as window positions, MRU lists etc.

Now my users are telling me that in non-admin (standard user) mode the apps dont work. Looking, I see that I'm not able to read a setting put into HKEY_LOCAL_MACHINE when the app was in admin mode.

What are my options for this? I know little about standard mode and how this affects access to the registry at all. Any info appreciated.

+11  A: 

You can read from HKLM as a non-admin user; you just can't write to it.

Use TRegistry.Create(KEY_READ) when constructing it, and set the RootKey to HKLM.

var
  Reg: TRegistry;
begin
  Reg := TRegistry.Create(KEY_READ)
  try
    Reg.RootKey := HKLM;
    // Read value here
  finally
    Reg.Free;
  end;
end;

You can also use TRegistry.OpenKeyReadOnly() when opening a specific registry key; this helps with non-admin access to areas of the registry as well.

Ken White
You most likely are not using read-only with your existing code, which is why it fails. Using Ken's solution should fix it for you with the least changes.
Jim McKeeth
That's great Ken, just what I was looking for.
Brian Frost
@Brian: Glad I could help. You might want to also consider Paul-Jan's comment to your question; you should probably at least test under a non-admin account to catch these kinds of things. MS started to tighten things (voluntarily) with XP, and has been enforcing more of the restrictions since Vista's release.
Ken White
@Ken: Yes, I looked hard at this last night and I find that there as Admin under W7 (and presumably Vista) there is also a virtualisation mechanism that apparently permits I/O to HKLM keys, but in fact the data is stored in VIRTUAL STORE - a location under one of the users. UNLESS your HKLM key already existed with the modify permission.
Brian Frost
@Brian: Yes, but the virtual store only applies if you're trying to write to HKLM, not if you open it read-only and read from it. Non-admin users can read from it any time, as long as they access it properly.
Ken White
+6  A: 

Please see "Where to store program settings instead of HKEY_LOCAL_MACHINE?"

The top-voted answer is particularly useful.

kemiisto
That's a great thread, thanks Rob.
Brian Frost
A: 

Your options include (a) use an INI/XML config file in a location that doesn't require admin rights to access, or (b) modify the security on your own subkey in HKLM using a tool like SetACL (public domain).

The problem with option a is the change in folder arrangements between XP and Vista/W7. I believe Vista tightened up access to CSIDL COMMON APPDATA - standard users don't have write acess if memory serves. You may have to store them in your own folder and arrange access rights yourself. Annoying.

One interesting problem with option b is that there are now officious little tools in use in corporate environments that crawl the registry and "correct" access rights they think are wrong. We haven't encountered a problem with customers using these yet, but we are aware they exist. Given the performance of the registry, we still prefer the modified HKLM approach and will continue to do it for the foreseeable future.

Bob Moore
The problem with option B is that it violates the basics of Windows security that MS and applications have been trying to implement since the introduction of XP, and enforce since Vista's release. Circumventing them by changing security on the registry is just bad programming practice. Your installer should run as an administrator and, if needed, write to HKLM at that time. Your app should run as a non-admin, and read from (not write to) HKLM in the proper manner as needed. Hackish workarounds like changing security are just that - hacks - that should be avoided. Corp security hates it too.
Ken White
Bizarre as it may seem, I actually agree with you. I wish we didn't have to do this. We were all set to change to using a cfg file system via Common Appdata when MS changed the access rules for that in Vista. Until MS acknowledge that there are classes of system which need a non-admin context app to change settings which affect other users, we're stuck.
Bob Moore
@Bob: They may acknowledge that but the choice isn't easy. It's the same with the location of common data files. Not having a location that is world-writable in a default install seems actually a good idea when you consider security. A standard install of a Unix-like system hasn't such a location either. root / Administrator can manually create such a location, and possibly set up quota to prevent a malicious user from filling up all empty space on the partition / drive.
mghie
I disagree with thefact that there are "classes of system" which need to make changes for multiple users without admin access. The ability to make changes that are system-wide is the purview of an administrator. User-level access should be able to change the settings for that single user. Changes that affect more than one user are for an administrator to make; anything other than that is a security hole.
Ken White
+1  A: 

One option, which I don't favour but will mention, is to give everyone (or a defined group etc) permission to access your key. There are various ways to do this, and there is code in the JCL that will do it, or you can use Regedit. But if you give permission (to that specific branch of HKLM) then it will work as you intended.

mj2008
This is a very bad idea. There are reasons that HKLM is not writable by non-admins; being able to write there is an attack vector for viruses and malware. Circumventing it because you're too lazy to do things the right way and test them the right way is just not a good idea.
Ken White
I agree - hence me not favouring it. But if this is an internal app used by three people, then it may be acceptable. And it would affect only that application. It certainly isn't something to do for a new application, or any mass-distributed app. For them, do it properly.
mj2008
A: 

The other thing that nobody's mentioned here is the issue of registry virtualization on Vista & Win7 (at least). It may not be an issue in your particular scenario, but I thought I'd mention it anyway in case it is relevant.
Even if your user has admin rights, if your application is NOT running "elevated" on Vista/Win7, your app still won't be able to write to the "real" HKLM key that you think it is. It will be being read and written to a virtualized copy of the appropriate HKLM key that only that particular user sees.
By "elevated", I mean that you will have been prompted with a UAC prompt on Vista/Win7. Run Regedit.exe for example on Vista/Win7, and you will be prompted with a UAC prompt.
If you're on Vista/Win7, it's possible that this is the issue you describe when you say it's not possible to read a key/value that was written in admin mode. If so, this would be because your app has at some stage written what is now a virtualized key/value; your app will now only ever see that key/value, even if an administrator modifies the "real" value.
As others have said, your app should not try to write to HKLM. If you feel it does need to write to HKLM, then on Vista/Win7 your options are (and these options can be made to work fine on XP too):

  • Add a manifest to your app requiring elevated admin rights as per this example.
  • Split your functionality requiring HKLM access out into a separate COM library and instantiate it as an elevated COM object as and when you need it. This is more complicated, but is a reasonable way to refactor existing functionality.

Here's another SO question that addresses some of these issues.

Conor Boyd
The question was about *reading* from HKLM, not writing to, so registry virtualization doesn't apply.
Ken White
BTW, not downvoting because, even though it has nothing to do with the question at hand, it's still good information.
Ken White
@Ken: reading between the lines of the original question, my reasonable interpretation was that the OP's app uses HKLM for storing configuration "preferences", which implies reading AND writing.
Conor Boyd
@Conor: From the OP: "my users are telling me that in non-admin (standard user) mode the apps dont work. Looking, I see that I'm not able to read a setting put into HKEY_LOCAL_MACHINE when the app was in admin mode." It clearly says "unable to READ". :-) I guess I'd have to question toe "reasonableness" (is that a word? <g>) of your interpretation.
Ken White
Fair enough Ken. ;-) I wasn't actually arguing with you, especially since you kindly didn't downvote me...
Conor Boyd