[LSASRV]
[reactos.git] / reactos / dll / win32 / lsasrv / authpackage.c
index 496b550..884ae5e 100644 (file)
@@ -6,29 +6,43 @@
  * COPYRIGHT:   Copyright 2013 Eric Kohl
  */
 
-/* INCLUDES ****************************************************************/
-
 #include "lsasrv.h"
 
-WINE_DEFAULT_DEBUG_CHANNEL(lsasrv);
-
 typedef enum _LSA_TOKEN_INFORMATION_TYPE
 {
     LsaTokenInformationNull,
     LsaTokenInformationV1
 } LSA_TOKEN_INFORMATION_TYPE, *PLSA_TOKEN_INFORMATION_TYPE;
 
+typedef struct _LSA_TOKEN_INFORMATION_V1
+{
+    LARGE_INTEGER ExpirationTime;
+    TOKEN_USER User;
+    PTOKEN_GROUPS Groups;
+    TOKEN_PRIMARY_GROUP PrimaryGroup;
+    PTOKEN_PRIVILEGES Privileges;
+    TOKEN_OWNER Owner;
+    TOKEN_DEFAULT_DACL DefaultDacl;
+} LSA_TOKEN_INFORMATION_V1, *PLSA_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*);
 typedef NTSTATUS (NTAPI *PLSA_FREE_CLIENT_BUFFER)(PLSA_CLIENT_REQUEST, PVOID);
+typedef NTSTATUS (NTAPI *PLSA_COPY_TO_CLIENT_BUFFER)(PLSA_CLIENT_REQUEST, ULONG,
+ PVOID, PVOID);
+typedef NTSTATUS (NTAPI *PLSA_COPY_FROM_CLIENT_BUFFER)(PLSA_CLIENT_REQUEST,
+ ULONG, PVOID, PVOID);
 
 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;
@@ -36,8 +50,8 @@ typedef struct LSA_DISPATCH_TABLE
     PLSA_FREE_LSA_HEAP FreeLsaHeap;
     PLSA_ALLOCATE_CLIENT_BUFFER AllocateClientBuffer;
     PLSA_FREE_CLIENT_BUFFER FreeClientBuffer;
-    PVOID /*PLSA_COPY_TO_CLIENT_BUFFER */ CopyToClientBuffer;
-    PVOID /*PLSA_COPY_FROM_CLIENT_BUFFER */ CopyFromClientBuffer;
+    PLSA_COPY_TO_CLIENT_BUFFER CopyToClientBuffer;
+    PLSA_COPY_FROM_CLIENT_BUFFER CopyFromClientBuffer;
 } LSA_DISPATCH_TABLE, *PLSA_DISPATCH_TABLE;
 
 
