* COPYRIGHT: Copyright 2013 Eric Kohl
*/
-/* INCLUDES ****************************************************************/
-
#include "lsasrv.h"
-WINE_DEFAULT_DEBUG_CHANNEL(lsasrv);
-
typedef enum _LSA_TOKEN_INFORMATION_TYPE
{
LsaTokenInformationNull,
typedef PVOID PLSA_CLIENT_REQUEST;
+typedef NTSTATUS (NTAPI *PLSA_CREATE_LOGON_SESSION)(PLUID);
+typedef NTSTATUS (NTAPI *PLSA_DELETE_LOGON_SESSION)(PLUID);
+
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 struct LSA_DISPATCH_TABLE
{
- PVOID /*PLSA_CREATE_LOGON_SESSION */ CreateLogonSession;
- PVOID /*PLSA_DELETE_LOGON_SESSION */ DeleteLogonSession;
+ PLSA_CREATE_LOGON_SESSION CreateLogonSession;
+ PLSA_DELETE_LOGON_SESSION DeleteLogonSession;
PVOID /*PLSA_ADD_CREDENTIAL */ AddCredential;
PVOID /*PLSA_GET_CREDENTIALS */ GetCredentials;
PVOID /*PLSA_DELETE_CREDENTIAL */ DeleteCredential;
}
-static
-NTSTATUS
-NTAPI
-LsapCreateLogonSession(IN PLUID LogonId)
-{
- TRACE("()\n");
- return STATUS_SUCCESS;
-}
-
-
-static
-NTSTATUS
-NTAPI
-LsapDeleteLogonSession(IN PLUID LogonId)
-{
- TRACE("()\n");
- return STATUS_SUCCESS;
-}
-
-
static
PVOID
NTAPI
&PackageId,
NULL);
-
- return STATUS_SUCCESS;
+ 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
+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;
+}
+
+
NTSTATUS
LsapLogonUser(PLSA_API_MSG RequestMsg,
PLSAP_LOGON_CONTEXT LogonContext)
PUNICODE_STRING AuthenticatingAuthority = NULL;
PUNICODE_STRING MachineName = NULL;
PVOID LocalAuthInfo = NULL;
+ PTOKEN_GROUPS LocalGroups = NULL;
HANDLE TokenHandle = NULL;
ULONG i;
ULONG PackageId;
Package = LsapGetAuthenticationPackage(PackageId);
if (Package == NULL)
{
- TRACE("LsapGetAuthenticationPackage() failed to find a package\n");
+ ERR("LsapGetAuthenticationPackage() failed to find a package\n");
return STATUS_NO_SUCH_PACKAGE;
}
RequestMsg->LogonUser.Request.AuthenticationInformationLength);
if (LocalAuthInfo == NULL)
{
- TRACE("RtlAllocateHeap() failed\n");
+ ERR("RtlAllocateHeap() failed\n");
return STATUS_INSUFFICIENT_RESOURCES;
}
NULL);
if (!NT_SUCCESS(Status))
{
- TRACE("NtReadVirtualMemory() failed (Status 0x%08lx)\n", 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,
if (!NT_SUCCESS(Status))
{
- TRACE("LsaApLogonUser/Ex/2 failed (Status 0x%08lx)\n", Status);
+ ERR("LsaApLogonUser/Ex/2 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;
}
&RequestMsg->LogonUser.Request.SourceContext);
if (!NT_SUCCESS(Status))
{
- TRACE("NtCreateToken failed (Status 0x%08lx)\n", Status);
+ ERR("NtCreateToken failed (Status 0x%08lx)\n", Status);
goto done;
}
}
DUPLICATE_SAME_ACCESS | DUPLICATE_SAME_ATTRIBUTES | DUPLICATE_CLOSE_SOURCE);
if (!NT_SUCCESS(Status))
{
- TRACE("NtDuplicateObject failed (Status 0x%08lx)\n", Status);
+ ERR("NtDuplicateObject failed (Status 0x%08lx)\n", Status);
goto done;
}
TokenHandle = NULL;
+ Status = LsapSetLogonSessionData(&RequestMsg->LogonUser.Reply.LogonId);
+ if (!NT_SUCCESS(Status))
+ {
+ ERR("LsapSetLogonSessionData failed (Status 0x%08lx)\n", Status);
+ goto done;
+ }
+
done:
if (!NT_SUCCESS(Status))
{
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)
}
}
+ /* 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;
}