[LSASRV][MSV1_0]
[reactos.git] / reactos / dll / win32 / lsasrv / authpackage.c
index a5af21f..6eea470 100644 (file)
@@ -6,12 +6,8 @@
  * COPYRIGHT:   Copyright 2013 Eric Kohl
  */
 
-/* INCLUDES ****************************************************************/
-
 #include "lsasrv.h"
 
-WINE_DEFAULT_DEBUG_CHANNEL(lsasrv);
-
 typedef enum _LSA_TOKEN_INFORMATION_TYPE
 {
     LsaTokenInformationNull,
@@ -31,6 +27,9 @@ typedef struct _LSA_TOKEN_INFORMATION_V1
 
 typedef PVOID PLSA_CLIENT_REQUEST;
 
+typedef NTSTATUS (NTAPI *PLSA_CREATE_LOGON_SESSION)(PLUID);
+typedef NTSTATUS (NTAPI *PLSA_DELETE_LOGON_SESSION)(PLUID);
+
 typedef PVOID (NTAPI *PLSA_ALLOCATE_LSA_HEAP)(ULONG);
 typedef VOID (NTAPI *PLSA_FREE_LSA_HEAP)(PVOID);
 typedef NTSTATUS (NTAPI *PLSA_ALLOCATE_CLIENT_BUFFER)(PLSA_CLIENT_REQUEST, ULONG, PVOID*);
@@ -42,8 +41,8 @@ typedef NTSTATUS (NTAPI *PLSA_COPY_FROM_CLIENT_BUFFER)(PLSA_CLIENT_REQUEST,
 
 typedef struct LSA_DISPATCH_TABLE
 {
-    PVOID /*PLSA_CREATE_LOGON_SESSION */ CreateLogonSession;
-    PVOID /*PLSA_DELETE_LOGON_SESSION */ DeleteLogonSession;
+    PLSA_CREATE_LOGON_SESSION CreateLogonSession;
+    PLSA_DELETE_LOGON_SESSION DeleteLogonSession;
     PVOID /*PLSA_ADD_CREDENTIAL */ AddCredential;
     PVOID /*PLSA_GET_CREDENTIALS */ GetCredentials;
     PVOID /*PLSA_DELETE_CREDENTIAL */ DeleteCredential;
@@ -294,26 +293,6 @@ LsapGetAuthenticationPackage(IN ULONG PackageId)
 }
 
 
-static
-NTSTATUS
-NTAPI
-LsapCreateLogonSession(IN PLUID LogonId)
-{
-    TRACE("()\n");
-    return STATUS_SUCCESS;
-}
-
-
-static
-NTSTATUS
-NTAPI
-LsapDeleteLogonSession(IN PLUID LogonId)
-{
-    TRACE("()\n");
-    return STATUS_SUCCESS;
-}
-
-
 static
 PVOID
 NTAPI
@@ -454,8 +433,7 @@ LsapInitAuthPackages(VOID)
                                     &PackageId,
                                     NULL);
 
-
-    return STATUS_SUCCESS;
+    return Status;
 }
 
 
@@ -557,6 +535,160 @@ LsapCallAuthenticationPackage(PLSA_API_MSG RequestMsg,
 }
 
 