@@ -227,7 +241,7 @@ LsapAddAuthPackage(IN PWSTR ValueName,
     TRACE("Package Name: %s\n", Package->Name->Buffer);
 
     Package->Id = *Id;
-    *Id++;
+    (*Id)++;
 
     InsertTailList(&PackageListHead, &Package->Entry);
 
@@ -308,8 +322,20 @@ LsapAllocateClientBuffer(IN PLSA_CLIENT_REQUEST ClientRequest,
                          IN ULONG LengthRequired,
                          OUT PVOID *ClientBaseAddress)
 {
-    FIXME("() stub\n");
-    return STATUS_NOT_IMPLEMENTED;
+    PLSAP_LOGON_CONTEXT LogonContext;
+    ULONG Length;
+
+    *ClientBaseAddress = NULL;
+
+    LogonContext = (PLSAP_LOGON_CONTEXT)ClientRequest;
+
+    Length = LengthRequired;
+    return NtAllocateVirtualMemory(LogonContext->ClientProcessHandle,
+                                   ClientBaseAddress,
+                                   0,
+                                   &Length,
+                                   MEM_COMMIT,
+                                   PAGE_READWRITE);
 }
 
 
@@ -319,8 +345,59 @@ NTAPI
 LsapFreeClientBuffer(IN PLSA_CLIENT_REQUEST ClientRequest,
                      IN PVOID ClientBaseAddress)
 {
-    FIXME("() stub\n");
-    return STATUS_NOT_IMPLEMENTED;
+    PLSAP_LOGON_CONTEXT LogonContext;
+    ULONG Length;
+
+    if (ClientBaseAddress == NULL)
+        return STATUS_SUCCESS;
+
+    LogonContext = (PLSAP_LOGON_CONTEXT)ClientRequest;
+
+    Length = 0;
+    return NtFreeVirtualMemory(LogonContext->ClientProcessHandle,
+                               &ClientBaseAddress,
+                               &Length,
+                               MEM_RELEASE);
+}
+
+
+static
+NTSTATUS
+NTAPI
+LsapCopyToClientBuffer(IN PLSA_CLIENT_REQUEST ClientRequest,
+                       IN ULONG Length,
+                       IN PVOID ClientBaseAddress,
+                       IN PVOID BufferToCopy)
+{
+    PLSAP_LOGON_CONTEXT LogonContext;
+
+    LogonContext = (PLSAP_LOGON_CONTEXT)ClientRequest;
+
+    return NtWriteVirtualMemory(LogonContext->ClientProcessHandle,
+                                ClientBaseAddress,
+                                BufferToCopy,
+                                Length,
+                                NULL);
+}
+
+
+static
+NTSTATUS
+NTAPI
+LsapCopyFromClientBuffer(IN PLSA_CLIENT_REQUEST ClientRequest,
+                         IN ULONG Length,
+                         IN PVOID BufferToCopy,
+                         IN PVOID ClientBaseAddress)
+{
+    PLSAP_LOGON_CONTEXT LogonContext;
+
+    LogonContext = (PLSAP_LOGON_CONTEXT)ClientRequest;
+
+    return NtReadVirtualMemory(LogonContext->ClientProcessHandle,
+                               ClientBaseAddress,
+                               BufferToCopy,
+                               Length,
+                               NULL);
 }
 
 
@@ -337,8 +414,8 @@ LsapInitAuthPackages(VOID)
     PackageId = 0;
 
     /* Initialize the dispatch table */
-    DispatchTable.CreateLogonSession = NULL;
-    DispatchTable.DeleteLogonSession = NULL;
+    DispatchTable.CreateLogonSession = &LsapCreateLogonSession;
+    DispatchTable.DeleteLogonSession = &LsapDeleteLogonSession;
     DispatchTable.AddCredential = NULL;
     DispatchTable.GetCredentials = NULL;
     DispatchTable.DeleteCredential = NULL;
@@ -346,8 +423,8 @@ LsapInitAuthPackages(VOID)
     DispatchTable.FreeLsaHeap = &LsapFreeHeap;
     DispatchTable.AllocateClientBuffer = &LsapAllocateClientBuffer;
     DispatchTable.FreeClientBuffer = &LsapFreeClientBuffer;
-    DispatchTable.CopyToClientBuffer = NULL;
-    DispatchTable.CopyFromClientBuffer = NULL;
+    DispatchTable.CopyToClientBuffer = &LsapCopyToClientBuffer;
+    DispatchTable.CopyFromClientBuffer = &LsapCopyFromClientBuffer;
 
     /* Add registered authentication packages */
     Status = RtlQueryRegistryValues(RTL_REGISTRY_CONTROL,
@@ -356,8 +433,7 @@ LsapInitAuthPackages(VOID)
                                     &PackageId,
                                     NULL);
 
-
-    return STATUS_SUCCESS;
+    return Status;
 }
 
 
