https://git.reactos.org/?p=reactos.git;a=commitdiff;h=782ff23261613bb745d55…
commit 782ff23261613bb745d553d95addbe1befbd4c8f
Author: Andreas Maier <staubim(a)quantentunnel.de>
AuthorDate: Sun Feb 16 11:05:25 2020 +0100
Commit: Thomas Faber <thomas.faber(a)reactos.org>
CommitDate: Sat Mar 28 23:27:34 2020 +0100
[MSV1_0] LsaApLogonUserEx2: use RtlRunDecodeUnicodeString to decode password
---
dll/win32/msv1_0/msv1_0.c | 29 +++++++++++++++++++++++++++++
sdk/include/ndk/rtlfuncs.h | 16 ++++++++++++++++
2 files changed, 45 insertions(+)
diff --git a/dll/win32/msv1_0/msv1_0.c b/dll/win32/msv1_0/msv1_0.c
index 6994940290c..6db439cc762 100644
--- a/dll/win32/msv1_0/msv1_0.c
+++ b/dll/win32/msv1_0/msv1_0.c
@@ -1193,6 +1193,8 @@ LsaApLogonUserEx2(IN PLSA_CLIENT_REQUEST ClientRequest,
LARGE_INTEGER PasswordLastSet;
DWORD ComputerNameSize;
BOOL SpecialAccount = FALSE;
+ UCHAR LogonPassHash;
+ PUNICODE_STRING ErasePassword = NULL;
TRACE("LsaApLogonUserEx2()\n");
@@ -1268,6 +1270,18 @@ LsaApLogonUserEx2(IN PLSA_CLIENT_REQUEST ClientRequest,
Status = RtlValidateUnicodeString(0, &LogonInfo->UserName);
if (!NT_SUCCESS(Status))
return STATUS_INVALID_PARAMETER;
+
+ /* MS docs says max length is 0xFF bytes. But thats not the full story:
+ *
+ * A Quote from
https://groups.google.com/forum/#!topic/microsoft.public.win32.programmer.k…:
+ * "... At least on my WinXP SP2. Domain and UserName are passed
+ * in clear text, but the Password is NOT. ..."
+ *
+ * If the higher byte of length != 0 we have to use RtlRunDecodeUnicodeString.
+ */
+ LogonPassHash = (LogonInfo->Password.Length >> 8) & 0xFF;
+ LogonInfo->Password.Length = LogonInfo->Password.Length & 0xFF;
+
/* Password is optional and can be an empty string */
if (LogonInfo->Password.Length)
{
@@ -1281,6 +1295,15 @@ LsaApLogonUserEx2(IN PLSA_CLIENT_REQUEST ClientRequest,
LogonInfo->Password.MaximumLength = 0;
}
+ /* Decode password */
+ if (LogonPassHash > 0)
+ {
+ RtlRunDecodeUnicodeString(LogonPassHash, &LogonInfo->Password);
+ }
+
+ /* ErasePassword will be "erased" before we return */
+ ErasePassword = &LogonInfo->Password;
+
Status = RtlValidateUnicodeString(0, &LogonInfo->Password);
if (!NT_SUCCESS(Status))
return STATUS_INVALID_PARAMETER;
@@ -1574,6 +1597,12 @@ LsaApLogonUserEx2(IN PLSA_CLIENT_REQUEST ClientRequest,
}
done:
+ /* Erase password */
+ if (ErasePassword)
+ {
+ RtlEraseUnicodeString(ErasePassword);
+ }
+
/* Update the logon time/count or the bad password time/count */
if ((UserHandle != NULL) &&
(Status == STATUS_SUCCESS || Status == STATUS_WRONG_PASSWORD))
diff --git a/sdk/include/ndk/rtlfuncs.h b/sdk/include/ndk/rtlfuncs.h
index 68f43745199..1e386af2861 100644
--- a/sdk/include/ndk/rtlfuncs.h
+++ b/sdk/include/ndk/rtlfuncs.h
@@ -2435,6 +2435,22 @@ RtlFreeBuffer(
Buffer->Size = Buffer->StaticSize;
}
+NTSYSAPI
+VOID
+NTAPI
+RtlRunEncodeUnicodeString(
+ _Inout_ PUCHAR Hash,
+ _Inout_ PUNICODE_STRING String
+);
+
+NTSYSAPI
+VOID
+NTAPI
+RtlRunDecodeUnicodeString(
+ _In_ UCHAR Hash,
+ _Inout_ PUNICODE_STRING String
+);
+
#endif /* NTOS_MODE_USER */
//