Privilege.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / cdf / src / WCF / IdentityModel / System / IdentityModel / Privilege.cs / 1305376 / Privilege.cs

                            //------------------------------------------------------------------------------ 
// Copyright (c) Microsoft Corporation.  All rights reserved.
//-----------------------------------------------------------------------------

namespace System.IdentityModel 
{
    using System.Collections.Generic; 
    using System.ComponentModel; 
    using System.Runtime.CompilerServices;
    using System.Runtime.ConstrainedExecution; 
    using System.Runtime.InteropServices;
    using System.Security.AccessControl;
    using System.Security.Principal;
    using System.ServiceModel.Diagnostics; 
    using System.Runtime.Versioning;
 
    class Privilege 
    {
        static Dictionary luids = new Dictionary(); 
        public const string SeAuditPrivilege = "SeAuditPrivilege";
        public const string SeTcbPrivilege = "SeTcbPrivilege";

        const uint SE_PRIVILEGE_DISABLED = 0x00000000; 
        const uint SE_PRIVILEGE_ENABLED_BY_DEFAULT = 0x00000001;
        const uint SE_PRIVILEGE_ENABLED = 0x00000002; 
        const uint SE_PRIVILEGE_USED_FOR_ACCESS = 0x80000000; 
        const int ERROR_SUCCESS = 0x0;
        const int ERROR_NO_TOKEN = 0x3F0; 
        const int ERROR_NOT_ALL_ASSIGNED = 0x514;

        string privilege;
        LUID luid; 
        bool needToRevert = false;
        bool initialEnabled = false; 
        bool isImpersonating = false; 
        SafeCloseHandle threadToken = null;
 
        public Privilege(string privilege)
        {
            this.privilege = privilege;
            this.luid = LuidFromPrivilege(privilege); 
        }
 
        public void Enable() 
        {
            // Note: AdjustTokenPrivileges should not try to adjust if the token is 
            // Primary token (process).  Duplicate the process token (impersonation) and
            // then set token to current thread  and unsetting (RevertToSelf) later.
            DiagnosticUtility.DebugAssert(this.threadToken == null, "");
            this.threadToken = GetThreadToken(); 
            EnableTokenPrivilege(this.threadToken);
        } 
 
        // Have to run in CER
        [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] 
        public int Revert()
        {
            if (!this.isImpersonating)
            { 
                if (this.needToRevert && !this.initialEnabled)
                { 
                    TOKEN_PRIVILEGE newState; 
                    newState.PrivilegeCount = 1;
                    newState.Privilege.Luid = this.luid; 
                    newState.Privilege.Attributes = SE_PRIVILEGE_DISABLED;

                    TOKEN_PRIVILEGE previousState;
                    uint previousSize = 0; 

                    if (!NativeMethods.AdjustTokenPrivileges( 
                                      this.threadToken, 
                                      false,
                                      ref newState, 
                                      TOKEN_PRIVILEGE.Size,
                                      out previousState,
                                      out previousSize))
                    { 
                        return Marshal.GetLastWin32Error();
                    } 
                } 
                this.needToRevert = false;
            } 
            else
            {
                if (!NativeMethods.RevertToSelf())
                { 
                    return Marshal.GetLastWin32Error();
                } 
                this.isImpersonating = false; 
            }
 
            if (this.threadToken != null)
            {
                this.threadToken.Close();
                this.threadToken = null; 
            }
 
            return ERROR_SUCCESS; 
        }
 
