summaryrefslogtreecommitdiff
path: root/source3
diff options
context:
space:
mode:
authorGerald Carter <jerry@samba.org>2005-06-14 18:08:39 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 10:57:14 -0500
commit023ac1031b0057ee752cf2d3a8de3d6e0d4b1802 (patch)
treee97aeaa7ada1fa760a7a4b3eb994ee2a9d538a6d /source3
parent2265f5c9d7a829a835d6b58be2abe0604ee0b367 (diff)
downloadsamba-023ac1031b0057ee752cf2d3a8de3d6e0d4b1802.tar.gz
samba-023ac1031b0057ee752cf2d3a8de3d6e0d4b1802.tar.bz2
samba-023ac1031b0057ee752cf2d3a8de3d6e0d4b1802.zip
r7576: implement access checks for open_scm and open_service
according to default security descriptor described in MSDN. no one can get in to due to the permissions, but i'll fix that next. (This used to be commit 11902e503ed4f6d6991a9fe7521fe44168274ec8)
Diffstat (limited to 'source3')
-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 );
}
/********************************************************************