X509SecurityTokenAuthenticator.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / cdf / src / WCF / IdentityModel / System / IdentityModel / Selectors / X509SecurityTokenAuthenticator.cs / 1305376 / X509SecurityTokenAuthenticator.cs

                            //------------------------------------------------------------ 
// Copyright (c) Microsoft Corporation.  All rights reserved.
//-----------------------------------------------------------

namespace System.IdentityModel.Selectors 
{
    using System.Collections.Generic; 
    using System.Collections.ObjectModel; 
    using System.ComponentModel;
    using System.Diagnostics; 
    using System.IdentityModel.Claims;
    using System.IdentityModel.Policy;
    using System.IdentityModel.Tokens;
    using System.Runtime.CompilerServices; 
    using System.Runtime.InteropServices;
    using System.Security.Cryptography.X509Certificates; 
    using System.Security.AccessControl; 
    using System.Security.Principal;
    using System.Text; 

    public class X509SecurityTokenAuthenticator : SecurityTokenAuthenticator
    {
        X509CertificateValidator validator; 
        bool mapToWindows;
        bool includeWindowsGroups; 
        bool cloneHandle; 

        public X509SecurityTokenAuthenticator() 
            : this(X509CertificateValidator.ChainTrust)
        {
        }
 
        public X509SecurityTokenAuthenticator(X509CertificateValidator validator)
            : this(validator, false) 
        { 
        }
 
        public X509SecurityTokenAuthenticator(X509CertificateValidator validator, bool mapToWindows)
            : this(validator, mapToWindows, WindowsClaimSet.DefaultIncludeWindowsGroups)
        {
        } 

        public X509SecurityTokenAuthenticator(X509CertificateValidator validator, bool mapToWindows, bool includeWindowsGroups) 
            : this(validator, mapToWindows, includeWindowsGroups, true) 
        {
        } 

        internal X509SecurityTokenAuthenticator(X509CertificateValidator validator, bool mapToWindows, bool includeWindowsGroups, bool cloneHandle)
        {
            if (validator == null) 
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("validator"); 
            } 

            this.validator = validator; 
            this.mapToWindows = mapToWindows;
            this.includeWindowsGroups = includeWindowsGroups;
            this.cloneHandle = cloneHandle;
        } 

        public bool MapCertificateToWindowsAccount 
        { 
            get { return this.mapToWindows; }
        } 

        protected override bool CanValidateTokenCore(SecurityToken token)
        {
            return token is X509SecurityToken; 
        }
 
        protected override ReadOnlyCollection ValidateTokenCore(SecurityToken token) 
        {
            X509SecurityToken x509Token = (X509SecurityToken)token; 
            this.validator.Validate(x509Token.Certificate);

            X509CertificateClaimSet x509ClaimSet = new X509CertificateClaimSet(x509Token.Certificate, this.cloneHandle);
            if (!this.mapToWindows) 
                return SecurityUtils.CreateAuthorizationPolicies(x509ClaimSet, x509Token.ValidTo);
 
            WindowsClaimSet windowsClaimSet; 
            if (token is X509WindowsSecurityToken)
            { 
                windowsClaimSet = new WindowsClaimSet( ( (X509WindowsSecurityToken)token ).WindowsIdentity, SecurityUtils.AuthTypeCertMap, this.includeWindowsGroups, this.cloneHandle );
            }
            else
            { 
                // Ensure NT_AUTH chain policy for certificate account mapping
                X509CertificateValidator.NTAuthChainTrust.Validate(x509Token.Certificate); 
 
                WindowsIdentity windowsIdentity = null;
                // for Vista, LsaLogon supporting mapping cert to NTToken 
                if (Environment.OSVersion.Version.Major >= SecurityUtils.WindowsVistaMajorNumber)
                {
                    windowsIdentity = KerberosCertificateLogon(x509Token.Certificate);
                } 
                else
                { 
                    // Downlevel, S4U over PrincipalName SubjectAltNames 
                    string name = x509Token.Certificate.GetNameInfo(X509NameType.UpnName, false);
                    if (String.IsNullOrEmpty(name)) 
                    {
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityTokenValidationException(SR.GetString(SR.InvalidNtMapping,
                            SecurityUtils.GetCertificateId(x509Token.Certificate))));
                    } 

                    using (WindowsIdentity initialWindowsIdentity = new WindowsIdentity(name, SecurityUtils.AuthTypeCertMap)) 
                    { 
                        // This is to make sure that the auth Type is shoved down to the class as the above constructor does not do it.
                        windowsIdentity = new WindowsIdentity(initialWindowsIdentity.Token, SecurityUtils.AuthTypeCertMap); 
                    }
                }

                windowsClaimSet = new WindowsClaimSet(windowsIdentity, SecurityUtils.AuthTypeCertMap, this.includeWindowsGroups, false); 
            }
            List claimSets = new List(2); 
            claimSets.Add(windowsClaimSet); 
            claimSets.Add(x509ClaimSet);
 