        [ResourceExposure(ResourceScope.None)]
        [ResourceConsumption( ResourceScope.Process, ResourceScope.Process )]
        SafeCloseHandle GetThreadToken()
        { 
            //
            // Open the thread token; if there is no thread token, get one from 
            // the process token by impersonating self. 
            //
            SafeCloseHandle threadToken; 
            if (!NativeMethods.OpenThreadToken(
                            NativeMethods.GetCurrentThread(),
                            TokenAccessLevels.Query | TokenAccessLevels.AdjustPrivileges,
                            true, 
                            out threadToken))
            { 
                int error = Marshal.GetLastWin32Error(); 
                Utility.CloseInvalidOutSafeHandle(threadToken);
                if (error != ERROR_NO_TOKEN) 
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(error));
                }
                else 
                {
                    SafeCloseHandle processToken; 
                    if (!NativeMethods.OpenProcessToken( 
                                    NativeMethods.GetCurrentProcess(),
                                    TokenAccessLevels.Duplicate, 
                                    out processToken))
                    {
                        error = Marshal.GetLastWin32Error();
                        Utility.CloseInvalidOutSafeHandle(processToken); 
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(error));
                    } 
 
                    try
                    { 
                        if (!NativeMethods.DuplicateTokenEx(
                                            processToken,
                                            TokenAccessLevels.Impersonate | TokenAccessLevels.Query | TokenAccessLevels.AdjustPrivileges,
                                            IntPtr.Zero, 
                                            SECURITY_IMPERSONATION_LEVEL.Impersonation,
                                            TokenType.TokenImpersonation, 
                                            out threadToken)) 
                        {
                            error = Marshal.GetLastWin32Error(); 
                            Utility.CloseInvalidOutSafeHandle(threadToken);
                            throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(error));
                        }
 
                        SetThreadToken(threadToken);
                    } 
                    finally 
                    {
                        processToken.Close(); 
                    }
                }
            }
            return threadToken; 
        }
 
        void EnableTokenPrivilege(SafeCloseHandle threadToken) 
        {
            DiagnosticUtility.DebugAssert(!this.needToRevert, ""); 
            TOKEN_PRIVILEGE newState;
            newState.PrivilegeCount = 1;
            newState.Privilege.Luid = this.luid;
            newState.Privilege.Attributes = SE_PRIVILEGE_ENABLED; 

            TOKEN_PRIVILEGE previousState; 
            uint previousSize = 0; 
            bool success = false;
            int error = 0; 

            // CER
            RuntimeHelpers.PrepareConstrainedRegions();
            try 
            {
            } 
            finally 
            {
                success = NativeMethods.AdjustTokenPrivileges( 
                                  threadToken,
                                  false,
                                  ref newState,
                                  TOKEN_PRIVILEGE.Size, 
                                  out previousState,
                                  out previousSize); 
 
                error = Marshal.GetLastWin32Error();
                if (success && error == ERROR_SUCCESS) 
                {
                    this.initialEnabled = (0 != (previousState.Privilege.Attributes & SE_PRIVILEGE_ENABLED));
                    this.needToRevert = true;
                } 
            }
 
            if (error == ERROR_NOT_ALL_ASSIGNED) 
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new PrivilegeNotHeldException(this.privilege)); 
            }
            else if (!success)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(error)); 
            }
        } 
 
        void SetThreadToken(SafeCloseHandle threadToken)
        { 
            DiagnosticUtility.DebugAssert(!this.isImpersonating, "");
            int error = 0;
            // CER
            RuntimeHelpers.PrepareConstrainedRegions(); 
            try
            { 
            } 
            finally
            { 
                if (!NativeMethods.SetThreadToken(IntPtr.Zero, threadToken))
                {
                    error = Marshal.GetLastWin32Error();
                } 
                else
                { 
                    this.isImpersonating = true; 
                }
            } 
            if (!this.isImpersonating)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(error));
            } 
        }
 
        static LUID LuidFromPrivilege(string privilege) 
        {
            LUID luid; 
            lock (luids)
            {
                if (luids.TryGetValue(privilege, out luid))
                { 
                    return luid;
                } 
            } 

            if (!NativeMethods.LookupPrivilegeValueW(null, privilege, out luid)) 
            {
                int error = Marshal.GetLastWin32Error();
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(error));
            } 

            lock (luids) 
            { 
                if (!luids.ContainsKey(privilege))
                { 
                    luids[privilege] = luid;
                }
            }
 
            return luid;
        } 
    } 
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
//------------------------------------------------------------------------------ 
// Copyright (c) Microsoft Corporation.  All rights reserved.
//-----------------------------------------------------------------------------

