From e5d301366c12faaebb95abb02d6a727b8a49e6bd Mon Sep 17 00:00:00 2001 From: Eric Kohl Date: Thu, 22 Sep 2016 11:27:05 +0000 Subject: [PATCH] [LSASRV] LsapGetLogonSessionData: Marshall the session data before sending them to the client. [SECUR32] LsaConnectUntrusted: Wait for the authentication thread. LsaGetLogonSessionData: Unmarshall the session data after receiving them from the server. svn path=/trunk/; revision=72767 --- reactos/dll/win32/lsasrv/session.c | 112 ++++++++++++++++++++++------ reactos/dll/win32/secur32/lsalpc.c | 71 ++++++++++++++++-- reactos/dll/win32/secur32/precomp.h | 1 + 3 files changed, 158 insertions(+), 26 deletions(-) diff --git a/reactos/dll/win32/lsasrv/session.c b/reactos/dll/win32/lsasrv/session.c index b7831814a09..91c8c606341 100644 --- a/reactos/dll/win32/lsasrv/session.c +++ b/reactos/dll/win32/lsasrv/session.c @@ -320,8 +320,8 @@ LsapGetLogonSessionData(IN OUT PLSA_API_MSG RequestMsg) PLSAP_LOGON_SESSION Session; PSECURITY_LOGON_SESSION_DATA LocalSessionData; PVOID ClientBaseAddress = NULL; - ULONG Length, MemSize; - LPWSTR Ptr; + ULONG TotalLength, MemSize, SidLength = 0; + PUCHAR Ptr; NTSTATUS Status; TRACE("LsapGetLogonSessionData(%p)\n", RequestMsg); @@ -332,47 +332,117 @@ LsapGetLogonSessionData(IN OUT PLSA_API_MSG RequestMsg) return STATUS_NO_SUCH_LOGON_SESSION; /* Calculate the required buffer size */ - Length = sizeof(SECURITY_LOGON_SESSION_DATA) + - Session->UserName.MaximumLength; -/* - Session->LogonDomain.MaximumLength + - Session->AuthenticationPackage.MaximumLength + - Session->LogonServer.MaximumLength + - Session->DnsDomainName.MaximumLength + - Session->Upn.MaximumLength; - + TotalLength = sizeof(SECURITY_LOGON_SESSION_DATA) + + Session->UserName.MaximumLength + + Session->LogonDomain.MaximumLength + + Session->AuthenticationPackage.MaximumLength + + Session->LogonServer.MaximumLength + + Session->DnsDomainName.MaximumLength + + Session->Upn.MaximumLength; if (Session->Sid != NULL) - RtlLengthSid(Session->Sid); -*/ - - TRACE("Length: %lu\n", Length); + { + SidLength = RtlLengthSid(Session->Sid); + TotalLength += SidLength; + } + TRACE("TotalLength: %lu\n", TotalLength); /* Allocate the buffer */ LocalSessionData = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, - Length); + TotalLength); if (LocalSessionData == NULL) return STATUS_INSUFFICIENT_RESOURCES; - Ptr = (LPWSTR)((ULONG_PTR)LocalSessionData + sizeof(SECURITY_LOGON_SESSION_DATA)); + Ptr = (PUCHAR)((ULONG_PTR)LocalSessionData + sizeof(SECURITY_LOGON_SESSION_DATA)); TRACE("LocalSessionData: %p Ptr: %p\n", LocalSessionData, Ptr); LocalSessionData->Size = sizeof(SECURITY_LOGON_SESSION_DATA); + /* Copy the LogonId */ RtlCopyLuid(&LocalSessionData->LogonId, &RequestMsg->GetLogonSessionData.Request.LogonId); + /* Copy the UserName string*/ LocalSessionData->UserName.Length = Session->UserName.Length; LocalSessionData->UserName.MaximumLength = Session->UserName.MaximumLength; - LocalSessionData->UserName.Buffer = Ptr; -// RtlCopyMemory(Ptr) + if (Session->UserName.MaximumLength != 0) + { + RtlCopyMemory(Ptr, Session->UserName.Buffer, Session->UserName.MaximumLength); + Ptr = (PUCHAR)((ULONG_PTR)Ptr + Session->UserName.MaximumLength); + LocalSessionData->UserName.Buffer = (PWSTR)((ULONG_PTR)Ptr - (ULONG_PTR)LocalSessionData); + } + + /* Copy the LogonDomain string */ + LocalSessionData->LogonDomain.Length = Session->LogonDomain.Length; + LocalSessionData->LogonDomain.MaximumLength = Session->LogonDomain.MaximumLength; + if (Session->LogonDomain.MaximumLength != 0) + { + RtlCopyMemory(Ptr, Session->LogonDomain.Buffer, Session->LogonDomain.MaximumLength); + Ptr = (PUCHAR)((ULONG_PTR)Ptr + Session->LogonDomain.MaximumLength); + + LocalSessionData->LogonDomain.Buffer = (PWSTR)((ULONG_PTR)Ptr - (ULONG_PTR)LocalSessionData); + } + + /* Copy the AuthenticationPackage string */ + LocalSessionData->AuthenticationPackage.Length = Session->AuthenticationPackage.Length; + LocalSessionData->AuthenticationPackage.MaximumLength = Session->AuthenticationPackage.MaximumLength; + if (Session->AuthenticationPackage.MaximumLength != 0) + { + RtlCopyMemory(Ptr, Session->AuthenticationPackage.Buffer, Session->AuthenticationPackage.MaximumLength); + Ptr = (PUCHAR)((ULONG_PTR)Ptr + Session->AuthenticationPackage.MaximumLength); + + LocalSessionData->AuthenticationPackage.Buffer = (PWSTR)((ULONG_PTR)Ptr - (ULONG_PTR)LocalSessionData); + } LocalSessionData->LogonType = Session->LogonType; LocalSessionData->Session = 0; + /* Sid */ + if (Session->Sid != NULL) + { + RtlCopyMemory(Ptr, Session->Sid, SidLength); + Ptr = (PUCHAR)((ULONG_PTR)Ptr + SidLength); + LocalSessionData->Sid = (PSID)((ULONG_PTR)Ptr - (ULONG_PTR)LocalSessionData); + } + + /* LogonTime */ + LocalSessionData->LogonTime.QuadPart = Session->LogonTime.QuadPart; + + /* Copy the LogonServer string */ + LocalSessionData->LogonServer.Length = Session->LogonServer.Length; + LocalSessionData->LogonServer.MaximumLength = Session->LogonServer.MaximumLength; + if (Session->LogonServer.MaximumLength != 0) + { + RtlCopyMemory(Ptr, Session->LogonServer.Buffer, Session->LogonServer.MaximumLength); + Ptr = (PUCHAR)((ULONG_PTR)Ptr + Session->LogonServer.MaximumLength); + + LocalSessionData->LogonServer.Buffer = (PWSTR)((ULONG_PTR)Ptr - (ULONG_PTR)LocalSessionData); + } + + /* Copy the DnsDomainName string */ + LocalSessionData->DnsDomainName.Length = Session->DnsDomainName.Length; + LocalSessionData->DnsDomainName.MaximumLength = Session->DnsDomainName.MaximumLength; + if (Session->DnsDomainName.MaximumLength != 0) + { + RtlCopyMemory(Ptr, Session->DnsDomainName.Buffer, Session->DnsDomainName.MaximumLength); + Ptr = (PUCHAR)((ULONG_PTR)Ptr + Session->DnsDomainName.MaximumLength); + + LocalSessionData->DnsDomainName.Buffer = (PWSTR)((ULONG_PTR)Ptr - (ULONG_PTR)LocalSessionData); + } + + /* Copy the Upn string */ + LocalSessionData->Upn.Length = Session->Upn.Length; + LocalSessionData->Upn.MaximumLength = Session->Upn.MaximumLength; + if (Session->Upn.MaximumLength != 0) + { + RtlCopyMemory(Ptr, Session->Upn.Buffer, Session->Upn.MaximumLength); + Ptr = (PUCHAR)((ULONG_PTR)Ptr + Session->Upn.MaximumLength); + + LocalSessionData->Upn.Buffer = (PWSTR)((ULONG_PTR)Ptr - (ULONG_PTR)LocalSessionData); + } InitializeObjectAttributes(&ObjectAttributes, @@ -391,7 +461,7 @@ LsapGetLogonSessionData(IN OUT PLSA_API_MSG RequestMsg) goto done; } - MemSize = Length; + MemSize = TotalLength; Status = NtAllocateVirtualMemory(ProcessHandle, &ClientBaseAddress, 0, @@ -410,7 +480,7 @@ LsapGetLogonSessionData(IN OUT PLSA_API_MSG RequestMsg) Status = NtWriteVirtualMemory(ProcessHandle, ClientBaseAddress, LocalSessionData, - Length, + TotalLength, NULL); if (!NT_SUCCESS(Status)) { diff --git a/reactos/dll/win32/secur32/lsalpc.c b/reactos/dll/win32/secur32/lsalpc.c index ac474b270a9..ff44f69063a 100644 --- a/reactos/dll/win32/secur32/lsalpc.c +++ b/reactos/dll/win32/secur32/lsalpc.c @@ -115,14 +115,53 @@ LsaConnectUntrusted( SECURITY_QUALITY_OF_SERVICE SecurityQos; LSA_CONNECTION_INFO ConnectInfo; ULONG ConnectInfoLength = sizeof(ConnectInfo); + OBJECT_ATTRIBUTES ObjectAttributes; + UNICODE_STRING EventName; + HANDLE EventHandle; NTSTATUS Status; TRACE("LsaConnectUntrusted(%p)\n", LsaHandle); - // TODO: Wait on L"\\SECURITY\\LSA_AUTHENTICATION_INITIALIZED" event - // for the LSA server to be ready, and because we are untrusted, - // we may need to impersonate ourselves before! + // TODO: we may need to impersonate ourselves before, because we are untrusted! + /* Wait for the LSA authentication thread */ + RtlInitUnicodeString(&EventName, + L"\\SECURITY\\LSA_AUTHENTICATION_INITIALIZED"); + InitializeObjectAttributes(&ObjectAttributes, + &EventName, + OBJ_CASE_INSENSITIVE | OBJ_PERMANENT, + NULL, + NULL); + Status = NtOpenEvent(&EventHandle, + SYNCHRONIZE, + &ObjectAttributes); + if (!NT_SUCCESS(Status)) + { + WARN("NtOpenEvent failed (Status 0x%08lx)\n", Status); + + Status = NtCreateEvent(&EventHandle, + SYNCHRONIZE, + &ObjectAttributes, + NotificationEvent, + FALSE); + if (!NT_SUCCESS(Status)) + { + WARN("NtCreateEvent failed (Status 0x%08lx)\n", Status); + return Status; + } + } + + Status = NtWaitForSingleObject(EventHandle, + TRUE, + NULL); + NtClose(EventHandle); + if (!NT_SUCCESS(Status)) + { + ERR("NtWaitForSingleObject failed (Status 0x%08lx)\n", Status); + return Status; + } + + /* Connect to the authentication port */ RtlInitUnicodeString(&PortName, L"\\LsaAuthenticationPort"); @@ -248,11 +287,33 @@ LsaGetLogonSessionData( SessionData = ApiMessage.GetLogonSessionData.Reply.SessionDataBuffer; + TRACE("UserName: %p\n", SessionData->UserName.Buffer); if (SessionData->UserName.Buffer != NULL) - SessionData->UserName.Buffer = (LPWSTR)((ULONG_PTR)&SessionData->UserName.Buffer + (ULONG_PTR)SessionData->UserName.Buffer); + SessionData->UserName.Buffer = (LPWSTR)((ULONG_PTR)SessionData + (ULONG_PTR)SessionData->UserName.Buffer); + TRACE("LogonDomain: %p\n", SessionData->LogonDomain.Buffer); + if (SessionData->LogonDomain.Buffer != NULL) + SessionData->LogonDomain.Buffer = (LPWSTR)((ULONG_PTR)SessionData + (ULONG_PTR)SessionData->LogonDomain.Buffer); + + TRACE("AuthenticationPackage: %p\n", SessionData->AuthenticationPackage.Buffer); + if (SessionData->AuthenticationPackage.Buffer != NULL) + SessionData->AuthenticationPackage.Buffer = (LPWSTR)((ULONG_PTR)SessionData + (ULONG_PTR)SessionData->AuthenticationPackage.Buffer); + + TRACE("Sid: %p\n", SessionData->Sid); if (SessionData->Sid != NULL) - SessionData->Sid = (LPWSTR)((ULONG_PTR)&SessionData->Sid + (ULONG_PTR)SessionData->Sid); + SessionData->Sid = (LPWSTR)((ULONG_PTR)SessionData + (ULONG_PTR)SessionData->Sid); + + TRACE("LogonServer: %p\n", SessionData->LogonServer.Buffer); + if (SessionData->LogonServer.Buffer != NULL) + SessionData->LogonServer.Buffer = (LPWSTR)((ULONG_PTR)SessionData + (ULONG_PTR)SessionData->LogonServer.Buffer); + + TRACE("DnsDomainName: %p\n", SessionData->DnsDomainName.Buffer); + if (SessionData->DnsDomainName.Buffer != NULL) + SessionData->DnsDomainName.Buffer = (LPWSTR)((ULONG_PTR)SessionData + (ULONG_PTR)SessionData->DnsDomainName.Buffer); + + TRACE("Upn: %p\n", SessionData->Upn.Buffer); + if (SessionData->Upn.Buffer != NULL) + SessionData->Upn.Buffer = (LPWSTR)((ULONG_PTR)SessionData + (ULONG_PTR)SessionData->Upn.Buffer); *ppLogonSessionData = SessionData; diff --git a/reactos/dll/win32/secur32/precomp.h b/reactos/dll/win32/secur32/precomp.h index a57daeaa66a..13d9eb24ffd 100644 --- a/reactos/dll/win32/secur32/precomp.h +++ b/reactos/dll/win32/secur32/precomp.h @@ -20,6 +20,7 @@ #include #include #define NTOS_MODE_USER +#include #include #include