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