https://git.reactos.org/?p=reactos.git;a=commitdiff;h=0bb830022c7a2bef814dc96a0311fcc66343389f
commit 0bb830022c7a2bef814dc96a0311fcc66343389f Author: Eric Kohl <eric.k...@reactos.org> AuthorDate: Sat Dec 28 16:04:50 2024 +0100 Commit: Eric Kohl <eric.k...@reactos.org> CommitDate: Sat Dec 28 16:04:50 2024 +0100 [MSV1_0] Implement LsaApCallPackage.MsV1_0GetUserInfo --- dll/win32/msv1_0/msv1_0.c | 201 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 199 insertions(+), 2 deletions(-) diff --git a/dll/win32/msv1_0/msv1_0.c b/dll/win32/msv1_0/msv1_0.c index 735b4a3e0df..35584bba37f 100644 --- a/dll/win32/msv1_0/msv1_0.c +++ b/dll/win32/msv1_0/msv1_0.c @@ -17,6 +17,10 @@ typedef struct _LOGON_LIST_ENTRY LIST_ENTRY ListEntry; LUID LogonId; ULONG EnumHandle; + UNICODE_STRING UserName; + UNICODE_STRING LogonDomainName; + UNICODE_STRING LogonServer; + SECURITY_LOGON_TYPE LogonType; } LOGON_LIST_ENTRY, *PLOGON_LIST_ENTRY; /* GLOBALS *****************************************************************/ @@ -27,6 +31,32 @@ ULONG EnumCounter; /* FUNCTIONS ***************************************************************/ +static +PLOGON_LIST_ENTRY +GetLogonByLogonId( + _In_ PLUID LogonId) +{ + PLOGON_LIST_ENTRY LogonEntry; + PLIST_ENTRY CurrentEntry; + + CurrentEntry = LogonListHead.Flink; + while (CurrentEntry != &LogonListHead) + { + LogonEntry = CONTAINING_RECORD(CurrentEntry, + LOGON_LIST_ENTRY, + ListEntry); + + if ((LogonEntry->LogonId.HighPart == LogonId->HighPart) && + (LogonEntry->LogonId.LowPart == LogonId->LowPart)) + return LogonEntry; + + CurrentEntry = CurrentEntry->Flink; + } + + return NULL; +} + + static NTSTATUS BuildInteractiveProfileBuffer(IN PLSA_CLIENT_REQUEST ClientRequest, @@ -287,6 +317,7 @@ done: return Status; } + static PSID AppendRidToSid(PSID SrcSid, @@ -854,6 +885,12 @@ MsvpEnumerateUsers( TRACE("MsvpEnumerateUsers()\n"); + if (SubmitBufferLength < sizeof(MSV1_0_ENUMUSERS_REQUEST)) + { + ERR("Invalid SubmitBufferLength %lu\n", SubmitBufferLength); + return STATUS_INVALID_PARAMETER; + } + /* Count the currently logged-on users */ CurrentEntry = LogonListHead.Flink; while (CurrentEntry != &LogonListHead) @@ -931,7 +968,7 @@ MsvpEnumerateUsers( goto done; } - *ProtocolReturnBuffer = (PMSV1_0_INTERACTIVE_PROFILE)ClientBaseAddress; + *ProtocolReturnBuffer = ClientBaseAddress; *ReturnBufferLength = BufferLength; *ProtocolStatus = STATUS_SUCCESS; @@ -946,7 +983,134 @@ done: ClientBaseAddress); } - return STATUS_SUCCESS; + return Status; +} + + +static +NTSTATUS +MsvpGetUserInfo( + _In_ PLSA_CLIENT_REQUEST ClientRequest, + _In_ PVOID ProtocolSubmitBuffer, + _In_ PVOID ClientBufferBase, + _In_ ULONG SubmitBufferLength, + _Out_ PVOID *ProtocolReturnBuffer, + _Out_ PULONG ReturnBufferLength, + _Out_ PNTSTATUS ProtocolStatus) +{ + PMSV1_0_GETUSERINFO_REQUEST RequestBuffer; + PLOGON_LIST_ENTRY LogonEntry; + PMSV1_0_GETUSERINFO_RESPONSE LocalBuffer = NULL; + PVOID ClientBaseAddress = NULL; + ULONG BufferLength; + PWSTR BufferPtr; + NTSTATUS Status = STATUS_SUCCESS; + + TRACE("MsvpGetUserInfo()\n"); + + if (SubmitBufferLength < sizeof(MSV1_0_GETUSERINFO_REQUEST)) + { + ERR("Invalid SubmitBufferLength %lu\n", SubmitBufferLength); + return STATUS_INVALID_PARAMETER; + } + + RequestBuffer = (PMSV1_0_GETUSERINFO_REQUEST)ProtocolSubmitBuffer; + + TRACE("LogonId: 0x%lx\n", RequestBuffer->LogonId.LowPart); + + LogonEntry = GetLogonByLogonId(&RequestBuffer->LogonId); + if (LogonEntry == NULL) + { + ERR("No logon found for LogonId %lx\n", RequestBuffer->LogonId.LowPart); + Status = STATUS_INSUFFICIENT_RESOURCES; + goto done; + } + + TRACE("UserName: %wZ\n", &LogonEntry->UserName); + TRACE("LogonDomain: %wZ\n", &LogonEntry->LogonDomainName); + TRACE("LogonServer: %wZ\n", &LogonEntry->LogonServer); + + BufferLength = sizeof(MSV1_0_GETUSERINFO_RESPONSE) + + LogonEntry->UserName.MaximumLength + + LogonEntry->LogonDomainName.MaximumLength + + LogonEntry->LogonServer.MaximumLength; + + LocalBuffer = DispatchTable.AllocateLsaHeap(BufferLength); + if (LocalBuffer == NULL) + { + ERR("Failed to allocate the local buffer!\n"); + Status = STATUS_INSUFFICIENT_RESOURCES; + goto done; + } + + Status = DispatchTable.AllocateClientBuffer(ClientRequest, + BufferLength, + &ClientBaseAddress); + if (!NT_SUCCESS(Status)) + { + ERR("DispatchTable.AllocateClientBuffer failed (Status 0x%08lx)\n", Status); + goto done; + } + + TRACE("ClientBaseAddress: %p\n", ClientBaseAddress); + + /* Fill the local buffer */ + LocalBuffer->MessageType = MsV1_0GetUserInfo; + + BufferPtr = (PWSTR)((ULONG_PTR)LocalBuffer + sizeof(MSV1_0_GETUSERINFO_RESPONSE)); + + /* UserName */ + LocalBuffer->UserName.Length = LogonEntry->UserName.Length; + LocalBuffer->UserName.MaximumLength = LogonEntry->UserName.MaximumLength; + LocalBuffer->UserName.Buffer = (PWSTR)((ULONG_PTR)ClientBaseAddress + (ULONG_PTR)BufferPtr - (ULONG_PTR)LocalBuffer); + + RtlCopyMemory(BufferPtr, LogonEntry->UserName.Buffer, LogonEntry->UserName.MaximumLength); + BufferPtr = (PWSTR)((ULONG_PTR)BufferPtr + (ULONG_PTR)LocalBuffer->UserName.MaximumLength); + + /* LogonDomainName */ + LocalBuffer->LogonDomainName.Length = LogonEntry->LogonDomainName.Length; + LocalBuffer->LogonDomainName.MaximumLength = LogonEntry->LogonDomainName.MaximumLength; + LocalBuffer->LogonDomainName.Buffer = (PWSTR)((ULONG_PTR)ClientBaseAddress + (ULONG_PTR)BufferPtr - (ULONG_PTR)LocalBuffer); + + RtlCopyMemory(BufferPtr, LogonEntry->LogonDomainName.Buffer, LogonEntry->LogonDomainName.MaximumLength); + BufferPtr = (PWSTR)((ULONG_PTR)BufferPtr + (ULONG_PTR)LocalBuffer->LogonDomainName.MaximumLength); + + /* LogonServer */ + LocalBuffer->LogonServer.Length = LogonEntry->LogonServer.Length; + LocalBuffer->LogonServer.MaximumLength = LogonEntry->LogonServer.MaximumLength; + LocalBuffer->LogonServer.Buffer = (PWSTR)((ULONG_PTR)ClientBaseAddress + (ULONG_PTR)BufferPtr - (ULONG_PTR)LocalBuffer); + + RtlCopyMemory(BufferPtr, LogonEntry->LogonServer.Buffer, LogonEntry->LogonServer.MaximumLength); + + /* Logon Type */ + LocalBuffer->LogonType = LogonEntry->LogonType; + + Status = DispatchTable.CopyToClientBuffer(ClientRequest, + BufferLength, + ClientBaseAddress, + LocalBuffer); + if (!NT_SUCCESS(Status)) + { + ERR("DispatchTable.CopyToClientBuffer failed (Status 0x%08lx)\n", Status); + goto done; + } + + *ProtocolReturnBuffer = ClientBaseAddress; + *ReturnBufferLength = BufferLength; + *ProtocolStatus = STATUS_SUCCESS; + +done: + if (LocalBuffer != NULL) + DispatchTable.FreeLsaHeap(LocalBuffer); + + if (!NT_SUCCESS(Status)) + { + if (ClientBaseAddress != NULL) + DispatchTable.FreeClientBuffer(ClientRequest, + ClientBaseAddress); + } + + return Status; } @@ -994,6 +1158,15 @@ LsaApCallPackage(IN PLSA_CLIENT_REQUEST ClientRequest, break; case MsV1_0GetUserInfo: + Status = MsvpGetUserInfo(ClientRequest, + ProtocolSubmitBuffer, + ClientBufferBase, + SubmitBufferLength, + ProtocolReturnBuffer, + ReturnBufferLength, + ProtocolStatus); + break; + case MsV1_0ReLogonUsers: Status = STATUS_INVALID_PARAMETER; break; @@ -1484,6 +1657,30 @@ LsaApLogonUserEx2(IN PLSA_CLIENT_REQUEST ClientRequest, LogonEntry->EnumHandle = EnumCounter; EnumCounter++; + TRACE("Logon User: %wZ %wZ %lx\n", LogonUserName, LogonDomain, LogonId->LowPart); + LogonEntry->UserName.Buffer = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, LogonUserName->MaximumLength); + if (LogonEntry->UserName.Buffer) + { + LogonEntry->UserName.MaximumLength = LogonUserName->MaximumLength; + RtlCopyUnicodeString(&LogonEntry->UserName, LogonUserName); + } + + LogonEntry->LogonDomainName.Buffer = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, LogonDomain->MaximumLength); + if (LogonEntry->LogonDomainName.Buffer) + { + LogonEntry->LogonDomainName.MaximumLength = LogonDomain->MaximumLength; + RtlCopyUnicodeString(&LogonEntry->LogonDomainName, LogonDomain); + } + + LogonEntry->LogonServer.Buffer = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, ComputerName.MaximumLength); + if (LogonEntry->LogonServer.Buffer) + { + LogonEntry->LogonServer.MaximumLength = ComputerName.MaximumLength; + RtlCopyUnicodeString(&LogonEntry->LogonServer, &ComputerName); + } + + LogonEntry->LogonType = LogonType; + InsertTailList(&LogonListHead, &LogonEntry->ListEntry); }