https://git.reactos.org/?p=reactos.git;a=commitdiff;h=ac73ba7db6db781b23d097...
commit ac73ba7db6db781b23d097d4518ec4f135f2e0bd Author: Eric Kohl eric.kohl@reactos.org AuthorDate: Mon Mar 4 17:25:11 2019 +0100 Commit: Eric Kohl eric.kohl@reactos.org CommitDate: Mon Mar 4 17:26:27 2019 +0100
[MSV1_0] Check logon hours and workstation names on logon. Also return the machine name on logon and fix the LOGONSERVER environment variable. --- dll/win32/msv1_0/msv1_0.c | 133 +++++++++++++++++++++++++++++++++++++++------- 1 file changed, 114 insertions(+), 19 deletions(-)
diff --git a/dll/win32/msv1_0/msv1_0.c b/dll/win32/msv1_0/msv1_0.c index 9ff2b92234..6529cd0511 100644 --- a/dll/win32/msv1_0/msv1_0.c +++ b/dll/win32/msv1_0/msv1_0.c @@ -94,7 +94,7 @@ static NTSTATUS BuildInteractiveProfileBuffer(IN PLSA_CLIENT_REQUEST ClientRequest, IN PSAMPR_USER_INFO_BUFFER UserInfo, - IN PUNICODE_STRING LogonServer, + IN PWSTR ComputerName, OUT PMSV1_0_INTERACTIVE_PROFILE *ProfileBuffer, OUT PULONG ProfileBufferLength) { @@ -113,7 +113,7 @@ BuildInteractiveProfileBuffer(IN PLSA_CLIENT_REQUEST ClientRequest, UserInfo->All.HomeDirectoryDrive.Length + sizeof(WCHAR) + UserInfo->All.ScriptPath.Length + sizeof(WCHAR) + UserInfo->All.ProfilePath.Length + sizeof(WCHAR) + - LogonServer->Length + sizeof(WCHAR); + ((wcslen(ComputerName) + 3) * sizeof(WCHAR));
LocalBuffer = DispatchTable.AllocateLsaHeap(BufferLength); if (LocalBuffer == NULL) @@ -204,12 +204,11 @@ BuildInteractiveProfileBuffer(IN PLSA_CLIENT_REQUEST ClientRequest,
Ptr = (LPWSTR)((ULONG_PTR)Ptr + LocalBuffer->HomeDirectoryDrive.MaximumLength);
- LocalBuffer->LogonServer.Length = LogonServer->Length; - LocalBuffer->LogonServer.MaximumLength = LogonServer->Length + sizeof(WCHAR); + LocalBuffer->LogonServer.Length = (wcslen(ComputerName) + 2) * sizeof(WCHAR); + LocalBuffer->LogonServer.MaximumLength = LocalBuffer->LogonServer.Length + sizeof(WCHAR); LocalBuffer->LogonServer.Buffer = (LPWSTR)((ULONG_PTR)ClientBaseAddress + (ULONG_PTR)Ptr - (ULONG_PTR)LocalBuffer); - memcpy(Ptr, - LogonServer->Buffer, - LogonServer->Length); + wcscpy(Ptr, L"\"); + wcscat(Ptr, ComputerName);
LocalBuffer->UserFlags = 0;
@@ -844,6 +843,73 @@ done: }
+static +BOOL +MsvpCheckLogonHours( + _In_ PSAMPR_LOGON_HOURS LogonHours, + _In_ PLARGE_INTEGER LogonTime) +{ + LARGE_INTEGER LocalLogonTime; + TIME_FIELDS TimeFields; + USHORT MinutesPerUnit, Offset; + + TRACE("MsvpCheckLogonHours(%p %p)\n", LogonHours, LogonTime); + + if (LogonHours->UnitsPerWeek == 0 || LogonHours->LogonHours == NULL) + return TRUE; + + RtlSystemTimeToLocalTime(LogonTime, &LocalLogonTime); + RtlTimeToTimeFields(&LocalLogonTime, &TimeFields); + + TRACE("UnitsPerWeek: %u\n", LogonHours->UnitsPerWeek); + MinutesPerUnit = 10080 / LogonHours->UnitsPerWeek; + + Offset = ((TimeFields.Weekday * 24 + TimeFields.Hour) * 60 + TimeFields.Minute) / MinutesPerUnit; + + return (BOOL)(LogonHours->LogonHours[Offset / 8] & (1 << (Offset % 8))); +} + + +static +BOOL +MsvpCheckWorkstations( + _In_ PRPC_UNICODE_STRING WorkStations, + _In_ PWSTR ComputerName) +{ + PWSTR pStart, pEnd; + BOOL bFound = FALSE; + + TRACE("MsvpCheckWorkstations(%wZ %S)\n", WorkStations, ComputerName); + + if (WorkStations->Length == 0 || WorkStations->Buffer == NULL) + return TRUE; + + pStart = WorkStations->Buffer; + for (;;) + { + pEnd = wcschr(pStart, L','); + if (pEnd != NULL) + *pEnd = UNICODE_NULL; + + if (_wcsicmp(ComputerName, pStart) == 0) + { + bFound = TRUE; + if (pEnd != NULL) + *pEnd = L','; + break; + } + + if (pEnd == NULL) + break; + + *pEnd = L','; + pStart = pEnd + 1; + } + + return bFound; +} + + /* * @unimplemented */ @@ -944,7 +1010,7 @@ LsaApCallPackageUntrusted(IN PLSA_CLIENT_REQUEST ClientRequest,
/* - * @unimplemented + * @implemented */ NTSTATUS NTAPI @@ -1008,7 +1074,7 @@ LsaApLogonTerminated(IN PLUID LogonId)
/* - * @unimplemented + * @implemented */ NTSTATUS NTAPI @@ -1026,11 +1092,11 @@ LsaApLogonUserEx2(IN PLSA_CLIENT_REQUEST ClientRequest, OUT PUNICODE_STRING *AccountName, OUT PUNICODE_STRING *AuthenticatingAuthority, OUT PUNICODE_STRING *MachineName, - OUT PSECPKG_PRIMARY_CRED PrimaryCredentials, - OUT PSECPKG_SUPPLEMENTAL_CRED_ARRAY *SupplementalCredentials) + OUT PSECPKG_PRIMARY_CRED PrimaryCredentials, /* Not supported yet */ + OUT PSECPKG_SUPPLEMENTAL_CRED_ARRAY *SupplementalCredentials) /* Not supported yet */ { PMSV1_0_INTERACTIVE_LOGON LogonInfo; - + WCHAR ComputerName[MAX_COMPUTERNAME_LENGTH + 1]; SAMPR_HANDLE ServerHandle = NULL; SAMPR_HANDLE DomainHandle = NULL; SAMPR_HANDLE UserHandle = NULL; @@ -1039,12 +1105,12 @@ LsaApLogonUserEx2(IN PLSA_CLIENT_REQUEST ClientRequest, SAMPR_ULONG_ARRAY RelativeIds = {0, NULL}; SAMPR_ULONG_ARRAY Use = {0, NULL}; PSAMPR_USER_INFO_BUFFER UserInfo = NULL; - UNICODE_STRING LogonServer; BOOLEAN SessionCreated = FALSE; LARGE_INTEGER LogonTime; LARGE_INTEGER AccountExpires; LARGE_INTEGER PasswordMustChange; LARGE_INTEGER PasswordLastSet; + DWORD ComputerNameSize; BOOL SpecialAccount = FALSE; NTSTATUS Status;
@@ -1078,8 +1144,6 @@ LsaApLogonUserEx2(IN PLSA_CLIENT_REQUEST ClientRequest, TRACE("Domain: %S\n", LogonInfo->LogonDomainName.Buffer); TRACE("User: %S\n", LogonInfo->UserName.Buffer); TRACE("Password: %S\n", LogonInfo->Password.Buffer); - - RtlInitUnicodeString(&LogonServer, L"Testserver"); } else { @@ -1090,6 +1154,10 @@ LsaApLogonUserEx2(IN PLSA_CLIENT_REQUEST ClientRequest, /* Get the logon time */ NtQuerySystemTime(&LogonTime);
+ /* Get the computer name */ + ComputerNameSize = MAX_COMPUTERNAME_LENGTH + 1; + GetComputerNameW(ComputerName, &ComputerNameSize); + /* Check for special accounts */ if (_wcsicmp(LogonInfo->LogonDomainName.Buffer, L"NT AUTHORITY") == 0) { @@ -1291,9 +1359,23 @@ LsaApLogonUserEx2(IN PLSA_CLIENT_REQUEST ClientRequest, goto done; }
- /* FIXME: more checks */ - // STATUS_INVALID_LOGON_HOURS; - // STATUS_INVALID_WORKSTATION; + /* Check logon hours */ + if (!MsvpCheckLogonHours(&UserInfo->All.LogonHours, &LogonTime)) + { + ERR("Invalid logon hours!\n"); + *SubStatus = STATUS_INVALID_LOGON_HOURS; + Status = STATUS_ACCOUNT_RESTRICTION; + goto done; + } + + /* Check workstations */ + if (!MsvpCheckWorkstations(&UserInfo->All.WorkStations, ComputerName)) + { + ERR("Invalid workstation!\n"); + *SubStatus = STATUS_INVALID_WORKSTATION; + Status = STATUS_ACCOUNT_RESTRICTION; + goto done; + } } }
@@ -1320,7 +1402,7 @@ LsaApLogonUserEx2(IN PLSA_CLIENT_REQUEST ClientRequest, /* Build and fill the interactive profile buffer */ Status = BuildInteractiveProfileBuffer(ClientRequest, UserInfo, - &LogonServer, + ComputerName, (PMSV1_0_INTERACTIVE_PROFILE*)ProfileBuffer, ProfileBufferSize); if (!NT_SUCCESS(Status)) @@ -1390,6 +1472,19 @@ done: } }
+ /* Return the machine name */ + *MachineName = DispatchTable.AllocateLsaHeap(sizeof(UNICODE_STRING)); + if (*MachineName != NULL) + { + (*MachineName)->Buffer = DispatchTable.AllocateLsaHeap((ComputerNameSize + 1) * sizeof(WCHAR)); + if ((*MachineName)->Buffer != NULL) + { + (*MachineName)->MaximumLength = (ComputerNameSize + 1) * sizeof(WCHAR); + (*MachineName)->Length = ComputerNameSize * sizeof(WCHAR); + RtlCopyMemory((*MachineName)->Buffer, ComputerName, (*MachineName)->MaximumLength); + } + } + if (!NT_SUCCESS(Status)) { if (SessionCreated != FALSE)