            List policies = new List(1);
            policies.Add(new UnconditionalPolicy(claimSets.AsReadOnly(), x509Token.ValidTo));
            return policies.AsReadOnly();
        } 

        // For Vista, LsaLogon supporting mapping cert to NTToken.  W/O SeTcbPrivilege 
        // the identify token is returned; otherwise, impersonation.  This is consistent 
        // with S4U.  Note: duplicate code partly from CLR's WindowsIdentity Class (S4U).
        static WindowsIdentity KerberosCertificateLogon(X509Certificate2 certificate) 
        {
            int status;
            SafeHGlobalHandle pSourceName = null;
            SafeHGlobalHandle pPackageName = null; 
            SafeHGlobalHandle pLogonInfo = null;
            SafeLsaLogonProcessHandle logonHandle = null; 
            SafeLsaReturnBufferHandle profileHandle = null; 
            SafeCloseHandle tokenHandle = null;
            try 
            {
                pSourceName = SafeHGlobalHandle.AllocHGlobal(NativeMethods.LsaSourceName.Length + 1);
                Marshal.Copy(NativeMethods.LsaSourceName, 0, pSourceName.DangerousGetHandle(), NativeMethods.LsaSourceName.Length);
                UNICODE_INTPTR_STRING sourceName = new UNICODE_INTPTR_STRING(NativeMethods.LsaSourceName.Length, NativeMethods.LsaSourceName.Length + 1, pSourceName.DangerousGetHandle()); 

                Privilege privilege = null; 
 
                RuntimeHelpers.PrepareConstrainedRegions();
                // Try to get an impersonation token. 
                try
                {
                    // Try to enable the TCB privilege if possible
                    try 
                    {
                        privilege = new Privilege(Privilege.SeTcbPrivilege); 
                        privilege.Enable(); 
                    }
                    catch (PrivilegeNotHeldException ex) 
                    {
                        if (DiagnosticUtility.ShouldTraceInformation)
                        {
                            DiagnosticUtility.ExceptionUtility.TraceHandledException(ex, TraceEventType.Information); 
                        }
                    } 
 
                    IntPtr dummy = IntPtr.Zero;
                    status = NativeMethods.LsaRegisterLogonProcess(ref sourceName, out logonHandle, out dummy); 
                    if (NativeMethods.ERROR_ACCESS_DENIED == NativeMethods.LsaNtStatusToWinError(status))
                    {
                        // We don't have the Tcb privilege. The best we can hope for is to get an Identification token.
                        status = NativeMethods.LsaConnectUntrusted(out logonHandle); 
                    }
                    if (status < 0) // non-negative numbers indicate success 
                    { 
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(NativeMethods.LsaNtStatusToWinError(status)));
                    } 
                }
                finally
                {
                    // if reverting privilege fails, fail fast! 
                    int revertResult = -1;
                    string message = null; 
                    try 
                    {
                        revertResult = privilege.Revert(); 
                        if (revertResult != 0)
                        {
                            message = SR.GetString(SR.RevertingPrivilegeFailed, new Win32Exception(revertResult));
                        } 
                    }
                    finally 
                    { 
                        if (revertResult != 0)
                        { 
                            DiagnosticUtility.FailFast(message);
                        }
                    }
                } 

                // package name ("Kerberos") 
                pPackageName = SafeHGlobalHandle.AllocHGlobal(NativeMethods.LsaKerberosName.Length + 1); 
                Marshal.Copy(NativeMethods.LsaKerberosName, 0, pPackageName.DangerousGetHandle(), NativeMethods.LsaKerberosName.Length);
                UNICODE_INTPTR_STRING packageName = new UNICODE_INTPTR_STRING(NativeMethods.LsaKerberosName.Length, NativeMethods.LsaKerberosName.Length + 1, pPackageName.DangerousGetHandle()); 

                uint packageId = 0;
                status = NativeMethods.LsaLookupAuthenticationPackage(logonHandle, ref packageName, out packageId);
                if (status < 0) // non-negative numbers indicate success 
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(NativeMethods.LsaNtStatusToWinError(status))); 
                } 

                // source context 
                TOKEN_SOURCE sourceContext = new TOKEN_SOURCE();
                if (!NativeMethods.AllocateLocallyUniqueId(out sourceContext.SourceIdentifier))
                {
                    int dwErrorCode = Marshal.GetLastWin32Error(); 
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(dwErrorCode));
                } 
 
                // SourceContext
                sourceContext.Name = new char[8]; 
                sourceContext.Name[0] = 'W'; sourceContext.Name[1] = 'C'; sourceContext.Name[2] = 'F';

                // LogonInfo
                byte[] certRawData = certificate.RawData; 
                int logonInfoSize = KERB_CERTIFICATE_S4U_LOGON.Size + certRawData.Length;
                pLogonInfo = SafeHGlobalHandle.AllocHGlobal(logonInfoSize); 
                unsafe 
                {
                    KERB_CERTIFICATE_S4U_LOGON* pInfo = (KERB_CERTIFICATE_S4U_LOGON*)pLogonInfo.DangerousGetHandle().ToPointer(); 
                    pInfo->MessageType = KERB_LOGON_SUBMIT_TYPE.KerbCertificateS4ULogon;
                    pInfo->Flags = NativeMethods.KERB_CERTIFICATE_S4U_LOGON_FLAG_CHECK_LOGONHOURS;
                    pInfo->UserPrincipalName = new UNICODE_INTPTR_STRING(0, 0, IntPtr.Zero);
                    pInfo->DomainName = new UNICODE_INTPTR_STRING(0, 0, IntPtr.Zero); 
                    pInfo->CertificateLength = (uint)certRawData.Length;
                    pInfo->Certificate = new IntPtr(pLogonInfo.DangerousGetHandle().ToInt64() + KERB_CERTIFICATE_S4U_LOGON.Size); 
                    Marshal.Copy(certRawData, 0, pInfo->Certificate, certRawData.Length); 
                }
 
                QUOTA_LIMITS quotas = new QUOTA_LIMITS();
                LUID logonId = new LUID();
                uint profileBufferLength;
                int subStatus = 0; 

                // Call LsaLogonUser 
                status = NativeMethods.LsaLogonUser( 
                    logonHandle,
                    ref sourceName, 
                    SecurityLogonType.Network,
                    packageId,
                    pLogonInfo.DangerousGetHandle(),
                    (uint)logonInfoSize, 
                    IntPtr.Zero,
                    ref sourceContext, 
                    out profileHandle, 
                    out profileBufferLength,
                    out logonId, 
                    out tokenHandle,
                    out quotas,
                    out subStatus
                    ); 

                // LsaLogon has restriction (eg. password expired).  SubStatus indicates the reason. 
                if ((uint)status == NativeMethods.STATUS_ACCOUNT_RESTRICTION && subStatus < 0) 
                {
                    status = subStatus; 
                }
                if (status < 0) // non-negative numbers indicate success
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(NativeMethods.LsaNtStatusToWinError(status))); 
                }
                if (subStatus < 0) // non-negative numbers indicate success 
                { 
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(NativeMethods.LsaNtStatusToWinError(subStatus)));
                } 

                return new WindowsIdentity(tokenHandle.DangerousGetHandle(), SecurityUtils.AuthTypeCertMap);
            }
            finally 
            {
                if (tokenHandle != null) 
                { 
                    tokenHandle.Close();
                } 
                if (pLogonInfo != null)
                {
                    pLogonInfo.Close();
                } 
                if (profileHandle != null)
                { 
                    profileHandle.Close(); 
                }
                if (pSourceName != null) 
                {
                    pSourceName.Close();
                }
                if (pPackageName != null) 
                {
                    pPackageName.Close(); 
                } 
                if (logonHandle != null)
                { 
                    logonHandle.Close();
                }
            }
        } 
    }
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
//------------------------------------------------------------ 
// Copyright (c) Microsoft Corporation.  All rights reserved.
//-----------------------------------------------------------

