Imported Upstream version 4.0.0~alpha1

Former-commit-id: 806294f5ded97629b74c85c09952f2a74fe182d9
This commit is contained in:
Jo Shields
2015-04-07 09:35:12 +01:00
parent 283343f570
commit 3c1f479b9d
22469 changed files with 2931443 additions and 869343 deletions

View File

@@ -0,0 +1,165 @@
// ==++==
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
// <OWNER>[....]</OWNER>
//
//
// GenericIdentity.cs
//
// A generic identity
//
namespace System.Security.Principal
{
using System;
using System.Diagnostics.Contracts;
// Claims feature is not available in Silverlight
#if !FEATURE_CORECLR
using System.Security.Claims;
using System.Collections.Generic;
using System.Runtime.Serialization;
#endif
[Serializable]
[System.Runtime.InteropServices.ComVisible(true)]
#if!FEATURE_CORECLR
public class GenericIdentity : ClaimsIdentity {
#else
public class GenericIdentity : IIdentity {
#endif
private string m_name;
private string m_type;
#if !FEATURE_CORECLR
[SecuritySafeCritical]
#endif
public GenericIdentity (string name) {
if (name == null)
throw new ArgumentNullException("name");
Contract.EndContractBlock();
m_name = name;
m_type = "";
#if !FEATURE_CORECLR
AddNameClaim();
#endif
}
#if !FEATURE_CORECLR
[SecuritySafeCritical]
#endif
public GenericIdentity (string name, string type) {
if (name == null)
throw new ArgumentNullException("name");
if (type == null)
throw new ArgumentNullException("type");
Contract.EndContractBlock();
m_name = name;
m_type = type;
#if !FEATURE_CORECLR
AddNameClaim();
#endif
}
#if !FEATURE_CORECLR
GenericIdentity()
: base()
{ }
#endif
#if !FEATURE_CORECLR
protected GenericIdentity(GenericIdentity identity)
: base(identity)
{
m_name = identity.m_name;
m_type = identity.m_type;
}
/// <summary>
/// Returns a new instance of <see cref="GenericIdentity"/> with values copied from this object.
/// </summary>
public override ClaimsIdentity Clone()
{
return new GenericIdentity(this);
}
public override IEnumerable<Claim> Claims
{
get
{
return base.Claims;
}
}
#endif
#if !FEATURE_CORECLR
public override string Name {
#else
public virtual string Name {
#endif
get {
return m_name;
}
}
#if !FEATURE_CORECLR
public override string AuthenticationType {
#else
public virtual string AuthenticationType {
#endif
get {
return m_type;
}
}
#if !FEATURE_CORECLR
public override bool IsAuthenticated {
#else
public virtual bool IsAuthenticated {
#endif
get {
return !m_name.Equals("");
}
}
#if !FEATURE_CORECLR
[OnDeserialized()]
private void OnDeserializedMethod(StreamingContext context)
{
// GenericIdentities that have been deserialized from a .net 4.0 runtime, will not have any claims.
// In this case add a name claim, otherwise assume it was deserialized.
bool claimFound = false;
foreach (Claim c in base.Claims)
{
claimFound = true;
break;
}
if (!claimFound)
{
AddNameClaim();
}
}
[SecuritySafeCritical]
private void AddNameClaim()
{
if (m_name != null)
{
base.AddClaim(new Claim(base.NameClaimType, m_name, ClaimValueTypes.String, ClaimsIdentity.DefaultIssuer, ClaimsIdentity.DefaultIssuer, this));
}
}
#endif // #if !FEATURE_CORECLR
}
}

View File

@@ -0,0 +1,147 @@
// ==++==
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
// <OWNER>[....]</OWNER>
//
//
// GenericPrincipal.cs
//
namespace System.Security.Principal
{
using System;
using System.Diagnostics.Contracts;
#if !FEATURE_CORECLR
using System.Collections.Generic;
using System.Runtime.Serialization;
using System.Security.Claims;
#endif
[Serializable]
[System.Runtime.InteropServices.ComVisible(true)]
#if !FEATURE_CORECLR
public class GenericPrincipal : ClaimsPrincipal {
#else
public class GenericPrincipal : IPrincipal {
#endif
private IIdentity m_identity;
private string[] m_roles;
public GenericPrincipal(IIdentity identity, string[] roles) {
if (identity == null)
throw new ArgumentNullException("identity");
Contract.EndContractBlock();
m_identity = identity;
if (roles != null) {
m_roles = new string[roles.Length];
for (int i = 0; i < roles.Length; ++i) {
m_roles[i] = roles[i];
}
}
else {
m_roles = null;
}
#if !FEATURE_CORECLR
AddIdentityWithRoles(m_identity, m_roles);
}
[OnDeserialized()]
private void OnDeserializedMethod(StreamingContext context)
{
// Here it the matrix of possible serializations
//
// Version From | Version To | ClaimsIdentities | Roles
// ============ ========== ================ ========================================================
// 4.0 4.5 None We always need to add a ClaimsIdentity, if Roles add them
//
// 4.5 4.5 Yes There should be a ClaimsIdentity, DebugAssert if this is not the case
// If there are roles, attach them to the first ClaimsIdentity.
// If there is no non-null ClaimsIdentity, add one. However, this is unusual and may be a bug.
ClaimsIdentity firstNonNullIdentity = null;
foreach (var identity in base.Identities)
{
if (identity != null)
{
firstNonNullIdentity = identity;
break;
}
}
if (m_roles != null && m_roles.Length > 0 && firstNonNullIdentity != null)
{
firstNonNullIdentity.ExternalClaims.Add(new RoleClaimProvider(ClaimsIdentity.DefaultIssuer, m_roles, firstNonNullIdentity).Claims);
}
else if (firstNonNullIdentity == null)
{
AddIdentityWithRoles(m_identity, m_roles);
}
}
/// <summary>
/// helper method to add roles
/// </summary>
[SecuritySafeCritical]
void AddIdentityWithRoles(IIdentity identity, string[] roles)
{
ClaimsIdentity claimsIdentity = identity as ClaimsIdentity;
if (claimsIdentity != null)
{
claimsIdentity = claimsIdentity.Clone();
}
else
{
claimsIdentity = new ClaimsIdentity(identity);
}
// if roles are not null then we need to add a provider
if (roles != null && roles.Length > 0)
{
claimsIdentity.ExternalClaims.Add(new RoleClaimProvider(ClaimsIdentity.DefaultIssuer, roles, claimsIdentity).Claims);
}
base.AddIdentity(claimsIdentity);
}
#else
}
#endif
#if !FEATURE_CORECLR
public override IIdentity Identity {
#else
public virtual IIdentity Identity {
#endif
get { return m_identity; }
}
#if !FEATURE_CORECLR
public override bool IsInRole(string role) {
#else
public virtual bool IsInRole (string role) {
#endif
if (role == null || m_roles == null)
return false;
for (int i = 0; i < m_roles.Length; ++i) {
if (m_roles[i] != null && String.Compare(m_roles[i], role, StringComparison.OrdinalIgnoreCase) == 0)
return true;
}
#if !FEATURE_CORECLR
// it may be the case a ClaimsIdentity was passed in as the IIdentity which may have contained claims, they need to be checked.
return base.IsInRole(role);
#else
return false;
#endif
}
}
}

View File

@@ -0,0 +1,65 @@
// ==++==
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
// <OWNER>[....]</OWNER>
//
using System;
using Microsoft.Win32;
using System.Runtime.Serialization;
using System.Text;
using System.Globalization;
using System.Security.Permissions;
namespace System.Security.Principal
{
[Serializable]
[System.Runtime.InteropServices.ComVisible(false)]
public sealed class IdentityNotMappedException : SystemException
{
private IdentityReferenceCollection unmappedIdentities;
public IdentityNotMappedException()
: base( Environment.GetResourceString( "IdentityReference_IdentityNotMapped" ))
{
}
public IdentityNotMappedException( string message )
: base( message )
{
}
public IdentityNotMappedException( String message, Exception inner )
: base( message, inner )
{
}
internal IdentityNotMappedException(string message, IdentityReferenceCollection unmappedIdentities)
: this( message )
{
this.unmappedIdentities = unmappedIdentities;
}
internal IdentityNotMappedException( SerializationInfo info, StreamingContext context )
: base ( info, context ) {}
[System.Security.SecurityCritical] // auto-generated_required
public override void GetObjectData( SerializationInfo serializationInfo, StreamingContext streamingContext )
{
base.GetObjectData(serializationInfo, streamingContext);
}
public IdentityReferenceCollection UnmappedIdentities {
get {
if (unmappedIdentities == null) {
unmappedIdentities = new IdentityReferenceCollection();
}
return unmappedIdentities;
}
}
}
}

View File

@@ -0,0 +1,67 @@
// ==++==
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
// <OWNER>[....]</OWNER>
//
using System;
using System.Security.Policy; // defines Url class
using System.Globalization;
using System.Diagnostics.Contracts;
namespace System.Security.Principal
{
[System.Runtime.InteropServices.ComVisible(false)]
public abstract class IdentityReference
{
internal IdentityReference()
{
// exists to prevent creation user-derived classes (for now)
}
// public abstract string Scheme { get; }
public abstract string Value { get; }
// public virtual Url Url
// {
// get { return new Url(""); } //
public abstract bool IsValidTargetType( Type targetType );
public abstract IdentityReference Translate( Type targetType );
public override abstract bool Equals( object o );
public override abstract int GetHashCode();
public override abstract string ToString();
public static bool operator==( IdentityReference left, IdentityReference right )
{
object l = left;
object r = right;
if ( l == null && r == null )
{
return true;
}
else if ( l == null || r == null )
{
return false;
}
else
{
return left.Equals( right );
}
}
public static bool operator!=( IdentityReference left, IdentityReference right )
{
return !( left == right ); // invoke operator==
}
}
}

View File

@@ -0,0 +1,32 @@
// ==++==
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
// <OWNER>[....]</OWNER>
//
//
// IIdentity.cs
//
// All identities will implement this interface
//
namespace System.Security.Principal
{
using System.Runtime.Remoting;
using System;
using System.Security.Util;
[System.Runtime.InteropServices.ComVisible(true)]
public interface IIdentity {
// Access to the name string
string Name { get; }
// Access to Authentication 'type' info
string AuthenticationType { get; }
// Determine if this represents the unauthenticated identity
bool IsAuthenticated { get; }
}
}

View File

@@ -0,0 +1,29 @@
// ==++==
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
// <OWNER>[....]</OWNER>
//
//
// IPrincipal.cs
//
// All roles will implement this interface
//
namespace System.Security.Principal
{
using System.Runtime.Remoting;
using System;
using System.Security.Util;
[System.Runtime.InteropServices.ComVisible(true)]
public interface IPrincipal {
// Retrieve the identity object
IIdentity Identity { get; }
// Perform a check for a specific role
bool IsInRole (string role);
}
}

View File

@@ -0,0 +1,457 @@
// ==++==
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
// <OWNER>[....]</OWNER>
namespace System.Security.Principal
{
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.Security.Permissions;
[System.Runtime.InteropServices.ComVisible(false)]
public class IdentityReferenceCollection : ICollection<IdentityReference>
{
#region Private members
//
// Container enumerated by this collection
//
private List<IdentityReference> _Identities;
#endregion
#region Constructors
//
// Creates an empty collection of default size
//
public IdentityReferenceCollection()
: this( 0 )
{
}
//
// Creates an empty collection of given initial size
//
public IdentityReferenceCollection( int capacity )
{
_Identities = new List<IdentityReference>( capacity );
}
#endregion
#region ICollection<IdentityReference> implementation
public void CopyTo( IdentityReference[] array, int offset )
{
_Identities.CopyTo( 0, array, offset, Count );
}
public int Count
{
get { return _Identities.Count; }
}
public bool IsReadOnly
{
get { return false; }
}
public void Add( IdentityReference identity )
{
if ( identity == null )
{
throw new ArgumentNullException( "identity" );
}
Contract.EndContractBlock();
_Identities.Add( identity );
}
public bool Remove( IdentityReference identity )
{
if ( identity == null )
{
throw new ArgumentNullException( "identity" );
}
Contract.EndContractBlock();
if ( Contains( identity ))
{
_Identities.Remove( identity );
return true;
}
return false;
}
public void Clear()
{
_Identities.Clear();
}
public bool Contains( IdentityReference identity )
{
if ( identity == null )
{
throw new ArgumentNullException( "identity" );
}
Contract.EndContractBlock();
return _Identities.Contains( identity );
}
#endregion
#region IEnumerable<IdentityReference> implementation
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
public IEnumerator<IdentityReference> GetEnumerator()
{
return new IdentityReferenceEnumerator( this );
}
#endregion
#region Public methods
public IdentityReference this[int index]
{
get
{
return _Identities[index];
}
set
{
if ( value == null )
{
throw new ArgumentNullException( "value" );
}
Contract.EndContractBlock();
_Identities[index] = value;
}
}
internal List<IdentityReference> Identities
{
get { return _Identities; }
}
public IdentityReferenceCollection Translate( Type targetType )
{
return Translate( targetType, false );
}
[SecuritySafeCritical]
[SecurityPermission(SecurityAction.Demand, ControlPrincipal = true)]
public IdentityReferenceCollection Translate( Type targetType, bool forceSuccess )
{
if ( targetType == null )
{
throw new ArgumentNullException( "targetType" );
}
//
// Target type must be a subclass of IdentityReference
//
if ( !targetType.IsSubclassOf( typeof( IdentityReference )))
{
throw new ArgumentException( Environment.GetResourceString( "IdentityReference_MustBeIdentityReference" ), "targetType" );
}
Contract.EndContractBlock();
//
// if the source collection is empty, just return an empty collection
//
if (Identities.Count == 0)
{
return new IdentityReferenceCollection();
}
int SourceSidsCount = 0;
int SourceNTAccountsCount = 0;
//
// First, see how many of each of the source types we have.
// The cases where source type == target type require no conversion.
//
for ( int i = 0; i < Identities.Count; i++ )
{
Type type = Identities[i].GetType();
if ( type == targetType )
{
continue;
}
else if ( type == typeof( SecurityIdentifier ))
{
SourceSidsCount += 1;
}
else if ( type == typeof( NTAccount ))
{
SourceNTAccountsCount += 1;
}
else
{
//
// Rare case that we have defined a type of identity reference and
// not included it in the code logic above (this is more like a bug in the implementation
// but only as long as we do not allow IdentityReference to be subclassed outside of the BCL)
//
Contract.Assert( false, "Source type is an IdentityReference type which has not been included in translation logic.");
throw new SystemException();
}
}
bool Homogeneous = false;
IdentityReferenceCollection SourceSids = null;
IdentityReferenceCollection SourceNTAccounts = null;
if ( SourceSidsCount == Count )
{
Homogeneous = true;
SourceSids = this;
}
else if ( SourceSidsCount > 0 )
{
SourceSids = new IdentityReferenceCollection( SourceSidsCount );
}
if ( SourceNTAccountsCount == Count )
{
Homogeneous = true;
SourceNTAccounts = this;
}
else if ( SourceNTAccountsCount > 0 )
{
SourceNTAccounts = new IdentityReferenceCollection( SourceNTAccountsCount );
}
//
// Repackage only if the source is not homogeneous (contains different source types)
//
IdentityReferenceCollection Result = null;
if ( !Homogeneous )
{
Result = new IdentityReferenceCollection( Identities.Count );
for ( int i = 0; i < Identities.Count; i++ )
{
IdentityReference id = this[i];
Type type = id.GetType();
if ( type == targetType )
{
continue;
}
else if ( type == typeof( SecurityIdentifier ))
{
SourceSids.Add( id );
}
else if ( type == typeof( NTAccount ))
{
SourceNTAccounts.Add( id );
}
else
{
//
// Rare case that we have defined a type of identity reference and
// not included it in the code logic above (this is more like a bug in the implementation
// but only as long as we do not allow IdentityReference to be subclassed outside of the BCL)
//
Contract.Assert( false, "Source type is an IdentityReference type which has not been included in translation logic.");
throw new SystemException();
}
}
}
bool someFailed = false;
IdentityReferenceCollection TargetSids = null, TargetNTAccounts = null;
if ( SourceSidsCount > 0 )
{
TargetSids = SecurityIdentifier.Translate( SourceSids, targetType, out someFailed );
if ( Homogeneous && !(forceSuccess && someFailed))
{
Result = TargetSids;
}
}
if ( SourceNTAccountsCount > 0 )
{
TargetNTAccounts = NTAccount.Translate( SourceNTAccounts, targetType, out someFailed );
if ( Homogeneous && !(forceSuccess && someFailed))
{
Result = TargetNTAccounts;
}
}
if (forceSuccess && someFailed) {
//
// Need to throw an exception here and provide information regarding
// which identity references could not be translated to the target type
//
Result = new IdentityReferenceCollection();
if (TargetSids != null) {
foreach (IdentityReference id in TargetSids) {
if ( id.GetType() != targetType )
{
Result.Add(id);
}
}
}
if (TargetNTAccounts != null) {
foreach (IdentityReference id in TargetNTAccounts) {
if ( id.GetType() != targetType )
{
Result.Add(id);
}
}
}
throw new IdentityNotMappedException( Environment.GetResourceString("IdentityReference_IdentityNotMapped"), Result);
}
else if ( !Homogeneous )
{
SourceSidsCount = 0;
SourceNTAccountsCount = 0;
Result = new IdentityReferenceCollection( Identities.Count );
for ( int i = 0; i < Identities.Count; i++ )
{
IdentityReference id = this[i];
Type type = id.GetType();
if ( type == targetType )
{
Result.Add( id );
}
else if ( type == typeof( SecurityIdentifier ))
{
Result.Add( TargetSids[SourceSidsCount++] );
}
else if ( type == typeof( NTAccount ))
{
Result.Add( TargetNTAccounts[SourceNTAccountsCount++] );
}
else
{
//
// Rare case that we have defined a type of identity reference and
// not included it in the code logic above (this is more like a bug in the implementation
// but only as long as we do not allow IdentityReference to be subclassed outside of the BCL)
//
Contract.Assert( false, "Source type is an IdentityReference type which has not been included in translation logic.");
throw new SystemException();
}
}
}
return Result;
}
#endregion
}
[System.Runtime.InteropServices.ComVisible(false)]
internal class IdentityReferenceEnumerator : IEnumerator<IdentityReference>, IDisposable
{
#region Private members
//
// Current enumeration index
//
private int _Current;
//
// Parent collection
//
private readonly IdentityReferenceCollection _Collection;
#endregion
#region Constructors
internal IdentityReferenceEnumerator( IdentityReferenceCollection collection )
{
if ( collection == null )
{
throw new ArgumentNullException( "collection" );
}
Contract.EndContractBlock();
_Collection = collection;
_Current = -1;
}
#endregion
#region IEnumerator implementation
/// <internalonly/>
object IEnumerator.Current
{
get { return _Collection.Identities[_Current]; }
}
public IdentityReference Current
{
get { return (( IEnumerator )this).Current as IdentityReference; }
}
public bool MoveNext()
{
_Current++;
return ( _Current < _Collection.Count );
}
public void Reset()
{
_Current = -1;
}
public void Dispose()
{
}
#endregion
}
}

View File

@@ -0,0 +1,453 @@
// ==++==
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
// <OWNER>[....]</OWNER>
//
using Microsoft.Win32;
using Microsoft.Win32.SafeHandles;
using System;
using System.Runtime.InteropServices;
using System.Globalization;
using System.Security.Permissions;
using System.Diagnostics.Contracts;
namespace System.Security.Principal
{
[System.Runtime.InteropServices.ComVisible(false)]
public sealed class NTAccount : IdentityReference
{
#region Private members
private readonly string _Name;
//
// Limit for nt account names for users is 20 while that for groups is 256
//
internal const int MaximumAccountNameLength = 256;
//
// Limit for dns domain names is 255
//
internal const int MaximumDomainNameLength = 255;
#endregion
#region Constructors
public NTAccount( string domainName, string accountName )
{
if ( accountName == null )
{
throw new ArgumentNullException( "accountName" );
}
if ( accountName.Length == 0 )
{
throw new ArgumentException( Environment.GetResourceString( "Argument_StringZeroLength" ), "accountName" );
}
if ( accountName.Length > MaximumAccountNameLength )
{
throw new ArgumentException( Environment.GetResourceString( "IdentityReference_AccountNameTooLong" ), "accountName");
}
if ( domainName != null && domainName.Length > MaximumDomainNameLength )
{
throw new ArgumentException( Environment.GetResourceString( "IdentityReference_DomainNameTooLong" ), "domainName");
}
Contract.EndContractBlock();
if ( domainName == null || domainName.Length == 0 )
{
_Name = accountName;
}
else
{
_Name = domainName + "\\" + accountName;
}
}
public NTAccount( string name )
{
if ( name == null )
{
throw new ArgumentNullException( "name" );
}
if ( name.Length == 0 )
{
throw new ArgumentException( Environment.GetResourceString( "Argument_StringZeroLength" ), "name" );
}
if ( name.Length > ( MaximumDomainNameLength + 1 /* '\' */ + MaximumAccountNameLength ))
{
throw new ArgumentException( Environment.GetResourceString( "IdentityReference_AccountNameTooLong" ), "name");
}
Contract.EndContractBlock();
_Name = name;
}
#endregion
#region Inherited properties and methods
public override string Value
{
get { return ToString(); }
}
public override bool IsValidTargetType( Type targetType )
{
if ( targetType == typeof( SecurityIdentifier ))
{
return true;
}
else if ( targetType == typeof( NTAccount ))
{
return true;
}
else
{
return false;
}
}
[SecurityPermission(SecurityAction.Demand, ControlPrincipal = true)]
[SecuritySafeCritical]
public override IdentityReference Translate( Type targetType )
{
if ( targetType == null )
{
throw new ArgumentNullException( "targetType" );
}
Contract.EndContractBlock();
if ( targetType == typeof( NTAccount ))
{
return this; // assumes that NTAccount objects are immutable
}
else if ( targetType == typeof( SecurityIdentifier ))
{
IdentityReferenceCollection irSource = new IdentityReferenceCollection( 1 );
irSource.Add( this );
IdentityReferenceCollection irTarget;
irTarget = NTAccount.Translate( irSource, targetType, true );
return irTarget[0];
}
else
{
throw new ArgumentException( Environment.GetResourceString( "IdentityReference_MustBeIdentityReference" ), "targetType" );
}
}
public override bool Equals( object o )
{
if ( o == null )
{
return false;
}
NTAccount nta = o as NTAccount;
if ( nta == null )
{
return false;
}
return ( this == nta ); // invokes operator==
}
public override int GetHashCode() {
return StringComparer.InvariantCultureIgnoreCase.GetHashCode(_Name);
}
public override string ToString()
{
return _Name;
}
[System.Security.SecurityCritical] // auto-generated
internal static IdentityReferenceCollection Translate( IdentityReferenceCollection sourceAccounts, Type targetType, bool forceSuccess)
{
bool SomeFailed = false;
IdentityReferenceCollection Result;
Result = Translate( sourceAccounts, targetType, out SomeFailed );
if (forceSuccess && SomeFailed) {
IdentityReferenceCollection UnmappedIdentities = new IdentityReferenceCollection();
foreach (IdentityReference id in Result)
{
if (id.GetType() != targetType)
{
UnmappedIdentities.Add(id);
}
}
throw new IdentityNotMappedException(Environment.GetResourceString("IdentityReference_IdentityNotMapped"), UnmappedIdentities);
}
return Result;
}
[System.Security.SecurityCritical] // auto-generated
internal static IdentityReferenceCollection Translate( IdentityReferenceCollection sourceAccounts, Type targetType, out bool someFailed )
{
if ( sourceAccounts == null )
{
throw new ArgumentNullException( "sourceAccounts" );
}
Contract.EndContractBlock();
if ( targetType == typeof( SecurityIdentifier ))
{
return TranslateToSids( sourceAccounts, out someFailed );
}
throw new ArgumentException( Environment.GetResourceString( "IdentityReference_MustBeIdentityReference" ), "targetType" );
}
#endregion
#region Operators
public static bool operator==( NTAccount left, NTAccount right )
{
object l = left;
object r = right;
if ( l == null && r == null )
{
return true;
}
else if ( l == null || r == null )
{
return false;
}
else
{
return ( left.ToString().Equals(right.ToString(), StringComparison.OrdinalIgnoreCase));
}
}
public static bool operator!=( NTAccount left, NTAccount right )
{
return !( left == right ); // invoke operator==
}
#endregion
#region Private methods
[System.Security.SecurityCritical] // auto-generated
private static IdentityReferenceCollection TranslateToSids( IdentityReferenceCollection sourceAccounts, out bool someFailed )
{
if ( sourceAccounts == null )
{
throw new ArgumentNullException( "sourceAccounts" );
}
if ( sourceAccounts.Count == 0 )
{
throw new ArgumentException( Environment.GetResourceString( "Arg_EmptyCollection" ), "sourceAccounts" );
}
Contract.EndContractBlock();
SafeLsaPolicyHandle LsaHandle = SafeLsaPolicyHandle.InvalidHandle;
SafeLsaMemoryHandle ReferencedDomainsPtr = SafeLsaMemoryHandle.InvalidHandle;
SafeLsaMemoryHandle SidsPtr = SafeLsaMemoryHandle.InvalidHandle;
try
{
//
// Construct an array of unicode strings
//
Win32Native.UNICODE_STRING[] Names = new Win32Native.UNICODE_STRING[ sourceAccounts.Count ];
int currentName = 0;
foreach ( IdentityReference id in sourceAccounts )
{
NTAccount nta = id as NTAccount;
if ( nta == null )
{
throw new ArgumentException( Environment.GetResourceString( "Argument_ImproperType" ), "sourceAccounts" );
}
Names[currentName].Buffer = nta.ToString();
if (Names[currentName].Buffer.Length * 2 + 2 > ushort.MaxValue)
{
// this should never happen since we are already validating account name length in constructor and
// it is less than this limit
Contract.Assert(false, "NTAccount::TranslateToSids - source account name is too long.");
throw new SystemException();
}
Names[currentName].Length = (ushort)(Names[currentName].Buffer.Length * 2);
Names[currentName].MaximumLength = (ushort)(Names[currentName].Length + 2);
currentName++;
}
//
// Open LSA policy (for lookup requires it)
//
LsaHandle = Win32.LsaOpenPolicy( null, PolicyRights.POLICY_LOOKUP_NAMES );
//
// Now perform the actual lookup
//
someFailed = false;
uint ReturnCode;
if ( Win32.LsaLookupNames2Supported )
{
ReturnCode = Win32Native.LsaLookupNames2( LsaHandle, 0, sourceAccounts.Count, Names, ref ReferencedDomainsPtr, ref SidsPtr );
}
else
{
ReturnCode = Win32Native.LsaLookupNames( LsaHandle, sourceAccounts.Count, Names, ref ReferencedDomainsPtr, ref SidsPtr );
}
//
// Make a decision regarding whether it makes sense to proceed
// based on the return code and the value of the forceSuccess argument
//
if ( ReturnCode == Win32Native.STATUS_NO_MEMORY ||
ReturnCode == Win32Native.STATUS_INSUFFICIENT_RESOURCES )
{
throw new OutOfMemoryException();
}
else if ( ReturnCode == Win32Native.STATUS_ACCESS_DENIED )
{
throw new UnauthorizedAccessException();
}
else if ( ReturnCode == Win32Native.STATUS_NONE_MAPPED ||
ReturnCode == Win32Native.STATUS_SOME_NOT_MAPPED )
{
someFailed = true;
}
else if ( ReturnCode != 0 )
{
int win32ErrorCode = Win32Native.LsaNtStatusToWinError(unchecked((int)ReturnCode));
if (win32ErrorCode != Win32Native.ERROR_TRUSTED_RELATIONSHIP_FAILURE)
{
Contract.Assert( false, string.Format( CultureInfo.InvariantCulture, "Win32Native.LsaLookupNames(2) returned unrecognized error {0}", win32ErrorCode ));
}
throw new SystemException(Win32Native.GetMessage(win32ErrorCode));
}
//
// Interpret the results and generate SID objects
//
IdentityReferenceCollection Result = new IdentityReferenceCollection( sourceAccounts.Count );
if ( ReturnCode == 0 || ReturnCode == Win32Native.STATUS_SOME_NOT_MAPPED )
{
if ( Win32.LsaLookupNames2Supported )
{
SidsPtr.Initialize((uint)sourceAccounts.Count, (uint)Marshal.SizeOf(typeof(Win32Native.LSA_TRANSLATED_SID2)));
Win32.InitializeReferencedDomainsPointer(ReferencedDomainsPtr);
Win32Native.LSA_TRANSLATED_SID2[] translatedSids = new Win32Native.LSA_TRANSLATED_SID2[sourceAccounts.Count];
SidsPtr.ReadArray(0, translatedSids, 0, translatedSids.Length);
for (int i = 0; i < sourceAccounts.Count; i++)
{
Win32Native.LSA_TRANSLATED_SID2 Lts = translatedSids[i];
//
// Only some names are recognized as NTAccount objects
//
switch ((SidNameUse)Lts.Use)
{
case SidNameUse.User:
case SidNameUse.Group:
case SidNameUse.Alias:
case SidNameUse.Computer:
case SidNameUse.WellKnownGroup:
Result.Add( new SecurityIdentifier( Lts.Sid, true ));
break;
default:
someFailed = true;
Result.Add( sourceAccounts[i] );
break;
}
}
}
else
{
SidsPtr.Initialize((uint)sourceAccounts.Count, (uint)Marshal.SizeOf(typeof(Win32Native.LSA_TRANSLATED_SID)));
Win32.InitializeReferencedDomainsPointer(ReferencedDomainsPtr);
Win32Native.LSA_REFERENCED_DOMAIN_LIST rdl = ReferencedDomainsPtr.Read<Win32Native.LSA_REFERENCED_DOMAIN_LIST>(0);
SecurityIdentifier[] ReferencedDomains = new SecurityIdentifier[ rdl.Entries ];
for (int i = 0; i < rdl.Entries; i++)
{
Win32Native.LSA_TRUST_INFORMATION ti = ( Win32Native.LSA_TRUST_INFORMATION )Marshal.PtrToStructure( new IntPtr(( long )rdl.Domains + i * Marshal.SizeOf( typeof( Win32Native.LSA_TRUST_INFORMATION ))), typeof( Win32Native.LSA_TRUST_INFORMATION ));
ReferencedDomains[i] = new SecurityIdentifier( ti.Sid, true );
}
Win32Native.LSA_TRANSLATED_SID[] translatedSids = new Win32Native.LSA_TRANSLATED_SID[sourceAccounts.Count];
SidsPtr.ReadArray(0, translatedSids, 0, translatedSids.Length);
for (int i = 0; i < sourceAccounts.Count; i++)
{
Win32Native.LSA_TRANSLATED_SID Lts = translatedSids[i];
switch ((SidNameUse)Lts.Use)
{
case SidNameUse.User:
case SidNameUse.Group:
case SidNameUse.Alias:
case SidNameUse.Computer:
case SidNameUse.WellKnownGroup:
Result.Add( new SecurityIdentifier( ReferencedDomains[ Lts.DomainIndex ], Lts.Rid ));
break;
default:
someFailed = true;
Result.Add( sourceAccounts[i] );
break;
}
}
}
}
else
{
for (int i = 0; i < sourceAccounts.Count; i++)
{
Result.Add( sourceAccounts[i] );
}
}
return Result;
}
finally
{
LsaHandle.Dispose();
ReferencedDomainsPtr.Dispose();
SidsPtr.Dispose();
}
}
#endregion
}
}

View File

@@ -0,0 +1,28 @@
// ==++==
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
// <OWNER>[....]</OWNER>
//
//
// PrincipalPolicy.cs
//
// Enum describing what type of principal to create by default (assuming no
// principal has been set on the AppDomain).
//
namespace System.Security.Principal
{
[Serializable]
[System.Runtime.InteropServices.ComVisible(true)]
public enum PrincipalPolicy {
// Note: it's important that the default policy has the value 0.
UnauthenticatedPrincipal = 0,
NoPrincipal = 1,
#if !FEATURE_PAL
WindowsPrincipal = 2,
#endif // !FEATURE_PAL
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,43 @@
// ==++==
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
// <OWNER>[....]</OWNER>
//
namespace System.Security.Principal
{
[Serializable]
[Flags]
[System.Runtime.InteropServices.ComVisible(true)]
public enum TokenAccessLevels {
AssignPrimary = 0x00000001,
Duplicate = 0x00000002,
Impersonate = 0x00000004,
Query = 0x00000008,
QuerySource = 0x00000010,
AdjustPrivileges = 0x00000020,
AdjustGroups = 0x00000040,
AdjustDefault = 0x00000080,
AdjustSessionId = 0x00000100,
Read = 0x00020000 | Query,
Write = 0x00020000 | AdjustPrivileges | AdjustGroups | AdjustDefault,
AllAccess = 0x000F0000 |
AssignPrimary |
Duplicate |
Impersonate |
Query |
QuerySource |
AdjustPrivileges |
AdjustGroups |
AdjustDefault |
AdjustSessionId,
MaximumAllowed = 0x02000000
}
}

View File

@@ -0,0 +1,22 @@
// ==++==
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
// <OWNER>[....]</OWNER>
//
namespace System.Security.Principal
{
#if !FEATURE_NETCORE
[Serializable]
[System.Runtime.InteropServices.ComVisible(true)]
#endif
public enum TokenImpersonationLevel {
None = 0,
Anonymous = 1,
Identification = 2,
Impersonation = 3,
Delegation = 4
}
}

View File

@@ -0,0 +1,457 @@
// ==++==
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
// <OWNER>[....]</OWNER>
//
using Microsoft.Win32;
using Microsoft.Win32.SafeHandles;
using System;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Security.Permissions;
using System.Text;
using System.Runtime.Versioning;
namespace System.Security.Principal
{
using BOOL = System.Int32;
using DWORD = System.UInt32;
using System.Globalization;
using System.Diagnostics.Contracts;
[Flags]
internal enum PolicyRights
{
POLICY_VIEW_LOCAL_INFORMATION = 0x00000001,
POLICY_VIEW_AUDIT_INFORMATION = 0x00000002,
POLICY_GET_PRIVATE_INFORMATION = 0x00000004,
POLICY_TRUST_ADMIN = 0x00000008,
POLICY_CREATE_ACCOUNT = 0x00000010,
POLICY_CREATE_SECRET = 0x00000020,
POLICY_CREATE_PRIVILEGE = 0x00000040,
POLICY_SET_DEFAULT_QUOTA_LIMITS = 0x00000080,
POLICY_SET_AUDIT_REQUIREMENTS = 0x00000100,
POLICY_AUDIT_LOG_ADMIN = 0x00000200,
POLICY_SERVER_ADMIN = 0x00000400,
POLICY_LOOKUP_NAMES = 0x00000800,
POLICY_NOTIFICATION = 0x00001000,
}
internal static class Win32
{
internal const BOOL FALSE = 0;
internal const BOOL TRUE = 1;
private static bool _LsaLookupNames2Supported;
private static bool _WellKnownSidApisSupported;
[System.Security.SecuritySafeCritical] // auto-generated
static Win32()
{
Win32Native.OSVERSIONINFO osvi = new Win32Native.OSVERSIONINFO();
bool r = Environment.GetVersion(osvi);
if ( !r )
{
Contract.Assert( r, "OSVersion native call failed." );
throw new SystemException( Environment.GetResourceString( "InvalidOperation_GetVersion" ));
}
if (osvi.MajorVersion > 5 || osvi.MinorVersion > 0 ) // Windows XP/2003 and above
{
//
// LsaLookupNames2 supported only on XP and Windows 2003 and above
//
_LsaLookupNames2Supported = true;
_WellKnownSidApisSupported = true;
}
else
{
// Win2000
_LsaLookupNames2Supported = false;
//
// WellKnownSid apis are only supported on Windows 2000 SP3 and above
// (so we need sp info)
//
Win32Native.OSVERSIONINFOEX osviex = new Win32Native.OSVERSIONINFOEX();
r = Environment.GetVersionEx(osviex);
if ( !r )
{
Contract.Assert( r, "OSVersion native call failed");
throw new SystemException( Environment.GetResourceString( "InvalidOperation_GetVersion" ));
}
if (osviex.ServicePackMajor < 3)
{
_WellKnownSidApisSupported = false;
}
else
{
_WellKnownSidApisSupported = true;
}
}
}
internal static bool LsaLookupNames2Supported
{
get {
return _LsaLookupNames2Supported;
}
}
internal static bool WellKnownSidApisSupported
{
get {
return _WellKnownSidApisSupported;
}
}
//
// Wrapper around advapi32.LsaOpenPolicy
//
[System.Security.SecurityCritical] // auto-generated
internal static SafeLsaPolicyHandle LsaOpenPolicy(
string systemName,
PolicyRights rights )
{
uint ReturnCode;
SafeLsaPolicyHandle Result;
Win32Native.LSA_OBJECT_ATTRIBUTES Loa;
Loa.Length = Marshal.SizeOf( typeof( Win32Native.LSA_OBJECT_ATTRIBUTES ));
Loa.RootDirectory = IntPtr.Zero;
Loa.ObjectName = IntPtr.Zero;
Loa.Attributes = 0;
Loa.SecurityDescriptor = IntPtr.Zero;
Loa.SecurityQualityOfService = IntPtr.Zero;
if ( 0 == ( ReturnCode = Win32Native.LsaOpenPolicy( systemName, ref Loa, ( int )rights, out Result )))
{
return Result;
}
else if ( ReturnCode == Win32Native.STATUS_ACCESS_DENIED )
{
throw new UnauthorizedAccessException();
}
else if ( ReturnCode == Win32Native.STATUS_INSUFFICIENT_RESOURCES ||
ReturnCode == Win32Native.STATUS_NO_MEMORY )
{
throw new OutOfMemoryException();
}
else
{
int win32ErrorCode = Win32Native.LsaNtStatusToWinError(unchecked((int) ReturnCode));
throw new SystemException(Win32Native.GetMessage(win32ErrorCode));
}
}
[System.Security.SecurityCritical] // auto-generated
internal static byte[] ConvertIntPtrSidToByteArraySid( IntPtr binaryForm )
{
byte[] ResultSid;
//
// Verify the revision (just sanity, should never fail to be 1)
//
byte Revision = Marshal.ReadByte( binaryForm, 0 );
if ( Revision != SecurityIdentifier.Revision )
{
throw new ArgumentException(Environment.GetResourceString( "IdentityReference_InvalidSidRevision" ), "binaryForm");
}
//
// Need the subauthority count in order to figure out how many bytes to read
//
byte SubAuthorityCount = Marshal.ReadByte( binaryForm, 1 );
if ( SubAuthorityCount < 0 ||
SubAuthorityCount > SecurityIdentifier.MaxSubAuthorities )
{
throw new ArgumentException(Environment.GetResourceString( "IdentityReference_InvalidNumberOfSubauthorities", SecurityIdentifier.MaxSubAuthorities), "binaryForm");
}
//
// Compute the size of the binary form of this SID and allocate the memory
//
int BinaryLength = 1 + 1 + 6 + SubAuthorityCount * 4;
ResultSid = new byte[ BinaryLength ];
//
// Extract the data from the returned pointer
//
Marshal.Copy( binaryForm, ResultSid, 0, BinaryLength );
return ResultSid;
}
//
// Wrapper around advapi32.ConvertStringSidToSidW
//
[System.Security.SecurityCritical] // auto-generated
internal static int CreateSidFromString(
string stringSid,
out byte[] resultSid
)
{
int ErrorCode;
IntPtr ByteArray = IntPtr.Zero;
try
{
if ( TRUE != Win32Native.ConvertStringSidToSid( stringSid, out ByteArray ))
{
ErrorCode = Marshal.GetLastWin32Error();
goto Error;
}
resultSid = ConvertIntPtrSidToByteArraySid( ByteArray );
}
finally
{
//
// Now is a good time to get rid of the returned pointer
//
Win32Native.LocalFree( ByteArray );
}
//
// Now invoke the SecurityIdentifier factory method to create the result
//
return Win32Native.ERROR_SUCCESS;
Error:
resultSid = null;
return ErrorCode;
}
//
// Wrapper around advapi32.CreateWellKnownSid
//
[System.Security.SecurityCritical] // auto-generated
internal static int CreateWellKnownSid(
WellKnownSidType sidType,
SecurityIdentifier domainSid,
out byte[] resultSid
)
{
//
// Check if the api is supported
//
if (!WellKnownSidApisSupported) {
throw new PlatformNotSupportedException( Environment.GetResourceString( "PlatformNotSupported_RequiresW2kSP3" ));
}
//
// Passing an array as big as it can ever be is a small price to pay for
// not having to P/Invoke twice (once to get the buffer, once to get the data)
//
uint length = ( uint )SecurityIdentifier.MaxBinaryLength;
resultSid = new byte[ length ];
if ( FALSE != Win32Native.CreateWellKnownSid(( int )sidType, domainSid == null ? null : domainSid.BinaryForm, resultSid, ref length ))
{
return Win32Native.ERROR_SUCCESS;
}
else
{
resultSid = null;
return Marshal.GetLastWin32Error();
}
}
//
// Wrapper around advapi32.EqualDomainSid
//
[System.Security.SecurityCritical] // auto-generated
internal static bool IsEqualDomainSid( SecurityIdentifier sid1, SecurityIdentifier sid2 )
{
//
// Check if the api is supported
//
if (!WellKnownSidApisSupported) {
throw new PlatformNotSupportedException( Environment.GetResourceString( "PlatformNotSupported_RequiresW2kSP3" ));
}
if ( sid1 == null || sid2 == null )
{
return false;
}
else
{
bool result;
byte[] BinaryForm1 = new Byte[sid1.BinaryLength];
sid1.GetBinaryForm( BinaryForm1, 0 );
byte[] BinaryForm2 = new Byte[sid2.BinaryLength];
sid2.GetBinaryForm( BinaryForm2, 0 );
return ( Win32Native.IsEqualDomainSid( BinaryForm1, BinaryForm2, out result ) == FALSE ? false : result );
}
}
/// <summary>
/// Setup the size of the buffer Windows provides for an LSA_REFERENCED_DOMAIN_LIST
/// </summary>
[System.Security.SecurityCritical] // auto-generated
internal static void InitializeReferencedDomainsPointer(SafeLsaMemoryHandle referencedDomains)
{
Contract.Assert(referencedDomains != null, "referencedDomains != null");
// We don't know the real size of the referenced domains yet, so we need to set an initial
// size based on the LSA_REFERENCED_DOMAIN_LIST structure, then resize it to include all of
// the domains.
referencedDomains.Initialize((uint)Marshal.SizeOf(typeof(Win32Native.LSA_REFERENCED_DOMAIN_LIST)));
Win32Native.LSA_REFERENCED_DOMAIN_LIST domainList = referencedDomains.Read<Win32Native.LSA_REFERENCED_DOMAIN_LIST>(0);
unsafe
{
byte* pRdl = null;
RuntimeHelpers.PrepareConstrainedRegions();
try
{
referencedDomains.AcquirePointer(ref pRdl);
// If there is a trust information list, then the buffer size is the end of that list minus
// the beginning of the domain list. Otherwise, then the buffer is just the size of the
// referenced domain list structure, which is what we defaulted to.
if (!domainList.Domains.IsNull())
{
Win32Native.LSA_TRUST_INFORMATION* pTrustInformation = (Win32Native.LSA_TRUST_INFORMATION*)domainList.Domains;
pTrustInformation = pTrustInformation + domainList.Entries;
long bufferSize = (byte*)pTrustInformation - pRdl;
Contract.Assert(bufferSize > 0, "bufferSize > 0");
referencedDomains.Initialize((ulong)bufferSize);
}
}
finally
{
if (pRdl != null)
referencedDomains.ReleasePointer();
}
}
}
//
// Wrapper around avdapi32.GetWindowsAccountDomainSid
//
[System.Security.SecurityCritical] // auto-generated
internal static int GetWindowsAccountDomainSid(
SecurityIdentifier sid,
out SecurityIdentifier resultSid
)
{
//
// Check if the api is supported
//
if (!WellKnownSidApisSupported) {
throw new PlatformNotSupportedException( Environment.GetResourceString( "PlatformNotSupported_RequiresW2kSP3" ));
}
//
// Passing an array as big as it can ever be is a small price to pay for
// not having to P/Invoke twice (once to get the buffer, once to get the data)
//
byte[] BinaryForm = new Byte[sid.BinaryLength];
sid.GetBinaryForm( BinaryForm, 0 );
uint sidLength = ( uint )SecurityIdentifier.MaxBinaryLength;
byte[] resultSidBinary = new byte[ sidLength ];
if ( FALSE != Win32Native.GetWindowsAccountDomainSid( BinaryForm, resultSidBinary, ref sidLength ))
{
resultSid = new SecurityIdentifier( resultSidBinary, 0 );
return Win32Native.ERROR_SUCCESS;
}
else
{
resultSid = null;
return Marshal.GetLastWin32Error();
}
}
//
// Wrapper around advapi32.IsWellKnownSid
//
[System.Security.SecurityCritical] // auto-generated
internal static bool IsWellKnownSid(
SecurityIdentifier sid,
WellKnownSidType type
)
{
//
// Check if the api is supported
//
if (!WellKnownSidApisSupported) {
throw new PlatformNotSupportedException( Environment.GetResourceString( "PlatformNotSupported_RequiresW2kSP3" ));
}
byte[] BinaryForm = new byte[sid.BinaryLength];
sid.GetBinaryForm( BinaryForm, 0 );
if ( FALSE == Win32Native.IsWellKnownSid( BinaryForm, ( int )type ))
{
return false;
}
else
{
return true;
}
}
// When the CLR is hosted, the host gets to implement these calls,
// otherwise, we call down into the Win32 APIs.
#if FEATURE_IMPERSONATION
[System.Security.SecurityCritical] // auto-generated
[ResourceExposure(ResourceScope.Process)]
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode), SuppressUnmanagedCodeSecurity]
internal static extern int ImpersonateLoggedOnUser (SafeTokenHandle hToken);
[System.Security.SecurityCritical] // auto-generated
[ResourceExposure(ResourceScope.Process)]
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern int OpenThreadToken (TokenAccessLevels dwDesiredAccess, WinSecurityContext OpenAs, out SafeTokenHandle phThreadToken);
[System.Security.SecurityCritical] // auto-generated
[ResourceExposure(ResourceScope.None)]
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode), SuppressUnmanagedCodeSecurity]
internal static extern int RevertToSelf ();
[System.Security.SecurityCritical] // auto-generated
[ResourceExposure(ResourceScope.None)]
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode), SuppressUnmanagedCodeSecurity]
internal static extern int SetThreadToken(SafeTokenHandle hToken);
#endif
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,145 @@
// ==++==
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
// <OWNER>[....]</OWNER>
//
//
// WindowsImpersonationContext.cs
//
// Representation of an impersonation context.
//
namespace System.Security.Principal
{
using Microsoft.Win32;
using Microsoft.Win32.SafeHandles;
using System.Runtime.InteropServices;
#if FEATURE_CORRUPTING_EXCEPTIONS
using System.Runtime.ExceptionServices;
#endif // FEATURE_CORRUPTING_EXCEPTIONS
using System.Security.Permissions;
using System.Runtime.ConstrainedExecution;
using System.Runtime.Versioning;
using System.Diagnostics.Contracts;
[System.Runtime.InteropServices.ComVisible(true)]
public class WindowsImpersonationContext : IDisposable {
[System.Security.SecurityCritical] // auto-generated
private SafeTokenHandle m_safeTokenHandle = SafeTokenHandle.InvalidHandle;
private WindowsIdentity m_wi;
private FrameSecurityDescriptor m_fsd;
[System.Security.SecurityCritical] // auto-generated
private WindowsImpersonationContext () {}
[System.Security.SecurityCritical] // auto-generated
[ResourceExposure(ResourceScope.None)]
[ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)]
internal WindowsImpersonationContext (SafeTokenHandle safeTokenHandle, WindowsIdentity wi, bool isImpersonating, FrameSecurityDescriptor fsd) {
if (safeTokenHandle.IsInvalid)
throw new ArgumentException(Environment.GetResourceString("Argument_InvalidImpersonationToken"));
Contract.EndContractBlock();
if (isImpersonating) {
if (!Win32Native.DuplicateHandle(Win32Native.GetCurrentProcess(),
safeTokenHandle,
Win32Native.GetCurrentProcess(),
ref m_safeTokenHandle,
0,
true,
Win32Native.DUPLICATE_SAME_ACCESS))
throw new SecurityException(Win32Native.GetMessage(Marshal.GetLastWin32Error()));
m_wi = wi;
}
m_fsd = fsd;
}
// Revert to previous impersonation (the only public method).
[System.Security.SecuritySafeCritical] // auto-generated
[ResourceExposure(ResourceScope.None)]
[ResourceConsumption(ResourceScope.Process, ResourceScope.Process)]
public void Undo () {
int hr = 0;
if (m_safeTokenHandle.IsInvalid) { // the thread was not initially impersonating
hr = Win32.RevertToSelf();
if (hr < 0)
Environment.FailFast(Win32Native.GetMessage(hr));
} else {
hr = Win32.RevertToSelf();
if (hr < 0)
Environment.FailFast(Win32Native.GetMessage(hr));
hr = Win32.ImpersonateLoggedOnUser(m_safeTokenHandle);
if (hr < 0)
throw new SecurityException(Win32Native.GetMessage(hr));
}
WindowsIdentity.UpdateThreadWI(m_wi);
if (m_fsd != null)
m_fsd.SetTokenHandles(null, null);
}
// Non-throwing version that does not new any exception objects. To be called when reliability matters
[System.Security.SecurityCritical] // auto-generated
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
[ResourceExposure(ResourceScope.None)]
[ResourceConsumption(ResourceScope.Process, ResourceScope.Process)]
#if FEATURE_CORRUPTING_EXCEPTIONS
[HandleProcessCorruptedStateExceptions] //
#endif // FEATURE_CORRUPTING_EXCEPTIONS
internal bool UndoNoThrow()
{
bool bRet = false;
try{
int hr = 0;
if (m_safeTokenHandle.IsInvalid)
{ // the thread was not initially impersonating
hr = Win32.RevertToSelf();
if (hr < 0)
Environment.FailFast(Win32Native.GetMessage(hr));
}
else
{
hr = Win32.RevertToSelf();
if (hr >= 0)
{
hr = Win32.ImpersonateLoggedOnUser(m_safeTokenHandle);
}
else
{
Environment.FailFast(Win32Native.GetMessage(hr));
}
}
bRet = (hr >= 0);
if (m_fsd != null)
m_fsd.SetTokenHandles(null,null);
}
catch
{
bRet = false;
}
return bRet;
}
//
// IDisposable interface.
//
[System.Security.SecuritySafeCritical] // auto-generated
[ComVisible(false)]
protected virtual void Dispose(bool disposing) {
if (disposing) {
if (m_safeTokenHandle != null && !m_safeTokenHandle.IsClosed) {
Undo();
m_safeTokenHandle.Dispose();
}
}
}
[ComVisible(false)]
public void Dispose () {
Dispose(true);
}
}
}

View File

@@ -0,0 +1,261 @@
// ==++==
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
// <OWNER>[....]</OWNER>
//
//
// WindowsPrincipal.cs
//
// Group membership checks.
//
namespace System.Security.Principal
{
using System.Diagnostics.Contracts;
using System.Runtime.InteropServices;
#if !FEATURE_CORECLR
using System.Runtime.Serialization;
using System.Security.Claims;
using System.Collections.Generic;
#endif
using System.Security.Permissions;
using Microsoft.Win32;
using Microsoft.Win32.SafeHandles;
using Hashtable = System.Collections.Hashtable;
[Serializable]
[ComVisible(true)]
public enum WindowsBuiltInRole {
Administrator = 0x220,
User = 0x221,
Guest = 0x222,
PowerUser = 0x223,
AccountOperator = 0x224,
SystemOperator = 0x225,
PrintOperator = 0x226,
BackupOperator = 0x227,
Replicator = 0x228
}
[Serializable]
[HostProtection(SecurityInfrastructure=true)]
[ComVisible(true)]
#if !FEATURE_CORECLR
public class WindowsPrincipal : ClaimsPrincipal {
#else
public class WindowsPrincipal : IPrincipal {
#endif
private WindowsIdentity m_identity = null;
// Following 3 fields are present purely for serialization compatability with Everett: not used in Whidbey
#pragma warning disable 169
private String[] m_roles;
private Hashtable m_rolesTable;
private bool m_rolesLoaded;
#pragma warning restore 169
//
// Constructors.
//
private WindowsPrincipal () {}
public WindowsPrincipal (WindowsIdentity ntIdentity)
#if !FEATURE_CORECLR
: base (ntIdentity)
#endif
{
if (ntIdentity == null)
throw new ArgumentNullException("ntIdentity");
Contract.EndContractBlock();
m_identity = ntIdentity;
}
#if !FEATURE_CORECLR
[OnDeserialized()]
[SecuritySafeCritical]
private void OnDeserializedMethod(StreamingContext context)
{
// Here it the matrix of possible serializations
//
// Version From | Version To | ClaimsIdentities | Roles
// ============ ========== ================ ========================================================
// 4.0 4.5 None We always need to add a ClaimsIdentity
//
// 4.5 4.5 Yes There should be a ClaimsIdentity
ClaimsIdentity firstNonNullIdentity = null;
foreach (var identity in base.Identities)
{
if (identity != null)
{
firstNonNullIdentity = identity;
break;
}
}
if (firstNonNullIdentity == null)
{
base.AddIdentity(m_identity);
}
}
#endif //!FEATURE_CORECLR
//
// Properties.
//
#if !FEATURE_CORECLR
public override IIdentity Identity {
#else
public virtual IIdentity Identity {
#endif
get {
return m_identity;
}
}
//
// Public methods.
//
[SecuritySafeCritical]
[SecurityPermission(SecurityAction.Demand, ControlPrincipal = true)]
#if !FEATURE_CORECLR
public override bool IsInRole (string role) {
#else
public virtual bool IsInRole (string role) {
#endif
if (role == null || role.Length == 0)
return false;
NTAccount ntAccount = new NTAccount(role);
IdentityReferenceCollection source = new IdentityReferenceCollection(1);
source.Add(ntAccount);
IdentityReferenceCollection target = NTAccount.Translate(source, typeof(SecurityIdentifier), false);
SecurityIdentifier sid = target[0] as SecurityIdentifier;
#if !FEATURE_CORECLR
if (sid != null) {
if ( IsInRole(sid) ) {
return true;
}
}
// possible that identity has other role claims that match
return base.IsInRole(role);
#else
if (sid == null)
return false;
return IsInRole(sid);
#endif
}
#if !FEATURE_CORECLR
// <summary
// Returns all of the claims from all of the identities that are windows user claims
// found in the NT token.
// </summary>
public virtual IEnumerable<Claim> UserClaims
{
get
{
foreach (ClaimsIdentity identity in Identities)
{
WindowsIdentity wi = identity as WindowsIdentity;
if ( wi!=null)
{
foreach (Claim claim in wi.UserClaims)
{
yield return claim;
}
}
}
}
}
// <summary
// Returns all of the claims from all of the identities that are windows device claims
// found in the NT token.
// </summary>
public virtual IEnumerable<Claim> DeviceClaims
{
get
{
foreach (ClaimsIdentity identity in Identities)
{
WindowsIdentity wi = identity as WindowsIdentity;
if (wi != null)
{
foreach (Claim claim in wi.DeviceClaims)
{
yield return claim;
}
}
}
}
}
#endif
public virtual bool IsInRole (WindowsBuiltInRole role) {
if (role < WindowsBuiltInRole.Administrator || role > WindowsBuiltInRole.Replicator)
throw new ArgumentException(Environment.GetResourceString("Arg_EnumIllegalVal", (int)role), "role");
Contract.EndContractBlock();
return IsInRole((int) role);
}
public virtual bool IsInRole (int rid) {
SecurityIdentifier sid = new SecurityIdentifier(IdentifierAuthority.NTAuthority,
new int[] {Win32Native.SECURITY_BUILTIN_DOMAIN_RID, rid});
return IsInRole(sid);
}
// This methods (with a SID parameter) is more general than the 2 overloads that accept a WindowsBuiltInRole or
// a rid (as an int). It is also better from a performance standpoint than the overload that accepts a string.
// The aformentioned overloads remain in this class since we do not want to introduce a
// breaking change. However, this method should be used in all new applications and we should document this.
[System.Security.SecuritySafeCritical] // auto-generated
[ComVisible(false)]
public virtual bool IsInRole (SecurityIdentifier sid) {
if (sid == null)
throw new ArgumentNullException("sid");
Contract.EndContractBlock();
// special case the anonymous identity.
if (m_identity.TokenHandle.IsInvalid)
return false;
// CheckTokenMembership expects an impersonation token
SafeTokenHandle token = SafeTokenHandle.InvalidHandle;
if (m_identity.ImpersonationLevel == TokenImpersonationLevel.None) {
if (!Win32Native.DuplicateTokenEx(m_identity.TokenHandle,
(uint) TokenAccessLevels.Query,
IntPtr.Zero,
(uint) TokenImpersonationLevel.Identification,
(uint) TokenType.TokenImpersonation,
ref token))
throw new SecurityException(Win32Native.GetMessage(Marshal.GetLastWin32Error()));
}
bool isMember = false;
// CheckTokenMembership will check if the SID is both present and enabled in the access token.
if (!Win32Native.CheckTokenMembership((m_identity.ImpersonationLevel != TokenImpersonationLevel.None ? m_identity.TokenHandle : token),
sid.BinaryForm,
ref isMember))
throw new SecurityException(Win32Native.GetMessage(Marshal.GetLastWin32Error()));
token.Dispose();
return isMember;
}
}
}