From f4982e547d0743e4e656f3e3ed496a6b44cdd7a6 Mon Sep 17 00:00:00 2001 From: Eric Kohl Date: Mon, 21 Feb 2022 16:38:29 +0100 Subject: [PATCH] [ADVAPI32][SECLOGON] Start the implementation of CreateProcessWithLogonW --- base/services/seclogon/CMakeLists.txt | 2 +- base/services/seclogon/precomp.h | 1 + base/services/seclogon/rpcserver.c | 49 +++++++++++- dll/win32/advapi32/CMakeLists.txt | 2 + dll/win32/advapi32/advapi32.h | 9 +++ dll/win32/advapi32/wine/security.c | 104 ++++++++++++++++++++++---- sdk/include/reactos/idl/seclogon.idl | 2 + 7 files changed, 151 insertions(+), 18 deletions(-) diff --git a/base/services/seclogon/CMakeLists.txt b/base/services/seclogon/CMakeLists.txt index 8ab9611b965..b9aa2910fa7 100644 --- a/base/services/seclogon/CMakeLists.txt +++ b/base/services/seclogon/CMakeLists.txt @@ -17,6 +17,6 @@ add_library(seclogon MODULE set_module_type(seclogon win32dll UNICODE) target_link_libraries(seclogon wine ${PSEH_LIB}) -add_importlibs(seclogon advapi32 rpcrt4 msvcrt kernel32 ntdll) +add_importlibs(seclogon userenv advapi32 rpcrt4 msvcrt kernel32 ntdll) add_pch(seclogon precomp.h SOURCE) add_cd_file(TARGET seclogon DESTINATION reactos/system32 FOR all) diff --git a/base/services/seclogon/precomp.h b/base/services/seclogon/precomp.h index ca2dd3fc80c..f8101a484c0 100644 --- a/base/services/seclogon/precomp.h +++ b/base/services/seclogon/precomp.h @@ -20,6 +20,7 @@ #include #include #include +#include #define NTOS_MODE_USER #include diff --git a/base/services/seclogon/rpcserver.c b/base/services/seclogon/rpcserver.c index 991ea703f4a..b927ca7e868 100644 --- a/base/services/seclogon/rpcserver.c +++ b/base/services/seclogon/rpcserver.c @@ -59,6 +59,12 @@ SeclCreateProcessWithLogonW( _In_ SECL_REQUEST *pRequest, _Out_ SECL_RESPONSE *pResponse) { + PROFILEINFOW ProfileInfo; + HANDLE hToken = NULL; + + ULONG dwError = ERROR_SUCCESS; + BOOL rc; + TRACE("SeclCreateProcessWithLogonW(%p %p %p)\n", hBinding, pRequest, pResponse); if (pRequest != NULL) @@ -69,12 +75,51 @@ SeclCreateProcessWithLogonW( 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); } - /* FIXME: Logon */ + 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; + } + } /* FIXME: Create Process */ +done: + if (ProfileInfo.hProfile != NULL) + UnloadUserProfile(hToken, ProfileInfo.hProfile); + + if (hToken != NULL) + CloseHandle(hToken); + if (pResponse != NULL) - pResponse->ulError = 4; + pResponse->ulError = dwError; } diff --git a/dll/win32/advapi32/CMakeLists.txt b/dll/win32/advapi32/CMakeLists.txt index 3e0d816d72e..cb2e495b1da 100644 --- a/dll/win32/advapi32/CMakeLists.txt +++ b/dll/win32/advapi32/CMakeLists.txt @@ -11,6 +11,7 @@ include_directories( add_rpc_files(client ${REACTOS_SOURCE_DIR}/sdk/include/reactos/idl/eventlogrpc.idl ${REACTOS_SOURCE_DIR}/sdk/include/reactos/idl/lsa.idl + ${REACTOS_SOURCE_DIR}/sdk/include/reactos/idl/seclogon.idl ${REACTOS_SOURCE_DIR}/sdk/include/reactos/idl/svcctl.idl ${REACTOS_SOURCE_DIR}/sdk/include/reactos/idl/winreg.idl) @@ -49,6 +50,7 @@ list(APPEND PCH_SKIP_SOURCE ${CMAKE_CURRENT_BINARY_DIR}/advapi32_stubs.c ${CMAKE_CURRENT_BINARY_DIR}/eventlogrpc_c.c ${CMAKE_CURRENT_BINARY_DIR}/lsa_c.c + ${CMAKE_CURRENT_BINARY_DIR}/seclogon_c.c ${CMAKE_CURRENT_BINARY_DIR}/svcctl_c.c ${CMAKE_CURRENT_BINARY_DIR}/winreg_c.c) diff --git a/dll/win32/advapi32/advapi32.h b/dll/win32/advapi32/advapi32.h index 77312e7654c..cf3d195304f 100644 --- a/dll/win32/advapi32/advapi32.h +++ b/dll/win32/advapi32/advapi32.h @@ -36,6 +36,7 @@ #include #include +#include #include #include @@ -70,6 +71,14 @@ RPC_STATUS EvtUnbindLocalHandle(void); DWORD ScmRpcStatusToWinError(RPC_STATUS Status); +/* sysfunc.h */ +NTSTATUS +WINAPI +SystemFunction034( + _In_ RPC_BINDING_HANDLE BindingHandle, + INT b, + _Out_ LPBYTE SessionKey); + /* Interface to ntmarta.dll **************************************************/ typedef struct _NTMARTA diff --git a/dll/win32/advapi32/wine/security.c b/dll/win32/advapi32/wine/security.c index 5651a92276a..4b20be2b14c 100644 --- a/dll/win32/advapi32/wine/security.c +++ b/dll/win32/advapi32/wine/security.c @@ -4,7 +4,7 @@ * Copyright 1999, 2000 Juergen Schmied * Copyright 2003 CodeWeavers Inc. (Ulrich Czekalla) * Copyright 2006 Robert Reif - * Copyright 2006 Hervé Poussineau + * Copyright 2006 HervĂ© Poussineau * * PROJECT: ReactOS system libraries * FILE: dll/win32/advapi32/wine/security.c @@ -3475,25 +3475,99 @@ ConvertSidToStringSidA(PSID Sid, /* * @unimplemented */ -BOOL WINAPI -CreateProcessWithLogonW(LPCWSTR lpUsername, - LPCWSTR lpDomain, - LPCWSTR lpPassword, - DWORD dwLogonFlags, - LPCWSTR lpApplicationName, - LPWSTR lpCommandLine, - DWORD dwCreationFlags, - LPVOID lpEnvironment, - LPCWSTR lpCurrentDirectory, - LPSTARTUPINFOW lpStartupInfo, - LPPROCESS_INFORMATION lpProcessInformation) +BOOL +WINAPI +CreateProcessWithLogonW( + _In_ LPCWSTR lpUsername, + _In_opt_ LPCWSTR lpDomain, + _In_ LPCWSTR lpPassword, + _In_ DWORD dwLogonFlags, + _In_opt_ LPCWSTR lpApplicationName, + _Inout_opt_ LPWSTR lpCommandLine, + _In_ DWORD dwCreationFlags, + _In_opt_ LPVOID lpEnvironment, + _In_opt_ LPCWSTR lpCurrentDirectory, + _In_ LPSTARTUPINFOW lpStartupInfo, + _Out_ LPPROCESS_INFORMATION lpProcessInformation) { - FIXME("%s %s %s 0x%08x %s %s 0x%08x %p %s %p %p stub\n", debugstr_w(lpUsername), debugstr_w(lpDomain), + LPWSTR pszStringBinding = NULL; + handle_t hBinding = NULL; + SECL_REQUEST Request; + SECL_RESPONSE Response; + RPC_STATUS Status; + + TRACE("CreateProcessWithLogonW(%s %s %s 0x%08x %s %s 0x%08x %p %s %p %p)\n", debugstr_w(lpUsername), debugstr_w(lpDomain), debugstr_w(lpPassword), dwLogonFlags, debugstr_w(lpApplicationName), debugstr_w(lpCommandLine), dwCreationFlags, lpEnvironment, debugstr_w(lpCurrentDirectory), lpStartupInfo, lpProcessInformation); - return FALSE; + Status = RpcStringBindingComposeW(NULL, + L"ncacn_np", + NULL, + L"\\pipe\\seclogon", + NULL, + &pszStringBinding); + if (Status != RPC_S_OK) + { + WARN("RpcStringBindingCompose returned 0x%x\n", Status); + SetLastError(Status); + return FALSE; + } + + /* Set the binding handle that will be used to bind to the server. */ + Status = RpcBindingFromStringBindingW(pszStringBinding, + &hBinding); + if (Status != RPC_S_OK) + { + WARN("RpcBindingFromStringBinding returned 0x%x\n", Status); + } + + Status = RpcStringFreeW(&pszStringBinding); + if (Status != RPC_S_OK) + { + WARN("RpcStringFree returned 0x%x\n", Status); + } + + Request.Username = (LPWSTR)lpUsername; + Request.Domain = (LPWSTR)lpDomain; + Request.Password = (LPWSTR)lpPassword; + Request.ApplicationName = (LPWSTR)lpApplicationName; + Request.CommandLine = (LPWSTR)lpCommandLine; + Request.CurrentDirectory = (LPWSTR)lpCurrentDirectory; + + Request.dwLogonFlags = dwLogonFlags; + Request.dwCreationFlags = dwCreationFlags; + + Response.ulError = ERROR_SUCCESS; + + RpcTryExcept + { + SeclCreateProcessWithLogonW(hBinding, &Request, &Response); + } + RpcExcept(EXCEPTION_EXECUTE_HANDLER) + { + WARN("Exception: %lx\n", RpcExceptionCode()); + } + RpcEndExcept; + + if (hBinding) + { + Status = RpcBindingFree(&hBinding); + if (Status != RPC_S_OK) + { + WARN("RpcBindingFree returned 0x%x\n", Status); + } + + hBinding = NULL; + } + + TRACE("Response.ulError %lu\n", Response.ulError); + if (Response.ulError != ERROR_SUCCESS) + SetLastError(Response.ulError); + + TRACE("CreateProcessWithLogonW() done\n"); + + return (Response.ulError == ERROR_SUCCESS); } BOOL WINAPI CreateProcessWithTokenW(HANDLE token, DWORD logon_flags, LPCWSTR application_name, LPWSTR command_line, diff --git a/sdk/include/reactos/idl/seclogon.idl b/sdk/include/reactos/idl/seclogon.idl index dd3392ae349..c605176e16f 100644 --- a/sdk/include/reactos/idl/seclogon.idl +++ b/sdk/include/reactos/idl/seclogon.idl @@ -12,6 +12,8 @@ typedef struct _SECL_REQUEST [string] WCHAR *ApplicationName; [string] WCHAR *CommandLine; [string] WCHAR *CurrentDirectory; + DWORD dwLogonFlags; + DWORD dwCreationFlags; } SECL_REQUEST, *PSECL_REQUEST; typedef struct _SECL_RESPONSE