From cce01fa95c3370d100c0c77205013dc70973cf1c Mon Sep 17 00:00:00 2001 From: Eric Kohl Date: Tue, 6 Dec 2016 17:29:30 +0000 Subject: [PATCH] =?UTF-8?q?[SERVICES]=20Create=20a=20new=20environment=20b?= =?UTF-8?q?lock=20when=20a=20service=20process=20is=20started.=20Patch=20b?= =?UTF-8?q?y=20Herm=C3=A8s=20B=C3=89LUSCA=20-=20MA=C3=8FTO.=20CORE-12414?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit svn path=/trunk/; revision=73433 --- reactos/base/system/services/CMakeLists.txt | 2 +- reactos/base/system/services/database.c | 81 ++++++++++++++++++--- 2 files changed, 70 insertions(+), 13 deletions(-) diff --git a/reactos/base/system/services/CMakeLists.txt b/reactos/base/system/services/CMakeLists.txt index ddb4994da7d..0005294b04b 100644 --- a/reactos/base/system/services/CMakeLists.txt +++ b/reactos/base/system/services/CMakeLists.txt @@ -26,6 +26,6 @@ if(NOT MSVC) endif() set_module_type(services win32gui UNICODE) -add_importlibs(services user32 advapi32 rpcrt4 msvcrt kernel32 ntdll) +add_importlibs(services userenv user32 advapi32 rpcrt4 msvcrt kernel32 ntdll) add_pch(services services.h SOURCE) add_cd_file(TARGET services DESTINATION reactos/system32 FOR all) diff --git a/reactos/base/system/services/database.c b/reactos/base/system/services/database.c index 167d6917349..fbe1f21b4e7 100644 --- a/reactos/base/system/services/database.c +++ b/reactos/base/system/services/database.c @@ -14,7 +14,7 @@ #include "services.h" -#include +#include #define NDEBUG #include @@ -1681,6 +1681,7 @@ ScmStartUserModeService(PSERVICE Service, { PROCESS_INFORMATION ProcessInformation; STARTUPINFOW StartupInfo; + LPVOID lpEnvironment; BOOL Result; DWORD dwError = ERROR_SUCCESS; @@ -1698,17 +1699,73 @@ ScmStartUserModeService(PSERVICE Service, StartupInfo.cb = sizeof(StartupInfo); ZeroMemory(&ProcessInformation, sizeof(ProcessInformation)); - Result = CreateProcessAsUserW(Service->lpImage->hToken, - NULL, - Service->lpImage->pszImagePath, - NULL, - NULL, - FALSE, - DETACHED_PROCESS | CREATE_SUSPENDED, - NULL, - NULL, - &StartupInfo, - &ProcessInformation); + /* Use the interactive desktop if the service is interactive */ + if (Service->Status.dwServiceType & SERVICE_INTERACTIVE_PROCESS) + StartupInfo.lpDesktop = L"winsta0\\default"; + + if (Service->lpImage->hToken) + { + /* User token: Run the service under the user account */ + + if (!CreateEnvironmentBlock(&lpEnvironment, Service->lpImage->hToken, FALSE)) + { + /* We failed, run the service with the current environment */ + DPRINT1("CreateEnvironmentBlock() failed with error %d, service '%S' will run with the current environment.\n", + Service->lpServiceName, GetLastError()); + lpEnvironment = NULL; + } + + /* Impersonate the new user */ + if (!ImpersonateLoggedOnUser(Service->lpImage->hToken)) + { + dwError = GetLastError(); + DPRINT1("ImpersonateLoggedOnUser() failed with error %d\n", GetLastError()); + return dwError; + } + + /* Launch the process in the user's logon session */ + Result = CreateProcessAsUserW(Service->lpImage->hToken, + NULL, + Service->lpImage->pszImagePath, + NULL, + NULL, + FALSE, + CREATE_UNICODE_ENVIRONMENT | DETACHED_PROCESS | CREATE_SUSPENDED, + lpEnvironment, + NULL, + &StartupInfo, + &ProcessInformation); + + /* Revert the impersonation */ + RevertToSelf(); + } + else + { + /* No user token: Run the service under the LocalSystem account */ + + if (!CreateEnvironmentBlock(&lpEnvironment, NULL, TRUE)) + { + /* We failed, run the service with the current environment */ + DPRINT1("CreateEnvironmentBlock() failed with error %d, service '%S' will run with the current environment.\n", + Service->lpServiceName, GetLastError()); + lpEnvironment = NULL; + } + + Result = CreateProcessW(NULL, + Service->lpImage->pszImagePath, + NULL, + NULL, + FALSE, + CREATE_UNICODE_ENVIRONMENT | DETACHED_PROCESS | CREATE_SUSPENDED, + lpEnvironment, + NULL, + &StartupInfo, + &ProcessInformation); + } + + if (lpEnvironment) + DestroyEnvironmentBlock(lpEnvironment); + if (!Result) { dwError = GetLastError();