[MSGINA]
authorEric Kohl <eric.kohl@reactos.org>
Sun, 2 Feb 2014 21:52:27 +0000 (21:52 +0000)
committerEric Kohl <eric.kohl@reactos.org>
Sun, 2 Feb 2014 21:52:27 +0000 (21:52 +0000)
Use our own implementation of LogonUser instead of the one from advapi32 in order to use only one LSA connection.

svn path=/trunk/; revision=61932

reactos/dll/win32/msgina/gui.c
reactos/dll/win32/msgina/lsa.c
reactos/dll/win32/msgina/msgina.c
reactos/dll/win32/msgina/msgina.h
reactos/dll/win32/msgina/tui.c

index 4031557..33abbd7 100644 (file)
@@ -829,7 +829,7 @@ DoUnlock(
         else
         {
             /* Wrong user name */
-            if (DoAdminUnlock(UserName, NULL, Password))
+            if (DoAdminUnlock(pgContext, UserName, NULL, Password))
             {
                 *Action = WLX_SAS_ACTION_UNLOCK_WKSTA;
                 res = TRUE;
index 354f7f0..126a55a 100644 (file)
@@ -49,4 +49,223 @@ ConnectToLsa(
     return TRUE;
 }
 
+
+BOOL
+MyLogonUser(
+    HANDLE LsaHandle,
+    ULONG AuthenticationPackage,
+    LPWSTR lpszUsername,
+    LPWSTR lpszDomain,
+    LPWSTR lpszPassword,
+    PHANDLE phToken)
+{
+    SID_IDENTIFIER_AUTHORITY LocalAuthority = {SECURITY_LOCAL_SID_AUTHORITY};
+    SID_IDENTIFIER_AUTHORITY SystemAuthority = {SECURITY_NT_AUTHORITY};
+    PSID LogonSid = NULL;
+    PSID LocalSid = NULL;
+    LSA_STRING OriginName;
+    UNICODE_STRING DomainName;
+    UNICODE_STRING UserName;
+    UNICODE_STRING Password;
+    PMSV1_0_INTERACTIVE_LOGON AuthInfo = NULL;
+    ULONG AuthInfoLength;
+    ULONG_PTR Ptr;
+    TOKEN_SOURCE TokenSource;
+    PTOKEN_GROUPS TokenGroups = NULL;
+    PMSV1_0_INTERACTIVE_PROFILE ProfileBuffer = NULL;
+    ULONG ProfileBufferLength = 0;
+    LUID Luid = {0, 0};
+    LUID LogonId = {0, 0};
+    HANDLE TokenHandle = NULL;
+    QUOTA_LIMITS QuotaLimits;
+    NTSTATUS SubStatus = STATUS_SUCCESS;
+    NTSTATUS Status;
+
+    *phToken = NULL;
+
+    RtlInitAnsiString((PANSI_STRING)&OriginName,
+                      "MSGINA Logon");
+
+    RtlInitUnicodeString(&DomainName,
+                         lpszDomain);
+
+    RtlInitUnicodeString(&UserName,
+                         lpszUsername);
+
+    RtlInitUnicodeString(&Password,
+                         lpszPassword);
+
+    AuthInfoLength = sizeof(MSV1_0_INTERACTIVE_LOGON)+
+                     DomainName.MaximumLength +
+                     UserName.MaximumLength +
+                     Password.MaximumLength;
+
+    AuthInfo = RtlAllocateHeap(RtlGetProcessHeap(),
+                               HEAP_ZERO_MEMORY,
+                               AuthInfoLength);
+    if (AuthInfo == NULL)
+    {
+        Status = STATUS_INSUFFICIENT_RESOURCES;
+        goto done;
+    }
+
+    AuthInfo->MessageType = MsV1_0InteractiveLogon;
+
+    Ptr = (ULONG_PTR)AuthInfo + sizeof(MSV1_0_INTERACTIVE_LOGON);
+
+    AuthInfo->LogonDomainName.Length = DomainName.Length;
+    AuthInfo->LogonDomainName.MaximumLength = DomainName.MaximumLength;
+    AuthInfo->LogonDomainName.Buffer = (DomainName.Buffer == NULL) ? NULL : (PWCHAR)Ptr;
+    if (DomainName.MaximumLength > 0)
+    {
+        RtlCopyMemory(AuthInfo->LogonDomainName.Buffer,
+                      DomainName.Buffer,
+                      DomainName.MaximumLength);
+
+        Ptr += DomainName.MaximumLength;
+    }
+
+    AuthInfo->UserName.Length = UserName.Length;
+    AuthInfo->UserName.MaximumLength = UserName.MaximumLength;
+    AuthInfo->UserName.Buffer = (PWCHAR)Ptr;
+    if (UserName.MaximumLength > 0)
+        RtlCopyMemory(AuthInfo->UserName.Buffer,
+                      UserName.Buffer,
+                      UserName.MaximumLength);
+
+    Ptr += UserName.MaximumLength;
+
+    AuthInfo->Password.Length = Password.Length;
+    AuthInfo->Password.MaximumLength = Password.MaximumLength;
+    AuthInfo->Password.Buffer = (PWCHAR)Ptr;
+    if (Password.MaximumLength > 0)
+        RtlCopyMemory(AuthInfo->Password.Buffer,
+                      Password.Buffer,
+                      Password.MaximumLength);
+
+    /* Create the Logon SID*/
+    AllocateLocallyUniqueId(&LogonId);
+    Status = RtlAllocateAndInitializeSid(&SystemAuthority,
+                                         SECURITY_LOGON_IDS_RID_COUNT,
+                                         SECURITY_LOGON_IDS_RID,
+                                         LogonId.HighPart,
+                                         LogonId.LowPart,
+                                         SECURITY_NULL_RID,
+                                         SECURITY_NULL_RID,
+                                         SECURITY_NULL_RID,
+                                         SECURITY_NULL_RID,
+                                         SECURITY_NULL_RID,
+                                         &LogonSid);
+    if (!NT_SUCCESS(Status))
+        goto done;
+
+    /* Create the Local SID*/
+    Status = RtlAllocateAndInitializeSid(&LocalAuthority,
+                                         1,
+                                         SECURITY_LOCAL_RID,
+                                         SECURITY_NULL_RID,
+                                         SECURITY_NULL_RID,
+                                         SECURITY_NULL_RID,
+                                         SECURITY_NULL_RID,
+                                         SECURITY_NULL_RID,
+                                         SECURITY_NULL_RID,
+                                         SECURITY_NULL_RID,
+                                         &LocalSid);
+    if (!NT_SUCCESS(Status))
+        goto done;
+
+    /* Allocate and set the token groups */
+    TokenGroups = RtlAllocateHeap(RtlGetProcessHeap(),
+                                  HEAP_ZERO_MEMORY,
+                                  sizeof(TOKEN_GROUPS) + ((2 - ANYSIZE_ARRAY) * sizeof(SID_AND_ATTRIBUTES)));
+    if (TokenGroups == NULL)
+    {
+        Status = STATUS_INSUFFICIENT_RESOURCES;
+        goto done;
+    }
+
+    TokenGroups->GroupCount = 2;
+    TokenGroups->Groups[0].Sid = LogonSid;
+    TokenGroups->Groups[0].Attributes = SE_GROUP_MANDATORY | SE_GROUP_ENABLED |
+                                        SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_LOGON_ID;
+    TokenGroups->Groups[1].Sid = LocalSid;
+    TokenGroups->Groups[1].Attributes = SE_GROUP_MANDATORY | SE_GROUP_ENABLED |
+                                        SE_GROUP_ENABLED_BY_DEFAULT;
+
+    /* Set the token source */
+    strcpy(TokenSource.SourceName, "LogonUser");
+    AllocateLocallyUniqueId(&TokenSource.SourceIdentifier);
+
+    Status = LsaLogonUser(LsaHandle,
+                          &OriginName,
+                          Interactive,
+                          AuthenticationPackage,
+                          (PVOID)AuthInfo,
+                          AuthInfoLength,
+                          TokenGroups,
+                          &TokenSource,
+                          (PVOID*)&ProfileBuffer,
+                          &ProfileBufferLength,
+                          &Luid,
+                          &TokenHandle,
+                          &QuotaLimits,
+                          &SubStatus);
+    if (!NT_SUCCESS(Status))
+    {
+        ERR("LsaLogonUser failed (Status 0x%08lx)\n", Status);
+        goto done;
+    }
+
+    if (ProfileBuffer != NULL)
+    {
+        TRACE("ProfileBuffer: %p\n", ProfileBuffer);
+        TRACE("MessageType: %u\n", ProfileBuffer->MessageType);
+
+        TRACE("FullName: %p\n", ProfileBuffer->FullName.Buffer);
+        TRACE("FullName: %S\n", ProfileBuffer->FullName.Buffer);
+
+        TRACE("LogonServer: %p\n", ProfileBuffer->LogonServer.Buffer);
+        TRACE("LogonServer: %S\n", ProfileBuffer->LogonServer.Buffer);
+    }
+
+    TRACE("Luid: 0x%08lx%08lx\n", Luid.HighPart, Luid.LowPart);
+
+    if (TokenHandle != NULL)
+    {
+        TRACE("TokenHandle: %p\n", TokenHandle);
+    }
+
+    *phToken = TokenHandle;
+
+done:
+    if (ProfileBuffer != NULL)
+        LsaFreeReturnBuffer(ProfileBuffer);
+
+    if (!NT_SUCCESS(Status))
+    {
+        if (TokenHandle != NULL)
+            CloseHandle(TokenHandle);
+    }
+
+    if (TokenGroups != NULL)
+        RtlFreeHeap(RtlGetProcessHeap(), 0, TokenGroups);
+
+    if (LocalSid != NULL)
+        RtlFreeSid(LocalSid);
+
+    if (LogonSid != NULL)
+        RtlFreeSid(LogonSid);
+
+    if (AuthInfo != NULL)
+        RtlFreeHeap(RtlGetProcessHeap(), 0, AuthInfo);
+
+    if (!NT_SUCCESS(Status))
+    {
+        SetLastError(RtlNtStatusToDosError(Status));
+        return FALSE;
+    }
+
+    return TRUE;
+}
+
 /* EOF */
index 2c7c1c1..167fb45 100644 (file)
@@ -594,6 +594,7 @@ DuplicationString(PWSTR Str)
 
 BOOL
 DoAdminUnlock(
+    IN PGINA_CONTEXT pgContext,
     IN PWSTR UserName,
     IN PWSTR Domain,
     IN PWSTR Password)
@@ -607,12 +608,15 @@ DoAdminUnlock(
 
     TRACE("(%S %S %S)\n", UserName, Domain, Password);
 
-    if (!LogonUserW(UserName,
-                    Domain,
-                    Password,
-                    LOGON32_LOGON_INTERACTIVE,
-                    LOGON32_PROVIDER_DEFAULT,
-                    &hToken))
+    if (!ConnectToLsa(pgContext))
+        return FALSE;
+
+    if (!MyLogonUser(pgContext->LsaHandle,
+                     pgContext->AuthenticationPackage,
+                     UserName,
+                     Domain,
+                     Password,
+                     &pgContext->UserToken))
     {
         WARN("LogonUserW() failed\n");
         return FALSE;
@@ -683,10 +687,15 @@ DoLoginTasks(
     DWORD dwLength;
     BOOL bResult;
 
-    if (!LogonUserW(UserName, Domain, Password,
-        LOGON32_LOGON_INTERACTIVE,
-        LOGON32_PROVIDER_DEFAULT,
-        &pgContext->UserToken))
+    if (!ConnectToLsa(pgContext))
+        return FALSE;
+
+    if (!MyLogonUser(pgContext->LsaHandle,
+                     pgContext->AuthenticationPackage,
+                     UserName,
+                     Domain,
+                     Password,
+                     &pgContext->UserToken))
     {
         WARN("LogonUserW() failed\n");
         goto cleanup;
index a9c62a4..f36450d 100644 (file)
@@ -90,10 +90,20 @@ BOOL
 ConnectToLsa(
     PGINA_CONTEXT pgContext);
 
+BOOL
+MyLogonUser(
+    HANDLE LsaHandle,
+    ULONG AuthenticationPackage,
+    LPWSTR lpszUsername,
+    LPWSTR lpszDomain,
+    LPWSTR lpszPassword,
+    PHANDLE phToken);
+
 /* msgina.c */
 
 BOOL
 DoAdminUnlock(
+    IN PGINA_CONTEXT pgContext,
     IN PWSTR UserName,
     IN PWSTR Domain,
     IN PWSTR Password);
index d071fd2..3a99ea4 100644 (file)
@@ -233,14 +233,20 @@ TUILockedSAS(
     if (!ReadString(IDS_ASKFORPASSWORD, Password, 256, FALSE))
         return WLX_SAS_ACTION_NONE;
 
-    if (!LogonUserW(UserName, NULL, Password,
-        LOGON32_LOGON_UNLOCK,
-        LOGON32_PROVIDER_DEFAULT,
-        &hToken))
+    if (!ConnectToLsa(pgContext))
+        return WLX_SAS_ACTION_NONE;
+
+    if (!MyLogonUser(pgContext->LsaHandle,
+                     pgContext->AuthenticationPackage,
+                     UserName,
+                     NULL,
+                     Password,
+                     &hToken))
     {
-        TRACE("LogonUserW() failed\n");
+        WARN("LogonUserW() failed\n");
         return WLX_SAS_ACTION_NONE;
     }
+
     CloseHandle(hToken);
     return WLX_SAS_ACTION_UNLOCK_WKSTA;
 }