From 5965ffcd7859925d4d364be53370845e11472144 Mon Sep 17 00:00:00 2001 From: Eric Kohl Date: Sat, 11 Jun 2016 09:41:05 +0000 Subject: [PATCH] [SERVICES] - Read the service security descriptors when the service list is created. - Assign and write the default security descriptor when a service does not have its own security desciptor. - Delete a service security desciptor when the service is deleted. svn path=/trunk/; revision=71611 --- reactos/base/system/services/config.c | 56 ++++++++++++++++++++++--- reactos/base/system/services/database.c | 28 +++++++++++-- reactos/base/system/services/services.h | 5 +++ 3 files changed, 80 insertions(+), 9 deletions(-) diff --git a/reactos/base/system/services/config.c b/reactos/base/system/services/config.c index b4263b16c13..c3998c34d51 100644 --- a/reactos/base/system/services/config.c +++ b/reactos/base/system/services/config.c @@ -586,10 +586,17 @@ ScmReadSecurityDescriptor( _Out_ PSECURITY_DESCRIPTOR *ppSecurityDescriptor) { PSECURITY_DESCRIPTOR pRelativeSD = NULL; + PSECURITY_DESCRIPTOR pResizedBuffer = NULL; HKEY hSecurityKey = NULL; DWORD dwBufferLength = 0; + DWORD dwAbsoluteSDSize = 0; DWORD dwType; DWORD dwError; + NTSTATUS Status; + + DPRINT("ScmReadSecurityDescriptor()\n"); + + *ppSecurityDescriptor = NULL; dwError = RegOpenKeyExW(hServiceKey, L"Security", @@ -598,7 +605,11 @@ ScmReadSecurityDescriptor( &hSecurityKey); if (dwError != ERROR_SUCCESS) { -DPRINT1("\n"); + 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; } @@ -610,19 +621,24 @@ DPRINT1("\n"); &dwBufferLength); if (dwError != ERROR_SUCCESS) { -DPRINT1("\n"); + 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) { -DPRINT1("\n"); return ERROR_OUTOFMEMORY; } + DPRINT("pRelativeSD: %lu\n", pRelativeSD); dwError = RegQueryValueExW(hSecurityKey, L"Security", 0, @@ -631,20 +647,48 @@ DPRINT1("\n"); &dwBufferLength); if (dwError != ERROR_SUCCESS) { -DPRINT1("\n"); goto done; } + Status = RtlSelfRelativeToAbsoluteSD2(pRelativeSD, + &dwAbsoluteSDSize); + if (Status == STATUS_BUFFER_TOO_SMALL) + { + pResizedBuffer = RtlReAllocateHeap(RtlGetProcessHeap(), + 0, + pRelativeSD, + dwAbsoluteSDSize); + if (pResizedBuffer == NULL) + { + dwError = ERROR_OUTOFMEMORY; + goto done; + } + pRelativeSD = pResizedBuffer; + Status = RtlSelfRelativeToAbsoluteSD2(pRelativeSD, + &dwAbsoluteSDSize); + if (!NT_SUCCESS(Status)) + { + dwError = RtlNtStatusToDosError(Status); + goto done; + } + } + else if (!NT_SUCCESS(Status)) + { + + dwError = RtlNtStatusToDosError(Status); + goto done; + } + + *ppSecurityDescriptor = pRelativeSD; done: - if (pRelativeSD != NULL) + if (dwError != ERROR_SUCCESS && pRelativeSD != NULL) RtlFreeHeap(RtlGetProcessHeap(), 0, pRelativeSD); if (hSecurityKey != NULL) RegCloseKey(hSecurityKey); - return dwError; } diff --git a/reactos/base/system/services/database.c b/reactos/base/system/services/database.c index 2b78b71f047..aee2c4ec065 100644 --- a/reactos/base/system/services/database.c +++ b/reactos/base/system/services/database.c @@ -554,8 +554,10 @@ ScmDeleteServiceRecord(PSERVICE lpService) /* Decrement the group reference counter */ ScmSetServiceGroup(lpService, NULL); - /* FIXME: SecurityDescriptor */ - + /* Release the SecurityDescriptor */ + if ((lpService->pSecurityDescriptor != NULL) && + (lpService->pSecurityDescriptor != pDefaultServiceSD)) + HeapFree(GetProcessHeap(), 0, lpService->pSecurityDescriptor); /* Remove the Service from the List */ RemoveEntryList(&lpService->ServiceListEntry); @@ -693,7 +695,27 @@ CreateServiceListEntry(LPCWSTR lpServiceName, if (ScmIsDeleteFlagSet(hServiceKey)) lpService->bDeleted = TRUE; -done:; + if (lpService->Status.dwServiceType & SERVICE_WIN32) + { + dwError = ScmReadSecurityDescriptor(hServiceKey, + &lpService->pSecurityDescriptor); + if (dwError != ERROR_SUCCESS) + goto done; + + /* Assing the default security descriptor if the security descriptor cannot be read */ + if (lpService->pSecurityDescriptor == NULL) + { + DPRINT("No security descriptor found! Assign default security descriptor!\n"); + lpService->pSecurityDescriptor = pDefaultServiceSD; + + dwError = ScmWriteSecurityDescriptor(hServiceKey, + lpService->pSecurityDescriptor); + if (dwError != ERROR_SUCCESS) + goto done; + } + } + +done: if (lpGroup != NULL) HeapFree(GetProcessHeap(), 0, lpGroup); diff --git a/reactos/base/system/services/services.h b/reactos/base/system/services/services.h index 8616b07885b..7c28a53d967 100644 --- a/reactos/base/system/services/services.h +++ b/reactos/base/system/services/services.h @@ -139,6 +139,11 @@ ScmWriteSecurityDescriptor( _In_ HKEY hServiceKey, _In_ PSECURITY_DESCRIPTOR pSecurityDescriptor); +DWORD +ScmReadSecurityDescriptor( + _In_ HKEY hServiceKey, + _Out_ PSECURITY_DESCRIPTOR *ppSecurityDescriptor); + /* controlset.c */