Ejemplo n.º 1
0
        public void Revert()
        {
            int error = 0;

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

            if ( !this.NeedToRevert )
            {
                return;
            }

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

            RuntimeHelpers.PrepareConstrainedRegions();
            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 ))
                    {
                        Win32Native.TOKEN_PRIVILEGE newState = new Win32Native.TOKEN_PRIVILEGE();
                        newState.PrivilegeCount = 1;
                        newState.Privilege.Luid = this.luid;
                        newState.Privilege.Attributes = ( this.initialState ? Win32Native.SE_PRIVILEGE_ENABLED : Win32Native.SE_PRIVILEGE_DISABLED );

                        Win32Native.TOKEN_PRIVILEGE previousState = new Win32Native.TOKEN_PRIVILEGE();
                        uint previousSize = 0;

                        if ( false == Win32Native.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 == Win32Native.ERROR_NOT_ENOUGH_MEMORY )
            {
                throw new OutOfMemoryException();
            }
            else if ( error == Win32Native.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();
            }
        }
        private void ToggleState(bool enable)
        {
            int num = 0;
            if (!this.currentThread.Equals(Thread.CurrentThread))
            {
                throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_MustBeSameThread"));
            }
            if (this.needToRevert)
            {
                throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_MustRevertPrivilege"));
            }
            RuntimeHelpers.PrepareConstrainedRegions();
            try
            {
            }
            finally
            {
                try
                {
                    this.tlsContents = Thread.GetData(tlsSlot) as TlsContents;
                    if (this.tlsContents == null)
                    {
                        this.tlsContents = new TlsContents();
                        Thread.SetData(tlsSlot, this.tlsContents);
                    }
                    else
                    {
                        this.tlsContents.IncrementReferenceCount();
                    }
                    Win32Native.TOKEN_PRIVILEGE newState = new Win32Native.TOKEN_PRIVILEGE {
                        PrivilegeCount = 1
                    };
                    newState.Privilege.Luid = this.luid;
                    newState.Privilege.Attributes = enable ? 2 : 0;
                    Win32Native.TOKEN_PRIVILEGE structure = new Win32Native.TOKEN_PRIVILEGE();
                    uint returnLength = 0;
                    int introduced4 = Marshal.SizeOf(structure);
                    if (!Win32Native.AdjustTokenPrivileges(this.tlsContents.ThreadHandle, false, ref newState, (uint) introduced4, ref structure, ref returnLength))
                    {
                        num = Marshal.GetLastWin32Error();
                    }
                    else if (0x514 == Marshal.GetLastWin32Error())
                    {
                        num = 0x514;
                    }
                    else
                    {
                        this.initialState = (structure.Privilege.Attributes & 2) != 0;
                        this.stateWasChanged = this.initialState != enable;
                        this.needToRevert = this.tlsContents.IsImpersonating || this.stateWasChanged;
                    }
                }
                finally
                {
                    if (!this.needToRevert)
                    {
                        this.Reset();
                    }
                }
            }
            switch (num)
            {
                case 0x514:
                    throw new PrivilegeNotHeldException(privileges[this.luid] as string);

                case 8:
                    throw new OutOfMemoryException();

                case 5:
                case 0x543:
                    throw new UnauthorizedAccessException();
            }
            if (num != 0)
            {
                throw new InvalidOperationException();
            }
        }
Ejemplo n.º 3
0
        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( Environment.GetResourceString( "InvalidOperation_MustBeSameThread" ));
            }

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

            if ( this.needToRevert )
            {
                throw new InvalidOperationException( Environment.GetResourceString( "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
            //

            RuntimeHelpers.PrepareConstrainedRegions();
            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 = Thread.GetData( tlsSlot ) as TlsContents;

                    if ( this.tlsContents == null )
                    {
                        this.tlsContents = new TlsContents();
                        Thread.SetData( tlsSlot, this.tlsContents );
                    }
                    else
                    {
                        this.tlsContents.IncrementReferenceCount();
                    }

                    Win32Native.TOKEN_PRIVILEGE newState = new Win32Native.TOKEN_PRIVILEGE();
                    newState.PrivilegeCount = 1;
                    newState.Privilege.Luid = this.luid;
                    newState.Privilege.Attributes = enable ? Win32Native.SE_PRIVILEGE_ENABLED : Win32Native.SE_PRIVILEGE_DISABLED;
                    
                    Win32Native.TOKEN_PRIVILEGE previousState = new Win32Native.TOKEN_PRIVILEGE();
                    uint previousSize = 0;

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

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

                        this.initialState = (( previousState.Privilege.Attributes & Win32Native.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 == Win32Native.ERROR_NOT_ALL_ASSIGNED )
            {
                throw new PrivilegeNotHeldException( privileges[this.luid] as string );
            }
            if ( error == Win32Native.ERROR_NOT_ENOUGH_MEMORY )
            {
                throw new OutOfMemoryException();
            }
            else if ( error == Win32Native.ERROR_ACCESS_DENIED ||
                error == Win32Native.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();
            }
        }
        public void Revert()
        {
            int num = 0;
            if (!this.currentThread.Equals(Thread.CurrentThread))
            {
                throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_MustBeSameThread"));
            }
            if (this.NeedToRevert)
            {
                RuntimeHelpers.PrepareConstrainedRegions();
                try
                {
                }
                finally
                {
                    bool flag = true;
                    try
                    {
                        if (this.stateWasChanged && ((this.tlsContents.ReferenceCountValue > 1) || !this.tlsContents.IsImpersonating))
                        {
                            Win32Native.TOKEN_PRIVILEGE newState = new Win32Native.TOKEN_PRIVILEGE {
                                PrivilegeCount = 1
                            };
                            newState.Privilege.Luid = this.luid;
                            newState.Privilege.Attributes = this.initialState ? 2 : 0;
                            Win32Native.TOKEN_PRIVILEGE structure = new Win32Native.TOKEN_PRIVILEGE();
                            uint returnLength = 0;
                            int introduced5 = Marshal.SizeOf(structure);
                            if (!Win32Native.AdjustTokenPrivileges(this.tlsContents.ThreadHandle, false, ref newState, (uint) introduced5, ref structure, ref returnLength))
                            {
                                num = Marshal.GetLastWin32Error();
                                flag = false;
                            }
                        }
                    }
                    finally
                    {
                        if (flag)
                        {
                            this.Reset();
                        }
                    }
                }
                switch (num)
                {
                    case 8:
                        throw new OutOfMemoryException();

                    case 5:
                        throw new UnauthorizedAccessException();
                }
                if (num != 0)
                {
                    throw new InvalidOperationException();
                }
            }
        }