+static
+NTSTATUS
+LsapCopyLocalGroups(
+    IN PLSAP_LOGON_CONTEXT LogonContext,
+    IN PTOKEN_GROUPS ClientGroups,
+    IN ULONG ClientGroupsCount,
+    OUT PTOKEN_GROUPS *TokenGroups)
+{
+    ULONG LocalGroupsLength = 0;
+    PTOKEN_GROUPS LocalGroups = NULL;
+    ULONG SidHeaderLength = 0;
+    PSID SidHeader = NULL;
+    PSID SrcSid, DstSid;
+    ULONG SidLength;
+    ULONG AllocatedSids = 0;
+    ULONG i;
+    NTSTATUS Status;
+
+    LocalGroupsLength = sizeof(TOKEN_GROUPS) +
+                        (ClientGroupsCount - ANYSIZE_ARRAY) * sizeof(SID_AND_ATTRIBUTES);
+    LocalGroups = RtlAllocateHeap(RtlGetProcessHeap(),
+                                  HEAP_ZERO_MEMORY,
+                                  LocalGroupsLength);
+    if (LocalGroups == NULL)
+    {
+        TRACE("RtlAllocateHeap() failed\n");
+        return STATUS_INSUFFICIENT_RESOURCES;
+    }
+
+    Status = NtReadVirtualMemory(LogonContext->ClientProcessHandle,
+                                 ClientGroups,
+                                 LocalGroups,
+                                 LocalGroupsLength,
+                                 NULL);
+    if (!NT_SUCCESS(Status))
+        goto done;
+
+
+    SidHeaderLength  = RtlLengthRequiredSid(0);
+    SidHeader = RtlAllocateHeap(RtlGetProcessHeap(),
+                                HEAP_ZERO_MEMORY,
+                                SidHeaderLength);
+    if (SidHeader == NULL)
+    {
+        Status = STATUS_INSUFFICIENT_RESOURCES;
+        goto done;
+    }
+
+    for (i = 0; i < ClientGroupsCount; i++)
+    {
+        SrcSid = LocalGroups->Groups[i].Sid;
+
+        Status = NtReadVirtualMemory(LogonContext->ClientProcessHandle,
+                                     SrcSid,
+                                     SidHeader,
+                                     SidHeaderLength,
+                                     NULL);
+        if (!NT_SUCCESS(Status))
+            goto done;
+
+        SidLength = RtlLengthSid(SidHeader);
+        TRACE("Sid %lu: Length %lu\n", i, SidLength);
+
+        DstSid = RtlAllocateHeap(RtlGetProcessHeap(),
+                                 HEAP_ZERO_MEMORY,
+                                 SidLength);
+        if (DstSid == NULL)
+        {
+            Status = STATUS_INSUFFICIENT_RESOURCES;
+            goto done;
+        }
+
+        Status = NtReadVirtualMemory(LogonContext->ClientProcessHandle,
+                                     SrcSid,
+                                     DstSid,
+                                     SidLength,
+                                     NULL);
+        if (!NT_SUCCESS(Status))
+        {
+            RtlFreeHeap(RtlGetProcessHeap(), 0, DstSid);
+            goto done;
+        }
+
+        LocalGroups->Groups[i].Sid = DstSid;
+        AllocatedSids++;
+    }
+
+    *TokenGroups = LocalGroups;
+
+done:
+    if (SidHeader != NULL)
+        RtlFreeHeap(RtlGetProcessHeap(), 0, SidHeader);
+
+    if (!NT_SUCCESS(Status))
+    {
+        if (LocalGroups != NULL)
+        {
+            for (i = 0; i < AllocatedSids; i++)
+                RtlFreeHeap(RtlGetProcessHeap(), 0, LocalGroups->Groups[i].Sid);
+
+            RtlFreeHeap(RtlGetProcessHeap(), 0, LocalGroups);
+        }
+    }
+
+    return Status;
+}
+
+
+static
+NTSTATUS
+LsapAddTokenDefaultDacl(
+    IN PVOID TokenInformation,
+    IN LSA_TOKEN_INFORMATION_TYPE TokenInformationType)
+{
+    PLSA_TOKEN_INFORMATION_V1 TokenInfo1;
+    PACL Dacl = NULL;
+    ULONG Length;
+
+    if (TokenInformationType == LsaTokenInformationV1)
+    {
+        TokenInfo1 = (PLSA_TOKEN_INFORMATION_V1)TokenInformation;
+
+        if (TokenInfo1->DefaultDacl.DefaultDacl != NULL)
+            return STATUS_SUCCESS;
+
+        Length = sizeof(ACL) +
+                 (2 * sizeof(ACCESS_ALLOWED_ACE)) +
+                 RtlLengthSid(TokenInfo1->Owner.Owner) +
+                 RtlLengthSid(LsapLocalSystemSid);
+
+        Dacl = DispatchTable.AllocateLsaHeap(Length);
+        if (Dacl == NULL)
+            return STATUS_INSUFFICIENT_RESOURCES;
+
+        RtlCreateAcl(Dacl, Length, ACL_REVISION);
+
+        RtlAddAccessAllowedAce(Dacl,
+                               ACL_REVISION,
+                               GENERIC_ALL,
+                               TokenInfo1->Owner.Owner);
+
+        /* SID: S-1-5-18 */
+        RtlAddAccessAllowedAce(Dacl,
+                               ACL_REVISION,
+                               GENERIC_ALL,
+                               LsapLocalSystemSid);
+
+        TokenInfo1->DefaultDacl.DefaultDacl = Dacl;
+    }
+
+    return STATUS_SUCCESS;
+}
+
+
 NTSTATUS
 LsapLogonUser(PLSA_API_MSG RequestMsg,
               PLSAP_LOGON_CONTEXT LogonContext)
