_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",
&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;
}
&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,
&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;
}
/* 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);
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);