Beispiel #1
0
        /// <summary>
        /// The function checks whether the object associated with the access token belongs
        /// to a user account that is a member of the local Administrators group, even if
        /// it currently is not elevated.
        /// </summary>
        /// <param name="userToken">The user token.</param>
        /// <returns>
        /// Returns true if the object associated with the access token belongs to user
        /// account that is a member of the local Administrators group. Returns false
        /// if the token does not.
        /// </returns>
        /// <exception cref="Win32Exception">
        /// </exception>
        /// <exception cref="System.ComponentModel.Win32Exception">When any native Windows API call fails, the function throws a Win32Exception with the last error code.</exception>
        public static bool IsUserInAdminGroup(SafeTokenHandle userToken)
        {
            // Determine whether system is running Windows Vista or later operating
            // systems (major version >= 6) because they support linked tokens, but
            // previous versions (major version < 6) do not.
            var version = Environment.OSVersion.Version;

            if ((version != null) && (version.Major >= 6))
            {
                // Running Windows Vista or later (major version >= 6).
                // Determine token type: limited, elevated, or default.

                // Allocate a buffer for the elevation type information.
                using var pElevationType = new SafeNativeMemory(sizeof(TOKEN_ELEVATION_TYPE));
                // Retrieve token elevation type information.
                if (!NativeMethods.GetTokenInformation(userToken, TOKEN_INFORMATION_CLASS.TokenElevationType, pElevationType))
                {
                    throw new Win32Exception();
                }

                // Marshal the TOKEN_ELEVATION_TYPE enum from native to .NET.
                var elevType = pElevationType.ReadInt32().ToEnum <TOKEN_ELEVATION_TYPE>();

                // If limited, get the linked elevated token for further check.
                if (elevType == TOKEN_ELEVATION_TYPE.TokenElevationTypeLimited)
                {
                    // Allocate a buffer for the linked token.
                    using var pLinkedToken = new SafeNativeMemory(IntPtr.Size);
                    // Get the linked token.
                    if (!NativeMethods.GetTokenInformation(userToken, TOKEN_INFORMATION_CLASS.TokenLinkedToken, pLinkedToken))
                    {
                        throw new Win32Exception();
                    }

                    // Marshal the linked token value from native to .NET.
                    var hLinkedToken = pLinkedToken.ReadIntPtr();
                    using var linkedToken = new SafeTokenHandle(hLinkedToken);
                    return(IsAdministrator(linkedToken));
                }
            }

            // CheckTokenMembership requires an impersonation token. If we just got
            // a linked token, it already is an impersonation token.  If we did not
            // get a linked token, duplicate the original into an impersonation
            // token for CheckTokenMembership.

            if (!NativeMethods.DuplicateToken(userToken, SECURITY_IMPERSONATION_LEVEL.SecurityIdentification, out var phTokenToCheck))
            {
                throw new Win32Exception();
            }

            using var hTokenToCheck = new SafeTokenHandle(phTokenToCheck);
            // Check if the token to be checked contains admin SID.
            return(IsAdministrator(hTokenToCheck));
        }
        /// <summary>
        /// The function checks whether the object associated with the access token belongs
        /// to a user account that is a member of the local Administrators group, even if
        /// it currently is not elevated.
        /// </summary>
        /// <param name="userToken">The user token.</param>
        /// <returns>
        /// Returns true if the object associated with the access token belongs to user
        /// account that is a member of the local Administrators group. Returns false
        /// if the token does not.
        /// </returns>
        /// <exception cref="Win32Exception">
        /// </exception>
        /// <exception cref="System.ComponentModel.Win32Exception">When any native Windows API call fails, the function throws a Win32Exception with the last error code.</exception>
        public static bool IsUserInAdminGroup([NotNull] SafeTokenHandle userToken)
        {
            Contract.Requires(userToken != null);

            // Determine whether system is running Windows Vista or later operating 
            // systems (major version >= 6) because they support linked tokens, but 
            // previous versions (major version < 6) do not.
            var version = Environment.OSVersion.Version;
            
            if ((version != null) && (version.Major >= 6))
            {
                // Running Windows Vista or later (major version >= 6). 
                // Determine token type: limited, elevated, or default. 

                // Allocate a buffer for the elevation type information.
                using (var pElevationType = new SafeNativeMemory(sizeof(TOKEN_ELEVATION_TYPE)))
                {
                    // Retrieve token elevation type information.
                    if (!NativeMethods.GetTokenInformation(userToken, TOKEN_INFORMATION_CLASS.TokenElevationType, pElevationType))
                    {
                        throw new Win32Exception();
                    }

                    // Marshal the TOKEN_ELEVATION_TYPE enum from native to .NET.
                    var elevType = pElevationType.ReadInt32().ToEnum<TOKEN_ELEVATION_TYPE>();

                    // If limited, get the linked elevated token for further check.
                    if (elevType == TOKEN_ELEVATION_TYPE.TokenElevationTypeLimited)
                    {
                        // Allocate a buffer for the linked token.
                        using (var pLinkedToken = new SafeNativeMemory(IntPtr.Size))
                        {
                            // Get the linked token.
                            if (!NativeMethods.GetTokenInformation(userToken, TOKEN_INFORMATION_CLASS.TokenLinkedToken, pLinkedToken))
                            {
                                throw new Win32Exception();
                            }

                            // Marshal the linked token value from native to .NET.
                            var hLinkedToken = pLinkedToken.ReadIntPtr();
                            using (var linkedToken = new SafeTokenHandle(hLinkedToken))
                            {
                                return IsAdministrator(linkedToken);
                            }
                        }
                    }
                }
            }

            // CheckTokenMembership requires an impersonation token. If we just got 
            // a linked token, it already is an impersonation token.  If we did not 
            // get a linked token, duplicate the original into an impersonation 
            // token for CheckTokenMembership.
            IntPtr phTokenToCheck;

            if (!NativeMethods.DuplicateToken(userToken, SECURITY_IMPERSONATION_LEVEL.SecurityIdentification, out phTokenToCheck))
            {
                throw new Win32Exception();
            }

            using (var hTokenToCheck = new SafeTokenHandle(phTokenToCheck))
            {
                // Check if the token to be checked contains admin SID.
                return IsAdministrator(hTokenToCheck);
            }
        }