Author: ekohl
Date: Sat May 28 21:56:56 2016
New Revision: 71449

URL: http://svn.reactos.org/svn/reactos?rev=71449&view=rev
Log:
[SERVICES]
Prepare service logon.

Modified:
    trunk/reactos/base/system/services/database.c
    trunk/reactos/base/system/services/rpcserver.c
    trunk/reactos/base/system/services/services.h

Modified: trunk/reactos/base/system/services/database.c
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/base/system/services/database.c?rev=71449&r1=71448&r2=71449&view=diff
==============================================================================
--- trunk/reactos/base/system/services/database.c       [iso-8859-1] (original)
+++ trunk/reactos/base/system/services/database.c       [iso-8859-1] Sat May 28 
21:56:56 2016
@@ -140,9 +140,9 @@
         CurrentImage = CONTAINING_RECORD(ImageEntry,
                                          SERVICE_IMAGE,
                                          ImageListEntry);
-        if (_wcsicmp(CurrentImage->szImagePath, lpImagePath) == 0)
-        {
-            DPRINT("Found image: '%S'\n", CurrentImage->szImagePath);
+        if (_wcsicmp(CurrentImage->pszImagePath, lpImagePath) == 0)
+        {
+            DPRINT("Found image: '%S'\n", CurrentImage->pszImagePath);
             return CurrentImage;
         }
 
@@ -153,21 +153,114 @@
 
     return NULL;
 
+}
+
+
+static
+BOOL
+ScmIsSameServiceAccount(
+    IN PWSTR pszAccountName1,
+    IN PWSTR pszAccountName2)
+{
+    if ((pszAccountName1 == NULL && pszAccountName2 == NULL) ||
+        (pszAccountName1 == NULL && wcscmp(pszAccountName2, L"LocalSystem") == 
0) ||
+        (pszAccountName2 == NULL && wcscmp(pszAccountName1, L"LocalSystem") == 
0) ||
+        (wcscmp(pszAccountName1, pszAccountName2) == 0))
+        return TRUE;
+
+    return FALSE;
+}
+
+
+static
+BOOL
+ScmIsLocalSystemAccount(
+    IN PWSTR pszAccountName)
+{
+    if (pszAccountName == NULL ||
+        wcscmp(pszAccountName, L"LocalSystem") == 0)
+        return TRUE;
+
+    return FALSE;
+}
+
+
+static
+DWORD
+ScmLogonService(
+    IN PSERVICE pService,
+    IN PSERVICE_IMAGE pImage)
+{
+    PWSTR pUserName = NULL;
+    PWSTR pDomainName = NULL;
+    PWSTR ptr;
+    DWORD dwError = ERROR_SUCCESS;
+
+    DPRINT("ScmLogonService()\n");
+
+    DPRINT("Service %S\n", pService->lpServiceName);
+
+    if (ScmIsLocalSystemAccount(pImage->pszAccountName))
+        return ERROR_SUCCESS;
+
+    ptr = wcschr(pImage->pszAccountName, L'\\');
+    if (ptr != NULL)
+    {
+        *ptr = 0;
+
+        pUserName = ptr + 1;
+        pDomainName = pImage->pszAccountName;
+    }
+    else
+    {
+        pUserName = pImage->pszAccountName;
+        pDomainName = NULL;
+    }
+
+    if (pDomainName == NULL || wcscmp(pDomainName, L".") == 0)
+    {
+        // pDomainName = computer name
+    }
+
+    DPRINT("Domain: %S  User: %S\n", pDomainName, pUserName);
+
+    /* FIXME */
+#if 0
+    if (!LogonUserW(pUserName,
+                    pDomainName,
+                    L"", // lpszPassword,
+                    LOGON32_LOGON_SERVICE,
+                    LOGON32_PROVIDER_DEFAULT,
+                    &pImage->hToken))
+    {
+        dwError = GetLastError();
+        DPRINT1("LogonUserW() failed (Error %lu)\n", dwError);
+    }
+#endif
+
+    if (ptr != NULL)
+        *ptr = L'\\';
+
+    return dwError;
 }
 
 
 static DWORD
 ScmCreateOrReferenceServiceImage(PSERVICE pService)
 {
-    RTL_QUERY_REGISTRY_TABLE QueryTable[2];
+    RTL_QUERY_REGISTRY_TABLE QueryTable[3];
     UNICODE_STRING ImagePath;
+    UNICODE_STRING ObjectName;
     PSERVICE_IMAGE pServiceImage = NULL;
     NTSTATUS Status;
     DWORD dwError = ERROR_SUCCESS;
+    DWORD dwRecordSize;
+    LPWSTR pString;
 
     DPRINT("ScmCreateOrReferenceServiceImage(%p)\n", pService);
 
     RtlInitUnicodeString(&ImagePath, NULL);
+    RtlInitUnicodeString(&ObjectName, NULL);
 
     /* Get service data */
     RtlZeroMemory(&QueryTable,
@@ -176,6 +269,9 @@
     QueryTable[0].Name = L"ImagePath";
     QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT | 
RTL_QUERY_REGISTRY_REQUIRED;
     QueryTable[0].EntryContext = &ImagePath;
+    QueryTable[1].Name = L"ObjectName";
+    QueryTable[1].Flags = RTL_QUERY_REGISTRY_DIRECT;
+    QueryTable[1].EntryContext = &ObjectName;
 
     Status = RtlQueryRegistryValues(RTL_REGISTRY_SERVICES,
                                     pService->lpServiceName,
@@ -189,14 +285,19 @@
     }
 
     DPRINT("ImagePath: '%wZ'\n", &ImagePath);
+    DPRINT("ObjectName: '%wZ'\n", &ObjectName);
 
     pServiceImage = ScmGetServiceImageByImagePath(ImagePath.Buffer);
     if (pServiceImage == NULL)
     {
+        dwRecordSize = sizeof(SERVICE_IMAGE) +
+                       ImagePath.Length + sizeof(WCHAR) +
+                       ((ObjectName.Length != 0) ? (ObjectName.Length + 
sizeof(WCHAR)) : 0);
+
         /* Create a new service image */
         pServiceImage = HeapAlloc(GetProcessHeap(),
                                   HEAP_ZERO_MEMORY,
-                                  FIELD_OFFSET(SERVICE_IMAGE, 
szImagePath[ImagePath.Length / sizeof(WCHAR) + 1]));
+                                  dwRecordSize);
         if (pServiceImage == NULL)
         {
             dwError = ERROR_NOT_ENOUGH_MEMORY;
@@ -206,11 +307,30 @@
         pServiceImage->dwImageRunCount = 1;
         pServiceImage->hControlPipe = INVALID_HANDLE_VALUE;
 
+        pString = (PWSTR)((INT_PTR)pServiceImage + sizeof(SERVICE_IMAGE));
+
         /* Set the image path */
-        wcscpy(pServiceImage->szImagePath,
+        pServiceImage->pszImagePath = pString;
+        wcscpy(pServiceImage->pszImagePath,
                ImagePath.Buffer);
 
-        RtlFreeUnicodeString(&ImagePath);
+        /* Set the account name */
+        if (ObjectName.Length > 0)
+        {
+            pString = pString + wcslen(pString) + 1;
+
+            pServiceImage->pszAccountName = pString;
+            wcscpy(pServiceImage->pszAccountName,
+                   ObjectName.Buffer);
+        }
+
+        /* Service logon */
+        dwError = ScmLogonService(pService, pServiceImage);
+        if (dwError != ERROR_SUCCESS)
+        {
+            DPRINT1("ScmLogonService() failed (Error %lu)\n", dwError);
+            goto done;
+        }
 
         /* Create the control pipe */
         dwError = ScmCreateNewControlPipe(pServiceImage);
@@ -229,16 +349,28 @@
     }
     else
     {
+//        if ((lpService->Status.dwServiceType & SERVICE_WIN32_SHARE_PROCESS) 
== 0)
+
+        /* Fail if services in an image use different accounts */
+        if (!ScmIsSameServiceAccount(pServiceImage->pszAccountName, 
ObjectName.Buffer))
+        {
+            dwError = ERROR_DIFFERENT_SERVICE_ACCOUNT;
+            goto done;
+        }
+
         /* Increment the run counter */
         pServiceImage->dwImageRunCount++;
     }
 
+    DPRINT("pServiceImage->pszImagePath: %S\n", pServiceImage->pszImagePath);
+    DPRINT("pServiceImage->pszAccountName: %S\n", 
pServiceImage->pszAccountName);
     DPRINT("pServiceImage->dwImageRunCount: %lu\n", 
pServiceImage->dwImageRunCount);
 
     /* Link the service image to the service */
     pService->lpImage = pServiceImage;
 
-done:;
+done:
+    RtlFreeUnicodeString(&ObjectName);
     RtlFreeUnicodeString(&ImagePath);
 
     DPRINT("ScmCreateOrReferenceServiceImage() done (Error: %lu)\n", dwError);
@@ -262,6 +394,10 @@
 
         /* Remove the service image from the list */
         RemoveEntryList(&pServiceImage->ImageListEntry);
+
+        /* Close the logon token */
+        if (pServiceImage->hToken != NULL)
+            CloseHandle(pServiceImage->hToken);
 
         /* Close the control pipe */
         if (pServiceImage->hControlPipe != INVALID_HANDLE_VALUE)
@@ -1566,16 +1702,17 @@
     StartupInfo.cb = sizeof(StartupInfo);
     ZeroMemory(&ProcessInformation, sizeof(ProcessInformation));
 
-    Result = CreateProcessW(NULL,
-                            Service->lpImage->szImagePath,
-                            NULL,
-                            NULL,
-                            FALSE,
-                            DETACHED_PROCESS | CREATE_SUSPENDED,
-                            NULL,
-                            NULL,
-                            &StartupInfo,
-                            &ProcessInformation);
+    Result = CreateProcessAsUserW(Service->lpImage->hToken,
+                                  NULL,
+                                  Service->lpImage->pszImagePath,
+                                  NULL,
+                                  NULL,
+                                  FALSE,
+                                  DETACHED_PROCESS | CREATE_SUSPENDED,
+                                  NULL,
+                                  NULL,
+                                  &StartupInfo,
+                                  &ProcessInformation);
     if (!Result)
     {
         dwError = GetLastError();

Modified: trunk/reactos/base/system/services/rpcserver.c
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/base/system/services/rpcserver.c?rev=71449&r1=71448&r2=71449&view=diff
==============================================================================
--- trunk/reactos/base/system/services/rpcserver.c      [iso-8859-1] (original)
+++ trunk/reactos/base/system/services/rpcserver.c      [iso-8859-1] Sat May 28 
21:56:56 2016
@@ -1992,6 +1992,7 @@
             goto done;
     }
 
+    /* Set the tag */
     if (lpdwTagId != NULL)
     {
         dwError = ScmAssignNewTag(lpService);

Modified: trunk/reactos/base/system/services/services.h
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/base/system/services/services.h?rev=71449&r1=71448&r2=71449&view=diff
==============================================================================
--- trunk/reactos/base/system/services/services.h       [iso-8859-1] (original)
+++ trunk/reactos/base/system/services/services.h       [iso-8859-1] Sat May 28 
21:56:56 2016
@@ -43,13 +43,14 @@
 typedef struct _SERVICE_IMAGE
 {
     LIST_ENTRY ImageListEntry;
+    LPWSTR pszImagePath;
+    LPWSTR pszAccountName;
     DWORD dwImageRunCount;
 
     HANDLE hControlPipe;
     HANDLE hProcess;
     DWORD dwProcessId;
-
-    WCHAR szImagePath[1];
+    HANDLE hToken;
 } SERVICE_IMAGE, *PSERVICE_IMAGE;
 
 


Reply via email to