namespace System.IdentityModel.Selectors 
{
    using System.Collections.Generic; 
    using System.Collections.ObjectModel; 
    using System.ComponentModel;
    using System.Diagnostics; 
    using System.IdentityModel.Claims;
    using System.IdentityModel.Policy;
    using System.IdentityModel.Tokens;
    using System.Runtime.CompilerServices; 
    using System.Runtime.InteropServices;
    using System.Security.Cryptography.X509Certificates; 
    using System.Security.AccessControl; 
    using System.Security.Principal;
    using System.Text; 

    public class X509SecurityTokenAuthenticator : SecurityTokenAuthenticator
    {
        X509CertificateValidator validator; 
        bool mapToWindows;
        bool includeWindowsGroups; 
        bool cloneHandle; 

        public X509SecurityTokenAuthenticator() 
            : this(X509CertificateValidator.ChainTrust)
        {
        }
 
        public X509SecurityTokenAuthenticator(X509CertificateValidator validator)
            : this(validator, false) 
        { 
        }
 
        public X509SecurityTokenAuthenticator(X509CertificateValidator validator, bool mapToWindows)
            : this(validator, mapToWindows, WindowsClaimSet.DefaultIncludeWindowsGroups)
        {
        } 

        public X509SecurityTokenAuthenticator(X509CertificateValidator validator, bool mapToWindows, bool includeWindowsGroups) 
            : this(validator, mapToWindows, includeWindowsGroups, true) 
        {
        } 

