mirror of
https://github.com/reactos/reactos.git
synced 2025-01-05 22:12:46 +00:00
[MSGINA]
Use our own implementation of LogonUser instead of the one from advapi32 in order to use only one LSA connection. svn path=/trunk/; revision=61932
This commit is contained in:
parent
fbd003350e
commit
d6031f2244
5 changed files with 260 additions and 16 deletions
|
@ -829,7 +829,7 @@ DoUnlock(
|
|||
else
|
||||
{
|
||||
/* Wrong user name */
|
||||
if (DoAdminUnlock(UserName, NULL, Password))
|
||||
if (DoAdminUnlock(pgContext, UserName, NULL, Password))
|
||||
{
|
||||
*Action = WLX_SAS_ACTION_UNLOCK_WKSTA;
|
||||
res = TRUE;
|
||||
|
|
|
@ -49,4 +49,223 @@ ConnectToLsa(
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
BOOL
|
||||
MyLogonUser(
|
||||
HANDLE LsaHandle,
|
||||
ULONG AuthenticationPackage,
|
||||
LPWSTR lpszUsername,
|
||||
LPWSTR lpszDomain,
|
||||
LPWSTR lpszPassword,
|
||||
PHANDLE phToken)
|
||||
{
|
||||
SID_IDENTIFIER_AUTHORITY LocalAuthority = {SECURITY_LOCAL_SID_AUTHORITY};
|
||||
SID_IDENTIFIER_AUTHORITY SystemAuthority = {SECURITY_NT_AUTHORITY};
|
||||
PSID LogonSid = NULL;
|
||||
PSID LocalSid = NULL;
|
||||
LSA_STRING OriginName;
|
||||
UNICODE_STRING DomainName;
|
||||
UNICODE_STRING UserName;
|
||||
UNICODE_STRING Password;
|
||||
PMSV1_0_INTERACTIVE_LOGON AuthInfo = NULL;
|
||||
ULONG AuthInfoLength;
|
||||
ULONG_PTR Ptr;
|
||||
TOKEN_SOURCE TokenSource;
|
||||
PTOKEN_GROUPS TokenGroups = NULL;
|
||||
PMSV1_0_INTERACTIVE_PROFILE ProfileBuffer = NULL;
|
||||
ULONG ProfileBufferLength = 0;
|
||||
LUID Luid = {0, 0};
|
||||
LUID LogonId = {0, 0};
|
||||
HANDLE TokenHandle = NULL;
|
||||
QUOTA_LIMITS QuotaLimits;
|
||||
NTSTATUS SubStatus = STATUS_SUCCESS;
|
||||
NTSTATUS Status;
|
||||
|
||||
*phToken = NULL;
|
||||
|
||||
RtlInitAnsiString((PANSI_STRING)&OriginName,
|
||||
"MSGINA Logon");
|
||||
|
||||
RtlInitUnicodeString(&DomainName,
|
||||
lpszDomain);
|
||||
|
||||
RtlInitUnicodeString(&UserName,
|
||||
lpszUsername);
|
||||
|
||||
RtlInitUnicodeString(&Password,
|
||||
lpszPassword);
|
||||
|
||||
AuthInfoLength = sizeof(MSV1_0_INTERACTIVE_LOGON)+
|
||||
DomainName.MaximumLength +
|
||||
UserName.MaximumLength +
|
||||
Password.MaximumLength;
|
||||
|
||||
AuthInfo = RtlAllocateHeap(RtlGetProcessHeap(),
|
||||
HEAP_ZERO_MEMORY,
|
||||
AuthInfoLength);
|
||||
if (AuthInfo == NULL)
|
||||
{
|
||||
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||
goto done;
|
||||
}
|
||||
|
||||
AuthInfo->MessageType = MsV1_0InteractiveLogon;
|
||||
|
||||
Ptr = (ULONG_PTR)AuthInfo + sizeof(MSV1_0_INTERACTIVE_LOGON);
|
||||
|
||||
AuthInfo->LogonDomainName.Length = DomainName.Length;
|
||||
AuthInfo->LogonDomainName.MaximumLength = DomainName.MaximumLength;
|
||||
AuthInfo->LogonDomainName.Buffer = (DomainName.Buffer == NULL) ? NULL : (PWCHAR)Ptr;
|
||||
if (DomainName.MaximumLength > 0)
|
||||
{
|
||||
RtlCopyMemory(AuthInfo->LogonDomainName.Buffer,
|
||||
DomainName.Buffer,
|
||||
DomainName.MaximumLength);
|
||||
|
||||
Ptr += DomainName.MaximumLength;
|
||||
}
|
||||
|
||||
AuthInfo->UserName.Length = UserName.Length;
|
||||
AuthInfo->UserName.MaximumLength = UserName.MaximumLength;
|
||||
AuthInfo->UserName.Buffer = (PWCHAR)Ptr;
|
||||
if (UserName.MaximumLength > 0)
|
||||
RtlCopyMemory(AuthInfo->UserName.Buffer,
|
||||
UserName.Buffer,
|
||||
UserName.MaximumLength);
|
||||
|
||||
Ptr += UserName.MaximumLength;
|
||||
|
||||
AuthInfo->Password.Length = Password.Length;
|
||||
AuthInfo->Password.MaximumLength = Password.MaximumLength;
|
||||
AuthInfo->Password.Buffer = (PWCHAR)Ptr;
|
||||
if (Password.MaximumLength > 0)
|
||||
RtlCopyMemory(AuthInfo->Password.Buffer,
|
||||
Password.Buffer,
|
||||
Password.MaximumLength);
|
||||
|
||||
/* Create the Logon SID*/
|
||||
AllocateLocallyUniqueId(&LogonId);
|
||||
Status = RtlAllocateAndInitializeSid(&SystemAuthority,
|
||||
SECURITY_LOGON_IDS_RID_COUNT,
|
||||
SECURITY_LOGON_IDS_RID,
|
||||
LogonId.HighPart,
|
||||
LogonId.LowPart,
|
||||
SECURITY_NULL_RID,
|
||||
SECURITY_NULL_RID,
|
||||
SECURITY_NULL_RID,
|
||||
SECURITY_NULL_RID,
|
||||
SECURITY_NULL_RID,
|
||||
&LogonSid);
|
||||
if (!NT_SUCCESS(Status))
|
||||
goto done;
|
||||
|
||||
/* Create the Local SID*/
|
||||
Status = RtlAllocateAndInitializeSid(&LocalAuthority,
|
||||
1,
|
||||
SECURITY_LOCAL_RID,
|
||||
SECURITY_NULL_RID,
|
||||
SECURITY_NULL_RID,
|
||||
SECURITY_NULL_RID,
|
||||
SECURITY_NULL_RID,
|
||||
SECURITY_NULL_RID,
|
||||
SECURITY_NULL_RID,
|
||||
SECURITY_NULL_RID,
|
||||
&LocalSid);
|
||||
if (!NT_SUCCESS(Status))
|
||||
goto done;
|
||||
|
||||
/* Allocate and set the token groups */
|
||||
TokenGroups = RtlAllocateHeap(RtlGetProcessHeap(),
|
||||
HEAP_ZERO_MEMORY,
|
||||
sizeof(TOKEN_GROUPS) + ((2 - ANYSIZE_ARRAY) * sizeof(SID_AND_ATTRIBUTES)));
|
||||
if (TokenGroups == NULL)
|
||||
{
|
||||
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||
goto done;
|
||||
}
|
||||
|
||||
TokenGroups->GroupCount = 2;
|
||||
TokenGroups->Groups[0].Sid = LogonSid;
|
||||
TokenGroups->Groups[0].Attributes = SE_GROUP_MANDATORY | SE_GROUP_ENABLED |
|
||||
SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_LOGON_ID;
|
||||
TokenGroups->Groups[1].Sid = LocalSid;
|
||||
TokenGroups->Groups[1].Attributes = SE_GROUP_MANDATORY | SE_GROUP_ENABLED |
|
||||
SE_GROUP_ENABLED_BY_DEFAULT;
|
||||
|
||||
/* Set the token source */
|
||||
strcpy(TokenSource.SourceName, "LogonUser");
|
||||
AllocateLocallyUniqueId(&TokenSource.SourceIdentifier);
|
||||
|
||||
Status = LsaLogonUser(LsaHandle,
|
||||
&OriginName,
|
||||
Interactive,
|
||||
AuthenticationPackage,
|
||||
(PVOID)AuthInfo,
|
||||
AuthInfoLength,
|
||||
TokenGroups,
|
||||
&TokenSource,
|
||||
(PVOID*)&ProfileBuffer,
|
||||
&ProfileBufferLength,
|
||||
&Luid,
|
||||
&TokenHandle,
|
||||
&QuotaLimits,
|
||||
&SubStatus);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
ERR("LsaLogonUser failed (Status 0x%08lx)\n", Status);
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (ProfileBuffer != NULL)
|
||||
{
|
||||
TRACE("ProfileBuffer: %p\n", ProfileBuffer);
|
||||
TRACE("MessageType: %u\n", ProfileBuffer->MessageType);
|
||||
|
||||
TRACE("FullName: %p\n", ProfileBuffer->FullName.Buffer);
|
||||
TRACE("FullName: %S\n", ProfileBuffer->FullName.Buffer);
|
||||
|
||||
TRACE("LogonServer: %p\n", ProfileBuffer->LogonServer.Buffer);
|
||||
TRACE("LogonServer: %S\n", ProfileBuffer->LogonServer.Buffer);
|
||||
}
|
||||
|
||||
TRACE("Luid: 0x%08lx%08lx\n", Luid.HighPart, Luid.LowPart);
|
||||
|
||||
if (TokenHandle != NULL)
|
||||
{
|
||||
TRACE("TokenHandle: %p\n", TokenHandle);
|
||||
}
|
||||
|
||||
*phToken = TokenHandle;
|
||||
|
||||
done:
|
||||
if (ProfileBuffer != NULL)
|
||||
LsaFreeReturnBuffer(ProfileBuffer);
|
||||
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
if (TokenHandle != NULL)
|
||||
CloseHandle(TokenHandle);
|
||||
}
|
||||
|
||||
if (TokenGroups != NULL)
|
||||
RtlFreeHeap(RtlGetProcessHeap(), 0, TokenGroups);
|
||||
|
||||
if (LocalSid != NULL)
|
||||
RtlFreeSid(LocalSid);
|
||||
|
||||
if (LogonSid != NULL)
|
||||
RtlFreeSid(LogonSid);
|
||||
|
||||
if (AuthInfo != NULL)
|
||||
RtlFreeHeap(RtlGetProcessHeap(), 0, AuthInfo);
|
||||
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
SetLastError(RtlNtStatusToDosError(Status));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
|
|
|
@ -594,6 +594,7 @@ DuplicationString(PWSTR Str)
|
|||
|
||||
BOOL
|
||||
DoAdminUnlock(
|
||||
IN PGINA_CONTEXT pgContext,
|
||||
IN PWSTR UserName,
|
||||
IN PWSTR Domain,
|
||||
IN PWSTR Password)
|
||||
|
@ -607,12 +608,15 @@ DoAdminUnlock(
|
|||
|
||||
TRACE("(%S %S %S)\n", UserName, Domain, Password);
|
||||
|
||||
if (!LogonUserW(UserName,
|
||||
Domain,
|
||||
Password,
|
||||
LOGON32_LOGON_INTERACTIVE,
|
||||
LOGON32_PROVIDER_DEFAULT,
|
||||
&hToken))
|
||||
if (!ConnectToLsa(pgContext))
|
||||
return FALSE;
|
||||
|
||||
if (!MyLogonUser(pgContext->LsaHandle,
|
||||
pgContext->AuthenticationPackage,
|
||||
UserName,
|
||||
Domain,
|
||||
Password,
|
||||
&pgContext->UserToken))
|
||||
{
|
||||
WARN("LogonUserW() failed\n");
|
||||
return FALSE;
|
||||
|
@ -683,10 +687,15 @@ DoLoginTasks(
|
|||
DWORD dwLength;
|
||||
BOOL bResult;
|
||||
|
||||
if (!LogonUserW(UserName, Domain, Password,
|
||||
LOGON32_LOGON_INTERACTIVE,
|
||||
LOGON32_PROVIDER_DEFAULT,
|
||||
&pgContext->UserToken))
|
||||
if (!ConnectToLsa(pgContext))
|
||||
return FALSE;
|
||||
|
||||
if (!MyLogonUser(pgContext->LsaHandle,
|
||||
pgContext->AuthenticationPackage,
|
||||
UserName,
|
||||
Domain,
|
||||
Password,
|
||||
&pgContext->UserToken))
|
||||
{
|
||||
WARN("LogonUserW() failed\n");
|
||||
goto cleanup;
|
||||
|
|
|
@ -90,10 +90,20 @@ BOOL
|
|||
ConnectToLsa(
|
||||
PGINA_CONTEXT pgContext);
|
||||
|
||||
BOOL
|
||||
MyLogonUser(
|
||||
HANDLE LsaHandle,
|
||||
ULONG AuthenticationPackage,
|
||||
LPWSTR lpszUsername,
|
||||
LPWSTR lpszDomain,
|
||||
LPWSTR lpszPassword,
|
||||
PHANDLE phToken);
|
||||
|
||||
/* msgina.c */
|
||||
|
||||
BOOL
|
||||
DoAdminUnlock(
|
||||
IN PGINA_CONTEXT pgContext,
|
||||
IN PWSTR UserName,
|
||||
IN PWSTR Domain,
|
||||
IN PWSTR Password);
|
||||
|
|
|
@ -233,14 +233,20 @@ TUILockedSAS(
|
|||
if (!ReadString(IDS_ASKFORPASSWORD, Password, 256, FALSE))
|
||||
return WLX_SAS_ACTION_NONE;
|
||||
|
||||
if (!LogonUserW(UserName, NULL, Password,
|
||||
LOGON32_LOGON_UNLOCK,
|
||||
LOGON32_PROVIDER_DEFAULT,
|
||||
&hToken))
|
||||
if (!ConnectToLsa(pgContext))
|
||||
return WLX_SAS_ACTION_NONE;
|
||||
|
||||
if (!MyLogonUser(pgContext->LsaHandle,
|
||||
pgContext->AuthenticationPackage,
|
||||
UserName,
|
||||
NULL,
|
||||
Password,
|
||||
&hToken))
|
||||
{
|
||||
TRACE("LogonUserW() failed\n");
|
||||
WARN("LogonUserW() failed\n");
|
||||
return WLX_SAS_ACTION_NONE;
|
||||
}
|
||||
|
||||
CloseHandle(hToken);
|
||||
return WLX_SAS_ACTION_UNLOCK_WKSTA;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue