I've read several questions regarding UAC and privilege elevation but I've not found a satisfactory/comprehensive answer.
I have this scenario: on Windows 6 or above, when the user opens a configuration window I have to show the shield (BCM_SETSHIELD) on the OK button only if privilege elevation will be required to complete the task. -- I do know that in the Windows UI the shield is always visualized for "administrative tasks", even if UAC is disabled, but the customer had this specific request.
I have draft this condition in order to show the icon:
The user has not administrative rightsOR
The current process has TOKEN_ELEVATION_TYPE == TokenElevationTypeLimited
The condition #1 is simple: if the user hasn't administrative rights elevation is always required regardless of UAC. The #2 implies that the user has administrative rights, and any other value of TOKEN_ELEVATION_TYPE means that elevation is not needed.
Is really that simple? I am missing something? And - there's a documented or well-known pattern regarding this topic?
You are right. Most people just put the shield on if the button will be running elevated, but the right thing to do is to put the shield on if the button will cause elevation (ie suppress it if you are already elevated, since everything you launch will remain elevated unless you go to some trouble to launch a non elevated process, and suppress it if UAC is off.)
The good news is that if someone in the Administrators group runs (under UAC) an application non-elevated, you'll get back false when you ask if they are an admin or not. So I think you might be ok with just that one test.
I see that there is a lot of confusion about this topic and the answer from Kate here is not correct and incomplete.
Since Vista an Admin may be logged in but his processes do not run elevated automatically. An Admin has a so called "Split Token". This means that there may be processes running for the SAME admin user, and some of them run elevated and other do NOT run elevated. When an Admin runs a not elevated process, some of the privileges of his token have been removed. It is not anymore as in XP where ALL processes run either elevated or not elevated.
Install Process Explorer from www.sysinternals.com and enable the column "Integrity Level". If you see there "Medium" this process does not run elevated. If you see there "High" the process runs elevated. If the process runs with Integrity level "High" no UAC prompt is required to start another process elevated.
When UAC is completely turned off, ALL processes run "High", so no elevation is required never. UAC can be turned off under
HKLM\Software\Microsoft\Windows\CurrentVersion\Policies\System
setting the key "EnableLUA". Changing this setting requires reboot.
But there is another point that was not yet mentioned here.
In Control panel it is possible to configure "Elevate without prompting". And in this case an Admin user can start an elevated process from another not elevated process and NO UAC prompt will show up.
This setting is stored under the same registry path in the key "ConsentPromptBehaviorAdmin" for admin users.
For all non-admin users there is the key "ConsentPromptBehaviorUser" but this changes only the bahavior, but elevation cannot be turned off. Non-admins will always get an UAC prompt. (if UAC is not completely off)
How do you know if your process runs elevated:
Call OpenProcess(), then OpenProcessToken(), then GetTokenInformation(TokenElevation).
And to get the Integrity Level call GetTokenInformation(TokenIntegrityLevel) and then GetSidSubAuthority()
So if you want to show your icon only if elevation is really required you must check if your process runs elevated and additionally check these registry keys and you must know if the user is an admin or not. This involes several lines of code and I would consider to show this icon always when elevation may be required to keep it simple.
Please note that the API IsUserAnAdmin() is deprecated. It must not be used anymore since Vista. Checking if a user belongs to the administrators group is much more code now.
Related
I'm having a mystery.
I have a Windows 7 PC, I am an administrator on it. But, I have a software tool that still requires me to run it with "Run as Administrator" to work properly. Why isn't it enough just to be the admin and just run it with double-click?
The thing gets complicated - I have another PC with a user that is an administrator also, and the tool runs there just with double-click properly.
What could be the difference between the PCs? In both of them, the user is an administrator!
Thanks for any help,
This is the impact of the User Account control (UAC), which assigned 2 tokens to admin accounts and runs the shell (explorer) and all started programs by default with the filtered token which represents standard user rights. To request admin rights, you have to right click and select “Run as administrator”.
I've a app embeded with manifest *.exe.manifest. When I launch executable it shows UAC prompt every time. How can I avoid this? I have element requireAdministrator with attrubute level equal to requireAdministrator. Is that possible at all?
You are seeing the UAC elevation prompt because you asked for it. The operative word here is require. If the user isn't currently running elevated then that's always going to invoke the elevation prompt.
If you don't want that to happen then you do have to replace requireAdministrator with asInvoker. With the side-effect that your program won't run with the elevated privileges or course. And no, you cannot elevate silently, that would defeat the point of UAC. The point of UAC is not to stop you from doing something, it is to let the user know.
Is there a way to mark a .EXE to request it be run as admin? So that:
If UAC is set to runas admin with no prompt - it runs as admin.
If user cannot runas admin (reqires different login), runs as user.
If prompts, prompts user. If accepted, runs as admin.
If prompt declined, runs as user.
I know how to do this with 2 .exe programs. But I'd like to do it with one. This program enters the user's license key. In HKLM if the app has admin rights (so all users have the key). In HKCU if no admin rights.
There is no way to mark an executable so that it will continue to run without admin privilege if the user rejects the elevation prompt. However, a process can attempt to launch a second copy of itself from the same executable with elevated privileges, and either pass the work to the new process (if it launches successfully) or continue the work itself (if not).
See this answer for an example of how to elevate yourself.
You can get 1 and 2 by requesting highestAvailable instead of requireAdmin. I don't like it, though, because throughout the rest of the app you may need to test to see if you're elevated or not.
You can't get #4. If an app tries to launch, shows a UAC dialog, and the user rejects the UAC, the app does not launch. If you have just part of your application that needs elevation, you are best to move that part to a separate exe and put a manifest on that exe that requires elevation, then leave the main app not requiring it.
I used "highestAvailable" in my exe's manifest. But in standard user and UAC ON its not elevating the exe.
Is this the behavior of "highestAvailable"?
I referred this MSDN link but its not clear whether "highestavailable" will elevate the exe or not. My requirement is to elevate the exe if UAC is on.
I changed to "requireAdministrator" and my exe is getting elevated in standard user with UAC ON.
Can someone explain me in detail about the elevation behavior of these two options "highestAvailabe" and "requireAdministrator"?
highestAvailable will elevate if the current user is an administrator. Which is consistent with what you have observed. When a standard user runs the process, no UAC dialog is shown and the process runs with the standard token. When an admin user executes, the UAC consent dialog is shown and the process will then run elevated.
If your program requires admin rights to function then you need to use requireAdministrator. When a standard user starts such a process, the over-the-shoulder UAC dialog is shown. That gives the user an opportunity to ask an admin to supply their credentials.
You should only use highestAvailable if your program is capable of running with a limited functionality in case the user is not able to elevate. This is what is meant by mixed-mode in the MSDN topic linked by your question.
I need to create an NSIS installer, which runs with administrator privileges. I request these privileges with
RequestExecutionLevel admin
So far this works. But I also need to place shortcut links on the users desktop. I do NOT want to create the shortcuts for all users but only for the currently logged in user. So I use
SetShellVarContext current
in the installer sections. If the current user has admin privileges, this works. If I have a normal user, Windows (7) asks for credentials for a privileged user, which is also correct. But the installer then creates the icons on the privileged users desktop, and not on current users.
So, how can I tell NSIS, that it should create desktop icons for the current user if she has no admin privileges?
FYI, if I omit both RequestExecutionLevel and SetShellVarContext, I am also prompted for administrative rights but the installer creates icons on the current user desktop as well as for the admin user. I think this is some kind of compatibility behavior.
You are not really supposed to do this (because of this exact issue) and you are basically asking how to create a installer that is broken by design. This is not a NSIS specific problem and not even UAC specific, it has existed since runas was added in Win2000! When you elevate with runas/UAC the new process is executed as that user and with their HKCU and shell folders...
If you need "RequestExecutionLevel admin" in your script then you are doing machine level things and should therefore call "SetShellVarContext all" and install the files in $ProgramFiles and write the uninstall registration under HKLM. This is true for any version of NT, not just Vista+/UAC. (Most people forget to test as non-admin on NT4 and NT5)
If creating shortcuts for all users is such a big problem then I suggest you enable the "Don't create shortcuts" checkbox on the startmenu page so the user can decide.
If you still want to force broken behavior then you need to use this plugin. (You should be able to find plenty of topics about this plugin on the NSIS forum)