// [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(); } }
// [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(); } }
// [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(); } }
// [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(); } }