Detect if it works as an administrator with or without elevated privileges?

I have an application that should determine if it works with elevated privileges or not. I currently have code similar to this:

static bool IsAdministrator() { WindowsIdentity identity = WindowsIdentity.GetCurrent(); WindowsPrincipal principal = new WindowsPrincipal(identity); return principal.IsInRole (WindowsBuiltInRole.Administrator); } 

This works to determine if the user is an administrator or not, but does not work if he works as an administrator without promotion. (For example, in vshost.exe).

How can I determine if an increase is [already valid or] possible?

+62
c # windows-vista uac user-accounts
Aug 02 '09 at 23:49
source share
7 answers

Try the following:

 using Microsoft.Win32; using System; using System.Diagnostics; using System.Runtime.InteropServices; using System.Security.Principal; public static class UacHelper { private const string uacRegistryKey = "Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\System"; private const string uacRegistryValue = "EnableLUA"; private static uint STANDARD_RIGHTS_READ = 0x00020000; private static uint TOKEN_QUERY = 0x0008; private static uint TOKEN_READ = (STANDARD_RIGHTS_READ | TOKEN_QUERY); [DllImport("advapi32.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] static extern bool OpenProcessToken(IntPtr ProcessHandle, UInt32 DesiredAccess, out IntPtr TokenHandle); [DllImport("advapi32.dll", SetLastError = true)] public static extern bool GetTokenInformation(IntPtr TokenHandle, TOKEN_INFORMATION_CLASS TokenInformationClass, IntPtr TokenInformation, uint TokenInformationLength, out uint ReturnLength); public enum TOKEN_INFORMATION_CLASS { TokenUser = 1, TokenGroups, TokenPrivileges, TokenOwner, TokenPrimaryGroup, TokenDefaultDacl, TokenSource, TokenType, TokenImpersonationLevel, TokenStatistics, TokenRestrictedSids, TokenSessionId, TokenGroupsAndPrivileges, TokenSessionReference, TokenSandBoxInert, TokenAuditPolicy, TokenOrigin, TokenElevationType, TokenLinkedToken, TokenElevation, TokenHasRestrictions, TokenAccessInformation, TokenVirtualizationAllowed, TokenVirtualizationEnabled, TokenIntegrityLevel, TokenUIAccess, TokenMandatoryPolicy, TokenLogonSid, MaxTokenInfoClass } public enum TOKEN_ELEVATION_TYPE { TokenElevationTypeDefault = 1, TokenElevationTypeFull, TokenElevationTypeLimited } public static bool IsUacEnabled { get { RegistryKey uacKey = Registry.LocalMachine.OpenSubKey(uacRegistryKey, false); bool result = uacKey.GetValue(uacRegistryValue).Equals(1); return result; } } public static bool IsProcessElevated { get { if (IsUacEnabled) { IntPtr tokenHandle; if (!OpenProcessToken(Process.GetCurrentProcess().Handle, TOKEN_READ, out tokenHandle)) { throw new ApplicationException("Could not get process token. Win32 Error Code: " + Marshal.GetLastWin32Error()); } TOKEN_ELEVATION_TYPE elevationResult = TOKEN_ELEVATION_TYPE.TokenElevationTypeDefault; int elevationResultSize = Marshal.SizeOf((int)elevationResult); uint returnedSize = 0; IntPtr elevationTypePtr = Marshal.AllocHGlobal(elevationResultSize); bool success = GetTokenInformation(tokenHandle, TOKEN_INFORMATION_CLASS.TokenElevationType, elevationTypePtr, (uint)elevationResultSize, out returnedSize); if (success) { elevationResult = (TOKEN_ELEVATION_TYPE)Marshal.ReadInt32(elevationTypePtr); bool isProcessAdmin = elevationResult == TOKEN_ELEVATION_TYPE.TokenElevationTypeFull; return isProcessAdmin; } else { throw new ApplicationException("Unable to determine the current elevation."); } } else { WindowsIdentity identity = WindowsIdentity.GetCurrent(); WindowsPrincipal principal = new WindowsPrincipal(identity); bool result = principal.IsInRole(WindowsBuiltInRole.Administrator); return result; } } } } 
+40
Dec 21 '10 at 8:49
source share

(new answer six years after the question was asked)

Denial of responsibility. This is what happened with my particular OS with my settings with my specific user:

 using System.Security.Principal; // ... static bool IsElevated { get { return WindowsIdentity.GetCurrent().Owner .IsWellKnown(WellKnownSidType.BuiltinAdministratorsSid); } } 

Therefore, when I run this "Run as administrator", the get accessor property returns true . During normal operation (even if my user "is" an administrator, just without starting this particular application "as an administrator"), it returns false .

This seems a lot easier than many other answers.

I do not know if there are times when this fails.

PS! It also seems OK:

  static bool IsElevated { get { var id = WindowsIdentity.GetCurrent(); return id.Owner != id.User; } } 
+20
Aug 06 '15 at 12:53 on
source share

The CodePlex UAChelper project has code that checks the height in UserAccountControl.cpp UserAccountControl::IsUserAdmin , which checks if UAC is enabled, and then checks if the process is elevated.

 bool UserAccountControl::IsCurrentProcessElevated::get() { return GetProcessTokenElevationType() == TokenElevationTypeFull; //elevated } 

from function:

 int UserAccountControl::GetProcessTokenElevationType() { HANDLE hToken; try { if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken)) throw gcnew Win32Exception(GetLastError()); TOKEN_ELEVATION_TYPE elevationType; DWORD dwSize; if (!GetTokenInformation(hToken, TokenElevationType, &elevationType, sizeof(elevationType), &dwSize)) throw gcnew Win32Exception(GetLastError()); return elevationType; } finally { CloseHandle(hToken); } } 
+15
Aug 03 '09 at 0:05
source share

Here is a modified version of this answer to include things like proper resource allocation and handling of Domain Admins.

 public static class UacHelper { private const string uacRegistryKey = "Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\System"; private const string uacRegistryValue = "EnableLUA"; private static uint STANDARD_RIGHTS_READ = 0x00020000; private static uint TOKEN_QUERY = 0x0008; private static uint TOKEN_READ = (STANDARD_RIGHTS_READ | TOKEN_QUERY); [DllImport("advapi32.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] static extern bool OpenProcessToken(IntPtr ProcessHandle, UInt32 DesiredAccess, out IntPtr TokenHandle); [DllImport("kernel32.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] static extern bool CloseHandle(IntPtr hObject); [DllImport("advapi32.dll", SetLastError = true)] public static extern bool GetTokenInformation(IntPtr TokenHandle, TOKEN_INFORMATION_CLASS TokenInformationClass, IntPtr TokenInformation, uint TokenInformationLength, out uint ReturnLength); public enum TOKEN_INFORMATION_CLASS { TokenUser = 1, TokenGroups, TokenPrivileges, TokenOwner, TokenPrimaryGroup, TokenDefaultDacl, TokenSource, TokenType, TokenImpersonationLevel, TokenStatistics, TokenRestrictedSids, TokenSessionId, TokenGroupsAndPrivileges, TokenSessionReference, TokenSandBoxInert, TokenAuditPolicy, TokenOrigin, TokenElevationType, TokenLinkedToken, TokenElevation, TokenHasRestrictions, TokenAccessInformation, TokenVirtualizationAllowed, TokenVirtualizationEnabled, TokenIntegrityLevel, TokenUIAccess, TokenMandatoryPolicy, TokenLogonSid, MaxTokenInfoClass } public enum TOKEN_ELEVATION_TYPE { TokenElevationTypeDefault = 1, TokenElevationTypeFull, TokenElevationTypeLimited } public static bool IsUacEnabled { get { using (RegistryKey uacKey = Registry.LocalMachine.OpenSubKey(uacRegistryKey, false)) { bool result = uacKey.GetValue(uacRegistryValue).Equals(1); return result; } } } public static bool IsProcessElevated { get { if (IsUacEnabled) { IntPtr tokenHandle = IntPtr.Zero; if (!OpenProcessToken(Process.GetCurrentProcess().Handle, TOKEN_READ, out tokenHandle)) { throw new ApplicationException("Could not get process token. Win32 Error Code: " + Marshal.GetLastWin32Error()); } try { TOKEN_ELEVATION_TYPE elevationResult = TOKEN_ELEVATION_TYPE.TokenElevationTypeDefault; int elevationResultSize = Marshal.SizeOf(typeof(TOKEN_ELEVATION_TYPE)); uint returnedSize = 0; IntPtr elevationTypePtr = Marshal.AllocHGlobal(elevationResultSize); try { bool success = GetTokenInformation(tokenHandle, TOKEN_INFORMATION_CLASS.TokenElevationType, elevationTypePtr, (uint) elevationResultSize, out returnedSize); if (success) { elevationResult = (TOKEN_ELEVATION_TYPE) Marshal.ReadInt32(elevationTypePtr); bool isProcessAdmin = elevationResult == TOKEN_ELEVATION_TYPE.TokenElevationTypeFull; return isProcessAdmin; } else { throw new ApplicationException("Unable to determine the current elevation."); } } finally { if (elevationTypePtr != IntPtr.Zero) Marshal.FreeHGlobal(elevationTypePtr); } } finally { if (tokenHandle != IntPtr.Zero) CloseHandle(tokenHandle); } } else { WindowsIdentity identity = WindowsIdentity.GetCurrent(); WindowsPrincipal principal = new WindowsPrincipal(identity); bool result = principal.IsInRole(WindowsBuiltInRole.Administrator) || principal.IsInRole(0x200); //Domain Administrator return result; } } } } 
+14
Jul 05 '13 at 16:04 on
source share

In .net Framwork 4.5, I found another method that works for me. Regarding the following script, which can be found here here (in German)

  rem --- Admintest.bat --- whoami /groups | find "S-1-5-32-544" > nul if errorlevel 1 goto ende echo Benutzer %username% ist lokaler Administrator. :ende 

In C #, it looks like this:

  private bool IsAdmin() { WindowsIdentity identity = WindowsIdentity.GetCurrent(); if (identity != null) { WindowsPrincipal principal = new WindowsPrincipal(identity); List<Claim> list = new List<Claim>(principal.UserClaims); Claim c = list.Find(p => p.Value.Contains("S-1-5-32-544")); if (c != null) return true; } return false; } 

But in .net <4.5, the WindowsPrincipal class does not contain the UserClaims property UserClaims and I did not find a way to get this information.

+6
Jul 22 '14 at 12:50
source share

Using TokenElevationType will work, but if you use PInvoke CheckTokenMembership() for the SID of the administrator group, your code will also work when UAC is off, and for 2000 / XP / 2003, and will also process SIDs.

There is also a IsUserAnAdmin() function that does a CheckTokenMembership check for you, but MSDN says that it may not be forever

+5
Aug 04 '09 at 22:40
source share

I think there is one more problem. I checked the solutions you provided, and I must say that when installing Windows 7 and logging in as administrator, the check does not work. Windows never returns information that a process is running in elevated mode. So the sequence:

 if (IsUacEnabled) return IsProcessInElevatedMode(); return IsUserAdmin(); 

does not return true when registering as an administrator, but the process has all the privileges to perform system operations (for example, stopping system services). Working sequence:

 if (IsUserAdmin()) return true; if (IsUacEnabled) return IsProcessInElevatedMode(); return false; 

You must first check if the process is running in the admin context. Additional Information:

 IsUacEnabled() - checks if the UAC has been enabled in the system (Windows) IsProcessInElevatedMode() - checks if the process is run in an elevated mode IsUserAdmin() - checks if the current user has an Administrtor role 

All of these methods are described in previous posts.

0
Jan 14 '15 at 15:08
source share



All Articles