/// <summary> /// Checks whether the primary access token of the process belongs to a user account that is a member of the local Administrator group, even if it currently is not elevated. /// </summary> /// <returns> /// True if the primary access token of the process belongs to a user account that is a member of the Administrators group; false otherwise. /// </returns> public static bool IsUserInAdminGroup() { // Default token's received aren't impersonation tokens, we are looking for an impersonation token. bool isImpersonationToken = false; // Open the access token of the current process. SafeTokenHandle processToken; if ( !AdvApi32.OpenProcessToken( Process.GetCurrentProcess().Handle, (uint)(TokenAccessLevels.Query | TokenAccessLevels.Duplicate), out processToken ) ) { MarshalHelper.ThrowLastWin32ErrorException(); } // Starting from Vista linked tokens are supported which need to be checked. if ( EnvironmentHelper.VistaOrHigher ) { // Determine token type: limited, elevated, or default. int marshalSize = sizeof( AdvApi32.TokenElevationType ); var elevationTypeHandle = SafeUnmanagedMemoryHandle.FromNewlyAllocatedMemory( marshalSize ); if ( !AdvApi32.GetTokenInformation( processToken, AdvApi32.TokenInformationClass.TokenElevationType, elevationTypeHandle.DangerousGetHandle(), marshalSize, out marshalSize ) ) { MarshalHelper.ThrowLastWin32ErrorException(); } var tokenType = (AdvApi32.TokenElevationType)Marshal.ReadInt32( elevationTypeHandle.DangerousGetHandle() ); // If limited, get the linked elevated token for further check. if ( tokenType == AdvApi32.TokenElevationType.TokenElevationTypeLimited ) { // Get the linked token. marshalSize = IntPtr.Size; var linkedTokenHandle = SafeUnmanagedMemoryHandle.FromNewlyAllocatedMemory( marshalSize ); if ( !AdvApi32.GetTokenInformation( processToken, AdvApi32.TokenInformationClass.TokenLinkedToken, linkedTokenHandle.DangerousGetHandle(), marshalSize, out marshalSize ) ) { MarshalHelper.ThrowLastWin32ErrorException(); } processToken = new SafeTokenHandle( Marshal.ReadIntPtr( linkedTokenHandle.DangerousGetHandle() ) ); isImpersonationToken = true; // Linked tokens are already impersonation tokens. } } // We need an impersonation token in order to check whether it contains admin SID. if ( !isImpersonationToken ) { SafeTokenHandle impersonatedToken; if ( !AdvApi32.DuplicateToken( processToken, AdvApi32.SecurityImpersonationLevel.SecurityIdentification, out impersonatedToken ) ) { MarshalHelper.ThrowLastWin32ErrorException(); } processToken = impersonatedToken; } // Check if the token to be checked contains admin SID. var identity= new WindowsIdentity( processToken.DangerousGetHandle() ); var principal = new WindowsPrincipal( identity ); return principal.IsInRole( WindowsBuiltInRole.Administrator ); }
public extern static bool DuplicateToken( SafeTokenHandle existingTokenHandle, SecurityImpersonationLevel impersonationLevel, out SafeTokenHandle duplicateTokenHandle );
public static extern bool GetTokenInformation( SafeTokenHandle tokenHandle, TokenInformationClass tokenInformationClass, IntPtr tokenInformation, int tokenInformationLength, out int returnLength );
public static extern bool OpenProcessToken( IntPtr processHandle, UInt32 desiredAccess, out SafeTokenHandle tokenHandle );
public static extern int SHSetKnownFolderPath( ref Guid folderId, KnownFolderRetrievalFlags flags, SafeTokenHandle accessToken, string path );
public extern static bool DuplicateToken(SafeTokenHandle existingTokenHandle, SecurityImpersonationLevel impersonationLevel, out SafeTokenHandle duplicateTokenHandle);
public static extern bool GetTokenInformation(SafeTokenHandle tokenHandle, TokenInformationClass tokenInformationClass, IntPtr tokenInformation, int tokenInformationLength, out int returnLength);
public static extern bool OpenProcessToken(IntPtr processHandle, UInt32 desiredAccess, out SafeTokenHandle tokenHandle);