Author: ekohl Date: Mon Feb 10 20:08:29 2014 New Revision: 62110
URL: http://svn.reactos.org/svn/reactos?rev=62110&view=rev Log: [MSV1_0] - Encrypt the old and new passwords before changing the password.
[MSGINA] - Store the new password after a successful password change in order to be able to unlock a locked computer with the new password.
Modified: trunk/reactos/dll/win32/msgina/gui.c trunk/reactos/dll/win32/msgina/msgina.c trunk/reactos/dll/win32/msgina/msgina.h trunk/reactos/dll/win32/msv1_0/msv1_0.c trunk/reactos/dll/win32/msv1_0/msv1_0.h
Modified: trunk/reactos/dll/win32/msgina/gui.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/msgina/gui.c?rev=... ============================================================================== --- trunk/reactos/dll/win32/msgina/gui.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/msgina/gui.c [iso-8859-1] Mon Feb 10 20:08:29 2014 @@ -283,7 +283,7 @@ IN HWND hwndDlg) { WCHAR UserName[256]; - WCHAR DomainName[256]; + WCHAR Domain[256]; WCHAR OldPassword[256]; WCHAR NewPassword1[256]; WCHAR NewPassword2[256]; @@ -297,7 +297,7 @@ NTSTATUS Status;
GetDlgItemTextW(hwndDlg, IDC_CHANGEPWD_USERNAME, UserName, 256); - GetDlgItemTextW(hwndDlg, IDC_CHANGEPWD_DOMAIN, DomainName, 256); + GetDlgItemTextW(hwndDlg, IDC_CHANGEPWD_DOMAIN, Domain, 256); GetDlgItemTextW(hwndDlg, IDC_CHANGEPWD_OLDPWD, OldPassword, 256); GetDlgItemTextW(hwndDlg, IDC_CHANGEPWD_NEWPWD1, NewPassword1, 256); GetDlgItemTextW(hwndDlg, IDC_CHANGEPWD_NEWPWD2, NewPassword2, 256); @@ -315,7 +315,7 @@
/* Calculate the request buffer size */ RequestBufferSize = sizeof(MSV1_0_CHANGEPASSWORD_REQUEST) + - ((wcslen(DomainName) + 1) * sizeof(WCHAR)) + + ((wcslen(Domain) + 1) * sizeof(WCHAR)) + ((wcslen(UserName) + 1) * sizeof(WCHAR)) + ((wcslen(OldPassword) + 1) * sizeof(WCHAR)) + ((wcslen(NewPassword1) + 1) * sizeof(WCHAR)); @@ -337,12 +337,12 @@ Ptr = (LPWSTR)((ULONG_PTR)RequestBuffer + sizeof(MSV1_0_CHANGEPASSWORD_REQUEST));
/* Pack the domain name */ - RequestBuffer->DomainName.Length = wcslen(DomainName) * sizeof(WCHAR); + RequestBuffer->DomainName.Length = wcslen(Domain) * sizeof(WCHAR); RequestBuffer->DomainName.MaximumLength = RequestBuffer->DomainName.Length + sizeof(WCHAR); RequestBuffer->DomainName.Buffer = Ptr;
RtlCopyMemory(RequestBuffer->DomainName.Buffer, - DomainName, + Domain, RequestBuffer->DomainName.MaximumLength);
Ptr = (LPWSTR)((ULONG_PTR)Ptr + RequestBuffer->DomainName.MaximumLength); @@ -412,6 +412,14 @@ MB_OK | MB_ICONINFORMATION, IDS_CHANGEPWDTITLE, IDS_PASSWORDCHANGED); + + if ((wcscmp(UserName, pgContext->UserName) == 0) && + (wcscmp(Domain, pgContext->Domain) == 0) && + (wcscmp(OldPassword, pgContext->Password) == 0)) + { + ZeroMemory(pgContext->Password, 256 * sizeof(WCHAR)); + wcscpy(pgContext->Password, NewPassword1); + }
done: if (RequestBuffer != NULL) @@ -755,11 +763,8 @@ if (GetTextboxText(hwndDlg, IDC_PASSWORD, &Password) && DoLoginTasks(pgContext, UserName, Domain, Password)) { - pgContext->Password = HeapAlloc(GetProcessHeap(), - HEAP_ZERO_MEMORY, - (wcslen(Password) + 1) * sizeof(WCHAR)); - if (pgContext->Password != NULL) - wcscpy(pgContext->Password, Password); + ZeroMemory(pgContext->Password, 256 * sizeof(WCHAR)); + wcscpy(pgContext->Password, Password);
result = WLX_SAS_ACTION_LOGON; }
Modified: trunk/reactos/dll/win32/msgina/msgina.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/msgina/msgina.c?r... ============================================================================== --- trunk/reactos/dll/win32/msgina/msgina.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/msgina/msgina.c [iso-8859-1] Mon Feb 10 20:08:29 2014 @@ -871,11 +871,8 @@
if (result == TRUE) { - pgContext->Password = HeapAlloc(GetProcessHeap(), - HEAP_ZERO_MEMORY, - (wcslen(Password) + 1) * sizeof(WCHAR)); - if (pgContext->Password != NULL) - wcscpy(pgContext->Password, Password); + ZeroMemory(pgContext->Password, 256 * sizeof(WCHAR)); + wcscpy(pgContext->Password, Password);
NotifyBootConfigStatus(TRUE); }
Modified: trunk/reactos/dll/win32/msgina/msgina.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/msgina/msgina.h?r... ============================================================================== --- trunk/reactos/dll/win32/msgina/msgina.h [iso-8859-1] (original) +++ trunk/reactos/dll/win32/msgina/msgina.h [iso-8859-1] Mon Feb 10 20:08:29 2014 @@ -42,7 +42,7 @@ /* Information to be filled during logon */ WCHAR UserName[256]; WCHAR Domain[256]; - LPWSTR Password; + WCHAR Password[256]; SYSTEMTIME LogonTime; HANDLE UserToken; PLUID pAuthenticationId;
Modified: trunk/reactos/dll/win32/msv1_0/msv1_0.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/msv1_0/msv1_0.c?r... ============================================================================== --- trunk/reactos/dll/win32/msv1_0/msv1_0.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/msv1_0/msv1_0.c [iso-8859-1] Mon Feb 10 20:08:29 2014 @@ -437,6 +437,22 @@ SAMPR_ULONG_ARRAY Use = {0, NULL}; NTSTATUS Status;
+ ENCRYPTED_NT_OWF_PASSWORD OldNtPassword; + ENCRYPTED_NT_OWF_PASSWORD NewNtPassword; + ENCRYPTED_LM_OWF_PASSWORD OldLmPassword; + ENCRYPTED_LM_OWF_PASSWORD NewLmPassword; + OEM_STRING LmPwdString; + CHAR LmPwdBuffer[15]; + BOOLEAN OldLmPasswordPresent = FALSE; + BOOLEAN NewLmPasswordPresent = FALSE; + + ENCRYPTED_LM_OWF_PASSWORD OldLmEncryptedWithNewLm; + ENCRYPTED_LM_OWF_PASSWORD NewLmEncryptedWithOldLm; + ENCRYPTED_LM_OWF_PASSWORD OldNtEncryptedWithNewNt; + ENCRYPTED_LM_OWF_PASSWORD NewNtEncryptedWithOldNt; + PENCRYPTED_LM_OWF_PASSWORD pOldLmEncryptedWithNewLm = NULL; + PENCRYPTED_LM_OWF_PASSWORD pNewLmEncryptedWithOldLm = NULL; + TRACE("()\n");
RequestBuffer = (PMSV1_0_CHANGEPASSWORD_REQUEST)ProtocolSubmitBuffer; @@ -523,26 +539,128 @@ }
- -#if 0 + /* Calculate the NT hash for the old password */ + Status = SystemFunction007(&RequestBuffer->OldPassword, + (LPBYTE)&OldNtPassword); + if (!NT_SUCCESS(Status)) + { + TRACE("SystemFunction007 failed (Status 0x%08lx)\n", Status); + goto done; + } + + /* Calculate the NT hash for the new password */ + Status = SystemFunction007(&RequestBuffer->NewPassword, + (LPBYTE)&NewNtPassword); + if (!NT_SUCCESS(Status)) + { + TRACE("SystemFunction007 failed (Status 0x%08lx)\n", Status); + goto done; + } + + /* Calculate the LM password and hash for the old password */ + LmPwdString.Length = 15; + LmPwdString.MaximumLength = 15; + LmPwdString.Buffer = LmPwdBuffer; + ZeroMemory(LmPwdString.Buffer, LmPwdString.MaximumLength); + + Status = RtlUpcaseUnicodeStringToOemString(&LmPwdString, + &RequestBuffer->OldPassword, + FALSE); + if (NT_SUCCESS(Status)) + { + /* Calculate the LM hash value of the password */ + Status = SystemFunction006(LmPwdString.Buffer, + (LPSTR)&OldLmPassword); + if (NT_SUCCESS(Status)) + { + OldLmPasswordPresent = TRUE; + } + } + + /* Calculate the LM password and hash for the new password */ + LmPwdString.Length = 15; + LmPwdString.MaximumLength = 15; + LmPwdString.Buffer = LmPwdBuffer; + ZeroMemory(LmPwdString.Buffer, LmPwdString.MaximumLength); + + Status = RtlUpcaseUnicodeStringToOemString(&LmPwdString, + &RequestBuffer->NewPassword, + FALSE); + if (NT_SUCCESS(Status)) + { + /* Calculate the LM hash value of the password */ + Status = SystemFunction006(LmPwdString.Buffer, + (LPSTR)&NewLmPassword); + if (NT_SUCCESS(Status)) + { + NewLmPasswordPresent = TRUE; + } + } + + /* Encrypt the old and new LM passwords, if they exist */ + if (OldLmPasswordPresent && NewLmPasswordPresent) + { + /* Encrypt the old LM password */ + Status = SystemFunction012((const BYTE *)&OldLmPassword, + (const BYTE *)&NewLmPassword, + (LPBYTE)&OldLmEncryptedWithNewLm); + if (!NT_SUCCESS(Status)) + { + TRACE("SystemFunction012 failed (Status 0x%08lx)\n", Status); + goto done; + } + + /* Encrypt the new LM password */ + Status = SystemFunction012((const BYTE *)&NewLmPassword, + (const BYTE *)&OldLmPassword, + (LPBYTE)&NewLmEncryptedWithOldLm); + if (!NT_SUCCESS(Status)) + { + TRACE("SystemFunction012 failed (Status 0x%08lx)\n", Status); + goto done; + } + + pOldLmEncryptedWithNewLm = &OldLmEncryptedWithNewLm; + pNewLmEncryptedWithOldLm = &NewLmEncryptedWithOldLm; + } + + /* Encrypt the old NT password */ + Status = SystemFunction012((const BYTE *)&OldNtPassword, + (const BYTE *)&NewNtPassword, + (LPBYTE)&OldNtEncryptedWithNewNt); + if (!NT_SUCCESS(Status)) + { + TRACE("SystemFunction012 failed (Status 0x%08lx)\n", Status); + goto done; + } + + /* Encrypt the new NT password */ + Status = SystemFunction012((const BYTE *)&NewNtPassword, + (const BYTE *)&OldNtPassword, + (LPBYTE)&NewNtEncryptedWithOldNt); + if (!NT_SUCCESS(Status)) + { + TRACE("SystemFunction012 failed (Status 0x%08lx)\n", Status); + goto done; + } + /* Change the password */ Status = SamrChangePasswordUser(UserHandle, - IN unsigned char LmPresent, - IN PENCRYPTED_LM_OWF_PASSWORD OldLmEncryptedWithNewLm, - IN PENCRYPTED_LM_OWF_PASSWORD NewLmEncryptedWithOldLm, - IN unsigned char NtPresent, - IN PENCRYPTED_NT_OWF_PASSWORD OldNtEncryptedWithNewNt, - IN PENCRYPTED_NT_OWF_PASSWORD NewNtEncryptedWithOldNt, - IN unsigned char NtCrossEncryptionPresent, - IN PENCRYPTED_NT_OWF_PASSWORD NewNtEncryptedWithNewLm, - IN unsigned char LmCrossEncryptionPresent, - IN PENCRYPTED_LM_OWF_PASSWORD NewLmEncryptedWithNewNt) + OldLmPasswordPresent && NewLmPasswordPresent, + pOldLmEncryptedWithNewLm, + pNewLmEncryptedWithOldLm, + TRUE, + &OldNtEncryptedWithNewNt, + &NewNtEncryptedWithOldNt, + FALSE, + NULL, + FALSE, + NULL); if (!NT_SUCCESS(Status)) { TRACE("SamrChangePasswordUser failed (Status %08lx)\n", Status); goto done; } -#endif
done: if (UserHandle != NULL)
Modified: trunk/reactos/dll/win32/msv1_0/msv1_0.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/msv1_0/msv1_0.h?r... ============================================================================== --- trunk/reactos/dll/win32/msv1_0/msv1_0.h [iso-8859-1] (original) +++ trunk/reactos/dll/win32/msv1_0/msv1_0.h [iso-8859-1] Mon Feb 10 20:08:29 2014 @@ -186,6 +186,20 @@
NTSTATUS NTAPI +SamrChangePasswordUser(IN SAMPR_HANDLE UserHandle, + IN unsigned char LmPresent, + IN PENCRYPTED_LM_OWF_PASSWORD OldLmEncryptedWithNewLm, + IN PENCRYPTED_LM_OWF_PASSWORD NewLmEncryptedWithOldLm, + IN unsigned char NtPresent, + IN PENCRYPTED_NT_OWF_PASSWORD OldNtEncryptedWithNewNt, + IN PENCRYPTED_NT_OWF_PASSWORD NewNtEncryptedWithOldNt, + IN unsigned char NtCrossEncryptionPresent, + IN PENCRYPTED_NT_OWF_PASSWORD NewNtEncryptedWithNewLm, + IN unsigned char LmCrossEncryptionPresent, + IN PENCRYPTED_LM_OWF_PASSWORD NewLmEncryptedWithNewNt); + +NTSTATUS +NTAPI SamrCloseHandle(IN OUT SAMPR_HANDLE *SamHandle);
NTSTATUS @@ -317,4 +331,10 @@ SystemFunction007(PUNICODE_STRING string, LPBYTE hash);
+NTSTATUS +WINAPI +SystemFunction012(const BYTE *in, + const BYTE *key, + LPBYTE out); + /* EOF */