SID.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / clr / src / BCL / System / Security / Principal / SID.cs / 1305376 / SID.cs

                            // ==++== 
//
//   Copyright (c) Microsoft Corporation.  All rights reserved.
//
// ==--== 
// [....]
// 
 
using System;
using System.Globalization; 
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Security.Permissions;
using System.Text; 
using Microsoft.Win32;
using Microsoft.Win32.SafeHandles; 
using System.Diagnostics.Contracts; 

namespace System.Security.Principal 
{
    //
    // Identifier authorities
    // 

    internal enum IdentifierAuthority : long 
    { 
        NullAuthority                            = 0,
        WorldAuthority                           = 1, 
        LocalAuthority                           = 2,
        CreatorAuthority                         = 3,
        NonUniqueAuthority                       = 4,
        NTAuthority                              = 5, 
        SiteServerAuthority                      = 6,
        InternetSiteAuthority                    = 7, 
        ExchangeAuthority                        = 8, 
        ResourceManagerAuthority                 = 9,
    } 

    //
    // SID name usage
    // 

    internal enum SidNameUse 
    { 
        User                              = 1,
        Group                             = 2, 
        Domain                            = 3,
        Alias                             = 4,
        WellKnownGroup                    = 5,
        DeletedAccount                    = 6, 
        Invalid                           = 7,
        Unknown                           = 8, 
        Computer                          = 9, 
    }
 
    //
    // Well-known SID types
    //
 
[System.Runtime.InteropServices.ComVisible(false)]
    public enum WellKnownSidType 
    { 
        NullSid                                  = 0,
        WorldSid                                 = 1, 
        LocalSid                                 = 2,
        CreatorOwnerSid                          = 3,
        CreatorGroupSid                          = 4,
        CreatorOwnerServerSid                    = 5, 
        CreatorGroupServerSid                    = 6,
        NTAuthoritySid                           = 7, 
        DialupSid                                = 8, 
        NetworkSid                               = 9,
        BatchSid                                 = 10, 
        InteractiveSid                           = 11,
        ServiceSid                               = 12,
        AnonymousSid                             = 13,
        ProxySid                                 = 14, 
        EnterpriseControllersSid                 = 15,
        SelfSid                                  = 16, 
        AuthenticatedUserSid                     = 17, 
        RestrictedCodeSid                        = 18,
        TerminalServerSid                        = 19, 
        RemoteLogonIdSid                         = 20,
        LogonIdsSid                              = 21,
        LocalSystemSid                           = 22,
        LocalServiceSid                          = 23, 
        NetworkServiceSid                        = 24,
        BuiltinDomainSid                         = 25, 
        BuiltinAdministratorsSid                 = 26, 
        BuiltinUsersSid                          = 27,
        BuiltinGuestsSid                         = 28, 
        BuiltinPowerUsersSid                     = 29,
        BuiltinAccountOperatorsSid               = 30,
        BuiltinSystemOperatorsSid                = 31,
        BuiltinPrintOperatorsSid                 = 32, 
        BuiltinBackupOperatorsSid                = 33,
        BuiltinReplicatorSid                     = 34, 
        BuiltinPreWindows2000CompatibleAccessSid = 35, 
        BuiltinRemoteDesktopUsersSid             = 36,
        BuiltinNetworkConfigurationOperatorsSid  = 37, 
        AccountAdministratorSid                  = 38,
        AccountGuestSid                          = 39,
        AccountKrbtgtSid                         = 40,
        AccountDomainAdminsSid                   = 41, 
        AccountDomainUsersSid                    = 42,
        AccountDomainGuestsSid                   = 43, 
        AccountComputersSid                      = 44, 
        AccountControllersSid                    = 45,
        AccountCertAdminsSid                     = 46, 
        AccountSchemaAdminsSid                   = 47,
        AccountEnterpriseAdminsSid               = 48,
        AccountPolicyAdminsSid                   = 49,
        AccountRasAndIasServersSid               = 50, 
        NtlmAuthenticationSid                    = 51,
        DigestAuthenticationSid                  = 52, 
        SChannelAuthenticationSid                = 53, 
        ThisOrganizationSid                      = 54,
        OtherOrganizationSid                     = 55, 
        BuiltinIncomingForestTrustBuildersSid    = 56,
        BuiltinPerformanceMonitoringUsersSid     = 57,
        BuiltinPerformanceLoggingUsersSid        = 58,
        BuiltinAuthorizationAccessSid            = 59, 
        WinBuiltinTerminalServerLicenseServersSid= 60,
        MaxDefined = WinBuiltinTerminalServerLicenseServersSid, 
    } 