        internal X509SecurityTokenAuthenticator(X509CertificateValidator validator, bool mapToWindows, bool includeWindowsGroups, bool cloneHandle)
        {
            if (validator == null) 
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("validator"); 
            } 

            this.validator = validator; 
            this.mapToWindows = mapToWindows;
            this.includeWindowsGroups = includeWindowsGroups;
            this.cloneHandle = cloneHandle;
        } 

        public bool MapCertificateToWindowsAccount 
        { 
            get { return this.mapToWindows; }
        } 

        protected override bool CanValidateTokenCore(SecurityToken token)
        {
            return token is X509SecurityToken; 
        }
 
        protected override ReadOnlyCollection ValidateTokenCore(SecurityToken token) 
        {
            X509SecurityToken x509Token = (X509SecurityToken)token; 
            this.validator.Validate(x509Token.Certificate);

            X509CertificateClaimSet x509ClaimSet = new X509CertificateClaimSet(x509Token.Certificate, this.cloneHandle);
            if (!this.mapToWindows) 
                return SecurityUtils.CreateAuthorizationPolicies(x509ClaimSet, x509Token.ValidTo);
 
            WindowsClaimSet windowsClaimSet; 
            if (token is X509WindowsSecurityToken)
            { 
                windowsClaimSet = new WindowsClaimSet( ( (X509WindowsSecurityToken)token ).WindowsIdentity, SecurityUtils.AuthTypeCertMap, this.includeWindowsGroups, this.cloneHandle );
            }
            else
            { 
                // Ensure NT_AUTH chain policy for certificate account mapping
                X509CertificateValidator.NTAuthChainTrust.Validate(x509Token.Certificate); 
 
                WindowsIdentity windowsIdentity = null;
                // for Vista, LsaLogon supporting mapping cert to NTToken 
                if (Environment.OSVersion.Version.Major >= SecurityUtils.WindowsVistaMajorNumber)
                {
                    windowsIdentity = KerberosCertificateLogon(x509Token.Certificate);
                } 
                else
                { 
                    // Downlevel, S4U over PrincipalName SubjectAltNames 
                    string name = x509Token.Certificate.GetNameInfo(X509NameType.UpnName, false);
                    if (String.IsNullOrEmpty(name)) 
                    {
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityTokenValidationException(SR.GetString(SR.InvalidNtMapping,
                            SecurityUtils.GetCertificateId(x509Token.Certificate))));
                    } 

                    using (WindowsIdentity initialWindowsIdentity = new WindowsIdentity(name, SecurityUtils.AuthTypeCertMap)) 
                    { 
                        // This is to make sure that the auth Type is shoved down to the class as the above constructor does not do it.
                        windowsIdentity = new WindowsIdentity(initialWindowsIdentity.Token, SecurityUtils.AuthTypeCertMap); 
                    }
                }

                windowsClaimSet = new WindowsClaimSet(windowsIdentity, SecurityUtils.AuthTypeCertMap, this.includeWindowsGroups, false); 
            }
            List claimSets = new List(2); 
            claimSets.Add(windowsClaimSet); 
            claimSets.Add(x509ClaimSet);
 
