[LSA][SECUR32] Check for untrusted clients
authorEric Kohl <eric.kohl@reactos.org>
Tue, 17 Sep 2019 10:58:11 +0000 (12:58 +0200)
committerEric Kohl <eric.kohl@reactos.org>
Tue, 17 Sep 2019 10:58:11 +0000 (12:58 +0200)
Calls  to LsapCallAuthenticationPackage are routed to LsaApCallPackageUntrusted instead of LsaApCallPackage for  untrusted clients.

dll/win32/lsasrv/authpackage.c
dll/win32/lsasrv/authport.c
dll/win32/lsasrv/lsasrv.h
dll/win32/secur32/lsalpc.c
sdk/include/reactos/subsys/lsass/lsass.h

index 29bb465..de14037 100644 (file)
@@ -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);
index 8e0b128..192c43b 100644 (file)
@@ -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;
 
index 62c7fdd..106a175 100644 (file)
@@ -28,6 +28,7 @@
 #include <ndk/obfuncs.h>
 #include <ndk/psfuncs.h>
 #include <ndk/rtlfuncs.h>
+#include <ndk/sefuncs.h>
 #include <ndk/ketypes.h>
 #include <ndk/setypes.h>
 
@@ -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
index 58a806c..6c21f5f 100644 (file)
@@ -174,6 +174,7 @@ LsaConnectUntrusted(
                   ConnectInfoLength);
 
     ConnectInfo.CreateContext = TRUE;
+    ConnectInfo.Untrusted = TRUE;
 
     Status = NtConnectPort(LsaHandle,
                            &PortName,
index 4d889c0..612c60b 100644 (file)
@@ -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;