    // 
    // This class implements revision 1 SIDs
    // NOTE: The SecurityIdentifier class is immutable and must remain this way
    //
 
[System.Runtime.InteropServices.ComVisible(false)]
    public sealed class SecurityIdentifier : IdentityReference, IComparable 
    { 
        #region Public Constants
 
        //
        // Identifier authority must be at most six bytes long
        //
 
        internal static readonly long MaxIdentifierAuthority = 0xFFFFFFFFFFFF;
 
        // 
        // Maximum number of subauthorities in a SID
        // 

        internal static readonly byte MaxSubAuthorities = 15;

        // 
        // Minimum length of a binary representation of a SID
        // 
 
        public static readonly int MinBinaryLength = 1 + 1 + 6; // Revision (1) + subauth count (1) + identifier authority (6)
 
        //
        // Maximum length of a binary representation of a SID
        //
 
        public static readonly int MaxBinaryLength = 1 + 1 + 6 + MaxSubAuthorities * 4; // 4 bytes for each subauth
 
        #endregion 

        #region Private Members 

        //
        // Immutable properties of a SID
        // 

        private IdentifierAuthority _IdentifierAuthority; 
        private int[] _SubAuthorities; 
        private byte[] _BinaryForm;
        private SecurityIdentifier _AccountDomainSid; 
        bool _AccountDomainSidInitialized = false;

        //
        // Computed attributes of a SID 
        //
 
        private string _SddlForm = null; 

        #endregion 

        #region Constructors

        // 
        // Shared constructor logic
        // NOTE: subauthorities are really unsigned integers, but due to CLS 
        //       lack of support for unsigned integers the caller must perform 
        //       the typecast
        // 

        private void CreateFromParts( IdentifierAuthority identifierAuthority, int[] subAuthorities )
        {
            if ( subAuthorities == null ) 
            {
                throw new ArgumentNullException( "subAuthorities" ); 
            } 

            Contract.EndContractBlock(); 

            //
            // Check the number of subauthorities passed in
            // 

            if ( subAuthorities.Length > MaxSubAuthorities ) 
            { 
                throw new ArgumentOutOfRangeException(
                    "subAuthorities.Length", 
                    subAuthorities.Length,
                    Environment.GetResourceString( "IdentityReference_InvalidNumberOfSubauthorities",  MaxSubAuthorities));
            }
 
            //
            // Identifier authority is atmost 6 bytes long 
            // 

            if ( identifierAuthority < 0  || 
                (long) identifierAuthority > MaxIdentifierAuthority )
            {
                throw new ArgumentOutOfRangeException(
                    "identifierAuthority", 
                    identifierAuthority,
                    Environment.GetResourceString( "IdentityReference_IdentifierAuthorityTooLarge" )); 
            } 

            // 
            // Create a local copy of the data passed in
            //

            _IdentifierAuthority = identifierAuthority; 
            _SubAuthorities = new int[ subAuthorities.Length ];
            subAuthorities.CopyTo( _SubAuthorities, 0 ); 
 
            //
            // Compute and store the binary form 
            //
            // typedef struct _SID {
            //     UCHAR Revision;
            //     UCHAR SubAuthorityCount; 
            //     SID_IDENTIFIER_AUTHORITY IdentifierAuthority;
            //     ULONG SubAuthority[ANYSIZE_ARRAY] 
            // } SID, *PISID; 
            //
 
            byte i;
            _BinaryForm = new byte[1 + 1 + 6 + 4 * this.SubAuthorityCount];

            // 
            // First two bytes contain revision and subauthority count
            // 
 
            _BinaryForm[0] = Revision;
            _BinaryForm[1] = ( byte )this.SubAuthorityCount; 

            //
            // Identifier authority takes up 6 bytes
            // 

            for ( i = 0; i < 6; i++ ) 
            { 
                _BinaryForm[2+i] = ( byte )(((( ulong )this._IdentifierAuthority ) >> (( 5 - i ) * 8 )) & 0xFF ) ;
            } 

            //
            // Subauthorities go last, preserving big-endian representation
            // 

            for ( i = 0; i < this.SubAuthorityCount; i++ ) 
            { 
                byte shift;
                for ( shift = 0; shift < 4; shift += 1 ) 
                {
                    _BinaryForm[8 + 4*i + shift] = ( byte )((( ulong )_SubAuthorities[i] ) >> ( shift * 8 ));
                }
            } 
        }
 