namespace System.IdentityModel 
{
    using System.Collections.Generic; 
    using System.ComponentModel; 
    using System.Runtime.CompilerServices;
    using System.Runtime.ConstrainedExecution; 
    using System.Runtime.InteropServices;
    using System.Security.AccessControl;
    using System.Security.Principal;
    using System.ServiceModel.Diagnostics; 
    using System.Runtime.Versioning;
 
    class Privilege 
    {
        static Dictionary luids = new Dictionary(); 
        public const string SeAuditPrivilege = "SeAuditPrivilege";
        public const string SeTcbPrivilege = "SeTcbPrivilege";

        const uint SE_PRIVILEGE_DISABLED = 0x00000000; 
        const uint SE_PRIVILEGE_ENABLED_BY_DEFAULT = 0x00000001;
        const uint SE_PRIVILEGE_ENABLED = 0x00000002; 
        const uint SE_PRIVILEGE_USED_FOR_ACCESS = 0x80000000; 
        const int ERROR_SUCCESS = 0x0;
        const int ERROR_NO_TOKEN = 0x3F0; 
        const int ERROR_NOT_ALL_ASSIGNED = 0x514;

        string privilege;
        LUID luid; 
        bool needToRevert = false;
        bool initialEnabled = false; 
        bool isImpersonating = false; 
        SafeCloseHandle threadToken = null;
 
        public Privilege(string privilege)
        {
            this.privilege = privilege;
            this.luid = LuidFromPrivilege(privilege); 
        }
 
        public void Enable() 
        {
            // Note: AdjustTokenPrivileges should not try to adjust if the token is 
            // Primary token (process).  Duplicate the process token (impersonation) and
            // then set token to current thread  and unsetting (RevertToSelf) later.
            DiagnosticUtility.DebugAssert(this.threadToken == null, "");
            this.threadToken = GetThreadToken(); 
            EnableTokenPrivilege(this.threadToken);
        } 
 
        // Have to run in CER
        [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] 
        public int Revert()
        {
            if (!this.isImpersonating)
            { 
                if (this.needToRevert && !this.initialEnabled)
                { 
                    TOKEN_PRIVILEGE newState; 
                    newState.PrivilegeCount = 1;
                    newState.Privilege.Luid = this.luid; 
                    newState.Privilege.Attributes = SE_PRIVILEGE_DISABLED;

                    TOKEN_PRIVILEGE previousState;
                    uint previousSize = 0; 

                    if (!NativeMethods.AdjustTokenPrivileges( 
                                      this.threadToken, 
                                      false,
                                      ref newState, 
                                      TOKEN_PRIVILEGE.Size,
                                      out previousState,
                                      out previousSize))
                    { 
                        return Marshal.GetLastWin32Error();
                    } 
                } 
                this.needToRevert = false;
            } 
            else
            {
                if (!NativeMethods.RevertToSelf())
                { 
                    return Marshal.GetLastWin32Error();
                } 
                this.isImpersonating = false; 
            }
 
            if (this.threadToken != null)
            {
                this.threadToken.Close();
                this.threadToken = null; 
            }
 
            return ERROR_SUCCESS; 
        }
 
