Synchronize with trunk r58457.
[reactos.git] / dll / win32 / lsasrv / authport.c
index 3d3633b..61f27b3 100644 (file)
 WINE_DEFAULT_DEBUG_CHANNEL(lsasrv);
 
 
+static LIST_ENTRY LsapLogonContextList;
+
 static HANDLE PortThreadHandle = NULL;
 static HANDLE AuthPortHandle = NULL;
 
 
 /* FUNCTIONS ***************************************************************/
 
-NTSTATUS WINAPI
-AuthPortThreadRoutine(PVOID Param)
+static NTSTATUS
+LsapDeregisterLogonProcess(PLSA_API_MSG RequestMsg,
+                           PLSAP_LOGON_CONTEXT LogonContext)
+{
+    TRACE("(%p %p)\n", RequestMsg, LogonContext);
+
+    RemoveHeadList(&LogonContext->Entry);
+
+    NtClose(LogonContext->ClientProcessHandle);
+    NtClose(LogonContext->ConnectionHandle);
+
+    RtlFreeHeap(RtlGetProcessHeap(), 0, LogonContext);
+
+    return STATUS_SUCCESS;
+}
+
+
+static NTSTATUS
+LsapCheckLogonProcess(PLSA_API_MSG RequestMsg,
+                      PLSAP_LOGON_CONTEXT *LogonContext)
 {
-    LSASS_REQUEST Request;
-    PPORT_MESSAGE Reply = NULL;
+    OBJECT_ATTRIBUTES ObjectAttributes;
+    HANDLE ProcessHandle = NULL;
+    PLSAP_LOGON_CONTEXT Context = NULL;
     NTSTATUS Status;
 
+    TRACE("(%p)\n", RequestMsg);
+
+    TRACE("Client ID: %p %p\n", RequestMsg->h.ClientId.UniqueProcess, RequestMsg->h.ClientId.UniqueThread);
+
+    InitializeObjectAttributes(&ObjectAttributes,
+                               NULL,
+                               0,
+                               NULL,
+                               NULL);
+
+    Status = NtOpenProcess(&ProcessHandle,
+                           PROCESS_VM_READ,
+                           &ObjectAttributes,
+                           &RequestMsg->h.ClientId);
+    if (!NT_SUCCESS(Status))
+    {
+        TRACE("NtOpenProcess() failed (Status %lx)\n", Status);
+        return Status;
+    }
+
+    /* Allocate the logon context */
+    Context = RtlAllocateHeap(RtlGetProcessHeap(),
+                              HEAP_ZERO_MEMORY,
+                              sizeof(LSAP_LOGON_CONTEXT));
+    if (Context == NULL)
+    {
+        NtClose(ProcessHandle);
+        return STATUS_INSUFFICIENT_RESOURCES;
+    }
+
+    TRACE("New LogonContext: %p\n", Context);
+
+    Context->ClientProcessHandle = ProcessHandle;
+
+    *LogonContext = Context;
+
+    return STATUS_SUCCESS;
+}
+
+
+static NTSTATUS
+LsapHandlePortConnection(PLSA_API_MSG RequestMsg)
+{
+    PLSAP_LOGON_CONTEXT LogonContext = NULL;
     HANDLE ConnectionHandle = NULL;
-    PVOID Context = NULL;
     BOOLEAN Accept;
+    REMOTE_PORT_VIEW RemotePortView;
+    NTSTATUS Status;
 
-    TRACE("AuthPortThreadRoutine() called\n");
+    TRACE("(%p)\n", RequestMsg);
 
-    Status = STATUS_SUCCESS;
+    TRACE("Logon Process Name: %s\n", RequestMsg->ConnectInfo.LogonProcessNameBuffer);
 
-    for (;;)
+    Status = LsapCheckLogonProcess(RequestMsg,
+                                   &LogonContext);
+
+    RequestMsg->ConnectInfo.OperationalMode = 0x43218765;
+
+    RequestMsg->ConnectInfo.Status = Status;
+
+    if (NT_SUCCESS(Status))
     {
-        Status = NtReplyWaitReceivePort(AuthPortHandle,
-                                        0,
-                                        Reply,
-                                        &Request.Header);
+        Accept = TRUE;
+    }
+    else
+    {
+        Accept = FALSE;
+    }
+
+    RemotePortView.Length = sizeof(REMOTE_PORT_VIEW);
+    Status = NtAcceptConnectPort(&ConnectionHandle,
+                                 (PVOID*)LogonContext,
+                                 &RequestMsg->h,
+                                 Accept,
+                                 NULL,
+                                 &RemotePortView);
+    if (!NT_SUCCESS(Status))
+    {
+        ERR("NtAcceptConnectPort failed (Status 0x%lx)\n", Status);
+        return Status;
+    }
+
+    if (Accept == TRUE)
+    {
+        LogonContext->ConnectionHandle = ConnectionHandle;
+
+        InsertHeadList(&LsapLogonContextList,
+                       &LogonContext->Entry);
+
+        Status = NtCompleteConnectPort(ConnectionHandle);
         if (!NT_SUCCESS(Status))
         {
-            TRACE("NtReplyWaitReceivePort() failed (Status %lx)\n", Status);
-            break;
+            ERR("NtCompleteConnectPort failed (Status 0x%lx)\n", Status);
+            return Status;
         }
+    }
 
-        TRACE("Received message\n");
+    return Status;
+}
 
