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: Authenticaton package management routines
6 * COPYRIGHT: Copyright 2013 Eric Kohl
11 typedef enum _LSA_TOKEN_INFORMATION_TYPE
13 LsaTokenInformationNull
,
15 } LSA_TOKEN_INFORMATION_TYPE
, *PLSA_TOKEN_INFORMATION_TYPE
;
17 typedef struct _LSA_TOKEN_INFORMATION_V1
19 LARGE_INTEGER ExpirationTime
;
22 TOKEN_PRIMARY_GROUP PrimaryGroup
;
23 PTOKEN_PRIVILEGES Privileges
;
25 TOKEN_DEFAULT_DACL DefaultDacl
;
26 } LSA_TOKEN_INFORMATION_V1
, *PLSA_TOKEN_INFORMATION_V1
;
28 typedef PVOID PLSA_CLIENT_REQUEST
;
30 typedef NTSTATUS (NTAPI
*PLSA_CREATE_LOGON_SESSION
)(PLUID
);
31 typedef NTSTATUS (NTAPI
*PLSA_DELETE_LOGON_SESSION
)(PLUID
);
33 typedef PVOID (NTAPI
*PLSA_ALLOCATE_LSA_HEAP
)(ULONG
);
34 typedef VOID (NTAPI
*PLSA_FREE_LSA_HEAP
)(PVOID
);
35 typedef NTSTATUS (NTAPI
*PLSA_ALLOCATE_CLIENT_BUFFER
)(PLSA_CLIENT_REQUEST
, ULONG
, PVOID
*);
36 typedef NTSTATUS (NTAPI
*PLSA_FREE_CLIENT_BUFFER
)(PLSA_CLIENT_REQUEST
, PVOID
);
37 typedef NTSTATUS (NTAPI
*PLSA_COPY_TO_CLIENT_BUFFER
)(PLSA_CLIENT_REQUEST
, ULONG
,
39 typedef NTSTATUS (NTAPI
*PLSA_COPY_FROM_CLIENT_BUFFER
)(PLSA_CLIENT_REQUEST
,
42 typedef struct LSA_DISPATCH_TABLE
44 PLSA_CREATE_LOGON_SESSION CreateLogonSession
;
45 PLSA_DELETE_LOGON_SESSION DeleteLogonSession
;
46 PVOID
/*PLSA_ADD_CREDENTIAL */ AddCredential
;
47 PVOID
/*PLSA_GET_CREDENTIALS */ GetCredentials
;
48 PVOID
/*PLSA_DELETE_CREDENTIAL */ DeleteCredential
;
49 PLSA_ALLOCATE_LSA_HEAP AllocateLsaHeap
;
50 PLSA_FREE_LSA_HEAP FreeLsaHeap
;
51 PLSA_ALLOCATE_CLIENT_BUFFER AllocateClientBuffer
;
52 PLSA_FREE_CLIENT_BUFFER FreeClientBuffer
;
53 PLSA_COPY_TO_CLIENT_BUFFER CopyToClientBuffer
;
54 PLSA_COPY_FROM_CLIENT_BUFFER CopyFromClientBuffer
;
55 } LSA_DISPATCH_TABLE
, *PLSA_DISPATCH_TABLE
;
58 typedef NTSTATUS (NTAPI
*PLSA_AP_INITIALIZE_PACKAGE
)(ULONG
, PLSA_DISPATCH_TABLE
,
59 PLSA_STRING
, PLSA_STRING
, PLSA_STRING
*);
60 typedef NTSTATUS (NTAPI
*PLSA_AP_CALL_PACKAGE_INTERNAL
)(PLSA_CLIENT_REQUEST
, PVOID
, PVOID
,
61 ULONG
, PVOID
*, PULONG
, PNTSTATUS
);
62 typedef NTSTATUS (NTAPI
*PLSA_AP_CALL_PACKAGE_PASSTHROUGH
)(PLSA_CLIENT_REQUEST
,
63 PVOID
, PVOID
, ULONG
, PVOID
*, PULONG
, PNTSTATUS
);
64 typedef NTSTATUS (NTAPI
*PLSA_AP_CALL_PACKAGE_UNTRUSTED
)(PLSA_CLIENT_REQUEST
,
65 PVOID
, PVOID
, ULONG
, PVOID
*, PULONG
, PNTSTATUS
);
66 typedef VOID (NTAPI
*PLSA_AP_LOGON_TERMINATED
)(PLUID
);
67 typedef NTSTATUS (NTAPI
*PLSA_AP_LOGON_USER_EX2
)(PLSA_CLIENT_REQUEST
,
68 SECURITY_LOGON_TYPE
, PVOID
, PVOID
, ULONG
, PVOID
*, PULONG
, PLUID
, PNTSTATUS
,
69 PLSA_TOKEN_INFORMATION_TYPE
, PVOID
*, PUNICODE_STRING
*, PUNICODE_STRING
*,
70 PUNICODE_STRING
*, PVOID
/*PSECPKG_PRIMARY_CRED*/, PVOID
/*PSECPKG_SUPPLEMENTAL_CRED_ARRAY **/);
71 typedef NTSTATUS (NTAPI
*PLSA_AP_LOGON_USER_EX
)(PLSA_CLIENT_REQUEST
,
72 SECURITY_LOGON_TYPE
, PVOID
, PVOID
, ULONG
, PVOID
*, PULONG
, PLUID
, PNTSTATUS
,
73 PLSA_TOKEN_INFORMATION_TYPE
, PVOID
*, PUNICODE_STRING
*, PUNICODE_STRING
*,
76 typedef NTSTATUS (NTAPI
*PLSA_AP_LOGON_USER_INTERNAL
)(PLSA_CLIENT_REQUEST
, SECURITY_LOGON_TYPE
,
77 PVOID
, PVOID
, ULONG
, PVOID
*, PULONG
, PLUID
, PNTSTATUS
, PLSA_TOKEN_INFORMATION_TYPE
,
78 PVOID
*, PUNICODE_STRING
*, PUNICODE_STRING
*);
80 typedef struct _AUTH_PACKAGE
87 PLSA_AP_INITIALIZE_PACKAGE LsaApInitializePackage
;
88 PLSA_AP_CALL_PACKAGE_INTERNAL LsaApCallPackage
;
89 PLSA_AP_CALL_PACKAGE_PASSTHROUGH LsaApCallPackagePassthrough
;
90 PLSA_AP_CALL_PACKAGE_UNTRUSTED LsaApCallPackageUntrusted
;
91 PLSA_AP_LOGON_TERMINATED LsaApLogonTerminated
;
92 PLSA_AP_LOGON_USER_EX2 LsaApLogonUserEx2
;
93 PLSA_AP_LOGON_USER_EX LsaApLogonUserEx
;
94 PLSA_AP_LOGON_USER_INTERNAL LsaApLogonUser
;
95 } AUTH_PACKAGE
, *PAUTH_PACKAGE
;
98 /* GLOBALS *****************************************************************/
100 static LIST_ENTRY PackageListHead
;
101 static ULONG PackageId
;
102 static LSA_DISPATCH_TABLE DispatchTable
;
105 /* FUNCTIONS ***************************************************************/
110 LsapAddAuthPackage(IN PWSTR ValueName
,
113 IN ULONG ValueLength
,
115 IN PVOID EntryContext
)
117 PAUTH_PACKAGE Package
= NULL
;
118 UNICODE_STRING PackageName
;
121 NTSTATUS Status
= STATUS_SUCCESS
;
123 TRACE("LsapAddAuthPackage()\n");
125 PackageName
.Length
= (USHORT
)ValueLength
- sizeof(WCHAR
);
126 PackageName
.MaximumLength
= (USHORT
)ValueLength
;
127 PackageName
.Buffer
= ValueData
;
129 Id
= (PULONG
)Context
;
131 Package
= RtlAllocateHeap(RtlGetProcessHeap(),
133 sizeof(AUTH_PACKAGE
));
135 return STATUS_INSUFFICIENT_RESOURCES
;
137 Status
= LdrLoadDll(NULL
,
140 &Package
->ModuleHandle
);
141 if (!NT_SUCCESS(Status
))
143 TRACE("LdrLoadDll failed (Status 0x%08lx)\n", Status
);
147 RtlInitAnsiString(&ProcName
, "LsaApInitializePackage");
148 Status
= LdrGetProcedureAddress(Package
->ModuleHandle
,
151 (PVOID
*)&Package
->LsaApInitializePackage
);
152 if (!NT_SUCCESS(Status
))
154 TRACE("LdrGetProcedureAddress() failed (Status 0x%08lx)\n", Status
);
158 RtlInitAnsiString(&ProcName
, "LsaApCallPackage");
159 Status
= LdrGetProcedureAddress(Package
->ModuleHandle
,
162 (PVOID
*)&Package
->LsaApCallPackage
);
163 if (!NT_SUCCESS(Status
))
165 TRACE("LdrGetProcedureAddress() failed (Status 0x%08lx)\n", Status
);
169 RtlInitAnsiString(&ProcName
, "LsaApCallPackagePassthrough");
170 Status
= LdrGetProcedureAddress(Package
->ModuleHandle
,
173 (PVOID
*)&Package
->LsaApCallPackagePassthrough
);
174 if (!NT_SUCCESS(Status
))
176 TRACE("LdrGetProcedureAddress() failed (Status 0x%08lx)\n", Status
);
180 RtlInitAnsiString(&ProcName
, "LsaApCallPackageUntrusted");
181 Status
= LdrGetProcedureAddress(Package
->ModuleHandle
,
184 (PVOID
*)&Package
->LsaApCallPackageUntrusted
);
185 if (!NT_SUCCESS(Status
))
187 TRACE("LdrGetProcedureAddress() failed (Status 0x%08lx)\n", Status
);
191 RtlInitAnsiString(&ProcName
, "LsaApLogonTerminated");
192 Status
= LdrGetProcedureAddress(Package
->ModuleHandle
,
195 (PVOID
*)&Package
->LsaApLogonTerminated
);
196 if (!NT_SUCCESS(Status
))
198 TRACE("LdrGetProcedureAddress() failed (Status 0x%08lx)\n", Status
);
202 RtlInitAnsiString(&ProcName
, "LsaApLogonUserEx2");
203 Status
= LdrGetProcedureAddress(Package
->ModuleHandle
,
206 (PVOID
*)&Package
->LsaApLogonUserEx2
);
207 if (!NT_SUCCESS(Status
))
209 RtlInitAnsiString(&ProcName
, "LsaApLogonUserEx");
210 Status
= LdrGetProcedureAddress(Package
->ModuleHandle
,
213 (PVOID
*)&Package
->LsaApLogonUserEx
);
214 if (!NT_SUCCESS(Status
))
216 RtlInitAnsiString(&ProcName
, "LsaApLogonUser");
217 Status
= LdrGetProcedureAddress(Package
->ModuleHandle
,
220 (PVOID
*)&Package
->LsaApLogonUser
);
221 if (!NT_SUCCESS(Status
))
223 TRACE("LdrGetProcedureAddress() failed (Status 0x%08lx)\n", Status
);
229 /* Initialize the current package */
230 Status
= Package
->LsaApInitializePackage(*Id
,
235 if (!NT_SUCCESS(Status
))
237 TRACE("Package->LsaApInitializePackage() failed (Status 0x%08lx)\n", Status
);
241 TRACE("Package Name: %s\n", Package
->Name
->Buffer
);
246 InsertTailList(&PackageListHead
, &Package
->Entry
);
249 if (!NT_SUCCESS(Status
))
253 if (Package
->ModuleHandle
!= NULL
)
254 LdrUnloadDll(Package
->ModuleHandle
);
256 if (Package
->Name
!= NULL
)
258 if (Package
->Name
->Buffer
!= NULL
)
259 RtlFreeHeap(RtlGetProcessHeap(), 0, Package
->Name
->Buffer
);
261 RtlFreeHeap(RtlGetProcessHeap(), 0, Package
->Name
);
264 RtlFreeHeap(RtlGetProcessHeap(), 0, Package
);
274 LsapGetAuthenticationPackage(IN ULONG PackageId
)
276 PLIST_ENTRY ListEntry
;
277 PAUTH_PACKAGE Package
;
279 ListEntry
= PackageListHead
.Flink
;
280 while (ListEntry
!= &PackageListHead
)
282 Package
= CONTAINING_RECORD(ListEntry
, AUTH_PACKAGE
, Entry
);
284 if (Package
->Id
== PackageId
)
289 ListEntry
= ListEntry
->Flink
;
299 LsapAllocateHeap(IN ULONG Length
)
301 return RtlAllocateHeap(RtlGetProcessHeap(),
310 LsapFreeHeap(IN PVOID Base
)
312 RtlFreeHeap(RtlGetProcessHeap(),
321 LsapAllocateClientBuffer(IN PLSA_CLIENT_REQUEST ClientRequest
,
322 IN ULONG LengthRequired
,
323 OUT PVOID
*ClientBaseAddress
)
325 PLSAP_LOGON_CONTEXT LogonContext
;
328 *ClientBaseAddress
= NULL
;
330 LogonContext
= (PLSAP_LOGON_CONTEXT
)ClientRequest
;
332 Length
= LengthRequired
;
333 return NtAllocateVirtualMemory(LogonContext
->ClientProcessHandle
,
345 LsapFreeClientBuffer(IN PLSA_CLIENT_REQUEST ClientRequest
,
346 IN PVOID ClientBaseAddress
)
348 PLSAP_LOGON_CONTEXT LogonContext
;
351 if (ClientBaseAddress
== NULL
)
352 return STATUS_SUCCESS
;
354 LogonContext
= (PLSAP_LOGON_CONTEXT
)ClientRequest
;
357 return NtFreeVirtualMemory(LogonContext
->ClientProcessHandle
,
367 LsapCopyToClientBuffer(IN PLSA_CLIENT_REQUEST ClientRequest
,
369 IN PVOID ClientBaseAddress
,
370 IN PVOID BufferToCopy
)
372 PLSAP_LOGON_CONTEXT LogonContext
;
374 LogonContext
= (PLSAP_LOGON_CONTEXT
)ClientRequest
;
376 return NtWriteVirtualMemory(LogonContext
->ClientProcessHandle
,
387 LsapCopyFromClientBuffer(IN PLSA_CLIENT_REQUEST ClientRequest
,
389 IN PVOID BufferToCopy
,
390 IN PVOID ClientBaseAddress
)
392 PLSAP_LOGON_CONTEXT LogonContext
;
394 LogonContext
= (PLSAP_LOGON_CONTEXT
)ClientRequest
;
396 return NtReadVirtualMemory(LogonContext
->ClientProcessHandle
,
405 LsapInitAuthPackages(VOID
)
407 RTL_QUERY_REGISTRY_TABLE AuthPackageTable
[] = {
408 {LsapAddAuthPackage
, 0, L
"Authentication Packages", NULL
, REG_NONE
, NULL
, 0},
409 {NULL
, 0, NULL
, NULL
, REG_NONE
, NULL
, 0}};
413 InitializeListHead(&PackageListHead
);
416 /* Initialize the dispatch table */
417 DispatchTable
.CreateLogonSession
= &LsapCreateLogonSession
;
418 DispatchTable
.DeleteLogonSession
= &LsapDeleteLogonSession
;
419 DispatchTable
.AddCredential
= NULL
;
420 DispatchTable
.GetCredentials
= NULL
;
421 DispatchTable
.DeleteCredential
= NULL
;
422 DispatchTable
.AllocateLsaHeap
= &LsapAllocateHeap
;
423 DispatchTable
.FreeLsaHeap
= &LsapFreeHeap
;
424 DispatchTable
.AllocateClientBuffer
= &LsapAllocateClientBuffer
;
425 DispatchTable
.FreeClientBuffer
= &LsapFreeClientBuffer
;
426 DispatchTable
.CopyToClientBuffer
= &LsapCopyToClientBuffer
;
427 DispatchTable
.CopyFromClientBuffer
= &LsapCopyFromClientBuffer
;
429 /* Add registered authentication packages */
430 Status
= RtlQueryRegistryValues(RTL_REGISTRY_CONTROL
,
441 LsapLookupAuthenticationPackage(PLSA_API_MSG RequestMsg
,
442 PLSAP_LOGON_CONTEXT LogonContext
)
444 PLIST_ENTRY ListEntry
;
445 PAUTH_PACKAGE Package
;
446 ULONG PackageNameLength
;
449 TRACE("(%p %p)\n", RequestMsg
, LogonContext
);
451 PackageNameLength
= RequestMsg
->LookupAuthenticationPackage
.Request
.PackageNameLength
;
452 PackageName
= RequestMsg
->LookupAuthenticationPackage
.Request
.PackageName
;
454 TRACE("PackageName: %s\n", PackageName
);
456 ListEntry
= PackageListHead
.Flink
;
457 while (ListEntry
!= &PackageListHead
)
459 Package
= CONTAINING_RECORD(ListEntry
, AUTH_PACKAGE
, Entry
);
461 if ((PackageNameLength
== Package
->Name
->Length
) &&
462 (_strnicmp(PackageName
, Package
->Name
->Buffer
, Package
->Name
->Length
) == 0))
464 RequestMsg
->LookupAuthenticationPackage
.Reply
.Package
= Package
->Id
;
465 return STATUS_SUCCESS
;
468 ListEntry
= ListEntry
->Flink
;
471 return STATUS_NO_SUCH_PACKAGE
;
476 LsapCallAuthenticationPackage(PLSA_API_MSG RequestMsg
,
477 PLSAP_LOGON_CONTEXT LogonContext
)
479 PAUTH_PACKAGE Package
;
480 PVOID LocalBuffer
= NULL
;
484 TRACE("(%p %p)\n", RequestMsg
, LogonContext
);
486 PackageId
= RequestMsg
->CallAuthenticationPackage
.Request
.AuthenticationPackage
;
488 /* Get the right authentication package */
489 Package
= LsapGetAuthenticationPackage(PackageId
);
492 TRACE("LsapGetAuthenticationPackage() failed to find a package\n");
493 return STATUS_NO_SUCH_PACKAGE
;
496 if (RequestMsg
->CallAuthenticationPackage
.Request
.SubmitBufferLength
> 0)
498 LocalBuffer
= RtlAllocateHeap(RtlGetProcessHeap(),
500 RequestMsg
->CallAuthenticationPackage
.Request
.SubmitBufferLength
);
501 if (LocalBuffer
== NULL
)
503 return STATUS_INSUFFICIENT_RESOURCES
;
506 Status
= NtReadVirtualMemory(LogonContext
->ClientProcessHandle
,
507 RequestMsg
->CallAuthenticationPackage
.Request
.ProtocolSubmitBuffer
,
509 RequestMsg
->CallAuthenticationPackage
.Request
.SubmitBufferLength
,
511 if (!NT_SUCCESS(Status
))
513 TRACE("NtReadVirtualMemory() failed (Status 0x%08lx)\n", Status
);
514 RtlFreeHeap(RtlGetProcessHeap(), 0, LocalBuffer
);
519 Status
= Package
->LsaApCallPackage((PLSA_CLIENT_REQUEST
)LogonContext
,
521 RequestMsg
->CallAuthenticationPackage
.Request
.ProtocolSubmitBuffer
,
522 RequestMsg
->CallAuthenticationPackage
.Request
.SubmitBufferLength
,
523 &RequestMsg
->CallAuthenticationPackage
.Reply
.ProtocolReturnBuffer
,
524 &RequestMsg
->CallAuthenticationPackage
.Reply
.ReturnBufferLength
,
525 &RequestMsg
->CallAuthenticationPackage
.Reply
.ProtocolStatus
);
526 if (!NT_SUCCESS(Status
))
528 TRACE("Package->LsaApCallPackage() failed (Status 0x%08lx)\n", Status
);
531 if (LocalBuffer
!= NULL
)
532 RtlFreeHeap(RtlGetProcessHeap(), 0, LocalBuffer
);
541 IN PLSAP_LOGON_CONTEXT LogonContext
,
542 IN PTOKEN_GROUPS ClientGroups
,
543 IN ULONG ClientGroupsCount
,
544 OUT PTOKEN_GROUPS
*TokenGroups
)
546 ULONG LocalGroupsLength
= 0;
547 PTOKEN_GROUPS LocalGroups
= NULL
;
548 ULONG SidHeaderLength
= 0;
549 PSID SidHeader
= NULL
;
552 ULONG AllocatedSids
= 0;
556 LocalGroupsLength
= sizeof(TOKEN_GROUPS
) +
557 (ClientGroupsCount
- ANYSIZE_ARRAY
) * sizeof(SID_AND_ATTRIBUTES
);
558 LocalGroups
= RtlAllocateHeap(RtlGetProcessHeap(),
561 if (LocalGroups
== NULL
)
563 TRACE("RtlAllocateHeap() failed\n");
564 return STATUS_INSUFFICIENT_RESOURCES
;
567 Status
= NtReadVirtualMemory(LogonContext
->ClientProcessHandle
,
572 if (!NT_SUCCESS(Status
))
576 SidHeaderLength
= RtlLengthRequiredSid(0);
577 SidHeader
= RtlAllocateHeap(RtlGetProcessHeap(),
580 if (SidHeader
== NULL
)
582 Status
= STATUS_INSUFFICIENT_RESOURCES
;
586 for (i
= 0; i
< ClientGroupsCount
; i
++)
588 SrcSid
= LocalGroups
->Groups
[i
].Sid
;
590 Status
= NtReadVirtualMemory(LogonContext
->ClientProcessHandle
,
595 if (!NT_SUCCESS(Status
))
598 SidLength
= RtlLengthSid(SidHeader
);
599 TRACE("Sid %lu: Length %lu\n", i
, SidLength
);
601 DstSid
= RtlAllocateHeap(RtlGetProcessHeap(),
606 Status
= STATUS_INSUFFICIENT_RESOURCES
;
610 Status
= NtReadVirtualMemory(LogonContext
->ClientProcessHandle
,
615 if (!NT_SUCCESS(Status
))
617 RtlFreeHeap(RtlGetProcessHeap(), 0, DstSid
);
621 LocalGroups
->Groups
[i
].Sid
= DstSid
;
625 *TokenGroups
= LocalGroups
;
628 if (SidHeader
!= NULL
)
629 RtlFreeHeap(RtlGetProcessHeap(), 0, SidHeader
);
631 if (!NT_SUCCESS(Status
))
633 if (LocalGroups
!= NULL
)
635 for (i
= 0; i
< AllocatedSids
; i
++)
636 RtlFreeHeap(RtlGetProcessHeap(), 0, LocalGroups
->Groups
[i
].Sid
);
638 RtlFreeHeap(RtlGetProcessHeap(), 0, LocalGroups
);
649 IN PVOID TokenInformation
,
650 IN LSA_TOKEN_INFORMATION_TYPE TokenInformationType
,
651 IN PTOKEN_GROUPS LocalGroups
)
653 PLSA_TOKEN_INFORMATION_V1 TokenInfo1
;
654 PTOKEN_GROUPS Groups
;
659 if (LocalGroups
== NULL
|| LocalGroups
->GroupCount
== 0)
660 return STATUS_SUCCESS
;
662 if (TokenInformationType
== LsaTokenInformationV1
)
664 TokenInfo1
= (PLSA_TOKEN_INFORMATION_V1
)TokenInformation
;
666 if (TokenInfo1
->Groups
!= NULL
)
668 Length
= sizeof(TOKEN_GROUPS
) +
669 (LocalGroups
->GroupCount
+ TokenInfo1
->Groups
->GroupCount
- ANYSIZE_ARRAY
) * sizeof(SID_AND_ATTRIBUTES
);
671 Groups
= RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY
, Length
);
674 ERR("Group buffer allocation failed!\n");
675 return STATUS_INSUFFICIENT_RESOURCES
;
678 Groups
->GroupCount
= LocalGroups
->GroupCount
+ TokenInfo1
->Groups
->GroupCount
;
680 for (i
= 0; i
< TokenInfo1
->Groups
->GroupCount
; i
++)
682 Groups
->Groups
[i
].Sid
= TokenInfo1
->Groups
->Groups
[i
].Sid
;
683 Groups
->Groups
[i
].Attributes
= TokenInfo1
->Groups
->Groups
[i
].Attributes
;
686 for (j
= 0; j
< LocalGroups
->GroupCount
; i
++, j
++)
688 Groups
->Groups
[i
].Sid
= LocalGroups
->Groups
[j
].Sid
;
689 Groups
->Groups
[i
].Attributes
= LocalGroups
->Groups
[j
].Attributes
;
690 LocalGroups
->Groups
[j
].Sid
= NULL
;
693 RtlFreeHeap(RtlGetProcessHeap(), 0, TokenInfo1
->Groups
);
695 TokenInfo1
->Groups
= Groups
;
699 Length
= sizeof(TOKEN_GROUPS
) +
700 (LocalGroups
->GroupCount
- ANYSIZE_ARRAY
) * sizeof(SID_AND_ATTRIBUTES
);
702 Groups
= RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY
, Length
);
705 ERR("Group buffer allocation failed!\n");
706 return STATUS_INSUFFICIENT_RESOURCES
;
709 Groups
->GroupCount
= LocalGroups
->GroupCount
;
711 for (i
= 0; i
< LocalGroups
->GroupCount
; i
++)
713 Groups
->Groups
[i
].Sid
= LocalGroups
->Groups
[i
].Sid
;
714 Groups
->Groups
[i
].Attributes
= LocalGroups
->Groups
[i
].Attributes
;
717 TokenInfo1
->Groups
= Groups
;
722 FIXME("TokenInformationType %d is not supported!\n", TokenInformationType
);
723 return STATUS_NOT_IMPLEMENTED
;
726 return STATUS_SUCCESS
;
731 LsapAddDefaultGroups(
732 IN PVOID TokenInformation
,
733 IN LSA_TOKEN_INFORMATION_TYPE TokenInformationType
,
734 IN SECURITY_LOGON_TYPE LogonType
)
736 PLSA_TOKEN_INFORMATION_V1 TokenInfo1
;
737 PTOKEN_GROUPS Groups
;
741 if (TokenInformationType
== LsaTokenInformationV1
)
743 TokenInfo1
= (PLSA_TOKEN_INFORMATION_V1
)TokenInformation
;
745 if (TokenInfo1
->Groups
!= NULL
)
747 Length
= sizeof(TOKEN_GROUPS
) +
748 (TokenInfo1
->Groups
->GroupCount
+ 2 - ANYSIZE_ARRAY
) * sizeof(SID_AND_ATTRIBUTES
);
750 Groups
= RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY
, Length
);
753 ERR("Group buffer allocation failed!\n");
754 return STATUS_INSUFFICIENT_RESOURCES
;
757 Groups
->GroupCount
= TokenInfo1
->Groups
->GroupCount
;
759 for (i
= 0; i
< TokenInfo1
->Groups
->GroupCount
; i
++)
761 Groups
->Groups
[i
].Sid
= TokenInfo1
->Groups
->Groups
[i
].Sid
;
762 Groups
->Groups
[i
].Attributes
= TokenInfo1
->Groups
->Groups
[i
].Attributes
;
765 RtlFreeHeap(RtlGetProcessHeap(), 0, TokenInfo1
->Groups
);
767 TokenInfo1
->Groups
= Groups
;
772 Length
= sizeof(TOKEN_GROUPS
) +
773 (2 - ANYSIZE_ARRAY
) * sizeof(SID_AND_ATTRIBUTES
);
775 Groups
= RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY
, Length
);
778 ERR("Group buffer allocation failed!\n");
779 return STATUS_INSUFFICIENT_RESOURCES
;
782 TokenInfo1
->Groups
= Groups
;
785 /* Append the World SID (aka Everyone) */
786 Length
= RtlLengthSid(LsapWorldSid
);
787 Groups
->Groups
[Groups
->GroupCount
].Sid
= RtlAllocateHeap(RtlGetProcessHeap(),
790 if (Groups
->Groups
[Groups
->GroupCount
].Sid
== NULL
)
791 return STATUS_INSUFFICIENT_RESOURCES
;
793 RtlCopyMemory(Groups
->Groups
[Groups
->GroupCount
].Sid
,
797 Groups
->Groups
[Groups
->GroupCount
].Attributes
=
798 SE_GROUP_ENABLED
| SE_GROUP_ENABLED_BY_DEFAULT
| SE_GROUP_MANDATORY
;
800 Groups
->GroupCount
++;
802 /* Append the logon type SID */
806 SrcSid
= LsapInteractiveSid
;
810 SrcSid
= LsapNetworkSid
;
814 SrcSid
= LsapBatchSid
;
818 SrcSid
= LsapServiceSid
;
822 FIXME("LogonType %d is not supported!\n", LogonType
);
823 return STATUS_NOT_IMPLEMENTED
;
826 Length
= RtlLengthSid(SrcSid
);
827 Groups
->Groups
[Groups
->GroupCount
].Sid
= RtlAllocateHeap(RtlGetProcessHeap(),
830 if (Groups
->Groups
[Groups
->GroupCount
].Sid
== NULL
)
831 return STATUS_INSUFFICIENT_RESOURCES
;
833 RtlCopyMemory(Groups
->Groups
[Groups
->GroupCount
].Sid
,
837 Groups
->Groups
[Groups
->GroupCount
].Attributes
=
838 SE_GROUP_ENABLED
| SE_GROUP_ENABLED_BY_DEFAULT
| SE_GROUP_MANDATORY
;
840 Groups
->GroupCount
++;
844 FIXME("TokenInformationType %d is not supported!\n", TokenInformationType
);
845 return STATUS_NOT_IMPLEMENTED
;
848 return STATUS_SUCCESS
;
855 IN PVOID TokenInformation
,
856 IN LSA_TOKEN_INFORMATION_TYPE TokenInformationType
)
858 PLSA_TOKEN_INFORMATION_V1 TokenInfo1
;
859 PSID OwnerSid
= NULL
;
862 if (TokenInformationType
== LsaTokenInformationV1
)
864 TokenInfo1
= (PLSA_TOKEN_INFORMATION_V1
)TokenInformation
;
866 if (TokenInfo1
->Owner
.Owner
!= NULL
)
867 return STATUS_SUCCESS
;
869 OwnerSid
= TokenInfo1
->User
.User
.Sid
;
870 for (i
= 0; i
< TokenInfo1
->Groups
->GroupCount
; i
++)
872 if (EqualSid(TokenInfo1
->Groups
->Groups
[i
].Sid
, LsapAdministratorsSid
))
874 OwnerSid
= LsapAdministratorsSid
;
879 Length
= RtlLengthSid(OwnerSid
);
880 TokenInfo1
->Owner
.Owner
= DispatchTable
.AllocateLsaHeap(Length
);
881 if (TokenInfo1
->Owner
.Owner
== NULL
)
882 return STATUS_INSUFFICIENT_RESOURCES
;
884 RtlCopyMemory(TokenInfo1
->Owner
.Owner
,
889 return STATUS_SUCCESS
;
895 LsapAddTokenDefaultDacl(
896 IN PVOID TokenInformation
,
897 IN LSA_TOKEN_INFORMATION_TYPE TokenInformationType
)
899 PLSA_TOKEN_INFORMATION_V1 TokenInfo1
;
903 if (TokenInformationType
== LsaTokenInformationV1
)
905 TokenInfo1
= (PLSA_TOKEN_INFORMATION_V1
)TokenInformation
;
907 if (TokenInfo1
->DefaultDacl
.DefaultDacl
!= NULL
)
908 return STATUS_SUCCESS
;
910 Length
= sizeof(ACL
) +
911 (2 * sizeof(ACCESS_ALLOWED_ACE
)) +
912 RtlLengthSid(TokenInfo1
->Owner
.Owner
) +
913 RtlLengthSid(LsapLocalSystemSid
);
915 Dacl
= DispatchTable
.AllocateLsaHeap(Length
);
917 return STATUS_INSUFFICIENT_RESOURCES
;
919 RtlCreateAcl(Dacl
, Length
, ACL_REVISION
);
921 RtlAddAccessAllowedAce(Dacl
,
924 TokenInfo1
->Owner
.Owner
);
927 RtlAddAccessAllowedAce(Dacl
,
932 TokenInfo1
->DefaultDacl
.DefaultDacl
= Dacl
;
935 return STATUS_SUCCESS
;
940 LsapLogonUser(PLSA_API_MSG RequestMsg
,
941 PLSAP_LOGON_CONTEXT LogonContext
)
943 PAUTH_PACKAGE Package
;
944 OBJECT_ATTRIBUTES ObjectAttributes
;
945 SECURITY_QUALITY_OF_SERVICE Qos
;
946 LSA_TOKEN_INFORMATION_TYPE TokenInformationType
;
947 PVOID TokenInformation
= NULL
;
948 PLSA_TOKEN_INFORMATION_V1 TokenInfo1
= NULL
;
949 PUNICODE_STRING AccountName
= NULL
;
950 PUNICODE_STRING AuthenticatingAuthority
= NULL
;
951 PUNICODE_STRING MachineName
= NULL
;
952 PVOID LocalAuthInfo
= NULL
;
953 PTOKEN_GROUPS LocalGroups
= NULL
;
954 HANDLE TokenHandle
= NULL
;
957 SECURITY_LOGON_TYPE LogonType
;
960 TRACE("(%p %p)\n", RequestMsg
, LogonContext
);
962 PackageId
= RequestMsg
->LogonUser
.Request
.AuthenticationPackage
;
963 LogonType
= RequestMsg
->LogonUser
.Request
.LogonType
;
965 /* Get the right authentication package */
966 Package
= LsapGetAuthenticationPackage(PackageId
);
969 ERR("LsapGetAuthenticationPackage() failed to find a package\n");
970 return STATUS_NO_SUCH_PACKAGE
;
973 if (RequestMsg
->LogonUser
.Request
.AuthenticationInformationLength
> 0)
975 /* Allocate the local authentication info buffer */
976 LocalAuthInfo
= RtlAllocateHeap(RtlGetProcessHeap(),
978 RequestMsg
->LogonUser
.Request
.AuthenticationInformationLength
);
979 if (LocalAuthInfo
== NULL
)
981 ERR("RtlAllocateHeap() failed\n");
982 return STATUS_INSUFFICIENT_RESOURCES
;
985 /* Read the authentication info from the callers adress space */
986 Status
= NtReadVirtualMemory(LogonContext
->ClientProcessHandle
,
987 RequestMsg
->LogonUser
.Request
.AuthenticationInformation
,
989 RequestMsg
->LogonUser
.Request
.AuthenticationInformationLength
,
991 if (!NT_SUCCESS(Status
))
993 ERR("NtReadVirtualMemory() failed (Status 0x%08lx)\n", Status
);
994 RtlFreeHeap(RtlGetProcessHeap(), 0, LocalAuthInfo
);
999 if (RequestMsg
->LogonUser
.Request
.LocalGroupsCount
> 0)
1001 Status
= LsapCopyLocalGroups(LogonContext
,
1002 RequestMsg
->LogonUser
.Request
.LocalGroups
,
1003 RequestMsg
->LogonUser
.Request
.LocalGroupsCount
,
1005 if (!NT_SUCCESS(Status
))
1007 ERR("LsapCopyLocalGroups failed (Status 0x%08lx)\n", Status
);
1011 TRACE("GroupCount: %lu\n", LocalGroups
->GroupCount
);
1014 if (Package
->LsaApLogonUserEx2
!= NULL
)
1016 Status
= Package
->LsaApLogonUserEx2((PLSA_CLIENT_REQUEST
)LogonContext
,
1017 RequestMsg
->LogonUser
.Request
.LogonType
,
1019 RequestMsg
->LogonUser
.Request
.AuthenticationInformation
,
1020 RequestMsg
->LogonUser
.Request
.AuthenticationInformationLength
,
1021 &RequestMsg
->LogonUser
.Reply
.ProfileBuffer
,
1022 &RequestMsg
->LogonUser
.Reply
.ProfileBufferLength
,
1023 &RequestMsg
->LogonUser
.Reply
.LogonId
,
1024 &RequestMsg
->LogonUser
.Reply
.SubStatus
,
1025 &TokenInformationType
,
1028 &AuthenticatingAuthority
,
1030 NULL
, /* FIXME: PSECPKG_PRIMARY_CRED PrimaryCredentials */
1031 NULL
); /* FIXME: PSECPKG_SUPPLEMENTAL_CRED_ARRAY *SupplementalCredentials */
1033 else if (Package
->LsaApLogonUserEx
!= NULL
)
1035 Status
= Package
->LsaApLogonUserEx((PLSA_CLIENT_REQUEST
)LogonContext
,
1036 RequestMsg
->LogonUser
.Request
.LogonType
,
1038 RequestMsg
->LogonUser
.Request
.AuthenticationInformation
,
1039 RequestMsg
->LogonUser
.Request
.AuthenticationInformationLength
,
1040 &RequestMsg
->LogonUser
.Reply
.ProfileBuffer
,
1041 &RequestMsg
->LogonUser
.Reply
.ProfileBufferLength
,
1042 &RequestMsg
->LogonUser
.Reply
.LogonId
,
1043 &RequestMsg
->LogonUser
.Reply
.SubStatus
,
1044 &TokenInformationType
,
1047 &AuthenticatingAuthority
,
1052 Status
= Package
->LsaApLogonUser((PLSA_CLIENT_REQUEST
)LogonContext
,
1053 RequestMsg
->LogonUser
.Request
.LogonType
,
1055 RequestMsg
->LogonUser
.Request
.AuthenticationInformation
,
1056 RequestMsg
->LogonUser
.Request
.AuthenticationInformationLength
,
1057 &RequestMsg
->LogonUser
.Reply
.ProfileBuffer
,
1058 &RequestMsg
->LogonUser
.Reply
.ProfileBufferLength
,
1059 &RequestMsg
->LogonUser
.Reply
.LogonId
,
1060 &RequestMsg
->LogonUser
.Reply
.SubStatus
,
1061 &TokenInformationType
,
1064 &AuthenticatingAuthority
);
1067 if (!NT_SUCCESS(Status
))
1069 ERR("LsaApLogonUser/Ex/2 failed (Status 0x%08lx)\n", Status
);
1073 if (LocalGroups
->GroupCount
> 0)
1075 /* Add local groups to the token information */
1076 Status
= LsapAddLocalGroups(TokenInformation
,
1077 TokenInformationType
,
1079 if (!NT_SUCCESS(Status
))
1081 ERR("LsapAddLocalGroupsToTokenInfo() failed (Status 0x%08lx)\n", Status
);
1086 Status
= LsapAddDefaultGroups(TokenInformation
,
1087 TokenInformationType
,
1089 if (!NT_SUCCESS(Status
))
1091 ERR("LsapAddDefaultGroups() failed (Status 0x%08lx)\n", Status
);
1095 Status
= LsapSetTokenOwner(TokenInformation
,
1096 TokenInformationType
);
1097 if (!NT_SUCCESS(Status
))
1099 ERR("LsapSetTokenOwner() failed (Status 0x%08lx)\n", Status
);
1103 Status
= LsapAddTokenDefaultDacl(TokenInformation
,
1104 TokenInformationType
);
1105 if (!NT_SUCCESS(Status
))
1107 ERR("LsapAddTokenDefaultDacl() failed (Status 0x%08lx)\n", Status
);
1111 if (TokenInformationType
== LsaTokenInformationV1
)
1113 TokenInfo1
= (PLSA_TOKEN_INFORMATION_V1
)TokenInformation
;
1115 Qos
.Length
= sizeof(SECURITY_QUALITY_OF_SERVICE
);
1116 Qos
.ImpersonationLevel
= SecurityImpersonation
;
1117 Qos
.ContextTrackingMode
= SECURITY_DYNAMIC_TRACKING
;
1118 Qos
.EffectiveOnly
= FALSE
;
1120 ObjectAttributes
.Length
= sizeof(OBJECT_ATTRIBUTES
);
1121 ObjectAttributes
.RootDirectory
= NULL
;
1122 ObjectAttributes
.ObjectName
= NULL
;
1123 ObjectAttributes
.Attributes
= 0;
1124 ObjectAttributes
.SecurityDescriptor
= NULL
;
1125 ObjectAttributes
.SecurityQualityOfService
= &Qos
;
1127 /* Create the logon token */
1128 Status
= NtCreateToken(&TokenHandle
,
1132 &RequestMsg
->LogonUser
.Reply
.LogonId
,
1133 &TokenInfo1
->ExpirationTime
,
1136 TokenInfo1
->Privileges
,
1138 &TokenInfo1
->PrimaryGroup
,
1139 &TokenInfo1
->DefaultDacl
,
1140 &RequestMsg
->LogonUser
.Request
.SourceContext
);
1141 if (!NT_SUCCESS(Status
))
1143 ERR("NtCreateToken failed (Status 0x%08lx)\n", Status
);
1149 FIXME("TokenInformationType %d is not supported!\n", TokenInformationType
);
1150 Status
= STATUS_NOT_IMPLEMENTED
;
1154 /* Duplicate the token handle into the client process */
1155 Status
= NtDuplicateObject(NtCurrentProcess(),
1157 LogonContext
->ClientProcessHandle
,
1158 &RequestMsg
->LogonUser
.Reply
.Token
,
1161 DUPLICATE_SAME_ACCESS
| DUPLICATE_SAME_ATTRIBUTES
| DUPLICATE_CLOSE_SOURCE
);
1162 if (!NT_SUCCESS(Status
))
1164 ERR("NtDuplicateObject failed (Status 0x%08lx)\n", Status
);
1170 Status
= LsapSetLogonSessionData(&RequestMsg
->LogonUser
.Reply
.LogonId
);
1171 if (!NT_SUCCESS(Status
))
1173 ERR("LsapSetLogonSessionData failed (Status 0x%08lx)\n", Status
);
1178 if (!NT_SUCCESS(Status
))
1180 if (TokenHandle
!= NULL
)
1181 NtClose(TokenHandle
);
1184 /* Free the local groups */
1185 if (LocalGroups
!= NULL
)
1187 for (i
= 0; i
< LocalGroups
->GroupCount
; i
++)
1189 if (LocalGroups
->Groups
[i
].Sid
!= NULL
)
1190 RtlFreeHeap(RtlGetProcessHeap(), 0, LocalGroups
->Groups
[i
].Sid
);
1193 RtlFreeHeap(RtlGetProcessHeap(), 0, LocalGroups
);
1196 /* Free the local authentication info buffer */
1197 if (LocalAuthInfo
!= NULL
)
1198 RtlFreeHeap(RtlGetProcessHeap(), 0, LocalAuthInfo
);
1200 /* Free the token information */
1201 if (TokenInformation
!= NULL
)
1203 if (TokenInformationType
== LsaTokenInformationV1
)
1205 TokenInfo1
= (PLSA_TOKEN_INFORMATION_V1
)TokenInformation
;
1207 if (TokenInfo1
!= NULL
)
1209 if (TokenInfo1
->User
.User
.Sid
!= NULL
)
1210 LsapFreeHeap(TokenInfo1
->User
.User
.Sid
);
1212 if (TokenInfo1
->Groups
!= NULL
)
1214 for (i
= 0; i
< TokenInfo1
->Groups
->GroupCount
; i
++)
1216 if (TokenInfo1
->Groups
->Groups
[i
].Sid
!= NULL
)
1217 LsapFreeHeap(TokenInfo1
->Groups
->Groups
[i
].Sid
);
1220 LsapFreeHeap(TokenInfo1
->Groups
);
1223 if (TokenInfo1
->PrimaryGroup
.PrimaryGroup
!= NULL
)
1224 LsapFreeHeap(TokenInfo1
->PrimaryGroup
.PrimaryGroup
);
1226 if (TokenInfo1
->Privileges
!= NULL
)
1227 LsapFreeHeap(TokenInfo1
->Privileges
);
1229 if (TokenInfo1
->Owner
.Owner
!= NULL
)
1230 LsapFreeHeap(TokenInfo1
->Owner
.Owner
);
1232 if (TokenInfo1
->DefaultDacl
.DefaultDacl
!= NULL
)
1233 LsapFreeHeap(TokenInfo1
->DefaultDacl
.DefaultDacl
);
1235 LsapFreeHeap(TokenInfo1
);
1240 FIXME("TokenInformationType %d is not supported!\n", TokenInformationType
);
1244 /* Free the account name */
1245 if (AccountName
!= NULL
)
1247 if (AccountName
->Buffer
!= NULL
)
1248 LsapFreeHeap(AccountName
->Buffer
);
1250 LsapFreeHeap(AccountName
);
1253 /* Free the authentication authority */
1254 if (AuthenticatingAuthority
!= NULL
)
1256 if (AuthenticatingAuthority
!= NULL
)
1257 LsapFreeHeap(AuthenticatingAuthority
->Buffer
);
1259 LsapFreeHeap(AuthenticatingAuthority
);
1262 /* Free the machine name */
1263 if (MachineName
!= NULL
)
1265 if (MachineName
->Buffer
!= NULL
)
1266 LsapFreeHeap(MachineName
->Buffer
);
1268 LsapFreeHeap(MachineName
);
1271 TRACE("LsapLogonUser done (Status 0x%08lx)\n", Status
);