From a66c7d2ecccb67cc26df81e455cbdea40ae1a285 Mon Sep 17 00:00:00 2001 From: Eric Kohl Date: Tue, 17 Sep 2019 12:58:11 +0200 Subject: [PATCH] [LSA][SECUR32] Check for untrusted clients Calls to LsapCallAuthenticationPackage are routed to LsaApCallPackageUntrusted instead of LsaApCallPackage for untrusted clients. --- dll/win32/lsasrv/authpackage.c | 23 ++++++--- dll/win32/lsasrv/authport.c | 64 +++++++++++++++++++++++- dll/win32/lsasrv/lsasrv.h | 2 + dll/win32/secur32/lsalpc.c | 1 + sdk/include/reactos/subsys/lsass/lsass.h | 1 + 5 files changed, 83 insertions(+), 8 deletions(-) diff --git a/dll/win32/lsasrv/authpackage.c b/dll/win32/lsasrv/authpackage.c index 29bb465d80b..de140375867 100644 --- a/dll/win32/lsasrv/authpackage.c +++ b/dll/win32/lsasrv/authpackage.c @@ -585,13 +585,22 @@ LsapCallAuthenticationPackage(PLSA_API_MSG RequestMsg, } } - Status = Package->LsaApCallPackage((PLSA_CLIENT_REQUEST)LogonContext, - LocalBuffer, - RequestMsg->CallAuthenticationPackage.Request.ProtocolSubmitBuffer, - RequestMsg->CallAuthenticationPackage.Request.SubmitBufferLength, - &RequestMsg->CallAuthenticationPackage.Reply.ProtocolReturnBuffer, - &RequestMsg->CallAuthenticationPackage.Reply.ReturnBufferLength, - &RequestMsg->CallAuthenticationPackage.Reply.ProtocolStatus); + if (LogonContext->Untrusted) + Status = Package->LsaApCallPackageUntrusted((PLSA_CLIENT_REQUEST)LogonContext, + LocalBuffer, + RequestMsg->CallAuthenticationPackage.Request.ProtocolSubmitBuffer, + RequestMsg->CallAuthenticationPackage.Request.SubmitBufferLength, + &RequestMsg->CallAuthenticationPackage.Reply.ProtocolReturnBuffer, + &RequestMsg->CallAuthenticationPackage.Reply.ReturnBufferLength, + &RequestMsg->CallAuthenticationPackage.Reply.ProtocolStatus); + else + Status = Package->LsaApCallPackage((PLSA_CLIENT_REQUEST)LogonContext, + LocalBuffer, + RequestMsg->CallAuthenticationPackage.Request.ProtocolSubmitBuffer, + RequestMsg->CallAuthenticationPackage.Request.SubmitBufferLength, + &RequestMsg->CallAuthenticationPackage.Reply.ProtocolReturnBuffer, + &RequestMsg->CallAuthenticationPackage.Reply.ReturnBufferLength, + &RequestMsg->CallAuthenticationPackage.Reply.ProtocolStatus); if (!NT_SUCCESS(Status)) { TRACE("Package->LsaApCallPackage() failed (Status 0x%08lx)\n", Status); diff --git a/dll/win32/lsasrv/authport.c b/dll/win32/lsasrv/authport.c index 8e0b128b0f1..192c43bda5a 100644 --- a/dll/win32/lsasrv/authport.c +++ b/dll/win32/lsasrv/authport.c @@ -35,6 +35,64 @@ LsapDeregisterLogonProcess(PLSA_API_MSG RequestMsg, } +static +BOOL +LsapIsTrustedClient( + _In_ HANDLE ProcessHandle) +{ + LUID TcbPrivilege = {SE_TCB_PRIVILEGE, 0}; + HANDLE TokenHandle = NULL; + PTOKEN_PRIVILEGES Privileges = NULL; + ULONG Size, i; + BOOL Trusted = FALSE; + NTSTATUS Status; + + Status = NtOpenProcessToken(ProcessHandle, + TOKEN_QUERY, + &TokenHandle); + if (!NT_SUCCESS(Status)) + goto done; + + Status = NtQueryInformationToken(TokenHandle, + TokenPrivileges, + NULL, + 0, + &Size); + if (!NT_SUCCESS(Status) && Status != STATUS_BUFFER_TOO_SMALL) + goto done; + + Privileges = RtlAllocateHeap(RtlGetProcessHeap(), 0, Size); + if (Privileges == NULL) + goto done; + + Status = NtQueryInformationToken(TokenHandle, + TokenPrivileges, + Privileges, + Size, + &Size); + if (!NT_SUCCESS(Status)) + goto done; + + for (i = 0; i < Privileges->PrivilegeCount; i++) + { + if (RtlEqualLuid(&Privileges->Privileges[i].Luid, &TcbPrivilege)) + { + Trusted = TRUE; + break; + } + } + +done: + if (Privileges != NULL) + RtlFreeHeap(RtlGetProcessHeap(), 0, Privileges); + + if (TokenHandle != NULL) + NtClose(TokenHandle); + + return Trusted; +} + + static NTSTATUS LsapCheckLogonProcess(PLSA_API_MSG RequestMsg, PLSAP_LOGON_CONTEXT *LogonContext) @@ -55,7 +113,7 @@ LsapCheckLogonProcess(PLSA_API_MSG RequestMsg, NULL); Status = NtOpenProcess(&ProcessHandle, - PROCESS_VM_READ | PROCESS_VM_WRITE | PROCESS_VM_OPERATION | PROCESS_DUP_HANDLE, + PROCESS_VM_READ | PROCESS_VM_WRITE | PROCESS_VM_OPERATION | PROCESS_DUP_HANDLE | PROCESS_QUERY_INFORMATION, &ObjectAttributes, &RequestMsg->h.ClientId); if (!NT_SUCCESS(Status)) @@ -77,6 +135,10 @@ LsapCheckLogonProcess(PLSA_API_MSG RequestMsg, TRACE("New LogonContext: %p\n", Context); Context->ClientProcessHandle = ProcessHandle; + Context->Untrusted = RequestMsg->ConnectInfo.Untrusted; + + if (Context->Untrusted == FALSE) + Context->Untrusted = LsapIsTrustedClient(ProcessHandle); *LogonContext = Context; diff --git a/dll/win32/lsasrv/lsasrv.h b/dll/win32/lsasrv/lsasrv.h index 62c7fdd2368..106a175722b 100644 --- a/dll/win32/lsasrv/lsasrv.h +++ b/dll/win32/lsasrv/lsasrv.h @@ -28,6 +28,7 @@ #include #include #include +#include #include #include @@ -78,6 +79,7 @@ typedef struct _LSAP_LOGON_CONTEXT LIST_ENTRY Entry; HANDLE ClientProcessHandle; HANDLE ConnectionHandle; + BOOL Untrusted; } LSAP_LOGON_CONTEXT, *PLSAP_LOGON_CONTEXT; typedef struct _SAMPR_ULONG_ARRAY diff --git a/dll/win32/secur32/lsalpc.c b/dll/win32/secur32/lsalpc.c index 58a806cbb58..6c21f5f1b97 100644 --- a/dll/win32/secur32/lsalpc.c +++ b/dll/win32/secur32/lsalpc.c @@ -174,6 +174,7 @@ LsaConnectUntrusted( ConnectInfoLength); ConnectInfo.CreateContext = TRUE; + ConnectInfo.Untrusted = TRUE; Status = NtConnectPort(LsaHandle, &PortName, diff --git a/sdk/include/reactos/subsys/lsass/lsass.h b/sdk/include/reactos/subsys/lsass/lsass.h index 4d889c0e6c9..612c60b4ff3 100644 --- a/sdk/include/reactos/subsys/lsass/lsass.h +++ b/sdk/include/reactos/subsys/lsass/lsass.h @@ -35,6 +35,7 @@ typedef struct _LSA_CONNECTION_INFO ULONG Length; CHAR LogonProcessNameBuffer[LSASS_MAX_LOGON_PROCESS_NAME_LENGTH + 1]; BOOL CreateContext; + BOOL Untrusted; } LSA_CONNECTION_INFO, *PLSA_CONNECTION_INFO; -- 2.17.1