-        if (Request.Header.u2.s2.Type == LPC_CONNECTION_REQUEST)
-        {
-            TRACE("Port connection request\n");
 
-            Accept = TRUE;
-            NtAcceptConnectPort(&ConnectionHandle,
-                                &Context,
-                                &Request.Header,
-                                Accept,
-                                NULL,
-                                NULL);
+NTSTATUS WINAPI
+AuthPortThreadRoutine(PVOID Param)
+{
+    PLSAP_LOGON_CONTEXT LogonContext;
+    PLSA_API_MSG ReplyMsg = NULL;
+    LSA_API_MSG RequestMsg;
+    NTSTATUS Status;
 
+    TRACE("AuthPortThreadRoutine() called\n");
 
-            NtCompleteConnectPort(ConnectionHandle);
+    Status = STATUS_SUCCESS;
 
-        }
-        else if (Request.Header.u2.s2.Type == LPC_PORT_CLOSED ||
-                 Request.Header.u2.s2.Type == LPC_CLIENT_DIED)
+    for (;;)
+    {
+        Status = NtReplyWaitReceivePort(AuthPortHandle,
+                                        (PVOID*)&LogonContext,
+                                        &ReplyMsg->h,
+                                        &RequestMsg.h);
+        if (!NT_SUCCESS(Status))
         {
-            TRACE("Port closed or client died request\n");
-
-//            return STATUS_UNSUCCESSFUL;
+            TRACE("NtReplyWaitReceivePort() failed (Status %lx)\n", Status);
+            break;
         }
-        else if (Request.Header.u2.s2.Type == LPC_REQUEST)
-        {
-            TRACE("Received request (Type: %lu)\n", Request.Type);
 
-        }
-        else if (Request.Header.u2.s2.Type == LPC_DATAGRAM)
-        {
-            TRACE("Received datagram\n");
+        TRACE("Received message\n");
 
+        switch (RequestMsg.h.u2.s2.Type)
+        {
+            case LPC_CONNECTION_REQUEST:
+                TRACE("Port connection request\n");
+                Status = LsapHandlePortConnection(&RequestMsg);
+                ReplyMsg = NULL;
+                break;
+
+            case LPC_PORT_CLOSED:
+                TRACE("Port closed\n");
+                ReplyMsg = NULL;
+                break;
+
+            case LPC_CLIENT_DIED:
+                TRACE("Client died\n");
+                ReplyMsg = NULL;
+                break;
+
+            default:
+                TRACE("Received request (ApiNumber: %lu)\n", RequestMsg.ApiNumber);
+
+                switch (RequestMsg.ApiNumber)
+                {
+                    case LSASS_REQUEST_CALL_AUTHENTICATION_PACKAGE:
+                        RequestMsg.Status = LsapCallAuthenticationPackage(&RequestMsg,
+                                                                          LogonContext);
+                        ReplyMsg = &RequestMsg;
+                        break;
+
+                    case LSASS_REQUEST_DEREGISTER_LOGON_PROCESS:
+
+                        ReplyMsg = &RequestMsg;
+                        RequestMsg.Status = STATUS_SUCCESS;
+                        Status = NtReplyPort(AuthPortHandle,
+                                             &ReplyMsg->h);
+
+                        LsapDeregisterLogonProcess(&RequestMsg,
+                                                   LogonContext);
+
+                        ReplyMsg = NULL;
+                        break;
+
+                    case LSASS_REQUEST_LOGON_USER:
+                        RequestMsg.Status = LsapLogonUser(&RequestMsg,
+                                                          LogonContext);
+                        ReplyMsg = &RequestMsg;
+                        break;
+
+                    case LSASS_REQUEST_LOOKUP_AUTHENTICATION_PACKAGE:
+                        RequestMsg.Status = LsapLookupAuthenticationPackage(&RequestMsg,
+                                                                            LogonContext);
+                        ReplyMsg = &RequestMsg;
+                        break;
+
+                    default:
+                        RequestMsg.Status = STATUS_SUCCESS; /* FIXME */
+                        ReplyMsg = &RequestMsg;
+                        break;
+                }
+
+                break;
         }
     }
 
-    return Status;
+    return STATUS_SUCCESS;
 }
 
 
@@ -96,6 +251,9 @@ StartAuthenticationPort(VOID)
     DWORD ThreadId;
     NTSTATUS Status;
 
+    /* Initialize the logon context list */
+    InitializeListHead(&LsapLogonContextList);
+
     RtlInitUnicodeString(&PortName,
                          L"\\LsaAuthenticationPort");
 
@@ -107,9 +265,9 @@ StartAuthenticationPort(VOID)
 
     Status = NtCreatePort(&AuthPortHandle,
                           &ObjectAttributes,
-                          0,
-                          0x100,
-                          0x2000);
+                          sizeof(LSA_CONNECTION_INFO),
+                          sizeof(LSA_API_MSG),
+                          sizeof(LSA_API_MSG) * 32);
     if (!NT_SUCCESS(Status))
     {
         TRACE("NtCreatePort() failed (Status %lx)\n", Status);