        private void CreateFromBinaryForm( byte[] binaryForm, int offset ) 
        {
            // 
            // Give us something to work with
            //

            if ( binaryForm == null ) 
            {
                throw new ArgumentNullException( "binaryForm" ); 
            } 

            // 
            // Negative offsets are not allowed
            //

            if ( offset < 0 ) 
            {
                throw new ArgumentOutOfRangeException( 
                    "offset", 
                    offset,
                    Environment.GetResourceString( "ArgumentOutOfRange_NeedNonNegNum" )); 
            }

            //
            // At least a minimum-size SID should fit in the buffer 
            //
 
            if ( binaryForm.Length - offset < SecurityIdentifier.MinBinaryLength ) 
            {
                throw new ArgumentOutOfRangeException( 
                    "binaryForm",
                    Environment.GetResourceString( "ArgumentOutOfRange_ArrayTooSmall" ));
            }
            Contract.EndContractBlock(); 

            IdentifierAuthority Authority; 
            int[] SubAuthorities; 

            // 
            // Extract the elements of a SID
            //

            if ( binaryForm[offset] != Revision ) 
            {
                // 
                // Revision is incorrect 
                //
 
                throw new ArgumentException(
                    Environment.GetResourceString( "IdentityReference_InvalidSidRevision" ),
                    "binaryForm" );
            } 

            // 
            // Insist on the correct number of subauthorities 
            //
 
            if ( binaryForm[offset + 1] > MaxSubAuthorities )
            {
                throw new ArgumentException(
                    Environment.GetResourceString( "IdentityReference_InvalidNumberOfSubauthorities", MaxSubAuthorities ), 
                    "binaryForm" );
            } 
 
            //
            // Make sure the buffer is big enough 
            //

            int Length = 1 + 1 + 6 + 4 * binaryForm[offset + 1];
 
            if ( binaryForm.Length - offset < Length )
            { 
                throw new ArgumentException( 
                    Environment.GetResourceString( "ArgumentOutOfRange_ArrayTooSmall" ),
                    "binaryForm" ); 
            }

            Authority =
                ( IdentifierAuthority )( 
                ((( long )binaryForm[offset + 2]) << 40 ) +
                ((( long )binaryForm[offset + 3]) << 32 ) + 
                ((( long )binaryForm[offset + 4]) << 24 ) + 
                ((( long )binaryForm[offset + 5]) << 16 ) +
                ((( long )binaryForm[offset + 6]) << 8 ) + 
                ((( long )binaryForm[offset + 7]) ));

            SubAuthorities = new int[binaryForm[offset + 1]];
 
            //
            // Subauthorities are represented in big-endian format 
            // 

            for ( byte i = 0; i < binaryForm[offset + 1]; i++ ) 
            {
                SubAuthorities[i] =
                    ( int )(
                    ((( uint )binaryForm[offset + 8 + 4*i + 0]) << 0 ) + 
                    ((( uint )binaryForm[offset + 8 + 4*i + 1]) << 8 ) +
                    ((( uint )binaryForm[offset + 8 + 4*i + 2]) << 16 ) + 
                    ((( uint )binaryForm[offset + 8 + 4*i + 3]) << 24 )); 
            }
 
            CreateFromParts( Authority, SubAuthorities );

            return;
 
        }
 
        // 
        // Constructs a SecurityIdentifier object from its string representation
        // Returns 'null' if string passed in is not a valid SID 
        // NOTE: although there is a P/Invoke call involved in the implementation of this method,
        //       there is no security risk involved, so no security demand is being made.
        //
 
