https://git.reactos.org/?p=reactos.git;a=commitdiff;h=ac73ba7db6db781b23d09…
commit ac73ba7db6db781b23d097d4518ec4f135f2e0bd
Author: Eric Kohl <eric.kohl(a)reactos.org>
AuthorDate: Mon Mar 4 17:25:11 2019 +0100
Commit: Eric Kohl <eric.kohl(a)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)