[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
This commit is contained in:
Eric Kohl 2016-06-11 09:41:05 +00:00
parent 4746de9066
commit 5965ffcd78
3 changed files with 80 additions and 9 deletions

View file

@ -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;
}

View file

@ -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);

View file

@ -139,6 +139,11 @@ ScmWriteSecurityDescriptor(
_In_ HKEY hServiceKey,
_In_ PSECURITY_DESCRIPTOR pSecurityDescriptor);
DWORD
ScmReadSecurityDescriptor(
_In_ HKEY hServiceKey,
_Out_ PSECURITY_DESCRIPTOR *ppSecurityDescriptor);
/* controlset.c */