[SERVICES]

- Create the absolute default service security descriptor when services.exe starts up.
- Create a self-relative security descriptor whenever it is needed.

svn path=/trunk/; revision=71684
This commit is contained in:
Eric Kohl 2016-06-27 22:19:19 +00:00
parent 0a1b24ef17
commit aa7b502c14

View file

@ -18,6 +18,11 @@ static PSID pLocalSystemSid = NULL;
static PSID pAuthenticatedUserSid = NULL; static PSID pAuthenticatedUserSid = NULL;
static PSID pAliasAdminsSid = NULL; static PSID pAliasAdminsSid = NULL;
static PACL pDefaultDacl = NULL;
static PACL pDefaultSacl = NULL;
static PSECURITY_DESCRIPTOR pDefaultSD = NULL;
/* FUNCTIONS ****************************************************************/ /* FUNCTIONS ****************************************************************/
@ -100,18 +105,11 @@ ScmCreateSids(VOID)
} }
static
DWORD DWORD
ScmCreateDefaultServiceSD( ScmCreateAcls(VOID)
PSECURITY_DESCRIPTOR *ppSecurityDescriptor)
{ {
PSECURITY_DESCRIPTOR pServiceSD = NULL;
PSECURITY_DESCRIPTOR pRelativeSD = NULL;
PACL pDacl = NULL;
PACL pSacl = NULL;
ULONG ulLength; ULONG ulLength;
DWORD dwBufferLength = 0;
NTSTATUS Status;
DWORD dwError = ERROR_SUCCESS;
/* Create DACL */ /* Create DACL */
ulLength = sizeof(ACL) + ulLength = sizeof(ACL) +
@ -119,28 +117,25 @@ ScmCreateDefaultServiceSD(
(sizeof(ACE) + RtlLengthSid(pAliasAdminsSid)) + (sizeof(ACE) + RtlLengthSid(pAliasAdminsSid)) +
(sizeof(ACE) + RtlLengthSid(pAuthenticatedUserSid)); (sizeof(ACE) + RtlLengthSid(pAuthenticatedUserSid));
pDacl = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, ulLength); pDefaultDacl = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, ulLength);
if (pDacl == NULL) if (pDefaultDacl == NULL)
{ return ERROR_OUTOFMEMORY;
dwError = ERROR_OUTOFMEMORY;
goto done;
}
RtlCreateAcl(pDacl, ulLength, ACL_REVISION); RtlCreateAcl(pDefaultDacl, ulLength, ACL_REVISION);
RtlAddAccessAllowedAce(pDacl, RtlAddAccessAllowedAce(pDefaultDacl,
ACL_REVISION, ACL_REVISION,
READ_CONTROL | SERVICE_ENUMERATE_DEPENDENTS | SERVICE_INTERROGATE | READ_CONTROL | SERVICE_ENUMERATE_DEPENDENTS | SERVICE_INTERROGATE |
SERVICE_PAUSE_CONTINUE | SERVICE_QUERY_CONFIG | SERVICE_QUERY_STATUS | SERVICE_PAUSE_CONTINUE | SERVICE_QUERY_CONFIG | SERVICE_QUERY_STATUS |
SERVICE_START | SERVICE_STOP | SERVICE_USER_DEFINED_CONTROL, SERVICE_START | SERVICE_STOP | SERVICE_USER_DEFINED_CONTROL,
pLocalSystemSid); pLocalSystemSid);
RtlAddAccessAllowedAce(pDacl, RtlAddAccessAllowedAce(pDefaultDacl,
ACL_REVISION, ACL_REVISION,
SERVICE_ALL_ACCESS, SERVICE_ALL_ACCESS,
pAliasAdminsSid); pAliasAdminsSid);
RtlAddAccessAllowedAce(pDacl, RtlAddAccessAllowedAce(pDefaultDacl,
ACL_REVISION, ACL_REVISION,
READ_CONTROL | SERVICE_ENUMERATE_DEPENDENTS | SERVICE_INTERROGATE | READ_CONTROL | SERVICE_ENUMERATE_DEPENDENTS | SERVICE_INTERROGATE |
SERVICE_QUERY_CONFIG | SERVICE_QUERY_STATUS | SERVICE_USER_DEFINED_CONTROL, SERVICE_QUERY_CONFIG | SERVICE_QUERY_STATUS | SERVICE_USER_DEFINED_CONTROL,
@ -150,79 +145,103 @@ ScmCreateDefaultServiceSD(
ulLength = sizeof(ACL) + ulLength = sizeof(ACL) +
(sizeof(ACE) + RtlLengthSid(pNullSid)); (sizeof(ACE) + RtlLengthSid(pNullSid));
pSacl = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, ulLength); pDefaultSacl = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, ulLength);
if (pSacl == NULL) if (pDefaultSacl == NULL)
{ return ERROR_OUTOFMEMORY;
dwError = ERROR_OUTOFMEMORY;
goto done;
}
RtlCreateAcl(pSacl, ulLength, ACL_REVISION); RtlCreateAcl(pDefaultSacl, ulLength, ACL_REVISION);
RtlAddAuditAccessAce(pSacl, RtlAddAuditAccessAce(pDefaultSacl,
ACL_REVISION, ACL_REVISION,
SERVICE_ALL_ACCESS, SERVICE_ALL_ACCESS,
pNullSid, pNullSid,
FALSE, FALSE,
TRUE); TRUE);
/* Create the absolute security descriptor */ return ERROR_SUCCESS;
pServiceSD = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(SECURITY_DESCRIPTOR)); }
if (pServiceSD == NULL)
{
dwError = ERROR_OUTOFMEMORY;
goto done;
}
DPRINT("pServiceSD %p\n", pServiceSD);
Status = RtlCreateSecurityDescriptor(pServiceSD,
static
VOID
ScmFreeAcls(VOID)
{
if (pDefaultDacl != NULL)
RtlFreeHeap(RtlGetProcessHeap(), 0, pDefaultDacl);
if (pDefaultSacl != NULL)
RtlFreeHeap(RtlGetProcessHeap(), 0, pDefaultSacl);
}
static
DWORD
ScmCreateDefaultSD(VOID)
{
NTSTATUS Status;
/* Create the absolute security descriptor */
pDefaultSD = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(SECURITY_DESCRIPTOR));
if (pDefaultSD == NULL)
return ERROR_OUTOFMEMORY;
DPRINT("pDefaultSD %p\n", pDefaultSD);
Status = RtlCreateSecurityDescriptor(pDefaultSD,
SECURITY_DESCRIPTOR_REVISION); SECURITY_DESCRIPTOR_REVISION);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ return RtlNtStatusToDosError(Status);
dwError = RtlNtStatusToDosError(Status);
goto done;
}
Status = RtlSetOwnerSecurityDescriptor(pServiceSD, Status = RtlSetOwnerSecurityDescriptor(pDefaultSD,
pLocalSystemSid, pLocalSystemSid,
FALSE); FALSE);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ return RtlNtStatusToDosError(Status);
dwError = RtlNtStatusToDosError(Status);
goto done;
}
Status = RtlSetGroupSecurityDescriptor(pServiceSD, Status = RtlSetGroupSecurityDescriptor(pDefaultSD,
pLocalSystemSid, pLocalSystemSid,
FALSE); FALSE);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ return RtlNtStatusToDosError(Status);
dwError = RtlNtStatusToDosError(Status);
goto done;
}
Status = RtlSetDaclSecurityDescriptor(pServiceSD, Status = RtlSetDaclSecurityDescriptor(pDefaultSD,
TRUE, TRUE,
pDacl, pDefaultDacl,
FALSE); FALSE);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ return RtlNtStatusToDosError(Status);
dwError = RtlNtStatusToDosError(Status);
goto done;
}
Status = RtlSetSaclSecurityDescriptor(pServiceSD, Status = RtlSetSaclSecurityDescriptor(pDefaultSD,
TRUE, TRUE,
pSacl, pDefaultSacl,
FALSE); FALSE);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ return RtlNtStatusToDosError(Status);
dwError = RtlNtStatusToDosError(Status);
goto done; return ERROR_SUCCESS;
} }
static
VOID
ScmFreeDefaultSD(VOID)
{
if (pDefaultSD != NULL)
RtlFreeHeap(RtlGetProcessHeap(), 0, pDefaultSD);
}
DWORD
ScmCreateDefaultServiceSD(
PSECURITY_DESCRIPTOR *ppSecurityDescriptor)
{
PSECURITY_DESCRIPTOR pRelativeSD = NULL;
DWORD dwBufferLength = 0;
NTSTATUS Status;
DWORD dwError = ERROR_SUCCESS;
/* Convert the absolute SD to a self-relative SD */ /* Convert the absolute SD to a self-relative SD */
Status = RtlAbsoluteToSelfRelativeSD(pServiceSD, Status = RtlAbsoluteToSelfRelativeSD(pDefaultSD,
NULL, NULL,
&dwBufferLength); &dwBufferLength);
if (Status != STATUS_BUFFER_TOO_SMALL) if (Status != STATUS_BUFFER_TOO_SMALL)
@ -243,7 +262,7 @@ ScmCreateDefaultServiceSD(
} }
DPRINT("pRelativeSD %p\n", pRelativeSD); DPRINT("pRelativeSD %p\n", pRelativeSD);
Status = RtlAbsoluteToSelfRelativeSD(pServiceSD, Status = RtlAbsoluteToSelfRelativeSD(pDefaultSD,
pRelativeSD, pRelativeSD,
&dwBufferLength); &dwBufferLength);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
@ -261,15 +280,6 @@ done:
RtlFreeHeap(RtlGetProcessHeap(), 0, pRelativeSD); RtlFreeHeap(RtlGetProcessHeap(), 0, pRelativeSD);
} }
if (pServiceSD != NULL)
RtlFreeHeap(RtlGetProcessHeap(), 0, pServiceSD);
if (pSacl != NULL)
RtlFreeHeap(RtlGetProcessHeap(), 0, pSacl);
if (pDacl != NULL)
RtlFreeHeap(RtlGetProcessHeap(), 0, pDacl);
return dwError; return dwError;
} }
@ -283,6 +293,14 @@ ScmInitializeSecurity(VOID)
if (dwError != ERROR_SUCCESS) if (dwError != ERROR_SUCCESS)
return dwError; return dwError;
dwError = ScmCreateAcls();
if (dwError != ERROR_SUCCESS)
return dwError;
dwError = ScmCreateDefaultSD();
if (dwError != ERROR_SUCCESS)
return dwError;
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
@ -290,6 +308,8 @@ ScmInitializeSecurity(VOID)
VOID VOID
ScmShutdownSecurity(VOID) ScmShutdownSecurity(VOID)
{ {
ScmFreeDefaultSD();
ScmFreeAcls();
ScmFreeSids(); ScmFreeSids();
} }