[SERVICES]
authorEric Kohl <eric.kohl@reactos.org>
Mon, 23 May 2016 15:02:37 +0000 (15:02 +0000)
committerEric Kohl <eric.kohl@reactos.org>
Mon, 23 May 2016 15:02:37 +0000 (15:02 +0000)
RCreateServiceW: Store a given password as a secret.

svn path=/trunk/; revision=71386

reactos/base/system/services/config.c
reactos/base/system/services/rpcserver.c
reactos/base/system/services/services.h

index 4a529c1..c3310cd 100644 (file)
@@ -10,6 +10,7 @@
 /* INCLUDES *****************************************************************/
 
 #include "services.h"
+#include <ntsecapi.h>
 
 #define NDEBUG
 #include <debug.h>
@@ -443,4 +444,58 @@ ScmReadDependencies(HKEY hServiceKey,
     return ERROR_SUCCESS;
 }
 
+
+DWORD
+ScmSetServicePassword(
+    IN PCWSTR pszServiceName,
+    IN PCWSTR pszPassword)
+{
+    OBJECT_ATTRIBUTES ObjectAttributes;
+    LSA_HANDLE PolicyHandle = NULL;
+    UNICODE_STRING ServiceName = {0, 0, NULL};
+    UNICODE_STRING Password;
+    NTSTATUS Status;
+    DWORD dwError = ERROR_SUCCESS;
+
+    RtlZeroMemory(&ObjectAttributes, sizeof(OBJECT_ATTRIBUTES));
+
+    Status = LsaOpenPolicy(NULL,
+                           &ObjectAttributes,
+                           POLICY_CREATE_SECRET,
+                           &PolicyHandle);
+    if (!NT_SUCCESS(Status))
+        return RtlNtStatusToDosError(Status);
+
+    ServiceName.Length = (wcslen(pszServiceName) + 4) * sizeof(WCHAR);
+    ServiceName.MaximumLength = ServiceName.Length + sizeof(WCHAR);
+    ServiceName.Buffer = HeapAlloc(GetProcessHeap(),
+                                   HEAP_ZERO_MEMORY,
+                                   ServiceName.MaximumLength);
+    if (ServiceName.Buffer == NULL)
+        return ERROR_NOT_ENOUGH_MEMORY;
+
+    wcscpy(ServiceName.Buffer, L"_SC_");
+    wcscat(ServiceName.Buffer, pszServiceName);
+
+    RtlInitUnicodeString(&Password, pszPassword);
+
+    Status = LsaStorePrivateData(PolicyHandle,
+                                 &ServiceName,
+                                 &Password);
+    if (!NT_SUCCESS(Status))
+    {
+        dwError = RtlNtStatusToDosError(Status);
+        goto done;
+    }
+
+done:
+    if (ServiceName.Buffer != NULL)
+        HeapFree(GetProcessHeap(), 0, ServiceName.Buffer);
+
+    if (PolicyHandle != NULL)
+        LsaClose(PolicyHandle);
+
+    return dwError;
+}
+
 /* EOF */
index de07077..118b760 100644 (file)
@@ -2323,6 +2323,7 @@ DWORD RCreateServiceW(
             goto done;
     }
 
+    /* Set the service tag */
     if (lpdwTagId != NULL)
     {
         dwError = RegSetValueExW(hServiceKey,
@@ -2345,9 +2346,10 @@ DWORD RCreateServiceW(
             goto done;
     }
 
-    /* Write service start name */
+    /* Start name and password are only used by Win32 services */
     if (dwServiceType & SERVICE_WIN32)
     {
+        /* Write service start name */
         lpObjectName = (lpServiceStartName != NULL) ? (LPWSTR)lpServiceStartName : L"LocalSystem";
         dwError = RegSetValueExW(hServiceKey,
                                  L"ObjectName",
@@ -2357,11 +2359,17 @@ DWORD RCreateServiceW(
                                  (DWORD)((wcslen(lpObjectName) + 1) * sizeof(WCHAR)));
         if (dwError != ERROR_SUCCESS)
             goto done;
-    }
 
-    if (lpPassword != NULL)
-    {
-        /* FIXME: Decrypt and write password */
+        if (lpPassword != NULL && wcslen((LPWSTR)lpPassword) != 0)
+        {
+            /* FIXME: Decrypt the password */
+
+            /* Write the password */
+            dwError = ScmSetServicePassword(lpServiceName,
+                                            (LPCWSTR)lpPassword);
+            if (dwError != ERROR_SUCCESS)
+                goto done;
+        }
     }
 
     dwError = ScmCreateServiceHandle(lpService,
index 0eda7ca..dce0c7e 100644 (file)
@@ -126,6 +126,10 @@ ScmReadDependencies(HKEY hServiceKey,
                     LPWSTR *lpDependencies,
                     DWORD *lpdwDependenciesLength);
 
+DWORD
+ScmSetServicePassword(
+    IN PCWSTR pszServiceName,
+    IN PCWSTR pszPassword);
 
 /* controlset.c */