X-Git-Url: https://git.reactos.org/?p=reactos.git;a=blobdiff_plain;f=base%2Fsystem%2Fservices%2Fconfig.c;h=14af8e5b0f16cdee639df040bb96dd0a8b4116d8;hp=0bdd98f23b925e186ec4df504cdf9cc1b377ec07;hb=5e2c4657ca10dea1154cb43f16ee6962999ac7a4;hpb=5eb7c07bb896c1f0d7e263566c8491ca724afd1b diff --git a/base/system/services/config.c b/base/system/services/config.c index 0bdd98f23b9..14af8e5b0f1 100644 --- a/base/system/services/config.c +++ b/base/system/services/config.c @@ -10,10 +10,12 @@ /* INCLUDES *****************************************************************/ #include "services.h" +#include #define NDEBUG #include + /* FUNCTIONS *****************************************************************/ @@ -129,6 +131,7 @@ ScmWriteDependencies(HKEY hServiceKey, if (*lpSrc == SC_GROUP_IDENTIFIERW) { lpSrc++; + cchLength--; cchGroupLength += cchLength; wcscpy(lpDst, lpSrc); lpDst = lpDst + cchLength; @@ -442,4 +445,260 @@ 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, + pszPassword ? &Password : NULL); + 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; +} + + +DWORD +ScmWriteSecurityDescriptor( + _In_ HKEY hServiceKey, + _In_ PSECURITY_DESCRIPTOR pSecurityDescriptor) +{ + HKEY hSecurityKey = NULL; + DWORD dwDisposition; + DWORD dwError; + + DPRINT("ScmWriteSecurityDescriptor(%p %p)\n", hServiceKey, pSecurityDescriptor); + + dwError = RegCreateKeyExW(hServiceKey, + L"Security", + 0, + NULL, + REG_OPTION_NON_VOLATILE, + KEY_SET_VALUE, + NULL, + &hSecurityKey, + &dwDisposition); + if (dwError != ERROR_SUCCESS) + return dwError; + + dwError = RegSetValueExW(hSecurityKey, + L"Security", + 0, + REG_BINARY, + (LPBYTE)pSecurityDescriptor, + RtlLengthSecurityDescriptor(pSecurityDescriptor)); + + RegCloseKey(hSecurityKey); + + return dwError; +} + + +DWORD +ScmReadSecurityDescriptor( + _In_ HKEY hServiceKey, + _Out_ PSECURITY_DESCRIPTOR *ppSecurityDescriptor) +{ + PSECURITY_DESCRIPTOR pRelativeSD = NULL; + HKEY hSecurityKey = NULL; + DWORD dwBufferLength = 0; + DWORD dwType; + DWORD dwError; + + DPRINT("ScmReadSecurityDescriptor(%p %p)\n", hServiceKey, ppSecurityDescriptor); + + *ppSecurityDescriptor = NULL; + + dwError = RegOpenKeyExW(hServiceKey, + L"Security", + 0, + KEY_QUERY_VALUE, + &hSecurityKey); + if (dwError != ERROR_SUCCESS) + { + DPRINT("RegOpenKeyExW() failed (Error %lu)\n", dwError); + + /* Do not fail if the Security key does not exist */ + if (dwError == ERROR_FILE_NOT_FOUND) + dwError = ERROR_SUCCESS; + goto done; + } + + dwError = RegQueryValueExW(hSecurityKey, + L"Security", + 0, + &dwType, + NULL, + &dwBufferLength); + if (dwError != ERROR_SUCCESS) + { + DPRINT("RegQueryValueExW() failed (Error %lu)\n", dwError); + + /* Do not fail if the Security value does not exist */ + if (dwError == ERROR_FILE_NOT_FOUND) + dwError = ERROR_SUCCESS; + goto done; + } + + DPRINT("dwBufferLength: %lu\n", dwBufferLength); + pRelativeSD = RtlAllocateHeap(RtlGetProcessHeap(), + HEAP_ZERO_MEMORY, + dwBufferLength); + if (pRelativeSD == NULL) + { + return ERROR_OUTOFMEMORY; + } + + DPRINT("pRelativeSD: %lu\n", pRelativeSD); + dwError = RegQueryValueExW(hSecurityKey, + L"Security", + 0, + &dwType, + (LPBYTE)pRelativeSD, + &dwBufferLength); + if (dwError != ERROR_SUCCESS) + { + goto done; + } + + *ppSecurityDescriptor = pRelativeSD; + +done: + if (dwError != ERROR_SUCCESS && pRelativeSD != NULL) + RtlFreeHeap(RtlGetProcessHeap(), 0, pRelativeSD); + + if (hSecurityKey != NULL) + RegCloseKey(hSecurityKey); + + return dwError; +} + + +DWORD +ScmDeleteRegKey( + _In_ HKEY hKey, + _In_ PCWSTR pszSubKey) +{ + DWORD dwMaxSubkeyLen, dwMaxValueLen; + DWORD dwMaxLen, dwSize; + PWSTR pszName = NULL; + HKEY hSubKey; + DWORD dwError; + + dwError = RegOpenKeyExW(hKey, pszSubKey, 0, KEY_READ, &hSubKey); + if (dwError != ERROR_SUCCESS) + return dwError; + + /* Get maximum length of key and value names */ + dwError = RegQueryInfoKeyW(hSubKey, NULL, NULL, NULL, NULL, + &dwMaxSubkeyLen, NULL, NULL, &dwMaxValueLen, NULL, NULL, NULL); + if (dwError != ERROR_SUCCESS) + goto done; + + dwMaxSubkeyLen++; + dwMaxValueLen++; + dwMaxLen = max(dwMaxSubkeyLen, dwMaxValueLen); + + /* Allocate the name buffer */ + pszName = HeapAlloc(GetProcessHeap(), 0, dwMaxLen * sizeof(WCHAR)); + if (pszName == NULL) + { + dwError = ERROR_NOT_ENOUGH_MEMORY; + goto done; + } + + /* Recursively delete all the subkeys */ + while (TRUE) + { + dwSize = dwMaxLen; + if (RegEnumKeyExW(hSubKey, 0, pszName, &dwSize, + NULL, NULL, NULL, NULL) != ERROR_SUCCESS) + { + break; + } + + dwError = ScmDeleteRegKey(hSubKey, pszName); + if (dwError != ERROR_SUCCESS) + goto done; + } + +done: + if (pszName != NULL) + HeapFree(GetProcessHeap(), 0, pszName); + + RegCloseKey(hSubKey); + + /* Finally delete the key */ + if (dwError == ERROR_SUCCESS) + dwError = RegDeleteKeyW(hKey, pszSubKey); + + return dwError; +} + + +DWORD +ScmDecryptPassword( + _In_ PBYTE pPassword, + _In_ DWORD dwPasswordSize, + _Out_ PWSTR *pClearTextPassword) +{ + PWSTR pBuffer; + + /* Allocate a buffer for the decrypted password */ + pBuffer = HeapAlloc(GetProcessHeap(), 0, dwPasswordSize); + if (pBuffer == NULL) + return ERROR_OUTOFMEMORY; + + /* Decrypt the password */ + CopyMemory(pBuffer, + pPassword, + dwPasswordSize); + + *pClearTextPassword = pBuffer; + + return ERROR_SUCCESS; +} + /* EOF */