        [ResourceExposure(ResourceScope.None)]
        [ResourceConsumption( ResourceScope.Process, ResourceScope.Process )]
        SafeCloseHandle GetThreadToken()
        { 
            //
            // Open the thread token; if there is no thread token, get one from 
            // the process token by impersonating self. 
            //
            SafeCloseHandle threadToken; 
            if (!NativeMethods.OpenThreadToken(
                            NativeMethods.GetCurrentThread(),
                            TokenAccessLevels.Query | TokenAccessLevels.AdjustPrivileges,
                            true, 
                            out threadToken))
            { 
                int error = Marshal.GetLastWin32Error(); 
                Utility.CloseInvalidOutSafeHandle(threadToken);
                if (error != ERROR_NO_TOKEN) 
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(error));
                }
                else 
                {
                    SafeCloseHandle processToken; 
                    if (!NativeMethods.OpenProcessToken( 
                                    NativeMethods.GetCurrentProcess(),
                                    TokenAccessLevels.Duplicate, 
                                    out processToken))
                    {
                        error = Marshal.GetLastWin32Error();
                        Utility.CloseInvalidOutSafeHandle(processToken); 
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(error));
                    } 
 
                    try
                    { 
                        if (!NativeMethods.DuplicateTokenEx(
                                            processToken,
                                            TokenAccessLevels.Impersonate | TokenAccessLevels.Query | TokenAccessLevels.AdjustPrivileges,
                                            IntPtr.Zero, 
                                            SECURITY_IMPERSONATION_LEVEL.Impersonation,
                                            TokenType.TokenImpersonation, 
                                            out threadToken)) 
                        {
                            error = Marshal.GetLastWin32Error(); 
                            Utility.CloseInvalidOutSafeHandle(threadToken);
                            throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(error));
                        }
 
                        SetThreadToken(threadToken);
                    } 
                    finally 
                    {
                        processToken.Close(); 
                    }
                }
            }
            return threadToken; 
        }
 
        void EnableTokenPrivilege(SafeCloseHandle threadToken) 
        {
            DiagnosticUtility.DebugAssert(!this.needToRevert, ""); 
            TOKEN_PRIVILEGE newState;
            newState.PrivilegeCount = 1;
            newState.Privilege.Luid = this.luid;
            newState.Privilege.Attributes = SE_PRIVILEGE_ENABLED; 

            TOKEN_PRIVILEGE previousState; 
            uint previousSize = 0; 
            bool success = false;
            int error = 0; 

            // CER
            RuntimeHelpers.PrepareConstrainedRegions();
            try 
            {
            } 
            finally 
            {
                success = NativeMethods.AdjustTokenPrivileges( 
                                  threadToken,
                                  false,
                                  ref newState,
                                  TOKEN_PRIVILEGE.Size, 
                                  out previousState,
                                  out previousSize); 
 
                error = Marshal.GetLastWin32Error();
                if (success && error == ERROR_SUCCESS) 
                {
                    this.initialEnabled = (0 != (previousState.Privilege.Attributes & SE_PRIVILEGE_ENABLED));
                    this.needToRevert = true;
                } 
            }
 
            if (error == ERROR_NOT_ALL_ASSIGNED) 
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new PrivilegeNotHeldException(this.privilege)); 
            }
            else if (!success)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(error)); 
            }
        } 
 
        void SetThreadToken(SafeCloseHandle threadToken)
        { 
            DiagnosticUtility.DebugAssert(!this.isImpersonating, "");
            int error = 0;
            // CER
            RuntimeHelpers.PrepareConstrainedRegions(); 
            try
            { 
            } 
            finally
            { 
                if (!NativeMethods.SetThreadToken(IntPtr.Zero, threadToken))
                {
                    error = Marshal.GetLastWin32Error();
                } 
                else
                { 
                    this.isImpersonating = true; 
                }
            } 
            if (!this.isImpersonating)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(error));
            } 
        }
 
        static LUID LuidFromPrivilege(string privilege) 
        {
            LUID luid; 
            lock (luids)
            {
                if (luids.TryGetValue(privilege, out luid))
                { 
                    return luid;
                } 
            } 

            if (!NativeMethods.LookupPrivilegeValueW(null, privilege, out luid)) 
            {
                int error = Marshal.GetLastWin32Error();
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(error));
            } 

            lock (luids) 
            { 
                if (!luids.ContainsKey(privilege))
                { 
                    luids[privilege] = luid;
                }
            }
 
            return luid;
        } 
    } 
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.

                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK