Example #1
0
        //      [SecurityPermission( SecurityAction.Demand, TogglePrivileges=true )]
        public void Revert()
        {
            int error = 0;

            if (!this.currentThread.Equals(Thread.CurrentThread))
            {
                throw new InvalidOperationException(SR.InvalidOperation_MustBeSameThread);
            }

            if (!this.NeedToRevert)
            {
                return;
            }

            //
            // This code must be eagerly prepared and non-interruptible.
            //

            try
            {
                //
                // The payload is entirely in the finally block
                // This is how we ensure that the code will not be
                // interrupted by catastrophic exceptions
                //
            }
            finally
            {
                bool success = true;

                try
                {
                    //
                    // Only call AdjustTokenPrivileges if we're not going to be reverting to self,
                    // on this Revert, since doing the latter obliterates the thread token anyway
                    //

                    if (this.stateWasChanged &&
                        (this.tlsContents.ReferenceCountValue > 1 ||
                         !this.tlsContents.IsImpersonating))
                    {
                        Interop.mincore.LUID_AND_ATTRIBUTES luidAndAttrs = new Interop.mincore.LUID_AND_ATTRIBUTES();
                        luidAndAttrs.Luid       = this.luid;
                        luidAndAttrs.Attributes = (this.initialState ? Interop.mincore.SEPrivileges.SE_PRIVILEGE_ENABLED : Interop.mincore.SEPrivileges.SE_PRIVILEGE_DISABLED);

                        Interop.mincore.TOKEN_PRIVILEGE newState = new Interop.mincore.TOKEN_PRIVILEGE();
                        newState.PrivilegeCount = 1;
                        newState.Privileges[0]  = luidAndAttrs;

                        Interop.mincore.TOKEN_PRIVILEGE previousState = new Interop.mincore.TOKEN_PRIVILEGE();
                        uint previousSize = 0;

                        if (false == Interop.mincore.AdjustTokenPrivileges(
                                this.tlsContents.ThreadHandle,
                                false,
                                ref newState,
                                (uint)Marshal.SizeOf(previousState),
                                ref previousState,
                                ref previousSize))
                        {
                            error   = Marshal.GetLastWin32Error();
                            success = false;
                        }
                    }
                }
                finally
                {
                    if (success)
                    {
                        this.Reset();
                    }
                }
            }

            if (error == Interop.mincore.Errors.ERROR_NOT_ENOUGH_MEMORY)
            {
                throw new OutOfMemoryException();
            }
            else if (error == Interop.mincore.Errors.ERROR_ACCESS_DENIED)
            {
                throw new UnauthorizedAccessException();
            }
            else if (error != 0)
            {
                System.Diagnostics.Debug.Assert(false, string.Format(CultureInfo.InvariantCulture, "AdjustTokenPrivileges() failed with unrecognized error code {0}", error));
                throw new InvalidOperationException();
            }
        }
Example #2
0
        //      [SecurityPermission( SecurityAction.Demand, TogglePrivileges=true )]
        public void Revert()
        {
            int error = 0;

            if (!this.currentThread.Equals(Thread.CurrentThread))
            {
                throw new InvalidOperationException(SR.InvalidOperation_MustBeSameThread);
            }

            if (!this.NeedToRevert)
            {
                return;
            }

            //
            // This code must be eagerly prepared and non-interruptible.
            //

            try
            {
                //
                // The payload is entirely in the finally block
                // This is how we ensure that the code will not be
                // interrupted by catastrophic exceptions
                //
            }
            finally
            {
                bool success = true;

                try
                {
                    //
                    // Only call AdjustTokenPrivileges if we're not going to be reverting to self,
                    // on this Revert, since doing the latter obliterates the thread token anyway
                    //

                    if (this.stateWasChanged &&
                        (this.tlsContents.ReferenceCountValue > 1 ||
                          !this.tlsContents.IsImpersonating))
                    {
                        Interop.mincore.LUID_AND_ATTRIBUTES luidAndAttrs = new Interop.mincore.LUID_AND_ATTRIBUTES();
                        luidAndAttrs.Luid = this.luid;
                        luidAndAttrs.Attributes = (this.initialState ? Interop.mincore.SEPrivileges.SE_PRIVILEGE_ENABLED : Interop.mincore.SEPrivileges.SE_PRIVILEGE_DISABLED);

                        Interop.mincore.TOKEN_PRIVILEGE newState = new Interop.mincore.TOKEN_PRIVILEGE();
                        newState.PrivilegeCount = 1;
                        newState.Privileges[0] = luidAndAttrs;

                        Interop.mincore.TOKEN_PRIVILEGE previousState = new Interop.mincore.TOKEN_PRIVILEGE();
                        uint previousSize = 0;

                        if (false == Interop.mincore.AdjustTokenPrivileges(
                                          this.tlsContents.ThreadHandle,
                                          false,
                                          ref newState,
                                          (uint)Marshal.SizeOf(previousState),
                                          ref previousState,
                                          ref previousSize))
                        {
                            error = Marshal.GetLastWin32Error();
                            success = false;
                        }
                    }
                }
                finally
                {
                    if (success)
                    {
                        this.Reset();
                    }
                }
            }

            if (error == Interop.mincore.Errors.ERROR_NOT_ENOUGH_MEMORY)
            {
                throw new OutOfMemoryException();
            }
            else if (error == Interop.mincore.Errors.ERROR_ACCESS_DENIED)
            {
                throw new UnauthorizedAccessException();
            }
            else if (error != 0)
            {
                Contract.Assert(false, string.Format(CultureInfo.InvariantCulture, "AdjustTokenPrivileges() failed with unrecognized error code {0}", error));
                throw new InvalidOperationException();
            }
        }
