r7576: implement access checks for open_scm and open_service
authorGerald Carter <jerry@samba.org>
Tue, 14 Jun 2005 18:08:39 +0000 (18:08 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 15:57:14 +0000 (10:57 -0500)
according to default security descriptor described in MSDN.

no one can get in to due to the permissions, but i'll fix
that next.

source/include/rpc_secdes.h
source/rpc_server/srv_svcctl_nt.c

index 9eb4c9a41e41bf19776eb31c79cfbffe61404869..fe95706d0308991b496e8c98624b3fa0592e4ceb 100644 (file)
@@ -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
index 707fd8bdd5afc4ba1b6f17136d0dc9d197b4f2f9..53fddcf964229e1cc92a3f27f4be2a8220d677b6 100644 (file)
@@ -440,6 +440,91 @@ BOOL init_svcctl_db(void)
        return True;
 }
 
+/********************************************************************
+********************************************************************/
+
+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;
+}
+
+
 /********************************************************************
 ********************************************************************/
 
@@ -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 );
 }
 
 /********************************************************************