[SERVICES]
authorEric Kohl <eric.kohl@reactos.org>
Mon, 2 Jan 2017 20:45:36 +0000 (20:45 +0000)
committerEric Kohl <eric.kohl@reactos.org>
Mon, 2 Jan 2017 20:45:36 +0000 (20:45 +0000)
- Add loading (not used yet) and unloading of user profiles.
- Create the service password secret name and pass it to LogonUserW.
Patch by Hermès BÉLUSCA - MAÏTO.

svn path=/trunk/; revision=73501

reactos/base/system/services/database.c
reactos/base/system/services/services.h

index 6188ecf..176ba15 100644 (file)
@@ -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);
index 7e03486..1d20f12 100644 (file)
@@ -51,6 +51,7 @@ typedef struct _SERVICE_IMAGE
     HANDLE hProcess;
     DWORD dwProcessId;
     HANDLE hToken;
+    HANDLE hProfile;
 } SERVICE_IMAGE, *PSERVICE_IMAGE;