reactos/base/services/seclogon/rpcserver.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;
}