Example #3
0
        //      [SecurityPermission( SecurityAction.Demand, TogglePrivileges=true )]
        private void ToggleState(bool enable)
        {
            int error = 0;

            //
            // All privilege operations must take place on the same thread
            //

            if (!this.currentThread.Equals(Thread.CurrentThread))
            {
                throw new InvalidOperationException(SR.InvalidOperation_MustBeSameThread);
            }

            //
            // This privilege was already altered and needs to be reverted before it can be altered again
            //

            if (this.needToRevert)
            {
                throw new InvalidOperationException(SR.InvalidOperation_MustRevertPrivilege);
            }

            //
            // Need to make this block of code non-interruptible so that it would preserve
            // consistency of thread oken state even in the face of catastrophic exceptions
            //

            try
            {
                //
                // The payload is entirely in the finally block
                // This is how we ensure that the code will not be
                // interrupted by catastrophic exceptions
                //
            }
            finally
            {
                try
                {
                    //
                    // Retrieve TLS state
                    //

                    this.tlsContents = tlsSlotData;

                    if (this.tlsContents == null)
                    {
                        this.tlsContents = new TlsContents();
                        tlsSlotData      = this.tlsContents;
                    }
                    else
                    {
                        this.tlsContents.IncrementReferenceCount();
                    }

                    Interop.mincore.LUID_AND_ATTRIBUTES luidAndAttrs = new Interop.mincore.LUID_AND_ATTRIBUTES();
                    luidAndAttrs.Luid       = this.luid;
                    luidAndAttrs.Attributes = enable ? Interop.mincore.SEPrivileges.SE_PRIVILEGE_ENABLED : Interop.mincore.SEPrivileges.SE_PRIVILEGE_DISABLED;

                    Interop.mincore.TOKEN_PRIVILEGE newState = new Interop.mincore.TOKEN_PRIVILEGE();
                    newState.PrivilegeCount = 1;
                    newState.Privileges[0]  = luidAndAttrs;

                    Interop.mincore.TOKEN_PRIVILEGE previousState = new Interop.mincore.TOKEN_PRIVILEGE();
                    uint previousSize = 0;

                    //
                    // Place the new privilege on the thread token and remember the previous state.
                    //

                    if (false == Interop.mincore.AdjustTokenPrivileges(
                            this.tlsContents.ThreadHandle,
                            false,
                            ref newState,
                            (uint)Marshal.SizeOf(previousState),
                            ref previousState,
                            ref previousSize))
                    {
                        error = Marshal.GetLastWin32Error();
                    }
                    else if (Interop.mincore.Errors.ERROR_NOT_ALL_ASSIGNED == Marshal.GetLastWin32Error())
                    {
                        error = Interop.mincore.Errors.ERROR_NOT_ALL_ASSIGNED;
                    }
                    else
                    {
                        //
                        // This is the initial state that revert will have to go back to
                        //

                        this.initialState = ((previousState.Privileges[0].Attributes & Interop.mincore.SEPrivileges.SE_PRIVILEGE_ENABLED) != 0);

                        //
                        // Remember whether state has changed at all
                        //

                        this.stateWasChanged = (this.initialState != enable);

                        //
                        // If we had to impersonate, or if the privilege state changed we'll need to revert
                        //

                        this.needToRevert = this.tlsContents.IsImpersonating || this.stateWasChanged;
                    }
                }
                finally
                {
                    if (!this.needToRevert)
                    {
                        this.Reset();
                    }
                }
            }

            if (error == Interop.mincore.Errors.ERROR_NOT_ALL_ASSIGNED)
            {
                throw new PrivilegeNotHeldException(privileges[this.luid]);
            }
            if (error == Interop.mincore.Errors.ERROR_NOT_ENOUGH_MEMORY)
            {
                throw new OutOfMemoryException();
            }
            else if (error == Interop.mincore.Errors.ERROR_ACCESS_DENIED ||
                     error == Interop.mincore.Errors.ERROR_CANT_OPEN_ANONYMOUS)
            {
                throw new UnauthorizedAccessException();
            }
            else if (error != 0)
            {
                System.Diagnostics.Debug.Assert(false, string.Format(CultureInfo.InvariantCulture, "AdjustTokenPrivileges() failed with unrecognized error code {0}", error));
                throw new InvalidOperationException();
            }
        }
