When a user with administrator privileges signs in, the User Account Control (UAC) feature signs in the administrator with a so-called “split token”, in which the user operates in Clark Kent mode: Although they have latent administrator privileges, the administrative powers in the token are disabled. To exercise those administrative powers, the user must elevate their token.
A customer wanted to discourage users from running their program elevated, but they also didn’t want to scold users who were running with UAC disabled (such as on Windows Server), since those users had no opportunity to de-elevate.
The way to inspect whether your token is split, and if so whether you have the non-administrator (“limited”) version or the administrator (“full”) version is to ask for the token’s elevation type.
 | Standard user | Administrative user |
---|---|---|
UAC disabled | TokenElevationTypeDefault | TokenElevationTypeDefault |
UAC enabled, not elevated | TokenElevationTypeDefault | TokenElevationTypeLimited |
UAC enabled, elevated | N/A | TokenElevationTypeFull |
Non-administrative users cannot split their token (there being no administrator privileges to split out), and administrative users cannot split their tokens if UAC is disabled.
If you are looking for “users who manually elevated”, then you can consult the table above and see that a token elevation type of Full
exactly identifies the “Administrative user, UAC enabled, elevated” box.
bool IsManuallyElevatedViaUAC() { TOKEN_ELEVATION_TYPE type; DWORD actual; if (!GetTokenInformation( GetCurrentProcessToken(), TokenElevationType, &type, sizeof(type), &actual)) { // insert your favorite error handling here throw_error(GetLastError()); } return type == TokenElevationTypeFull; }
We learned about GetÂCurrentÂProcessÂToken()
a little while ago. This is a convenient pseudo-handle that refers to the current process. We ask for the current process’s token’s elevation type, and if that is Full
, then we are in that box in the bottom right corner.
The helpers in the token_helpers.h
header in the Windows Implementation Library (wil) turn this into a one-line function.
bool IsManuallyElevatedViaUAC() { return wil::get_token_information<TOKEN_ELEVATION_TYPE>( GetCurrentProcessToken()) == TokenElevationTypeFull; }
Thank you very much for this. I would like to know however, how to boot as System/NT Authority.
The same privilege level granted during windows setup and Audit mode.
Thanks in advance.
The title of this post is slightly misleading because this code checks how the token was born, not if it’s elevated. You can make a Full elevated token with a lower integrity level. To actually check for elevation, you need TokenIntegrityLevel >= SECURITY_MANDATORY_HIGH_RID.
What's more, if what you really want to know is whether the token has administrative privileges, checking the integrity level doesn't work either. :-)
https://stackoverflow.com/a/30970434/886887
Which I guess just goes to show that you need to know why you're asking in order to know what the right question is. (In this scenario, "A customer wanted to discourage users from running their program elevated", I'd argue that you probably don't need to worry too much about the...
The other case is when you are signed in as a standard user but elevated using explicit administrative credentials. I’m not sure what the token elevation type is in this case, it might not be as easy to detect.
My guess is that it’s TokenElevationTypeDefault if UAC disabled, and TokenElevationTypeFull if UAC enabled. That is, the same as when the administrator is elevated (or always-elevated).
I did some testing and was unable to elevate when UAC was turned off (i.e., with the local group policy security option "User Account Control: Run all administrators in Admin Approval Mode" set to "Disabled").
With UAC turned on, logged in as a standard user, and elevating to the local administrator account, you get TokenElevationTypeDefault if "User Account Control: Admin Approval Mode for the Built-in Administrator account" is disabled or TokenElevationTypeFull if it is enabled.
If I...
Re: Can you elevate with UAC disabled?
Yes. I have UAC disabled on my daily driver computer and use 2 separate accounts and elevate by entering the credential. If the policy is set to deny elevation for limited users, there might be a problem, but I would expect one could always “runasuser” (Run as different user).
If UAC is disabled, do you even get the opportunity to elevate?