+++ /dev/null
-/*
- * PROJECT: Local Security Authority Server DLL
- * LICENSE: GPL - See COPYING in the top level directory
- * FILE: dll/win32/lsasrv/authpackage.c
- * PURPOSE: Authentication package management routines
- * COPYRIGHT: Copyright 2013 Eric Kohl
- */
-
-#include "lsasrv.h"
-
-#include <ndk/sefuncs.h>
-#include <ndk/umfuncs.h>
-
-typedef enum _LSA_TOKEN_INFORMATION_TYPE
-{
- LsaTokenInformationNull,
- LsaTokenInformationV1
-} LSA_TOKEN_INFORMATION_TYPE, *PLSA_TOKEN_INFORMATION_TYPE;
-
-typedef struct _LSA_TOKEN_INFORMATION_V1
-{
- LARGE_INTEGER ExpirationTime;
- TOKEN_USER User;
- PTOKEN_GROUPS Groups;
- TOKEN_PRIMARY_GROUP PrimaryGroup;
- PTOKEN_PRIVILEGES Privileges;
- TOKEN_OWNER Owner;
- TOKEN_DEFAULT_DACL DefaultDacl;
-} LSA_TOKEN_INFORMATION_V1, *PLSA_TOKEN_INFORMATION_V1;
-
-typedef PVOID PLSA_CLIENT_REQUEST;
-
-typedef NTSTATUS (NTAPI *PLSA_CREATE_LOGON_SESSION)(PLUID);
-typedef NTSTATUS (NTAPI *PLSA_DELETE_LOGON_SESSION)(PLUID);
-typedef NTSTATUS (NTAPI *PLSA_ADD_CREDENTIAL)(PLUID, ULONG, PLSA_STRING, PLSA_STRING);
-typedef NTSTATUS (NTAPI *PLSA_GET_CREDENTIALS)(PLUID, ULONG, PULONG, BOOLEAN, PLSA_STRING, PULONG, PLSA_STRING);
-typedef NTSTATUS (NTAPI *PLSA_DELETE_CREDENTIAL)(PLUID, ULONG, PLSA_STRING);
-typedef PVOID (NTAPI *PLSA_ALLOCATE_LSA_HEAP)(ULONG);
-typedef VOID (NTAPI *PLSA_FREE_LSA_HEAP)(PVOID);
-typedef NTSTATUS (NTAPI *PLSA_ALLOCATE_CLIENT_BUFFER)(PLSA_CLIENT_REQUEST, ULONG, PVOID*);
-typedef NTSTATUS (NTAPI *PLSA_FREE_CLIENT_BUFFER)(PLSA_CLIENT_REQUEST, PVOID);
-typedef NTSTATUS (NTAPI *PLSA_COPY_TO_CLIENT_BUFFER)(PLSA_CLIENT_REQUEST, ULONG,
- PVOID, PVOID);
-typedef NTSTATUS (NTAPI *PLSA_COPY_FROM_CLIENT_BUFFER)(PLSA_CLIENT_REQUEST,
- ULONG, PVOID, PVOID);
-
-typedef struct LSA_DISPATCH_TABLE
-{
- PLSA_CREATE_LOGON_SESSION CreateLogonSession;
- PLSA_DELETE_LOGON_SESSION DeleteLogonSession;
- PLSA_ADD_CREDENTIAL AddCredential;
- PLSA_GET_CREDENTIALS GetCredentials;
- PLSA_DELETE_CREDENTIAL DeleteCredential;
- PLSA_ALLOCATE_LSA_HEAP AllocateLsaHeap;
- PLSA_FREE_LSA_HEAP FreeLsaHeap;
- PLSA_ALLOCATE_CLIENT_BUFFER AllocateClientBuffer;
- PLSA_FREE_CLIENT_BUFFER FreeClientBuffer;
- PLSA_COPY_TO_CLIENT_BUFFER CopyToClientBuffer;
- PLSA_COPY_FROM_CLIENT_BUFFER CopyFromClientBuffer;
-} LSA_DISPATCH_TABLE, *PLSA_DISPATCH_TABLE;
-
-
-typedef NTSTATUS (NTAPI *PLSA_AP_INITIALIZE_PACKAGE)(ULONG, PLSA_DISPATCH_TABLE,
- PLSA_STRING, PLSA_STRING, PLSA_STRING *);
-typedef NTSTATUS (NTAPI *PLSA_AP_CALL_PACKAGE_INTERNAL)(PLSA_CLIENT_REQUEST, PVOID, PVOID,
- ULONG, PVOID *, PULONG, PNTSTATUS);
-typedef NTSTATUS (NTAPI *PLSA_AP_CALL_PACKAGE_PASSTHROUGH)(PLSA_CLIENT_REQUEST,
- PVOID, PVOID, ULONG, PVOID *, PULONG, PNTSTATUS);
-typedef NTSTATUS (NTAPI *PLSA_AP_CALL_PACKAGE_UNTRUSTED)(PLSA_CLIENT_REQUEST,
- PVOID, PVOID, ULONG, PVOID *, PULONG, PNTSTATUS);
-typedef VOID (NTAPI *PLSA_AP_LOGON_TERMINATED)(PLUID);
-typedef NTSTATUS (NTAPI *PLSA_AP_LOGON_USER_EX2)(PLSA_CLIENT_REQUEST,
- SECURITY_LOGON_TYPE, PVOID, PVOID, ULONG, PVOID *, PULONG, PLUID, PNTSTATUS,
- PLSA_TOKEN_INFORMATION_TYPE, PVOID *, PUNICODE_STRING *, PUNICODE_STRING *,
- PUNICODE_STRING *, PVOID /*PSECPKG_PRIMARY_CRED*/, PVOID /*PSECPKG_SUPPLEMENTAL_CRED_ARRAY **/);
-typedef NTSTATUS (NTAPI *PLSA_AP_LOGON_USER_EX)(PLSA_CLIENT_REQUEST,
- SECURITY_LOGON_TYPE, PVOID, PVOID, ULONG, PVOID *, PULONG, PLUID, PNTSTATUS,
- PLSA_TOKEN_INFORMATION_TYPE, PVOID *, PUNICODE_STRING *, PUNICODE_STRING *,
- PUNICODE_STRING *);
-
-typedef NTSTATUS (NTAPI *PLSA_AP_LOGON_USER_INTERNAL)(PLSA_CLIENT_REQUEST, SECURITY_LOGON_TYPE,
- PVOID, PVOID, ULONG, PVOID *, PULONG, PLUID, PNTSTATUS, PLSA_TOKEN_INFORMATION_TYPE,
- PVOID *, PUNICODE_STRING *, PUNICODE_STRING *);
-
-typedef struct _AUTH_PACKAGE
-{
- LIST_ENTRY Entry;
- PSTRING Name;
- ULONG Id;
- PVOID ModuleHandle;
-
- PLSA_AP_INITIALIZE_PACKAGE LsaApInitializePackage;
- PLSA_AP_CALL_PACKAGE_INTERNAL LsaApCallPackage;
- PLSA_AP_CALL_PACKAGE_PASSTHROUGH LsaApCallPackagePassthrough;
- PLSA_AP_CALL_PACKAGE_UNTRUSTED LsaApCallPackageUntrusted;
- PLSA_AP_LOGON_TERMINATED LsaApLogonTerminated;
- PLSA_AP_LOGON_USER_EX2 LsaApLogonUserEx2;
- PLSA_AP_LOGON_USER_EX LsaApLogonUserEx;
- PLSA_AP_LOGON_USER_INTERNAL LsaApLogonUser;
-} AUTH_PACKAGE, *PAUTH_PACKAGE;
-
-VOID
-NTAPI
-LsaIFree_LSAPR_PRIVILEGE_SET(IN PLSAPR_PRIVILEGE_SET Ptr);
-
-typedef wchar_t *PSAMPR_SERVER_NAME;
-typedef void *SAMPR_HANDLE;
-
-typedef struct _SAMPR_ULONG_ARRAY
-{
- unsigned long Count;
- unsigned long *Element;
-} SAMPR_ULONG_ARRAY, *PSAMPR_ULONG_ARRAY;
-
-typedef struct _SAMPR_SID_INFORMATION
-{
- PRPC_SID SidPointer;
-} SAMPR_SID_INFORMATION, *PSAMPR_SID_INFORMATION;
-
-typedef struct _SAMPR_PSID_ARRAY
-{
- unsigned long Count;
- PSAMPR_SID_INFORMATION Sids;
-} SAMPR_PSID_ARRAY, *PSAMPR_PSID_ARRAY;
-
-NTSTATUS
-NTAPI
-SamIConnect(
- PSAMPR_SERVER_NAME ServerName,
- SAMPR_HANDLE *ServerHandle,
- ACCESS_MASK DesiredAccess,
- BOOLEAN Trusted);
-
-VOID
-NTAPI
-SamIFree_SAMPR_ULONG_ARRAY(
- PSAMPR_ULONG_ARRAY Ptr);
-
-NTSTATUS
-__stdcall
-SamrCloseHandle(
- SAMPR_HANDLE *SamHandle);
-
-NTSTATUS
-__stdcall
-SamrOpenDomain(
- SAMPR_HANDLE ServerHandle,
- ACCESS_MASK DesiredAccess,
- PRPC_SID DomainId,
- SAMPR_HANDLE *DomainHandle);
-
-NTSTATUS
-__stdcall
-SamrGetAliasMembership(
- SAMPR_HANDLE DomainHandle,
- PSAMPR_PSID_ARRAY SidArray,
- PSAMPR_ULONG_ARRAY Membership);
-
-
-/* GLOBALS *****************************************************************/
-
-static LIST_ENTRY PackageListHead;
-static ULONG PackageId;
-static LSA_DISPATCH_TABLE DispatchTable;
-
-#define CONST_LUID(x1, x2) {x1, x2}
-static const LUID SeChangeNotifyPrivilege = CONST_LUID(SE_CHANGE_NOTIFY_PRIVILEGE, 0);
-static const LUID SeCreateGlobalPrivilege = CONST_LUID(SE_CREATE_GLOBAL_PRIVILEGE, 0);
-static const LUID SeImpersonatePrivilege = CONST_LUID(SE_IMPERSONATE_PRIVILEGE, 0);
-
-
-/* FUNCTIONS ***************************************************************/
-
-static
-NTSTATUS
-NTAPI
-LsapAddAuthPackage(IN PWSTR ValueName,
- IN ULONG ValueType,
- IN PVOID ValueData,
- IN ULONG ValueLength,
- IN PVOID Context,
- IN PVOID EntryContext)
-{
- PAUTH_PACKAGE Package = NULL;
- UNICODE_STRING PackageName;
- STRING ProcName;
- PULONG Id;
- NTSTATUS Status = STATUS_SUCCESS;
-
- TRACE("LsapAddAuthPackage()\n");
-
- PackageName.Length = (USHORT)ValueLength - sizeof(WCHAR);
- PackageName.MaximumLength = (USHORT)ValueLength;
- PackageName.Buffer = ValueData;
-
- Id = (PULONG)Context;
-
- Package = RtlAllocateHeap(RtlGetProcessHeap(),
- HEAP_ZERO_MEMORY,
- sizeof(AUTH_PACKAGE));
- if (Package == NULL)
- return STATUS_INSUFFICIENT_RESOURCES;
-
- Status = LdrLoadDll(NULL,
- NULL,
- &PackageName,
- &Package->ModuleHandle);
- if (!NT_SUCCESS(Status))
- {
- TRACE("LdrLoadDll failed (Status 0x%08lx)\n", Status);
- goto done;
- }
-
- RtlInitAnsiString(&ProcName, "LsaApInitializePackage");
- Status = LdrGetProcedureAddress(Package->ModuleHandle,
- &ProcName,
- 0,
- (PVOID *)&Package->LsaApInitializePackage);
- if (!NT_SUCCESS(Status))
- {
- TRACE("LdrGetProcedureAddress() failed (Status 0x%08lx)\n", Status);
- goto done;
- }
-
- RtlInitAnsiString(&ProcName, "LsaApCallPackage");
- Status = LdrGetProcedureAddress(Package->ModuleHandle,
- &ProcName,
- 0,
- (PVOID *)&Package->LsaApCallPackage);
- if (!NT_SUCCESS(Status))
- {
- TRACE("LdrGetProcedureAddress() failed (Status 0x%08lx)\n", Status);
- goto done;
- }
-
- RtlInitAnsiString(&ProcName, "LsaApCallPackagePassthrough");
- Status = LdrGetProcedureAddress(Package->ModuleHandle,
- &ProcName,
- 0,
- (PVOID *)&Package->LsaApCallPackagePassthrough);
- if (!NT_SUCCESS(Status))
- {
- TRACE("LdrGetProcedureAddress() failed (Status 0x%08lx)\n", Status);
- goto done;
- }
-
- RtlInitAnsiString(&ProcName, "LsaApCallPackageUntrusted");
- Status = LdrGetProcedureAddress(Package->ModuleHandle,
- &ProcName,
- 0,
- (PVOID *)&Package->LsaApCallPackageUntrusted);
- if (!NT_SUCCESS(Status))
- {
- TRACE("LdrGetProcedureAddress() failed (Status 0x%08lx)\n", Status);
- goto done;
- }
-
- RtlInitAnsiString(&ProcName, "LsaApLogonTerminated");
- Status = LdrGetProcedureAddress(Package->ModuleHandle,
- &ProcName,
- 0,
- (PVOID *)&Package->LsaApLogonTerminated);
- if (!NT_SUCCESS(Status))
- {
- TRACE("LdrGetProcedureAddress() failed (Status 0x%08lx)\n", Status);
- goto done;
- }
-
- RtlInitAnsiString(&ProcName, "LsaApLogonUserEx2");
- Status = LdrGetProcedureAddress(Package->ModuleHandle,
- &ProcName,
- 0,
- (PVOID *)&Package->LsaApLogonUserEx2);
- if (!NT_SUCCESS(Status))
- {
- RtlInitAnsiString(&ProcName, "LsaApLogonUserEx");
- Status = LdrGetProcedureAddress(Package->ModuleHandle,
- &ProcName,
- 0,
- (PVOID *)&Package->LsaApLogonUserEx);
- if (!NT_SUCCESS(Status))
- {
- RtlInitAnsiString(&ProcName, "LsaApLogonUser");
- Status = LdrGetProcedureAddress(Package->ModuleHandle,
- &ProcName,
- 0,
- (PVOID *)&Package->LsaApLogonUser);
- if (!NT_SUCCESS(Status))
- {
- TRACE("LdrGetProcedureAddress() failed (Status 0x%08lx)\n", Status);
- goto done;
- }
- }
- }
-
- /* Initialize the current package */
- Status = Package->LsaApInitializePackage(*Id,
- &DispatchTable,
- NULL,
- NULL,
- &Package->Name);
- if (!NT_SUCCESS(Status))
- {
- TRACE("Package->LsaApInitializePackage() failed (Status 0x%08lx)\n", Status);
- goto done;
- }
-
- TRACE("Package Name: %s\n", Package->Name->Buffer);
-
- Package->Id = *Id;
- (*Id)++;
-
- InsertTailList(&PackageListHead, &Package->Entry);
-
-done:
- if (!NT_SUCCESS(Status))
- {
- if (Package != NULL)
- {
- if (Package->ModuleHandle != NULL)
- LdrUnloadDll(Package->ModuleHandle);
-
- if (Package->Name != NULL)
- {
- if (Package->Name->Buffer != NULL)
- RtlFreeHeap(RtlGetProcessHeap(), 0, Package->Name->Buffer);
-
- RtlFreeHeap(RtlGetProcessHeap(), 0, Package->Name);
- }
-
- RtlFreeHeap(RtlGetProcessHeap(), 0, Package);
- }
- }
-
- return Status;
-}
-
-
-static
-PAUTH_PACKAGE
-LsapGetAuthenticationPackage(IN ULONG PackageId)
-{
- PLIST_ENTRY ListEntry;
- PAUTH_PACKAGE Package;
-
- ListEntry = PackageListHead.Flink;
- while (ListEntry != &PackageListHead)
- {
- Package = CONTAINING_RECORD(ListEntry, AUTH_PACKAGE, Entry);
-
- if (Package->Id == PackageId)
- {
- return Package;
- }
-
- ListEntry = ListEntry->Flink;
- }
-
- return NULL;
-}
-
-
-PVOID
-NTAPI
-LsapAllocateHeap(IN ULONG Length)
-{
- return RtlAllocateHeap(RtlGetProcessHeap(), 0, Length);
-}
-
-
-PVOID
-NTAPI
-LsapAllocateHeapZero(IN ULONG Length)
-{
- return RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, Length);
-}
-
-
-VOID
-NTAPI
-LsapFreeHeap(IN PVOID Base)
-{
- RtlFreeHeap(RtlGetProcessHeap(), 0, Base);
-}
-
-
-static
-NTSTATUS
-NTAPI
-LsapAllocateClientBuffer(IN PLSA_CLIENT_REQUEST ClientRequest,
- IN ULONG LengthRequired,
- OUT PVOID *ClientBaseAddress)
-{
- PLSAP_LOGON_CONTEXT LogonContext;
- ULONG Length;
-
- *ClientBaseAddress = NULL;
-
- LogonContext = (PLSAP_LOGON_CONTEXT)ClientRequest;
-
- Length = LengthRequired;
- return NtAllocateVirtualMemory(LogonContext->ClientProcessHandle,
- ClientBaseAddress,
- 0,
- &Length,
- MEM_COMMIT,
- PAGE_READWRITE);
-}
-
-
-static
-NTSTATUS
-NTAPI
-LsapFreeClientBuffer(IN PLSA_CLIENT_REQUEST ClientRequest,
- IN PVOID ClientBaseAddress)
-{
- PLSAP_LOGON_CONTEXT LogonContext;
- ULONG Length;
-
- if (ClientBaseAddress == NULL)
- return STATUS_SUCCESS;
-
- LogonContext = (PLSAP_LOGON_CONTEXT)ClientRequest;
-
- Length = 0;
- return NtFreeVirtualMemory(LogonContext->ClientProcessHandle,
- &ClientBaseAddress,
- &Length,
- MEM_RELEASE);
-}
-
-
-static
-NTSTATUS
-NTAPI
-LsapCopyToClientBuffer(IN PLSA_CLIENT_REQUEST ClientRequest,
- IN ULONG Length,
- IN PVOID ClientBaseAddress,
- IN PVOID BufferToCopy)
-{
- PLSAP_LOGON_CONTEXT LogonContext;
-
- LogonContext = (PLSAP_LOGON_CONTEXT)ClientRequest;
-
- return NtWriteVirtualMemory(LogonContext->ClientProcessHandle,
- ClientBaseAddress,
- BufferToCopy,
- Length,
- NULL);
-}
-
-
-static
-NTSTATUS
-NTAPI
-LsapCopyFromClientBuffer(IN PLSA_CLIENT_REQUEST ClientRequest,
- IN ULONG Length,
- IN PVOID BufferToCopy,
- IN PVOID ClientBaseAddress)
-{
- PLSAP_LOGON_CONTEXT LogonContext;
-
- LogonContext = (PLSAP_LOGON_CONTEXT)ClientRequest;
-
- return NtReadVirtualMemory(LogonContext->ClientProcessHandle,
- ClientBaseAddress,
- BufferToCopy,
- Length,
- NULL);
-}
-
-
-NTSTATUS
-LsapInitAuthPackages(VOID)
-{
- RTL_QUERY_REGISTRY_TABLE AuthPackageTable[] = {
- {LsapAddAuthPackage, 0, L"Authentication Packages", NULL, REG_NONE, NULL, 0},
- {NULL, 0, NULL, NULL, REG_NONE, NULL, 0}};
-
- NTSTATUS Status;
-
- InitializeListHead(&PackageListHead);
- PackageId = 0;
-
- /* Initialize the dispatch table */
- DispatchTable.CreateLogonSession = &LsapCreateLogonSession;
- DispatchTable.DeleteLogonSession = &LsapDeleteLogonSession;
- DispatchTable.AddCredential = &LsapAddCredential;
- DispatchTable.GetCredentials = &LsapGetCredentials;
- DispatchTable.DeleteCredential = &LsapDeleteCredential;
- DispatchTable.AllocateLsaHeap = &LsapAllocateHeapZero;
- DispatchTable.FreeLsaHeap = &LsapFreeHeap;
- DispatchTable.AllocateClientBuffer = &LsapAllocateClientBuffer;
- DispatchTable.FreeClientBuffer = &LsapFreeClientBuffer;
- DispatchTable.CopyToClientBuffer = &LsapCopyToClientBuffer;
- DispatchTable.CopyFromClientBuffer = &LsapCopyFromClientBuffer;
-
- /* Add registered authentication packages */
- Status = RtlQueryRegistryValues(RTL_REGISTRY_CONTROL,
- L"Lsa",
- AuthPackageTable,
- &PackageId,
- NULL);
-
- return Status;
-}
-
-
-NTSTATUS
-LsapLookupAuthenticationPackage(PLSA_API_MSG RequestMsg,
- PLSAP_LOGON_CONTEXT LogonContext)
-{
- PLIST_ENTRY ListEntry;
- PAUTH_PACKAGE Package;
- ULONG PackageNameLength;
- PCHAR PackageName;
-
- TRACE("(%p %p)\n", RequestMsg, LogonContext);
-
- PackageNameLength = RequestMsg->LookupAuthenticationPackage.Request.PackageNameLength;
- PackageName = RequestMsg->LookupAuthenticationPackage.Request.PackageName;
-
- TRACE("PackageName: %s\n", PackageName);
-
- ListEntry = PackageListHead.Flink;
- while (ListEntry != &PackageListHead)
- {
- Package = CONTAINING_RECORD(ListEntry, AUTH_PACKAGE, Entry);
-
- if ((PackageNameLength == Package->Name->Length) &&
- (_strnicmp(PackageName, Package->Name->Buffer, Package->Name->Length) == 0))
- {
- RequestMsg->LookupAuthenticationPackage.Reply.Package = Package->Id;
- return STATUS_SUCCESS;
- }
-
- ListEntry = ListEntry->Flink;
- }
-
- return STATUS_NO_SUCH_PACKAGE;
-}
-
-
-NTSTATUS
-LsapCallAuthenticationPackage(PLSA_API_MSG RequestMsg,
- PLSAP_LOGON_CONTEXT LogonContext)
-{
- PAUTH_PACKAGE Package;
- PVOID LocalBuffer = NULL;
- ULONG PackageId;
- NTSTATUS Status;
-
- TRACE("(%p %p)\n", RequestMsg, LogonContext);
-
- PackageId = RequestMsg->CallAuthenticationPackage.Request.AuthenticationPackage;
-
- /* Get the right authentication package */
- Package = LsapGetAuthenticationPackage(PackageId);
- if (Package == NULL)
- {
- TRACE("LsapGetAuthenticationPackage() failed to find a package\n");
- return STATUS_NO_SUCH_PACKAGE;
- }
-
- if (RequestMsg->CallAuthenticationPackage.Request.SubmitBufferLength > 0)
- {
- LocalBuffer = RtlAllocateHeap(RtlGetProcessHeap(),
- HEAP_ZERO_MEMORY,
- RequestMsg->CallAuthenticationPackage.Request.SubmitBufferLength);
- if (LocalBuffer == NULL)
- {
- return STATUS_INSUFFICIENT_RESOURCES;
- }
-
- Status = NtReadVirtualMemory(LogonContext->ClientProcessHandle,
- RequestMsg->CallAuthenticationPackage.Request.ProtocolSubmitBuffer,
- LocalBuffer,
- RequestMsg->CallAuthenticationPackage.Request.SubmitBufferLength,
- NULL);
- if (!NT_SUCCESS(Status))
- {
- TRACE("NtReadVirtualMemory() failed (Status 0x%08lx)\n", Status);
- RtlFreeHeap(RtlGetProcessHeap(), 0, LocalBuffer);
- return Status;
- }
- }
-
- Status = Package->LsaApCallPackage((PLSA_CLIENT_REQUEST)LogonContext,
- LocalBuffer,
- RequestMsg->CallAuthenticationPackage.Request.ProtocolSubmitBuffer,
- RequestMsg->CallAuthenticationPackage.Request.SubmitBufferLength,
- &RequestMsg->CallAuthenticationPackage.Reply.ProtocolReturnBuffer,
- &RequestMsg->CallAuthenticationPackage.Reply.ReturnBufferLength,
- &RequestMsg->CallAuthenticationPackage.Reply.ProtocolStatus);
- if (!NT_SUCCESS(Status))
- {
- TRACE("Package->LsaApCallPackage() failed (Status 0x%08lx)\n", Status);
- }
-
- if (LocalBuffer != NULL)
- RtlFreeHeap(RtlGetProcessHeap(), 0, LocalBuffer);
-
- return Status;
-}
-
-
-static
-NTSTATUS
-LsapCopyLocalGroups(
- IN PLSAP_LOGON_CONTEXT LogonContext,
- IN PTOKEN_GROUPS ClientGroups,
- IN ULONG ClientGroupsCount,
- OUT PTOKEN_GROUPS *TokenGroups)
-{
- ULONG LocalGroupsLength = 0;
- PTOKEN_GROUPS LocalGroups = NULL;
- ULONG SidHeaderLength = 0;
- PSID SidHeader = NULL;
- PSID SrcSid, DstSid;
- ULONG SidLength;
- ULONG AllocatedSids = 0;
- ULONG i;
- NTSTATUS Status;
-
- LocalGroupsLength = sizeof(TOKEN_GROUPS) +
- (ClientGroupsCount - ANYSIZE_ARRAY) * sizeof(SID_AND_ATTRIBUTES);
- LocalGroups = RtlAllocateHeap(RtlGetProcessHeap(),
- HEAP_ZERO_MEMORY,
- LocalGroupsLength);
- if (LocalGroups == NULL)
- {
- TRACE("RtlAllocateHeap() failed\n");
- return STATUS_INSUFFICIENT_RESOURCES;
- }
-
- Status = NtReadVirtualMemory(LogonContext->ClientProcessHandle,
- ClientGroups,
- LocalGroups,
- LocalGroupsLength,
- NULL);
- if (!NT_SUCCESS(Status))
- goto done;
-
-
- SidHeaderLength = RtlLengthRequiredSid(0);
- SidHeader = RtlAllocateHeap(RtlGetProcessHeap(),
- HEAP_ZERO_MEMORY,
- SidHeaderLength);
- if (SidHeader == NULL)
- {
- Status = STATUS_INSUFFICIENT_RESOURCES;
- goto done;
- }
-
- for (i = 0; i < ClientGroupsCount; i++)
- {
- SrcSid = LocalGroups->Groups[i].Sid;
-
- Status = NtReadVirtualMemory(LogonContext->ClientProcessHandle,
- SrcSid,
- SidHeader,
- SidHeaderLength,
- NULL);
- if (!NT_SUCCESS(Status))
- goto done;
-
- SidLength = RtlLengthSid(SidHeader);
- TRACE("Sid %lu: Length %lu\n", i, SidLength);
-
- DstSid = RtlAllocateHeap(RtlGetProcessHeap(),
- HEAP_ZERO_MEMORY,
- SidLength);
- if (DstSid == NULL)
- {
- Status = STATUS_INSUFFICIENT_RESOURCES;
- goto done;
- }
-
- Status = NtReadVirtualMemory(LogonContext->ClientProcessHandle,
- SrcSid,
- DstSid,
- SidLength,
- NULL);
- if (!NT_SUCCESS(Status))
- {
- RtlFreeHeap(RtlGetProcessHeap(), 0, DstSid);
- goto done;
- }
-
- LocalGroups->Groups[i].Sid = DstSid;
- AllocatedSids++;
- }
-
- *TokenGroups = LocalGroups;
-
-done:
- if (SidHeader != NULL)
- RtlFreeHeap(RtlGetProcessHeap(), 0, SidHeader);
-
- if (!NT_SUCCESS(Status))
- {
- if (LocalGroups != NULL)
- {
- for (i = 0; i < AllocatedSids; i++)
- RtlFreeHeap(RtlGetProcessHeap(), 0, LocalGroups->Groups[i].Sid);
-
- RtlFreeHeap(RtlGetProcessHeap(), 0, LocalGroups);
- }
- }
-
- return Status;
-}
-
-
-static
-NTSTATUS
-LsapAddLocalGroups(
- IN PVOID TokenInformation,
- IN LSA_TOKEN_INFORMATION_TYPE TokenInformationType,
- IN PTOKEN_GROUPS LocalGroups)
-{
- PLSA_TOKEN_INFORMATION_V1 TokenInfo1;
- PTOKEN_GROUPS Groups;
- ULONG Length;
- ULONG i;
- ULONG j;
-
- if (LocalGroups == NULL || LocalGroups->GroupCount == 0)
- return STATUS_SUCCESS;
-
- if (TokenInformationType == LsaTokenInformationV1)
- {
- TokenInfo1 = (PLSA_TOKEN_INFORMATION_V1)TokenInformation;
-
- if (TokenInfo1->Groups != NULL)
- {
- Length = sizeof(TOKEN_GROUPS) +
- (LocalGroups->GroupCount + TokenInfo1->Groups->GroupCount - ANYSIZE_ARRAY) * sizeof(SID_AND_ATTRIBUTES);
-
- Groups = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, Length);
- if (Groups == NULL)
- {
- ERR("Group buffer allocation failed!\n");
- return STATUS_INSUFFICIENT_RESOURCES;
- }
-
- Groups->GroupCount = LocalGroups->GroupCount + TokenInfo1->Groups->GroupCount;
-
- for (i = 0; i < TokenInfo1->Groups->GroupCount; i++)
- {
- Groups->Groups[i].Sid = TokenInfo1->Groups->Groups[i].Sid;
- Groups->Groups[i].Attributes = TokenInfo1->Groups->Groups[i].Attributes;
- }
-
- for (j = 0; j < LocalGroups->GroupCount; i++, j++)
- {
- Groups->Groups[i].Sid = LocalGroups->Groups[j].Sid;
- Groups->Groups[i].Attributes = LocalGroups->Groups[j].Attributes;
- LocalGroups->Groups[j].Sid = NULL;
- }
-
- RtlFreeHeap(RtlGetProcessHeap(), 0, TokenInfo1->Groups);
-
- TokenInfo1->Groups = Groups;
- }
- else
- {
- Length = sizeof(TOKEN_GROUPS) +
- (LocalGroups->GroupCount - ANYSIZE_ARRAY) * sizeof(SID_AND_ATTRIBUTES);
-
- Groups = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, Length);
- if (Groups == NULL)
- {
- ERR("Group buffer allocation failed!\n");
- return STATUS_INSUFFICIENT_RESOURCES;
- }
-
- Groups->GroupCount = LocalGroups->GroupCount;
-
- for (i = 0; i < LocalGroups->GroupCount; i++)
- {
- Groups->Groups[i].Sid = LocalGroups->Groups[i].Sid;
- Groups->Groups[i].Attributes = LocalGroups->Groups[i].Attributes;
- }
-
- TokenInfo1->Groups = Groups;
- }
- }
- else
- {
- FIXME("TokenInformationType %d is not supported!\n", TokenInformationType);
- return STATUS_NOT_IMPLEMENTED;
- }
-
- return STATUS_SUCCESS;
-}
-
-static
-NTSTATUS
-LsapAddDefaultGroups(
- IN PVOID TokenInformation,
- IN LSA_TOKEN_INFORMATION_TYPE TokenInformationType,
- IN SECURITY_LOGON_TYPE LogonType)
-{
- PLSA_TOKEN_INFORMATION_V1 TokenInfo1;
- PTOKEN_GROUPS Groups;
- ULONG i, Length;
- PSID SrcSid;
-
- if (TokenInformationType == LsaTokenInformationV1)
- {
- TokenInfo1 = (PLSA_TOKEN_INFORMATION_V1)TokenInformation;
-
- if (TokenInfo1->Groups != NULL)
- {
- Length = sizeof(TOKEN_GROUPS) +
- (TokenInfo1->Groups->GroupCount + 2 - ANYSIZE_ARRAY) * sizeof(SID_AND_ATTRIBUTES);
-
- Groups = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, Length);
- if (Groups == NULL)
- {
- ERR("Group buffer allocation failed!\n");
- return STATUS_INSUFFICIENT_RESOURCES;
- }
-
- Groups->GroupCount = TokenInfo1->Groups->GroupCount;
-
- for (i = 0; i < TokenInfo1->Groups->GroupCount; i++)
- {
- Groups->Groups[i].Sid = TokenInfo1->Groups->Groups[i].Sid;
- Groups->Groups[i].Attributes = TokenInfo1->Groups->Groups[i].Attributes;
- }
-
- RtlFreeHeap(RtlGetProcessHeap(), 0, TokenInfo1->Groups);
-
- TokenInfo1->Groups = Groups;
-
- }
- else
- {
- Length = sizeof(TOKEN_GROUPS) +
- (2 - ANYSIZE_ARRAY) * sizeof(SID_AND_ATTRIBUTES);
-
- Groups = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, Length);
- if (Groups == NULL)
- {
- ERR("Group buffer allocation failed!\n");
- return STATUS_INSUFFICIENT_RESOURCES;
- }
-
- TokenInfo1->Groups = Groups;
- }
-
- /* Append the World SID (aka Everyone) */
- Length = RtlLengthSid(LsapWorldSid);
- Groups->Groups[Groups->GroupCount].Sid = RtlAllocateHeap(RtlGetProcessHeap(),
- HEAP_ZERO_MEMORY,
- Length);
- if (Groups->Groups[Groups->GroupCount].Sid == NULL)
- return STATUS_INSUFFICIENT_RESOURCES;
-
- RtlCopyMemory(Groups->Groups[Groups->GroupCount].Sid,
- LsapWorldSid,
- Length);
-
- Groups->Groups[Groups->GroupCount].Attributes =
- SE_GROUP_ENABLED | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_MANDATORY;
-
- Groups->GroupCount++;
-
- /* Append the logon type SID */
- switch (LogonType)
- {
- case Interactive:
- SrcSid = LsapInteractiveSid;
- break;
-
- case Network:
- SrcSid = LsapNetworkSid;
- break;
-
- case Batch:
- SrcSid = LsapBatchSid;
- break;
-
- case Service:
- SrcSid = LsapServiceSid;
- break;
-
- default:
- FIXME("LogonType %d is not supported!\n", LogonType);
- return STATUS_NOT_IMPLEMENTED;
- }
-
- Length = RtlLengthSid(SrcSid);
- Groups->Groups[Groups->GroupCount].Sid = RtlAllocateHeap(RtlGetProcessHeap(),
- HEAP_ZERO_MEMORY,
- Length);
- if (Groups->Groups[Groups->GroupCount].Sid == NULL)
- return STATUS_INSUFFICIENT_RESOURCES;
-
- RtlCopyMemory(Groups->Groups[Groups->GroupCount].Sid,
- SrcSid,
- Length);
-
- Groups->Groups[Groups->GroupCount].Attributes =
- SE_GROUP_ENABLED | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_MANDATORY;
-
- Groups->GroupCount++;
- }
- else
- {
- FIXME("TokenInformationType %d is not supported!\n", TokenInformationType);
- return STATUS_NOT_IMPLEMENTED;
- }
-
- return STATUS_SUCCESS;
-}
-
-
-static
-NTSTATUS
-LsapAppendSidToGroups(
- IN PTOKEN_GROUPS *TokenGroups,
- IN PSID DomainSid,
- IN ULONG RelativeId)
-{
- PTOKEN_GROUPS Groups;
- PSID Sid;
- ULONG Length;
- ULONG i;
-
- Sid = LsapAppendRidToSid(DomainSid, RelativeId);
- if (Sid == NULL)
- {
- ERR("Group SID creation failed!\n");
- return STATUS_INSUFFICIENT_RESOURCES;
- }
-
- if (*TokenGroups == NULL)
- {
- Length = sizeof(TOKEN_GROUPS) +
- (1 - ANYSIZE_ARRAY) * sizeof(SID_AND_ATTRIBUTES);
-
- Groups = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, Length);
- if (Groups == NULL)
- {
- ERR("Group buffer allocation failed!\n");
- return STATUS_INSUFFICIENT_RESOURCES;
- }
-
- Groups->GroupCount = 1;
-
- Groups->Groups[0].Sid = Sid;
- Groups->Groups[0].Attributes =
- SE_GROUP_ENABLED | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_MANDATORY;
-
- *TokenGroups = Groups;
- }
- else
- {
- for (i = 0; i < (*TokenGroups)->GroupCount; i++)
- {
- if (RtlEqualSid((*TokenGroups)->Groups[i].Sid, Sid))
- {
- RtlFreeHeap(RtlGetProcessHeap(), 0, Sid);
- return STATUS_SUCCESS;
- }
- }
-
- Length = sizeof(TOKEN_GROUPS) +
- ((*TokenGroups)->GroupCount + 1 - ANYSIZE_ARRAY) * sizeof(SID_AND_ATTRIBUTES);
-
- Groups = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, Length);
- if (Groups == NULL)
- {
- ERR("Group buffer allocation failed!\n");
- return STATUS_INSUFFICIENT_RESOURCES;
- }
-
- Groups->GroupCount = (*TokenGroups)->GroupCount;
-
- for (i = 0; i < (*TokenGroups)->GroupCount; i++)
- {
- Groups->Groups[i].Sid = (*TokenGroups)->Groups[i].Sid;
- Groups->Groups[i].Attributes = (*TokenGroups)->Groups[i].Attributes;
- }
-
- Groups->Groups[Groups->GroupCount].Sid = Sid;
- Groups->Groups[Groups->GroupCount].Attributes =
- SE_GROUP_ENABLED | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_MANDATORY;
-
- Groups->GroupCount++;
-
- RtlFreeHeap(RtlGetProcessHeap(), 0, *TokenGroups);
-
- *TokenGroups = Groups;
- }
-
- return STATUS_SUCCESS;
-}
-
-
-static
-NTSTATUS
-LsapAddSamGroups(
- IN PVOID TokenInformation,
- IN LSA_TOKEN_INFORMATION_TYPE TokenInformationType)
-{
- PLSA_TOKEN_INFORMATION_V1 TokenInfo1;
- SAMPR_HANDLE ServerHandle = NULL;
- SAMPR_HANDLE BuiltinDomainHandle = NULL;
- SAMPR_HANDLE AccountDomainHandle = NULL;
- SAMPR_PSID_ARRAY SidArray;
- SAMPR_ULONG_ARRAY BuiltinMembership;
- SAMPR_ULONG_ARRAY AccountMembership;
- ULONG i;
- NTSTATUS Status = STATUS_SUCCESS;
-
- if (TokenInformationType != LsaTokenInformationV1)
- return STATUS_SUCCESS;
-
- TokenInfo1 = (PLSA_TOKEN_INFORMATION_V1)TokenInformation;
-
- SidArray.Count = TokenInfo1->Groups->GroupCount + 1;
- SidArray.Sids = RtlAllocateHeap(RtlGetProcessHeap(),
- HEAP_ZERO_MEMORY,
- (TokenInfo1->Groups->GroupCount + 1) * sizeof(PRPC_SID));
- if (SidArray.Sids == NULL)
- return STATUS_INSUFFICIENT_RESOURCES;
-
- SidArray.Sids[0].SidPointer = TokenInfo1->User.User.Sid;
- for (i = 0; i < TokenInfo1->Groups->GroupCount; i++)
- SidArray.Sids[i + 1].SidPointer = TokenInfo1->Groups->Groups[i].Sid;
-
- BuiltinMembership.Element = NULL;
- AccountMembership.Element = NULL;
-
- Status = SamIConnect(NULL,
- &ServerHandle,
- SAM_SERVER_CONNECT | SAM_SERVER_LOOKUP_DOMAIN,
- FALSE);
- if (!NT_SUCCESS(Status))
- {
- TRACE("SamIConnect failed (Status %08lx)\n", Status);
- goto done;
- }
-
- Status = SamrOpenDomain(ServerHandle,
- DOMAIN_GET_ALIAS_MEMBERSHIP,
- BuiltinDomainSid,
- &BuiltinDomainHandle);
- if (!NT_SUCCESS(Status))
- {
- TRACE("SamrOpenDomain failed (Status %08lx)\n", Status);
- goto done;
- }
-
- Status = SamrOpenDomain(ServerHandle,
- DOMAIN_GET_ALIAS_MEMBERSHIP,
- AccountDomainSid,
- &AccountDomainHandle);
- if (!NT_SUCCESS(Status))
- {
- TRACE("SamrOpenDomain failed (Status %08lx)\n", Status);
- goto done;
- }
-
- Status = SamrGetAliasMembership(BuiltinDomainHandle,
- &SidArray,
- &BuiltinMembership);
- if (!NT_SUCCESS(Status))
- {
- TRACE("SamrGetAliasMembership failed (Status %08lx)\n", Status);
- goto done;
- }
-
- Status = SamrGetAliasMembership(AccountDomainHandle,
- &SidArray,
- &AccountMembership);
- if (!NT_SUCCESS(Status))
- {
- TRACE("SamrGetAliasMembership failed (Status %08lx)\n", Status);
- goto done;
- }
-
- TRACE("Builtin Memberships: %lu\n", BuiltinMembership.Count);
- for (i = 0; i < BuiltinMembership.Count; i++)
- {
- TRACE("RID %lu: %lu (0x%lx)\n", i, BuiltinMembership.Element[i], BuiltinMembership.Element[i]);
- Status = LsapAppendSidToGroups(&TokenInfo1->Groups,
- BuiltinDomainSid,
- BuiltinMembership.Element[i]);
- if (!NT_SUCCESS(Status))
- {
- TRACE("LsapAppendSidToGroups failed (Status %08lx)\n", Status);
- goto done;
- }
- }
-
- TRACE("Account Memberships: %lu\n", AccountMembership.Count);
- for (i = 0; i < AccountMembership.Count; i++)
- {
- TRACE("RID %lu: %lu (0x%lx)\n", i, AccountMembership.Element[i], AccountMembership.Element[i]);
- Status = LsapAppendSidToGroups(&TokenInfo1->Groups,
- AccountDomainSid,
- AccountMembership.Element[i]);
- if (!NT_SUCCESS(Status))
- {
- TRACE("LsapAppendSidToGroups failed (Status %08lx)\n", Status);
- goto done;
- }
- }
-
-done:
- RtlFreeHeap(RtlGetProcessHeap(), 0, SidArray.Sids);
-
- if (AccountMembership.Element != NULL)
- SamIFree_SAMPR_ULONG_ARRAY(&AccountMembership);
-
- if (BuiltinMembership.Element != NULL)
- SamIFree_SAMPR_ULONG_ARRAY(&BuiltinMembership);
-
- if (AccountDomainHandle != NULL)
- SamrCloseHandle(&AccountDomainHandle);
-
- if (BuiltinDomainHandle != NULL)
- SamrCloseHandle(&BuiltinDomainHandle);
-
- if (ServerHandle != NULL)
- SamrCloseHandle(&ServerHandle);
-
-// return Status;
-
- return STATUS_SUCCESS;
-}
-
-
-static
-NTSTATUS
-LsapSetTokenOwner(
- IN PVOID TokenInformation,
- IN LSA_TOKEN_INFORMATION_TYPE TokenInformationType)
-{
- PLSA_TOKEN_INFORMATION_V1 TokenInfo1;
- PSID OwnerSid = NULL;
- ULONG i, Length;
-
- if (TokenInformationType == LsaTokenInformationV1)
- {
- TokenInfo1 = (PLSA_TOKEN_INFORMATION_V1)TokenInformation;
-
- if (TokenInfo1->Owner.Owner != NULL)
- return STATUS_SUCCESS;
-
- OwnerSid = TokenInfo1->User.User.Sid;
- for (i = 0; i < TokenInfo1->Groups->GroupCount; i++)
- {
- if (EqualSid(TokenInfo1->Groups->Groups[i].Sid, LsapAdministratorsSid))
- {
- OwnerSid = LsapAdministratorsSid;
- break;
- }
- }
-
- Length = RtlLengthSid(OwnerSid);
- TokenInfo1->Owner.Owner = DispatchTable.AllocateLsaHeap(Length);
- if (TokenInfo1->Owner.Owner == NULL)
- return STATUS_INSUFFICIENT_RESOURCES;
-
- RtlCopyMemory(TokenInfo1->Owner.Owner,
- OwnerSid,
- Length);
- }
-
- return STATUS_SUCCESS;
-}
-
-
-static
-NTSTATUS
-LsapAddTokenDefaultDacl(
- IN PVOID TokenInformation,
- IN LSA_TOKEN_INFORMATION_TYPE TokenInformationType)
-{
- PLSA_TOKEN_INFORMATION_V1 TokenInfo1;
- PACL Dacl = NULL;
- ULONG Length;
-
- if (TokenInformationType == LsaTokenInformationV1)
- {
- TokenInfo1 = (PLSA_TOKEN_INFORMATION_V1)TokenInformation;
-
- if (TokenInfo1->DefaultDacl.DefaultDacl != NULL)
- return STATUS_SUCCESS;
-
- Length = sizeof(ACL) +
- (2 * sizeof(ACCESS_ALLOWED_ACE)) +
- RtlLengthSid(TokenInfo1->Owner.Owner) +
- RtlLengthSid(LsapLocalSystemSid);
-
- Dacl = DispatchTable.AllocateLsaHeap(Length);
- if (Dacl == NULL)
- return STATUS_INSUFFICIENT_RESOURCES;
-
- RtlCreateAcl(Dacl, Length, ACL_REVISION);
-
- RtlAddAccessAllowedAce(Dacl,
- ACL_REVISION,
- GENERIC_ALL,
- TokenInfo1->Owner.Owner);
-
- /* SID: S-1-5-18 */
- RtlAddAccessAllowedAce(Dacl,
- ACL_REVISION,
- GENERIC_ALL,
- LsapLocalSystemSid);
-
- TokenInfo1->DefaultDacl.DefaultDacl = Dacl;
- }
-
- return STATUS_SUCCESS;
-}
-
-
-static
-NTSTATUS
-LsapAddPrivilegeToTokenPrivileges(PTOKEN_PRIVILEGES *TokenPrivileges,
- PLSAPR_LUID_AND_ATTRIBUTES Privilege)
-{
- PTOKEN_PRIVILEGES LocalPrivileges;
- ULONG Length, TokenPrivilegeCount, i;
- NTSTATUS Status = STATUS_SUCCESS;
-
- if (*TokenPrivileges == NULL)
- {
- Length = sizeof(TOKEN_PRIVILEGES) +
- (1 - ANYSIZE_ARRAY) * sizeof(LUID_AND_ATTRIBUTES);
- LocalPrivileges = RtlAllocateHeap(RtlGetProcessHeap(),
- 0,
- Length);
- if (LocalPrivileges == NULL)
- return STATUS_INSUFFICIENT_RESOURCES;
-
- LocalPrivileges->PrivilegeCount = 1;
- LocalPrivileges->Privileges[0].Luid = Privilege->Luid;
- LocalPrivileges->Privileges[0].Attributes = Privilege->Attributes;
- }
- else
- {
- TokenPrivilegeCount = (*TokenPrivileges)->PrivilegeCount;
-
- for (i = 0; i < TokenPrivilegeCount; i++)
- {
- if (RtlEqualLuid(&(*TokenPrivileges)->Privileges[i].Luid, &Privilege->Luid))
- return STATUS_SUCCESS;
- }
-
- Length = sizeof(TOKEN_PRIVILEGES) +
- (TokenPrivilegeCount + 1 - ANYSIZE_ARRAY) * sizeof(LUID_AND_ATTRIBUTES);
- LocalPrivileges = RtlAllocateHeap(RtlGetProcessHeap(),
- 0,
- Length);
- if (LocalPrivileges == NULL)
- return STATUS_INSUFFICIENT_RESOURCES;
-
- LocalPrivileges->PrivilegeCount = TokenPrivilegeCount + 1;
- for (i = 0; i < TokenPrivilegeCount; i++)
- {
- LocalPrivileges->Privileges[i].Luid = (*TokenPrivileges)->Privileges[i].Luid;
- LocalPrivileges->Privileges[i].Attributes = (*TokenPrivileges)->Privileges[i].Attributes;
- }
-
- LocalPrivileges->Privileges[TokenPrivilegeCount].Luid = Privilege->Luid;
- LocalPrivileges->Privileges[TokenPrivilegeCount].Attributes = Privilege->Attributes;
-
- RtlFreeHeap(RtlGetProcessHeap(), 0, *TokenPrivileges);
- }
-
- *TokenPrivileges = LocalPrivileges;
-
- return Status;
-}
-
-static
-NTSTATUS
-LsapSetPrivileges(
- IN PVOID TokenInformation,
- IN LSA_TOKEN_INFORMATION_TYPE TokenInformationType)
-{
- PLSA_TOKEN_INFORMATION_V1 TokenInfo1;
- LSAPR_HANDLE PolicyHandle = NULL;
- LSAPR_HANDLE AccountHandle = NULL;
- PLSAPR_PRIVILEGE_SET Privileges = NULL;
- ULONG i, j;
- NTSTATUS Status;
-
- if (TokenInformationType == LsaTokenInformationV1)
- {
- TokenInfo1 = (PLSA_TOKEN_INFORMATION_V1)TokenInformation;
-
- Status = LsarOpenPolicy(NULL,
- NULL,
- 0,
- &PolicyHandle);
- if (!NT_SUCCESS(Status))
- return Status;
-
- for (i = 0; i < TokenInfo1->Groups->GroupCount; i++)
- {
- Status = LsarOpenAccount(PolicyHandle,
- TokenInfo1->Groups->Groups[i].Sid,
- ACCOUNT_VIEW,
- &AccountHandle);
- if (!NT_SUCCESS(Status))
- continue;
-
- Status = LsarEnumeratePrivilegesAccount(AccountHandle,
- &Privileges);
- if (NT_SUCCESS(Status))
- {
- for (j = 0; j < Privileges->PrivilegeCount; j++)
- {
- Status = LsapAddPrivilegeToTokenPrivileges(&TokenInfo1->Privileges,
- &(Privileges->Privilege[j]));
- if (!NT_SUCCESS(Status))
- {
- /* We failed, clean everything and return */
- LsaIFree_LSAPR_PRIVILEGE_SET(Privileges);
- LsarClose(&AccountHandle);
- LsarClose(&PolicyHandle);
-
- return Status;
- }
- }
-
- LsaIFree_LSAPR_PRIVILEGE_SET(Privileges);
- Privileges = NULL;
- }
-
- LsarClose(&AccountHandle);
- }
-
- LsarClose(&PolicyHandle);
-
- if (TokenInfo1->Privileges != NULL)
- {
- for (i = 0; i < TokenInfo1->Privileges->PrivilegeCount; i++)
- {
- if (RtlEqualLuid(&TokenInfo1->Privileges->Privileges[i].Luid, &SeChangeNotifyPrivilege) ||
- RtlEqualLuid(&TokenInfo1->Privileges->Privileges[i].Luid, &SeCreateGlobalPrivilege) ||
- RtlEqualLuid(&TokenInfo1->Privileges->Privileges[i].Luid, &SeImpersonatePrivilege))
- {
- TokenInfo1->Privileges->Privileges[i].Attributes |= SE_PRIVILEGE_ENABLED | SE_PRIVILEGE_ENABLED_BY_DEFAULT;
- }
- }
- }
- }
-
- return STATUS_SUCCESS;
-}
-
-
-NTSTATUS
-LsapLogonUser(PLSA_API_MSG RequestMsg,
- PLSAP_LOGON_CONTEXT LogonContext)
-{
- PAUTH_PACKAGE Package;
- OBJECT_ATTRIBUTES ObjectAttributes;
- SECURITY_QUALITY_OF_SERVICE Qos;
- LSA_TOKEN_INFORMATION_TYPE TokenInformationType;
- PVOID TokenInformation = NULL;
- PLSA_TOKEN_INFORMATION_V1 TokenInfo1 = NULL;
- PUNICODE_STRING AccountName = NULL;
- PUNICODE_STRING AuthenticatingAuthority = NULL;
- PUNICODE_STRING MachineName = NULL;
- PVOID LocalAuthInfo = NULL;
- PTOKEN_GROUPS LocalGroups = NULL;
- HANDLE TokenHandle = NULL;
- ULONG i;
- ULONG PackageId;
- SECURITY_LOGON_TYPE LogonType;
- NTSTATUS Status;
-
- PUNICODE_STRING UserName = NULL;
- PUNICODE_STRING LogonDomainName = NULL;
-// UNICODE_STRING LogonServer;
-
-
- TRACE("LsapLogonUser(%p %p)\n", RequestMsg, LogonContext);
-
- PackageId = RequestMsg->LogonUser.Request.AuthenticationPackage;
- LogonType = RequestMsg->LogonUser.Request.LogonType;
-
- /* Get the right authentication package */
- Package = LsapGetAuthenticationPackage(PackageId);
- if (Package == NULL)
- {
- ERR("LsapGetAuthenticationPackage() failed to find a package\n");
- return STATUS_NO_SUCH_PACKAGE;
- }
-
- if (RequestMsg->LogonUser.Request.AuthenticationInformationLength > 0)
- {
- /* Allocate the local authentication info buffer */
- LocalAuthInfo = RtlAllocateHeap(RtlGetProcessHeap(),
- HEAP_ZERO_MEMORY,
- RequestMsg->LogonUser.Request.AuthenticationInformationLength);
- if (LocalAuthInfo == NULL)
- {
- ERR("RtlAllocateHeap() failed\n");
- return STATUS_INSUFFICIENT_RESOURCES;
- }
-
- /* Read the authentication info from the callers address space */
- Status = NtReadVirtualMemory(LogonContext->ClientProcessHandle,
- RequestMsg->LogonUser.Request.AuthenticationInformation,
- LocalAuthInfo,
- RequestMsg->LogonUser.Request.AuthenticationInformationLength,
- NULL);
- if (!NT_SUCCESS(Status))
- {
- ERR("NtReadVirtualMemory() failed (Status 0x%08lx)\n", Status);
- RtlFreeHeap(RtlGetProcessHeap(), 0, LocalAuthInfo);
- return Status;
- }
- }
-
- if (RequestMsg->LogonUser.Request.LocalGroupsCount > 0)
- {
- Status = LsapCopyLocalGroups(LogonContext,
- RequestMsg->LogonUser.Request.LocalGroups,
- RequestMsg->LogonUser.Request.LocalGroupsCount,
- &LocalGroups);
- if (!NT_SUCCESS(Status))
- {
- ERR("LsapCopyLocalGroups failed (Status 0x%08lx)\n", Status);
- goto done;
- }
-
- TRACE("GroupCount: %lu\n", LocalGroups->GroupCount);
- }
-
- if (Package->LsaApLogonUserEx2 != NULL)
- {
- Status = Package->LsaApLogonUserEx2((PLSA_CLIENT_REQUEST)LogonContext,
- RequestMsg->LogonUser.Request.LogonType,
- LocalAuthInfo,
- RequestMsg->LogonUser.Request.AuthenticationInformation,
- RequestMsg->LogonUser.Request.AuthenticationInformationLength,
- &RequestMsg->LogonUser.Reply.ProfileBuffer,
- &RequestMsg->LogonUser.Reply.ProfileBufferLength,
- &RequestMsg->LogonUser.Reply.LogonId,
- &RequestMsg->LogonUser.Reply.SubStatus,
- &TokenInformationType,
- &TokenInformation,
- &AccountName,
- &AuthenticatingAuthority,
- &MachineName,
- NULL, /* FIXME: PSECPKG_PRIMARY_CRED PrimaryCredentials */
- NULL); /* FIXME: PSECPKG_SUPPLEMENTAL_CRED_ARRAY *SupplementalCredentials */
- }
- else if (Package->LsaApLogonUserEx != NULL)
- {
- Status = Package->LsaApLogonUserEx((PLSA_CLIENT_REQUEST)LogonContext,
- RequestMsg->LogonUser.Request.LogonType,
- LocalAuthInfo,
- RequestMsg->LogonUser.Request.AuthenticationInformation,
- RequestMsg->LogonUser.Request.AuthenticationInformationLength,
- &RequestMsg->LogonUser.Reply.ProfileBuffer,
- &RequestMsg->LogonUser.Reply.ProfileBufferLength,
- &RequestMsg->LogonUser.Reply.LogonId,
- &RequestMsg->LogonUser.Reply.SubStatus,
- &TokenInformationType,
- &TokenInformation,
- &AccountName,
- &AuthenticatingAuthority,
- &MachineName);
- }
- else
- {
- Status = Package->LsaApLogonUser((PLSA_CLIENT_REQUEST)LogonContext,
- RequestMsg->LogonUser.Request.LogonType,
- LocalAuthInfo,
- RequestMsg->LogonUser.Request.AuthenticationInformation,
- RequestMsg->LogonUser.Request.AuthenticationInformationLength,
- &RequestMsg->LogonUser.Reply.ProfileBuffer,
- &RequestMsg->LogonUser.Reply.ProfileBufferLength,
- &RequestMsg->LogonUser.Reply.LogonId,
- &RequestMsg->LogonUser.Reply.SubStatus,
- &TokenInformationType,
- &TokenInformation,
- &AccountName,
- &AuthenticatingAuthority);
- }
-
- if (!NT_SUCCESS(Status))
- {
- ERR("LsaApLogonUser/Ex/2 failed (Status 0x%08lx)\n", Status);
- goto done;
- }
-
- if (LocalGroups->GroupCount > 0)
- {
- /* Add local groups to the token information */
- Status = LsapAddLocalGroups(TokenInformation,
- TokenInformationType,
- LocalGroups);
- if (!NT_SUCCESS(Status))
- {
- ERR("LsapAddLocalGroupsToTokenInfo() failed (Status 0x%08lx)\n", Status);
- goto done;
- }
- }
-
- Status = LsapAddDefaultGroups(TokenInformation,
- TokenInformationType,
- LogonType);
- if (!NT_SUCCESS(Status))
- {
- ERR("LsapAddDefaultGroups() failed (Status 0x%08lx)\n", Status);
- goto done;
- }
-
- Status = LsapAddSamGroups(TokenInformation,
- TokenInformationType);
- if (!NT_SUCCESS(Status))
- {
- ERR("LsapAddSamGroups() failed (Status 0x%08lx)\n", Status);
- goto done;
- }
-
- Status = LsapSetTokenOwner(TokenInformation,
- TokenInformationType);
- if (!NT_SUCCESS(Status))
- {
- ERR("LsapSetTokenOwner() failed (Status 0x%08lx)\n", Status);
- goto done;
- }
-
- Status = LsapAddTokenDefaultDacl(TokenInformation,
- TokenInformationType);
- if (!NT_SUCCESS(Status))
- {
- ERR("LsapAddTokenDefaultDacl() failed (Status 0x%08lx)\n", Status);
- goto done;
- }
-
- Status = LsapSetPrivileges(TokenInformation,
- TokenInformationType);
- if (!NT_SUCCESS(Status))
- {
- ERR("LsapSetPrivileges() failed (Status 0x%08lx)\n", Status);
- goto done;
- }
-
- if (TokenInformationType == LsaTokenInformationV1)
- {
- TokenInfo1 = (PLSA_TOKEN_INFORMATION_V1)TokenInformation;
-
- Qos.Length = sizeof(SECURITY_QUALITY_OF_SERVICE);
- Qos.ImpersonationLevel = SecurityImpersonation;
- Qos.ContextTrackingMode = SECURITY_DYNAMIC_TRACKING;
- Qos.EffectiveOnly = FALSE;
-
- ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES);
- ObjectAttributes.RootDirectory = NULL;
- ObjectAttributes.ObjectName = NULL;
- ObjectAttributes.Attributes = 0;
- ObjectAttributes.SecurityDescriptor = NULL;
- ObjectAttributes.SecurityQualityOfService = &Qos;
-
- /* Create the logon token */
- Status = NtCreateToken(&TokenHandle,
- TOKEN_ALL_ACCESS,
- &ObjectAttributes,
- TokenPrimary,
- &RequestMsg->LogonUser.Reply.LogonId,
- &TokenInfo1->ExpirationTime,
- &TokenInfo1->User,
- TokenInfo1->Groups,
- TokenInfo1->Privileges,
- &TokenInfo1->Owner,
- &TokenInfo1->PrimaryGroup,
- &TokenInfo1->DefaultDacl,
- &RequestMsg->LogonUser.Request.SourceContext);
- if (!NT_SUCCESS(Status))
- {
- ERR("NtCreateToken failed (Status 0x%08lx)\n", Status);
- goto done;
- }
- }
- else
- {
- FIXME("TokenInformationType %d is not supported!\n", TokenInformationType);
- Status = STATUS_NOT_IMPLEMENTED;
- goto done;
- }
-
- /* Duplicate the token handle into the client process */
- Status = NtDuplicateObject(NtCurrentProcess(),
- TokenHandle,
- LogonContext->ClientProcessHandle,
- &RequestMsg->LogonUser.Reply.Token,
- 0,
- 0,
- DUPLICATE_SAME_ACCESS | DUPLICATE_SAME_ATTRIBUTES | DUPLICATE_CLOSE_SOURCE);
- if (!NT_SUCCESS(Status))
- {
- ERR("NtDuplicateObject failed (Status 0x%08lx)\n", Status);
- goto done;
- }
-
-// TokenHandle = NULL;
-
- if (LogonType == Interactive ||
- LogonType == Batch ||
- LogonType == Service)
- {
- UserName = &((PMSV1_0_INTERACTIVE_LOGON)LocalAuthInfo)->UserName;
- LogonDomainName = &((PMSV1_0_INTERACTIVE_LOGON)LocalAuthInfo)->LogonDomainName;
- }
- else
- {
- FIXME("LogonType %lu is not supported yet!\n", LogonType);
- }
-
- Status = LsapSetLogonSessionData(&RequestMsg->LogonUser.Reply.LogonId,
- LogonType,
- UserName,
- LogonDomainName,
- TokenInfo1->User.User.Sid);
- if (!NT_SUCCESS(Status))
- {
- ERR("LsapSetLogonSessionData failed (Status 0x%08lx)\n", Status);
- goto done;
- }
-
-done:
-// if (!NT_SUCCESS(Status))
-// {
- if (TokenHandle != NULL)
- NtClose(TokenHandle);
-// }
-
- /* Free the local groups */
- if (LocalGroups != NULL)
- {
- for (i = 0; i < LocalGroups->GroupCount; i++)
- {
- if (LocalGroups->Groups[i].Sid != NULL)
- RtlFreeHeap(RtlGetProcessHeap(), 0, LocalGroups->Groups[i].Sid);
- }
-
- RtlFreeHeap(RtlGetProcessHeap(), 0, LocalGroups);
- }
-
- /* Free the local authentication info buffer */
- if (LocalAuthInfo != NULL)
- RtlFreeHeap(RtlGetProcessHeap(), 0, LocalAuthInfo);
-
- /* Free the token information */
- if (TokenInformation != NULL)
- {
- if (TokenInformationType == LsaTokenInformationV1)
- {
- TokenInfo1 = (PLSA_TOKEN_INFORMATION_V1)TokenInformation;
-
- if (TokenInfo1 != NULL)
- {
- if (TokenInfo1->User.User.Sid != NULL)
- LsapFreeHeap(TokenInfo1->User.User.Sid);
-
- if (TokenInfo1->Groups != NULL)
- {
- for (i = 0; i < TokenInfo1->Groups->GroupCount; i++)
- {
- if (TokenInfo1->Groups->Groups[i].Sid != NULL)
- LsapFreeHeap(TokenInfo1->Groups->Groups[i].Sid);
- }
-
- LsapFreeHeap(TokenInfo1->Groups);
- }
-
- if (TokenInfo1->PrimaryGroup.PrimaryGroup != NULL)
- LsapFreeHeap(TokenInfo1->PrimaryGroup.PrimaryGroup);
-
- if (TokenInfo1->Privileges != NULL)
- LsapFreeHeap(TokenInfo1->Privileges);
-
- if (TokenInfo1->Owner.Owner != NULL)
- LsapFreeHeap(TokenInfo1->Owner.Owner);
-
- if (TokenInfo1->DefaultDacl.DefaultDacl != NULL)
- LsapFreeHeap(TokenInfo1->DefaultDacl.DefaultDacl);
-
- LsapFreeHeap(TokenInfo1);
- }
- }
- else
- {
- FIXME("TokenInformationType %d is not supported!\n", TokenInformationType);
- }
- }
-
- /* Free the account name */
- if (AccountName != NULL)
- {
- if (AccountName->Buffer != NULL)
- LsapFreeHeap(AccountName->Buffer);
-
- LsapFreeHeap(AccountName);
- }
-
- /* Free the authentication authority */
- if (AuthenticatingAuthority != NULL)
- {
- if (AuthenticatingAuthority != NULL)
- LsapFreeHeap(AuthenticatingAuthority->Buffer);
-
- LsapFreeHeap(AuthenticatingAuthority);
- }
-
- /* Free the machine name */
- if (MachineName != NULL)
- {
- if (MachineName->Buffer != NULL)
- LsapFreeHeap(MachineName->Buffer);
-
- LsapFreeHeap(MachineName);
- }
-
- TRACE("LsapLogonUser done (Status 0x%08lx)\n", Status);
-
- return Status;
-}
-
-/* EOF */