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/CMake…
==============================================================================
--- 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/confi…
==============================================================================
--- 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/rpcse…
==============================================================================
--- 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/secur…
==============================================================================
--- 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/servi…
==============================================================================
--- 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/servi…
==============================================================================
--- 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, ...);