        [System.Security.SecuritySafeCritical]  // auto-generated
        public SecurityIdentifier( string sddlForm ) 
        { 
            byte[] resultSid;
 
            //
            // Give us something to work with
            //
 
            if ( sddlForm == null )
            { 
                throw new ArgumentNullException( "sddlForm" ); 
            }
            Contract.EndContractBlock(); 

            //
            // Call into the underlying O/S conversion routine
            // 

            int Error = Win32.CreateSidFromString( sddlForm, out resultSid ); 
 
            if ( Error == Win32Native.ERROR_INVALID_SID )
            { 
                throw new ArgumentException( Environment.GetResourceString( "Argument_InvalidValue" ), "sddlForm" );
            }
            else if ( Error == Win32Native.ERROR_NOT_ENOUGH_MEMORY )
            { 
                  throw new OutOfMemoryException();
            } 
            else if ( Error != Win32Native.ERROR_SUCCESS ) 
            {
                Contract.Assert( false, string.Format( CultureInfo.InvariantCulture, "Win32.CreateSidFromString returned unrecognized error {0}", Error )); 
                throw new SystemException(Win32Native.GetMessage(Error));
            }

            CreateFromBinaryForm( resultSid, 0 ); 
        }
 
        // 
        // Constructs a SecurityIdentifier object from its binary representation
        // 

        public SecurityIdentifier( byte[] binaryForm, int offset )
        {
            CreateFromBinaryForm( binaryForm, offset ); 
        }
 
        // 
        // Constructs a SecurityIdentifier object from an IntPtr
        // 
        [System.Security.SecuritySafeCritical]  // auto-generated
        [SecurityPermission(SecurityAction.Demand, UnmanagedCode=true)]
        public SecurityIdentifier( IntPtr binaryForm )
            : this( binaryForm, true ) 
        {
        } 
 
        [System.Security.SecurityCritical]  // auto-generated
        internal SecurityIdentifier( IntPtr binaryForm, bool noDemand ) 
            : this( Win32.ConvertIntPtrSidToByteArraySid( binaryForm ), 0 )
        {
        }
 
        //
        // Constructs a well-known SID 
        // The 'domainSid' parameter is optional and only used 
        // by the well-known types that require it
        // NOTE: although there is a P/Invoke call involved in the implementation of this constructor, 
        //       there is no security risk involved, so no security demand is being made.
        //

