Exemplo n.º 1
0
 internal static extern int LsaLogonUser(
     [In] SafeLsaLogonProcessHandle LsaHandle,
     [In] ref UNICODE_INTPTR_STRING OriginName,
     [In] SecurityLogonType LogonType,
     [In] uint AuthenticationPackage,
     [In] IntPtr AuthenticationInformation,
     [In] uint AuthenticationInformationLength,
     [In] IntPtr LocalGroups,
     [In] ref TOKEN_SOURCE SourceContext,
     [Out] out SafeLsaReturnBufferHandle ProfileBuffer,
     [Out] out uint ProfileBufferLength,
     [Out] out LUID LogonId,
     [Out] out SafeCloseHandle Token,
     [Out] out QUOTA_LIMITS Quotas,
     [Out] out int SubStatus
     );
        private static bool GetLsaLogonUserHandle(string username, SafeHGlobalHandle pLogonInfo, int logonInfoSize)
        {
            if (null == pLogonInfo)
            {
                throw new ArgumentNullException("pLogonInfo");
            }
            int status;
            SafeHGlobalHandle         pSourceName   = null;
            SafeHGlobalHandle         pPackageName  = null;
            SafeLsaLogonProcessHandle logonHandle   = null;
            SafeLsaReturnBufferHandle profileHandle = null;
            SafeCloseHandle           tokenHandle   = null;

            try
            {
                UNICODE_INTPTR_STRING sourceName = NativeMethods.ConvertByteStringToUnicodeIntPtrString(NativeMethods.LsaSourceName, out pSourceName);
                logonHandle = NativeMethods.RegisterProcess(sourceName);

                RuntimeHelpers.PrepareConstrainedRegions();
                //get packageId
                UNICODE_INTPTR_STRING packageName = NativeMethods.ConvertByteStringToUnicodeIntPtrString(NativeMethods.LsaNegotiateName, out pPackageName);
                uint packageId = 0;
                status = NativeMethods.LsaLookupAuthenticationPackage(logonHandle, ref packageName, out packageId);
                if (status < 0) // non-negative numbers indicate success
                {
                    Trace.TraceError(string.Format("LsaLookupAuthenticationPackage failed for user {0} with status  {1}", username, status));
                    throw new Win32Exception(NativeMethods.LsaNtStatusToWinError(status));
                }

                //get Source context
                TOKEN_SOURCE sourceContext = new TOKEN_SOURCE();
                if (!NativeMethods.AllocateLocallyUniqueId(out sourceContext.SourceIdentifier))
                {
                    int dwErrorCode = Marshal.GetLastWin32Error();
                    Trace.TraceError(string.Format("AllocateLocallyUniqueId failed for user {0} with status  {1}", username, dwErrorCode));
                    throw new Win32Exception(dwErrorCode);
                }
                sourceContext.Name    = new char[8];
                sourceContext.Name[0] = 'A'; sourceContext.Name[1] = 'D'; sourceContext.Name[2] = 'F'; sourceContext.Name[2] = 'S';

                //other parameters
                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;
                    Trace.TraceError(string.Format("Authentication failed for user {0} with account restriction error {1}", username, status));
                    return(false);
                }
                if (status < 0) // non-negative numbers indicate success
                {
                    Trace.TraceError(string.Format("Authentication failed for user {0} with status {1}", username, status));
                    return(false);
                }
                if (subStatus < 0) // non-negative numbers indicate success
                {
                    Trace.TraceError(string.Format("Authentication failed for user {0} with subStatus {1}", username, subStatus));
                    return(false);
                }

                return(true);
            }
            finally
            {
                pSourceName?.Close();
                pPackageName?.Close();
                tokenHandle?.Close();
                profileHandle?.Close();
            }
        }