[LSASRV] LsapLogonUser creates an impersonation token for a network logon
[reactos.git] / dll / win32 / lsasrv / authpackage.c
index 8122ad2..8eef860 100644 (file)
@@ -2,7 +2,7 @@
  * PROJECT:     Local Security Authority Server DLL
  * LICENSE:     GPL - See COPYING in the top level directory
  * FILE:        dll/win32/lsasrv/authpackage.c
- * PURPOSE:     Authenticaton package management routines
+ * PURPOSE:     Authentication package management routines
  * COPYRIGHT:   Copyright 2013 Eric Kohl
  */
 
@@ -32,7 +32,9 @@ typedef PVOID PLSA_CLIENT_REQUEST;
 
 typedef NTSTATUS (NTAPI *PLSA_CREATE_LOGON_SESSION)(PLUID);
 typedef NTSTATUS (NTAPI *PLSA_DELETE_LOGON_SESSION)(PLUID);
-
+typedef NTSTATUS (NTAPI *PLSA_ADD_CREDENTIAL)(PLUID, ULONG, PLSA_STRING, PLSA_STRING);
+typedef NTSTATUS (NTAPI *PLSA_GET_CREDENTIALS)(PLUID, ULONG, PULONG, BOOLEAN, PLSA_STRING, PULONG, PLSA_STRING);
+typedef NTSTATUS (NTAPI *PLSA_DELETE_CREDENTIAL)(PLUID, ULONG, PLSA_STRING);
 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*);
@@ -46,9 +48,9 @@ typedef struct LSA_DISPATCH_TABLE
 {
     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;
+    PLSA_ADD_CREDENTIAL AddCredential;
+    PLSA_GET_CREDENTIALS GetCredentials;
+    PLSA_DELETE_CREDENTIAL DeleteCredential;
     PLSA_ALLOCATE_LSA_HEAP AllocateLsaHeap;
     PLSA_FREE_LSA_HEAP FreeLsaHeap;
     PLSA_ALLOCATE_CLIENT_BUFFER AllocateClientBuffer;
@@ -104,12 +106,6 @@ LsaIFree_LSAPR_PRIVILEGE_SET(IN PLSAPR_PRIVILEGE_SET Ptr);
 typedef wchar_t *PSAMPR_SERVER_NAME;
 typedef void *SAMPR_HANDLE;
 
-typedef struct _SAMPR_ULONG_ARRAY
-{
-    unsigned long Count;
-    unsigned long *Element;
-} SAMPR_ULONG_ARRAY, *PSAMPR_ULONG_ARRAY;
-
 typedef struct _SAMPR_SID_INFORMATION
 {
     PRPC_SID SidPointer;
@@ -358,25 +354,27 @@ LsapGetAuthenticationPackage(IN ULONG PackageId)
 }
 
 
-static
 PVOID
 NTAPI
 LsapAllocateHeap(IN ULONG Length)
 {
-    return RtlAllocateHeap(RtlGetProcessHeap(),
-                           HEAP_ZERO_MEMORY,
-                           Length);
+    return RtlAllocateHeap(RtlGetProcessHeap(), 0, Length);
+}
+
+
+PVOID
+NTAPI
+LsapAllocateHeapZero(IN ULONG Length)
+{
+    return RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, Length);
 }
 
 
-static
 VOID
 NTAPI
 LsapFreeHeap(IN PVOID Base)
 {
-    RtlFreeHeap(RtlGetProcessHeap(),
-                0,
-                Base);
+    RtlFreeHeap(RtlGetProcessHeap(), 0, Base);
 }
 
 
