I receive random reports from random users about UnauthorizedAccessException when reading or writing(creating files) to random folder. Usually on their own Documents folder. And more problem is that when app is unable to write its data to {USER}\AppData\Roaming.
The application is running as admin** and usually reports are from Windows 7 and Windows 8 users.
Is there any way to fix this without setting the permission manually.
**To determine if app is running as admin
AppDomain myDomain = Thread.GetDomain();
myDomain.SetPrincipalPolicy(PrincipalPolicy.WindowsPrincipal);
WindowsPrincipal myPrincipal = (WindowsPrincipal)Thread.CurrentPrincipal;
boolean isRunningasAdmin = myPrincipal.IsInRole(WindowsBuiltInRole.Administrator));
edit : in app.manifest
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
With respect to the question: Is it possible to avoid permission related exceptions while attempting to write to the disk?
In short, the answer is: yes this can be accomplished through the use of impersonation.
SOLUTION NOTES
IMPERSONATION & PERMISSIONS
Impersonation is the ability of a thread to execute using a different
security information than the process that owns the thread. Typically,
a thread in a server application impersonates a client. This allows
the server thread to act on behalf of that client to access objects on
the server or validate access to the client's own objects. [SOURCE: A Complete Impersonation Demo]
As highlighted by Aasmund Eldhuset, running as an administrator does not guarantee that you will have the appropriate permissions to access the file system.
As a sanity check, you could create a simple application to ensure that everything is working as expected.
Create a simple WinForms application that will write a text file to disk using impersonation.
See: A Complete Impersonation Demo
Create a test environment with folders/directories and different user permissions
Verify that everything works:
Run the test application and have it write to a directory where you DO have permission.
Run the test application and have it write to a directory where you **DO NOT* have the appropriate permissions.
APPLICATION DESIGN
I suggest that you take user feedback with a grain of salt as it is not uncommon for users to provide inaccurate or incomplete descriptions of problems they are encountering.
In your scenario, I would have your application attempt to write to the directory/folder in question when the application starts. If the write fails, then you can record relevant information (e.g. the name of the user that is executing the write operation) to an event log (e.g. text file) for later review.
ADDITIONAL READING
CodeProject: A Complete Impersonation Demo in C#.NET
Microsoft TechNet: RunAs command
High-Level Overview of Windows Privileges
Related
I wrote a .NET console application that needs to be scheduled trough Windows scheduler. Such console performs some network and database activities and write a logfile. The application work if run on Desktop/Command prompt but if I try to run it trough the scheduler it refuse to start. Another issue I faced is the write access to the app folder. Even if I set permissions to the folder containing application binaries to be wrote by 'Everyone' the app seems unable to create the log file and/or append data to it. The problem fixes if I run the application with Administrator priviledges (on desktop) but if I define the Activity in the scheduler to Run with higher privildegs this will not fix it anyway.
Best course of action is to create a Service account with admin privileges and schedule the task under such account and select the option to run whether the user is logged on or off.
This approach is even more relevant where Active Directory is in place.
Hope this helps,
Apex
I found the issue... http://support.microsoft.com/kb/2452723
It seems that the "Start In" parameter of the Action should not contain quotes.
Of course the folder should be 'writetable' for the user assigned to the task.
I've been wrestling with this issue for a few days and can't find any posts that solve it for me. Maybe what I want isn't possible.
We have developed a WinForms application for internal use at our company.
Most employees do not have admin access in windows.
Our application requires admin access to the machine and needs to automatically start when the user logs on.
Here's what I've tried:
1) Putting a Shortcut in the Startup folder
I can get the app to automatically launch (using a relauncher), but it still requires an admin to be at the computer on every restart (to enter the password).
2) Registry Key
I created a Software\Microsoft\Windows\CurrentVersion\Run registry key to automatically start the application. Whether I run the relauncher or the app itself, UAC demands a password on every restart (or relogin).
3) Scheduled Task
I created a scheduled task to automatically start the app on logon using admin permissions on the machine (under use the following account). I also checked the 'Run with highest privileges' box. UAC still pops up on every restart.
4) Windows Service
I tried to run the app as a windows service, but it has a user interface (which is disabled by windows services).
5) Disable UAC for Specific Program
It looks like you can disable UAC for a specific program but that involves downloading the Application Compatibility Toolkit, creating some kind of database, etc. I'd very much prefer that our IT staff wouldn't have to do that at every machine. At this point, it's probably my only option.
It seems like an admin should be able to install an application so that it runs automatically without a prompt. Am I missing a way to do this?
You should make split your program into a non-admin UI, which runs on user startup, and an admin service, which performs the administrative tasks.
To run admin-requiring code from the UI, use WCF to ask the service to do it.
Beware that hostile parties may impersonate the UI and ask the service to do malicious things; you need to carefully figure out what the service should be able to do in response to IPC calls.
Your problem is not a UAC problem, it is a security problem.
And the answer depends on what your application that "requires admin rights" needs to do.
If your application needs to be able to start, and stop services, then the User needs the ability to start and stop services. In which case you need to give the users that privilege.
If the user's need the ability to alter or delete files, then they need that privilege too. In that case it is easier to grant Full Control permissions to Everyone.
If your application needs the ability to modify registry keys in the HKLM tree then you can, again, grant Full Control to Everyone in the registry.
If you need your users to have the ability to modify items, then they need permissions to modify those locations. Granting them those NTFS permissions is not a bad thing; it is exactly what those permissions exist for - to control access.
But why
But then we ask why? What is it you're doing that users need all the rights of an administrator, and all capabilities of an administrator, all the power of an administrator, but you don't want to make them a member of the Administrator's group?
The answer is almost invariably that your internal use application doesn't need to run as an administrator.
What Would XP Do?
The question becomes:
What would you do on Windows XP?
A standard user on Windows XP didn't even have the UAC convenience feature. If a user wanted to run an application an administrator: they had to logout and login as an administrator. How did, or how would, the application work on a system with UAC disabled?
Presumably very little of your application needs to run as admin - the rest would be better running as the unprivileged user. This is very common (think self-updating browsers, for example).
The proper way to do this is to install a service to do the privileged bit, and have the UI communicate with the service.
Our application requires admin access to the machine ...
Why?
You cannot bypass the UAC prompt, and this is by design.
See FAQ: Why can’t I bypass the UAC prompt? for a good discussion of why. Excerpt:
If it were possible to mark an application to run with silently-elevated privileges, what would become of all those apps out there with LUA bugs? Answer: they'd all be marked to silently elevate. How would future software for Windows be written? Answer: To silently elevate. Nobody would actually fix their apps, and end-user applications will continue to require and run with full administrative permissions unnecessarily.
I am using Visual Studio 2010, and I'm writing a program that needs to set (and read) new registry values under HKLM\Software\myapp
The program is .NET 2.0-based and as for now it runs on Windows 7 64-bit. Here is my ocde:
RegistryKey softwareKey = Registry.LocalMachine.OpenSubKey("Software", true);
RegistryKey MyKey = softwareKey.CreateSubKey("MyApp");
RegistryKey = MyKey.CreateSubKey("MyKey");
selfPlacingWindowKey.SetValue("instaldateperson", datestr + usrname);
The problem I have when running Visual Studio 2010, is that it will run the app but logged on as me, I am a user and member of local admin group.. however I cannot create the key (despite I am part of local admin group, who have rights to do so). Neither do I know how to do it as a logon as (but its also not what I want since then I would put Adminuser and password inside the code, and I already am admin ?? so why ??)
If this isn't possible at all, are there options for creating registry keys?
Somehow add them to the project or so ??.. I am a bit confused here.
Just because you're running as Administrator (or using an account with administrative privileges) does not mean that those administrative privileges are always in effect. This is a security measure, preventing malware from exploiting users who foolishly use their computer all the time with administrative privileges.
To wield your administrative privileges, you need to elevate the process. There are two ways to do this:
Use a manifest that indicates your application requires administrative privileges, and thus demand elevation at startup.
This means your application will always run elevated and should only be used when your application needs this. The Windows Registry Editor (RegEdit), for example, does this, because there's little you can do there without administrative privileges.
Find information about how to accomplish this here on MSDN, or in my answer here. Basically, you just want to add the following line to your manifest:
<requestedExecutionLevel level="requireAdministrator" />
If you only need administrative privileges for certain tasks (i.e., saving a particular setting to the registry) and the rest of your application does not require it, you should launch a new elevated process to do this. There is no way to temporarily elevate the current process, so you actually need to spin off a new process.
The advantage of this method is that your application does not have to run with administrative privileges all the time (which increases security), and that users who do not have administrative privileges will still be able to run your app to do everything else (i.e., everything but the one or two tasks that do require elevation).
You spin off a separate process that contains only the logic needed to write to the registry using the Process class and request elevation for this process using the runas verb. For more information, see this question. I have also written an answer that provides a complete description how to accomplish this from C#, including sample code.
Of course, as other answers have mentioned, it is more likely that the design of your application is incorrect. The whole logic of the Windows security model is that regular applications to not require administrative privileges. They don't need to write to the registry or do other things that could potentially compromise the machine. If you need to persist settings, might I suggest two other possible approaches:
Recognizing that Windows is indeed a multi-user operating system and writing your settings only for the current user. This makes good sense anyway because different users often have different settings and preferences. Instead of the HKEY_LOCAL_MACHINE branch of the registry (which requires administrative privileges to access), you would want to use HKEY_CURRENT_USER. Change your first line of code to:
RegistryKey softwareKey = Registry.CurrentUser.OpenSubKey("Software", true);
Skipping all of the hassle and complication of writing to the registry altogether by using logic built into .NET to persist your application's settings. Start reading the answers here, or here, or on MSDN to learn how to do that. I'd say that this is by far your best option. Don't write complicated code yourself to do something that the framework you use already has built-in support for doing with ease.
The design of your application is probably wrong. Standard desktop apps are not supposed to write to HKEY_LOCAL_MACHINE. Because of UAC, you need to have administrator rights, and be running in an elevated process in order to be able to write to HKLM.
If your application does need to make changes to HKLM then consider doing so at installation time because the installer will be run elevated.
If a desktop application does need to write to HKLM then it should consider separating those parts of the application that need to run elevated into a separate process. Otherwise the users are going to be very fed up with having to go through a UAC dialog in order to run your application. Even if they aren't using the part of the application that writes to HKLM. And if you force the entire app to require elevation then standard users can never run it at all.
The reason you can't create the key under HKEY_LOCAL_MACHINE while running Visual Studio is because Visual Studio isn't running as an elevated process.
For end-users the manifest of the application needs to indicate that full Administrator privileges are required. Here is the documentation on embedding a manifest for UAC
If the registry key doesn't need to be global on the machine consider writing to HKEY_CURRENT_USER instead.
You should to give writable permission adding true value after your key in the method.
Registry.LocalMachine.CreateSubKey(#"YOURKEY", true);
Registry.LocalMachine.OpenSubKey(#"YOURKEY", true);
Also you need elevated permissions to do that, then you can create a .manifest file and setting the level in requireAdministrator like that:
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
NOTE:
In your code:
RegistryKey softwareKey = Registry.LocalMachine.OpenSubKey("Software", true);
RegistryKey MyKey = softwareKey.CreateSubKey("MyApp");
RegistryKey = MyKey.CreateSubKey("MyKey");
selfPlacingWindowKey.SetValue("instaldateperson", datestr + usrname);
Check if the object label si correct, you are using the labels softwareKey and MyKey to create an object but to set the value you are using another label selfPlacingWindowKey.
Resuming. Create a .manifest file in your project. Give it the same name as the executable. "name_of_executable.exe.manifest" Finally change or create the tag for:
<requestedExecutionLevel level = "requireAdministrator" uiAccess = "false" />
The previous answers mentioned that you need to specify in the manifest that you require administrator permissions to use HKLM
You can create a manifest by;
Right click on your project,
Going to Add New
Click On General
Click on Application Manifest File
Click Add
Open your manifest file and find and un-comment the requireAdministrator line
The more nuanced thing that may be tripping you up is having Prefer 32bit ticked in your project settings.
This will mean that the Registry can't get the access mask it requires and it will fail silently without an inner exception because the error handler needs the same access mask so it can't be exploited.
You should avoid storing things in this part of the registry unless you absolutely need to persist settings across users, The registry also shouldn't be used to store passwords or other sensitive information as you can NOT reliably control access even with ACLs.
I'm working on a WPF application right now in C#, and I need to be able to save some images. These images need to be saved into a directory that the user that's currently logged in doesn't have access to without some administrative privileges (essentially, to control the security on what images are being saved to that directory).
How can I set up such security permissions? Is there some directory that I can add subdirectories to with these images inside?
Normally, I would try to post some code in example to what I have. I'm not entirely sure where to begin with this problem, though.
As Andrew already told in his comment you should really best start with a service. This will run under another account (normally System, but you can change this within the control panel). To start with this a service is in the first step nothing more than any other normal process. So to get a connection between the user application and the service you can use any inter-process communication as you like.
The only difference between a normal application and a service is that the service will be started and managed through the service manager and thous needs to derive from ServiceBase. Also maybe this Walkthrough might help you to start.
Default context for all non-user programs is system which it available to you via service programming and you are not familiar with it. A hack would be logging into another account (i.e administrator) and run the program in that context which is not possible on all windows versions and I believe doesn't worth the resources it cost and also is a security risk.
Another solution would be encrypt your application data and store it somewhere.
My application needs to run with administrator privileges because of some specific phone components.
I've build an executable that does nothing else than calling the real application with the specific local administrator account (username and password).
I use the ProcessStartInfo and Process class for this purpose.
The problem: Some word interop is being done and the required word templates are stored on a unc share.
Local admin -> no domain/network context -> no access to shares.
Are there any other solutions than these two:
put a domain account into the administrator group on the affected machines and call the app. with this user
put the word templates onto the local drive
Maybe there are some uac elevation experts out there?
I think the best way would be to temporarily switch back to the "real" domain user context, but I don't know how this should work without providing his credentials...
Thanks for reading - and maybe feedback!
Having that small application, which knows the administrator password is a security nightmare. Have you tried opening the .exe for your small app in notepad? I'm fairly sure that the password will be there - in plaintext for anyone to read.
It is far better to solve this by giving the user running the app the required privileges. Full administrator access is very seldom required. Have you tried looking into exactly what the phone app needs? Sysinternal's Process Monitor is often very good to use.