mirror of
https://github.com/reactos/reactos.git
synced 2024-08-30 07:08:19 +00:00
199 lines
5.6 KiB
C
199 lines
5.6 KiB
C
/*
|
|
* PROJECT: ReactOS Secondary Logon Service
|
|
* LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
|
|
* PURPOSE: Secondary Logon service RPC server
|
|
* COPYRIGHT: Eric Kohl 2022 <eric.kohl@reactos.org>
|
|
*/
|
|
|
|
/* INCLUDES *****************************************************************/
|
|
|
|
#include "precomp.h"
|
|
|
|
#include <seclogon_s.h>
|
|
|
|
WINE_DEFAULT_DEBUG_CHANNEL(seclogon);
|
|
|
|
/* FUNCTIONS *****************************************************************/
|
|
|
|
|
|
void __RPC_FAR * __RPC_USER midl_user_allocate(SIZE_T len)
|
|
{
|
|
return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len);
|
|
}
|
|
|
|
|
|
void __RPC_USER midl_user_free(void __RPC_FAR * ptr)
|
|
{
|
|
HeapFree(GetProcessHeap(), 0, ptr);
|
|
}
|
|
|
|
|
|
DWORD
|
|
StartRpcServer(VOID)
|
|
{
|
|
NTSTATUS Status;
|
|
|
|
Status = lpServiceGlobals->StartRpcServer(L"seclogon", ISeclogon_v1_0_s_ifspec);
|
|
TRACE("StartRpcServer returned 0x%08lx\n", Status);
|
|
|
|
return RtlNtStatusToDosError(Status);
|
|
}
|
|
|
|
|
|
DWORD
|
|
StopRpcServer(VOID)
|
|
{
|
|
NTSTATUS Status;
|
|
|
|
Status = lpServiceGlobals->StopRpcServer(ISeclogon_v1_0_s_ifspec);
|
|
TRACE("StopRpcServer returned 0x%08lx\n", Status);
|
|
|
|
return RtlNtStatusToDosError(Status);
|
|
}
|
|
|
|
|
|
VOID
|
|
__stdcall
|
|
SeclCreateProcessWithLogonW(
|
|
_In_ handle_t hBinding,
|
|
_In_ SECL_REQUEST *pRequest,
|
|
_Out_ SECL_RESPONSE *pResponse)
|
|
{
|
|
STARTUPINFOW StartupInfo;
|
|
PROCESS_INFORMATION ProcessInfo;
|
|
|
|
PROFILEINFOW ProfileInfo;
|
|
HANDLE hToken = NULL;
|
|
HANDLE hTargetProcessHandle = NULL;
|
|
|
|
ULONG dwError = ERROR_SUCCESS;
|
|
BOOL rc;
|
|
|
|
TRACE("SeclCreateProcessWithLogonW(%p %p %p)\n", hBinding, pRequest, pResponse);
|
|
|
|
if (pRequest != NULL)
|
|
{
|
|
TRACE("Username: '%S'\n", pRequest->Username);
|
|
TRACE("Domain: '%S'\n", pRequest->Domain);
|
|
TRACE("Password: '%S'\n", pRequest->Password);
|
|
TRACE("ApplicationName: '%S'\n", pRequest->ApplicationName);
|
|
TRACE("CommandLine: '%S'\n", pRequest->CommandLine);
|
|
TRACE("CurrentDirectory: '%S'\n", pRequest->CurrentDirectory);
|
|
TRACE("LogonFlags: 0x%lx\n", pRequest->dwLogonFlags);
|
|
TRACE("CreationFlags: 0x%lx\n", pRequest->dwCreationFlags);
|
|
TRACE("ProcessId: %lu\n", pRequest->dwProcessId);
|
|
}
|
|
|
|
hTargetProcessHandle = OpenProcess(PROCESS_DUP_HANDLE,
|
|
FALSE,
|
|
pRequest->dwProcessId);
|
|
if (hTargetProcessHandle == NULL)
|
|
{
|
|
dwError = GetLastError();
|
|
WARN("OpenProcess() failed with Error %lu\n", dwError);
|
|
goto done;
|
|
}
|
|
|
|
ZeroMemory(&ProfileInfo, sizeof(ProfileInfo));
|
|
|
|
/* Logon */
|
|
rc = LogonUser(pRequest->Username,
|
|
pRequest->Domain,
|
|
pRequest->Password,
|
|
LOGON32_LOGON_INTERACTIVE,
|
|
LOGON32_PROVIDER_DEFAULT,
|
|
&hToken);
|
|
if (rc == FALSE)
|
|
{
|
|
dwError = GetLastError();
|
|
WARN("LogonUser() failed with Error %lu\n", dwError);
|
|
goto done;
|
|
}
|
|
|
|
/* Load the user profile */
|
|
if (pRequest->dwLogonFlags & LOGON_WITH_PROFILE)
|
|
{
|
|
ProfileInfo.dwSize = sizeof(ProfileInfo);
|
|
ProfileInfo.lpUserName = pRequest->Username;
|
|
|
|
rc = LoadUserProfileW(hToken,
|
|
&ProfileInfo);
|
|
if (rc == FALSE)
|
|
{
|
|
dwError = GetLastError();
|
|
WARN("LoadUserProfile() failed with Error %lu\n", dwError);
|
|
goto done;
|
|
}
|
|
}
|
|
|
|
/* Initialize the startup information */
|
|
ZeroMemory(&StartupInfo, sizeof(StartupInfo));
|
|
StartupInfo.cb = sizeof(StartupInfo);
|
|
|
|
/* FIXME: Get startup info from the caller */
|
|
|
|
/* Initialize the process information */
|
|
ZeroMemory(&ProcessInfo, sizeof(ProcessInfo));
|
|
|
|
/* Create Process */
|
|
rc = CreateProcessAsUserW(hToken,
|
|
pRequest->ApplicationName,
|
|
pRequest->CommandLine,
|
|
NULL, // lpProcessAttributes,
|
|
NULL, // lpThreadAttributes,
|
|
FALSE, // bInheritHandles,
|
|
pRequest->dwCreationFlags,
|
|
pRequest->Environment, // lpEnvironment,
|
|
pRequest->CurrentDirectory,
|
|
&StartupInfo,
|
|
&ProcessInfo);
|
|
if (rc == FALSE)
|
|
{
|
|
dwError = GetLastError();
|
|
WARN("CreateProcessAsUser() failed with Error %lu\n", dwError);
|
|
goto done;
|
|
}
|
|
|
|
/* Return process info to the caller */
|
|
if (pResponse != NULL)
|
|
{
|
|
DuplicateHandle(GetCurrentProcess(),
|
|
ProcessInfo.hProcess,
|
|
hTargetProcessHandle,
|
|
(PHANDLE)&pResponse->hProcess,
|
|
0,
|
|
FALSE,
|
|
DUPLICATE_SAME_ACCESS);
|
|
|
|
DuplicateHandle(GetCurrentProcess(),
|
|
ProcessInfo.hThread,
|
|
hTargetProcessHandle,
|
|
(PHANDLE)&pResponse->hThread,
|
|
0,
|
|
FALSE,
|
|
DUPLICATE_SAME_ACCESS);
|
|
|
|
pResponse->dwProcessId = ProcessInfo.dwProcessId;
|
|
pResponse->dwThreadId = ProcessInfo.dwThreadId;
|
|
}
|
|
|
|
done:
|
|
if (hTargetProcessHandle)
|
|
CloseHandle(hTargetProcessHandle);
|
|
|
|
if (ProcessInfo.hThread)
|
|
CloseHandle(ProcessInfo.hThread);
|
|
|
|
if (ProcessInfo.hProcess)
|
|
CloseHandle(ProcessInfo.hProcess);
|
|
|
|
if (ProfileInfo.hProfile != NULL)
|
|
UnloadUserProfile(hToken, ProfileInfo.hProfile);
|
|
|
|
if (hToken != NULL)
|
|
CloseHandle(hToken);
|
|
|
|
if (pResponse != NULL)
|
|
pResponse->dwError = dwError;
|
|
}
|