            List policies = new List(1);
            policies.Add(new UnconditionalPolicy(claimSets.AsReadOnly(), x509Token.ValidTo));
            return policies.AsReadOnly();
        } 

        // For Vista, LsaLogon supporting mapping cert to NTToken.  W/O SeTcbPrivilege 
        // the identify token is returned; otherwise, impersonation.  This is consistent 
        // with S4U.  Note: duplicate code partly from CLR's WindowsIdentity Class (S4U).
        static WindowsIdentity KerberosCertificateLogon(X509Certificate2 certificate) 
        {
            int status;
            SafeHGlobalHandle pSourceName = null;
            SafeHGlobalHandle pPackageName = null; 
            SafeHGlobalHandle pLogonInfo = null;
            SafeLsaLogonProcessHandle logonHandle = null; 
            SafeLsaReturnBufferHandle profileHandle = null; 
            SafeCloseHandle tokenHandle = null;
            try 
            {
                pSourceName = SafeHGlobalHandle.AllocHGlobal(NativeMethods.LsaSourceName.Length + 1);
                Marshal.Copy(NativeMethods.LsaSourceName, 0, pSourceName.DangerousGetHandle(), NativeMethods.LsaSourceName.Length);
                UNICODE_INTPTR_STRING sourceName = new UNICODE_INTPTR_STRING(NativeMethods.LsaSourceName.Length, NativeMethods.LsaSourceName.Length + 1, pSourceName.DangerousGetHandle()); 

                Privilege privilege = null; 
 
                RuntimeHelpers.PrepareConstrainedRegions();
                // Try to get an impersonation token. 
                try
                {
                    // Try to enable the TCB privilege if possible
                    try 
                    {
                        privilege = new Privilege(Privilege.SeTcbPrivilege); 
                        privilege.Enable(); 
                    }
                    catch (PrivilegeNotHeldException ex) 
                    {
                        if (DiagnosticUtility.ShouldTraceInformation)
                        {
                            DiagnosticUtility.ExceptionUtility.TraceHandledException(ex, TraceEventType.Information); 
                        }
                    } 
 
                    IntPtr dummy = IntPtr.Zero;
                    status = NativeMethods.LsaRegisterLogonProcess(ref sourceName, out logonHandle, out dummy); 
                    if (NativeMethods.ERROR_ACCESS_DENIED == NativeMethods.LsaNtStatusToWinError(status))
                    {
                        // We don't have the Tcb privilege. The best we can hope for is to get an Identification token.
                        status = NativeMethods.LsaConnectUntrusted(out logonHandle); 
                    }
                    if (status < 0) // non-negative numbers indicate success 
                    { 
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(NativeMethods.LsaNtStatusToWinError(status)));
                    } 
                }
                finally
                {
                    // if reverting privilege fails, fail fast! 
                    int revertResult = -1;
                    string message = null; 
                    try 
                    {
                        revertResult = privilege.Revert(); 
                        if (revertResult != 0)
                        {
                            message = SR.GetString(SR.RevertingPrivilegeFailed, new Win32Exception(revertResult));
                        } 
                    }
                    finally 
                    { 
                        if (revertResult != 0)
                        { 
                            DiagnosticUtility.FailFast(message);
                        }
                    }
                } 

                // package name ("Kerberos") 
                pPackageName = SafeHGlobalHandle.AllocHGlobal(NativeMethods.LsaKerberosName.Length + 1); 
                Marshal.Copy(NativeMethods.LsaKerberosName, 0, pPackageName.DangerousGetHandle(), NativeMethods.LsaKerberosName.Length);
                UNICODE_INTPTR_STRING packageName = new UNICODE_INTPTR_STRING(NativeMethods.LsaKerberosName.Length, NativeMethods.LsaKerberosName.Length + 1, pPackageName.DangerousGetHandle()); 

                uint packageId = 0;
                status = NativeMethods.LsaLookupAuthenticationPackage(logonHandle, ref packageName, out packageId);
                if (status < 0) // non-negative numbers indicate success 
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(NativeMethods.LsaNtStatusToWinError(status))); 
                } 

                // source context 
                TOKEN_SOURCE sourceContext = new TOKEN_SOURCE();
                if (!NativeMethods.AllocateLocallyUniqueId(out sourceContext.SourceIdentifier))
                {
                    int dwErrorCode = Marshal.GetLastWin32Error(); 
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(dwErrorCode));
                } 
 
                // SourceContext
                sourceContext.Name = new char[8]; 
                sourceContext.Name[0] = 'W'; sourceContext.Name[1] = 'C'; sourceContext.Name[2] = 'F';

                // LogonInfo
                byte[] certRawData = certificate.RawData; 
                int logonInfoSize = KERB_CERTIFICATE_S4U_LOGON.Size + certRawData.Length;
                pLogonInfo = SafeHGlobalHandle.AllocHGlobal(logonInfoSize); 
                unsafe 
                {
                    KERB_CERTIFICATE_S4U_LOGON* pInfo = (KERB_CERTIFICATE_S4U_LOGON*)pLogonInfo.DangerousGetHandle().ToPointer(); 
                    pInfo->MessageType = KERB_LOGON_SUBMIT_TYPE.KerbCertificateS4ULogon;
                    pInfo->Flags = NativeMethods.KERB_CERTIFICATE_S4U_LOGON_FLAG_CHECK_LOGONHOURS;
                    pInfo->UserPrincipalName = new UNICODE_INTPTR_STRING(0, 0, IntPtr.Zero);
                    pInfo->DomainName = new UNICODE_INTPTR_STRING(0, 0, IntPtr.Zero); 
                    pInfo->CertificateLength = (uint)certRawData.Length;
                    pInfo->Certificate = new IntPtr(pLogonInfo.DangerousGetHandle().ToInt64() + KERB_CERTIFICATE_S4U_LOGON.Size); 
                    Marshal.Copy(certRawData, 0, pInfo->Certificate, certRawData.Length); 
                }
 
                QUOTA_LIMITS quotas = new QUOTA_LIMITS();
                LUID logonId = new LUID();
                uint profileBufferLength;
                int subStatus = 0; 

                // Call LsaLogonUser 
                status = NativeMethods.LsaLogonUser( 
                    logonHandle,
                    ref sourceName, 
                    SecurityLogonType.Network,
                    packageId,
                    pLogonInfo.DangerousGetHandle(),
                    (uint)logonInfoSize, 
                    IntPtr.Zero,
                    ref sourceContext, 
                    out profileHandle, 
                    out profileBufferLength,
                    out logonId, 
                    out tokenHandle,
                    out quotas,
                    out subStatus
                    ); 

                // LsaLogon has restriction (eg. password expired).  SubStatus indicates the reason. 
                if ((uint)status == NativeMethods.STATUS_ACCOUNT_RESTRICTION && subStatus < 0) 
                {
                    status = subStatus; 
                }
                if (status < 0) // non-negative numbers indicate success
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(NativeMethods.LsaNtStatusToWinError(status))); 
                }
                if (subStatus < 0) // non-negative numbers indicate success 
                { 
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(NativeMethods.LsaNtStatusToWinError(subStatus)));
                } 

                return new WindowsIdentity(tokenHandle.DangerousGetHandle(), SecurityUtils.AuthTypeCertMap);
            }
            finally 
            {
                if (tokenHandle != null) 
                { 
                    tokenHandle.Close();
                } 
                if (pLogonInfo != null)
                {
                    pLogonInfo.Close();
                } 
                if (profileHandle != null)
                { 
                    profileHandle.Close(); 
                }
                if (pSourceName != null) 
                {
                    pSourceName.Close();
                }
                if (pPackageName != null) 
                {
                    pPackageName.Close(); 
                } 
                if (logonHandle != null)
                { 
                    logonHandle.Close();
                }
            }
        } 
    }
} 

// 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