@@ -401,14 +477,15 @@ LsapCallAuthenticationPackage(PLSA_API_MSG RequestMsg,
                               PLSAP_LOGON_CONTEXT LogonContext)
 {
     PAUTH_PACKAGE Package;
+    PVOID LocalBuffer = NULL;
     ULONG PackageId;
-
     NTSTATUS Status;
 
     TRACE("(%p %p)\n", RequestMsg, LogonContext);
 
     PackageId = RequestMsg->CallAuthenticationPackage.Request.AuthenticationPackage;
 
+    /* Get the right authentication package */
     Package = LsapGetAuthenticationPackage(PackageId);
     if (Package == NULL)
     {
@@ -416,9 +493,32 @@ LsapCallAuthenticationPackage(PLSA_API_MSG RequestMsg,
         return STATUS_NO_SUCH_PACKAGE;
     }
 
-    Status = Package->LsaApCallPackage(NULL, /* FIXME: PLSA_CLIENT_REQUEST ClientRequest */
+    if (RequestMsg->CallAuthenticationPackage.Request.SubmitBufferLength > 0)
+    {
+        LocalBuffer = RtlAllocateHeap(RtlGetProcessHeap(),
+                                      HEAP_ZERO_MEMORY,
+                                      RequestMsg->CallAuthenticationPackage.Request.SubmitBufferLength);
+        if (LocalBuffer == NULL)
+        {
+            return STATUS_INSUFFICIENT_RESOURCES;
+        }
+
+        Status = NtReadVirtualMemory(LogonContext->ClientProcessHandle,
+                                     RequestMsg->CallAuthenticationPackage.Request.ProtocolSubmitBuffer,
+                                     LocalBuffer,
+                                     RequestMsg->CallAuthenticationPackage.Request.SubmitBufferLength,
+                                     NULL);
+        if (!NT_SUCCESS(Status))
+        {
+            TRACE("NtReadVirtualMemory() failed (Status 0x%08lx)\n", Status);
+            RtlFreeHeap(RtlGetProcessHeap(), 0, LocalBuffer);
+            return Status;
+        }
+    }
+
+    Status = Package->LsaApCallPackage((PLSA_CLIENT_REQUEST)LogonContext,
+                                       LocalBuffer,
                                        RequestMsg->CallAuthenticationPackage.Request.ProtocolSubmitBuffer,
-                                       NULL, /* FIXME: PVOID ClientBufferBase */
                                        RequestMsg->CallAuthenticationPackage.Request.SubmitBufferLength,
                                        &RequestMsg->CallAuthenticationPackage.Reply.ProtocolReturnBuffer,
                                        &RequestMsg->CallAuthenticationPackage.Reply.ReturnBufferLength,
@@ -428,6 +528,115 @@ LsapCallAuthenticationPackage(PLSA_API_MSG RequestMsg,
         TRACE("Package->LsaApCallPackage() failed (Status 0x%08lx)\n", Status);
     }
 
+    if (LocalBuffer != NULL)
+        RtlFreeHeap(RtlGetProcessHeap(), 0, LocalBuffer);
+
+    return Status;
+}
+
+
+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 Sid;
+    ULONG SidLength;
+    ULONG CopiedSids = 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++)
+    {
+        Status = NtReadVirtualMemory(LogonContext->ClientProcessHandle,
+                                     LocalGroups->Groups[i].Sid,
+                                     SidHeader,
+                                     SidHeaderLength,
+                                     NULL);
+        if (!NT_SUCCESS(Status))
+            goto done;
+
+        SidLength = RtlLengthSid(SidHeader);
+        TRACE("Sid %lu: Length %lu\n", i, SidLength);
+
+        Sid = RtlAllocateHeap(RtlGetProcessHeap(),
+                              HEAP_ZERO_MEMORY,
+                              SidLength);
+        if (SidHeader == NULL)
+        {
+            Status = STATUS_INSUFFICIENT_RESOURCES;
+            goto done;
+        }
+
+        Status = NtReadVirtualMemory(LogonContext->ClientProcessHandle,
+                                     LocalGroups->Groups[i].Sid,
+                                     Sid,
+                                     SidLength,
+                                     NULL);
+        if (!NT_SUCCESS(Status))
+        {
+            RtlFreeHeap(RtlGetProcessHeap(), 0, Sid);
+            goto done;
+        }
+
+        LocalGroups->Groups[i].Sid = Sid;
+        CopiedSids++;
+    }
+
+    *TokenGroups = LocalGroups;
+
+done:
+    if (SidHeader != NULL)
+        RtlFreeHeap(RtlGetProcessHeap(), 0, SidHeader);
+
+    if (!NT_SUCCESS(Status))
+    {
+        if (LocalGroups != NULL)
+        {
+            for (i = 0; i < CopiedSids; i++)
+                RtlFreeHeap(RtlGetProcessHeap(), 0, LocalGroups->Groups[i].Sid);
+
+            RtlFreeHeap(RtlGetProcessHeap(), 0, LocalGroups);
+        }
+    }
+
     return Status;
 }
 
@@ -437,19 +646,26 @@ LsapLogonUser(PLSA_API_MSG RequestMsg,
               PLSAP_LOGON_CONTEXT LogonContext)
 {
     PAUTH_PACKAGE Package;
-    ULONG PackageId;
-    NTSTATUS Status;
-
+    OBJECT_ATTRIBUTES ObjectAttributes;
+    SECURITY_QUALITY_OF_SERVICE Qos;
     LSA_TOKEN_INFORMATION_TYPE TokenInformationType;
     PVOID TokenInformation = NULL;
+    PLSA_TOKEN_INFORMATION_V1 TokenInfo1 = NULL;
     PUNICODE_STRING AccountName = NULL;
     PUNICODE_STRING AuthenticatingAuthority = NULL;
     PUNICODE_STRING MachineName = NULL;
+    PVOID LocalAuthInfo = NULL;
+    PTOKEN_GROUPS LocalGroups = NULL;
+    HANDLE TokenHandle = NULL;
+    ULONG i;
+    ULONG PackageId;
+    NTSTATUS Status;
 
     TRACE("(%p %p)\n", RequestMsg, LogonContext);
 
     PackageId = RequestMsg->LogonUser.Request.AuthenticationPackage;
 
+    /* Get the right authentication package */
     Package = LsapGetAuthenticationPackage(PackageId);
     if (Package == NULL)
     {
@@ -457,12 +673,50 @@ LsapLogonUser(PLSA_API_MSG RequestMsg,
         return STATUS_NO_SUCH_PACKAGE;
     }
 
+    if (RequestMsg->LogonUser.Request.AuthenticationInformationLength > 0)
+    {
+        /* Allocate the local authentication info buffer */
+        LocalAuthInfo = RtlAllocateHeap(RtlGetProcessHeap(),
+                                        HEAP_ZERO_MEMORY,
+                                        RequestMsg->LogonUser.Request.AuthenticationInformationLength);
+        if (LocalAuthInfo == NULL)
+        {
+            TRACE("RtlAllocateHeap() failed\n");
+            return STATUS_INSUFFICIENT_RESOURCES;
+        }
+
+        /* Read the authentication info from the callers adress space */
+        Status = NtReadVirtualMemory(LogonContext->ClientProcessHandle,
+                                     RequestMsg->LogonUser.Request.AuthenticationInformation,
+                                     LocalAuthInfo,
+                                     RequestMsg->LogonUser.Request.AuthenticationInformationLength,
+                                     NULL);
+        if (!NT_SUCCESS(Status))
+        {
+            TRACE("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))
+            goto done;
+
+        TRACE("GroupCount: %lu\n", LocalGroups->GroupCount);
+    }
+
     if (Package->LsaApLogonUserEx2 != NULL)
     {
-        Status = Package->LsaApLogonUserEx2(NULL,  /* FIXME: PLSA_CLIENT_REQUEST ClientRequest */
+        Status = Package->LsaApLogonUserEx2((PLSA_CLIENT_REQUEST)LogonContext,
                                             RequestMsg->LogonUser.Request.LogonType,
+                                            LocalAuthInfo,
                                             RequestMsg->LogonUser.Request.AuthenticationInformation,
-                                            NULL,  /* FIXME: PVOID ClientBufferBase*/
                                             RequestMsg->LogonUser.Request.AuthenticationInformationLength,
                                             &RequestMsg->LogonUser.Reply.ProfileBuffer,
                                             &RequestMsg->LogonUser.Reply.ProfileBufferLength,
@@ -478,10 +732,10 @@ LsapLogonUser(PLSA_API_MSG RequestMsg,
     }
     else if (Package->LsaApLogonUserEx != NULL)
     {
-        Status = Package->LsaApLogonUserEx(NULL,  /* FIXME: PLSA_CLIENT_REQUEST ClientRequest */
+        Status = Package->LsaApLogonUserEx((PLSA_CLIENT_REQUEST)LogonContext,
                                            RequestMsg->LogonUser.Request.LogonType,
+                                           LocalAuthInfo,
                                            RequestMsg->LogonUser.Request.AuthenticationInformation,
-                                           NULL,  /* FIXME: PVOID ClientBufferBase*/
                                            RequestMsg->LogonUser.Request.AuthenticationInformationLength,
                                            &RequestMsg->LogonUser.Reply.ProfileBuffer,
                                            &RequestMsg->LogonUser.Reply.ProfileBufferLength,
@@ -495,10 +749,10 @@ LsapLogonUser(PLSA_API_MSG RequestMsg,
     }
     else
     {
-        Status = Package->LsaApLogonUser(NULL,  /* FIXME: PLSA_CLIENT_REQUEST ClientRequest */
+        Status = Package->LsaApLogonUser((PLSA_CLIENT_REQUEST)LogonContext,
                                          RequestMsg->LogonUser.Request.LogonType,
+                                         LocalAuthInfo,
                                          RequestMsg->LogonUser.Request.AuthenticationInformation,
-                                         NULL,  /* FIXME:  PVOID ClientBufferBase*/
                                          RequestMsg->LogonUser.Request.AuthenticationInformationLength,
                                          &RequestMsg->LogonUser.Reply.ProfileBuffer,
                                          &RequestMsg->LogonUser.Reply.ProfileBufferLength,
@@ -510,27 +764,171 @@ LsapLogonUser(PLSA_API_MSG RequestMsg,
                                          &AuthenticatingAuthority);
     }
 
+    if (!NT_SUCCESS(Status))
+    {
+        TRACE("LsaApLogonUser/Ex/2 failed (Status 0x%08lx)\n", Status);
+        goto done;
+    }
 
-    if (TokenInformation != NULL)
+    if (TokenInformationType == LsaTokenInformationV1)
+    {
+        TokenInfo1 = (PLSA_TOKEN_INFORMATION_V1)TokenInformation;
+
+        Qos.Length = sizeof(SECURITY_QUALITY_OF_SERVICE);
+        Qos.ImpersonationLevel = SecurityImpersonation;
+        Qos.ContextTrackingMode = SECURITY_DYNAMIC_TRACKING;
+        Qos.EffectiveOnly = FALSE;
+
+        ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES);
+        ObjectAttributes.RootDirectory = NULL;
+        ObjectAttributes.ObjectName = NULL;
+        ObjectAttributes.Attributes = 0;
+        ObjectAttributes.SecurityDescriptor = NULL;
+        ObjectAttributes.SecurityQualityOfService = &Qos;
+
+        /* Create the logon token */
+        Status = NtCreateToken(&TokenHandle,
+                               TOKEN_ALL_ACCESS,
+                               &ObjectAttributes,
+                               TokenPrimary,
+                               &RequestMsg->LogonUser.Reply.LogonId,
+                               &TokenInfo1->ExpirationTime,
+                               &TokenInfo1->User,
+                               TokenInfo1->Groups,
+                               TokenInfo1->Privileges,
+                               &TokenInfo1->Owner,
+                               &TokenInfo1->PrimaryGroup,
+                               &TokenInfo1->DefaultDacl,
+                               &RequestMsg->LogonUser.Request.SourceContext);
+        if (!NT_SUCCESS(Status))
+        {
+            TRACE("NtCreateToken failed (Status 0x%08lx)\n", Status);
+            goto done;
+        }
+    }
+    else
     {
+        FIXME("TokenInformationType %d is not supported!\n", TokenInformationType);
+        Status = STATUS_NOT_IMPLEMENTED;
+        goto done;
+    }
 
+    /* Duplicate the token handle into the client process */
+    Status = NtDuplicateObject(NtCurrentProcess(),
+                               TokenHandle,
+                               LogonContext->ClientProcessHandle,
+                               &RequestMsg->LogonUser.Reply.Token,
+                               0,
+                               0,
+                               DUPLICATE_SAME_ACCESS | DUPLICATE_SAME_ATTRIBUTES | DUPLICATE_CLOSE_SOURCE);
+    if (!NT_SUCCESS(Status))
+    {
+        TRACE("NtDuplicateObject failed (Status 0x%08lx)\n", Status);
+        goto done;
     }
 
-    if (AuthenticatingAuthority != NULL)
+    TokenHandle = NULL;
+
+    Status = LsapSetLogonSessionData(&RequestMsg->LogonUser.Reply.LogonId);
+    if (!NT_SUCCESS(Status))
+    {
+        TRACE("LsapSetLogonSessionData failed (Status 0x%08lx)\n", Status);
+        goto done;
+    }
+
+done:
+    if (!NT_SUCCESS(Status))
     {
+        if (TokenHandle != NULL)
+            NtClose(TokenHandle);
+    }
 
+    /* Free the local groups */
+    if (LocalGroups != NULL)
+    {
+        for (i = 0; i < LocalGroups->GroupCount; i++)
+            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)
+        {
+            TokenInfo1 = (PLSA_TOKEN_INFORMATION_V1)TokenInformation;
+
+            if (TokenInfo1 != NULL)
+            {
+                if (TokenInfo1->User.User.Sid != NULL)
+                    LsapFreeHeap(TokenInfo1->User.User.Sid);
+
+                if (TokenInfo1->Groups != NULL)
+                {
+                    for (i = 0; i < TokenInfo1->Groups->GroupCount; i++)
+                    {
+                        if (TokenInfo1->Groups->Groups[i].Sid != NULL)
+                            LsapFreeHeap(TokenInfo1->Groups->Groups[i].Sid);
+                    }
+
+                    LsapFreeHeap(TokenInfo1->Groups);
+                }
+
+                if (TokenInfo1->PrimaryGroup.PrimaryGroup != NULL)
+                    LsapFreeHeap(TokenInfo1->PrimaryGroup.PrimaryGroup);
+
+                if (TokenInfo1->Privileges != NULL)
+                    LsapFreeHeap(TokenInfo1->Privileges);
+
+                if (TokenInfo1->Owner.Owner != NULL)
+                    LsapFreeHeap(TokenInfo1->Owner.Owner);
+
+                if (TokenInfo1->DefaultDacl.DefaultDacl != NULL)
+                    LsapFreeHeap(TokenInfo1->DefaultDacl.DefaultDacl);
+
+                LsapFreeHeap(TokenInfo1);
+            }
+        }
+        else
+        {
+            FIXME("TokenInformationType %d is not supported!\n", TokenInformationType);
+        }
+    }
+
+    /* 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;
 }