summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/include/rpc_secdes.h34
-rw-r--r--source3/rpc_server/srv_svcctl_nt.c126
2 files changed, 139 insertions, 21 deletions
diff --git a/source3/include/rpc_secdes.h b/source3/include/rpc_secdes.h
index 9eb4c9a41e..fe95706d03 100644
--- a/source3/include/rpc_secdes.h
+++ b/source3/include/rpc_secdes.h
@@ -475,15 +475,20 @@ typedef struct standard_mapping {
#define SC_RIGHT_MGR_QUERY_LOCK_STATUS 0x0010
#define SC_RIGHT_MGR_MODIFY_BOOT_CONFIG 0x0020
+#define SC_MANAGER_READ_ACCESS \
+ ( STANDARD_RIGHTS_READ_ACCESS | \
+ SC_RIGHT_MGR_CONNECT | \
+ SC_RIGHT_MGR_ENUMERATE_SERVICE | \
+ SC_RIGHT_MGR_QUERY_LOCK_STATUS )
+
#define SC_MANAGER_ALL_ACCESS \
( STANDARD_RIGHTS_REQUIRED_ACCESS | \
- SC_RIGHT_MGR_CONNECT | \
+ SC_MANAGER_READ_ACCESS | \
SC_RIGHT_MGR_CREATE_SERVICE | \
- SC_RIGHT_MGR_ENUMERATE_SERVICE | \
SC_RIGHT_MGR_LOCK | \
- SC_RIGHT_MGR_QUERY_LOCK_STATUS | \
SC_RIGHT_MGR_MODIFY_BOOT_CONFIG )
+
/* Service Object Bits */
#define SC_RIGHT_SVC_QUERY_CONFIG 0x0001
@@ -496,17 +501,26 @@ typedef struct standard_mapping {
#define SC_RIGHT_SVC_INTERROGATE 0x0080
#define SC_RIGHT_SVC_USER_DEFINED_CONTROL 0x0100
-#define SERVICE_ALL_ACCESS \
- ( STANDARD_RIGHTS_REQUIRED_ACCESS | \
+#define SERVICE_READ_ACCESS \
+ ( STANDARD_RIGHTS_READ_ACCESS | \
+ SC_RIGHT_SVC_ENUMERATE_DEPENDENTS | \
+ SC_RIGHT_SVC_INTERROGATE | \
SC_RIGHT_SVC_QUERY_CONFIG | \
- SC_RIGHT_SVC_CHANGE_CONFIG | \
SC_RIGHT_SVC_QUERY_STATUS | \
- SC_RIGHT_SVC_ENUMERATE_DEPENDENTS | \
+ SC_RIGHT_SVC_USER_DEFINED_CONTROL )
+
+#define SERVICE_EXECUTE_ACCESS \
+ ( SERVICE_READ_ACCESS | \
SC_RIGHT_SVC_START | \
SC_RIGHT_SVC_STOP | \
- SC_RIGHT_SVC_PAUSE_CONTINUE | \
- SC_RIGHT_SVC_INTERROGATE | \
- SC_RIGHT_SVC_USER_DEFINED_CONTROL )
+ SC_RIGHT_SVC_PAUSE_CONTINUE )
+
+#define SERVICE_ALL_ACCESS \
+ ( STANDARD_RIGHTS_REQUIRED_ACCESS | \
+ SERVICE_READ_ACCESS | \
+ SERVICE_EXECUTE_ACCESS )
+
+
/*
* Access Bits for registry ACLS
diff --git a/source3/rpc_server/srv_svcctl_nt.c b/source3/rpc_server/srv_svcctl_nt.c
index 707fd8bdd5..53fddcf964 100644
--- a/source3/rpc_server/srv_svcctl_nt.c
+++ b/source3/rpc_server/srv_svcctl_nt.c
@@ -443,6 +443,91 @@ BOOL init_svcctl_db(void)
/********************************************************************
********************************************************************/
+static NTSTATUS svcctl_access_check( SEC_DESC *sec_desc, NT_USER_TOKEN *token,
+ uint32 access_desired, uint32 *access_granted )
+{
+ NTSTATUS result;
+
+ /* maybe add privilege checks in here later */
+
+ se_access_check( sec_desc, token, access_desired, access_granted, &result );
+
+ return result;
+}
+
+/********************************************************************
+********************************************************************/
+
+static SEC_DESC* construct_scm_sd( TALLOC_CTX *ctx )
+{
+ SEC_ACE ace[2];
+ SEC_ACCESS mask;
+ size_t i = 0;
+ SEC_DESC *sd;
+ SEC_ACL *acl;
+ uint32 sd_size;
+
+ /* basic access for Everyone */
+
+ init_sec_access(&mask, SC_MANAGER_READ_ACCESS );
+ init_sec_ace(&ace[i++], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
+
+ /* Full Access 'BUILTIN\Administrators' */
+
+ init_sec_access(&mask,SC_MANAGER_ALL_ACCESS );
+ init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
+
+
+ /* create the security descriptor */
+
+ if ( !(acl = make_sec_acl(ctx, NT4_ACL_REVISION, i, ace)) )
+ return NULL;
+
+ if ( !(sd = make_sec_desc(ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE, NULL, NULL, NULL, acl, &sd_size)) )
+ return NULL;
+
+ return sd;
+}
+
+/********************************************************************
+********************************************************************/
+
+static SEC_DESC* construct_service_sd( TALLOC_CTX *ctx )
+{
+ SEC_ACE ace[4];
+ SEC_ACCESS mask;
+ size_t i = 0;
+ SEC_DESC *sd;
+ SEC_ACL *acl;
+ uint32 sd_size;
+
+ /* basic access for Everyone */
+
+ init_sec_access(&mask, SERVICE_READ_ACCESS );
+ init_sec_ace(&ace[i++], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
+
+ init_sec_access(&mask,SERVICE_EXECUTE_ACCESS );
+ init_sec_ace(&ace[i++], &global_sid_Builtin_Power_Users, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
+
+ init_sec_access(&mask,SERVICE_ALL_ACCESS );
+ init_sec_ace(&ace[i++], &global_sid_Builtin_Server_Operators, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
+ init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
+
+ /* create the security descriptor */
+
+ if ( !(acl = make_sec_acl(ctx, NT4_ACL_REVISION, i, ace)) )
+ return NULL;
+
+ if ( !(sd = make_sec_desc(ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE, NULL, NULL, NULL, acl, &sd_size)) )
+ return NULL;
+
+ return sd;
+}
+
+
+/********************************************************************
+********************************************************************/
+
static BOOL read_service_tdb_to_si(TDB_CONTEXT *stdb,char *service_name, Service_info *si)
{
@@ -546,12 +631,15 @@ static SERVICE_INFO *find_service_info_by_hnd(pipes_struct *p, POLICY_HND *hnd)
/******************************************************************
*****************************************************************/
-WERROR create_open_service_handle( pipes_struct *p, POLICY_HND *handle, const char *service )
+static WERROR create_open_service_handle( pipes_struct *p, POLICY_HND *handle,
+ const char *service, uint32 access_granted )
{
SERVICE_INFO *info = NULL;
if ( !(info = SMB_MALLOC_P( SERVICE_INFO )) )
return WERR_NOMEM;
+
+ ZERO_STRUCTP( info );
/* the Service Manager has a NULL name */
@@ -574,6 +662,8 @@ WERROR create_open_service_handle( pipes_struct *p, POLICY_HND *handle, const ch
#endif
}
+ info->access_granted = access_granted;
+
/* store the SERVICE_INFO and create an open handle */
if ( !create_policy_hnd( p, handle, free_service_handle_info, info ) ) {
@@ -589,13 +679,20 @@ WERROR create_open_service_handle( pipes_struct *p, POLICY_HND *handle, const ch
WERROR _svcctl_open_scmanager(pipes_struct *p, SVCCTL_Q_OPEN_SCMANAGER *q_u, SVCCTL_R_OPEN_SCMANAGER *r_u)
{
- /* perform access checks */
+ SEC_DESC *sec_desc;
+ uint32 access_granted = 0;
+ NTSTATUS status;
-
- /* open the handle and return */
+ /* perform access checks */
- return create_open_service_handle( p, &r_u->handle, NULL );
-
+ if ( !(sec_desc = construct_scm_sd( p->mem_ctx )) )
+ return WERR_NOMEM;
+
+ status = svcctl_access_check( sec_desc, p->pipe_user.nt_user_token, q_u->access, &access_granted );
+ if ( !NT_STATUS_IS_OK(status) )
+ return ntstatus_to_werror( status );
+
+ return create_open_service_handle( p, &r_u->handle, NULL, access_granted );
}
/********************************************************************
@@ -603,6 +700,9 @@ WERROR _svcctl_open_scmanager(pipes_struct *p, SVCCTL_Q_OPEN_SCMANAGER *q_u, SVC
WERROR _svcctl_open_service(pipes_struct *p, SVCCTL_Q_OPEN_SERVICE *q_u, SVCCTL_R_OPEN_SERVICE *r_u)
{
+ SEC_DESC *sec_desc;
+ uint32 access_granted = 0;
+ NTSTATUS status;
pstring service;
rpcstr_pull(service, q_u->servicename.buffer, sizeof(service), q_u->servicename.uni_str_len*2, 0);
@@ -614,17 +714,21 @@ WERROR _svcctl_open_service(pipes_struct *p, SVCCTL_Q_OPEN_SERVICE *q_u, SVCCTL_
return WERR_ACCESS_DENIED;
}
- /* check the access granted on the SCM handle */
-
- /* check the access requested on this service */
+ /* perform access checks */
-
+ if ( !(sec_desc = construct_service_sd( p->mem_ctx )) )
+ return WERR_NOMEM;
+
+ status = svcctl_access_check( sec_desc, p->pipe_user.nt_user_token, q_u->access, &access_granted );
+ if ( !NT_STATUS_IS_OK(status) )
+ return ntstatus_to_werror( status );
+
#if 0 /* FIXME!!! */
if ( ! read_service_tdb_to_si(service_tdb,service, info) ) {
return WERR_NO_SUCH_SERVICE;
#endif
- return create_open_service_handle( p, &r_u->handle, service );
+ return create_open_service_handle( p, &r_u->handle, service, access_granted );
}
/********************************************************************