Allowing administrators to modify user's settings from within my program -- what's my best option? - permissions

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.

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.

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.

Related

Can you read/write to the registry without administrative permissions?

Essentially I need somewhere to store an expiration date for my software and do not want this to be accidentally deleted (the likelihood of anyone tampering with my software is relatively minimal). I thought about writing this to the registry, however this appears to require administrative permissions. Is there any way to get around this issue?
Thanks
The better alternative would be to use Isolated Storage.
If you really need to modify the registry, and you don't have sufficient privileges to do so, you would need to either ask for an administrator's credentials, so you could temporary elevate your privileges, or you would need to make a request to another process, such as a service, which is already running under another account with sufficient privileges.
If Isolated Storage is a bigger tool than you need for the job, another simpler option would be to use an App.config setting. You can create a setting in your project properties designer screen, and then you can read/write the setting via My.Settings.

About 'writing to files' and user permissions

I'm working on a VB.NET (2010) project that will need to write text files to the end user's computer. I have read online that due to some user's security settings, that the safest place to write files to is the Application Data folder.
But what I would like to do (if possible) is allow the user to select where they want the files written to, via a SaveToFile dialog (I am using a SaveFileDialog in combination with My.Computer.FileSystem.WriteAllText).
So my question is... if I use a SaveFileDialog (as opposed to saving a file without using a dialog), does that mean that my files will always be written to wherever the user selects?
Or is it possible that the user could select a location (ie their "desktop"), and it would not write the file there, due to their security settings? (UAC, Firewall, etc).
If the latter is possible, is there anything I can suggest to the user that they can do that would enable my program to write files to wherever they select, and it would work 100% of the time?
Like maybe... if they right-click on my program's exe file and go to Properties > Security, and make sure the 'Write' permission is allowed, will that do the trick? Or is there more to it than that?
And does it mke any difference whether or not they are logged into their computer as "admin"?
I've read a lot of conflicting things about all of this online, so I'm just trying to getting a better understanding of it all so that I know how to proceed.
Thanks!
The [Save As] dialog will only let the users select a folder they have read and write acceess to and that is done for you by the Operating system . So that is the best option in my openion

TRAC, hide a project in available projects page depending on permissions

I have multiple projects in TRAC. I'm using mod_wsgi, and my wsgi script file TRAC_ENV_PARENT_DIR variable is pointing to the folder containing folders with all these projects. A few users have access to different projects. When a user visits the TRAC URL, she can see the listing containing all these projects, yet has no access to some of them.
Is there any way to show to a user only those projects this user has access to?
Please advise.
Preamble: I abhor security through obscurity. Your request could be read as cosmetics in web site presentation. Don't aim at improved access control, because knowing a valid path will still give access to each Trac environment depending on it's settings. Of course better navigation is a good reason.
Requiring to hide folders depending on user's permission means you require authentication before granting access to TRAC_ENV_PARENT_DIR. This could be done with standard mechanisms that your web server supports. This is just the precondition.
As you say, you have some non-public Trac instances in your Trac environment folder collection. How complicated it is to identify all folders correctly, that depends on how much you want to spend on initial implementation vs. maintenance.
I should be trivial, but error-prone, to provide a list of either the public or the private directories, of course whatever is easier to maintain. Zero additional configuration would require to open each Trac environment and look up user permissions. )** This sounds rather cumbersome and means probably a performance penalty for applications with large user base and frequent access. You will at least work with a cached list, if you go down this road.
You can't use Trac's auto-generated Available projects list but you'll have to deliver at least two versions of an index page for authenticated/unprivileged and authenticated and privileged users.
For the sake of maintenability you'll want to consolitate configuration and permissions. For access to each Trac environment you could use trac.ini inheritance and a shared .htpasswd file. However you can't inherit permissions, because these settings are stored inside the Trac db. You could give TracUserSyncPlugin a shot, but it seems not yet fit for production, or at least lacks feedback of all the happy users, if they exist.
)** While I'm not aware of dedicated documentation about this, there are actually several possibilities. Since permissions are stored in the Trac db, all involve reading/querying the permission db table. It's structure is documented with all other tables of the Trac db schema. To read you'll want to open the Trac environment(s) and then use a direct query on the table (see a AccountManagerPlugin changeset for an example) or construct and query a PermissionCache object.
It may be an old question, but so far i've found the answers to be rather complex without need.
I think using the information stated here, http://trac.edgewall.org/wiki/TracInterfaceCustomization#ProjectList , one could build a template that checks for users and permissions and then show the data it should.
In my case, i just needed to point the "TRAC_ENV_INDEX_TEMPLATE" variable to blank HTML, and that was enough for me.

Username and password storage location

