From 197eafa50e81c6671e75546c474a8d452d8a08d2 Mon Sep 17 00:00:00 2001 From: Eric Kohl Date: Mon, 23 May 2016 15:02:37 +0000 Subject: [PATCH] [SERVICES] RCreateServiceW: Store a given password as a secret. svn path=/trunk/; revision=71386 --- reactos/base/system/services/config.c | 55 ++++++++++++++++++++++++ reactos/base/system/services/rpcserver.c | 18 +++++--- reactos/base/system/services/services.h | 4 ++ 3 files changed, 72 insertions(+), 5 deletions(-) diff --git a/reactos/base/system/services/config.c b/reactos/base/system/services/config.c index 4a529c171d6..c3310cdccec 100644 --- a/reactos/base/system/services/config.c +++ b/reactos/base/system/services/config.c @@ -10,6 +10,7 @@ /* INCLUDES *****************************************************************/ #include "services.h" +#include #define NDEBUG #include @@ -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 */ diff --git a/reactos/base/system/services/rpcserver.c b/reactos/base/system/services/rpcserver.c index de070777b14..118b760123d 100644 --- a/reactos/base/system/services/rpcserver.c +++ b/reactos/base/system/services/rpcserver.c @@ -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, diff --git a/reactos/base/system/services/services.h b/reactos/base/system/services/services.h index 0eda7ca019f..dce0c7e1cbb 100644 --- a/reactos/base/system/services/services.h +++ b/reactos/base/system/services/services.h @@ -126,6 +126,10 @@ ScmReadDependencies(HKEY hServiceKey, LPWSTR *lpDependencies, DWORD *lpdwDependenciesLength); +DWORD +ScmSetServicePassword( + IN PCWSTR pszServiceName, + IN PCWSTR pszPassword); /* controlset.c */ -- 2.17.1