From f5a5066918f9e0c8e533a833bf3954d03c5d3ce7 Mon Sep 17 00:00:00 2001 From: Eric Kohl Date: Sat, 5 Oct 2013 15:27:26 +0000 Subject: [PATCH] [MSV1_0] Add the password check to the logon routine. svn path=/trunk/; revision=60535 --- reactos/dll/win32/msv1_0/CMakeLists.txt | 2 +- reactos/dll/win32/msv1_0/msv1_0.c | 97 +++++++++++++++++++++++-- reactos/dll/win32/msv1_0/msv1_0.h | 10 +++ 3 files changed, 103 insertions(+), 6 deletions(-) diff --git a/reactos/dll/win32/msv1_0/CMakeLists.txt b/reactos/dll/win32/msv1_0/CMakeLists.txt index 2d504c0cf0a..003681efa2f 100644 --- a/reactos/dll/win32/msv1_0/CMakeLists.txt +++ b/reactos/dll/win32/msv1_0/CMakeLists.txt @@ -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) diff --git a/reactos/dll/win32/msv1_0/msv1_0.c b/reactos/dll/win32/msv1_0/msv1_0.c index b5bf8aee5a1..def4006b3df 100644 --- a/reactos/dll/win32/msv1_0/msv1_0.c +++ b/reactos/dll/win32/msv1_0/msv1_0.c @@ -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; diff --git a/reactos/dll/win32/msv1_0/msv1_0.h b/reactos/dll/win32/msv1_0/msv1_0.h index 2223d294a24..dd0be5abddb 100644 --- a/reactos/dll/win32/msv1_0/msv1_0.h +++ b/reactos/dll/win32/msv1_0/msv1_0.h @@ -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 */ -- 2.17.1