/// <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));
        }
Esempio n. 2
0
        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);
                }
            }
        }