        [System.Security.SecuritySafeCritical]  // auto-generated 
        public SecurityIdentifier( WellKnownSidType sidType, SecurityIdentifier domainSid )
        { 
            // 
            // sidType must not be equal to LogonIdsSid
            // 

            if (sidType == WellKnownSidType.LogonIdsSid)
            {
                throw new ArgumentException(Environment.GetResourceString("IdentityReference_CannotCreateLogonIdsSid"), "sidType"); 
            }
            Contract.EndContractBlock(); 
 
            byte[] resultSid;
            int Error; 

            //
            // Check if well known sids are supported on this platform
            // 
            if (!Win32.WellKnownSidApisSupported) {
                throw new PlatformNotSupportedException( Environment.GetResourceString( "PlatformNotSupported_RequiresW2kSP3" )); 
            } 

            // 
            // sidType should not exceed the max defined value
            //

            if ((sidType < WellKnownSidType.NullSid) || (sidType > WellKnownSidType.MaxDefined)) 
            {
                throw new ArgumentException( Environment.GetResourceString( "Argument_InvalidValue" ), "sidType" ); 
            } 

            // 
            // for sidType between 38 to 50, the domainSid parameter must be specified
            //

            if ((sidType >= WellKnownSidType.AccountAdministratorSid) && (sidType <= WellKnownSidType.AccountRasAndIasServersSid)) 
            {
                if (domainSid == null) { 
                    throw new ArgumentNullException( "domainSid", Environment.GetResourceString( "IdentityReference_DomainSidRequired", sidType) ); 
                }
 
                //
                // verify that the domain sid is a valid windows domain sid
                // to do that we call GetAccountDomainSid and the return value should be the same as the domainSid
                // 

                SecurityIdentifier resultDomainSid; 
                int ErrorCode; 

                ErrorCode = Win32.GetWindowsAccountDomainSid( domainSid, out resultDomainSid ); 

                if ( ErrorCode == Win32Native.ERROR_INSUFFICIENT_BUFFER ) {
                    throw new OutOfMemoryException();
                } 
                else if ( ErrorCode == Win32Native.ERROR_NON_ACCOUNT_SID )
                { 
                    // this means that the domain sid is not valid 
                    throw new ArgumentException( Environment.GetResourceString( "IdentityReference_NotAWindowsDomain" ), "domainSid" );
                } 
                else if ( ErrorCode != Win32Native.ERROR_SUCCESS )
                {
                    Contract.Assert( false, string.Format( CultureInfo.InvariantCulture, "Win32.GetWindowsAccountDomainSid returned unrecognized error {0}", ErrorCode) );
                    throw new SystemException(Win32Native.GetMessage(ErrorCode)); 
                }
 
                // 
                // if domainSid is passed in as S-1-5-21-3-4-5-6,  the above api will return S-1-5-21-3-4-5 as the domainSid
                // Since these do not match S-1-5-21-3-4-5-6 is not a valid domainSid (wrong number of subauthorities) 
                //
                if (resultDomainSid != domainSid) {
                    throw new ArgumentException( Environment.GetResourceString( "IdentityReference_NotAWindowsDomain" ), "domainSid" );
                } 

            } 
 

            Error = Win32.CreateWellKnownSid( sidType, domainSid, out resultSid ); 

            if ( Error == Win32Native.ERROR_INVALID_PARAMETER )
            {
                throw new ArgumentException( Win32Native.GetMessage(Error), "sidType/domainSid" ); 
            }
            else if ( Error != Win32Native.ERROR_SUCCESS ) 
            { 
                Contract.Assert( false, string.Format( CultureInfo.InvariantCulture, "Win32.CreateWellKnownSid returned unrecognized error {0}", Error ));
                throw new SystemException( Win32Native.GetMessage( Error )); 
            }

            CreateFromBinaryForm( resultSid, 0 );
        } 

        internal SecurityIdentifier( SecurityIdentifier domainSid, uint rid ) 
        { 
            int i;
            int[] SubAuthorities = new int[ domainSid.SubAuthorityCount + 1 ]; 

            for ( i = 0; i < domainSid.SubAuthorityCount; i++ )
            {
                SubAuthorities[i] = domainSid.GetSubAuthority( i ); 
            }
 
            SubAuthorities[i] = ( int )rid; 

            CreateFromParts( domainSid.IdentifierAuthority, SubAuthorities ); 
        }

        internal SecurityIdentifier( IdentifierAuthority identifierAuthority, int[] subAuthorities )
        { 
            CreateFromParts( identifierAuthority, subAuthorities );
        } 
 
        #endregion
 
        #region Static Properties

        //
        // Revision is always '1' 
        //
 
        internal static byte Revision 
        {
            get { return 1; } 
        }

        #endregion
 
        #region Non-static Properties
 
        // 
        // This is for internal consumption only, hence it is marked 'internal'
        // Making this call public would require a deep copy of the data to 
        // prevent the caller from messing with the internal representation.
        //

        internal byte[] BinaryForm 
        {
            get { return _BinaryForm; } 
        } 

        internal IdentifierAuthority IdentifierAuthority 
        {
            get { return _IdentifierAuthority; }
        }
 
        internal int SubAuthorityCount
        { 
            get { return _SubAuthorities.Length; } 
        }
 
        public int BinaryLength
        {
            get
            { 
                return _BinaryForm.Length;
            } 
        } 

        // 
        // Returns the domain portion of a SID or null if the specified
        // SID is not an account SID
        // NOTE: although there is a P/Invoke call involved in the implementation of this method,
        //       there is no security risk involved, so no security demand is being made. 
        //
 
        public SecurityIdentifier AccountDomainSid 
        {
            [System.Security.SecuritySafeCritical]  // auto-generated 
            get
            {
                if ( !_AccountDomainSidInitialized )
                { 
                    _AccountDomainSid = GetAccountDomainSid();
                    _AccountDomainSidInitialized = true; 
                } 

                return _AccountDomainSid; 
            }
        }

        #endregion 

        #region Inherited properties and methods 
 
