/// <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 static string GetUserSidFromSessionId(UInt32 sessionId) // Gets the unique Security Identifier (SID) // of the User logged on to 'sessionId' { IntPtr token = (IntPtr)0; IntPtr tokenInf = IntPtr.Zero; uint tokenInfLen = 0; IntPtr szSid = IntPtr.Zero; string sid; try { AcquireSystemPrivilege(AdvApi32.SE_TCB_NAME); Trace.WriteLine("Using session id " + sessionId.ToString()); if (!WtsApi32.WTSQueryUserToken(sessionId, out token)) { Win32Error.Set("WTSQueryUserToken"); throw new Exception(Win32Error.GetFullErrMsg()); } // Get tokenInfLen AdvApi32.GetTokenInformation( token, AdvApi32.TOKEN_INFORMATION_CLASS.TokenUser, tokenInf, tokenInfLen, out tokenInfLen ); Win32Error.Set("GetTokenInformation"); if (Win32Error.GetErrorNo() != WinError.ERROR_INSUFFICIENT_BUFFER) { throw new Exception(Win32Error.GetFullErrMsg()); } tokenInf = Marshal.AllocHGlobal((int)tokenInfLen); if (!AdvApi32.GetTokenInformation( token, AdvApi32.TOKEN_INFORMATION_CLASS.TokenUser, tokenInf, tokenInfLen, out tokenInfLen)) { Win32Error.Set("GetTokenInformation"); throw new Exception(Win32Error.GetFullErrMsg()); } AdvApi32.TOKEN_USER tokenUser = (AdvApi32.TOKEN_USER)Marshal.PtrToStructure( tokenInf, typeof(AdvApi32.TOKEN_USER) ); if (!AdvApi32.ConvertSidToStringSid( tokenUser.User.Sid, out szSid)) { Win32Error.Set("ConvertSidToStringSid"); throw new Exception(Win32Error.GetFullErrMsg()); } sid = Marshal.PtrToStringAuto(szSid); return(sid); } finally { if (szSid != IntPtr.Zero) { Kernel32.LocalFree(szSid); } if (tokenInf != IntPtr.Zero) { Marshal.FreeHGlobal(tokenInf); } if (token != IntPtr.Zero) { Kernel32.CloseHandle(token); } } }