From bbd6a57c0ff6d77984d1ca934ffbec6dfbdb861d Mon Sep 17 00:00:00 2001 From: Whindmar Saksit Date: Thu, 1 May 2025 17:51:42 +0200 Subject: [PATCH] [MSGINA][LSASRV] Support LSA secret DefaultPassword in autologon (#7936) --- dll/win32/lsasrv/lsarpc.c | 4 +++- dll/win32/msgina/msgina.c | 46 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 1 deletion(-) diff --git a/dll/win32/lsasrv/lsarpc.c b/dll/win32/lsasrv/lsarpc.c index de22cf47097..30cdad6a2b5 100644 --- a/dll/win32/lsasrv/lsarpc.c +++ b/dll/win32/lsasrv/lsarpc.c @@ -3620,6 +3620,8 @@ LsarRetrievePrivateData( PRPC_UNICODE_STRING KeyName, PLSAPR_CR_CIPHER_VALUE *EncryptedData) { + /* TODO: This should just call LsarOpenSecret(SECRET_QUERY_VALUE)+LsarQuerySecret? */ + PLSA_DB_OBJECT PolicyObject = NULL; PLSA_DB_OBJECT SecretObject = NULL; PLSAPR_CR_CIPHER_VALUE EncCurrentValue = NULL; @@ -3633,7 +3635,7 @@ LsarRetrievePrivateData( /* Validate the SecretHandle */ Status = LsapValidateDbObject(PolicyHandle, LsaDbPolicyObject, - POLICY_CREATE_SECRET, + POLICY_GET_PRIVATE_INFORMATION, &PolicyObject); if (!NT_SUCCESS(Status)) { diff --git a/dll/win32/msgina/msgina.c b/dll/win32/msgina/msgina.c index bc1143a5705..cdf796a0a13 100644 --- a/dll/win32/msgina/msgina.c +++ b/dll/win32/msgina/msgina.c @@ -161,6 +161,50 @@ cleanup: HeapFree(GetProcessHeap(), 0, SystemStartOptions); } +static BOOL +SafeGetUnicodeString( + _In_ const LSA_UNICODE_STRING *pInput, + _Out_ PWSTR pszOutput, + _In_ SIZE_T cchMax) +{ + HRESULT hr; + hr = StringCbCopyNExW(pszOutput, cchMax * sizeof(WCHAR), + pInput->Buffer, pInput->Length, + NULL, NULL, + STRSAFE_NO_TRUNCATION | STRSAFE_NULL_ON_FAILURE); + return (hr == S_OK); +} + +/* Reference: https://learn.microsoft.com/en-us/windows/win32/secauthn/protecting-the-automatic-logon-password */ +static BOOL +GetLsaDefaultPassword(_Inout_ PGINA_CONTEXT pgContext) +{ + LSA_HANDLE hPolicy; + LSA_UNICODE_STRING Name, *pPwd; + LSA_OBJECT_ATTRIBUTES ObjectAttributes = { sizeof(ObjectAttributes) }; + + NTSTATUS Status = LsaOpenPolicy(NULL, &ObjectAttributes, + POLICY_GET_PRIVATE_INFORMATION, &hPolicy); + if (!NT_SUCCESS(Status)) + return FALSE; + + RtlInitUnicodeString(&Name, L"DefaultPassword"); + Status = LsaRetrievePrivateData(hPolicy, &Name, &pPwd); + LsaClose(hPolicy); + + if (Status == STATUS_SUCCESS) + { + if (!SafeGetUnicodeString(pPwd, pgContext->Password, + _countof(pgContext->Password))) + { + Status = STATUS_BUFFER_TOO_SMALL; + } + SecureZeroMemory(pPwd->Buffer, pPwd->Length); + LsaFreeMemory(pPwd); + } + + return Status == STATUS_SUCCESS; +} static BOOL @@ -259,6 +303,8 @@ GetRegistrySettings(PGINA_CONTEXT pgContext) NULL, (LPBYTE)&pgContext->Password, &dwSize); + if (rc) + GetLsaDefaultPassword(pgContext); if (lpIgnoreShiftOverride != NULL) HeapFree(GetProcessHeap(), 0, lpIgnoreShiftOverride);