1 // ==++== 2 // 3 // Copyright (c) Microsoft Corporation. All rights reserved. 4 // 5 // ==--== 6 // <OWNER>Microsoft</OWNER> 7 // 8 9 // 10 // WindowsImpersonationContext.cs 11 // 12 // Representation of an impersonation context. 13 // 14 15 namespace System.Security.Principal 16 { 17 using Microsoft.Win32; 18 using Microsoft.Win32.SafeHandles; 19 using System.Runtime.InteropServices; 20 #if FEATURE_CORRUPTING_EXCEPTIONS 21 using System.Runtime.ExceptionServices; 22 #endif // FEATURE_CORRUPTING_EXCEPTIONS 23 using System.Security.Permissions; 24 using System.Runtime.ConstrainedExecution; 25 using System.Runtime.Versioning; 26 using System.Diagnostics.Contracts; 27 28 [System.Runtime.InteropServices.ComVisible(true)] 29 public class WindowsImpersonationContext : IDisposable { 30 [System.Security.SecurityCritical] // auto-generated 31 private SafeAccessTokenHandle m_safeTokenHandle = SafeAccessTokenHandle.InvalidHandle; 32 private WindowsIdentity m_wi; 33 private FrameSecurityDescriptor m_fsd; 34 35 [System.Security.SecurityCritical] // auto-generated WindowsImpersonationContext()36 private WindowsImpersonationContext () {} 37 38 [System.Security.SecurityCritical] // auto-generated 39 [ResourceExposure(ResourceScope.None)] 40 [ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)] WindowsImpersonationContext(SafeAccessTokenHandle safeTokenHandle, WindowsIdentity wi, bool isImpersonating, FrameSecurityDescriptor fsd)41 internal WindowsImpersonationContext (SafeAccessTokenHandle safeTokenHandle, WindowsIdentity wi, bool isImpersonating, FrameSecurityDescriptor fsd) { 42 if (safeTokenHandle.IsInvalid) 43 throw new ArgumentException(Environment.GetResourceString("Argument_InvalidImpersonationToken")); 44 Contract.EndContractBlock(); 45 46 if (isImpersonating) { 47 if (!Win32Native.DuplicateHandle(Win32Native.GetCurrentProcess(), 48 safeTokenHandle, 49 Win32Native.GetCurrentProcess(), 50 ref m_safeTokenHandle, 51 0, 52 true, 53 Win32Native.DUPLICATE_SAME_ACCESS)) 54 throw new SecurityException(Win32Native.GetMessage(Marshal.GetLastWin32Error())); 55 m_wi = wi; 56 } 57 m_fsd = fsd; 58 } 59 60 // Revert to previous impersonation (the only public method). 61 [System.Security.SecuritySafeCritical] // auto-generated 62 [ResourceExposure(ResourceScope.None)] 63 [ResourceConsumption(ResourceScope.Process, ResourceScope.Process)] Undo()64 public void Undo () { 65 int hr = 0; 66 if (m_safeTokenHandle.IsInvalid) { // the thread was not initially impersonating 67 hr = Win32.RevertToSelf(); 68 if (hr < 0) 69 Environment.FailFast(Win32Native.GetMessage(hr)); 70 } else { 71 hr = Win32.RevertToSelf(); 72 if (hr < 0) 73 Environment.FailFast(Win32Native.GetMessage(hr)); 74 hr = Win32.ImpersonateLoggedOnUser(m_safeTokenHandle); 75 if (hr < 0) 76 throw new SecurityException(Win32Native.GetMessage(hr)); 77 } 78 WindowsIdentity.UpdateThreadWI(m_wi); 79 if (m_fsd != null) 80 m_fsd.SetTokenHandles(null, null); 81 } 82 83 // Non-throwing version that does not new any exception objects. To be called when reliability matters 84 [System.Security.SecurityCritical] // auto-generated 85 [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] 86 [ResourceExposure(ResourceScope.None)] 87 [ResourceConsumption(ResourceScope.Process, ResourceScope.Process)] 88 #if FEATURE_CORRUPTING_EXCEPTIONS 89 [HandleProcessCorruptedStateExceptions] // 90 #endif // FEATURE_CORRUPTING_EXCEPTIONS UndoNoThrow()91 internal bool UndoNoThrow() 92 { 93 bool bRet = false; 94 try{ 95 int hr = 0; 96 if (m_safeTokenHandle.IsInvalid) 97 { // the thread was not initially impersonating 98 hr = Win32.RevertToSelf(); 99 if (hr < 0) 100 Environment.FailFast(Win32Native.GetMessage(hr)); 101 } 102 else 103 { 104 hr = Win32.RevertToSelf(); 105 if (hr >= 0) 106 { 107 hr = Win32.ImpersonateLoggedOnUser(m_safeTokenHandle); 108 } 109 else 110 { 111 Environment.FailFast(Win32Native.GetMessage(hr)); 112 } 113 } 114 bRet = (hr >= 0); 115 if (m_fsd != null) 116 m_fsd.SetTokenHandles(null,null); 117 } 118 catch 119 { 120 bRet = false; 121 } 122 return bRet; 123 } 124 125 // 126 // IDisposable interface. 127 // 128 129 [System.Security.SecuritySafeCritical] // auto-generated 130 [ComVisible(false)] Dispose(bool disposing)131 protected virtual void Dispose(bool disposing) { 132 if (disposing) { 133 if (m_safeTokenHandle != null && !m_safeTokenHandle.IsClosed) { 134 Undo(); 135 m_safeTokenHandle.Dispose(); 136 } 137 } 138 } 139 140 [ComVisible(false)] Dispose()141 public void Dispose () { 142 Dispose(true); 143 } 144 } 145 } 146