views:

247

answers:

6

My application needs to read an option on startup to check if it should start in read-only mode. The option should not be allowed to be changed by the user.

I usually do this now using a value set in the HKLM\Software section of the system registry. The administrator sets the value and the users can't change it (they don't have writes to modify in HKLM).

The problem is that on a server (or Citrix) machine this affects all users. I'd like to figure out a way to do this on a per-user basis. How do others handle this? Is there a section in the system registry for this kind of per user setting that the user can't change?

Thanks for any suggestions or comments!

A: 

Whats wrong with HKCU instead of HKLM? This would be per-user. Unfortunately it could be changed by the user if the user knew how to edit the registry and find the key.

skamradt
I use HKCU for normal user settings. In this case though, it is a setting that the user shouldn't be able to change.
MarkF
+2  A: 

The concept of a per-user settings area that the user can't change doesn't really make sense - if they're user settings, "you" (the user) expect to be able to change them.

I can think of two alternatives:

  • Write your settings in HKLM, but have a different setting for each user and a global fallback setting for users without the setting set
  • Write them in HKCU, but use the registry security APIs to prevent them writing to it. You will probably need permissions greater than theirs to prevent them undoing the permission changes. I don't really like this option, but if you want to follow it you probably want to start with the RegGetKeySecurity and RegSetKeySecurity APIs. This article might be interesting as well.

Personally I think the first option would be the easiest, and also would involve less dodgy stuff in the user's registry tree. Hope that helps!

David M
Why doesn't it make sense? I even gave an example of the kind of setting (read-only) that you wouldn't want the user to be able to change... This option would be initially set by an administrator, not by the user. Just because a setting is per-user does not mean that that user should be able to change it. File restrictions, database rights, and disk quotas are all examples of settings that are per-user but that the user shouldn't be able to change.
MarkF
That's a good point. Do you know where those things are stored?If they're stored in the HKCU tree with permissions so the user can't modify them, then it follows it would be quite valid to have per-user settings (of any security permissions) in the user tree. Ie I think you're right. So maybe go with option #2.
David M
Thanks David. I do think that I might end up with using a read-only setting in HKCU (either in the policies area as mentioned by Oliver, or with a homemade readonly key as you suggest). Thanks for your suggestions!
MarkF
+1  A: 

How about two settings?

1) Set a flag in HKLM specifying that read-only is the default behavior on this machine.

2) For any users that need full access, set a token in HKCU which enables full access.

The token could be a cryptographic hash of some salt plus the username, so it couldn't be copied to give permission to another user.

Thanks, I agree that's a good suggestion. If the read-only registry thing doesn't work out, this may be a good alternative.
MarkF
+5  A: 

This is essentially what the HKEY_CURRENT_USER\Software\Policies key is for, i.e. a key within the user-specific part of the registry that is by default read-only to the user himself.

By convention the key hierarchy should complement the one you already have under HKEY_CURRENT_USER\Software, e.g. if your regular user preferences are stored under HKEY_CURRENT_USER\Software\MyCompany\MyProgram then the protected user preferences (or "policies" in MS lingo) should be stored under HKEY_CURRENT_USER\Software\Policies\MyCompany\MyProgram

Note that it is recommended to only set values under this key via Group Policy Objects and never by direct registry access.

Oliver Giesen
Thanks Oliver! That looks like what I'm looking for except for the recommendation about the entries only being edited by Group Policy Objects. I guess I need to research exactly how "not recommended" it is, since it seems to fit my needs otherwise! I suppose I could have the administrators create a new read-only key just for my special settings, but if one already exists they may be more apt to agree to just add to it.
MarkF
As far as I have understood it the recommendation is mainly based on the fact that *if* you do choose to use GPOs later on then anything you write to that key might get overwritten by a GPO without warning.I'm currently evaluating support for GPO-controlling our own app but I haven't reached the practical stage yet so I couldn't give you any more details at the moment.
Oliver Giesen
+1  A: 

Why don't you store options in your own database? It seems reasonable and handy enough (at least to me 8) ) No problems with making "portable" version of your product. No users bothering any settings you don't want them to bother.

Wiseman
That's how we handle it. In fact we have "rights" values 0-9. These are in a table inaccessible to the users.
Despatcher
Actually I do do that for some cases. Some clients however don't want to create the rights table and/or manage the users by name. In some cases users share the same username, but need different rights (not what I would do, but I don't have any control over the client's policies...) They want to make the setting on install with a script (or direct registry editing perhaps).
MarkF
If it's not too confusing, you can store some non-standard-user settings privately(database), and make others public. While you are using separate object for retrieving options this complexity will be "wrapped" inside it. But there many cases, of course, when this advice is not suitable.
Wiseman
A: 
  • Take one of the files coming with your program, that should not be altered (at least not by the restricted user). If there is no such file, create one just for this purpose.
  • Let the administrator set read only rights to that file for those restricted users.
  • In the program check whether you have write access to that file.
Uwe Raabe
Thanks. I've done something like this in the past, but it seems to me that a savvy user could just copy my exe to a different directory on their machine (or re-install it completely to a different directory.) It really depends on how "locked down" their machine is I guess!
MarkF
If you use a new file for this access option, you can store it in any place you like, especially somewhere the user has no rights by default. You can create it from inside your application in case it is missing when you are running as admin, otherwise assume it is read-only. With a dedicated location for that file it doesn't matter where your application is located.Setting user rights for files is something every admin should know and it is straight forward. Any other scheme has to be explained to him.
Uwe Raabe