        public override bool Equals( object o )
        { 
            if ( o == null )
            {
                return false;
            } 

            SecurityIdentifier sid = o as SecurityIdentifier; 
 
            if ( sid == null )
            { 
                return false;
            }

            return ( this == sid ); // invokes operator== 
        }
 
        public bool Equals( SecurityIdentifier sid ) 
        {
            if ( sid == null ) 
            {
                return false;
            }
 
            return ( this == sid ); // invokes operator==
        } 
 
        public override int GetHashCode() {
            int hashCode = ((long)this.IdentifierAuthority).GetHashCode(); 
            for(int i = 0; i < SubAuthorityCount; i++) {
                hashCode ^= this.GetSubAuthority(i);
            }
            return hashCode; 
        }
 
        public override string ToString() 
        {
            if ( _SddlForm == null ) 
            {
                StringBuilder result = new StringBuilder();

                // 
                // Typecasting of _IdentifierAuthority to a long below is important, since
                // otherwise you would see this: "S-1-NTAuthority-32-544" 
                // 

                result.AppendFormat( "S-1-{0}", ( long )_IdentifierAuthority ); 

                for ( int i = 0; i < SubAuthorityCount; i++ )
                {
                    result.AppendFormat( "-{0}", ( uint )( _SubAuthorities[i] )); 
                }
 
                _SddlForm = result.ToString(); 
            }
 
            return _SddlForm;
        }
#if false
        public override string Scheme 
        {
            get { return "ms-sid"; } 
        } 
#endif
        public override string Value 
        {
            get { return ToString().ToUpper(CultureInfo.InvariantCulture); }
        }
 
        internal static bool IsValidTargetTypeStatic( Type targetType )
       { 
            if ( targetType == typeof( NTAccount )) 
            {
                return true; 
            }
            else if ( targetType == typeof( SecurityIdentifier ))
            {
                return true; 
            }
            else 
            { 
                return false;
            } 
        }

        public override bool IsValidTargetType( Type targetType )
        { 
            return IsValidTargetTypeStatic( targetType );
        } 
 

        [System.Security.SecurityCritical]  // auto-generated 
        internal SecurityIdentifier GetAccountDomainSid()
        {
            SecurityIdentifier ResultSid;
            int Error; 

            Error = Win32.GetWindowsAccountDomainSid( this, out ResultSid ); 
 
            if ( Error == Win32Native.ERROR_INSUFFICIENT_BUFFER )
            { 
                throw new OutOfMemoryException();
            }
            else if ( Error == Win32Native.ERROR_NON_ACCOUNT_SID )
            { 
                ResultSid = null;
            } 
            else if ( Error != Win32Native.ERROR_SUCCESS ) 
            {
                Contract.Assert( false, string.Format( CultureInfo.InvariantCulture, "Win32.GetWindowsAccountDomainSid returned unrecognized error {0}", Error) ); 
                throw new SystemException(Win32Native.GetMessage(Error));
            }
            return ResultSid;
        } 

        [System.Security.SecuritySafeCritical]  // auto-generated 
        public bool IsAccountSid() { 

            if ( !_AccountDomainSidInitialized ) 
            {
                    _AccountDomainSid = GetAccountDomainSid();
                    _AccountDomainSidInitialized = true;
            } 

            if (_AccountDomainSid == null) { 
                return false; 
            }
 
            return true;
        }

        [SecurityPermission(SecurityAction.Demand, ControlPrincipal = true)] 
        [SecuritySafeCritical]
        public override IdentityReference Translate( Type targetType ) 
        { 
            if ( targetType == null )
            { 
                throw new ArgumentNullException( "targetType" );
            }
            Contract.EndContractBlock();
 
            if ( targetType == typeof( SecurityIdentifier ))
            { 
                return this; // assumes SecurityIdentifier objects are immutable 
            }
            else if ( targetType == typeof( NTAccount )) 
            {
                IdentityReferenceCollection irSource = new IdentityReferenceCollection( 1 );
                irSource.Add( this );
                IdentityReferenceCollection irTarget; 

                irTarget = SecurityIdentifier.Translate( irSource, targetType, true ); 
 
                return irTarget[0];
            } 
            else
            {
                throw new ArgumentException( Environment.GetResourceString( "IdentityReference_MustBeIdentityReference" ), "targetType" );
            } 
        }
 
