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);
     }
 

Reply via email to