@@ -388,7 +386,7 @@ LsapAllocateClientBuffer(IN PLSA_CLIENT_REQUEST ClientRequest,
                          OUT PVOID *ClientBaseAddress)
 {
     PLSAP_LOGON_CONTEXT LogonContext;
-    ULONG Length;
+    SIZE_T Length;
 
     *ClientBaseAddress = NULL;
 
@@ -411,7 +409,7 @@ LsapFreeClientBuffer(IN PLSA_CLIENT_REQUEST ClientRequest,
                      IN PVOID ClientBaseAddress)
 {
     PLSAP_LOGON_CONTEXT LogonContext;
-    ULONG Length;
+    SIZE_T Length;
 
     if (ClientBaseAddress == NULL)
         return STATUS_SUCCESS;
@@ -481,10 +479,10 @@ LsapInitAuthPackages(VOID)
     /* Initialize the dispatch table */
     DispatchTable.CreateLogonSession = &LsapCreateLogonSession;
     DispatchTable.DeleteLogonSession = &LsapDeleteLogonSession;
-    DispatchTable.AddCredential = NULL;
-    DispatchTable.GetCredentials = NULL;
-    DispatchTable.DeleteCredential = NULL;
-    DispatchTable.AllocateLsaHeap = &LsapAllocateHeap;
+    DispatchTable.AddCredential = &LsapAddCredential;
+    DispatchTable.GetCredentials = &LsapGetCredentials;
+    DispatchTable.DeleteCredential = &LsapDeleteCredential;
+    DispatchTable.AllocateLsaHeap = &LsapAllocateHeapZero;
     DispatchTable.FreeLsaHeap = &LsapFreeHeap;
     DispatchTable.AllocateClientBuffer = &LsapAllocateClientBuffer;
     DispatchTable.FreeClientBuffer = &LsapFreeClientBuffer;
@@ -948,7 +946,7 @@ LsapAppendSidToGroups(
         Groups->GroupCount = 1;
 
         Groups->Groups[0].Sid = Sid;
-        Groups->Groups[0].Attributes = 
+        Groups->Groups[0].Attributes =
             SE_GROUP_ENABLED | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_MANDATORY;
 
         *TokenGroups = Groups;
@@ -983,7 +981,7 @@ LsapAppendSidToGroups(
         }
 
         Groups->Groups[Groups->GroupCount].Sid = Sid;
-        Groups->Groups[Groups->GroupCount].Attributes = 
+        Groups->Groups[Groups->GroupCount].Attributes =
             SE_GROUP_ENABLED | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_MANDATORY;
 
         Groups->GroupCount++;
@@ -1029,6 +1027,9 @@ LsapAddSamGroups(
     for (i = 0; i < TokenInfo1->Groups->GroupCount; i++)
         SidArray.Sids[i + 1].SidPointer = TokenInfo1->Groups->Groups[i].Sid;
 
+    BuiltinMembership.Element = NULL;
+    AccountMembership.Element = NULL;
+
     Status = SamIConnect(NULL,
                          &ServerHandle,
                          SAM_SERVER_CONNECT | SAM_SERVER_LOOKUP_DOMAIN,
@@ -1059,7 +1060,6 @@ LsapAddSamGroups(
         goto done;
     }
 
-    BuiltinMembership.Element = NULL;
     Status = SamrGetAliasMembership(BuiltinDomainHandle,
                                     &SidArray,
                                     &BuiltinMembership);
@@ -1069,7 +1069,6 @@ LsapAddSamGroups(
         goto done;
     }
 
-    AccountMembership.Element = NULL;
     Status = SamrGetAliasMembership(AccountDomainHandle,
                                     &SidArray,
                                     &AccountMembership);
@@ -1138,7 +1137,7 @@ LsapSetTokenOwner(
     IN LSA_TOKEN_INFORMATION_TYPE TokenInformationType)
 {
     PLSA_TOKEN_INFORMATION_V1 TokenInfo1;
-    PSID OwnerSid = NULL;
+    PSID_AND_ATTRIBUTES OwnerSid = NULL;
     ULONG i, Length;
 
     if (TokenInformationType == LsaTokenInformationV1)
@@ -1148,24 +1147,25 @@ LsapSetTokenOwner(
         if (TokenInfo1->Owner.Owner != NULL)
             return STATUS_SUCCESS;
 
-        OwnerSid = TokenInfo1->User.User.Sid;
+        OwnerSid = &TokenInfo1->User.User;
         for (i = 0; i < TokenInfo1->Groups->GroupCount; i++)
         {
             if (EqualSid(TokenInfo1->Groups->Groups[i].Sid, LsapAdministratorsSid))
             {
-                OwnerSid = LsapAdministratorsSid;
+                OwnerSid = &TokenInfo1->Groups->Groups[i];
                 break;
             }
         }
 
-        Length = RtlLengthSid(OwnerSid);
+        Length = RtlLengthSid(OwnerSid->Sid);
         TokenInfo1->Owner.Owner = DispatchTable.AllocateLsaHeap(Length);
         if (TokenInfo1->Owner.Owner == NULL)
             return STATUS_INSUFFICIENT_RESOURCES;
 
         RtlCopyMemory(TokenInfo1->Owner.Owner,
-                      OwnerSid,
+                      OwnerSid->Sid,
                       Length);
+        OwnerSid->Attributes |= SE_GROUP_OWNER;
     }
 
     return STATUS_SUCCESS;
@@ -1377,7 +1377,12 @@ LsapLogonUser(PLSA_API_MSG RequestMsg,
     SECURITY_LOGON_TYPE LogonType;
     NTSTATUS Status;
 
-    TRACE("(%p %p)\n", RequestMsg, LogonContext);
+    PUNICODE_STRING UserName = NULL;
+    PUNICODE_STRING LogonDomainName = NULL;
+//    UNICODE_STRING LogonServer;
+
+
+    TRACE("LsapLogonUser(%p %p)\n", RequestMsg, LogonContext);
 
     PackageId = RequestMsg->LogonUser.Request.AuthenticationPackage;
     LogonType = RequestMsg->LogonUser.Request.LogonType;
@@ -1402,7 +1407,7 @@ LsapLogonUser(PLSA_API_MSG RequestMsg,
             return STATUS_INSUFFICIENT_RESOURCES;
         }
 
-        /* Read the authentication info from the callers adress space */
+        /* Read the authentication info from the callers address space */
         Status = NtReadVirtualMemory(LogonContext->ClientProcessHandle,
                                      RequestMsg->LogonUser.Request.AuthenticationInformation,
                                      LocalAuthInfo,
@@ -1546,6 +1551,7 @@ LsapLogonUser(PLSA_API_MSG RequestMsg,
 
     if (TokenInformationType == LsaTokenInformationV1)
     {
+        TOKEN_PRIVILEGES NoPrivilege = {0};
         TokenInfo1 = (PLSA_TOKEN_INFORMATION_V1)TokenInformation;
 
         Qos.Length = sizeof(SECURITY_QUALITY_OF_SERVICE);
@@ -1564,12 +1570,13 @@ LsapLogonUser(PLSA_API_MSG RequestMsg,
         Status = NtCreateToken(&TokenHandle,
                                TOKEN_ALL_ACCESS,
                                &ObjectAttributes,
-                               TokenPrimary,
+                               (RequestMsg->LogonUser.Request.LogonType == Network) ? TokenImpersonation : TokenPrimary,
                                &RequestMsg->LogonUser.Reply.LogonId,
                                &TokenInfo1->ExpirationTime,
                                &TokenInfo1->User,
                                TokenInfo1->Groups,
-                               TokenInfo1->Privileges,
+                               TokenInfo1->Privileges ? TokenInfo1->Privileges
+                                                      : &NoPrivilege,
                                &TokenInfo1->Owner,
                                &TokenInfo1->PrimaryGroup,
                                &TokenInfo1->DefaultDacl,
@@ -1601,9 +1608,25 @@ LsapLogonUser(PLSA_API_MSG RequestMsg,
         goto done;
     }
 
-    TokenHandle = NULL;
+//    TokenHandle = NULL;
+
+    if (LogonType == Interactive ||
+        LogonType == Batch ||
+        LogonType == Service)
+    {
+        UserName = &((PMSV1_0_INTERACTIVE_LOGON)LocalAuthInfo)->UserName;
+        LogonDomainName = &((PMSV1_0_INTERACTIVE_LOGON)LocalAuthInfo)->LogonDomainName;
+    }
+    else
+    {
+        FIXME("LogonType %lu is not supported yet!\n", LogonType);
+    }
 
-    Status = LsapSetLogonSessionData(&RequestMsg->LogonUser.Reply.LogonId);
+    Status = LsapSetLogonSessionData(&RequestMsg->LogonUser.Reply.LogonId,
+                                     LogonType,
+                                     UserName,
+                                     LogonDomainName,
+                                     TokenInfo1->User.User.Sid);
     if (!NT_SUCCESS(Status))
     {
         ERR("LsapSetLogonSessionData failed (Status 0x%08lx)\n", Status);
@@ -1611,11 +1634,11 @@ LsapLogonUser(PLSA_API_MSG RequestMsg,
     }
 
 done:
-    if (!NT_SUCCESS(Status))
-    {
+//    if (!NT_SUCCESS(Status))
+//    {
         if (TokenHandle != NULL)
             NtClose(TokenHandle);
-    }
+//    }
 
     /* Free the local groups */
     if (LocalGroups != NULL)