        #endregion 

        #region Operators 

        public static bool operator== ( SecurityIdentifier left, SecurityIdentifier 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.CompareTo( right ) == 0 );
            } 
        }

        public static bool operator!= ( SecurityIdentifier left, SecurityIdentifier right )
        { 
            return !( left == right );
        } 
 
        #endregion
 
        #region IComparable implementation

        public int CompareTo( SecurityIdentifier sid )
        { 
            if ( sid == null )
            { 
                throw new ArgumentNullException( "sid" ); 
            }
            Contract.EndContractBlock(); 

            if ( this.IdentifierAuthority < sid.IdentifierAuthority )
            {
                return -1; 
            }
 
            if ( this.IdentifierAuthority > sid.IdentifierAuthority ) 
            {
                return 1; 
            }

            if ( this.SubAuthorityCount < sid.SubAuthorityCount )
            { 
                return -1;
            } 
 
            if ( this.SubAuthorityCount > sid.SubAuthorityCount )
            { 
                return 1;
            }

            for ( int i = 0; i < this.SubAuthorityCount; i++ ) 
            {
                int diff = this.GetSubAuthority( i ) - sid.GetSubAuthority( i ); 
 
                if ( diff != 0 )
                { 
                    return diff;
                }
            }
 
            return 0;
        } 
 
        #endregion
 
        #region Public Methods

        internal int GetSubAuthority( int index )
        { 
            return this._SubAuthorities[ index ];
        } 
 
        //
        // Determines whether this SID is a well known SID of the specified type 
        //
        // NOTE: although there is a P/Invoke call involved in the implementation of this method,
        //       there is no security risk involved, so no security demand is being made.
        // 

        [System.Security.SecuritySafeCritical]  // auto-generated 
        public bool IsWellKnown( WellKnownSidType type ) 
        {
            return Win32.IsWellKnownSid( this, type ); 
        }

        public void GetBinaryForm( byte[] binaryForm, int offset )
        { 
            _BinaryForm.CopyTo( binaryForm, offset );
        } 
 
        //
        // NOTE: although there is a P/Invoke call involved in the implementation of this method, 
        //       there is no security risk involved, so no security demand is being made.
        //

        [System.Security.SecuritySafeCritical]  // auto-generated 
        public bool IsEqualDomainSid( SecurityIdentifier sid )
        { 
            return Win32.IsEqualDomainSid( this, sid ); 
        }
 
        [System.Security.SecurityCritical]  // auto-generated
        private static IdentityReferenceCollection TranslateToNTAccounts( IdentityReferenceCollection sourceSids, out bool someFailed )
        {
            if (sourceSids == null) 
            {
                throw new ArgumentNullException("sourceSids"); 
            } 

            if (sourceSids.Count == 0) 
            {
                throw new ArgumentException(Environment.GetResourceString("Arg_EmptyCollection"), "sourceSids");
            }
            Contract.EndContractBlock(); 

            IntPtr[] SidArrayPtr = new IntPtr[sourceSids.Count]; 
            GCHandle[] HandleArray = new GCHandle[ sourceSids.Count ]; 
            SafeLsaPolicyHandle LsaHandle = SafeLsaPolicyHandle.InvalidHandle;
            SafeLsaMemoryHandle ReferencedDomainsPtr = SafeLsaMemoryHandle.InvalidHandle; 
            SafeLsaMemoryHandle NamesPtr = SafeLsaMemoryHandle.InvalidHandle;

            try
            { 
                //
                // Pin all elements in the array of SIDs 
                // 

                int currentSid = 0; 
                foreach ( IdentityReference id in sourceSids )
                {
                    SecurityIdentifier sid = id as SecurityIdentifier;
 
                    if ( sid == null )
                    { 
                        throw new ArgumentException( Environment.GetResourceString( "Argument_ImproperType" ), "sourceSids" ); 
                    }
 
                    HandleArray[currentSid] = GCHandle.Alloc(sid.BinaryForm, GCHandleType.Pinned);
                    SidArrayPtr[currentSid] = HandleArray[currentSid].AddrOfPinnedObject();
                    currentSid++;
                } 

                // 
                // Open LSA policy (for lookup requires it) 
                //
 
                LsaHandle = Win32.LsaOpenPolicy( null, PolicyRights.POLICY_LOOKUP_NAMES );

                //
                // Perform the actual lookup 
                //
 
                someFailed = false; 
                uint ReturnCode;
                ReturnCode = Win32Native.LsaLookupSids( LsaHandle, sourceSids.Count, SidArrayPtr, ref ReferencedDomainsPtr, ref NamesPtr ); 

                //
                // 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));
 
                    Contract.Assert( false, string.Format( CultureInfo.InvariantCulture, "Win32Native.LsaLookupSids returned {0}", win32ErrorCode)); 
                    throw new SystemException(Win32Native.GetMessage(win32ErrorCode));
                } 


                NamesPtr.Initialize((uint)sourceSids.Count, (uint)Marshal.SizeOf(typeof(Win32Native.LSA_TRANSLATED_NAME)));
                Win32.InitializeReferencedDomainsPointer(ReferencedDomainsPtr); 

                // 
                // Interpret the results and generate NTAccount objects 
                //
 
                IdentityReferenceCollection Result = new IdentityReferenceCollection( sourceSids.Count );

                if ( ReturnCode == 0 || ReturnCode == Win32Native.STATUS_SOME_NOT_MAPPED )
                { 
                    //
                    // Interpret the results and generate NT Account objects 
                    // 

                    Win32Native.LSA_REFERENCED_DOMAIN_LIST rdl = ReferencedDomainsPtr.Read(0); 
                    string[] ReferencedDomains = new string[ 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] = Marshal.PtrToStringUni(ti.Name.Buffer, ti.Name.Length / sizeof(char)); 
                    } 

                    Win32Native.LSA_TRANSLATED_NAME[] translatedNames = new Win32Native.LSA_TRANSLATED_NAME[sourceSids.Count]; 
                    NamesPtr.ReadArray(0, translatedNames, 0, translatedNames.Length);

                    for (int i = 0; i < sourceSids.Count; i++)
                    { 
                        Win32Native.LSA_TRANSLATED_NAME Ltn = translatedNames[i];
 
                        switch ((SidNameUse)Ltn.Use) 
                        {
                            case SidNameUse.User: 
                            case SidNameUse.Group:
                            case SidNameUse.Alias:
                            case SidNameUse.Computer:
                            case SidNameUse.WellKnownGroup: 
                                string account = Marshal.PtrToStringUni(Ltn.Name.Buffer, Ltn.Name.Length / sizeof(char)); ;
                                string domain = ReferencedDomains[Ltn.DomainIndex]; 
                                Result.Add( new NTAccount( domain, account )); 
                                break;
 
                            default:
                                someFailed = true;
                                Result.Add( sourceSids[i] );
                                break; 
                        }
                    } 
                } 
                else
                { 
                    for (int i = 0; i < sourceSids.Count; i++)
                    {
                        Result.Add( sourceSids[i] );
                    } 
                }
 
                return Result; 
            }
            finally 
            {
                for (int i = 0; i < sourceSids.Count; i++)
                {
                    if ( HandleArray[i].IsAllocated ) 
                    {
                        HandleArray[i].Free(); 
                    } 
                }
 
                LsaHandle.Dispose();
                ReferencedDomainsPtr.Dispose();
                NamesPtr.Dispose();
            } 
        }
 
        [System.Security.SecurityCritical]  // auto-generated 
        internal static IdentityReferenceCollection Translate( IdentityReferenceCollection sourceSids, Type targetType, bool forceSuccess)
        { 
            bool SomeFailed = false;
            IdentityReferenceCollection Result;

 
            Result = Translate( sourceSids, 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 sourceSids, Type targetType, out bool someFailed ) 
        {
            if ( sourceSids == null )
            {
                throw new ArgumentNullException( "sourceSids" ); 
            }
            Contract.EndContractBlock(); 
 
            if ( targetType == typeof( NTAccount ))
            { 
                return TranslateToNTAccounts( sourceSids, out someFailed );
            }

            throw new ArgumentException( Environment.GetResourceString( "IdentityReference_MustBeIdentityReference" ), "targetType" ); 
        }
 
        #endregion 
    }
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK