Beispiel #1
0
 public static extern bool DuplicateToken(SafeTokenHandle ExistingTokenHandle, SecurityImpersonationLevel ImpersonationLevel,
     out SafeTokenHandle DuplicateTokenHandle);
Beispiel #2
0
 public static extern bool GetTokenInformation(SafeTokenHandle hToken, TokenInformationClass tokenInfoClass, IntPtr pTokenInfo, Int32 tokenInfoLength,
     out Int32 returnLength);
Beispiel #3
0
 public static extern bool OpenProcessToken(IntPtr hProcess, UInt32 desiredAccess, out SafeTokenHandle hToken);
Beispiel #4
0
        /// <summary>
        /// The function checks whether the primary access token of the process belongs 
        /// to user account that is a member of the local Administrators group, even if 
        /// it currently is not elevated.
        /// </summary>
        /// <returns>
        /// Returns true if the primary access token of the process belongs to user 
        /// account that is a member of the local Administrators group. Returns false 
        /// if the token does not.
        /// </returns>
        /// <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()
        {
            bool fInAdminGroup = false;
            SafeTokenHandle hToken = null;
            SafeTokenHandle hTokenToCheck = null;
            IntPtr pElevationType = IntPtr.Zero;
            IntPtr pLinkedToken = IntPtr.Zero;
            int cbSize = 0;

            try {
                // Open the access token of the current process for query and duplicate.
                if (!Advapi32.OpenProcessToken(Process.GetCurrentProcess().Handle,
                    Advapi32.TOKEN_QUERY | Advapi32.TOKEN_DUPLICATE, out hToken)) {
                    throw new Win32Exception(Marshal.GetLastWin32Error());
                }

                // 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.
                if (Environment.OSVersion.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.
                    //cbSize = sizeof(TOKEN_ELEVATION_TYPE); // TODO: is this ok?
                    cbSize = 8;
                    pElevationType = Marshal.AllocHGlobal(cbSize);
                    if (pElevationType == IntPtr.Zero) {
                        throw new Win32Exception(Marshal.GetLastWin32Error());
                    }

                    // Retrieve token elevation type information.
                    if (!Advapi32.GetTokenInformation(hToken,
                        TokenInformationClass.TokenElevationType, pElevationType,
                        cbSize, out cbSize)) {
                        throw new Win32Exception(Marshal.GetLastWin32Error());
                    }

                    // Marshal the TOKEN_ELEVATION_TYPE enum from native to .NET.
                    TokenElevationType elevType = (TokenElevationType)
                        Marshal.ReadInt32(pElevationType);

                    // If limited, get the linked elevated token for further check.
                    if (elevType == TokenElevationType.TokenElevationTypeLimited) {
                        // Allocate a buffer for the linked token.
                        cbSize = IntPtr.Size;
                        pLinkedToken = Marshal.AllocHGlobal(cbSize);
                        if (pLinkedToken == IntPtr.Zero) {
                            throw new Win32Exception(Marshal.GetLastWin32Error());
                        }

                        // Get the linked token.
                        if (!Advapi32.GetTokenInformation(hToken,
                            TokenInformationClass.TokenLinkedToken, pLinkedToken,
                            cbSize, out cbSize)) {
                            throw new Win32Exception(Marshal.GetLastWin32Error());
                        }

                        // Marshal the linked token value from native to .NET.
                        IntPtr hLinkedToken = Marshal.ReadIntPtr(pLinkedToken);
                        hTokenToCheck = new SafeTokenHandle(hLinkedToken);
                    }
                }

                // 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 (hTokenToCheck == null) {
                    if (!Advapi32.DuplicateToken(hToken,
                        SecurityImpersonationLevel.SecurityIdentification,
                        out hTokenToCheck)) {
                        throw new Win32Exception(Marshal.GetLastWin32Error());
                    }
                }

                // Check if the token to be checked contains admin SID.
                WindowsIdentity id = new WindowsIdentity(hTokenToCheck.DangerousGetHandle());
                WindowsPrincipal principal = new WindowsPrincipal(id);
                fInAdminGroup = principal.IsInRole(WindowsBuiltInRole.Administrator);
            }
            finally {
                // Centralized cleanup for all allocated resources.
                if (hToken != null) {
                    hToken.Close();
                    hToken = null;
                }
                if (hTokenToCheck != null) {
                    hTokenToCheck.Close();
                    hTokenToCheck = null;
                }
                if (pElevationType != IntPtr.Zero) {
                    Marshal.FreeHGlobal(pElevationType);
                    pElevationType = IntPtr.Zero;
                }
                if (pLinkedToken != IntPtr.Zero) {
                    Marshal.FreeHGlobal(pLinkedToken);
                    pLinkedToken = IntPtr.Zero;
                }
            }

            return fInAdminGroup;
        }