|
// ==++==
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
/*============================================================
**
** Class: SecurityContext
**
** <OWNER>Microsoft</OWNER>
**
**
** Purpose: Capture security context for a thread
**
**
===========================================================*/
namespace System.Security
{
using Microsoft.Win32;
using Microsoft.Win32.SafeHandles;
using System.Threading;
using System.Runtime.Remoting;
using System.Security.Principal;
using System.Collections;
using System.Runtime.Serialization;
using System.Security.Permissions;
using System.Runtime.InteropServices;
using System.Runtime.CompilerServices;
#if FEATURE_CORRUPTING_EXCEPTIONS
using System.Runtime.ExceptionServices;
#endif // FEATURE_CORRUPTING_EXCEPTIONS
using System.Runtime.ConstrainedExecution;
using System.Runtime.Versioning;
using System.Diagnostics.Contracts;
using System.Diagnostics.CodeAnalysis;
// This enum must be kept in sync with the SecurityContextSource enum in the VM
public enum SecurityContextSource
{
CurrentAppDomain = 0,
CurrentAssembly
}
internal enum SecurityContextDisableFlow
{
Nothing = 0,
WI = 0x1,
All = 0x3FFF
}
#if !FEATURE_PAL && FEATURE_IMPERSONATION
internal enum WindowsImpersonationFlowMode {
IMP_FASTFLOW = 0,
IMP_NOFLOW = 1,
IMP_ALWAYSFLOW = 2,
IMP_DEFAULT = IMP_FASTFLOW
}
#endif
#if FEATURE_COMPRESSEDSTACK
internal struct SecurityContextSwitcher: IDisposable
{
internal SecurityContext.Reader prevSC; // prev SC that we restore on an Undo
internal SecurityContext currSC; //current SC - SetSecurityContext that created the switcher set this on the Thread
internal ExecutionContext currEC; // current ExecutionContext on Thread
internal CompressedStackSwitcher cssw;
#if !FEATURE_PAL && FEATURE_IMPERSONATION
internal WindowsImpersonationContext wic;
#endif
[System.Security.SecuritySafeCritical] // overrides public transparent member
public void Dispose()
{
Undo();
}
[System.Security.SecurityCritical] // auto-generated
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
#if FEATURE_CORRUPTING_EXCEPTIONS
[HandleProcessCorruptedStateExceptions] //
[SuppressMessage("Microsoft.Security", "CA2153:DoNotCatchCorruptedStateExceptionsInGeneralHandlers", Justification = "Reviewed for security")]
#endif // FEATURE_CORRUPTING_EXCEPTIONS
internal bool UndoNoThrow()
{
try
{
Undo();
}
catch (Exception ex)
{
if (!AppContextSwitches.UseLegacyExecutionContextBehaviorUponUndoFailure)
{
// Fail fast since we can't continue safely
Environment.FailFast(Environment.GetResourceString("ExecutionContext_UndoFailed"), ex);
}
return false;
}
return true;
}
[System.Security.SecurityCritical] // auto-generated
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
[ResourceExposure(ResourceScope.None)]
[ResourceConsumption(ResourceScope.Process, ResourceScope.Process)] // FailFast
#if FEATURE_CORRUPTING_EXCEPTIONS
[HandleProcessCorruptedStateExceptions] //
[SuppressMessage("Microsoft.Security", "CA2153:DoNotCatchCorruptedStateExceptionsInGeneralHandlers", Justification = "Reviewed for security")]
#endif // FEATURE_CORRUPTING_EXCEPTIONS
public void Undo()
{
if (currSC == null)
{
return; // mutiple Undo()s called on this switcher object
}
if (currEC != null)
{
Contract.Assert(currEC == Thread.CurrentThread.GetMutableExecutionContext(), "SecurityContextSwitcher used from another thread");
Contract.Assert(currSC == currEC.SecurityContext, "SecurityContextSwitcher context mismatch");
// restore the saved security context
currEC.SecurityContext = prevSC.DangerousGetRawSecurityContext();
}
else
{
// caller must have already restored the ExecutionContext
Contract.Assert(Thread.CurrentThread.GetExecutionContextReader().SecurityContext.IsSame(prevSC));
}
currSC = null; // this will prevent the switcher object being used again
bool bNoException = true;
#if !FEATURE_PAL && FEATURE_IMPERSONATION
try
{
if (wic != null)
bNoException &= wic.UndoNoThrow();
}
catch
{
// Failfast since we can't continue safely...
bNoException &= cssw.UndoNoThrow();
System.Environment.FailFast(Environment.GetResourceString("ExecutionContext_UndoFailed"));
}
#endif
bNoException &= cssw.UndoNoThrow();
if (!bNoException)
{
// Failfast since we can't continue safely...
System.Environment.FailFast(Environment.GetResourceString("ExecutionContext_UndoFailed"));
}
}
}
public sealed class SecurityContext : IDisposable
{
#if !FEATURE_PAL && FEATURE_IMPERSONATION
// Note that only one of the following variables will be true. The way we set up the flow mode in the g_pConfig guarantees this.
static bool _LegacyImpersonationPolicy = (GetImpersonationFlowMode() == WindowsImpersonationFlowMode.IMP_NOFLOW);
static bool _alwaysFlowImpersonationPolicy = (GetImpersonationFlowMode() == WindowsImpersonationFlowMode.IMP_ALWAYSFLOW);
#endif
/*=========================================================================
** Data accessed from managed code that needs to be defined in
** SecurityContextObject to maintain alignment between the two classes.
** DON'T CHANGE THESE UNLESS YOU MODIFY SecurityContextObject in vm\object.h
=========================================================================*/
private ExecutionContext _executionContext;
#if !FEATURE_PAL && FEATURE_IMPERSONATION
private volatile WindowsIdentity _windowsIdentity;
#endif
private volatile CompressedStack _compressedStack;
static private volatile SecurityContext _fullTrustSC;
internal volatile bool isNewCapture = false;
internal volatile SecurityContextDisableFlow _disableFlow = SecurityContextDisableFlow.Nothing;
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
internal SecurityContext()
{
}
internal struct Reader
{
SecurityContext m_sc;
public Reader(SecurityContext sc) { m_sc = sc; }
public SecurityContext DangerousGetRawSecurityContext() { return m_sc; }
public bool IsNull { get { return m_sc == null; } }
public bool IsSame(SecurityContext sc) { return m_sc == sc; }
public bool IsSame(SecurityContext.Reader sc) { return m_sc == sc.m_sc; }
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool IsFlowSuppressed(SecurityContextDisableFlow flags)
{
return (m_sc == null) ? false : ((m_sc._disableFlow & flags) == flags);
}
public CompressedStack CompressedStack { get { return IsNull ? null : m_sc.CompressedStack; } }
public WindowsIdentity WindowsIdentity
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get { return IsNull ? null : m_sc.WindowsIdentity; }
}
}
static internal SecurityContext FullTrustSecurityContext
{
[System.Security.SecurityCritical] // auto-generated
get
{
if (_fullTrustSC == null)
_fullTrustSC = CreateFullTrustSecurityContext();
return _fullTrustSC;
}
}
// link the security context to an ExecutionContext
internal ExecutionContext ExecutionContext
{
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
set
{
_executionContext = value;
}
}
#if !FEATURE_PAL && FEATURE_IMPERSONATION
internal WindowsIdentity WindowsIdentity
{
get
{
return _windowsIdentity;
}
set
{
// Note, we do not dispose of the existing windows identity, since some code such as remoting
// relies on reusing that identity. If you are not going to reuse the existing identity, then
// you should dispose of the existing identity before resetting it.
_windowsIdentity = value;
}
}
#endif // !FEATURE_PAL && FEATURE_IMPERSONATION
internal CompressedStack CompressedStack
{
get
{
return _compressedStack;
}
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
set
{
_compressedStack = value;
}
}
public void Dispose()
{
#if !FEATURE_PAL && FEATURE_IMPERSONATION
if (_windowsIdentity != null)
_windowsIdentity.Dispose();
#endif // !FEATURE_PAL
}
[System.Security.SecurityCritical] // auto-generated_required
public static AsyncFlowControl SuppressFlow()
{
return SuppressFlow(SecurityContextDisableFlow.All);
}
[System.Security.SecurityCritical] // auto-generated_required
public static AsyncFlowControl SuppressFlowWindowsIdentity()
{
return SuppressFlow(SecurityContextDisableFlow.WI);
}
[SecurityCritical]
internal static AsyncFlowControl SuppressFlow(SecurityContextDisableFlow flags)
{
if (IsFlowSuppressed(flags))
{
throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_CannotSupressFlowMultipleTimes"));
}
ExecutionContext ec = Thread.CurrentThread.GetMutableExecutionContext();
if (ec.SecurityContext == null)
ec.SecurityContext = new SecurityContext();
AsyncFlowControl afc = new AsyncFlowControl();
afc.Setup(flags);
return afc;
}
[SecuritySafeCritical]
public static void RestoreFlow()
{
SecurityContext sc = Thread.CurrentThread.GetMutableExecutionContext().SecurityContext;
if (sc == null || sc._disableFlow == SecurityContextDisableFlow.Nothing)
{
throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_CannotRestoreUnsupressedFlow"));
}
sc._disableFlow = SecurityContextDisableFlow.Nothing;
}
public static bool IsFlowSuppressed()
{
return SecurityContext.IsFlowSuppressed(SecurityContextDisableFlow.All);
}
#if !FEATURE_PAL && FEATURE_IMPERSONATION
public static bool IsWindowsIdentityFlowSuppressed()
{
return (_LegacyImpersonationPolicy|| SecurityContext.IsFlowSuppressed(SecurityContextDisableFlow.WI));
}
#endif
[SecuritySafeCritical]
internal static bool IsFlowSuppressed(SecurityContextDisableFlow flags)
{
return Thread.CurrentThread.GetExecutionContextReader().SecurityContext.IsFlowSuppressed(flags);
}
// This method is special from a security perspective - the VM will not allow a stack walk to
// continue past the call to SecurityContext.Run. If you change the signature to this method, or
// provide an alternate way to do a SecurityContext.Run make sure to update
// SecurityStackWalk::IsSpecialRunFrame in the VM to search for the new method.
[System.Security.SecurityCritical] // auto-generated_required
[DynamicSecurityMethodAttribute()]
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
public static void Run(SecurityContext securityContext, ContextCallback callback, Object state)
{
if (securityContext == null )
{
throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_NullContext"));
}
Contract.EndContractBlock();
StackCrawlMark stackMark = StackCrawlMark.LookForMe;
if (!securityContext.isNewCapture)
{
throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_NotNewCaptureContext"));
}
securityContext.isNewCapture = false;
ExecutionContext.Reader ec = Thread.CurrentThread.GetExecutionContextReader();
// Optimization: do the callback directly if both the current and target contexts are equal to the
// default full-trust security context
if ( SecurityContext.CurrentlyInDefaultFTSecurityContext(ec)
&& securityContext.IsDefaultFTSecurityContext())
{
callback(state);
if (GetCurrentWI(Thread.CurrentThread.GetExecutionContextReader()) != null)
{
// If we enter here it means the callback did an impersonation
// that we need to revert.
// We don't need to revert any other security state since it is stack-based
// and automatically goes away when the callback returns.
WindowsIdentity.SafeRevertToSelf(ref stackMark);
// Ensure we have reverted to the state we entered in.
Contract.Assert(GetCurrentWI(Thread.CurrentThread.GetExecutionContextReader()) == null);
}
}
else
{
RunInternal(securityContext, callback, state);
}
}
[System.Security.SecurityCritical] // auto-generated
internal static void RunInternal(SecurityContext securityContext, ContextCallback callBack, Object state)
{
if (cleanupCode == null)
{
tryCode = new RuntimeHelpers.TryCode(runTryCode);
cleanupCode = new RuntimeHelpers.CleanupCode(runFinallyCode);
}
SecurityContextRunData runData = new SecurityContextRunData(securityContext, callBack, state);
RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(tryCode, cleanupCode, runData);
}
internal class SecurityContextRunData
{
internal SecurityContext sc;
internal ContextCallback callBack;
internal Object state;
internal SecurityContextSwitcher scsw;
internal SecurityContextRunData(SecurityContext securityContext, ContextCallback cb, Object state)
{
this.sc = securityContext;
this.callBack = cb;
this.state = state;
this.scsw = new SecurityContextSwitcher();
}
}
[System.Security.SecurityCritical] // auto-generated
[ResourceExposure(ResourceScope.Process)]
[ResourceConsumption(ResourceScope.Process)]
static internal void runTryCode(Object userData)
{
SecurityContextRunData rData = (SecurityContextRunData) userData;
rData.scsw = SetSecurityContext(rData.sc, Thread.CurrentThread.GetExecutionContextReader().SecurityContext, modifyCurrentExecutionContext: true);
rData.callBack(rData.state);
}
[System.Security.SecurityCritical] // auto-generated
[PrePrepareMethod]
static internal void runFinallyCode(Object userData, bool exceptionThrown)
{
SecurityContextRunData rData = (SecurityContextRunData) userData;
rData.scsw.Undo();
}
static volatile internal RuntimeHelpers.TryCode tryCode;
static volatile internal RuntimeHelpers.CleanupCode cleanupCode;
// Internal API that gets called from public SetSecurityContext and from SetExecutionContext
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
[System.Security.SecurityCritical] // auto-generated
[ResourceExposure(ResourceScope.Process)]
[ResourceConsumption(ResourceScope.Process)]
[DynamicSecurityMethodAttribute()]
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
internal static SecurityContextSwitcher SetSecurityContext(SecurityContext sc, SecurityContext.Reader prevSecurityContext, bool modifyCurrentExecutionContext)
{
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
return SetSecurityContext(sc, prevSecurityContext, modifyCurrentExecutionContext, ref stackMark);
}
[System.Security.SecurityCritical] // auto-generated
#if FEATURE_CORRUPTING_EXCEPTIONS
[HandleProcessCorruptedStateExceptions] //
[SuppressMessage("Microsoft.Security", "CA2153:DoNotCatchCorruptedStateExceptionsInGeneralHandlers", Justification = "Reviewed for security")]
#endif // FEATURE_CORRUPTING_EXCEPTIONS
internal static SecurityContextSwitcher SetSecurityContext(SecurityContext sc, SecurityContext.Reader prevSecurityContext, bool modifyCurrentExecutionContext, ref StackCrawlMark stackMark)
{
// Save the flow state at capture and reset it in the SC.
SecurityContextDisableFlow _capturedFlowState = sc._disableFlow;
sc._disableFlow = SecurityContextDisableFlow.Nothing;
//Set up the switcher object
SecurityContextSwitcher scsw = new SecurityContextSwitcher();
scsw.currSC = sc;
scsw.prevSC = prevSecurityContext;
if (modifyCurrentExecutionContext)
{
// save the current Execution Context
ExecutionContext currEC = Thread.CurrentThread.GetMutableExecutionContext();
scsw.currEC = currEC;
currEC.SecurityContext = sc;
}
if (sc != null)
{
RuntimeHelpers.PrepareConstrainedRegions();
try
{
#if !FEATURE_PAL && FEATURE_IMPERSONATION
scsw.wic = null;
if (!_LegacyImpersonationPolicy)
{
if (sc.WindowsIdentity != null)
{
scsw.wic = sc.WindowsIdentity.Impersonate(ref stackMark);
}
else if ( ((_capturedFlowState & SecurityContextDisableFlow.WI) == 0)
&& prevSecurityContext.WindowsIdentity != null)
{
// revert impersonation if there was no WI flow supression at capture and we're currently impersonating
scsw.wic = WindowsIdentity.SafeRevertToSelf(ref stackMark);
}
}
#endif
scsw.cssw = CompressedStack.SetCompressedStack(sc.CompressedStack, prevSecurityContext.CompressedStack);
}
catch
{
scsw.UndoNoThrow();
throw;
}
}
return scsw;
}
/// <internalonly/>
[System.Security.SecuritySafeCritical] // auto-generated
public SecurityContext CreateCopy()
{
if (!isNewCapture)
{
throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_NotNewCaptureContext"));
}
SecurityContext sc = new SecurityContext();
sc.isNewCapture = true;
sc._disableFlow = _disableFlow;
#if !FEATURE_PAL && FEATURE_IMPERSONATION
if (WindowsIdentity != null)
sc._windowsIdentity = new WindowsIdentity(WindowsIdentity.AccessToken);
#endif //!FEATURE_PAL && FEATURE_IMPERSONATION
if (_compressedStack != null)
sc._compressedStack = _compressedStack.CreateCopy();
return sc;
}
/// <internalonly/>
[System.Security.SecuritySafeCritical] // auto-generated
internal SecurityContext CreateMutableCopy()
{
Contract.Assert(!this.isNewCapture);
SecurityContext sc = new SecurityContext();
sc._disableFlow = this._disableFlow;
#if !FEATURE_PAL && FEATURE_IMPERSONATION
if (this.WindowsIdentity != null)
sc._windowsIdentity = new WindowsIdentity(this.WindowsIdentity.AccessToken);
#endif //!FEATURE_PAL && FEATURE_IMPERSONATION
//
if (this._compressedStack != null)
sc._compressedStack = this._compressedStack.CreateCopy();
return sc;
}
[System.Security.SecuritySafeCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
public static SecurityContext Capture( )
{
// check to see if Flow is suppressed
if (IsFlowSuppressed())
return null;
StackCrawlMark stackMark= StackCrawlMark.LookForMyCaller;
SecurityContext sc = SecurityContext.Capture(Thread.CurrentThread.GetExecutionContextReader(), ref stackMark);
if (sc == null)
sc = CreateFullTrustSecurityContext();
return sc;
}
// create a clone from a non-existing SecurityContext
[System.Security.SecurityCritical] // auto-generated
[MethodImpl(MethodImplOptions.AggressiveInlining)]
static internal SecurityContext Capture(ExecutionContext.Reader currThreadEC, ref StackCrawlMark stackMark)
{
// check to see if Flow is suppressed
if (currThreadEC.SecurityContext.IsFlowSuppressed(SecurityContextDisableFlow.All))
return null;
// If we're in FT right now, return null
if (CurrentlyInDefaultFTSecurityContext(currThreadEC))
return null;
return CaptureCore(currThreadEC, ref stackMark);
}
[System.Security.SecurityCritical] // auto-generated
static private SecurityContext CaptureCore(ExecutionContext.Reader currThreadEC, ref StackCrawlMark stackMark)
{
SecurityContext sc = new SecurityContext();
sc.isNewCapture = true;
#if !FEATURE_PAL && FEATURE_IMPERSONATION
// Force create WindowsIdentity
if (!IsWindowsIdentityFlowSuppressed())
{
WindowsIdentity currentIdentity = GetCurrentWI(currThreadEC);
if (currentIdentity != null)
sc._windowsIdentity = new WindowsIdentity(currentIdentity.AccessToken);
}
else
{
sc._disableFlow = SecurityContextDisableFlow.WI;
}
#endif // !FEATURE_PAL && FEATURE_IMPERSONATION
// Force create CompressedStack
sc.CompressedStack = CompressedStack.GetCompressedStack(ref stackMark);
return sc;
}
[System.Security.SecurityCritical] // auto-generated
static internal SecurityContext CreateFullTrustSecurityContext()
{
SecurityContext sc = new SecurityContext();
sc.isNewCapture = true;
#if !FEATURE_PAL && FEATURE_IMPERSONATION
if (IsWindowsIdentityFlowSuppressed())
{
sc._disableFlow = SecurityContextDisableFlow.WI;
}
#endif // !FEATURE_PAL && FEATURE_IMPERSONATION
// Force create CompressedStack
sc.CompressedStack = new CompressedStack(null);
return sc;
}
#if !FEATURE_PAL && FEATURE_IMPERSONATION
static internal bool AlwaysFlowImpersonationPolicy { get { return _alwaysFlowImpersonationPolicy; } }
// Check to see if we have a WI on the thread and return if we do
[System.Security.SecurityCritical] // auto-generated
[ResourceExposure(ResourceScope.None)]
[ResourceConsumption(ResourceScope.Process, ResourceScope.Process)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
static internal WindowsIdentity GetCurrentWI(ExecutionContext.Reader threadEC)
{
return GetCurrentWI(threadEC, _alwaysFlowImpersonationPolicy);
}
[System.Security.SecurityCritical] // auto-generated
[ResourceExposure(ResourceScope.None)]
[ResourceConsumption(ResourceScope.Process, ResourceScope.Process)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
static internal WindowsIdentity GetCurrentWI(ExecutionContext.Reader threadEC, bool cachedAlwaysFlowImpersonationPolicy)
{
Contract.Assert(cachedAlwaysFlowImpersonationPolicy == _alwaysFlowImpersonationPolicy);
if (cachedAlwaysFlowImpersonationPolicy)
{
// Examine the threadtoken at the cost of a kernel call if the user has set the IMP_ALWAYSFLOW mode
return WindowsIdentity.GetCurrentInternal(TokenAccessLevels.MaximumAllowed, true);
}
return threadEC.SecurityContext.WindowsIdentity;
}
[System.Security.SecurityCritical]
[ResourceExposure(ResourceScope.None)]
[ResourceConsumption(ResourceScope.Process, ResourceScope.Process)]
static internal void RestoreCurrentWI(ExecutionContext.Reader currentEC, ExecutionContext.Reader prevEC, WindowsIdentity targetWI, bool cachedAlwaysFlowImpersonationPolicy)
{
Contract.Assert(currentEC.IsSame(Thread.CurrentThread.GetExecutionContextReader()));
Contract.Assert(cachedAlwaysFlowImpersonationPolicy == _alwaysFlowImpersonationPolicy);
// NOTE: cachedAlwaysFlowImpersonationPolicy is a perf optimization to avoid always having to access a static variable here.
if (cachedAlwaysFlowImpersonationPolicy || prevEC.SecurityContext.WindowsIdentity != targetWI)
{
//
// Either we're always flowing, or the target WI was obtained from the current EC in the first place.
//
Contract.Assert(_alwaysFlowImpersonationPolicy || currentEC.SecurityContext.WindowsIdentity == targetWI);
RestoreCurrentWIInternal(targetWI);
}
}
[System.Security.SecurityCritical]
[ResourceExposure(ResourceScope.None)]
[ResourceConsumption(ResourceScope.Process, ResourceScope.Process)]
static private void RestoreCurrentWIInternal(WindowsIdentity targetWI)
{
int hr = Win32.RevertToSelf();
if (hr < 0)
Environment.FailFast(Win32Native.GetMessage(hr));
if (targetWI != null)
{
SafeAccessTokenHandle tokenHandle = targetWI.AccessToken;
if (tokenHandle != null && !tokenHandle.IsInvalid)
{
hr = Win32.ImpersonateLoggedOnUser(tokenHandle);
if (hr < 0)
Environment.FailFast(Win32Native.GetMessage(hr));
}
}
}
[System.Security.SecurityCritical] // auto-generated
internal bool IsDefaultFTSecurityContext()
{
return (WindowsIdentity == null && (CompressedStack == null || CompressedStack.CompressedStackHandle == null));
}
[System.Security.SecurityCritical] // auto-generated
[MethodImpl(MethodImplOptions.AggressiveInlining)]
static internal bool CurrentlyInDefaultFTSecurityContext(ExecutionContext.Reader threadEC)
{
return (IsDefaultThreadSecurityInfo() && GetCurrentWI(threadEC) == null);
}
#else
internal bool IsDefaultFTSecurityContext()
{
return (CompressedStack == null || CompressedStack.CompressedStackHandle == null);
}
static internal bool CurrentlyInDefaultFTSecurityContext(ExecutionContext threadEC)
{
return (IsDefaultThreadSecurityInfo());
}
#endif
#if !FEATURE_PAL && FEATURE_IMPERSONATION
[System.Security.SecuritySafeCritical] // auto-generated
[ResourceExposure(ResourceScope.None)]
[MethodImplAttribute(MethodImplOptions.InternalCall), ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
internal extern static WindowsImpersonationFlowMode GetImpersonationFlowMode();
#endif
[System.Security.SecurityCritical] // auto-generated
[ResourceExposure(ResourceScope.None)]
[MethodImplAttribute(MethodImplOptions.InternalCall), ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
internal extern static bool IsDefaultThreadSecurityInfo();
}
#endif // FEATURE_COMPRESSEDSTACK
}
|