From ade0d2cda58e0f3fef5943c51437efb7b9a6f139 Mon Sep 17 00:00:00 2001 From: Eric Kohl Date: Mon, 2 Jan 2017 20:45:36 +0000 Subject: [PATCH] =?UTF-8?q?[SERVICES]=20-=20Add=20loading=20(not=20used=20?= =?UTF-8?q?yet)=20and=20unloading=20of=20user=20profiles.=20-=20Create=20t?= =?UTF-8?q?he=20service=20password=20secret=20name=20and=20pass=20it=20to?= =?UTF-8?q?=20LogonUserW.=20Patch=20by=20Herm=C3=A8s=20B=C3=89LUSCA=20-=20?= =?UTF-8?q?MA=C3=8FTO.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit svn path=/trunk/; revision=73501 --- reactos/base/system/services/database.c | 78 ++++++++++++++++++++----- reactos/base/system/services/services.h | 1 + 2 files changed, 64 insertions(+), 15 deletions(-) diff --git a/reactos/base/system/services/database.c b/reactos/base/system/services/database.c index 6188ecfeb05..176ba15e3f5 100644 --- a/reactos/base/system/services/database.c +++ b/reactos/base/system/services/database.c @@ -192,12 +192,15 @@ ScmLogonService( IN PSERVICE_IMAGE pImage) { #if 0 - PWSTR pUserName = NULL; - PWSTR pDomainName = NULL; + PROFILEINFOW ProfileInfo; + PWSTR pszUserName = NULL; + PWSTR pszDomainName = NULL; + PWSTR pszPassword = NULL; PWSTR ptr; DWORD dwError = ERROR_SUCCESS; #endif - DPRINT("ScmLogonService()\n"); + + DPRINT("ScmLogonService(%p %p)\n", pService, pImage); DPRINT("Service %S\n", pService->lpServiceName); @@ -208,40 +211,77 @@ ScmLogonService( return ERROR_SUCCESS; #if 0 + /* Get the user and domain names */ ptr = wcschr(pImage->pszAccountName, L'\\'); if (ptr != NULL) { *ptr = L'\0'; - pUserName = ptr + 1; - pDomainName = pImage->pszAccountName; + pszUserName = ptr + 1; + pszDomainName = pImage->pszAccountName; } else { - pUserName = pImage->pszAccountName; - pDomainName = NULL; + pszUserName = pImage->pszAccountName; + pszDomainName = NULL; } - if (pDomainName == NULL || wcscmp(pDomainName, L".") == 0) + /* Build the service 'password' */ + pszPassword = HeapAlloc(GetProcessHeap(), + HEAP_ZERO_MEMORY, + (wcslen(pService->lpServiceName) + 5) * sizeof(WCHAR)); + if (pszPassword == NULL) { - // pDomainName = computer name + dwError = ERROR_NOT_ENOUGH_MEMORY; + goto done; } - DPRINT("Domain: %S User: %S\n", pDomainName, pUserName); + wcscpy(pszPassword, L"_SC_"); + wcscat(pszPassword, pService->lpServiceName); - /* Logon the user */ - // FIXME: Use the password!! - if (!LogonUserW(pUserName, - pDomainName, - L"", // FIXME: lpszPassword, + DPRINT("Domain: %S User: %S Password: %S\n", pszDomainName, pszUserName, pszPassword); + + /* Service logon */ + if (!LogonUserW(pszUserName, + pszDomainName, + pszPassword, LOGON32_LOGON_SERVICE, LOGON32_PROVIDER_DEFAULT, &pImage->hToken)) { dwError = GetLastError(); DPRINT1("LogonUserW() failed (Error %lu)\n", dwError); + goto done; } + // FIXME: Call LoadUserProfileW to be able to initialize a per-user + // environment block, with user-specific environment variables as + // %USERNAME%, %USERPROFILE%, and %ALLUSERSPROFILE% correctly initialized!! + + /* Load the user profile, so that the per-user environment variables can be initialized */ + ZeroMemory(&ProfileInfo, sizeof(ProfileInfo)); + ProfileInfo.dwSize = sizeof(ProfileInfo); + ProfileInfo.dwFlags = PI_NOUI; + ProfileInfo.lpUserName = pszUserName; + // ProfileInfo.lpProfilePath = NULL; + // ProfileInfo.lpDefaultPath = NULL; + // ProfileInfo.lpServerName = NULL; + // ProfileInfo.lpPolicyPath = NULL; + // ProfileInfo.hProfile = NULL; + + if (!LoadUserProfileW(pImage->hToken, &ProfileInfo)) + { + dwError = GetLastError(); + DPRINT1("LoadUserProfileW() failed (Error %lu)\n", dwError); + goto done; + } + + pImage->hProfile = ProfileInfo.hProfile; + +done: + if (pszPassword != NULL) + HeapFree(GetProcessHeap(), 0, pszPassword); + if (ptr != NULL) *ptr = L'\\'; @@ -348,6 +388,10 @@ ScmCreateOrReferenceServiceImage(PSERVICE pService) { DPRINT1("ScmCreateNewControlPipe() failed (Error %lu)\n", dwError); + /* Unload the user profile */ + if (pServiceImage->hProfile != NULL) + UnloadUserProfile(pServiceImage->hToken, pServiceImage->hProfile); + /* Close the logon token */ if (pServiceImage->hToken != NULL) CloseHandle(pServiceImage->hToken); @@ -421,6 +465,10 @@ ScmDereferenceServiceImage(PSERVICE_IMAGE pServiceImage) if (pServiceImage->hControlPipe != INVALID_HANDLE_VALUE) CloseHandle(pServiceImage->hControlPipe); + /* Unload the user profile */ + if (pServiceImage->hProfile != NULL) + UnloadUserProfile(pServiceImage->hToken, pServiceImage->hProfile); + /* Close the logon token */ if (pServiceImage->hToken != NULL) CloseHandle(pServiceImage->hToken); diff --git a/reactos/base/system/services/services.h b/reactos/base/system/services/services.h index 7e034868c15..1d20f120d1d 100644 --- a/reactos/base/system/services/services.h +++ b/reactos/base/system/services/services.h @@ -51,6 +51,7 @@ typedef struct _SERVICE_IMAGE HANDLE hProcess; DWORD dwProcessId; HANDLE hToken; + HANDLE hProfile; } SERVICE_IMAGE, *PSERVICE_IMAGE;