Example #4
0
        //      [SecurityPermission( SecurityAction.Demand, TogglePrivileges=true )]
        private void ToggleState(bool enable)
        {
            int error = 0;

            //
            // All privilege operations must take place on the same thread
            //

            if (!this.currentThread.Equals(Thread.CurrentThread))
            {
                throw new InvalidOperationException(SR.InvalidOperation_MustBeSameThread);
            }

            //
            // This privilege was already altered and needs to be reverted before it can be altered again
            //

            if (this.needToRevert)
            {
                throw new InvalidOperationException(SR.InvalidOperation_MustRevertPrivilege);
            }

            //
            // Need to make this block of code non-interruptible so that it would preserve
            // consistency of thread oken state even in the face of catastrophic exceptions
            //

            try
            {
                //
                // The payload is entirely in the finally block
                // This is how we ensure that the code will not be
                // interrupted by catastrophic exceptions
                //
            }
            finally
            {
                try
                {
                    //
                    // Retrieve TLS state
                    //

                    this.tlsContents = tlsSlotData;

                    if (this.tlsContents == null)
                    {
                        this.tlsContents = new TlsContents();
                        tlsSlotData = this.tlsContents;
                    }
                    else
                    {
                        this.tlsContents.IncrementReferenceCount();
                    }

                    Interop.mincore.LUID_AND_ATTRIBUTES luidAndAttrs = new Interop.mincore.LUID_AND_ATTRIBUTES();
                    luidAndAttrs.Luid = this.luid;
                    luidAndAttrs.Attributes = enable ? Interop.mincore.SEPrivileges.SE_PRIVILEGE_ENABLED : Interop.mincore.SEPrivileges.SE_PRIVILEGE_DISABLED;

                    Interop.mincore.TOKEN_PRIVILEGE newState = new Interop.mincore.TOKEN_PRIVILEGE();
                    newState.PrivilegeCount = 1;
                    newState.Privileges[0] = luidAndAttrs;

                    Interop.mincore.TOKEN_PRIVILEGE previousState = new Interop.mincore.TOKEN_PRIVILEGE();
                    uint previousSize = 0;

                    //
                    // Place the new privilege on the thread token and remember the previous state.
                    //

                    if (false == Interop.mincore.AdjustTokenPrivileges(
                                      this.tlsContents.ThreadHandle,
                                      false,
                                      ref newState,
                                      (uint)Marshal.SizeOf(previousState),
                                      ref previousState,
                                      ref previousSize))
                    {
                        error = Marshal.GetLastWin32Error();
                    }
                    else if (Interop.mincore.Errors.ERROR_NOT_ALL_ASSIGNED == Marshal.GetLastWin32Error())
                    {
                        error = Interop.mincore.Errors.ERROR_NOT_ALL_ASSIGNED;
                    }
                    else
                    {
                        //
                        // This is the initial state that revert will have to go back to
                        //

                        this.initialState = ((previousState.Privileges[0].Attributes & Interop.mincore.SEPrivileges.SE_PRIVILEGE_ENABLED) != 0);

                        //
                        // Remember whether state has changed at all
                        //

                        this.stateWasChanged = (this.initialState != enable);

                        //
                        // If we had to impersonate, or if the privilege state changed we'll need to revert
                        //

                        this.needToRevert = this.tlsContents.IsImpersonating || this.stateWasChanged;
                    }
                }
                finally
                {
                    if (!this.needToRevert)
                    {
                        this.Reset();
                    }
                }
            }

            if (error == Interop.mincore.Errors.ERROR_NOT_ALL_ASSIGNED)
            {
                throw new PrivilegeNotHeldException(privileges[this.luid]);
            }
            if (error == Interop.mincore.Errors.ERROR_NOT_ENOUGH_MEMORY)
            {
                throw new OutOfMemoryException();
            }
            else if (error == Interop.mincore.Errors.ERROR_ACCESS_DENIED ||
                error == Interop.mincore.Errors.ERROR_CANT_OPEN_ANONYMOUS)
            {
                throw new UnauthorizedAccessException();
            }
            else if (error != 0)
            {
                Contract.Assert(false, string.Format(CultureInfo.InvariantCulture, "AdjustTokenPrivileges() failed with unrecognized error code {0}", error));
                throw new InvalidOperationException();
            }
        }