I have a C# app that needs to allow the user to change the Computer Name. This is a pretty privileged operation. I can only get it to work if the user runs the app as Administrator (Windows 7, right-click on executable, "Run as Administrator"). Fine, but the user IS an administrator, so why would they need to Run AS an Administrator? I've tried this several times. It always fails if the user--an administrator--tries to do it running the application normally. It always works if they run it as "Run as Administrator".
If the answer is, "It just works that way, you have to run as admin even if you are an admin," my question is how can I detect if they are running with super-duper admin privileges? I found this, but it just checks to see if the user is part of the Administrator user group which, I already pointed out, isn't sufficient (and throws a null pointer exception).
Am I missing something here? Do I need to approach it from another angle?
It's because of User Account Control (UAC). Introduced in Vista, this changes the way administrator user accounts operate.
When an user from the administrator group logs on, the user is allocated two tokens: a token with all privileges, and a token with reduced privileges. When that user creates a new process, the process is by default handed the reduced privilege token. So, although the user has administrator rights, she does not exercise them by default. This is a "Good Thing"™.
To exercise those rights the user must start the process with elevated rights. For example, by using the "Run as administrator" verb. When she does this, the full token is handed to the new process and the full range of rights can be exercised.
You almost certainly don't want to be detecting whether or not your process is running elevated. Best practise is to mark those parts of your program that require elevation and force the system to show UAC elevation dialogs when those parts of the program execute.
The bind is that elevation can only happen at process start. So if you need to split your app into parts that require elevation, and parts that don't, there need to be multiple processes. Whilst you could mark your entire app as requiring elevation, you should not do so if the only thing that needs elevation is the very rare scenario where the computer name is to be changed.
Your next step is to bone up on the details over at MSDN. For example:
http://msdn.microsoft.com/en-us/library/windows/desktop/bb756996.aspx
http://msdn.microsoft.com/en-us/library/windows/desktop/aa511445.aspx
Related
I have written a small program in c# that helps with switching between licenses for my company. It's a tray icon with a menu with the different choices.
It changes an environment variable and needs to have elevated rights in its manifest.
This means that the UAC warning shows up every time the program starts, which is not ideal because it would be really nice to have the program on autostart when Windows starts, without the warning showing up all the time.
Are there a good way to do this?
Is it possible to:
Run the program without elevated privileges and only get the UAC
warning when I call the function to change the variables.
Change the
environment variables without admin rights.
Add the program to a "white list" programmatically (although more realistic, add it manually)
I know the UAC is there to protect from malicious software, but it would be really nice to solve this in a way that enables me to start the program at Windows start.
I haven't been able to fine any silver bullet on this problem.
Any advise?
The normal way around this is you have a windows service that runs with system privileges that will set the environment variables for you.
You will need to have your installer install the service and set it to auto start. Then your tray application will need to communicate with the service with some kind of Inter-Process Communication (like WCF), the tray program can then send the requests to change the variable and the service can execute those changes.
Another way to handle this is start your program un-elevated then when you need to do something that requires UAC privileges you launch a new copy of your program as an administrator and pass in command line arguments that tell it to do the work you need done then exit. You also could have your program check to see if it is an admin, and if it already is elevated it could skip the step of starting the new copy.
What you need to do is move the license information to a location that all users can write to:
user's own environment variable
%CSIDL_COMMON_APPDATA% (e.g. C:\ProgramData, which all users can write to)
HKEY_CURRENT_USER
The ideal solution involves writing to a common machine-wide location:
%CSIDL_COMMON_APPDATA% (e.g. C:\ProgramData)
HKEY_LOCAL_MACHINE/Software/Contoso/License
C:\Program Files\Contoso\License\license.txt
Legacy software can't be changed
But assuming there are many existing unchangeable applications that cannot be altered to look anywhere else but an environment variable for license information you can (after you smack that guy who designed that):
write the license information to the user's own environment variable
Your switching tool will call:
SetEnvironmentVariable("ContosoLicenseInfo", "V2h5IGFyZSB5b3UgZGVjb2RpbmcgdGhpbmdzIHRoYXQgZG9uJ3QgYmVsb25nIHRvIHlvdT8=");
What would you have done under Windows XP
All this hand-wringing about UAC. You have to ask yourself:
What would I have done under Windows XP?
Without UAC, and the user running as a standard user, what will your license switching tool have done?
would have it crashed horribly on startup?
would it have crashed as soon as the user tried to use it?
would it have failed in a polite way?
would it show a message on startup saying: "Sorry, no."?
What would you have done under Windows 7?
Even better, you have to ask what you would have done for a user running under Windows 7? A standard user logs in, and you have a program in their startup group that claims to require administrative privileges.
The user needs to go get an administrator during login to run your tool? That's not going to fly.
If you're dead set against using a per-user location.
If you're dead set against using a common location that all users can write to
Then change your tool to run without needing user privileges.
Only when the user goes to do something do you need admin privileges.
Check if the user is an admin:
Boolean IsUserAnAdmin()
{
PSID administratorsGroup;
administratorsGroup = AllocateAndInitializeSid(SECURITY_NT_AUTHORITY, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0);
Boolean result = CheckTokenMembership(0, administratorsGroup);
FreeSid(administratorsGroup);
}
If they are an admin, you can perform the action as in.
If the user is not an admin, then you put the UAC shield on the Apply button.
You then re-launch your tool as an admin:
ShellExecute("runas", "C:\Program Files\Contoso\LicenseSwitcher.exe", ...); //the "runas" verb triggers elevation
But what would you do under Windows 7
None of the UAC stuff works if UAC is disabled. In that case: you are a standard user, and that's it.
In that case, it really is best to convert to:
machine wide location for the default license
per-user location if you want to choose your own
UAC is there to protect the Windows User by alerting them (and requiring an explicit action) that a particular application is requesting elevated permissions. If it was possible to bypass it from with the application itself them it would leave it a little pointless :)
I would assume that you are looking to change environment variables globally because I believe that you can change them for the current process without being elevated.
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 have an application that does a loop which starts some processes programmatically one by one. My app itself runs under a standard user, but I need to run only those processes as admin so I can install them.
To achieve this, I use the 4th response from this thread
My two questions are:
is that code which is pointed in the above response, supposed to ensure that the process automatically runs as admin, or that the user is shown a dialog where he chooses whether to run as admin or not? I am confused by what this code is supposed to do.
Also, in case a dialog is supposed to be given to the user - how can the app be coded, so that the first user option is remembered in my loop for the next processes started with the verb "runas" ? So basically to store somewhere the user option (run as admin or not) for the other processes.
Thank you in advance
First question: It is how to start an elevated process from a non-elevated one.
Second question: there isn't -- or at least shouldn't! -- be any way for a non-elevated process to elevate anything without a user prompt. The best solution for your program is either to start it off with admin rights, or to use the first elevation request as an opportunity to restart with them (using the technique you linked to).
I didnt get correct answer and got lots of answers like "we can not do like this" for my previous questions.
Thats why I decided to explain in detail about my problem please help me if you can or please ask your friend who can answer this.
Now my problem:
Step 1:
I created a C# program which edits various windows registries.
For editing windows registries we must have an Admin privilege.
My program is running fine in Administrator mode without any problem.
Step 2:
I want my program to be run into limited user mode also. If few people didnt get what I am saying here is that I want to run my above C# code into Guest mode.
In guest mode there is a restriction that We can not change Windows Registries.
So as I am executing my Application, I am getting one notification which is asking for Admin Password.
After inserting Admin Password my application is working fine.
Step 3:
I want that my application must not ask Admin password every time in Guest/limited account.
I also want that in Guest mode my Application should work.
I also want that in Guest mode my Application should be able to access and change Windows Registries.
Step 4:
Lot of people replied me that we can not do this in Guest mode since Windows is restricting users to edit windows registries for security purpose. So please if you also feel like this then please do not reply to this question.
I am answering to those people that, all good antivirus which run into Guest mode has access to Windows Registries.
Step 5:
Since I know Admin Password so is there any way of saving Admin password in our C# code and bypass popup message of asking Admin password again and again.
Is there any way that we will instruct Windows that our application will be running in Admin mode and do not ask for Admin password again and again
How Antivirus application running in Guest mode do all the operation like deleting virus from system32 folder and resetting registries after Virus attack. These antivirus application never asks for "We found a virus in System32 folder, Since I am running in Guest mode and unable to delete virus, so please enter Admin password so that I can delete virus"
I hope you understood what i mean to ask?
I want to develop a C# application which should run in any mode (Admin/Guest/Limited) and should be able to Create, Edit and Delete Windows Registries.
Note: Please do not answer this with "right click and Run As Administrator".
To the best of my knowledge, antivirus software solves this problem by running two (or more) processes: a user interface program running as the guest user, and a privileged process (usually a Windows service). The user program is not able to actually manipulate privilege-restricted resources (like secure registry hives) -- instead, it communicates with the privileged process (hopefully in some secure way) and the privileged process performs the privileged action on behalf of the user.
This is the same kind of technique by which programs ever access privileged resources, such as hardware. Your user-level process doesn't (usually) have the right to perform various hardware actions, like remapping memory in the MMU, but the OS does, and you can get the OS to do what you want by asking it to. System calls thunk into kernel mode, which is fully privileged. However, the system call interface limits the kinds of privileged actions which you can take.
I cant help but saying, NO, you cant do admin things under a guest account. And no- you cant programmatically bypass UAC.
Maybe the following 2 workarounds are interresting for you?
I believe antivirus software runs under the System account (can only be installed by an administrator). For your application, you can create a server/client architecture (both running no the same machine) where the server is installed by the administrator (as part of the whole package) and runs by default under the System account. Then you can use the client on the quest account to send commands to the server.
One other solution might be not to use the registry directly but use another underlying datastore which is accessible by a guest account and synchronize that on demand with the registry (startup and shutdown?), so you only need the admin to login once or twice during the run of your app.
I need one of my .exe to always run as administrator without UAC prompt. My program will be installed with setup, which will have for one time admin rights, and I need to perform such step in this setup that my exe will be always executed as admin without UAC prompt.
I've found 2 solutions so far:
1.
Use custom service, which will elevate the program for me.
2.
Use Task Scheduler.
Is there any other solution? Some manifest probably?
Thanks.
If it were possible to do this, then UAC would be completely ineffective. The inability of applications to elevate themselves without user consent is the fundamental principle behind UAC.
Aside from already having an elevated process that launches it (i.e. service or task scheduler), the answer is no, it can't be done.
Of course what you are supposed to do if you want to just drive UI is to use the UI access flag in your manifest (see http://msdn.microsoft.com/en-us/library/ms742884.aspx). If you install your application in a trusted location (e.g. system32) and it is signed (bleh!) then when you run your application it will be elevated to high (for an admin account).
The signing requirement makes it slightly annoying but at least it reduces slightly the attack surface as your code gets run with high integrity but not with an administrator token.