xref: /reactos/dll/win32/lsasrv/authpackage.c (revision bee9b2fc)
1 /*
2  * PROJECT:     Local Security Authority Server DLL
3  * LICENSE:     GPL - See COPYING in the top level directory
4  * FILE:        dll/win32/lsasrv/authpackage.c
5  * PURPOSE:     Authentication package management routines
6  * COPYRIGHT:   Copyright 2013 Eric Kohl
7  */
8 
9 #include "lsasrv.h"
10 
11 #include <ndk/sefuncs.h>
12 #include <ndk/umfuncs.h>
13 
14 typedef enum _LSA_TOKEN_INFORMATION_TYPE
15 {
16     LsaTokenInformationNull,
17     LsaTokenInformationV1
18 } LSA_TOKEN_INFORMATION_TYPE, *PLSA_TOKEN_INFORMATION_TYPE;
19 
20 typedef struct _LSA_TOKEN_INFORMATION_NULL
21 {
22     LARGE_INTEGER ExpirationTime;
23     PTOKEN_GROUPS Groups;
24 } LSA_TOKEN_INFORMATION_NULL, *PLSA_TOKEN_INFORMATION_NULL;
25 
26 typedef struct _LSA_TOKEN_INFORMATION_V1
27 {
28     LARGE_INTEGER ExpirationTime;
29     TOKEN_USER User;
30     PTOKEN_GROUPS Groups;
31     TOKEN_PRIMARY_GROUP PrimaryGroup;
32     PTOKEN_PRIVILEGES Privileges;
33     TOKEN_OWNER Owner;
34     TOKEN_DEFAULT_DACL DefaultDacl;
35 } LSA_TOKEN_INFORMATION_V1, *PLSA_TOKEN_INFORMATION_V1;
36 
37 typedef PVOID PLSA_CLIENT_REQUEST;
38 
39 typedef NTSTATUS (NTAPI *PLSA_CREATE_LOGON_SESSION)(PLUID);
40 typedef NTSTATUS (NTAPI *PLSA_DELETE_LOGON_SESSION)(PLUID);
41 typedef NTSTATUS (NTAPI *PLSA_ADD_CREDENTIAL)(PLUID, ULONG, PLSA_STRING, PLSA_STRING);
42 typedef NTSTATUS (NTAPI *PLSA_GET_CREDENTIALS)(PLUID, ULONG, PULONG, BOOLEAN, PLSA_STRING, PULONG, PLSA_STRING);
43 typedef NTSTATUS (NTAPI *PLSA_DELETE_CREDENTIAL)(PLUID, ULONG, PLSA_STRING);
44 typedef PVOID (NTAPI *PLSA_ALLOCATE_LSA_HEAP)(ULONG);
45 typedef VOID (NTAPI *PLSA_FREE_LSA_HEAP)(PVOID);
46 typedef NTSTATUS (NTAPI *PLSA_ALLOCATE_CLIENT_BUFFER)(PLSA_CLIENT_REQUEST, ULONG, PVOID*);
47 typedef NTSTATUS (NTAPI *PLSA_FREE_CLIENT_BUFFER)(PLSA_CLIENT_REQUEST, PVOID);
48 typedef NTSTATUS (NTAPI *PLSA_COPY_TO_CLIENT_BUFFER)(PLSA_CLIENT_REQUEST, ULONG,
49  PVOID, PVOID);
50 typedef NTSTATUS (NTAPI *PLSA_COPY_FROM_CLIENT_BUFFER)(PLSA_CLIENT_REQUEST,
51  ULONG, PVOID, PVOID);
52 
53 typedef struct LSA_DISPATCH_TABLE
54 {
55     PLSA_CREATE_LOGON_SESSION CreateLogonSession;
56     PLSA_DELETE_LOGON_SESSION DeleteLogonSession;
57     PLSA_ADD_CREDENTIAL AddCredential;
58     PLSA_GET_CREDENTIALS GetCredentials;
59     PLSA_DELETE_CREDENTIAL DeleteCredential;
60     PLSA_ALLOCATE_LSA_HEAP AllocateLsaHeap;
61     PLSA_FREE_LSA_HEAP FreeLsaHeap;
62     PLSA_ALLOCATE_CLIENT_BUFFER AllocateClientBuffer;
63     PLSA_FREE_CLIENT_BUFFER FreeClientBuffer;
64     PLSA_COPY_TO_CLIENT_BUFFER CopyToClientBuffer;
65     PLSA_COPY_FROM_CLIENT_BUFFER CopyFromClientBuffer;
66 } LSA_DISPATCH_TABLE, *PLSA_DISPATCH_TABLE;
67 
68 
69 typedef NTSTATUS (NTAPI *PLSA_AP_INITIALIZE_PACKAGE)(ULONG, PLSA_DISPATCH_TABLE,
70  PLSA_STRING, PLSA_STRING, PLSA_STRING *);
71 typedef NTSTATUS (NTAPI *PLSA_AP_CALL_PACKAGE_INTERNAL)(PLSA_CLIENT_REQUEST, PVOID, PVOID,
72  ULONG, PVOID *, PULONG, PNTSTATUS);
73 typedef NTSTATUS (NTAPI *PLSA_AP_CALL_PACKAGE_PASSTHROUGH)(PLSA_CLIENT_REQUEST,
74  PVOID, PVOID, ULONG, PVOID *, PULONG, PNTSTATUS);
75 typedef NTSTATUS (NTAPI *PLSA_AP_CALL_PACKAGE_UNTRUSTED)(PLSA_CLIENT_REQUEST,
76  PVOID, PVOID, ULONG, PVOID *, PULONG, PNTSTATUS);
77 typedef VOID (NTAPI *PLSA_AP_LOGON_TERMINATED)(PLUID);
78 typedef NTSTATUS (NTAPI *PLSA_AP_LOGON_USER_EX2)(PLSA_CLIENT_REQUEST,
79  SECURITY_LOGON_TYPE, PVOID, PVOID, ULONG, PVOID *, PULONG, PLUID, PNTSTATUS,
80  PLSA_TOKEN_INFORMATION_TYPE, PVOID *, PUNICODE_STRING *, PUNICODE_STRING *,
81  PUNICODE_STRING *, PVOID /*PSECPKG_PRIMARY_CRED*/, PVOID /*PSECPKG_SUPPLEMENTAL_CRED_ARRAY **/);
82 typedef NTSTATUS (NTAPI *PLSA_AP_LOGON_USER_EX)(PLSA_CLIENT_REQUEST,
83  SECURITY_LOGON_TYPE, PVOID, PVOID, ULONG, PVOID *, PULONG, PLUID, PNTSTATUS,
84  PLSA_TOKEN_INFORMATION_TYPE, PVOID *, PUNICODE_STRING *, PUNICODE_STRING *,
85  PUNICODE_STRING *);
86 
87 typedef NTSTATUS (NTAPI *PLSA_AP_LOGON_USER_INTERNAL)(PLSA_CLIENT_REQUEST, SECURITY_LOGON_TYPE,
88  PVOID, PVOID, ULONG, PVOID *, PULONG, PLUID, PNTSTATUS, PLSA_TOKEN_INFORMATION_TYPE,
89  PVOID *, PUNICODE_STRING *, PUNICODE_STRING *);
90 
91 typedef struct _AUTH_PACKAGE
92 {
93     LIST_ENTRY Entry;
94     PSTRING Name;
95     ULONG Id;
96     PVOID ModuleHandle;
97 
98     PLSA_AP_INITIALIZE_PACKAGE LsaApInitializePackage;
99     PLSA_AP_CALL_PACKAGE_INTERNAL LsaApCallPackage;
100     PLSA_AP_CALL_PACKAGE_PASSTHROUGH LsaApCallPackagePassthrough;
101     PLSA_AP_CALL_PACKAGE_UNTRUSTED LsaApCallPackageUntrusted;
102     PLSA_AP_LOGON_TERMINATED LsaApLogonTerminated;
103     PLSA_AP_LOGON_USER_EX2 LsaApLogonUserEx2;
104     PLSA_AP_LOGON_USER_EX LsaApLogonUserEx;
105     PLSA_AP_LOGON_USER_INTERNAL LsaApLogonUser;
106 } AUTH_PACKAGE, *PAUTH_PACKAGE;
107 
108 VOID
109 NTAPI
110 LsaIFree_LSAPR_PRIVILEGE_SET(IN PLSAPR_PRIVILEGE_SET Ptr);
111 
112 typedef wchar_t *PSAMPR_SERVER_NAME;
113 typedef void *SAMPR_HANDLE;
114 
115 typedef struct _SAMPR_SID_INFORMATION
116 {
117     PRPC_SID SidPointer;
118 } SAMPR_SID_INFORMATION, *PSAMPR_SID_INFORMATION;
119 
120 typedef struct _SAMPR_PSID_ARRAY
121 {
122     unsigned long Count;
123     PSAMPR_SID_INFORMATION Sids;
124 } SAMPR_PSID_ARRAY, *PSAMPR_PSID_ARRAY;
125 
126 NTSTATUS
127 NTAPI
128 SamIConnect(
129     PSAMPR_SERVER_NAME ServerName,
130     SAMPR_HANDLE *ServerHandle,
131     ACCESS_MASK DesiredAccess,
132     BOOLEAN Trusted);
133 
134 VOID
135 NTAPI
136 SamIFree_SAMPR_ULONG_ARRAY(
137     PSAMPR_ULONG_ARRAY Ptr);
138 
139 NTSTATUS
140 __stdcall
141 SamrCloseHandle(
142     SAMPR_HANDLE *SamHandle);
143 
144 NTSTATUS
145 __stdcall
146 SamrOpenDomain(
147     SAMPR_HANDLE ServerHandle,
148     ACCESS_MASK DesiredAccess,
149     PRPC_SID DomainId,
150     SAMPR_HANDLE *DomainHandle);
151 
152 NTSTATUS
153 __stdcall
154 SamrGetAliasMembership(
155     SAMPR_HANDLE DomainHandle,
156     PSAMPR_PSID_ARRAY SidArray,
157     PSAMPR_ULONG_ARRAY Membership);
158 
159 
160 /* GLOBALS *****************************************************************/
161 
162 static LIST_ENTRY PackageListHead;
163 static ULONG PackageId;
164 static LSA_DISPATCH_TABLE DispatchTable;
165 
166 #define CONST_LUID(x1, x2) {x1, x2}
167 static const LUID SeChangeNotifyPrivilege = CONST_LUID(SE_CHANGE_NOTIFY_PRIVILEGE, 0);
168 static const LUID SeCreateGlobalPrivilege = CONST_LUID(SE_CREATE_GLOBAL_PRIVILEGE, 0);
169 static const LUID SeImpersonatePrivilege = CONST_LUID(SE_IMPERSONATE_PRIVILEGE, 0);
170 
171 
172 /* FUNCTIONS ***************************************************************/
173 
174 static
175 NTSTATUS
176 NTAPI
LsapAddAuthPackage(IN PWSTR ValueName,IN ULONG ValueType,IN PVOID ValueData,IN ULONG ValueLength,IN PVOID Context,IN PVOID EntryContext)177 LsapAddAuthPackage(IN PWSTR ValueName,
178                    IN ULONG ValueType,
179                    IN PVOID ValueData,
180                    IN ULONG ValueLength,
181                    IN PVOID Context,
182                    IN PVOID EntryContext)
183 {
184     PAUTH_PACKAGE Package = NULL;
185     UNICODE_STRING PackageName;
186     STRING ProcName;
187     PULONG Id;
188     NTSTATUS Status = STATUS_SUCCESS;
189 
190     TRACE("LsapAddAuthPackage()\n");
191 
192     PackageName.Length = (USHORT)ValueLength - sizeof(WCHAR);
193     PackageName.MaximumLength = (USHORT)ValueLength;
194     PackageName.Buffer = ValueData;
195 
196     Id = (PULONG)Context;
197 
198     Package = RtlAllocateHeap(RtlGetProcessHeap(),
199                                   HEAP_ZERO_MEMORY,
200                                   sizeof(AUTH_PACKAGE));
201     if (Package == NULL)
202         return STATUS_INSUFFICIENT_RESOURCES;
203 
204     Status = LdrLoadDll(NULL,
205                         NULL,
206                         &PackageName,
207                         &Package->ModuleHandle);
208     if (!NT_SUCCESS(Status))
209     {
210         TRACE("LdrLoadDll failed (Status 0x%08lx)\n", Status);
211         goto done;
212     }
213 
214     RtlInitAnsiString(&ProcName, "LsaApInitializePackage");
215     Status = LdrGetProcedureAddress(Package->ModuleHandle,
216                                     &ProcName,
217                                     0,
218                                     (PVOID *)&Package->LsaApInitializePackage);
219     if (!NT_SUCCESS(Status))
220     {
221         TRACE("LdrGetProcedureAddress() failed (Status 0x%08lx)\n", Status);
222         goto done;
223     }
224 
225     RtlInitAnsiString(&ProcName, "LsaApCallPackage");
226     Status = LdrGetProcedureAddress(Package->ModuleHandle,
227                                     &ProcName,
228                                     0,
229                                     (PVOID *)&Package->LsaApCallPackage);
230     if (!NT_SUCCESS(Status))
231     {
232         TRACE("LdrGetProcedureAddress() failed (Status 0x%08lx)\n", Status);
233         goto done;
234     }
235 
236     RtlInitAnsiString(&ProcName, "LsaApCallPackagePassthrough");
237     Status = LdrGetProcedureAddress(Package->ModuleHandle,
238                                     &ProcName,
239                                     0,
240                                     (PVOID *)&Package->LsaApCallPackagePassthrough);
241     if (!NT_SUCCESS(Status))
242     {
243         TRACE("LdrGetProcedureAddress() failed (Status 0x%08lx)\n", Status);
244         goto done;
245     }
246 
247     RtlInitAnsiString(&ProcName, "LsaApCallPackageUntrusted");
248     Status = LdrGetProcedureAddress(Package->ModuleHandle,
249                                     &ProcName,
250                                     0,
251                                     (PVOID *)&Package->LsaApCallPackageUntrusted);
252     if (!NT_SUCCESS(Status))
253     {
254         TRACE("LdrGetProcedureAddress() failed (Status 0x%08lx)\n", Status);
255         goto done;
256     }
257 
258     RtlInitAnsiString(&ProcName, "LsaApLogonTerminated");
259     Status = LdrGetProcedureAddress(Package->ModuleHandle,
260                                     &ProcName,
261                                     0,
262                                     (PVOID *)&Package->LsaApLogonTerminated);
263     if (!NT_SUCCESS(Status))
264     {
265         TRACE("LdrGetProcedureAddress() failed (Status 0x%08lx)\n", Status);
266         goto done;
267     }
268 
269     RtlInitAnsiString(&ProcName, "LsaApLogonUserEx2");
270     Status = LdrGetProcedureAddress(Package->ModuleHandle,
271                                     &ProcName,
272                                     0,
273                                     (PVOID *)&Package->LsaApLogonUserEx2);
274     if (!NT_SUCCESS(Status))
275     {
276         RtlInitAnsiString(&ProcName, "LsaApLogonUserEx");
277         Status = LdrGetProcedureAddress(Package->ModuleHandle,
278                                         &ProcName,
279                                         0,
280                                         (PVOID *)&Package->LsaApLogonUserEx);
281         if (!NT_SUCCESS(Status))
282         {
283             RtlInitAnsiString(&ProcName, "LsaApLogonUser");
284             Status = LdrGetProcedureAddress(Package->ModuleHandle,
285                                             &ProcName,
286                                             0,
287                                             (PVOID *)&Package->LsaApLogonUser);
288             if (!NT_SUCCESS(Status))
289             {
290                 TRACE("LdrGetProcedureAddress() failed (Status 0x%08lx)\n", Status);
291                 goto done;
292             }
293         }
294     }
295 
296     /* Initialize the current package */
297     Status = Package->LsaApInitializePackage(*Id,
298                                              &DispatchTable,
299                                              NULL,
300                                              NULL,
301                                              &Package->Name);
302     if (!NT_SUCCESS(Status))
303     {
304         TRACE("Package->LsaApInitializePackage() failed (Status 0x%08lx)\n", Status);
305         goto done;
306     }
307 
308     TRACE("Package Name: %s\n", Package->Name->Buffer);
309 
310     Package->Id = *Id;
311     (*Id)++;
312 
313     InsertTailList(&PackageListHead, &Package->Entry);
314 
315 done:
316     if (!NT_SUCCESS(Status))
317     {
318         if (Package != NULL)
319         {
320             if (Package->ModuleHandle != NULL)
321                 LdrUnloadDll(Package->ModuleHandle);
322 
323             if (Package->Name != NULL)
324             {
325                 if (Package->Name->Buffer != NULL)
326                     RtlFreeHeap(RtlGetProcessHeap(), 0, Package->Name->Buffer);
327 
328                 RtlFreeHeap(RtlGetProcessHeap(), 0, Package->Name);
329             }
330 
331             RtlFreeHeap(RtlGetProcessHeap(), 0, Package);
332         }
333     }
334 
335     return Status;
336 }
337 
338 
339 static
340 PAUTH_PACKAGE
LsapGetAuthenticationPackage(IN ULONG PackageId)341 LsapGetAuthenticationPackage(IN ULONG PackageId)
342 {
343     PLIST_ENTRY ListEntry;
344     PAUTH_PACKAGE Package;
345 
346     ListEntry = PackageListHead.Flink;
347     while (ListEntry != &PackageListHead)
348     {
349         Package = CONTAINING_RECORD(ListEntry, AUTH_PACKAGE, Entry);
350 
351         if (Package->Id == PackageId)
352         {
353             return Package;
354         }
355 
356         ListEntry = ListEntry->Flink;
357     }
358 
359     return NULL;
360 }
361 
362 
363 PVOID
364 NTAPI
LsapAllocateHeap(IN ULONG Length)365 LsapAllocateHeap(IN ULONG Length)
366 {
367     return RtlAllocateHeap(RtlGetProcessHeap(), 0, Length);
368 }
369 
370 
371 PVOID
372 NTAPI
LsapAllocateHeapZero(IN ULONG Length)373 LsapAllocateHeapZero(IN ULONG Length)
374 {
375     return RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, Length);
376 }
377 
378 
379 VOID
380 NTAPI
LsapFreeHeap(IN PVOID Base)381 LsapFreeHeap(IN PVOID Base)
382 {
383     RtlFreeHeap(RtlGetProcessHeap(), 0, Base);
384 }
385 
386 
387 static
388 NTSTATUS
389 NTAPI
LsapAllocateClientBuffer(IN PLSA_CLIENT_REQUEST ClientRequest,IN ULONG LengthRequired,OUT PVOID * ClientBaseAddress)390 LsapAllocateClientBuffer(IN PLSA_CLIENT_REQUEST ClientRequest,
391                          IN ULONG LengthRequired,
392                          OUT PVOID *ClientBaseAddress)
393 {
394     PLSAP_LOGON_CONTEXT LogonContext;
395     SIZE_T Length;
396 
397     *ClientBaseAddress = NULL;
398 
399     LogonContext = (PLSAP_LOGON_CONTEXT)ClientRequest;
400 
401     Length = LengthRequired;
402     return NtAllocateVirtualMemory(LogonContext->ClientProcessHandle,
403                                    ClientBaseAddress,
404                                    0,
405                                    &Length,
406                                    MEM_COMMIT,
407                                    PAGE_READWRITE);
408 }
409 
410 
411 static
412 NTSTATUS
413 NTAPI
LsapFreeClientBuffer(IN PLSA_CLIENT_REQUEST ClientRequest,IN PVOID ClientBaseAddress)414 LsapFreeClientBuffer(IN PLSA_CLIENT_REQUEST ClientRequest,
415                      IN PVOID ClientBaseAddress)
416 {
417     PLSAP_LOGON_CONTEXT LogonContext;
418     SIZE_T Length;
419 
420     if (ClientBaseAddress == NULL)
421         return STATUS_SUCCESS;
422 
423     LogonContext = (PLSAP_LOGON_CONTEXT)ClientRequest;
424 
425     Length = 0;
426     return NtFreeVirtualMemory(LogonContext->ClientProcessHandle,
427                                &ClientBaseAddress,
428                                &Length,
429                                MEM_RELEASE);
430 }
431 
432 
433 static
434 NTSTATUS
435 NTAPI
LsapCopyToClientBuffer(IN PLSA_CLIENT_REQUEST ClientRequest,IN ULONG Length,IN PVOID ClientBaseAddress,IN PVOID BufferToCopy)436 LsapCopyToClientBuffer(IN PLSA_CLIENT_REQUEST ClientRequest,
437                        IN ULONG Length,
438                        IN PVOID ClientBaseAddress,
439                        IN PVOID BufferToCopy)
440 {
441     PLSAP_LOGON_CONTEXT LogonContext;
442 
443     LogonContext = (PLSAP_LOGON_CONTEXT)ClientRequest;
444 
445     return NtWriteVirtualMemory(LogonContext->ClientProcessHandle,
446                                 ClientBaseAddress,
447                                 BufferToCopy,
448                                 Length,
449                                 NULL);
450 }
451 
452 
453 static
454 NTSTATUS
455 NTAPI
LsapCopyFromClientBuffer(IN PLSA_CLIENT_REQUEST ClientRequest,IN ULONG Length,IN PVOID BufferToCopy,IN PVOID ClientBaseAddress)456 LsapCopyFromClientBuffer(IN PLSA_CLIENT_REQUEST ClientRequest,
457                          IN ULONG Length,
458                          IN PVOID BufferToCopy,
459                          IN PVOID ClientBaseAddress)
460 {
461     PLSAP_LOGON_CONTEXT LogonContext;
462 
463     LogonContext = (PLSAP_LOGON_CONTEXT)ClientRequest;
464 
465     return NtReadVirtualMemory(LogonContext->ClientProcessHandle,
466                                ClientBaseAddress,
467                                BufferToCopy,
468                                Length,
469                                NULL);
470 }
471 
472 
473 NTSTATUS
LsapInitAuthPackages(VOID)474 LsapInitAuthPackages(VOID)
475 {
476     RTL_QUERY_REGISTRY_TABLE AuthPackageTable[] = {
477     {LsapAddAuthPackage, 0, L"Authentication Packages", NULL, REG_NONE, NULL, 0},
478     {NULL, 0, NULL, NULL, REG_NONE, NULL, 0}};
479 
480     NTSTATUS Status;
481 
482     InitializeListHead(&PackageListHead);
483     PackageId = 0;
484 
485     /* Initialize the dispatch table */
486     DispatchTable.CreateLogonSession = &LsapCreateLogonSession;
487     DispatchTable.DeleteLogonSession = &LsapDeleteLogonSession;
488     DispatchTable.AddCredential = &LsapAddCredential;
489     DispatchTable.GetCredentials = &LsapGetCredentials;
490     DispatchTable.DeleteCredential = &LsapDeleteCredential;
491     DispatchTable.AllocateLsaHeap = &LsapAllocateHeapZero;
492     DispatchTable.FreeLsaHeap = &LsapFreeHeap;
493     DispatchTable.AllocateClientBuffer = &LsapAllocateClientBuffer;
494     DispatchTable.FreeClientBuffer = &LsapFreeClientBuffer;
495     DispatchTable.CopyToClientBuffer = &LsapCopyToClientBuffer;
496     DispatchTable.CopyFromClientBuffer = &LsapCopyFromClientBuffer;
497 
498     /* Add registered authentication packages */
499     Status = RtlQueryRegistryValues(RTL_REGISTRY_CONTROL,
500                                     L"Lsa",
501                                     AuthPackageTable,
502                                     &PackageId,
503                                     NULL);
504 
505     return Status;
506 }
507 
508 
509 NTSTATUS
LsapLookupAuthenticationPackage(PLSA_API_MSG RequestMsg,PLSAP_LOGON_CONTEXT LogonContext)510 LsapLookupAuthenticationPackage(PLSA_API_MSG RequestMsg,
511                                 PLSAP_LOGON_CONTEXT LogonContext)
512 {
513     PLIST_ENTRY ListEntry;
514     PAUTH_PACKAGE Package;
515     ULONG PackageNameLength;
516     PCHAR PackageName;
517 
518     TRACE("(%p %p)\n", RequestMsg, LogonContext);
519 
520     PackageNameLength = RequestMsg->LookupAuthenticationPackage.Request.PackageNameLength;
521     PackageName = RequestMsg->LookupAuthenticationPackage.Request.PackageName;
522 
523     TRACE("PackageName: %s\n", PackageName);
524 
525     ListEntry = PackageListHead.Flink;
526     while (ListEntry != &PackageListHead)
527     {
528         Package = CONTAINING_RECORD(ListEntry, AUTH_PACKAGE, Entry);
529 
530         if ((PackageNameLength == Package->Name->Length) &&
531             (_strnicmp(PackageName, Package->Name->Buffer, Package->Name->Length) == 0))
532         {
533             RequestMsg->LookupAuthenticationPackage.Reply.Package = Package->Id;
534             return STATUS_SUCCESS;
535         }
536 
537         ListEntry = ListEntry->Flink;
538     }
539 
540     return STATUS_NO_SUCH_PACKAGE;
541 }
542 
543 
544 VOID
LsapTerminateLogon(_In_ PLUID LogonId)545 LsapTerminateLogon(
546     _In_ PLUID LogonId)
547 {
548     PLIST_ENTRY ListEntry;
549     PAUTH_PACKAGE Package;
550 
551     ListEntry = PackageListHead.Flink;
552     while (ListEntry != &PackageListHead)
553     {
554         Package = CONTAINING_RECORD(ListEntry, AUTH_PACKAGE, Entry);
555 
556         Package->LsaApLogonTerminated(LogonId);
557 
558         ListEntry = ListEntry->Flink;
559     }
560 }
561 
562 
563 NTSTATUS
LsapCallAuthenticationPackage(PLSA_API_MSG RequestMsg,PLSAP_LOGON_CONTEXT LogonContext)564 LsapCallAuthenticationPackage(PLSA_API_MSG RequestMsg,
565                               PLSAP_LOGON_CONTEXT LogonContext)
566 {
567     PAUTH_PACKAGE Package;
568     PVOID LocalBuffer = NULL;
569     ULONG PackageId;
570     NTSTATUS Status;
571 
572     TRACE("(%p %p)\n", RequestMsg, LogonContext);
573 
574     PackageId = RequestMsg->CallAuthenticationPackage.Request.AuthenticationPackage;
575 
576     /* Get the right authentication package */
577     Package = LsapGetAuthenticationPackage(PackageId);
578     if (Package == NULL)
579     {
580         TRACE("LsapGetAuthenticationPackage() failed to find a package\n");
581         return STATUS_NO_SUCH_PACKAGE;
582     }
583 
584     if (RequestMsg->CallAuthenticationPackage.Request.SubmitBufferLength > 0)
585     {
586         LocalBuffer = RtlAllocateHeap(RtlGetProcessHeap(),
587                                       HEAP_ZERO_MEMORY,
588                                       RequestMsg->CallAuthenticationPackage.Request.SubmitBufferLength);
589         if (LocalBuffer == NULL)
590         {
591             return STATUS_INSUFFICIENT_RESOURCES;
592         }
593 
594         Status = NtReadVirtualMemory(LogonContext->ClientProcessHandle,
595                                      RequestMsg->CallAuthenticationPackage.Request.ProtocolSubmitBuffer,
596                                      LocalBuffer,
597                                      RequestMsg->CallAuthenticationPackage.Request.SubmitBufferLength,
598                                      NULL);
599         if (!NT_SUCCESS(Status))
600         {
601             TRACE("NtReadVirtualMemory() failed (Status 0x%08lx)\n", Status);
602             RtlFreeHeap(RtlGetProcessHeap(), 0, LocalBuffer);
603             return Status;
604         }
605     }
606 
607     if (LogonContext->TrustedCaller)
608         Status = Package->LsaApCallPackage((PLSA_CLIENT_REQUEST)LogonContext,
609                                            LocalBuffer,
610                                            RequestMsg->CallAuthenticationPackage.Request.ProtocolSubmitBuffer,
611                                            RequestMsg->CallAuthenticationPackage.Request.SubmitBufferLength,
612                                            &RequestMsg->CallAuthenticationPackage.Reply.ProtocolReturnBuffer,
613                                            &RequestMsg->CallAuthenticationPackage.Reply.ReturnBufferLength,
614                                            &RequestMsg->CallAuthenticationPackage.Reply.ProtocolStatus);
615     else
616         Status = Package->LsaApCallPackageUntrusted((PLSA_CLIENT_REQUEST)LogonContext,
617                                                     LocalBuffer,
618                                                     RequestMsg->CallAuthenticationPackage.Request.ProtocolSubmitBuffer,
619                                                     RequestMsg->CallAuthenticationPackage.Request.SubmitBufferLength,
620                                                     &RequestMsg->CallAuthenticationPackage.Reply.ProtocolReturnBuffer,
621                                                     &RequestMsg->CallAuthenticationPackage.Reply.ReturnBufferLength,
622                                                     &RequestMsg->CallAuthenticationPackage.Reply.ProtocolStatus);
623     if (!NT_SUCCESS(Status))
624     {
625         TRACE("Package->LsaApCallPackage() failed (Status 0x%08lx)\n", Status);
626     }
627 
628     if (LocalBuffer != NULL)
629         RtlFreeHeap(RtlGetProcessHeap(), 0, LocalBuffer);
630 
631     return Status;
632 }
633 
634 
635 static
636 NTSTATUS
LsapCopyLocalGroups(IN PLSAP_LOGON_CONTEXT LogonContext,IN PTOKEN_GROUPS ClientGroups,IN ULONG ClientGroupsCount,OUT PTOKEN_GROUPS * TokenGroups)637 LsapCopyLocalGroups(
638     IN PLSAP_LOGON_CONTEXT LogonContext,
639     IN PTOKEN_GROUPS ClientGroups,
640     IN ULONG ClientGroupsCount,
641     OUT PTOKEN_GROUPS *TokenGroups)
642 {
643     ULONG LocalGroupsLength = 0;
644     PTOKEN_GROUPS LocalGroups = NULL;
645     ULONG SidHeaderLength = 0;
646     PSID SidHeader = NULL;
647     PSID SrcSid, DstSid;
648     ULONG SidLength;
649     ULONG AllocatedSids = 0;
650     ULONG i;
651     NTSTATUS Status;
652 
653     LocalGroupsLength = sizeof(TOKEN_GROUPS) +
654                         (ClientGroupsCount - ANYSIZE_ARRAY) * sizeof(SID_AND_ATTRIBUTES);
655     LocalGroups = RtlAllocateHeap(RtlGetProcessHeap(),
656                                   HEAP_ZERO_MEMORY,
657                                   LocalGroupsLength);
658     if (LocalGroups == NULL)
659     {
660         TRACE("RtlAllocateHeap() failed\n");
661         return STATUS_INSUFFICIENT_RESOURCES;
662     }
663 
664     Status = NtReadVirtualMemory(LogonContext->ClientProcessHandle,
665                                  ClientGroups,
666                                  LocalGroups,
667                                  LocalGroupsLength,
668                                  NULL);
669     if (!NT_SUCCESS(Status))
670         goto done;
671 
672 
673     SidHeaderLength  = RtlLengthRequiredSid(0);
674     SidHeader = RtlAllocateHeap(RtlGetProcessHeap(),
675                                 HEAP_ZERO_MEMORY,
676                                 SidHeaderLength);
677     if (SidHeader == NULL)
678     {
679         Status = STATUS_INSUFFICIENT_RESOURCES;
680         goto done;
681     }
682 
683     for (i = 0; i < ClientGroupsCount; i++)
684     {
685         SrcSid = LocalGroups->Groups[i].Sid;
686 
687         Status = NtReadVirtualMemory(LogonContext->ClientProcessHandle,
688                                      SrcSid,
689                                      SidHeader,
690                                      SidHeaderLength,
691                                      NULL);
692         if (!NT_SUCCESS(Status))
693             goto done;
694 
695         SidLength = RtlLengthSid(SidHeader);
696         TRACE("Sid %lu: Length %lu\n", i, SidLength);
697 
698         DstSid = RtlAllocateHeap(RtlGetProcessHeap(),
699                                  HEAP_ZERO_MEMORY,
700                                  SidLength);
701         if (DstSid == NULL)
702         {
703             Status = STATUS_INSUFFICIENT_RESOURCES;
704             goto done;
705         }
706 
707         Status = NtReadVirtualMemory(LogonContext->ClientProcessHandle,
708                                      SrcSid,
709                                      DstSid,
710                                      SidLength,
711                                      NULL);
712         if (!NT_SUCCESS(Status))
713         {
714             RtlFreeHeap(RtlGetProcessHeap(), 0, DstSid);
715             goto done;
716         }
717 
718         LocalGroups->Groups[i].Sid = DstSid;
719         AllocatedSids++;
720     }
721 
722     *TokenGroups = LocalGroups;
723 
724 done:
725     if (SidHeader != NULL)
726         RtlFreeHeap(RtlGetProcessHeap(), 0, SidHeader);
727 
728     if (!NT_SUCCESS(Status))
729     {
730         if (LocalGroups != NULL)
731         {
732             for (i = 0; i < AllocatedSids; i++)
733                 RtlFreeHeap(RtlGetProcessHeap(), 0, LocalGroups->Groups[i].Sid);
734 
735             RtlFreeHeap(RtlGetProcessHeap(), 0, LocalGroups);
736         }
737     }
738 
739     return Status;
740 }
741 
742 
743 static
744 NTSTATUS
LsapAddLocalGroups(IN PVOID TokenInformation,IN LSA_TOKEN_INFORMATION_TYPE TokenInformationType,IN PTOKEN_GROUPS LocalGroups)745 LsapAddLocalGroups(
746     IN PVOID TokenInformation,
747     IN LSA_TOKEN_INFORMATION_TYPE TokenInformationType,
748     IN PTOKEN_GROUPS LocalGroups)
749 {
750     PLSA_TOKEN_INFORMATION_V1 TokenInfo1;
751     PTOKEN_GROUPS Groups;
752     ULONG Length;
753     ULONG i;
754     ULONG j;
755 
756     if (LocalGroups == NULL || LocalGroups->GroupCount == 0)
757         return STATUS_SUCCESS;
758 
759     if (TokenInformationType == LsaTokenInformationV1)
760     {
761         TokenInfo1 = (PLSA_TOKEN_INFORMATION_V1)TokenInformation;
762 
763         if (TokenInfo1->Groups != NULL)
764         {
765             Length = sizeof(TOKEN_GROUPS) +
766                      (LocalGroups->GroupCount + TokenInfo1->Groups->GroupCount - ANYSIZE_ARRAY) * sizeof(SID_AND_ATTRIBUTES);
767 
768             Groups = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, Length);
769             if (Groups == NULL)
770             {
771                 ERR("Group buffer allocation failed!\n");
772                 return STATUS_INSUFFICIENT_RESOURCES;
773             }
774 
775             Groups->GroupCount = LocalGroups->GroupCount + TokenInfo1->Groups->GroupCount;
776 
777             for (i = 0; i < TokenInfo1->Groups->GroupCount; i++)
778             {
779                 Groups->Groups[i].Sid = TokenInfo1->Groups->Groups[i].Sid;
780                 Groups->Groups[i].Attributes = TokenInfo1->Groups->Groups[i].Attributes;
781             }
782 
783             for (j = 0; j < LocalGroups->GroupCount; i++, j++)
784             {
785                 Groups->Groups[i].Sid = LocalGroups->Groups[j].Sid;
786                 Groups->Groups[i].Attributes = LocalGroups->Groups[j].Attributes;
787                 LocalGroups->Groups[j].Sid = NULL;
788             }
789 
790             RtlFreeHeap(RtlGetProcessHeap(), 0, TokenInfo1->Groups);
791 
792             TokenInfo1->Groups = Groups;
793         }
794         else
795         {
796             Length = sizeof(TOKEN_GROUPS) +
797                      (LocalGroups->GroupCount - ANYSIZE_ARRAY) * sizeof(SID_AND_ATTRIBUTES);
798 
799             Groups = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, Length);
800             if (Groups == NULL)
801             {
802                 ERR("Group buffer allocation failed!\n");
803                 return STATUS_INSUFFICIENT_RESOURCES;
804             }
805 
806             Groups->GroupCount = LocalGroups->GroupCount;
807 
808             for (i = 0; i < LocalGroups->GroupCount; i++)
809             {
810                 Groups->Groups[i].Sid = LocalGroups->Groups[i].Sid;
811                 Groups->Groups[i].Attributes = LocalGroups->Groups[i].Attributes;
812             }
813 
814             TokenInfo1->Groups = Groups;
815         }
816     }
817     else
818     {
819         FIXME("TokenInformationType %d is not supported!\n", TokenInformationType);
820         return STATUS_NOT_IMPLEMENTED;
821     }
822 
823     return STATUS_SUCCESS;
824 }
825 
826 static
827 NTSTATUS
LsapAddDefaultGroups(IN PVOID TokenInformation,IN LSA_TOKEN_INFORMATION_TYPE TokenInformationType,IN SECURITY_LOGON_TYPE LogonType)828 LsapAddDefaultGroups(
829     IN PVOID TokenInformation,
830     IN LSA_TOKEN_INFORMATION_TYPE TokenInformationType,
831     IN SECURITY_LOGON_TYPE LogonType)
832 {
833     PLSA_TOKEN_INFORMATION_V1 TokenInfo1;
834     PTOKEN_GROUPS Groups;
835     ULONG i, Length;
836     PSID SrcSid;
837 
838     if (TokenInformationType == LsaTokenInformationV1)
839     {
840         TokenInfo1 = (PLSA_TOKEN_INFORMATION_V1)TokenInformation;
841 
842         if (TokenInfo1->Groups != NULL)
843         {
844             Length = sizeof(TOKEN_GROUPS) +
845                      (TokenInfo1->Groups->GroupCount + 2 - ANYSIZE_ARRAY) * sizeof(SID_AND_ATTRIBUTES);
846 
847             Groups = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, Length);
848             if (Groups == NULL)
849             {
850                 ERR("Group buffer allocation failed!\n");
851                 return STATUS_INSUFFICIENT_RESOURCES;
852             }
853 
854             Groups->GroupCount = TokenInfo1->Groups->GroupCount;
855 
856             for (i = 0; i < TokenInfo1->Groups->GroupCount; i++)
857             {
858                 Groups->Groups[i].Sid = TokenInfo1->Groups->Groups[i].Sid;
859                 Groups->Groups[i].Attributes = TokenInfo1->Groups->Groups[i].Attributes;
860             }
861 
862             RtlFreeHeap(RtlGetProcessHeap(), 0, TokenInfo1->Groups);
863 
864             TokenInfo1->Groups = Groups;
865 
866         }
867         else
868         {
869             Length = sizeof(TOKEN_GROUPS) +
870                      (2 - ANYSIZE_ARRAY) * sizeof(SID_AND_ATTRIBUTES);
871 
872             Groups = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, Length);
873             if (Groups == NULL)
874             {
875                 ERR("Group buffer allocation failed!\n");
876                 return STATUS_INSUFFICIENT_RESOURCES;
877             }
878 
879             TokenInfo1->Groups = Groups;
880         }
881 
882         /* Append the World SID (aka Everyone) */
883         Length = RtlLengthSid(LsapWorldSid);
884         Groups->Groups[Groups->GroupCount].Sid = RtlAllocateHeap(RtlGetProcessHeap(),
885                                                                  HEAP_ZERO_MEMORY,
886                                                                  Length);
887         if (Groups->Groups[Groups->GroupCount].Sid == NULL)
888             return STATUS_INSUFFICIENT_RESOURCES;
889 
890         RtlCopyMemory(Groups->Groups[Groups->GroupCount].Sid,
891                       LsapWorldSid,
892                       Length);
893 
894         Groups->Groups[Groups->GroupCount].Attributes =
895             SE_GROUP_ENABLED | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_MANDATORY;
896 
897         Groups->GroupCount++;
898 
899         /* Append the logon type SID */
900         switch (LogonType)
901         {
902             case Interactive:
903                 SrcSid = LsapInteractiveSid;
904                 break;
905 
906             case Network:
907                 SrcSid = LsapNetworkSid;
908                 break;
909 
910             case Batch:
911                 SrcSid = LsapBatchSid;
912                 break;
913 
914             case Service:
915                 SrcSid = LsapServiceSid;
916                 break;
917 
918             default:
919                 FIXME("LogonType %d is not supported!\n", LogonType);
920                 return STATUS_NOT_IMPLEMENTED;
921         }
922 
923         Length = RtlLengthSid(SrcSid);
924         Groups->Groups[Groups->GroupCount].Sid = RtlAllocateHeap(RtlGetProcessHeap(),
925                                                                  HEAP_ZERO_MEMORY,
926                                                                  Length);
927         if (Groups->Groups[Groups->GroupCount].Sid == NULL)
928             return STATUS_INSUFFICIENT_RESOURCES;
929 
930         RtlCopyMemory(Groups->Groups[Groups->GroupCount].Sid,
931                       SrcSid,
932                       Length);
933 
934         Groups->Groups[Groups->GroupCount].Attributes =
935             SE_GROUP_ENABLED | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_MANDATORY;
936 
937         Groups->GroupCount++;
938     }
939     else
940     {
941         FIXME("TokenInformationType %d is not supported!\n", TokenInformationType);
942         return STATUS_NOT_IMPLEMENTED;
943     }
944 
945     return STATUS_SUCCESS;
946 }
947 
948 
949 static
950 NTSTATUS
LsapAppendSidToGroups(IN PTOKEN_GROUPS * TokenGroups,IN PSID DomainSid,IN ULONG RelativeId)951 LsapAppendSidToGroups(
952     IN PTOKEN_GROUPS *TokenGroups,
953     IN PSID DomainSid,
954     IN ULONG RelativeId)
955 {
956     PTOKEN_GROUPS Groups;
957     PSID Sid;
958     ULONG Length;
959     ULONG i;
960 
961     Sid = LsapAppendRidToSid(DomainSid, RelativeId);
962     if (Sid == NULL)
963     {
964         ERR("Group SID creation failed!\n");
965         return STATUS_INSUFFICIENT_RESOURCES;
966     }
967 
968     if (*TokenGroups == NULL)
969     {
970         Length = sizeof(TOKEN_GROUPS) +
971                  (1 - ANYSIZE_ARRAY) * sizeof(SID_AND_ATTRIBUTES);
972 
973         Groups = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, Length);
974         if (Groups == NULL)
975         {
976             ERR("Group buffer allocation failed!\n");
977             return STATUS_INSUFFICIENT_RESOURCES;
978         }
979 
980         Groups->GroupCount = 1;
981 
982         Groups->Groups[0].Sid = Sid;
983         Groups->Groups[0].Attributes =
984             SE_GROUP_ENABLED | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_MANDATORY;
985 
986         *TokenGroups = Groups;
987     }
988     else
989     {
990         for (i = 0; i < (*TokenGroups)->GroupCount; i++)
991         {
992             if (RtlEqualSid((*TokenGroups)->Groups[i].Sid, Sid))
993             {
994                 RtlFreeHeap(RtlGetProcessHeap(), 0, Sid);
995                 return STATUS_SUCCESS;
996             }
997         }
998 
999         Length = sizeof(TOKEN_GROUPS) +
1000                  ((*TokenGroups)->GroupCount + 1 - ANYSIZE_ARRAY) * sizeof(SID_AND_ATTRIBUTES);
1001 
1002         Groups = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, Length);
1003         if (Groups == NULL)
1004         {
1005             ERR("Group buffer allocation failed!\n");
1006             return STATUS_INSUFFICIENT_RESOURCES;
1007         }
1008 
1009         Groups->GroupCount = (*TokenGroups)->GroupCount;
1010 
1011         for (i = 0; i < (*TokenGroups)->GroupCount; i++)
1012         {
1013             Groups->Groups[i].Sid = (*TokenGroups)->Groups[i].Sid;
1014             Groups->Groups[i].Attributes = (*TokenGroups)->Groups[i].Attributes;
1015         }
1016 
1017         Groups->Groups[Groups->GroupCount].Sid = Sid;
1018         Groups->Groups[Groups->GroupCount].Attributes =
1019             SE_GROUP_ENABLED | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_MANDATORY;
1020 
1021         Groups->GroupCount++;
1022 
1023         RtlFreeHeap(RtlGetProcessHeap(), 0, *TokenGroups);
1024 
1025         *TokenGroups = Groups;
1026     }
1027 
1028     return STATUS_SUCCESS;
1029 }
1030 
1031 
1032 static
1033 NTSTATUS
LsapAddSamGroups(IN PVOID TokenInformation,IN LSA_TOKEN_INFORMATION_TYPE TokenInformationType)1034 LsapAddSamGroups(
1035     IN PVOID TokenInformation,
1036     IN LSA_TOKEN_INFORMATION_TYPE TokenInformationType)
1037 {
1038     PLSA_TOKEN_INFORMATION_V1 TokenInfo1;
1039     SAMPR_HANDLE ServerHandle = NULL;
1040     SAMPR_HANDLE BuiltinDomainHandle = NULL;
1041     SAMPR_HANDLE AccountDomainHandle = NULL;
1042     SAMPR_PSID_ARRAY SidArray;
1043     SAMPR_ULONG_ARRAY BuiltinMembership;
1044     SAMPR_ULONG_ARRAY AccountMembership;
1045     ULONG i;
1046     NTSTATUS Status = STATUS_SUCCESS;
1047 
1048     if (TokenInformationType != LsaTokenInformationV1)
1049         return STATUS_SUCCESS;
1050 
1051     TokenInfo1 = (PLSA_TOKEN_INFORMATION_V1)TokenInformation;
1052 
1053     SidArray.Count = TokenInfo1->Groups->GroupCount + 1;
1054     SidArray.Sids = RtlAllocateHeap(RtlGetProcessHeap(),
1055                                     HEAP_ZERO_MEMORY,
1056                                     (TokenInfo1->Groups->GroupCount + 1) * sizeof(PRPC_SID));
1057     if (SidArray.Sids == NULL)
1058         return STATUS_INSUFFICIENT_RESOURCES;
1059 
1060     SidArray.Sids[0].SidPointer = TokenInfo1->User.User.Sid;
1061     for (i = 0; i < TokenInfo1->Groups->GroupCount; i++)
1062         SidArray.Sids[i + 1].SidPointer = TokenInfo1->Groups->Groups[i].Sid;
1063 
1064     BuiltinMembership.Element = NULL;
1065     AccountMembership.Element = NULL;
1066 
1067     Status = SamIConnect(NULL,
1068                          &ServerHandle,
1069                          SAM_SERVER_CONNECT | SAM_SERVER_LOOKUP_DOMAIN,
1070                          FALSE);
1071     if (!NT_SUCCESS(Status))
1072     {
1073         TRACE("SamIConnect failed (Status %08lx)\n", Status);
1074         goto done;
1075     }
1076 
1077     Status = SamrOpenDomain(ServerHandle,
1078                             DOMAIN_GET_ALIAS_MEMBERSHIP,
1079                             BuiltinDomainSid,
1080                             &BuiltinDomainHandle);
1081     if (!NT_SUCCESS(Status))
1082     {
1083         TRACE("SamrOpenDomain failed (Status %08lx)\n", Status);
1084         goto done;
1085     }
1086 
1087     Status = SamrOpenDomain(ServerHandle,
1088                             DOMAIN_GET_ALIAS_MEMBERSHIP,
1089                             AccountDomainSid,
1090                             &AccountDomainHandle);
1091     if (!NT_SUCCESS(Status))
1092     {
1093         TRACE("SamrOpenDomain failed (Status %08lx)\n", Status);
1094         goto done;
1095     }
1096 
1097     Status = SamrGetAliasMembership(BuiltinDomainHandle,
1098                                     &SidArray,
1099                                     &BuiltinMembership);
1100     if (!NT_SUCCESS(Status))
1101     {
1102         TRACE("SamrGetAliasMembership failed (Status %08lx)\n", Status);
1103         goto done;
1104     }
1105 
1106     Status = SamrGetAliasMembership(AccountDomainHandle,
1107                                     &SidArray,
1108                                     &AccountMembership);
1109     if (!NT_SUCCESS(Status))
1110     {
1111         TRACE("SamrGetAliasMembership failed (Status %08lx)\n", Status);
1112         goto done;
1113     }
1114 
1115     TRACE("Builtin Memberships: %lu\n", BuiltinMembership.Count);
1116     for (i = 0; i < BuiltinMembership.Count; i++)
1117     {
1118         TRACE("RID %lu: %lu (0x%lx)\n", i, BuiltinMembership.Element[i], BuiltinMembership.Element[i]);
1119         Status = LsapAppendSidToGroups(&TokenInfo1->Groups,
1120                                        BuiltinDomainSid,
1121                                        BuiltinMembership.Element[i]);
1122         if (!NT_SUCCESS(Status))
1123         {
1124             TRACE("LsapAppendSidToGroups failed (Status %08lx)\n", Status);
1125             goto done;
1126         }
1127     }
1128 
1129     TRACE("Account Memberships: %lu\n", AccountMembership.Count);
1130     for (i = 0; i < AccountMembership.Count; i++)
1131     {
1132         TRACE("RID %lu: %lu (0x%lx)\n", i, AccountMembership.Element[i], AccountMembership.Element[i]);
1133         Status = LsapAppendSidToGroups(&TokenInfo1->Groups,
1134                                        AccountDomainSid,
1135                                        AccountMembership.Element[i]);
1136         if (!NT_SUCCESS(Status))
1137         {
1138             TRACE("LsapAppendSidToGroups failed (Status %08lx)\n", Status);
1139             goto done;
1140         }
1141     }
1142 
1143 done:
1144     RtlFreeHeap(RtlGetProcessHeap(), 0, SidArray.Sids);
1145 
1146     if (AccountMembership.Element != NULL)
1147         SamIFree_SAMPR_ULONG_ARRAY(&AccountMembership);
1148 
1149     if (BuiltinMembership.Element != NULL)
1150         SamIFree_SAMPR_ULONG_ARRAY(&BuiltinMembership);
1151 
1152     if (AccountDomainHandle != NULL)
1153         SamrCloseHandle(&AccountDomainHandle);
1154 
1155     if (BuiltinDomainHandle != NULL)
1156         SamrCloseHandle(&BuiltinDomainHandle);
1157 
1158     if (ServerHandle != NULL)
1159         SamrCloseHandle(&ServerHandle);
1160 
1161 //    return Status;
1162 
1163     return STATUS_SUCCESS;
1164 }
1165 
1166 
1167 static
1168 NTSTATUS
LsapSetTokenOwner(IN PVOID TokenInformation,IN LSA_TOKEN_INFORMATION_TYPE TokenInformationType)1169 LsapSetTokenOwner(
1170     IN PVOID TokenInformation,
1171     IN LSA_TOKEN_INFORMATION_TYPE TokenInformationType)
1172 {
1173     PLSA_TOKEN_INFORMATION_V1 TokenInfo1;
1174     PSID_AND_ATTRIBUTES OwnerSid = NULL;
1175     ULONG i, Length;
1176 
1177     if (TokenInformationType == LsaTokenInformationV1)
1178     {
1179         TokenInfo1 = (PLSA_TOKEN_INFORMATION_V1)TokenInformation;
1180 
1181         if (TokenInfo1->Owner.Owner != NULL)
1182             return STATUS_SUCCESS;
1183 
1184         OwnerSid = &TokenInfo1->User.User;
1185         for (i = 0; i < TokenInfo1->Groups->GroupCount; i++)
1186         {
1187             if (EqualSid(TokenInfo1->Groups->Groups[i].Sid, LsapAdministratorsSid))
1188             {
1189                 OwnerSid = &TokenInfo1->Groups->Groups[i];
1190                 break;
1191             }
1192         }
1193 
1194         Length = RtlLengthSid(OwnerSid->Sid);
1195         TokenInfo1->Owner.Owner = DispatchTable.AllocateLsaHeap(Length);
1196         if (TokenInfo1->Owner.Owner == NULL)
1197             return STATUS_INSUFFICIENT_RESOURCES;
1198 
1199         RtlCopyMemory(TokenInfo1->Owner.Owner,
1200                       OwnerSid->Sid,
1201                       Length);
1202         OwnerSid->Attributes |= SE_GROUP_OWNER;
1203     }
1204 
1205     return STATUS_SUCCESS;
1206 }
1207 
1208 
1209 static
1210 NTSTATUS
LsapAddTokenDefaultDacl(IN PVOID TokenInformation,IN LSA_TOKEN_INFORMATION_TYPE TokenInformationType)1211 LsapAddTokenDefaultDacl(
1212     IN PVOID TokenInformation,
1213     IN LSA_TOKEN_INFORMATION_TYPE TokenInformationType)
1214 {
1215     PLSA_TOKEN_INFORMATION_V1 TokenInfo1;
1216     PACL Dacl = NULL;
1217     ULONG Length;
1218 
1219     if (TokenInformationType == LsaTokenInformationV1)
1220     {
1221         TokenInfo1 = (PLSA_TOKEN_INFORMATION_V1)TokenInformation;
1222 
1223         if (TokenInfo1->DefaultDacl.DefaultDacl != NULL)
1224             return STATUS_SUCCESS;
1225 
1226         Length = sizeof(ACL) +
1227                  (2 * sizeof(ACCESS_ALLOWED_ACE)) +
1228                  RtlLengthSid(TokenInfo1->Owner.Owner) +
1229                  RtlLengthSid(LsapLocalSystemSid);
1230 
1231         Dacl = DispatchTable.AllocateLsaHeap(Length);
1232         if (Dacl == NULL)
1233             return STATUS_INSUFFICIENT_RESOURCES;
1234 
1235         RtlCreateAcl(Dacl, Length, ACL_REVISION);
1236 
1237         RtlAddAccessAllowedAce(Dacl,
1238                                ACL_REVISION,
1239                                GENERIC_ALL,
1240                                TokenInfo1->Owner.Owner);
1241 
1242         /* SID: S-1-5-18 */
1243         RtlAddAccessAllowedAce(Dacl,
1244                                ACL_REVISION,
1245                                GENERIC_ALL,
1246                                LsapLocalSystemSid);
1247 
1248         TokenInfo1->DefaultDacl.DefaultDacl = Dacl;
1249     }
1250 
1251     return STATUS_SUCCESS;
1252 }
1253 
1254 
1255 static
1256 NTSTATUS
LsapAddPrivilegeToTokenPrivileges(PTOKEN_PRIVILEGES * TokenPrivileges,PLSAPR_LUID_AND_ATTRIBUTES Privilege)1257 LsapAddPrivilegeToTokenPrivileges(PTOKEN_PRIVILEGES *TokenPrivileges,
1258                                   PLSAPR_LUID_AND_ATTRIBUTES Privilege)
1259 {
1260     PTOKEN_PRIVILEGES LocalPrivileges;
1261     ULONG Length, TokenPrivilegeCount, i;
1262     NTSTATUS Status = STATUS_SUCCESS;
1263 
1264     if (*TokenPrivileges == NULL)
1265     {
1266         Length = sizeof(TOKEN_PRIVILEGES) +
1267                  (1 - ANYSIZE_ARRAY) * sizeof(LUID_AND_ATTRIBUTES);
1268         LocalPrivileges = RtlAllocateHeap(RtlGetProcessHeap(),
1269                                           0,
1270                                           Length);
1271         if (LocalPrivileges == NULL)
1272             return STATUS_INSUFFICIENT_RESOURCES;
1273 
1274         LocalPrivileges->PrivilegeCount = 1;
1275         LocalPrivileges->Privileges[0].Luid = Privilege->Luid;
1276         LocalPrivileges->Privileges[0].Attributes = Privilege->Attributes;
1277     }
1278     else
1279     {
1280         TokenPrivilegeCount = (*TokenPrivileges)->PrivilegeCount;
1281 
1282         for (i = 0; i < TokenPrivilegeCount; i++)
1283         {
1284             if (RtlEqualLuid(&(*TokenPrivileges)->Privileges[i].Luid, &Privilege->Luid))
1285                 return STATUS_SUCCESS;
1286         }
1287 
1288         Length = sizeof(TOKEN_PRIVILEGES) +
1289                  (TokenPrivilegeCount + 1 - ANYSIZE_ARRAY) * sizeof(LUID_AND_ATTRIBUTES);
1290         LocalPrivileges = RtlAllocateHeap(RtlGetProcessHeap(),
1291                                           0,
1292                                           Length);
1293         if (LocalPrivileges == NULL)
1294             return STATUS_INSUFFICIENT_RESOURCES;
1295 
1296         LocalPrivileges->PrivilegeCount = TokenPrivilegeCount + 1;
1297         for (i = 0; i < TokenPrivilegeCount; i++)
1298         {
1299             LocalPrivileges->Privileges[i].Luid = (*TokenPrivileges)->Privileges[i].Luid;
1300             LocalPrivileges->Privileges[i].Attributes = (*TokenPrivileges)->Privileges[i].Attributes;
1301         }
1302 
1303         LocalPrivileges->Privileges[TokenPrivilegeCount].Luid = Privilege->Luid;
1304         LocalPrivileges->Privileges[TokenPrivilegeCount].Attributes = Privilege->Attributes;
1305 
1306         RtlFreeHeap(RtlGetProcessHeap(), 0, *TokenPrivileges);
1307     }
1308 
1309     *TokenPrivileges = LocalPrivileges;
1310 
1311     return Status;
1312 }
1313 
1314 static
1315 NTSTATUS
LsapSetPrivileges(IN PVOID TokenInformation,IN LSA_TOKEN_INFORMATION_TYPE TokenInformationType)1316 LsapSetPrivileges(
1317     IN PVOID TokenInformation,
1318     IN LSA_TOKEN_INFORMATION_TYPE TokenInformationType)
1319 {
1320     PLSA_TOKEN_INFORMATION_V1 TokenInfo1;
1321     LSAPR_HANDLE PolicyHandle = NULL;
1322     LSAPR_HANDLE AccountHandle = NULL;
1323     PLSAPR_PRIVILEGE_SET Privileges = NULL;
1324     ULONG i, j;
1325     NTSTATUS Status;
1326 
1327     if (TokenInformationType == LsaTokenInformationV1)
1328     {
1329         TokenInfo1 = (PLSA_TOKEN_INFORMATION_V1)TokenInformation;
1330 
1331         Status = LsarOpenPolicy(NULL,
1332                                 NULL,
1333                                 0,
1334                                 &PolicyHandle);
1335         if (!NT_SUCCESS(Status))
1336             return Status;
1337 
1338         for (i = 0; i < TokenInfo1->Groups->GroupCount; i++)
1339         {
1340             Status = LsarOpenAccount(PolicyHandle,
1341                                      TokenInfo1->Groups->Groups[i].Sid,
1342                                      ACCOUNT_VIEW,
1343                                      &AccountHandle);
1344             if (!NT_SUCCESS(Status))
1345                 continue;
1346 
1347             Status = LsarEnumeratePrivilegesAccount(AccountHandle,
1348                                                     &Privileges);
1349             if (NT_SUCCESS(Status))
1350             {
1351                 for (j = 0; j < Privileges->PrivilegeCount; j++)
1352                 {
1353                     Status = LsapAddPrivilegeToTokenPrivileges(&TokenInfo1->Privileges,
1354                                                                &(Privileges->Privilege[j]));
1355                     if (!NT_SUCCESS(Status))
1356                     {
1357                         /* We failed, clean everything and return */
1358                         LsaIFree_LSAPR_PRIVILEGE_SET(Privileges);
1359                         LsarClose(&AccountHandle);
1360                         LsarClose(&PolicyHandle);
1361 
1362                         return Status;
1363                     }
1364                 }
1365 
1366                 LsaIFree_LSAPR_PRIVILEGE_SET(Privileges);
1367                 Privileges = NULL;
1368             }
1369 
1370             LsarClose(&AccountHandle);
1371         }
1372 
1373         LsarClose(&PolicyHandle);
1374 
1375         if (TokenInfo1->Privileges != NULL)
1376         {
1377             for (i = 0; i < TokenInfo1->Privileges->PrivilegeCount; i++)
1378             {
1379                 if (RtlEqualLuid(&TokenInfo1->Privileges->Privileges[i].Luid, &SeChangeNotifyPrivilege) ||
1380                     RtlEqualLuid(&TokenInfo1->Privileges->Privileges[i].Luid, &SeCreateGlobalPrivilege) ||
1381                     RtlEqualLuid(&TokenInfo1->Privileges->Privileges[i].Luid, &SeImpersonatePrivilege))
1382                 {
1383                     TokenInfo1->Privileges->Privileges[i].Attributes |= SE_PRIVILEGE_ENABLED | SE_PRIVILEGE_ENABLED_BY_DEFAULT;
1384                 }
1385             }
1386         }
1387     }
1388 
1389     return STATUS_SUCCESS;
1390 }
1391 
1392 
1393 NTSTATUS
LsapLogonUser(PLSA_API_MSG RequestMsg,PLSAP_LOGON_CONTEXT LogonContext)1394 LsapLogonUser(PLSA_API_MSG RequestMsg,
1395               PLSAP_LOGON_CONTEXT LogonContext)
1396 {
1397     PAUTH_PACKAGE Package;
1398     OBJECT_ATTRIBUTES ObjectAttributes;
1399     SECURITY_QUALITY_OF_SERVICE Qos;
1400     LSA_TOKEN_INFORMATION_TYPE TokenInformationType;
1401     PVOID TokenInformation = NULL;
1402     PLSA_TOKEN_INFORMATION_NULL TokenInfo0 = NULL;
1403     PLSA_TOKEN_INFORMATION_V1 TokenInfo1 = NULL;
1404     PUNICODE_STRING AccountName = NULL;
1405     PUNICODE_STRING AuthenticatingAuthority = NULL;
1406     PUNICODE_STRING MachineName = NULL;
1407     PVOID LocalAuthInfo = NULL;
1408     PTOKEN_GROUPS LocalGroups = NULL;
1409     HANDLE TokenHandle = NULL;
1410     ULONG i;
1411     ULONG PackageId;
1412     SECURITY_LOGON_TYPE LogonType;
1413     NTSTATUS Status;
1414 
1415     PUNICODE_STRING UserName = NULL;
1416     PUNICODE_STRING LogonDomainName = NULL;
1417 //    UNICODE_STRING LogonServer;
1418 
1419 
1420     TRACE("LsapLogonUser(%p %p)\n", RequestMsg, LogonContext);
1421 
1422     PackageId = RequestMsg->LogonUser.Request.AuthenticationPackage;
1423     LogonType = RequestMsg->LogonUser.Request.LogonType;
1424 
1425     /* Get the right authentication package */
1426     Package = LsapGetAuthenticationPackage(PackageId);
1427     if (Package == NULL)
1428     {
1429         ERR("LsapGetAuthenticationPackage() failed to find a package\n");
1430         return STATUS_NO_SUCH_PACKAGE;
1431     }
1432 
1433     if (RequestMsg->LogonUser.Request.AuthenticationInformationLength > 0)
1434     {
1435         /* Allocate the local authentication info buffer */
1436         LocalAuthInfo = RtlAllocateHeap(RtlGetProcessHeap(),
1437                                         HEAP_ZERO_MEMORY,
1438                                         RequestMsg->LogonUser.Request.AuthenticationInformationLength);
1439         if (LocalAuthInfo == NULL)
1440         {
1441             ERR("RtlAllocateHeap() failed\n");
1442             return STATUS_INSUFFICIENT_RESOURCES;
1443         }
1444 
1445         /* Read the authentication info from the callers address space */
1446         Status = NtReadVirtualMemory(LogonContext->ClientProcessHandle,
1447                                      RequestMsg->LogonUser.Request.AuthenticationInformation,
1448                                      LocalAuthInfo,
1449                                      RequestMsg->LogonUser.Request.AuthenticationInformationLength,
1450                                      NULL);
1451         if (!NT_SUCCESS(Status))
1452         {
1453             ERR("NtReadVirtualMemory() failed (Status 0x%08lx)\n", Status);
1454             RtlFreeHeap(RtlGetProcessHeap(), 0, LocalAuthInfo);
1455             return Status;
1456         }
1457     }
1458 
1459     if (RequestMsg->LogonUser.Request.LocalGroupsCount > 0)
1460     {
1461         Status = LsapCopyLocalGroups(LogonContext,
1462                                      RequestMsg->LogonUser.Request.LocalGroups,
1463                                      RequestMsg->LogonUser.Request.LocalGroupsCount,
1464                                      &LocalGroups);
1465         if (!NT_SUCCESS(Status))
1466         {
1467             ERR("LsapCopyLocalGroups failed (Status 0x%08lx)\n", Status);
1468             goto done;
1469         }
1470 
1471         TRACE("GroupCount: %lu\n", LocalGroups->GroupCount);
1472     }
1473 
1474     if (Package->LsaApLogonUserEx2 != NULL)
1475     {
1476         Status = Package->LsaApLogonUserEx2((PLSA_CLIENT_REQUEST)LogonContext,
1477                                             RequestMsg->LogonUser.Request.LogonType,
1478                                             LocalAuthInfo,
1479                                             RequestMsg->LogonUser.Request.AuthenticationInformation,
1480                                             RequestMsg->LogonUser.Request.AuthenticationInformationLength,
1481                                             &RequestMsg->LogonUser.Reply.ProfileBuffer,
1482                                             &RequestMsg->LogonUser.Reply.ProfileBufferLength,
1483                                             &RequestMsg->LogonUser.Reply.LogonId,
1484                                             &RequestMsg->LogonUser.Reply.SubStatus,
1485                                             &TokenInformationType,
1486                                             &TokenInformation,
1487                                             &AccountName,
1488                                             &AuthenticatingAuthority,
1489                                             &MachineName,
1490                                             NULL,  /* FIXME: PSECPKG_PRIMARY_CRED PrimaryCredentials */
1491                                             NULL); /* FIXME: PSECPKG_SUPPLEMENTAL_CRED_ARRAY *SupplementalCredentials */
1492     }
1493     else if (Package->LsaApLogonUserEx != NULL)
1494     {
1495         Status = Package->LsaApLogonUserEx((PLSA_CLIENT_REQUEST)LogonContext,
1496                                            RequestMsg->LogonUser.Request.LogonType,
1497                                            LocalAuthInfo,
1498                                            RequestMsg->LogonUser.Request.AuthenticationInformation,
1499                                            RequestMsg->LogonUser.Request.AuthenticationInformationLength,
1500                                            &RequestMsg->LogonUser.Reply.ProfileBuffer,
1501                                            &RequestMsg->LogonUser.Reply.ProfileBufferLength,
1502                                            &RequestMsg->LogonUser.Reply.LogonId,
1503                                            &RequestMsg->LogonUser.Reply.SubStatus,
1504                                            &TokenInformationType,
1505                                            &TokenInformation,
1506                                            &AccountName,
1507                                            &AuthenticatingAuthority,
1508                                            &MachineName);
1509     }
1510     else
1511     {
1512         Status = Package->LsaApLogonUser((PLSA_CLIENT_REQUEST)LogonContext,
1513                                          RequestMsg->LogonUser.Request.LogonType,
1514                                          LocalAuthInfo,
1515                                          RequestMsg->LogonUser.Request.AuthenticationInformation,
1516                                          RequestMsg->LogonUser.Request.AuthenticationInformationLength,
1517                                          &RequestMsg->LogonUser.Reply.ProfileBuffer,
1518                                          &RequestMsg->LogonUser.Reply.ProfileBufferLength,
1519                                          &RequestMsg->LogonUser.Reply.LogonId,
1520                                          &RequestMsg->LogonUser.Reply.SubStatus,
1521                                          &TokenInformationType,
1522                                          &TokenInformation,
1523                                          &AccountName,
1524                                          &AuthenticatingAuthority);
1525     }
1526 
1527     if (!NT_SUCCESS(Status))
1528     {
1529         ERR("LsaApLogonUser/Ex/2 failed (Status 0x%08lx)\n", Status);
1530         goto done;
1531     }
1532 
1533     if (LocalGroups->GroupCount > 0)
1534     {
1535         /* Add local groups to the token information */
1536         Status = LsapAddLocalGroups(TokenInformation,
1537                                     TokenInformationType,
1538                                     LocalGroups);
1539         if (!NT_SUCCESS(Status))
1540         {
1541             ERR("LsapAddLocalGroupsToTokenInfo() failed (Status 0x%08lx)\n", Status);
1542             goto done;
1543         }
1544     }
1545 
1546     Status = LsapAddDefaultGroups(TokenInformation,
1547                                   TokenInformationType,
1548                                   LogonType);
1549     if (!NT_SUCCESS(Status))
1550     {
1551         ERR("LsapAddDefaultGroups() failed (Status 0x%08lx)\n", Status);
1552         goto done;
1553     }
1554 
1555     Status = LsapAddSamGroups(TokenInformation,
1556                               TokenInformationType);
1557     if (!NT_SUCCESS(Status))
1558     {
1559         ERR("LsapAddSamGroups() failed (Status 0x%08lx)\n", Status);
1560         goto done;
1561     }
1562 
1563     Status = LsapSetTokenOwner(TokenInformation,
1564                                TokenInformationType);
1565     if (!NT_SUCCESS(Status))
1566     {
1567         ERR("LsapSetTokenOwner() failed (Status 0x%08lx)\n", Status);
1568         goto done;
1569     }
1570 
1571     Status = LsapAddTokenDefaultDacl(TokenInformation,
1572                                      TokenInformationType);
1573     if (!NT_SUCCESS(Status))
1574     {
1575         ERR("LsapAddTokenDefaultDacl() failed (Status 0x%08lx)\n", Status);
1576         goto done;
1577     }
1578 
1579     Status = LsapSetPrivileges(TokenInformation,
1580                                TokenInformationType);
1581     if (!NT_SUCCESS(Status))
1582     {
1583         ERR("LsapSetPrivileges() failed (Status 0x%08lx)\n", Status);
1584         goto done;
1585     }
1586 
1587     if (TokenInformationType == LsaTokenInformationNull)
1588     {
1589         TOKEN_USER TokenUser;
1590         TOKEN_PRIMARY_GROUP TokenPrimaryGroup;
1591         TOKEN_GROUPS NoGroups = {0};
1592         TOKEN_PRIVILEGES NoPrivileges = {0};
1593 
1594         TokenInfo0 = (PLSA_TOKEN_INFORMATION_NULL)TokenInformation;
1595 
1596         TokenUser.User.Sid = LsapWorldSid;
1597         TokenUser.User.Attributes = 0;
1598         TokenPrimaryGroup.PrimaryGroup = LsapWorldSid;
1599 
1600         Qos.Length = sizeof(SECURITY_QUALITY_OF_SERVICE);
1601         Qos.ImpersonationLevel = SecurityImpersonation;
1602         Qos.ContextTrackingMode = SECURITY_STATIC_TRACKING;
1603         Qos.EffectiveOnly = TRUE;
1604 
1605         ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES);
1606         ObjectAttributes.RootDirectory = NULL;
1607         ObjectAttributes.ObjectName = NULL;
1608         ObjectAttributes.Attributes = 0;
1609         ObjectAttributes.SecurityDescriptor = NULL;
1610         ObjectAttributes.SecurityQualityOfService = &Qos;
1611 
1612         /* Create the logon token */
1613         Status = NtCreateToken(&TokenHandle,
1614                                TOKEN_ALL_ACCESS,
1615                                &ObjectAttributes,
1616                                TokenImpersonation,
1617                                &RequestMsg->LogonUser.Reply.LogonId,
1618                                &TokenInfo0->ExpirationTime,
1619                                &TokenUser,
1620                                &NoGroups,
1621                                &NoPrivileges,
1622                                NULL,
1623                                &TokenPrimaryGroup,
1624                                NULL,
1625                                &RequestMsg->LogonUser.Request.SourceContext);
1626     }
1627     else if (TokenInformationType == LsaTokenInformationV1)
1628     {
1629         TOKEN_PRIVILEGES NoPrivileges = {0};
1630         PSECURITY_DESCRIPTOR TokenSd;
1631         ULONG TokenSdSize;
1632 
1633         TokenInfo1 = (PLSA_TOKEN_INFORMATION_V1)TokenInformation;
1634 
1635         /* Set up a security descriptor for token object itself */
1636         Status = LsapCreateTokenSd(&TokenInfo1->User, &TokenSd, &TokenSdSize);
1637         if (!NT_SUCCESS(Status))
1638         {
1639             TokenSd = NULL;
1640         }
1641 
1642         Qos.Length = sizeof(SECURITY_QUALITY_OF_SERVICE);
1643         Qos.ImpersonationLevel = SecurityImpersonation;
1644         Qos.ContextTrackingMode = SECURITY_DYNAMIC_TRACKING;
1645         Qos.EffectiveOnly = FALSE;
1646 
1647         ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES);
1648         ObjectAttributes.RootDirectory = NULL;
1649         ObjectAttributes.ObjectName = NULL;
1650         ObjectAttributes.Attributes = 0;
1651         ObjectAttributes.SecurityDescriptor = TokenSd;
1652         ObjectAttributes.SecurityQualityOfService = &Qos;
1653 
1654         /* Create the logon token */
1655         Status = NtCreateToken(&TokenHandle,
1656                                TOKEN_ALL_ACCESS,
1657                                &ObjectAttributes,
1658                                (RequestMsg->LogonUser.Request.LogonType == Network) ? TokenImpersonation : TokenPrimary,
1659                                &RequestMsg->LogonUser.Reply.LogonId,
1660                                &TokenInfo1->ExpirationTime,
1661                                &TokenInfo1->User,
1662                                TokenInfo1->Groups,
1663                                TokenInfo1->Privileges ? TokenInfo1->Privileges : &NoPrivileges,
1664                                &TokenInfo1->Owner,
1665                                &TokenInfo1->PrimaryGroup,
1666                                &TokenInfo1->DefaultDacl,
1667                                &RequestMsg->LogonUser.Request.SourceContext);
1668 
1669         /* Free the allocated security descriptor */
1670         RtlFreeHeap(RtlGetProcessHeap(), 0, TokenSd);
1671 
1672         if (!NT_SUCCESS(Status))
1673         {
1674             ERR("NtCreateToken failed (Status 0x%08lx)\n", Status);
1675             goto done;
1676         }
1677     }
1678     else
1679     {
1680         FIXME("TokenInformationType %d is not supported!\n", TokenInformationType);
1681         Status = STATUS_NOT_IMPLEMENTED;
1682         goto done;
1683     }
1684 
1685     if (LogonType == Interactive ||
1686         LogonType == Batch ||
1687         LogonType == Service)
1688     {
1689         UserName = &((PMSV1_0_INTERACTIVE_LOGON)LocalAuthInfo)->UserName;
1690         LogonDomainName = &((PMSV1_0_INTERACTIVE_LOGON)LocalAuthInfo)->LogonDomainName;
1691     }
1692     else
1693     {
1694         FIXME("LogonType %lu is not supported yet!\n", LogonType);
1695     }
1696 
1697     Status = LsapSetLogonSessionData(&RequestMsg->LogonUser.Reply.LogonId,
1698                                      LogonType,
1699                                      UserName,
1700                                      LogonDomainName,
1701                                      TokenInfo1->User.User.Sid);
1702     if (!NT_SUCCESS(Status))
1703     {
1704         ERR("LsapSetLogonSessionData failed (Status 0x%08lx)\n", Status);
1705         goto done;
1706     }
1707 
1708     /*
1709      * Duplicate the token handle into the client process.
1710      * This must be the last step because we cannot
1711      * close the duplicated token handle in case something fails.
1712      */
1713     Status = NtDuplicateObject(NtCurrentProcess(),
1714                                TokenHandle,
1715                                LogonContext->ClientProcessHandle,
1716                                &RequestMsg->LogonUser.Reply.Token,
1717                                0,
1718                                0,
1719                                DUPLICATE_SAME_ACCESS | DUPLICATE_SAME_ATTRIBUTES | DUPLICATE_CLOSE_SOURCE);
1720     if (!NT_SUCCESS(Status))
1721     {
1722         ERR("NtDuplicateObject failed (Status 0x%08lx)\n", Status);
1723         goto done;
1724     }
1725 
1726 done:
1727     if (!NT_SUCCESS(Status))
1728     {
1729         /* Notify the authentification package of the failure */
1730         Package->LsaApLogonTerminated(&RequestMsg->LogonUser.Reply.LogonId);
1731 
1732         /* Delete the logon session */
1733         LsapDeleteLogonSession(&RequestMsg->LogonUser.Reply.LogonId);
1734 
1735         /* Release the profile buffer */
1736         LsapFreeClientBuffer((PLSA_CLIENT_REQUEST)LogonContext,
1737                              RequestMsg->LogonUser.Reply.ProfileBuffer);
1738         RequestMsg->LogonUser.Reply.ProfileBuffer = NULL;
1739     }
1740 
1741     if (TokenHandle != NULL)
1742         NtClose(TokenHandle);
1743 
1744     /* Free the local groups */
1745     if (LocalGroups != NULL)
1746     {
1747         for (i = 0; i < LocalGroups->GroupCount; i++)
1748         {
1749             if (LocalGroups->Groups[i].Sid != NULL)
1750                 RtlFreeHeap(RtlGetProcessHeap(), 0, LocalGroups->Groups[i].Sid);
1751         }
1752 
1753         RtlFreeHeap(RtlGetProcessHeap(), 0, LocalGroups);
1754     }
1755 
1756     /* Free the local authentication info buffer */
1757     if (LocalAuthInfo != NULL)
1758         RtlFreeHeap(RtlGetProcessHeap(), 0, LocalAuthInfo);
1759 
1760     /* Free the token information */
1761     if (TokenInformation != NULL)
1762     {
1763         if (TokenInformationType == LsaTokenInformationNull)
1764         {
1765             TokenInfo0 = (PLSA_TOKEN_INFORMATION_NULL)TokenInformation;
1766 
1767             if (TokenInfo0 != NULL)
1768             {
1769                 if (TokenInfo0->Groups != NULL)
1770                 {
1771                     for (i = 0; i < TokenInfo0->Groups->GroupCount; i++)
1772                     {
1773                         if (TokenInfo0->Groups->Groups[i].Sid != NULL)
1774                             LsapFreeHeap(TokenInfo0->Groups->Groups[i].Sid);
1775                     }
1776 
1777                     LsapFreeHeap(TokenInfo0->Groups);
1778                 }
1779 
1780                 LsapFreeHeap(TokenInfo0);
1781             }
1782         }
1783         else if (TokenInformationType == LsaTokenInformationV1)
1784         {
1785             TokenInfo1 = (PLSA_TOKEN_INFORMATION_V1)TokenInformation;
1786 
1787             if (TokenInfo1 != NULL)
1788             {
1789                 if (TokenInfo1->User.User.Sid != NULL)
1790                     LsapFreeHeap(TokenInfo1->User.User.Sid);
1791 
1792                 if (TokenInfo1->Groups != NULL)
1793                 {
1794                     for (i = 0; i < TokenInfo1->Groups->GroupCount; i++)
1795                     {
1796                         if (TokenInfo1->Groups->Groups[i].Sid != NULL)
1797                             LsapFreeHeap(TokenInfo1->Groups->Groups[i].Sid);
1798                     }
1799 
1800                     LsapFreeHeap(TokenInfo1->Groups);
1801                 }
1802 
1803                 if (TokenInfo1->PrimaryGroup.PrimaryGroup != NULL)
1804                     LsapFreeHeap(TokenInfo1->PrimaryGroup.PrimaryGroup);
1805 
1806                 if (TokenInfo1->Privileges != NULL)
1807                     LsapFreeHeap(TokenInfo1->Privileges);
1808 
1809                 if (TokenInfo1->Owner.Owner != NULL)
1810                     LsapFreeHeap(TokenInfo1->Owner.Owner);
1811 
1812                 if (TokenInfo1->DefaultDacl.DefaultDacl != NULL)
1813                     LsapFreeHeap(TokenInfo1->DefaultDacl.DefaultDacl);
1814 
1815                 LsapFreeHeap(TokenInfo1);
1816             }
1817         }
1818         else
1819         {
1820             FIXME("TokenInformationType %d is not supported!\n", TokenInformationType);
1821         }
1822     }
1823 
1824     /* Free the account name */
1825     if (AccountName != NULL)
1826     {
1827         if (AccountName->Buffer != NULL)
1828             LsapFreeHeap(AccountName->Buffer);
1829 
1830         LsapFreeHeap(AccountName);
1831     }
1832 
1833     /* Free the authentication authority */
1834     if (AuthenticatingAuthority != NULL)
1835     {
1836         if (AuthenticatingAuthority->Buffer != NULL)
1837             LsapFreeHeap(AuthenticatingAuthority->Buffer);
1838 
1839         LsapFreeHeap(AuthenticatingAuthority);
1840     }
1841 
1842     /* Free the machine name */
1843     if (MachineName != NULL)
1844     {
1845         if (MachineName->Buffer != NULL)
1846             LsapFreeHeap(MachineName->Buffer);
1847 
1848         LsapFreeHeap(MachineName);
1849     }
1850 
1851     TRACE("LsapLogonUser done (Status 0x%08lx)\n", Status);
1852 
1853     return Status;
1854 }
1855 
1856 /* EOF */
1857