views:

245

answers:

2

I've been working on making my app easier to use for administrators. One of the things I'd really like to do is allow admins to modify other user's settings from within the program -- while still making it possible for regular ol' users to modify their own settings, as my application isn't necessarily only for administrators who want to force users to use specific settings.

I thought of two possible ways of doing this:

1) Move the user setting file path from where it is now (CLSID_APPDATA, commonly Documents and Settings\Username) to a world-accessible path (CLSID_COMMON_APPDATA , commonly Documents and Settings\All Users). Then, save each user's settings to a unique file for the user (probably having a name which equals that of the user's textual SID), so the folder looks something like:

C:\Documents and Settings\All Users\My Company\My Program\settings\123-abc-456-def.settings
C:\Documents and Settings\All Users\My Company\My Program\settings\234-bcd-477-xyz.settings
C:\Documents and Settings\All Users\My Company\My Program\settings\946-hdc-743-ddd.settings

Pros:

  • This allows an admin to see and directly modify any user's settings, because the COMMON_APPDATA path is the same for all users. This is how I'd really like it to be -- it's the most straightforward -- but there's a major con:
Cons:

  • Permissions could be a problem. To allow regular users to save their settings, you'd have to allow users write access to the program's COMMON_APPDATA setting folder.

    Of course, when the settings are saved and the setting file created on disk, you'd want to limit write access on the user's setting file to the user who the settings are for, and for admins, so that other limited user's can't modify them.

    However, it could be that before a user has a chance to write their own settings from within the program, a savvy, malicious limited user creates a setting file for that specific user, without the knowledge of the user. If the limited user creates the file, that means they own the file... and then that user (who the settings are for) can't modify the settings anymore, unless an admin changes the permissions on the file.

    An unlikely situation perhaps, but it still worries me.
2) Instead of moving the setting file path to a globally-accessible path and modifying the user's setting file directly, have my app create and save an "override" file in the app's CLSID_COMMON_APPDATA folder, to allow the admin to override the user's settings.

When my app loads for that user (who's settings were "overridden") it'll detect this file and load it instead of the regular setting file, which is located in CLSID_APPDATA (Documents and Settings\Username).

Pros:

  • Permissions are easy to deal with.

    By default, for the Documents and Settings\Username APPDATA folder, only admins and Username can access the files from within. So that in itself protects the user's own regular personal settings from other limited users.

    To protect the "override" settings, my app can simply deny write access to the COMMON_APPDATA folder -- where the override file is written -- to all but administrators, and then that's that. These overriding settings will only be modifiable by admins.
Cons:

  • This method is obviously more roundabout. If a user modifies his own regular personal settings, an admin won't see those changes -- the admin can only see the settings he's overriding the user's regular settings with (which he can force the user to use instead).

    In some ways, this might be good, but... the fact that it's roundabout turns me off somewhat.

I'm interested to hear what you guys think about this. Which is my best option? I'm personally leaning more towards #2, because while it's less straightforward, it seems to be more secure and isn't so roundabout where it'd be confusing for an admin.

However, I'm also open to suggestions. Is there a superior option you think would work better?

EDIT 7/6/09: I should note that for option #2, the admin could not only override all user's settings with a single override file, but also override an individual user's settings with an override file specific to that user (just like with option #1, that file name would likely be that of the SID of the user who's settings are being overridden). Not sure if that was completely clear in the original post.

+1  A: 

Unless there is more than one user account on each computer (i.e. a computer is used by more than one person), option two is the better choice.

Even if there is more than one user account on each computer, I think option two is still a better choice. Worst case, the administrator will have to change settings on a handful of accounts on the same computer instead of one.

If your facility allows random usage of any computer by any person, then option one is the better choice, since option two will make it too difficult to maintain that many different accounts on every computer.

Of course, you can always put the application settings in user folders on the server. That would make it very convenient for an administrator.

Robert Harvey
The facility would allow random usage of any computer by any person.You bring up a good point... the All Users APPDATA folder doesn't roam with a user, and is computer-specific, so that might be a pain in some cases. However, I'm really trying to design my program to work with Active Directory and Terminal Services... can I safely assume that both AD and TS would make this a non-issue? I would think that an organization with hundreds, perhaps thousands of computers, would have a single All Users APPDATA dir?
ZZZzzz
Terminal Services only works for server machines. Active directory, AFAIK, doesn't care about application folders on individual workstations. IMO your best best is to make roaming profiles. Keeping them workstation-specific is going to be a maintenance nightmare.
Robert Harvey
Argh, my cookie got cleared before I could respond. Here's my thinking: Active Directory makes it easy to install software once, and have it accessible to as many computers as are on the network, correct? If that's the case, wouldn't it be just as easy for the admin to, if it's not already, have everyone share the same All Users folder? And if they don't want to do that, then allow them to configure my program to use an alternate globally-accessible but only-admin-writable folder?
ZZZzzz
That makes sense to me.
Robert Harvey
Cool. I'm just curious; for what reason(s) do you think option two is superior to option one in most cases?As far as Terminal Services goes, the way I understand it, you have a server computer that does all of the work, and then all of the client computers simply send it commands over the network. So this would mean -- I would assume -- there should only be one All Users APPDATA folder.One more thing; I think putting settings in user folders would still give you the problem of a limited user creating settings for a user before that user can deny access to all but themselves in the folder.
ZZZzzz
I think the most important point is all of these settings need to be kept on the server. If they are on the server it doesn't really matter whether you use option 1 or option 2; it will still be easy to get to the settings and maintain them. If these settings are on the individual machines they will be endlessly duplicated, inconsistently set, and impossible to maintain, regardless of whether you use option 1 or option 2.
Robert Harvey
Terminal Services is a way to run multiple "sessions" (essentially user desktops) on a server machine, and have clients use a session in a virtual window from their workstation. In essence, several copies of the application are running on the server. If this is your method of allowing your users to run the application, then the application settings are all already on the server, and they are easily accessible on the server computer. If the application runs on the individual workstations, Terminal Services will not help you.
Robert Harvey
A: 

If the administrator already has rights to the user's directory where his setting's file is stored, wouldn't that already solve your problem? Either way though, it sounds like option 2 would be best, then you could have a single file that could override say a group of users, then each user have their own settings as well. Just so long as your application is smart enough to tell when to override a setting and when not too, option 2 shouldn't be that much of an issue.

sunmorgus
Unfortunately, there doesn't appear to be an easy, documented way to get the local appdata path for a specific user... otherwise, you're right, that would be so much easier. It looks like RegLoadKey() might technically work -- then I can get the Shell Folders/User Shell Folders key -- but I'm not sure how it would function in a networked/AD/terminal services environment. SHGetFolderPath() accepts a handle to an access token, but this requires all users -- even admins -- to enter the user's password, and it still requires the user's registry hive be mounted, anyway.
ZZZzzz

related questions