[MSV1_0]
authorEric Kohl <eric.kohl@reactos.org>
Sat, 5 Oct 2013 15:27:26 +0000 (15:27 +0000)
committerEric Kohl <eric.kohl@reactos.org>
Sat, 5 Oct 2013 15:27:26 +0000 (15:27 +0000)
Add the password check to the logon routine.

svn path=/trunk/; revision=60535

reactos/dll/win32/msv1_0/CMakeLists.txt
reactos/dll/win32/msv1_0/msv1_0.c
reactos/dll/win32/msv1_0/msv1_0.h

index 2d504c0..003681e 100644 (file)
@@ -14,7 +14,7 @@ add_library(msv1_0 SHARED ${SOURCE})
 set_module_type(msv1_0 win32dll UNICODE ENTRYPOINT 0)
 target_link_libraries(msv1_0 wine ${PSEH_LIB})
 add_delay_importlibs(msv1_0 samsrv lsasrv)
-add_importlibs(msv1_0 kernel32 ntdll)
+add_importlibs(msv1_0 advapi32 kernel32 ntdll)
 add_pch(msv1_0 msv1_0.h)
 add_dependencies(msv1_0 psdk)
 add_cd_file(TARGET msv1_0 DESTINATION reactos/system32 FOR all)
index b5bf8ae..def4006 100644 (file)
@@ -764,6 +764,83 @@ ChangePassword(IN PLSA_CLIENT_REQUEST ClientRequest,
 }
 
 
+static
+NTSTATUS
+MsvpCheckPassword(PUNICODE_STRING UserPassword,
+                  PSAMPR_USER_INFO_BUFFER UserInfo)
+{
+    ENCRYPTED_NT_OWF_PASSWORD UserNtPassword;
+    ENCRYPTED_LM_OWF_PASSWORD UserLmPassword;
+    BOOLEAN UserLmPasswordPresent = FALSE;
+    BOOLEAN UserNtPasswordPresent = FALSE;
+    OEM_STRING LmPwdString;
+    CHAR LmPwdBuffer[15];
+    NTSTATUS Status;
+
+    TRACE("(%p %p)\n", UserPassword, UserInfo);
+
+    /* Calculate the LM password and hash for the users password */
+    LmPwdString.Length = 15;
+    LmPwdString.MaximumLength = 15;
+    LmPwdString.Buffer = LmPwdBuffer;
+    ZeroMemory(LmPwdString.Buffer, LmPwdString.MaximumLength);
+
+    Status = RtlUpcaseUnicodeStringToOemString(&LmPwdString,
+                                               UserPassword,
+                                               FALSE);
+    if (NT_SUCCESS(Status))
+    {
+        /* Calculate the LM hash value of the users password */
+        Status = SystemFunction006(LmPwdString.Buffer,
+                                   (LPSTR)&UserLmPassword);
+        if (NT_SUCCESS(Status))
+        {
+            UserLmPasswordPresent = TRUE;
+        }
+    }
+
+    /* Calculate the NT hash of the users password */
+    Status = SystemFunction007(UserPassword,
+                               (LPBYTE)&UserNtPassword);
+    if (NT_SUCCESS(Status))
+    {
+        UserNtPasswordPresent = TRUE;
+    }
+
+    Status = STATUS_SUCCESS;
+
+    if (UserNtPasswordPresent && UserInfo->All.NtPasswordPresent)
+    {
+        TRACE("Check NT password hashes:\n");
+        if (!RtlEqualMemory(&UserNtPassword,
+                            UserInfo->All.NtOwfPassword.Buffer,
+                            sizeof(ENCRYPTED_NT_OWF_PASSWORD)))
+        {
+            TRACE("  failed!\n");
+            Status = STATUS_WRONG_PASSWORD;
+        }
+    }
+    else if (UserLmPasswordPresent && UserInfo->All.LmPasswordPresent)
+    {
+        TRACE("Check LM password hashes:\n");
+        if (!RtlEqualMemory(&UserLmPassword,
+                            UserInfo->All.LmOwfPassword.Buffer,
+                            sizeof(ENCRYPTED_LM_OWF_PASSWORD)))
+        {
+            TRACE("  failed!\n");
+            Status = STATUS_WRONG_PASSWORD;
+        }
+    }
+    else
+    {
+        TRACE("No matching hashes available!\n");
+        Status = STATUS_WRONG_PASSWORD;
+    }
+
+    return Status;
+}
+
+
 /*
  * @unimplemented
  */
@@ -1077,11 +1154,16 @@ LsaApLogonUser(IN PLSA_CLIENT_REQUEST ClientRequest,
 
     /* FIXME: Check restrictions */
 
-    /* FIXME: Check the password */
+    /* Check the password */
     if ((UserInfo->All.UserAccountControl & USER_PASSWORD_NOT_REQUIRED) == 0)
     {
-        FIXME("Must check the password!\n");
-
+        Status = MsvpCheckPassword(&(LogonInfo->Password),
+                                   UserInfo);
+        if (!NT_SUCCESS(Status))
+        {
+            TRACE("MsvpCheckPassword failed (Status %08lx)\n", Status);
+            goto done;
+        }
     }
 
     /* Return logon information */
@@ -1130,8 +1212,6 @@ LsaApLogonUser(IN PLSA_CLIENT_REQUEST ClientRequest,
         goto done;
     }
 
-    *SubStatus = STATUS_SUCCESS;
-
 done:
     /* Return the account name */
     *AccountName = DispatchTable.AllocateLsaHeap(sizeof(UNICODE_STRING));
@@ -1177,6 +1257,13 @@ done:
     if (AccountDomainSid != NULL)
         RtlFreeHeap(RtlGetProcessHeap(), 0, AccountDomainSid);
 
+    if (Status == STATUS_NO_SUCH_USER ||
+        Status == STATUS_WRONG_PASSWORD)
+    {
+        *SubStatus = Status;
+        Status = STATUS_LOGON_FAILURE;
+    }
+
     TRACE("LsaApLogonUser done (Status %08lx)\n", Status);
 
     return Status;
index 2223d29..dd0be5a 100644 (file)
@@ -297,4 +297,14 @@ LsarQueryInformationPolicy(IN LSAPR_HANDLE PolicyHandle,
                            IN POLICY_INFORMATION_CLASS InformationClass,
                            OUT PLSAPR_POLICY_INFORMATION *PolicyInformation);
 
+NTSTATUS
+WINAPI
+SystemFunction006(LPCSTR password,
+                  LPSTR hash);
+
+NTSTATUS
+WINAPI
+SystemFunction007(PUNICODE_STRING string,
+                  LPBYTE hash);
+
 /* EOF */