@@ -571,6 +703,7 @@ LsapLogonUser(PLSA_API_MSG RequestMsg,
     PUNICODE_STRING AuthenticatingAuthority = NULL;
     PUNICODE_STRING MachineName = NULL;
     PVOID LocalAuthInfo = NULL;
+    PTOKEN_GROUPS LocalGroups = NULL;
     HANDLE TokenHandle = NULL;
     ULONG i;
     ULONG PackageId;
@@ -584,7 +717,7 @@ LsapLogonUser(PLSA_API_MSG RequestMsg,
     Package = LsapGetAuthenticationPackage(PackageId);
     if (Package == NULL)
     {
-        TRACE("LsapGetAuthenticationPackage() failed to find a package\n");
+        ERR("LsapGetAuthenticationPackage() failed to find a package\n");
         return STATUS_NO_SUCH_PACKAGE;
     }
 
@@ -596,7 +729,7 @@ LsapLogonUser(PLSA_API_MSG RequestMsg,
                                         RequestMsg->LogonUser.Request.AuthenticationInformationLength);
         if (LocalAuthInfo == NULL)
         {
-            TRACE("RtlAllocateHeap() failed\n");
+            ERR("RtlAllocateHeap() failed\n");
             return STATUS_INSUFFICIENT_RESOURCES;
         }
 
@@ -608,12 +741,27 @@ LsapLogonUser(PLSA_API_MSG RequestMsg,
                                      NULL);
         if (!NT_SUCCESS(Status))
         {
-            TRACE("NtReadVirtualMemory() failed (Status 0x%08lx)\n", Status);
+            ERR("NtReadVirtualMemory() failed (Status 0x%08lx)\n", Status);
             RtlFreeHeap(RtlGetProcessHeap(), 0, LocalAuthInfo);
             return Status;
         }
     }
 
+    if (RequestMsg->LogonUser.Request.LocalGroupsCount > 0)
+    {
+        Status = LsapCopyLocalGroups(LogonContext,
+                                     RequestMsg->LogonUser.Request.LocalGroups,
+                                     RequestMsg->LogonUser.Request.LocalGroupsCount,
+                                     &LocalGroups);
+        if (!NT_SUCCESS(Status))
+        {
+            ERR("LsapCopyLocalGroups failed (Status 0x%08lx)\n", Status);
+            goto done;
+        }
+
+        TRACE("GroupCount: %lu\n", LocalGroups->GroupCount);
+    }
+
     if (Package->LsaApLogonUserEx2 != NULL)
     {
         Status = Package->LsaApLogonUserEx2((PLSA_CLIENT_REQUEST)LogonContext,
@@ -669,7 +817,16 @@ LsapLogonUser(PLSA_API_MSG RequestMsg,
 
     if (!NT_SUCCESS(Status))
     {
-        TRACE("LsaApLogonUser/Ex/2 failed (Status 0x%08lx)\n", Status);
+        ERR("LsaApLogonUser/Ex/2 failed (Status 0x%08lx)\n", Status);
+        goto done;
+    }
+
+
+    Status = LsapAddTokenDefaultDacl(TokenInformation,
+                                     TokenInformationType);
+    if (!NT_SUCCESS(Status))
+    {
+        ERR("LsapAddTokenDefaultDacl() failed (Status 0x%08lx)\n", Status);
         goto done;
     }
 
@@ -705,7 +862,7 @@ LsapLogonUser(PLSA_API_MSG RequestMsg,
                                &RequestMsg->LogonUser.Request.SourceContext);
         if (!NT_SUCCESS(Status))
         {
-            TRACE("NtCreateToken failed (Status 0x%08lx)\n", Status);
+            ERR("NtCreateToken failed (Status 0x%08lx)\n", Status);
             goto done;
         }
     }
@@ -726,12 +883,19 @@ LsapLogonUser(PLSA_API_MSG RequestMsg,
                                DUPLICATE_SAME_ACCESS | DUPLICATE_SAME_ATTRIBUTES | DUPLICATE_CLOSE_SOURCE);
     if (!NT_SUCCESS(Status))
     {
-        TRACE("NtDuplicateObject failed (Status 0x%08lx)\n", Status);
+        ERR("NtDuplicateObject failed (Status 0x%08lx)\n", Status);
         goto done;
     }
 
     TokenHandle = NULL;
 
+    Status = LsapSetLogonSessionData(&RequestMsg->LogonUser.Reply.LogonId);
+    if (!NT_SUCCESS(Status))
+    {
+        ERR("LsapSetLogonSessionData failed (Status 0x%08lx)\n", Status);
+        goto done;
+    }
+
 done:
     if (!NT_SUCCESS(Status))
     {
@@ -739,10 +903,23 @@ done:
             NtClose(TokenHandle);
     }
 
+    /* Free the local groups */
+    if (LocalGroups != NULL)
+    {
+        for (i = 0; i < LocalGroups->GroupCount; i++)
+        {
+            if (LocalGroups->Groups[i].Sid != NULL)
+                RtlFreeHeap(RtlGetProcessHeap(), 0, LocalGroups->Groups[i].Sid);
+        }
+
+        RtlFreeHeap(RtlGetProcessHeap(), 0, LocalGroups);
+    }
+
     /* Free the local authentication info buffer */
     if (LocalAuthInfo != NULL)
         RtlFreeHeap(RtlGetProcessHeap(), 0, LocalAuthInfo);
 
+    /* Free the token information */
     if (TokenInformation != NULL)
     {
         if (TokenInformationType == LsaTokenInformationV1)
@@ -786,21 +963,35 @@ done:
         }
     }
 
+    /* Free the account name */
     if (AccountName != NULL)
     {
+        if (AccountName->Buffer != NULL)
+            LsapFreeHeap(AccountName->Buffer);
 
+        LsapFreeHeap(AccountName);
     }
 
+    /* Free the authentication authority */
     if (AuthenticatingAuthority != NULL)
     {
+        if (AuthenticatingAuthority != NULL)
+            LsapFreeHeap(AuthenticatingAuthority->Buffer);
 
+        LsapFreeHeap(AuthenticatingAuthority);
     }
 
+    /* Free the machine name */
     if (MachineName != NULL)
     {
+        if (MachineName->Buffer != NULL)
+            LsapFreeHeap(MachineName->Buffer);
 
+        LsapFreeHeap(MachineName);
     }
 
+    TRACE("LsapLogonUser done (Status 0x%08lx)\n", Status);
+
     return Status;
 }