I am writing a program in vb.net that requires a user to log in before he can use the application. The main user is created when the program is installed, similar to how windows works when it is installed.
The main user can add additional users to the program. I already know that I should store the passwords encrypted. My question is, where should I store the usernames and passwords? The registry, Isolated storage or .config file. I don't want any user to be able to modify/delete that file as the other user would obviously not be able to log in. Also, this file should be accessible for any user that logs into the computer.
The computer is not guaranteed to be connected to the internet, so it must be stored locally.
Thanks
To tell you the truth if someone has the will power to look for the file they will find it, so storage can help up security but I would focus on the contents of the file itself.
You could try to store the data of the application as a encrypted file which could stop the amateur attempts but as you are using the .net framework your program could could be decompiled and any symmetric encryption algorithms could be rendered useless.
I think your best bet would be to either generate a seed according to the computer the program is on, and if decryption fails call home or go into Lock Down.
Another option would be to store the encrypted (encrypted with your symmetric key) file and a hash file (in different locations probably). If the hash of the loaded file then does not match the hash file your program could then call home (If you have a home to call).
This is just a idea, haven't actually tried anything like this.
If you are not able to use windows users/credentials in any way on the machine, then there really is no absolute way to prevent the file from being removed/changed, Since anyone on the computer has the same access as the main user, who needs rights to modify the file in order for him to add users through the program.
The only way to do it for sure is to have the main user logon with a different user name, and set the file permissions on that file/folder to make sure that only the main user has modify permission to the file (and the other user account does not have the right to modify permissions). I know you said it wouldn't work in your environment(which is?) but you might be able to create users and run stuff under different credentials through your code without having the users log on any different.
The only crazy way I can think of is to create a service on the computer that once it starts running, it opens and holds a handle to that file with sharing set such that no other process can open the file for writing. You'd of course have to workout some way for the main user to be able to add users.

How to tell Windows Explorer not to request file details and thumbnails in certain folder?

Is there a way (via shell extension or registry setting) to tell Windows Explorer that it shouldn't read files in the folder being shown in order to extract metadata or create thumbnails?
The problem is that when the user navigates to the folder, Windows Explorer attempts to read all files in the folder and extract certain metadata from them. If the medium is slow, this takes ages and causes unnecessary load on the file system. This is especially true in case of thumbnails, when the whole graphic file is read.
I am looking for ways to do this (restrict Explorer) in code, so "don't use Thumbnail mode" is not an acceptable answer :).
Upd: per-user settings won't work unfortunately cause we as a disk provider can deal only with our own disk (and the user might want to have separate settings for regular disks and virtual disks). I believe there must be some way to "explain" the OS that the drive is slow.
Maybe there's some IRP on driver level that we need to handle to tell the OS that the medium is slow?
Is there a way (via shell extension or
registry setting) to tell Windows
Explorer that it shouldn't read files
in the folder being shown in order to
extract metadata or create thumbnails?
Not that I know off, but depending on the priorities regarding the use case details you outlined there might be two options still to approximate the desired result:
Via group policy
Note that this essential expands/details the network folder related aspect of Freds answer, which you dismissed in your update; however, you claim to be able to deploy shell extensions or registry settings and the following two group policies simply execute the latter by administrative means:
User Configuration -> Administrative Templates -> Windows Components -> Windows Explorer:
Turn off the display of thumbnails and only display icons **on network folders**
Turns off the caching of thumbnails in hidden thumbs.db files.
This boils down to the following registry settings:
Windows Registry Editor Version 5.00
[HKEY_CURRENT_USER\Software\Policies\Microsoft\Windows\Explorer]
"DisableThumbnailsOnNetworkFolders"=dword:00000001
"DisableThumbsDBOnNetworkFolders"=dword:00000001
Of course this is still not per folder, but at least limited to network folders and ignores regular disks and virtual disks.
Via hackish workaround
Given your statement we as disk provider can deal only with our own disk there might be a hackish workaround, though I'm afraid it lacks the last mile (untested by myself).
Starting from Chris W. Reas own answer to How can I suppress those annoying Thumbs.db files in Windows Vista and Windows 7?:
Also worth knowing: In Vista and Windows 7, Thumbs.db applies to network folders only. For local folders, Vista and Windows 7 instead save thumbnail cache information to a database in a local folder at "%userprofile%\AppData\Local\Microsoft\Windows\Explorer"
Continuing from there, Wil claims the following potentially clever solution to work on a per folder basis:
Go to the drive and create a file called thumbs.db (in notepad or anything), then change the permissions on the file for everyone (including SYSTEM) to deny all.
Unfortunately, aside from the automation requirements to create the dummy thumbs.db in each folder, the outcome depends on how Explorer will react on the inaccessible file - because caching is optional as per group policy, it might as well display thumbnails without caching them, making the bandwidth issue even worse in turn ...
Good luck!
I'm not sure if you can disable thumbnail generation/display for certain folders but this article talks about a script which could quickly disable it via context menu.
The script modifies a value in the registry key HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced\. I suppose you could find something similar in that key for the other metadata. ShowInfoTip sounds promising. There might be relevant information in other nearby keys.
This may be a complete non-answer depending on your needs, but how about storing the files without file extensions that the OS wants to make thumbnails of? Call it file.jpg.abc and it won't be reading thumbnails, for sure.