Author: ekohl Date: Thu Jun 9 21:30:48 2016 New Revision: 71603
URL: http://svn.reactos.org/svn/reactos?rev=71603&view=rev Log: [SERVICES] - Create a default service security descriptor. - RCreateServiceW: Assign the default security descriptor to new services on service creation and store it in the registry. - RQueryServiceObjectSecurity: Return the services security descriptor to the caller.
Added: trunk/reactos/base/system/services/security.c (with props) Modified: trunk/reactos/base/system/services/CMakeLists.txt trunk/reactos/base/system/services/config.c trunk/reactos/base/system/services/rpcserver.c trunk/reactos/base/system/services/services.c trunk/reactos/base/system/services/services.h
Modified: trunk/reactos/base/system/services/CMakeLists.txt URL: http://svn.reactos.org/svn/reactos/trunk/reactos/base/system/services/CMakeL... ============================================================================== --- trunk/reactos/base/system/services/CMakeLists.txt [iso-8859-1] (original) +++ trunk/reactos/base/system/services/CMakeLists.txt [iso-8859-1] Thu Jun 9 21:30:48 2016 @@ -14,6 +14,7 @@ groupdb.c lock.c rpcserver.c + security.c services.c services.h ${CMAKE_CURRENT_BINARY_DIR}/svcctl_s.c)
Modified: trunk/reactos/base/system/services/config.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/base/system/services/config... ============================================================================== --- trunk/reactos/base/system/services/config.c [iso-8859-1] (original) +++ trunk/reactos/base/system/services/config.c [iso-8859-1] Thu Jun 9 21:30:48 2016 @@ -498,4 +498,154 @@ return dwError; }
+ +DWORD +ScmWriteSecurityDescriptor( + _In_ HKEY hServiceKey, + _In_ PSECURITY_DESCRIPTOR pSecurityDescriptor) +{ + PSECURITY_DESCRIPTOR pRelativeSD = NULL; + HKEY hSecurityKey = NULL; + DWORD dwBufferLength = 0; + DWORD dwDisposition; + DWORD dwError; + NTSTATUS Status; + + DPRINT1("ScmWriteSecurityDescriptor(%p %p)\n", hServiceKey, pSecurityDescriptor); + + Status = RtlAbsoluteToSelfRelativeSD(pSecurityDescriptor, + NULL, + &dwBufferLength); + if (Status != STATUS_BUFFER_TOO_SMALL) + { +DPRINT1("\n"); + return RtlNtStatusToDosError(Status); + } + + DPRINT1("BufferLength %lu\n", dwBufferLength); + + pRelativeSD = RtlAllocateHeap(RtlGetProcessHeap(), + HEAP_ZERO_MEMORY, + dwBufferLength); + if (pRelativeSD == NULL) + { +DPRINT1("\n"); + return ERROR_OUTOFMEMORY; + } + +DPRINT1("\n"); + Status = RtlAbsoluteToSelfRelativeSD(pSecurityDescriptor, + pRelativeSD, + &dwBufferLength); + if (!NT_SUCCESS(Status)) + { +DPRINT1("\n"); + dwError = RtlNtStatusToDosError(Status); + goto done; + } + +DPRINT1("\n"); + dwError = RegCreateKeyExW(hServiceKey, + L"Security", + 0, + NULL, + REG_OPTION_NON_VOLATILE, + KEY_SET_VALUE, + NULL, + &hSecurityKey, + &dwDisposition); + if (dwError != ERROR_SUCCESS) + { +DPRINT1("\n"); + goto done; + } + +DPRINT1("\n"); + dwError = RegSetValueExW(hSecurityKey, + L"Security", + 0, + REG_BINARY, + (LPBYTE)pRelativeSD, + dwBufferLength); +DPRINT1("\n"); + +done: + if (hSecurityKey != NULL) + RegCloseKey(hSecurityKey); + + if (pRelativeSD != NULL) + RtlFreeHeap(RtlGetProcessHeap(), 0, pRelativeSD); + + 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; + + dwError = RegOpenKeyExW(hServiceKey, + L"Security", + 0, + KEY_QUERY_VALUE, + &hSecurityKey); + if (dwError != ERROR_SUCCESS) + { +DPRINT1("\n"); + goto done; + } + + dwError = RegQueryValueExW(hSecurityKey, + L"Security", + 0, + &dwType, + NULL, + &dwBufferLength); + if (dwError != ERROR_SUCCESS) + { +DPRINT1("\n"); + goto done; + } + + pRelativeSD = RtlAllocateHeap(RtlGetProcessHeap(), + HEAP_ZERO_MEMORY, + dwBufferLength); + if (pRelativeSD == NULL) + { +DPRINT1("\n"); + return ERROR_OUTOFMEMORY; + } + + dwError = RegQueryValueExW(hSecurityKey, + L"Security", + 0, + &dwType, + (LPBYTE)pRelativeSD, + &dwBufferLength); + if (dwError != ERROR_SUCCESS) + { +DPRINT1("\n"); + goto done; + } + + + +done: + if (pRelativeSD != NULL) + RtlFreeHeap(RtlGetProcessHeap(), 0, pRelativeSD); + + if (hSecurityKey != NULL) + RegCloseKey(hSecurityKey); + + + return dwError; +} + /* EOF */
Modified: trunk/reactos/base/system/services/rpcserver.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/base/system/services/rpcser... ============================================================================== --- trunk/reactos/base/system/services/rpcserver.c [iso-8859-1] (original) +++ trunk/reactos/base/system/services/rpcserver.c [iso-8859-1] Thu Jun 9 21:30:48 2016 @@ -1364,9 +1364,6 @@ DWORD dwBytesNeeded; DWORD dwError;
- - SECURITY_DESCRIPTOR ObjectDescriptor; - DPRINT("RQueryServiceObjectSecurity() called\n");
hSvc = ScmGetServiceFromHandle(hService); @@ -1401,11 +1398,8 @@ /* Lock the service database */ ScmLockDatabaseShared();
- - /* hack */ - Status = RtlCreateSecurityDescriptor(&ObjectDescriptor, SECURITY_DESCRIPTOR_REVISION); - - Status = RtlQuerySecurityObject(&ObjectDescriptor /* lpService->lpSecurityDescriptor */, + /* Retrieve the security descriptor */ + Status = RtlQuerySecurityObject(lpService->pSecurityDescriptor, dwSecurityInformation, (PSECURITY_DESCRIPTOR)lpSecurityDescriptor, cbBufSize, @@ -2258,6 +2252,12 @@ goto done; }
+ /* Assign the default security descriptor */ + if (dwServiceType & SERVICE_WIN32) + { + lpService->pSecurityDescriptor = pDefaultServiceSD; + } + /* Write service data to the registry */ /* Create the service key */ dwError = ScmCreateServiceKey(lpServiceName, @@ -2391,6 +2391,13 @@ if (dwError != ERROR_SUCCESS) goto done; } + +DPRINT1("\n"); + /* Write the security descriptor */ + dwError = ScmWriteSecurityDescriptor(hServiceKey, + lpService->pSecurityDescriptor); + if (dwError != ERROR_SUCCESS) + goto done; }
dwError = ScmCreateServiceHandle(lpService,
Added: trunk/reactos/base/system/services/security.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/base/system/services/securi... ============================================================================== --- trunk/reactos/base/system/services/security.c (added) +++ trunk/reactos/base/system/services/security.c [iso-8859-1] Thu Jun 9 21:30:48 2016 @@ -0,0 +1,268 @@ +/* + * PROJECT: ReactOS Service Control Manager + * LICENSE: GPL - See COPYING in the top level directory + * FILE: base/system/services/security.c + * PURPOSE: Security functions + * COPYRIGHT: Eric Kohl + */ + +/* INCLUDES *****************************************************************/ + +#include "services.h" + +#define NDEBUG +#include <debug.h> + +PSECURITY_DESCRIPTOR pDefaultServiceSD = NULL; + +static PSID pNullSid = NULL; +static PSID pLocalSystemSid = NULL; +static PSID pAuthenticatedUserSid = NULL; +static PSID pAliasAdminsSid = NULL; + + +/* FUNCTIONS ****************************************************************/ + +static +VOID +ScmFreeSids(VOID) +{ + if (pNullSid != NULL) + RtlFreeHeap(RtlGetProcessHeap(), 0, pNullSid); + + if (pLocalSystemSid != NULL) + RtlFreeHeap(RtlGetProcessHeap(), 0, pLocalSystemSid); + + if (pAuthenticatedUserSid != NULL) + RtlFreeHeap(RtlGetProcessHeap(), 0, pAuthenticatedUserSid); + + if (pAliasAdminsSid != NULL) + RtlFreeHeap(RtlGetProcessHeap(), 0, pAliasAdminsSid); + +} + + +static +DWORD +ScmCreateSids(VOID) +{ + SID_IDENTIFIER_AUTHORITY NullAuthority = {SECURITY_NULL_SID_AUTHORITY}; + SID_IDENTIFIER_AUTHORITY NtAuthority = {SECURITY_NT_AUTHORITY}; + PULONG pSubAuthority; + ULONG ulLength1 = RtlLengthRequiredSid(1); + ULONG ulLength2 = RtlLengthRequiredSid(2); + + /* Create the Null SID */ + pNullSid = RtlAllocateHeap(RtlGetProcessHeap(), 0, ulLength1); + if (pNullSid == NULL) + { + return ERROR_OUTOFMEMORY; + } + + RtlInitializeSid(pNullSid, &NullAuthority, 1); + pSubAuthority = RtlSubAuthoritySid(pNullSid, 0); + *pSubAuthority = SECURITY_NULL_RID; + + /* Create the LocalSystem SID */ + pLocalSystemSid = RtlAllocateHeap(RtlGetProcessHeap(), 0, ulLength1); + if (pLocalSystemSid == NULL) + { + return ERROR_OUTOFMEMORY; + } + + RtlInitializeSid(pLocalSystemSid, &NtAuthority, 1); + pSubAuthority = RtlSubAuthoritySid(pLocalSystemSid, 0); + *pSubAuthority = SECURITY_LOCAL_SYSTEM_RID; + + /* Create the AuthenticatedUser SID */ + pAuthenticatedUserSid = RtlAllocateHeap(RtlGetProcessHeap(), 0, ulLength1); + if (pAuthenticatedUserSid == NULL) + { + return ERROR_OUTOFMEMORY; + } + + RtlInitializeSid(pAuthenticatedUserSid, &NtAuthority, 1); + pSubAuthority = RtlSubAuthoritySid(pAuthenticatedUserSid, 0); + *pSubAuthority = SECURITY_AUTHENTICATED_USER_RID; + + /* Create the AliasAdmins SID */ + pAliasAdminsSid = RtlAllocateHeap(RtlGetProcessHeap(), 0, ulLength2); + if (pAliasAdminsSid == NULL) + { + return ERROR_OUTOFMEMORY; + } + + RtlInitializeSid(pAliasAdminsSid, &NtAuthority, 2); + pSubAuthority = RtlSubAuthoritySid(pAliasAdminsSid, 0); + *pSubAuthority = SECURITY_BUILTIN_DOMAIN_RID; + pSubAuthority = RtlSubAuthoritySid(pAliasAdminsSid, 1); + *pSubAuthority = DOMAIN_ALIAS_RID_ADMINS; + + return ERROR_SUCCESS; +} + + +static +DWORD +ScmCreateDefaultServiceSD(VOID) +{ + PSECURITY_DESCRIPTOR pServiceSD = NULL; + PACL pDacl = NULL; + PACL pSacl = NULL; + ULONG ulLength; + NTSTATUS Status; + DWORD dwError = ERROR_SUCCESS; + + /* Create DACL */ + ulLength = sizeof(ACL) + + (sizeof(ACE) + RtlLengthSid(pLocalSystemSid)) + + (sizeof(ACE) + RtlLengthSid(pAliasAdminsSid)) + + (sizeof(ACE) + RtlLengthSid(pAuthenticatedUserSid)); + + pDacl = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, ulLength); + if (pDacl == NULL) + { + dwError = ERROR_OUTOFMEMORY; + goto done; + } + + RtlCreateAcl(pDacl, ulLength, ACL_REVISION); + + RtlAddAccessAllowedAce(pDacl, + ACL_REVISION, + READ_CONTROL | SERVICE_ENUMERATE_DEPENDENTS | SERVICE_INTERROGATE | + SERVICE_PAUSE_CONTINUE | SERVICE_QUERY_CONFIG | SERVICE_QUERY_STATUS | + SERVICE_START | SERVICE_STOP | SERVICE_USER_DEFINED_CONTROL, + pLocalSystemSid); + + RtlAddAccessAllowedAce(pDacl, + ACL_REVISION, + SERVICE_ALL_ACCESS, + pAliasAdminsSid); + + RtlAddAccessAllowedAce(pDacl, + ACL_REVISION, + READ_CONTROL | SERVICE_ENUMERATE_DEPENDENTS | SERVICE_INTERROGATE | + SERVICE_QUERY_CONFIG | SERVICE_QUERY_STATUS | SERVICE_USER_DEFINED_CONTROL, + pAuthenticatedUserSid); + + /* Create SACL */ + ulLength = sizeof(ACL) + + (sizeof(ACE) + RtlLengthSid(pNullSid)); + + pSacl = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, ulLength); + if (pSacl == NULL) + { + dwError = ERROR_OUTOFMEMORY; + goto done; + } + + RtlCreateAcl(pSacl, ulLength, ACL_REVISION); + + RtlAddAuditAccessAce(pSacl, + ACL_REVISION, + SERVICE_ALL_ACCESS, + pNullSid, + FALSE, + TRUE); + + + pServiceSD = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(SECURITY_DESCRIPTOR)); + if (pServiceSD == NULL) + { + dwError = ERROR_OUTOFMEMORY; + goto done; + } +DPRINT1("pServiceSD %p\n", pServiceSD); + + Status = RtlCreateSecurityDescriptor(pServiceSD, + SECURITY_DESCRIPTOR_REVISION); + if (!NT_SUCCESS(Status)) + { + dwError = RtlNtStatusToDosError(Status); + goto done; + } + + Status = RtlSetOwnerSecurityDescriptor(pServiceSD, + pLocalSystemSid, + FALSE); + if (!NT_SUCCESS(Status)) + { + dwError = RtlNtStatusToDosError(Status); + goto done; + } + + Status = RtlSetGroupSecurityDescriptor(pServiceSD, + pLocalSystemSid, + FALSE); + if (!NT_SUCCESS(Status)) + { + dwError = RtlNtStatusToDosError(Status); + goto done; + } + + Status = RtlSetDaclSecurityDescriptor(pServiceSD, + TRUE, + pDacl, + FALSE); + if (!NT_SUCCESS(Status)) + { + dwError = RtlNtStatusToDosError(Status); + goto done; + } + + Status = RtlSetSaclSecurityDescriptor(pServiceSD, + TRUE, + pSacl, + FALSE); + if (!NT_SUCCESS(Status)) + { + dwError = RtlNtStatusToDosError(Status); + goto done; + } + + + pDefaultServiceSD = pServiceSD; +DPRINT1("pDefaultServiceSD %p\n", pDefaultServiceSD); + +done: + if (dwError != ERROR_SUCCESS) + { + if (pDacl != NULL) + RtlFreeHeap(RtlGetProcessHeap(), 0, pDacl); + + if (pSacl != NULL) + RtlFreeHeap(RtlGetProcessHeap(), 0, pSacl); + + if (pServiceSD != NULL) + RtlFreeHeap(RtlGetProcessHeap(), 0, pServiceSD); + } + + return dwError; +} + + +DWORD +ScmInitializeSecurity(VOID) +{ + DWORD dwError; + + dwError = ScmCreateSids(); + if (dwError != ERROR_SUCCESS) + return dwError; + + dwError = ScmCreateDefaultServiceSD(); + if (dwError != ERROR_SUCCESS) + return dwError; + + return ERROR_SUCCESS; +} + + +VOID +ScmShutdownSecurity(VOID) +{ + ScmFreeSids(); +} + +/* EOF */
Propchange: trunk/reactos/base/system/services/security.c ------------------------------------------------------------------------------ svn:eol-style = native
Modified: trunk/reactos/base/system/services/services.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/base/system/services/servic... ============================================================================== --- trunk/reactos/base/system/services/services.c [iso-8859-1] (original) +++ trunk/reactos/base/system/services/services.c [iso-8859-1] Thu Jun 9 21:30:48 2016 @@ -354,6 +354,8 @@
// ScmInitThreadManager();
+ ScmInitializeSecurity(); + /* FIXME: more initialization */
/* Read the control set values */ @@ -432,6 +434,8 @@ WaitForSingleObject(hScmShutdownEvent, INFINITE);
done: + ScmShutdownSecurity(); + /* Delete our communication named pipe's critical section */ if (bCanDeleteNamedPipeCriticalSection == TRUE) ScmDeleteNamedPipeCriticalSection();
Modified: trunk/reactos/base/system/services/services.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/base/system/services/servic... ============================================================================== --- trunk/reactos/base/system/services/services.h [iso-8859-1] (original) +++ trunk/reactos/base/system/services/services.h [iso-8859-1] Thu Jun 9 21:30:48 2016 @@ -72,7 +72,7 @@
ULONG Flags;
- PSECURITY_DESCRIPTOR lpSecurityDescriptor; + PSECURITY_DESCRIPTOR pSecurityDescriptor;
BOOLEAN ServiceVisited;
@@ -98,6 +98,8 @@ extern BOOL ScmInitialize; extern BOOL ScmShutdown;
+extern PSECURITY_DESCRIPTOR pDefaultServiceSD; +
/* FUNCTIONS ***************************************************************/
@@ -131,6 +133,12 @@ ScmSetServicePassword( IN PCWSTR pszServiceName, IN PCWSTR pszPassword); + +DWORD +ScmWriteSecurityDescriptor( + _In_ HKEY hServiceKey, + _In_ PSECURITY_DESCRIPTOR pSecurityDescriptor); +
/* controlset.c */
@@ -197,6 +205,12 @@ VOID ScmStartRpcServer(VOID);
+/* security.c */ + +DWORD ScmInitializeSecurity(VOID); +VOID ScmShutdownSecurity(VOID); + + /* services.c */
VOID PrintString(LPCSTR fmt, ...);