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