29bb465d80b64ca8d15db2ce11476e177872a3a9
[reactos.git] / dll / win32 / lsasrv / authpackage.c
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
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
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
365 LsapAllocateHeap(IN ULONG Length)
366 {
367 return RtlAllocateHeap(RtlGetProcessHeap(), 0, Length);
368 }
369
370
371 PVOID
372 NTAPI
373 LsapAllocateHeapZero(IN ULONG Length)
374 {
375 return RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, Length);
376 }
377
378
379 VOID
380 NTAPI
381 LsapFreeHeap(IN PVOID Base)
382 {
383 RtlFreeHeap(RtlGetProcessHeap(), 0, Base);
384 }
385
386
387 static
388 NTSTATUS
389 NTAPI
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
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
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
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
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
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 NTSTATUS
545 LsapCallAuthenticationPackage(PLSA_API_MSG RequestMsg,
546 PLSAP_LOGON_CONTEXT LogonContext)
547 {
548 PAUTH_PACKAGE Package;
549 PVOID LocalBuffer = NULL;
550 ULONG PackageId;
551 NTSTATUS Status;
552
553 TRACE("(%p %p)\n", RequestMsg, LogonContext);
554
555 PackageId = RequestMsg->CallAuthenticationPackage.Request.AuthenticationPackage;
556
557 /* Get the right authentication package */
558 Package = LsapGetAuthenticationPackage(PackageId);
559 if (Package == NULL)
560 {
561 TRACE("LsapGetAuthenticationPackage() failed to find a package\n");
562 return STATUS_NO_SUCH_PACKAGE;
563 }
564
565 if (RequestMsg->CallAuthenticationPackage.Request.SubmitBufferLength > 0)
566 {
567 LocalBuffer = RtlAllocateHeap(RtlGetProcessHeap(),
568 HEAP_ZERO_MEMORY,
569 RequestMsg->CallAuthenticationPackage.Request.SubmitBufferLength);
570 if (LocalBuffer == NULL)
571 {
572 return STATUS_INSUFFICIENT_RESOURCES;
573 }
574
575 Status = NtReadVirtualMemory(LogonContext->ClientProcessHandle,
576 RequestMsg->CallAuthenticationPackage.Request.ProtocolSubmitBuffer,
577 LocalBuffer,
578 RequestMsg->CallAuthenticationPackage.Request.SubmitBufferLength,
579 NULL);
580 if (!NT_SUCCESS(Status))
581 {
582 TRACE("NtReadVirtualMemory() failed (Status 0x%08lx)\n", Status);
583 RtlFreeHeap(RtlGetProcessHeap(), 0, LocalBuffer);
584 return Status;
585 }
586 }
587
588 Status = Package->LsaApCallPackage((PLSA_CLIENT_REQUEST)LogonContext,
589 LocalBuffer,
590 RequestMsg->CallAuthenticationPackage.Request.ProtocolSubmitBuffer,
591 RequestMsg->CallAuthenticationPackage.Request.SubmitBufferLength,
592 &RequestMsg->CallAuthenticationPackage.Reply.ProtocolReturnBuffer,
593 &RequestMsg->CallAuthenticationPackage.Reply.ReturnBufferLength,
594 &RequestMsg->CallAuthenticationPackage.Reply.ProtocolStatus);
595 if (!NT_SUCCESS(Status))
596 {
597 TRACE("Package->LsaApCallPackage() failed (Status 0x%08lx)\n", Status);
598 }
599
600 if (LocalBuffer != NULL)
601 RtlFreeHeap(RtlGetProcessHeap(), 0, LocalBuffer);
602
603 return Status;
604 }
605
606
607 static
608 NTSTATUS
609 LsapCopyLocalGroups(
610 IN PLSAP_LOGON_CONTEXT LogonContext,
611 IN PTOKEN_GROUPS ClientGroups,
612 IN ULONG ClientGroupsCount,
613 OUT PTOKEN_GROUPS *TokenGroups)
614 {
615 ULONG LocalGroupsLength = 0;
616 PTOKEN_GROUPS LocalGroups = NULL;
617 ULONG SidHeaderLength = 0;
618 PSID SidHeader = NULL;
619 PSID SrcSid, DstSid;
620 ULONG SidLength;
621 ULONG AllocatedSids = 0;
622 ULONG i;
623 NTSTATUS Status;
624
625 LocalGroupsLength = sizeof(TOKEN_GROUPS) +
626 (ClientGroupsCount - ANYSIZE_ARRAY) * sizeof(SID_AND_ATTRIBUTES);
627 LocalGroups = RtlAllocateHeap(RtlGetProcessHeap(),
628 HEAP_ZERO_MEMORY,
629 LocalGroupsLength);
630 if (LocalGroups == NULL)
631 {
632 TRACE("RtlAllocateHeap() failed\n");
633 return STATUS_INSUFFICIENT_RESOURCES;
634 }
635
636 Status = NtReadVirtualMemory(LogonContext->ClientProcessHandle,
637 ClientGroups,
638 LocalGroups,
639 LocalGroupsLength,
640 NULL);
641 if (!NT_SUCCESS(Status))
642 goto done;
643
644
645 SidHeaderLength = RtlLengthRequiredSid(0);
646 SidHeader = RtlAllocateHeap(RtlGetProcessHeap(),
647 HEAP_ZERO_MEMORY,
648 SidHeaderLength);
649 if (SidHeader == NULL)
650 {
651 Status = STATUS_INSUFFICIENT_RESOURCES;
652 goto done;
653 }
654
655 for (i = 0; i < ClientGroupsCount; i++)
656 {
657 SrcSid = LocalGroups->Groups[i].Sid;
658
659 Status = NtReadVirtualMemory(LogonContext->ClientProcessHandle,
660 SrcSid,
661 SidHeader,
662 SidHeaderLength,
663 NULL);
664 if (!NT_SUCCESS(Status))
665 goto done;
666
667 SidLength = RtlLengthSid(SidHeader);
668 TRACE("Sid %lu: Length %lu\n", i, SidLength);
669
670 DstSid = RtlAllocateHeap(RtlGetProcessHeap(),
671 HEAP_ZERO_MEMORY,
672 SidLength);
673 if (DstSid == NULL)
674 {
675 Status = STATUS_INSUFFICIENT_RESOURCES;
676 goto done;
677 }
678
679 Status = NtReadVirtualMemory(LogonContext->ClientProcessHandle,
680 SrcSid,
681 DstSid,
682 SidLength,
683 NULL);
684 if (!NT_SUCCESS(Status))
685 {
686 RtlFreeHeap(RtlGetProcessHeap(), 0, DstSid);
687 goto done;
688 }
689
690 LocalGroups->Groups[i].Sid = DstSid;
691 AllocatedSids++;
692 }
693
694 *TokenGroups = LocalGroups;
695
696 done:
697 if (SidHeader != NULL)
698 RtlFreeHeap(RtlGetProcessHeap(), 0, SidHeader);
699
700 if (!NT_SUCCESS(Status))
701 {
702 if (LocalGroups != NULL)
703 {
704 for (i = 0; i < AllocatedSids; i++)
705 RtlFreeHeap(RtlGetProcessHeap(), 0, LocalGroups->Groups[i].Sid);
706
707 RtlFreeHeap(RtlGetProcessHeap(), 0, LocalGroups);
708 }
709 }
710
711 return Status;
712 }
713
714
715 static
716 NTSTATUS
717 LsapAddLocalGroups(
718 IN PVOID TokenInformation,
719 IN LSA_TOKEN_INFORMATION_TYPE TokenInformationType,
720 IN PTOKEN_GROUPS LocalGroups)
721 {
722 PLSA_TOKEN_INFORMATION_V1 TokenInfo1;
723 PTOKEN_GROUPS Groups;
724 ULONG Length;
725 ULONG i;
726 ULONG j;
727
728 if (LocalGroups == NULL || LocalGroups->GroupCount == 0)
729 return STATUS_SUCCESS;
730
731 if (TokenInformationType == LsaTokenInformationV1)
732 {
733 TokenInfo1 = (PLSA_TOKEN_INFORMATION_V1)TokenInformation;
734
735 if (TokenInfo1->Groups != NULL)
736 {
737 Length = sizeof(TOKEN_GROUPS) +
738 (LocalGroups->GroupCount + TokenInfo1->Groups->GroupCount - ANYSIZE_ARRAY) * sizeof(SID_AND_ATTRIBUTES);
739
740 Groups = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, Length);
741 if (Groups == NULL)
742 {
743 ERR("Group buffer allocation failed!\n");
744 return STATUS_INSUFFICIENT_RESOURCES;
745 }
746
747 Groups->GroupCount = LocalGroups->GroupCount + TokenInfo1->Groups->GroupCount;
748
749 for (i = 0; i < TokenInfo1->Groups->GroupCount; i++)
750 {
751 Groups->Groups[i].Sid = TokenInfo1->Groups->Groups[i].Sid;
752 Groups->Groups[i].Attributes = TokenInfo1->Groups->Groups[i].Attributes;
753 }
754
755 for (j = 0; j < LocalGroups->GroupCount; i++, j++)
756 {
757 Groups->Groups[i].Sid = LocalGroups->Groups[j].Sid;
758 Groups->Groups[i].Attributes = LocalGroups->Groups[j].Attributes;
759 LocalGroups->Groups[j].Sid = NULL;
760 }
761
762 RtlFreeHeap(RtlGetProcessHeap(), 0, TokenInfo1->Groups);
763
764 TokenInfo1->Groups = Groups;
765 }
766 else
767 {
768 Length = sizeof(TOKEN_GROUPS) +
769 (LocalGroups->GroupCount - ANYSIZE_ARRAY) * sizeof(SID_AND_ATTRIBUTES);
770
771 Groups = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, Length);
772 if (Groups == NULL)
773 {
774 ERR("Group buffer allocation failed!\n");
775 return STATUS_INSUFFICIENT_RESOURCES;
776 }
777
778 Groups->GroupCount = LocalGroups->GroupCount;
779
780 for (i = 0; i < LocalGroups->GroupCount; i++)
781 {
782 Groups->Groups[i].Sid = LocalGroups->Groups[i].Sid;
783 Groups->Groups[i].Attributes = LocalGroups->Groups[i].Attributes;
784 }
785
786 TokenInfo1->Groups = Groups;
787 }
788 }
789 else
790 {
791 FIXME("TokenInformationType %d is not supported!\n", TokenInformationType);
792 return STATUS_NOT_IMPLEMENTED;
793 }
794
795 return STATUS_SUCCESS;
796 }
797
798 static
799 NTSTATUS
800 LsapAddDefaultGroups(
801 IN PVOID TokenInformation,
802 IN LSA_TOKEN_INFORMATION_TYPE TokenInformationType,
803 IN SECURITY_LOGON_TYPE LogonType)
804 {
805 PLSA_TOKEN_INFORMATION_V1 TokenInfo1;
806 PTOKEN_GROUPS Groups;
807 ULONG i, Length;
808 PSID SrcSid;
809
810 if (TokenInformationType == LsaTokenInformationV1)
811 {
812 TokenInfo1 = (PLSA_TOKEN_INFORMATION_V1)TokenInformation;
813
814 if (TokenInfo1->Groups != NULL)
815 {
816 Length = sizeof(TOKEN_GROUPS) +
817 (TokenInfo1->Groups->GroupCount + 2 - ANYSIZE_ARRAY) * sizeof(SID_AND_ATTRIBUTES);
818
819 Groups = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, Length);
820 if (Groups == NULL)
821 {
822 ERR("Group buffer allocation failed!\n");
823 return STATUS_INSUFFICIENT_RESOURCES;
824 }
825
826 Groups->GroupCount = TokenInfo1->Groups->GroupCount;
827
828 for (i = 0; i < TokenInfo1->Groups->GroupCount; i++)
829 {
830 Groups->Groups[i].Sid = TokenInfo1->Groups->Groups[i].Sid;
831 Groups->Groups[i].Attributes = TokenInfo1->Groups->Groups[i].Attributes;
832 }
833
834 RtlFreeHeap(RtlGetProcessHeap(), 0, TokenInfo1->Groups);
835
836 TokenInfo1->Groups = Groups;
837
838 }
839 else
840 {
841 Length = sizeof(TOKEN_GROUPS) +
842 (2 - ANYSIZE_ARRAY) * sizeof(SID_AND_ATTRIBUTES);
843
844 Groups = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, Length);
845 if (Groups == NULL)
846 {
847 ERR("Group buffer allocation failed!\n");
848 return STATUS_INSUFFICIENT_RESOURCES;
849 }
850
851 TokenInfo1->Groups = Groups;
852 }
853
854 /* Append the World SID (aka Everyone) */
855 Length = RtlLengthSid(LsapWorldSid);
856 Groups->Groups[Groups->GroupCount].Sid = RtlAllocateHeap(RtlGetProcessHeap(),
857 HEAP_ZERO_MEMORY,
858 Length);
859 if (Groups->Groups[Groups->GroupCount].Sid == NULL)
860 return STATUS_INSUFFICIENT_RESOURCES;
861
862 RtlCopyMemory(Groups->Groups[Groups->GroupCount].Sid,
863 LsapWorldSid,
864 Length);
865
866 Groups->Groups[Groups->GroupCount].Attributes =
867 SE_GROUP_ENABLED | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_MANDATORY;
868
869 Groups->GroupCount++;
870
871 /* Append the logon type SID */
872 switch (LogonType)
873 {
874 case Interactive:
875 SrcSid = LsapInteractiveSid;
876 break;
877
878 case Network:
879 SrcSid = LsapNetworkSid;
880 break;
881
882 case Batch:
883 SrcSid = LsapBatchSid;
884 break;
885
886 case Service:
887 SrcSid = LsapServiceSid;
888 break;
889
890 default:
891 FIXME("LogonType %d is not supported!\n", LogonType);
892 return STATUS_NOT_IMPLEMENTED;
893 }
894
895 Length = RtlLengthSid(SrcSid);
896 Groups->Groups[Groups->GroupCount].Sid = RtlAllocateHeap(RtlGetProcessHeap(),
897 HEAP_ZERO_MEMORY,
898 Length);
899 if (Groups->Groups[Groups->GroupCount].Sid == NULL)
900 return STATUS_INSUFFICIENT_RESOURCES;
901
902 RtlCopyMemory(Groups->Groups[Groups->GroupCount].Sid,
903 SrcSid,
904 Length);
905
906 Groups->Groups[Groups->GroupCount].Attributes =
907 SE_GROUP_ENABLED | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_MANDATORY;
908
909 Groups->GroupCount++;
910 }
911 else
912 {
913 FIXME("TokenInformationType %d is not supported!\n", TokenInformationType);
914 return STATUS_NOT_IMPLEMENTED;
915 }
916
917 return STATUS_SUCCESS;
918 }
919
920
921 static
922 NTSTATUS
923 LsapAppendSidToGroups(
924 IN PTOKEN_GROUPS *TokenGroups,
925 IN PSID DomainSid,
926 IN ULONG RelativeId)
927 {
928 PTOKEN_GROUPS Groups;
929 PSID Sid;
930 ULONG Length;
931 ULONG i;
932
933 Sid = LsapAppendRidToSid(DomainSid, RelativeId);
934 if (Sid == NULL)
935 {
936 ERR("Group SID creation failed!\n");
937 return STATUS_INSUFFICIENT_RESOURCES;
938 }
939
940 if (*TokenGroups == NULL)
941 {
942 Length = sizeof(TOKEN_GROUPS) +
943 (1 - ANYSIZE_ARRAY) * sizeof(SID_AND_ATTRIBUTES);
944
945 Groups = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, Length);
946 if (Groups == NULL)
947 {
948 ERR("Group buffer allocation failed!\n");
949 return STATUS_INSUFFICIENT_RESOURCES;
950 }
951
952 Groups->GroupCount = 1;
953
954 Groups->Groups[0].Sid = Sid;
955 Groups->Groups[0].Attributes =
956 SE_GROUP_ENABLED | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_MANDATORY;
957
958 *TokenGroups = Groups;
959 }
960 else
961 {
962 for (i = 0; i < (*TokenGroups)->GroupCount; i++)
963 {
964 if (RtlEqualSid((*TokenGroups)->Groups[i].Sid, Sid))
965 {
966 RtlFreeHeap(RtlGetProcessHeap(), 0, Sid);
967 return STATUS_SUCCESS;
968 }
969 }
970
971 Length = sizeof(TOKEN_GROUPS) +
972 ((*TokenGroups)->GroupCount + 1 - ANYSIZE_ARRAY) * sizeof(SID_AND_ATTRIBUTES);
973
974 Groups = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, Length);
975 if (Groups == NULL)
976 {
977 ERR("Group buffer allocation failed!\n");
978 return STATUS_INSUFFICIENT_RESOURCES;
979 }
980
981 Groups->GroupCount = (*TokenGroups)->GroupCount;
982
983 for (i = 0; i < (*TokenGroups)->GroupCount; i++)
984 {
985 Groups->Groups[i].Sid = (*TokenGroups)->Groups[i].Sid;
986 Groups->Groups[i].Attributes = (*TokenGroups)->Groups[i].Attributes;
987 }
988
989 Groups->Groups[Groups->GroupCount].Sid = Sid;
990 Groups->Groups[Groups->GroupCount].Attributes =
991 SE_GROUP_ENABLED | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_MANDATORY;
992
993 Groups->GroupCount++;
994
995 RtlFreeHeap(RtlGetProcessHeap(), 0, *TokenGroups);
996
997 *TokenGroups = Groups;
998 }
999
1000 return STATUS_SUCCESS;
1001 }
1002
1003
1004 static
1005 NTSTATUS
1006 LsapAddSamGroups(
1007 IN PVOID TokenInformation,
1008 IN LSA_TOKEN_INFORMATION_TYPE TokenInformationType)
1009 {
1010 PLSA_TOKEN_INFORMATION_V1 TokenInfo1;
1011 SAMPR_HANDLE ServerHandle = NULL;
1012 SAMPR_HANDLE BuiltinDomainHandle = NULL;
1013 SAMPR_HANDLE AccountDomainHandle = NULL;
1014 SAMPR_PSID_ARRAY SidArray;
1015 SAMPR_ULONG_ARRAY BuiltinMembership;
1016 SAMPR_ULONG_ARRAY AccountMembership;
1017 ULONG i;
1018 NTSTATUS Status = STATUS_SUCCESS;
1019
1020 if (TokenInformationType != LsaTokenInformationV1)
1021 return STATUS_SUCCESS;
1022
1023 TokenInfo1 = (PLSA_TOKEN_INFORMATION_V1)TokenInformation;
1024
1025 SidArray.Count = TokenInfo1->Groups->GroupCount + 1;
1026 SidArray.Sids = RtlAllocateHeap(RtlGetProcessHeap(),
1027 HEAP_ZERO_MEMORY,
1028 (TokenInfo1->Groups->GroupCount + 1) * sizeof(PRPC_SID));
1029 if (SidArray.Sids == NULL)
1030 return STATUS_INSUFFICIENT_RESOURCES;
1031
1032 SidArray.Sids[0].SidPointer = TokenInfo1->User.User.Sid;
1033 for (i = 0; i < TokenInfo1->Groups->GroupCount; i++)
1034 SidArray.Sids[i + 1].SidPointer = TokenInfo1->Groups->Groups[i].Sid;
1035
1036 BuiltinMembership.Element = NULL;
1037 AccountMembership.Element = NULL;
1038
1039 Status = SamIConnect(NULL,
1040 &ServerHandle,
1041 SAM_SERVER_CONNECT | SAM_SERVER_LOOKUP_DOMAIN,
1042 FALSE);
1043 if (!NT_SUCCESS(Status))
1044 {
1045 TRACE("SamIConnect failed (Status %08lx)\n", Status);
1046 goto done;
1047 }
1048
1049 Status = SamrOpenDomain(ServerHandle,
1050 DOMAIN_GET_ALIAS_MEMBERSHIP,
1051 BuiltinDomainSid,
1052 &BuiltinDomainHandle);
1053 if (!NT_SUCCESS(Status))
1054 {
1055 TRACE("SamrOpenDomain failed (Status %08lx)\n", Status);
1056 goto done;
1057 }
1058
1059 Status = SamrOpenDomain(ServerHandle,
1060 DOMAIN_GET_ALIAS_MEMBERSHIP,
1061 AccountDomainSid,
1062 &AccountDomainHandle);
1063 if (!NT_SUCCESS(Status))
1064 {
1065 TRACE("SamrOpenDomain failed (Status %08lx)\n", Status);
1066 goto done;
1067 }
1068
1069 Status = SamrGetAliasMembership(BuiltinDomainHandle,
1070 &SidArray,
1071 &BuiltinMembership);
1072 if (!NT_SUCCESS(Status))
1073 {
1074 TRACE("SamrGetAliasMembership failed (Status %08lx)\n", Status);
1075 goto done;
1076 }
1077
1078 Status = SamrGetAliasMembership(AccountDomainHandle,
1079 &SidArray,
1080 &AccountMembership);
1081 if (!NT_SUCCESS(Status))
1082 {
1083 TRACE("SamrGetAliasMembership failed (Status %08lx)\n", Status);
1084 goto done;
1085 }
1086
1087 TRACE("Builtin Memberships: %lu\n", BuiltinMembership.Count);
1088 for (i = 0; i < BuiltinMembership.Count; i++)
1089 {
1090 TRACE("RID %lu: %lu (0x%lx)\n", i, BuiltinMembership.Element[i], BuiltinMembership.Element[i]);
1091 Status = LsapAppendSidToGroups(&TokenInfo1->Groups,
1092 BuiltinDomainSid,
1093 BuiltinMembership.Element[i]);
1094 if (!NT_SUCCESS(Status))
1095 {
1096 TRACE("LsapAppendSidToGroups failed (Status %08lx)\n", Status);
1097 goto done;
1098 }
1099 }
1100
1101 TRACE("Account Memberships: %lu\n", AccountMembership.Count);
1102 for (i = 0; i < AccountMembership.Count; i++)
1103 {
1104 TRACE("RID %lu: %lu (0x%lx)\n", i, AccountMembership.Element[i], AccountMembership.Element[i]);
1105 Status = LsapAppendSidToGroups(&TokenInfo1->Groups,
1106 AccountDomainSid,
1107 AccountMembership.Element[i]);
1108 if (!NT_SUCCESS(Status))
1109 {
1110 TRACE("LsapAppendSidToGroups failed (Status %08lx)\n", Status);
1111 goto done;
1112 }
1113 }
1114
1115 done:
1116 RtlFreeHeap(RtlGetProcessHeap(), 0, SidArray.Sids);
1117
1118 if (AccountMembership.Element != NULL)
1119 SamIFree_SAMPR_ULONG_ARRAY(&AccountMembership);
1120
1121 if (BuiltinMembership.Element != NULL)
1122 SamIFree_SAMPR_ULONG_ARRAY(&BuiltinMembership);
1123
1124 if (AccountDomainHandle != NULL)
1125 SamrCloseHandle(&AccountDomainHandle);
1126
1127 if (BuiltinDomainHandle != NULL)
1128 SamrCloseHandle(&BuiltinDomainHandle);
1129
1130 if (ServerHandle != NULL)
1131 SamrCloseHandle(&ServerHandle);
1132
1133 // return Status;
1134
1135 return STATUS_SUCCESS;
1136 }
1137
1138
1139 static
1140 NTSTATUS
1141 LsapSetTokenOwner(
1142 IN PVOID TokenInformation,
1143 IN LSA_TOKEN_INFORMATION_TYPE TokenInformationType)
1144 {
1145 PLSA_TOKEN_INFORMATION_V1 TokenInfo1;
1146 PSID_AND_ATTRIBUTES OwnerSid = NULL;
1147 ULONG i, Length;
1148
1149 if (TokenInformationType == LsaTokenInformationV1)
1150 {
1151 TokenInfo1 = (PLSA_TOKEN_INFORMATION_V1)TokenInformation;
1152
1153 if (TokenInfo1->Owner.Owner != NULL)
1154 return STATUS_SUCCESS;
1155
1156 OwnerSid = &TokenInfo1->User.User;
1157 for (i = 0; i < TokenInfo1->Groups->GroupCount; i++)
1158 {
1159 if (EqualSid(TokenInfo1->Groups->Groups[i].Sid, LsapAdministratorsSid))
1160 {
1161 OwnerSid = &TokenInfo1->Groups->Groups[i];
1162 break;
1163 }
1164 }
1165
1166 Length = RtlLengthSid(OwnerSid->Sid);
1167 TokenInfo1->Owner.Owner = DispatchTable.AllocateLsaHeap(Length);
1168 if (TokenInfo1->Owner.Owner == NULL)
1169 return STATUS_INSUFFICIENT_RESOURCES;
1170
1171 RtlCopyMemory(TokenInfo1->Owner.Owner,
1172 OwnerSid->Sid,
1173 Length);
1174 OwnerSid->Attributes |= SE_GROUP_OWNER;
1175 }
1176
1177 return STATUS_SUCCESS;
1178 }
1179
1180
1181 static
1182 NTSTATUS
1183 LsapAddTokenDefaultDacl(
1184 IN PVOID TokenInformation,
1185 IN LSA_TOKEN_INFORMATION_TYPE TokenInformationType)
1186 {
1187 PLSA_TOKEN_INFORMATION_V1 TokenInfo1;
1188 PACL Dacl = NULL;
1189 ULONG Length;
1190
1191 if (TokenInformationType == LsaTokenInformationV1)
1192 {
1193 TokenInfo1 = (PLSA_TOKEN_INFORMATION_V1)TokenInformation;
1194
1195 if (TokenInfo1->DefaultDacl.DefaultDacl != NULL)
1196 return STATUS_SUCCESS;
1197
1198 Length = sizeof(ACL) +
1199 (2 * sizeof(ACCESS_ALLOWED_ACE)) +
1200 RtlLengthSid(TokenInfo1->Owner.Owner) +
1201 RtlLengthSid(LsapLocalSystemSid);
1202
1203 Dacl = DispatchTable.AllocateLsaHeap(Length);
1204 if (Dacl == NULL)
1205 return STATUS_INSUFFICIENT_RESOURCES;
1206
1207 RtlCreateAcl(Dacl, Length, ACL_REVISION);
1208
1209 RtlAddAccessAllowedAce(Dacl,
1210 ACL_REVISION,
1211 GENERIC_ALL,
1212 TokenInfo1->Owner.Owner);
1213
1214 /* SID: S-1-5-18 */
1215 RtlAddAccessAllowedAce(Dacl,
1216 ACL_REVISION,
1217 GENERIC_ALL,
1218 LsapLocalSystemSid);
1219
1220 TokenInfo1->DefaultDacl.DefaultDacl = Dacl;
1221 }
1222
1223 return STATUS_SUCCESS;
1224 }
1225
1226
1227 static
1228 NTSTATUS
1229 LsapAddPrivilegeToTokenPrivileges(PTOKEN_PRIVILEGES *TokenPrivileges,
1230 PLSAPR_LUID_AND_ATTRIBUTES Privilege)
1231 {
1232 PTOKEN_PRIVILEGES LocalPrivileges;
1233 ULONG Length, TokenPrivilegeCount, i;
1234 NTSTATUS Status = STATUS_SUCCESS;
1235
1236 if (*TokenPrivileges == NULL)
1237 {
1238 Length = sizeof(TOKEN_PRIVILEGES) +
1239 (1 - ANYSIZE_ARRAY) * sizeof(LUID_AND_ATTRIBUTES);
1240 LocalPrivileges = RtlAllocateHeap(RtlGetProcessHeap(),
1241 0,
1242 Length);
1243 if (LocalPrivileges == NULL)
1244 return STATUS_INSUFFICIENT_RESOURCES;
1245
1246 LocalPrivileges->PrivilegeCount = 1;
1247 LocalPrivileges->Privileges[0].Luid = Privilege->Luid;
1248 LocalPrivileges->Privileges[0].Attributes = Privilege->Attributes;
1249 }
1250 else
1251 {
1252 TokenPrivilegeCount = (*TokenPrivileges)->PrivilegeCount;
1253
1254 for (i = 0; i < TokenPrivilegeCount; i++)
1255 {
1256 if (RtlEqualLuid(&(*TokenPrivileges)->Privileges[i].Luid, &Privilege->Luid))
1257 return STATUS_SUCCESS;
1258 }
1259
1260 Length = sizeof(TOKEN_PRIVILEGES) +
1261 (TokenPrivilegeCount + 1 - ANYSIZE_ARRAY) * sizeof(LUID_AND_ATTRIBUTES);
1262 LocalPrivileges = RtlAllocateHeap(RtlGetProcessHeap(),
1263 0,
1264 Length);
1265 if (LocalPrivileges == NULL)
1266 return STATUS_INSUFFICIENT_RESOURCES;
1267
1268 LocalPrivileges->PrivilegeCount = TokenPrivilegeCount + 1;
1269 for (i = 0; i < TokenPrivilegeCount; i++)
1270 {
1271 LocalPrivileges->Privileges[i].Luid = (*TokenPrivileges)->Privileges[i].Luid;
1272 LocalPrivileges->Privileges[i].Attributes = (*TokenPrivileges)->Privileges[i].Attributes;
1273 }
1274
1275 LocalPrivileges->Privileges[TokenPrivilegeCount].Luid = Privilege->Luid;
1276 LocalPrivileges->Privileges[TokenPrivilegeCount].Attributes = Privilege->Attributes;
1277
1278 RtlFreeHeap(RtlGetProcessHeap(), 0, *TokenPrivileges);
1279 }
1280
1281 *TokenPrivileges = LocalPrivileges;
1282
1283 return Status;
1284 }
1285
1286 static
1287 NTSTATUS
1288 LsapSetPrivileges(
1289 IN PVOID TokenInformation,
1290 IN LSA_TOKEN_INFORMATION_TYPE TokenInformationType)
1291 {
1292 PLSA_TOKEN_INFORMATION_V1 TokenInfo1;
1293 LSAPR_HANDLE PolicyHandle = NULL;
1294 LSAPR_HANDLE AccountHandle = NULL;
1295 PLSAPR_PRIVILEGE_SET Privileges = NULL;
1296 ULONG i, j;
1297 NTSTATUS Status;
1298
1299 if (TokenInformationType == LsaTokenInformationV1)
1300 {
1301 TokenInfo1 = (PLSA_TOKEN_INFORMATION_V1)TokenInformation;
1302
1303 Status = LsarOpenPolicy(NULL,
1304 NULL,
1305 0,
1306 &PolicyHandle);
1307 if (!NT_SUCCESS(Status))
1308 return Status;
1309
1310 for (i = 0; i < TokenInfo1->Groups->GroupCount; i++)
1311 {
1312 Status = LsarOpenAccount(PolicyHandle,
1313 TokenInfo1->Groups->Groups[i].Sid,
1314 ACCOUNT_VIEW,
1315 &AccountHandle);
1316 if (!NT_SUCCESS(Status))
1317 continue;
1318
1319 Status = LsarEnumeratePrivilegesAccount(AccountHandle,
1320 &Privileges);
1321 if (NT_SUCCESS(Status))
1322 {
1323 for (j = 0; j < Privileges->PrivilegeCount; j++)
1324 {
1325 Status = LsapAddPrivilegeToTokenPrivileges(&TokenInfo1->Privileges,
1326 &(Privileges->Privilege[j]));
1327 if (!NT_SUCCESS(Status))
1328 {
1329 /* We failed, clean everything and return */
1330 LsaIFree_LSAPR_PRIVILEGE_SET(Privileges);
1331 LsarClose(&AccountHandle);
1332 LsarClose(&PolicyHandle);
1333
1334 return Status;
1335 }
1336 }
1337
1338 LsaIFree_LSAPR_PRIVILEGE_SET(Privileges);
1339 Privileges = NULL;
1340 }
1341
1342 LsarClose(&AccountHandle);
1343 }
1344
1345 LsarClose(&PolicyHandle);
1346
1347 if (TokenInfo1->Privileges != NULL)
1348 {
1349 for (i = 0; i < TokenInfo1->Privileges->PrivilegeCount; i++)
1350 {
1351 if (RtlEqualLuid(&TokenInfo1->Privileges->Privileges[i].Luid, &SeChangeNotifyPrivilege) ||
1352 RtlEqualLuid(&TokenInfo1->Privileges->Privileges[i].Luid, &SeCreateGlobalPrivilege) ||
1353 RtlEqualLuid(&TokenInfo1->Privileges->Privileges[i].Luid, &SeImpersonatePrivilege))
1354 {
1355 TokenInfo1->Privileges->Privileges[i].Attributes |= SE_PRIVILEGE_ENABLED | SE_PRIVILEGE_ENABLED_BY_DEFAULT;
1356 }
1357 }
1358 }
1359 }
1360
1361 return STATUS_SUCCESS;
1362 }
1363
1364
1365 NTSTATUS
1366 LsapLogonUser(PLSA_API_MSG RequestMsg,
1367 PLSAP_LOGON_CONTEXT LogonContext)
1368 {
1369 PAUTH_PACKAGE Package;
1370 OBJECT_ATTRIBUTES ObjectAttributes;
1371 SECURITY_QUALITY_OF_SERVICE Qos;
1372 LSA_TOKEN_INFORMATION_TYPE TokenInformationType;
1373 PVOID TokenInformation = NULL;
1374 PLSA_TOKEN_INFORMATION_NULL TokenInfo0 = NULL;
1375 PLSA_TOKEN_INFORMATION_V1 TokenInfo1 = NULL;
1376 PUNICODE_STRING AccountName = NULL;
1377 PUNICODE_STRING AuthenticatingAuthority = NULL;
1378 PUNICODE_STRING MachineName = NULL;
1379 PVOID LocalAuthInfo = NULL;
1380 PTOKEN_GROUPS LocalGroups = NULL;
1381 HANDLE TokenHandle = NULL;
1382 ULONG i;
1383 ULONG PackageId;
1384 SECURITY_LOGON_TYPE LogonType;
1385 NTSTATUS Status;
1386
1387 PUNICODE_STRING UserName = NULL;
1388 PUNICODE_STRING LogonDomainName = NULL;
1389 // UNICODE_STRING LogonServer;
1390
1391
1392 TRACE("LsapLogonUser(%p %p)\n", RequestMsg, LogonContext);
1393
1394 PackageId = RequestMsg->LogonUser.Request.AuthenticationPackage;
1395 LogonType = RequestMsg->LogonUser.Request.LogonType;
1396
1397 /* Get the right authentication package */
1398 Package = LsapGetAuthenticationPackage(PackageId);
1399 if (Package == NULL)
1400 {
1401 ERR("LsapGetAuthenticationPackage() failed to find a package\n");
1402 return STATUS_NO_SUCH_PACKAGE;
1403 }
1404
1405 if (RequestMsg->LogonUser.Request.AuthenticationInformationLength > 0)
1406 {
1407 /* Allocate the local authentication info buffer */
1408 LocalAuthInfo = RtlAllocateHeap(RtlGetProcessHeap(),
1409 HEAP_ZERO_MEMORY,
1410 RequestMsg->LogonUser.Request.AuthenticationInformationLength);
1411 if (LocalAuthInfo == NULL)
1412 {
1413 ERR("RtlAllocateHeap() failed\n");
1414 return STATUS_INSUFFICIENT_RESOURCES;
1415 }
1416
1417 /* Read the authentication info from the callers address space */
1418 Status = NtReadVirtualMemory(LogonContext->ClientProcessHandle,
1419 RequestMsg->LogonUser.Request.AuthenticationInformation,
1420 LocalAuthInfo,
1421 RequestMsg->LogonUser.Request.AuthenticationInformationLength,
1422 NULL);
1423 if (!NT_SUCCESS(Status))
1424 {
1425 ERR("NtReadVirtualMemory() failed (Status 0x%08lx)\n", Status);
1426 RtlFreeHeap(RtlGetProcessHeap(), 0, LocalAuthInfo);
1427 return Status;
1428 }
1429 }
1430
1431 if (RequestMsg->LogonUser.Request.LocalGroupsCount > 0)
1432 {
1433 Status = LsapCopyLocalGroups(LogonContext,
1434 RequestMsg->LogonUser.Request.LocalGroups,
1435 RequestMsg->LogonUser.Request.LocalGroupsCount,
1436 &LocalGroups);
1437 if (!NT_SUCCESS(Status))
1438 {
1439 ERR("LsapCopyLocalGroups failed (Status 0x%08lx)\n", Status);
1440 goto done;
1441 }
1442
1443 TRACE("GroupCount: %lu\n", LocalGroups->GroupCount);
1444 }
1445
1446 if (Package->LsaApLogonUserEx2 != NULL)
1447 {
1448 Status = Package->LsaApLogonUserEx2((PLSA_CLIENT_REQUEST)LogonContext,
1449 RequestMsg->LogonUser.Request.LogonType,
1450 LocalAuthInfo,
1451 RequestMsg->LogonUser.Request.AuthenticationInformation,
1452 RequestMsg->LogonUser.Request.AuthenticationInformationLength,
1453 &RequestMsg->LogonUser.Reply.ProfileBuffer,
1454 &RequestMsg->LogonUser.Reply.ProfileBufferLength,
1455 &RequestMsg->LogonUser.Reply.LogonId,
1456 &RequestMsg->LogonUser.Reply.SubStatus,
1457 &TokenInformationType,
1458 &TokenInformation,
1459 &AccountName,
1460 &AuthenticatingAuthority,
1461 &MachineName,
1462 NULL, /* FIXME: PSECPKG_PRIMARY_CRED PrimaryCredentials */
1463 NULL); /* FIXME: PSECPKG_SUPPLEMENTAL_CRED_ARRAY *SupplementalCredentials */
1464 }
1465 else if (Package->LsaApLogonUserEx != NULL)
1466 {
1467 Status = Package->LsaApLogonUserEx((PLSA_CLIENT_REQUEST)LogonContext,
1468 RequestMsg->LogonUser.Request.LogonType,
1469 LocalAuthInfo,
1470 RequestMsg->LogonUser.Request.AuthenticationInformation,
1471 RequestMsg->LogonUser.Request.AuthenticationInformationLength,
1472 &RequestMsg->LogonUser.Reply.ProfileBuffer,
1473 &RequestMsg->LogonUser.Reply.ProfileBufferLength,
1474 &RequestMsg->LogonUser.Reply.LogonId,
1475 &RequestMsg->LogonUser.Reply.SubStatus,
1476 &TokenInformationType,
1477 &TokenInformation,
1478 &AccountName,
1479 &AuthenticatingAuthority,
1480 &MachineName);
1481 }
1482 else
1483 {
1484 Status = Package->LsaApLogonUser((PLSA_CLIENT_REQUEST)LogonContext,
1485 RequestMsg->LogonUser.Request.LogonType,
1486 LocalAuthInfo,
1487 RequestMsg->LogonUser.Request.AuthenticationInformation,
1488 RequestMsg->LogonUser.Request.AuthenticationInformationLength,
1489 &RequestMsg->LogonUser.Reply.ProfileBuffer,
1490 &RequestMsg->LogonUser.Reply.ProfileBufferLength,
1491 &RequestMsg->LogonUser.Reply.LogonId,
1492 &RequestMsg->LogonUser.Reply.SubStatus,
1493 &TokenInformationType,
1494 &TokenInformation,
1495 &AccountName,
1496 &AuthenticatingAuthority);
1497 }
1498
1499 if (!NT_SUCCESS(Status))
1500 {
1501 ERR("LsaApLogonUser/Ex/2 failed (Status 0x%08lx)\n", Status);
1502 goto done;
1503 }
1504
1505 if (LocalGroups->GroupCount > 0)
1506 {
1507 /* Add local groups to the token information */
1508 Status = LsapAddLocalGroups(TokenInformation,
1509 TokenInformationType,
1510 LocalGroups);
1511 if (!NT_SUCCESS(Status))
1512 {
1513 ERR("LsapAddLocalGroupsToTokenInfo() failed (Status 0x%08lx)\n", Status);
1514 goto done;
1515 }
1516 }
1517
1518 Status = LsapAddDefaultGroups(TokenInformation,
1519 TokenInformationType,
1520 LogonType);
1521 if (!NT_SUCCESS(Status))
1522 {
1523 ERR("LsapAddDefaultGroups() failed (Status 0x%08lx)\n", Status);
1524 goto done;
1525 }
1526
1527 Status = LsapAddSamGroups(TokenInformation,
1528 TokenInformationType);
1529 if (!NT_SUCCESS(Status))
1530 {
1531 ERR("LsapAddSamGroups() failed (Status 0x%08lx)\n", Status);
1532 goto done;
1533 }
1534
1535 Status = LsapSetTokenOwner(TokenInformation,
1536 TokenInformationType);
1537 if (!NT_SUCCESS(Status))
1538 {
1539 ERR("LsapSetTokenOwner() failed (Status 0x%08lx)\n", Status);
1540 goto done;
1541 }
1542
1543 Status = LsapAddTokenDefaultDacl(TokenInformation,
1544 TokenInformationType);
1545 if (!NT_SUCCESS(Status))
1546 {
1547 ERR("LsapAddTokenDefaultDacl() failed (Status 0x%08lx)\n", Status);
1548 goto done;
1549 }
1550
1551 Status = LsapSetPrivileges(TokenInformation,
1552 TokenInformationType);
1553 if (!NT_SUCCESS(Status))
1554 {
1555 ERR("LsapSetPrivileges() failed (Status 0x%08lx)\n", Status);
1556 goto done;
1557 }
1558
1559 if (TokenInformationType == LsaTokenInformationNull)
1560 {
1561 TOKEN_USER TokenUser;
1562 TOKEN_PRIMARY_GROUP TokenPrimaryGroup;
1563 TOKEN_GROUPS NoGroups = {0};
1564 TOKEN_PRIVILEGES NoPrivileges = {0};
1565
1566 TokenInfo0 = (PLSA_TOKEN_INFORMATION_NULL)TokenInformation;
1567
1568 TokenUser.User.Sid = LsapWorldSid;
1569 TokenUser.User.Attributes = 0;
1570 TokenPrimaryGroup.PrimaryGroup = LsapWorldSid;
1571
1572 Qos.Length = sizeof(SECURITY_QUALITY_OF_SERVICE);
1573 Qos.ImpersonationLevel = SecurityImpersonation;
1574 Qos.ContextTrackingMode = SECURITY_STATIC_TRACKING;
1575 Qos.EffectiveOnly = TRUE;
1576
1577 ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES);
1578 ObjectAttributes.RootDirectory = NULL;
1579 ObjectAttributes.ObjectName = NULL;
1580 ObjectAttributes.Attributes = 0;
1581 ObjectAttributes.SecurityDescriptor = NULL;
1582 ObjectAttributes.SecurityQualityOfService = &Qos;
1583
1584 /* Create the logon token */
1585 Status = NtCreateToken(&TokenHandle,
1586 TOKEN_ALL_ACCESS,
1587 &ObjectAttributes,
1588 TokenImpersonation,
1589 &RequestMsg->LogonUser.Reply.LogonId,
1590 &TokenInfo0->ExpirationTime,
1591 &TokenUser,
1592 &NoGroups,
1593 &NoPrivileges,
1594 NULL,
1595 &TokenPrimaryGroup,
1596 NULL,
1597 &RequestMsg->LogonUser.Request.SourceContext);
1598 }
1599 else if (TokenInformationType == LsaTokenInformationV1)
1600 {
1601 TOKEN_PRIVILEGES NoPrivileges = {0};
1602
1603 TokenInfo1 = (PLSA_TOKEN_INFORMATION_V1)TokenInformation;
1604
1605 Qos.Length = sizeof(SECURITY_QUALITY_OF_SERVICE);
1606 Qos.ImpersonationLevel = SecurityImpersonation;
1607 Qos.ContextTrackingMode = SECURITY_DYNAMIC_TRACKING;
1608 Qos.EffectiveOnly = FALSE;
1609
1610 ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES);
1611 ObjectAttributes.RootDirectory = NULL;
1612 ObjectAttributes.ObjectName = NULL;
1613 ObjectAttributes.Attributes = 0;
1614 ObjectAttributes.SecurityDescriptor = NULL;
1615 ObjectAttributes.SecurityQualityOfService = &Qos;
1616
1617 /* Create the logon token */
1618 Status = NtCreateToken(&TokenHandle,
1619 TOKEN_ALL_ACCESS,
1620 &ObjectAttributes,
1621 (RequestMsg->LogonUser.Request.LogonType == Network) ? TokenImpersonation : TokenPrimary,
1622 &RequestMsg->LogonUser.Reply.LogonId,
1623 &TokenInfo1->ExpirationTime,
1624 &TokenInfo1->User,
1625 TokenInfo1->Groups,
1626 TokenInfo1->Privileges ? TokenInfo1->Privileges : &NoPrivileges,
1627 &TokenInfo1->Owner,
1628 &TokenInfo1->PrimaryGroup,
1629 &TokenInfo1->DefaultDacl,
1630 &RequestMsg->LogonUser.Request.SourceContext);
1631 if (!NT_SUCCESS(Status))
1632 {
1633 ERR("NtCreateToken failed (Status 0x%08lx)\n", Status);
1634 goto done;
1635 }
1636 }
1637 else
1638 {
1639 FIXME("TokenInformationType %d is not supported!\n", TokenInformationType);
1640 Status = STATUS_NOT_IMPLEMENTED;
1641 goto done;
1642 }
1643
1644 if (LogonType == Interactive ||
1645 LogonType == Batch ||
1646 LogonType == Service)
1647 {
1648 UserName = &((PMSV1_0_INTERACTIVE_LOGON)LocalAuthInfo)->UserName;
1649 LogonDomainName = &((PMSV1_0_INTERACTIVE_LOGON)LocalAuthInfo)->LogonDomainName;
1650 }
1651 else
1652 {
1653 FIXME("LogonType %lu is not supported yet!\n", LogonType);
1654 }
1655
1656 Status = LsapSetLogonSessionData(&RequestMsg->LogonUser.Reply.LogonId,
1657 LogonType,
1658 UserName,
1659 LogonDomainName,
1660 TokenInfo1->User.User.Sid);
1661 if (!NT_SUCCESS(Status))
1662 {
1663 ERR("LsapSetLogonSessionData failed (Status 0x%08lx)\n", Status);
1664 goto done;
1665 }
1666
1667 /*
1668 * Duplicate the token handle into the client process.
1669 * This must be the last step because we cannot
1670 * close the duplicated token handle in case something fails.
1671 */
1672 Status = NtDuplicateObject(NtCurrentProcess(),
1673 TokenHandle,
1674 LogonContext->ClientProcessHandle,
1675 &RequestMsg->LogonUser.Reply.Token,
1676 0,
1677 0,
1678 DUPLICATE_SAME_ACCESS | DUPLICATE_SAME_ATTRIBUTES | DUPLICATE_CLOSE_SOURCE);
1679 if (!NT_SUCCESS(Status))
1680 {
1681 ERR("NtDuplicateObject failed (Status 0x%08lx)\n", Status);
1682 goto done;
1683 }
1684
1685 done:
1686 if (!NT_SUCCESS(Status))
1687 {
1688 /* Notify the authentification package of the failure */
1689 Package->LsaApLogonTerminated(&RequestMsg->LogonUser.Reply.LogonId);
1690
1691 /* Delete the logon session */
1692 LsapDeleteLogonSession(&RequestMsg->LogonUser.Reply.LogonId);
1693
1694 /* Release the profile buffer */
1695 LsapFreeClientBuffer((PLSA_CLIENT_REQUEST)LogonContext,
1696 RequestMsg->LogonUser.Reply.ProfileBuffer);
1697 RequestMsg->LogonUser.Reply.ProfileBuffer = NULL;
1698 }
1699
1700 if (TokenHandle != NULL)
1701 NtClose(TokenHandle);
1702
1703 /* Free the local groups */
1704 if (LocalGroups != NULL)
1705 {
1706 for (i = 0; i < LocalGroups->GroupCount; i++)
1707 {
1708 if (LocalGroups->Groups[i].Sid != NULL)
1709 RtlFreeHeap(RtlGetProcessHeap(), 0, LocalGroups->Groups[i].Sid);
1710 }
1711
1712 RtlFreeHeap(RtlGetProcessHeap(), 0, LocalGroups);
1713 }
1714
1715 /* Free the local authentication info buffer */
1716 if (LocalAuthInfo != NULL)
1717 RtlFreeHeap(RtlGetProcessHeap(), 0, LocalAuthInfo);
1718
1719 /* Free the token information */
1720 if (TokenInformation != NULL)
1721 {
1722 if (TokenInformationType == LsaTokenInformationNull)
1723 {
1724 TokenInfo0 = (PLSA_TOKEN_INFORMATION_NULL)TokenInformation;
1725
1726 if (TokenInfo0 != NULL)
1727 {
1728 if (TokenInfo0->Groups != NULL)
1729 {
1730 for (i = 0; i < TokenInfo0->Groups->GroupCount; i++)
1731 {
1732 if (TokenInfo0->Groups->Groups[i].Sid != NULL)
1733 LsapFreeHeap(TokenInfo0->Groups->Groups[i].Sid);
1734 }
1735
1736 LsapFreeHeap(TokenInfo0->Groups);
1737 }
1738
1739 LsapFreeHeap(TokenInfo0);
1740 }
1741 }
1742 else if (TokenInformationType == LsaTokenInformationV1)
1743 {
1744 TokenInfo1 = (PLSA_TOKEN_INFORMATION_V1)TokenInformation;
1745
1746 if (TokenInfo1 != NULL)
1747 {
1748 if (TokenInfo1->User.User.Sid != NULL)
1749 LsapFreeHeap(TokenInfo1->User.User.Sid);
1750
1751 if (TokenInfo1->Groups != NULL)
1752 {
1753 for (i = 0; i < TokenInfo1->Groups->GroupCount; i++)
1754 {
1755 if (TokenInfo1->Groups->Groups[i].Sid != NULL)
1756 LsapFreeHeap(TokenInfo1->Groups->Groups[i].Sid);
1757 }
1758
1759 LsapFreeHeap(TokenInfo1->Groups);
1760 }
1761
1762 if (TokenInfo1->PrimaryGroup.PrimaryGroup != NULL)
1763 LsapFreeHeap(TokenInfo1->PrimaryGroup.PrimaryGroup);
1764
1765 if (TokenInfo1->Privileges != NULL)
1766 LsapFreeHeap(TokenInfo1->Privileges);
1767
1768 if (TokenInfo1->Owner.Owner != NULL)
1769 LsapFreeHeap(TokenInfo1->Owner.Owner);
1770
1771 if (TokenInfo1->DefaultDacl.DefaultDacl != NULL)
1772 LsapFreeHeap(TokenInfo1->DefaultDacl.DefaultDacl);
1773
1774 LsapFreeHeap(TokenInfo1);
1775 }
1776 }
1777 else
1778 {
1779 FIXME("TokenInformationType %d is not supported!\n", TokenInformationType);
1780 }
1781 }
1782
1783 /* Free the account name */
1784 if (AccountName != NULL)
1785 {
1786 if (AccountName->Buffer != NULL)
1787 LsapFreeHeap(AccountName->Buffer);
1788
1789 LsapFreeHeap(AccountName);
1790 }
1791
1792 /* Free the authentication authority */
1793 if (AuthenticatingAuthority != NULL)
1794 {
1795 if (AuthenticatingAuthority != NULL)
1796 LsapFreeHeap(AuthenticatingAuthority->Buffer);
1797
1798 LsapFreeHeap(AuthenticatingAuthority);
1799 }
1800
1801 /* Free the machine name */
1802 if (MachineName != NULL)
1803 {
1804 if (MachineName->Buffer != NULL)
1805 LsapFreeHeap(MachineName->Buffer);
1806
1807 LsapFreeHeap(MachineName);
1808 }
1809
1810 TRACE("LsapLogonUser done (Status 0x%08lx)\n", Status);
1811
1812 return Status;
1813 }
1814
1815 /* EOF */