private IntPtr GetTokenWithEnabledPrivilege(string privilege, NativeMethods.TOKEN_PRIVILEGE previousState) { IntPtr zero = IntPtr.Zero; bool flag = true; try { flag = NativeMethods.OpenThreadToken(NativeMethods.GetCurrentThread(), 40, true, out zero); if (!flag) { if ((long)Marshal.GetLastWin32Error() == (long)0x3f0) { flag = NativeMethods.OpenProcessToken(NativeMethods.GetCurrentProcess(), 40, out zero); } if (!flag) { throw new Win32Exception(Marshal.GetLastWin32Error()); } } NativeMethods.LUID lUID = new NativeMethods.LUID(); flag = NativeMethods.LookupPrivilegeValue(null, privilege, ref lUID); if (flag) { NativeMethods.TOKEN_PRIVILEGE tOKENPRIVILEGE = new NativeMethods.TOKEN_PRIVILEGE(); tOKENPRIVILEGE.PrivilegeCount = 1; tOKENPRIVILEGE.Privilege.Attributes = 2; tOKENPRIVILEGE.Privilege.Luid = lUID; uint num = 0; flag = NativeMethods.AdjustTokenPrivileges(zero, false, ref tOKENPRIVILEGE, Marshal.SizeOf(previousState), ref previousState, ref num); if (!flag) { throw new Win32Exception(Marshal.GetLastWin32Error()); } } else { throw new Win32Exception(Marshal.GetLastWin32Error()); } } finally { if (!flag) { NativeMethods.CloseHandle(zero); zero = IntPtr.Zero; } } return(zero); }
protected override void ProcessRecord() { string sddlForm; ObjectSecurity objectSecurity = this.securityDescriptor as ObjectSecurity; if (this.inputObject == null) { if (this.Path != null) { if (objectSecurity != null) { if ((this.CentralAccessPolicy != null || this.ClearCentralAccessPolicy) && !DownLevelHelper.IsWin8AndAbove()) { Exception parameterBindingException = new ParameterBindingException(); base.WriteError(new ErrorRecord(parameterBindingException, "SetAcl_OperationNotSupported", ErrorCategory.InvalidArgument, null)); return; } else { if (this.CentralAccessPolicy == null || !this.ClearCentralAccessPolicy) { IntPtr zero = IntPtr.Zero; NativeMethods.TOKEN_PRIVILEGE tOKENPRIVILEGE = new NativeMethods.TOKEN_PRIVILEGE(); try { if (this.CentralAccessPolicy == null) { if (this.ClearCentralAccessPolicy) { zero = this.GetEmptySacl(); if (zero == IntPtr.Zero) { SystemException systemException = new SystemException(UtilsStrings.GetEmptySaclFail); base.WriteError(new ErrorRecord(systemException, "SetAcl_ClearCentralAccessPolicy", ErrorCategory.InvalidResult, null)); return; } } } else { zero = this.GetSaclWithCapId(this.CentralAccessPolicy); if (zero == IntPtr.Zero) { SystemException systemException1 = new SystemException(UtilsStrings.GetSaclWithCapIdFail); base.WriteError(new ErrorRecord(systemException1, "SetAcl_CentralAccessPolicy", ErrorCategory.InvalidResult, null)); return; } } string[] path = this.Path; for (int i = 0; i < (int)path.Length; i++) { string str = path[i]; Collection <PathInfo> pathInfos = new Collection <PathInfo>(); CmdletProviderContext cmdletProviderContext = base.CmdletProviderContext; cmdletProviderContext.PassThru = this.Passthru; if (!this.isLiteralPath) { pathInfos = base.SessionState.Path.GetResolvedPSPathFromPSPath(str, base.CmdletProviderContext); } else { ProviderInfo providerInfo = null; PSDriveInfo pSDriveInfo = null; string unresolvedProviderPathFromPSPath = base.SessionState.Path.GetUnresolvedProviderPathFromPSPath(str, out providerInfo, out pSDriveInfo); pathInfos.Add(new PathInfo(pSDriveInfo, providerInfo, unresolvedProviderPathFromPSPath, base.SessionState)); cmdletProviderContext.SuppressWildcardExpansion = true; } foreach (PathInfo pathInfo in pathInfos) { if (!base.ShouldProcess(pathInfo.Path)) { continue; } try { base.InvokeProvider.SecurityDescriptor.Set(pathInfo.Path, objectSecurity, cmdletProviderContext); if (this.CentralAccessPolicy != null || this.ClearCentralAccessPolicy) { if (pathInfo.Provider.NameEquals(base.Context.ProviderNames.FileSystem)) { IntPtr tokenWithEnabledPrivilege = this.GetTokenWithEnabledPrivilege("SeSecurityPrivilege", tOKENPRIVILEGE); if (tokenWithEnabledPrivilege != IntPtr.Zero) { int num = NativeMethods.SetNamedSecurityInfo(pathInfo.ProviderPath, NativeMethods.SeObjectType.SE_FILE_OBJECT, NativeMethods.SecurityInformation.SCOPE_SECURITY_INFORMATION, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, zero); if (tokenWithEnabledPrivilege != IntPtr.Zero) { NativeMethods.TOKEN_PRIVILEGE tOKENPRIVILEGE1 = new NativeMethods.TOKEN_PRIVILEGE(); uint num1 = 0; NativeMethods.AdjustTokenPrivileges(tokenWithEnabledPrivilege, false, ref tOKENPRIVILEGE, Marshal.SizeOf(tOKENPRIVILEGE1), ref tOKENPRIVILEGE1, ref num1); NativeMethods.CloseHandle(tokenWithEnabledPrivilege); } if (num != 0) { SystemException win32Exception = new Win32Exception(num, UtilsStrings.SetCentralAccessPolicyFail); base.WriteError(new ErrorRecord(win32Exception, "SetAcl_SetNamedSecurityInfo", ErrorCategory.InvalidResult, null)); } } else { SystemException systemException2 = new SystemException(UtilsStrings.GetTokenWithEnabledPrivilegeFail); base.WriteError(new ErrorRecord(systemException2, "SetAcl_AdjustTokenPrivileges", ErrorCategory.InvalidResult, null)); return; } } else { Exception argumentException = new ArgumentException("Path"); base.WriteError(new ErrorRecord(argumentException, "SetAcl_Path", ErrorCategory.InvalidArgument, this.AclObject)); continue; } } } catch (NotSupportedException notSupportedException) { object[] objArray = new object[1]; objArray[0] = pathInfo.Path; ErrorRecord errorRecord = SecurityUtils.CreateNotSupportedErrorRecord(UtilsStrings.OperationNotSupportedOnPath, "SetAcl_OperationNotSupported", objArray); base.WriteError(errorRecord); } } } return; } finally { Marshal.FreeHGlobal(zero); } } else { Exception exception = new ArgumentException(UtilsStrings.InvalidCentralAccessPolicyParameters); ErrorRecord errorRecord1 = SecurityUtils.CreateInvalidArgumentErrorRecord(exception, "SetAcl_OperationNotSupported"); base.WriteError(errorRecord1); return; } } } else { Exception argumentException1 = new ArgumentException("AclObject"); base.WriteError(new ErrorRecord(argumentException1, "SetAcl_AclObject", ErrorCategory.InvalidArgument, this.AclObject)); return; } } else { Exception exception1 = new ArgumentException("Path"); base.WriteError(new ErrorRecord(exception1, "SetAcl_Path", ErrorCategory.InvalidArgument, this.AclObject)); } } else { PSMethodInfo item = this.inputObject.Methods["SetSecurityDescriptor"]; if (item == null) { ErrorRecord errorRecord2 = SecurityUtils.CreateNotSupportedErrorRecord(UtilsStrings.SetMethodNotFound, "SetAcl_OperationNotSupported", new object[0]); base.WriteError(errorRecord2); return; } else { CommonSecurityDescriptor commonSecurityDescriptor = this.securityDescriptor as CommonSecurityDescriptor; if (objectSecurity == null) { if (commonSecurityDescriptor == null) { Exception argumentException2 = new ArgumentException("AclObject"); base.WriteError(new ErrorRecord(argumentException2, "SetAcl_AclObject", ErrorCategory.InvalidArgument, this.AclObject)); return; } else { sddlForm = commonSecurityDescriptor.GetSddlForm(AccessControlSections.All); } } else { sddlForm = objectSecurity.GetSecurityDescriptorSddlForm(AccessControlSections.All); } try { object[] objArray1 = new object[1]; objArray1[0] = sddlForm; item.Invoke(objArray1); return; } catch (Exception exception3) { Exception exception2 = exception3; CommandProcessorBase.CheckForSevereException(exception2); ErrorRecord errorRecord3 = SecurityUtils.CreateNotSupportedErrorRecord(UtilsStrings.MethodInvokeFail, "SetAcl_OperationNotSupported", new object[0]); base.WriteError(errorRecord3); } } } }
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("Operation must take place on the thread that created the object"); } // // This privilege was already altered and needs to be reverted before it can be altered again // if (this.NeedToRevert) { throw new InvalidOperationException("Must revert the privilege prior to attempting this operation"); } // // 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(); } NativeMethods.TOKEN_PRIVILEGE newState = new NativeMethods.TOKEN_PRIVILEGE(); newState.PrivilegeCount = 1; newState.Privilege.Luid = this.luid; newState.Privilege.Attributes = (enable ? NativeMethods.PrivilegeAttribute.Enabled : NativeMethods.PrivilegeAttribute.Disabled); NativeMethods.TOKEN_PRIVILEGE previousState = new NativeMethods.TOKEN_PRIVILEGE(); uint previousSize = 0; // // Place the new privilege on the thread token and remember the previous state. // bool fResult = NativeMethods.AdjustTokenPrivileges(this.tlsContents.ThreadHandle, false, ref newState, (uint)Marshal.SizeOf(previousState), ref previousState, ref previousSize); error = Marshal.GetLastWin32Error(); if (fResult && error != Win32Error.ERROR_NOT_ALL_ASSIGNED) { // // This is the initial state that revert will have to go back to // this.initialState = ((previousState.Privilege.Attributes & NativeMethods.PrivilegeAttribute.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(); } } } switch (error) { case Win32Error.ERROR_NOT_ALL_ASSIGNED: throw new PrivilegeNotHeldException( privileges[this.luid] as string); case Win32Error.ERROR_NOT_ENOUGH_MEMORY: throw new InsufficientMemoryException(); case Win32Error.ERROR_CANT_OPEN_ANONYMOUS: goto case Win32Error.ERROR_ACCESS_DENIED; case Win32Error.ERROR_ACCESS_DENIED: { throw new UnauthorizedAccessException("The caller does not have the right to change the " + "privilege"); } default: { if (error != Win32Error.ERROR_SUCCESS) { throw new Win32Exception(error); } break; } } }
public void Revert() { int error = 0; // // All privilege operations must take place on the same thread // if (!this.currentThread.Equals(Thread.CurrentThread)) { throw new InvalidOperationException("Operation must take place on the thread that created the object"); } 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)) { NativeMethods.TOKEN_PRIVILEGE newState = new NativeMethods.TOKEN_PRIVILEGE(); newState.PrivilegeCount = 1; newState.Privilege.Luid = this.luid; newState.Privilege.Attributes = (this.initialState ? NativeMethods.PrivilegeAttribute.Enabled : NativeMethods.PrivilegeAttribute.Disabled); NativeMethods.TOKEN_PRIVILEGE previousState = new NativeMethods.TOKEN_PRIVILEGE(); uint previousSize = 0; if (!NativeMethods.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 == Win32Error.ERROR_NOT_ENOUGH_MEMORY) { throw new InsufficientMemoryException(); } else if (error == Win32Error.ERROR_ACCESS_DENIED) { throw new UnauthorizedAccessException("Caller does not have the permission to change the privilege"); } else if (error != 0) { throw new Win32Exception(error); } }