rpc_server/srv_svcctl_nt.c

ソースコードを見る。

データ構造

struct  service_control_op

関数

BOOL init_service_op_table (void)
static struct service_control_opfind_service_by_name (const char *name)
static NTSTATUS svcctl_access_check (SEC_DESC *sec_desc, NT_USER_TOKEN *token, uint32 access_desired, uint32 *access_granted)
static SEC_DESCconstruct_scm_sd (TALLOC_CTX *ctx)
static void free_service_handle_info (void *ptr)
static SERVICE_INFOfind_service_info_by_hnd (pipes_struct *p, POLICY_HND *hnd)
static WERROR create_open_service_handle (pipes_struct *p, POLICY_HND *handle, uint32 type, const char *service, uint32 access_granted)
WERROR _svcctl_open_scmanager (pipes_struct *p, SVCCTL_Q_OPEN_SCMANAGER *q_u, SVCCTL_R_OPEN_SCMANAGER *r_u)
WERROR _svcctl_open_service (pipes_struct *p, SVCCTL_Q_OPEN_SERVICE *q_u, SVCCTL_R_OPEN_SERVICE *r_u)
WERROR _svcctl_close_service (pipes_struct *p, SVCCTL_Q_CLOSE_SERVICE *q_u, SVCCTL_R_CLOSE_SERVICE *r_u)
WERROR _svcctl_get_display_name (pipes_struct *p, SVCCTL_Q_GET_DISPLAY_NAME *q_u, SVCCTL_R_GET_DISPLAY_NAME *r_u)
WERROR _svcctl_query_status (pipes_struct *p, SVCCTL_Q_QUERY_STATUS *q_u, SVCCTL_R_QUERY_STATUS *r_u)
static int enumerate_status (TALLOC_CTX *ctx, ENUM_SERVICES_STATUS **status, NT_USER_TOKEN *token)
WERROR _svcctl_enum_services_status (pipes_struct *p, SVCCTL_Q_ENUM_SERVICES_STATUS *q_u, SVCCTL_R_ENUM_SERVICES_STATUS *r_u)
WERROR _svcctl_start_service (pipes_struct *p, SVCCTL_Q_START_SERVICE *q_u, SVCCTL_R_START_SERVICE *r_u)
WERROR _svcctl_control_service (pipes_struct *p, SVCCTL_Q_CONTROL_SERVICE *q_u, SVCCTL_R_CONTROL_SERVICE *r_u)
WERROR _svcctl_enum_dependent_services (pipes_struct *p, SVCCTL_Q_ENUM_DEPENDENT_SERVICES *q_u, SVCCTL_R_ENUM_DEPENDENT_SERVICES *r_u)
WERROR _svcctl_query_service_status_ex (pipes_struct *p, SVCCTL_Q_QUERY_SERVICE_STATUSEX *q_u, SVCCTL_R_QUERY_SERVICE_STATUSEX *r_u)
static WERROR fill_svc_config (TALLOC_CTX *ctx, const char *name, SERVICE_CONFIG *config, NT_USER_TOKEN *token)
WERROR _svcctl_query_service_config (pipes_struct *p, SVCCTL_Q_QUERY_SERVICE_CONFIG *q_u, SVCCTL_R_QUERY_SERVICE_CONFIG *r_u)
WERROR _svcctl_query_service_config2 (pipes_struct *p, SVCCTL_Q_QUERY_SERVICE_CONFIG2 *q_u, SVCCTL_R_QUERY_SERVICE_CONFIG2 *r_u)
WERROR _svcctl_lock_service_db (pipes_struct *p, SVCCTL_Q_LOCK_SERVICE_DB *q_u, SVCCTL_R_LOCK_SERVICE_DB *r_u)
WERROR _svcctl_unlock_service_db (pipes_struct *p, SVCCTL_Q_UNLOCK_SERVICE_DB *q_u, SVCCTL_R_UNLOCK_SERVICE_DB *r_u)
WERROR _svcctl_query_service_sec (pipes_struct *p, SVCCTL_Q_QUERY_SERVICE_SEC *q_u, SVCCTL_R_QUERY_SERVICE_SEC *r_u)
WERROR _svcctl_set_service_sec (pipes_struct *p, SVCCTL_Q_SET_SERVICE_SEC *q_u, SVCCTL_R_SET_SERVICE_SEC *r_u)

変数

SERVICE_CONTROL_OPS rcinit_svc_ops
SERVICE_CONTROL_OPS spoolss_svc_ops
SERVICE_CONTROL_OPS netlogon_svc_ops
SERVICE_CONTROL_OPS winreg_svc_ops
SERVICE_CONTROL_OPS wins_svc_ops
service_control_opsvcctl_ops
static struct generic_mapping scm_generic_map
static struct generic_mapping svc_generic_map


関数

BOOL init_service_op_table ( void   ) 

srv_svcctl_nt.c62 行で定義されています。

参照先 service_control_op::namenamenetlogon_svc_opsservice_control_op::opsrcinit_svc_opsspoolss_svc_opsstr_list_count()svcctl_opstalloc_strdup()winreg_svc_opswins_svc_ops.

参照元 svcctl_init_keys().

00063 {
00064         const char **service_list = lp_svcctl_list();
00065         int num_services = SVCCTL_NUM_INTERNAL_SERVICES + str_list_count( service_list );
00066         int i;
00067         
00068         if ( !(svcctl_ops = TALLOC_ARRAY( NULL, struct service_control_op, num_services+1)) ) {
00069                 DEBUG(0,("init_service_op_table: talloc() failed!\n"));
00070                 return False;
00071         }
00072 
00073         /* services listed in smb.conf get the rc.init interface */
00074         
00075         for ( i=0; service_list && service_list[i]; i++ ) {
00076                 svcctl_ops[i].name = talloc_strdup( svcctl_ops, service_list[i] );
00077                 svcctl_ops[i].ops  = &rcinit_svc_ops;
00078         }
00079         
00080         /* add builtin services */
00081         
00082         svcctl_ops[i].name = talloc_strdup( svcctl_ops, "Spooler" );
00083         svcctl_ops[i].ops  = &spoolss_svc_ops;
00084         i++;
00085         
00086         svcctl_ops[i].name = talloc_strdup( svcctl_ops, "NETLOGON" );
00087         svcctl_ops[i].ops  = &netlogon_svc_ops;
00088         i++;
00089         
00090         svcctl_ops[i].name = talloc_strdup( svcctl_ops, "RemoteRegistry" );
00091         svcctl_ops[i].ops  = &winreg_svc_ops;
00092         i++;
00093         
00094         svcctl_ops[i].name = talloc_strdup( svcctl_ops, "WINS" );
00095         svcctl_ops[i].ops  = &wins_svc_ops;
00096         i++;
00097         
00098         /* NULL terminate the array */
00099         
00100         svcctl_ops[i].name = NULL;
00101         svcctl_ops[i].ops  = NULL;
00102         
00103         return True;
00104 }

static struct service_control_op* find_service_by_name ( const char *  name  )  [static]

srv_svcctl_nt.c109 行で定義されています。

参照先 service_control_op::namestrequal()svcctl_ops.

参照元 create_open_service_handle().

00110 {
00111         int i;
00112 
00113         for ( i=0; svcctl_ops[i].name; i++ ) {
00114                 if ( strequal( name, svcctl_ops[i].name ) )
00115                         return &svcctl_ops[i];
00116         }
00117 
00118         return NULL;
00119 }

static NTSTATUS svcctl_access_check ( SEC_DESC sec_desc,
NT_USER_TOKEN token,
uint32  access_desired,
uint32 *  access_granted 
) [static]

srv_svcctl_nt.c123 行で定義されています。

参照先 get_root_nt_token()resultse_access_check()sec_initial_uid().

参照元 _svcctl_open_scmanager()_svcctl_open_service().

00125 {
00126         NTSTATUS result;
00127 
00128         if ( geteuid() == sec_initial_uid() ) {
00129                 DEBUG(5,("svcctl_access_check: using root's token\n"));
00130                 token = get_root_nt_token();
00131         }
00132         
00133         se_access_check( sec_desc, token, access_desired, access_granted, &result );
00134 
00135         return result;
00136 }

static SEC_DESC* construct_scm_sd ( TALLOC_CTX ctx  )  [static]

srv_svcctl_nt.c141 行で定義されています。

参照先 global_sid_Builtin_Administratorsglobal_sid_Worldinit_sec_access()init_sec_ace()make_sec_acl()make_sec_desc()SEC_ACE_TYPE_ACCESS_ALLOWED.

参照元 _svcctl_open_scmanager().

00142 {
00143         SEC_ACE ace[2]; 
00144         SEC_ACCESS mask;
00145         size_t i = 0;
00146         SEC_DESC *sd;
00147         SEC_ACL *acl;
00148         size_t sd_size;
00149 
00150         /* basic access for Everyone */
00151         
00152         init_sec_access(&mask, SC_MANAGER_READ_ACCESS );
00153         init_sec_ace(&ace[i++], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
00154         
00155         /* Full Access 'BUILTIN\Administrators' */
00156         
00157         init_sec_access(&mask,SC_MANAGER_ALL_ACCESS );
00158         init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
00159         
00160         
00161         /* create the security descriptor */
00162         
00163         if ( !(acl = make_sec_acl(ctx, NT4_ACL_REVISION, i, ace)) )
00164                 return NULL;
00165 
00166         if ( !(sd = make_sec_desc(ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE, NULL, NULL, NULL, acl, &sd_size)) )
00167                 return NULL;
00168 
00169         return sd;
00170 }

static void free_service_handle_info ( void *  ptr  )  [static]

srv_svcctl_nt.c176 行で定義されています。

参照元 create_open_service_handle().

00177 {
00178         TALLOC_FREE( ptr );
00179 }

static SERVICE_INFO* find_service_info_by_hnd ( pipes_struct p,
POLICY_HND hnd 
) [static]

srv_svcctl_nt.c185 行で定義されています。

参照先 find_policy_by_hnd().

参照元 _svcctl_control_service()_svcctl_enum_dependent_services()_svcctl_enum_services_status()_svcctl_get_display_name()_svcctl_lock_service_db()_svcctl_open_service()_svcctl_query_service_config()_svcctl_query_service_config2()_svcctl_query_service_sec()_svcctl_query_service_status_ex()_svcctl_query_status()_svcctl_set_service_sec()_svcctl_start_service()_svcctl_unlock_service_db().

00186 {
00187         SERVICE_INFO *service_info = NULL;
00188 
00189         if( !find_policy_by_hnd( p, hnd, (void **)(void *)&service_info) ) {
00190                 DEBUG(2,("find_service_info_by_hnd: handle not found"));
00191                 return NULL;
00192         }
00193 
00194         return service_info;
00195 }

static WERROR create_open_service_handle ( pipes_struct p,
POLICY_HND handle,
uint32  type,
const char *  service,
uint32  access_granted 
) [static]

srv_svcctl_nt.c200 行で定義されています。

参照先 _ServiceInfo::access_grantedcreate_policy_hnd()find_service_by_name()free_service_handle_info()handleservice_control_op::name_ServiceInfo::nameservice_control_op::ops_ServiceInfo::opsresulttalloc_strdup()_ServiceInfo::type.

参照元 _svcctl_lock_service_db()_svcctl_open_scmanager()_svcctl_open_service().

00202 {
00203         SERVICE_INFO *info = NULL;
00204         WERROR result = WERR_OK;
00205         struct service_control_op *s_op;
00206         
00207         if ( !(info = TALLOC_ZERO_P( NULL, SERVICE_INFO )) )
00208                 return WERR_NOMEM;
00209 
00210         /* the Service Manager has a NULL name */
00211         
00212         info->type = SVC_HANDLE_IS_SCM;
00213         
00214         switch ( type ) {
00215         case SVC_HANDLE_IS_SCM:
00216                 info->type = SVC_HANDLE_IS_SCM;
00217                 break;
00218 
00219         case SVC_HANDLE_IS_DBLOCK:
00220                 info->type = SVC_HANDLE_IS_DBLOCK;
00221                 break;
00222                 
00223         case SVC_HANDLE_IS_SERVICE:
00224                 info->type = SVC_HANDLE_IS_SERVICE;
00225                 
00226                 /* lookup the SERVICE_CONTROL_OPS */
00227 
00228                 if ( !(s_op = find_service_by_name( service )) ) {
00229                         result = WERR_NO_SUCH_SERVICE;
00230                         goto done;
00231                 }
00232                 
00233                 info->ops = s_op->ops;
00234 
00235                 if ( !(info->name  = talloc_strdup( info, s_op->name )) ) {
00236                         result = WERR_NOMEM;
00237                         goto done;
00238                 }
00239                 break;
00240 
00241         default:
00242                 result = WERR_NO_SUCH_SERVICE;
00243                 goto done;
00244         }
00245 
00246         info->access_granted = access_granted;  
00247         
00248         /* store the SERVICE_INFO and create an open handle */
00249         
00250         if ( !create_policy_hnd( p, handle, free_service_handle_info, info ) ) {
00251                 result = WERR_ACCESS_DENIED;
00252                 goto done;
00253         }
00254                 
00255 done:
00256         if ( !W_ERROR_IS_OK(result) )
00257                 free_service_handle_info( info );
00258 
00259         return result;
00260 }

WERROR _svcctl_open_scmanager ( pipes_struct p,
SVCCTL_Q_OPEN_SCMANAGER q_u,
SVCCTL_R_OPEN_SCMANAGER r_u 
)

srv_svcctl_nt.c265 行で定義されています。

参照先 SVCCTL_Q_OPEN_SCMANAGER::accessconstruct_scm_sd()create_open_service_handle()SVCCTL_R_OPEN_SCMANAGER::handlepipes_struct::mem_ctxcurrent_user::nt_user_tokenntstatus_to_werror()pipes_struct::pipe_userscm_generic_mapse_map_generic()statussvcctl_access_check().

参照元 api_svcctl_open_scmanager().

00266 {
00267         SEC_DESC *sec_desc;
00268         uint32 access_granted = 0;
00269         NTSTATUS status;
00270         
00271         /* perform access checks */
00272         
00273         if ( !(sec_desc = construct_scm_sd( p->mem_ctx )) )
00274                 return WERR_NOMEM;
00275                 
00276         se_map_generic( &q_u->access, &scm_generic_map );
00277         status = svcctl_access_check( sec_desc, p->pipe_user.nt_user_token, q_u->access, &access_granted );
00278         if ( !NT_STATUS_IS_OK(status) )
00279                 return ntstatus_to_werror( status );
00280                 
00281         return create_open_service_handle( p, &r_u->handle, SVC_HANDLE_IS_SCM, NULL, access_granted );
00282 }

WERROR _svcctl_open_service ( pipes_struct p,
SVCCTL_Q_OPEN_SERVICE q_u,
SVCCTL_R_OPEN_SERVICE r_u 
)

srv_svcctl_nt.c287 行で定義されています。

参照先 SVCCTL_Q_OPEN_SERVICE::accessUNISTR2::buffercreate_open_service_handle()find_service_info_by_hnd()get_root_nt_token()SVCCTL_R_OPEN_SERVICE::handleSVCCTL_Q_OPEN_SERVICE::handlepipes_struct::mem_ctxcurrent_user::nt_user_tokenntstatus_to_werror()pipes_struct::pipe_userrpcstr_pull()se_map_generic()SVCCTL_Q_OPEN_SERVICE::servicenamestatussvc_generic_mapsvcctl_access_check()svcctl_get_secdesc()UNISTR2::uni_str_len.

参照元 api_svcctl_open_service().

00288 {
00289         SEC_DESC *sec_desc;
00290         uint32 access_granted = 0;
00291         NTSTATUS status;
00292         pstring service;
00293 
00294         rpcstr_pull(service, q_u->servicename.buffer, sizeof(service), q_u->servicename.uni_str_len*2, 0);
00295         
00296         DEBUG(5, ("_svcctl_open_service: Attempting to open Service [%s], \n", service));
00297 
00298         
00299         /* based on my tests you can open a service if you have a valid scm handle */
00300         
00301         if ( !find_service_info_by_hnd( p, &q_u->handle ) )
00302                 return WERR_BADFID;
00303                         
00304         /* perform access checks.  Use the root token in order to ensure that we 
00305            retrieve the security descriptor */
00306         
00307         if ( !(sec_desc = svcctl_get_secdesc( p->mem_ctx, service, get_root_nt_token() )) )
00308                 return WERR_NOMEM;
00309                 
00310         se_map_generic( &q_u->access, &svc_generic_map );
00311         status = svcctl_access_check( sec_desc, p->pipe_user.nt_user_token, q_u->access, &access_granted );
00312         if ( !NT_STATUS_IS_OK(status) )
00313                 return ntstatus_to_werror( status );
00314         
00315         return create_open_service_handle( p, &r_u->handle, SVC_HANDLE_IS_SERVICE, service, access_granted );
00316 }

WERROR _svcctl_close_service ( pipes_struct p,
SVCCTL_Q_CLOSE_SERVICE q_u,
SVCCTL_R_CLOSE_SERVICE r_u 
)

srv_svcctl_nt.c321 行で定義されています。

参照先 close_policy_hnd()SVCCTL_Q_CLOSE_SERVICE::handle.

参照元 api_svcctl_close_service().

00322 {
00323         return close_policy_hnd( p, &q_u->handle ) ? WERR_OK : WERR_BADFID;
00324 }

WERROR _svcctl_get_display_name ( pipes_struct p,
SVCCTL_Q_GET_DISPLAY_NAME q_u,
SVCCTL_R_GET_DISPLAY_NAME r_u 
)

srv_svcctl_nt.c329 行で定義されています。

参照先 UNISTR2::bufferfind_service_info_by_hnd()SVCCTL_Q_GET_DISPLAY_NAME::handleinit_svcctl_r_get_display_name()current_user::nt_user_tokenpipes_struct::pipe_userrpcstr_pull()SVCCTL_Q_GET_DISPLAY_NAME::servicenamesvcctl_lookup_dispname()_ServiceInfo::typeUNISTR2::uni_str_len.

参照元 api_svcctl_get_display_name().

00330 {
00331         fstring service;
00332         const char *display_name;
00333         SERVICE_INFO *info = find_service_info_by_hnd( p, &q_u->handle );
00334         
00335         /* can only use an SCM handle here */
00336         
00337         if ( !info || (info->type != SVC_HANDLE_IS_SCM) )
00338                 return WERR_BADFID;
00339                 
00340         rpcstr_pull(service, q_u->servicename.buffer, sizeof(service), q_u->servicename.uni_str_len*2, 0);
00341         
00342         display_name = svcctl_lookup_dispname( service, p->pipe_user.nt_user_token );
00343         init_svcctl_r_get_display_name( r_u, display_name );
00344 
00345         return WERR_OK;
00346 }

WERROR _svcctl_query_status ( pipes_struct p,
SVCCTL_Q_QUERY_STATUS q_u,
SVCCTL_R_QUERY_STATUS r_u 
)

srv_svcctl_nt.c351 行で定義されています。

参照先 _ServiceInfo::access_grantedfind_service_info_by_hnd()SVCCTL_Q_QUERY_STATUS::handle_ServiceInfo::name_ServiceInfo::opsSERVICE_CONTROL_OPS::service_statusSVCCTL_R_QUERY_STATUS::svc_status_ServiceInfo::type.

参照元 api_svcctl_query_status().

00352 {
00353         SERVICE_INFO *info = find_service_info_by_hnd( p, &q_u->handle );
00354         
00355         /* perform access checks */
00356 
00357         if ( !info || (info->type != SVC_HANDLE_IS_SERVICE) )
00358                 return WERR_BADFID;
00359                 
00360         if ( !(info->access_granted & SC_RIGHT_SVC_QUERY_STATUS) )
00361                 return WERR_ACCESS_DENIED;
00362                 
00363         /* try the service specific status call */
00364 
00365         return info->ops->service_status( info->name, &r_u->svc_status );
00366 }

static int enumerate_status ( TALLOC_CTX ctx,
ENUM_SERVICES_STATUS **  status,
NT_USER_TOKEN token 
) [static]

srv_svcctl_nt.c371 行で定義されています。

参照先 init_unistr()nameservice_control_op::opsSERVICE_CONTROL_OPS::service_statusstatussvcctl_lookup_dispname()svcctl_ops.

参照元 _svcctl_enum_services_status().

00372 {
00373         int num_services = 0;
00374         int i;
00375         ENUM_SERVICES_STATUS *st;
00376         const char *display_name;
00377         
00378         /* just count */
00379         while ( svcctl_ops[num_services].name )
00380                 num_services++;
00381 
00382         if ( !(st = TALLOC_ARRAY( ctx, ENUM_SERVICES_STATUS, num_services )) ) {
00383                 DEBUG(0,("enumerate_status: talloc() failed!\n"));
00384                 return -1;
00385         }
00386         
00387         for ( i=0; i<num_services; i++ ) {
00388                 init_unistr( &st[i].servicename, svcctl_ops[i].name );
00389                 
00390                 display_name = svcctl_lookup_dispname( svcctl_ops[i].name, token );
00391                 init_unistr( &st[i].displayname, display_name );
00392                 
00393                 svcctl_ops[i].ops->service_status( svcctl_ops[i].name, &st[i].status );
00394         }
00395         
00396         *status = st;
00397 
00398         return num_services;
00399 }

WERROR _svcctl_enum_services_status ( pipes_struct p,
SVCCTL_Q_ENUM_SERVICES_STATUS q_u,
SVCCTL_R_ENUM_SERVICES_STATUS r_u 
)

srv_svcctl_nt.c404 行で定義されています。

参照先 _ServiceInfo::access_grantedSVCCTL_Q_ENUM_SERVICES_STATUS::buffer_sizeenumerate_status()find_service_info_by_hnd()SVCCTL_Q_ENUM_SERVICES_STATUS::handlepipes_struct::mem_ctxcurrent_user::nt_user_tokenpipes_struct::pipe_userresultsvcctl_sizeof_enum_services_status()_ServiceInfo::type.

参照元 api_svcctl_enum_services_status().

00405 {
00406         ENUM_SERVICES_STATUS *services = NULL;
00407         int num_services;
00408         int i = 0;
00409         size_t buffer_size = 0;
00410         WERROR result = WERR_OK;
00411         SERVICE_INFO *info = find_service_info_by_hnd( p, &q_u->handle );
00412         NT_USER_TOKEN *token = p->pipe_user.nt_user_token;
00413         
00414         /* perform access checks */
00415 
00416         if ( !info || (info->type != SVC_HANDLE_IS_SCM) )
00417                 return WERR_BADFID;
00418                 
00419         if ( !(info->access_granted & SC_RIGHT_MGR_ENUMERATE_SERVICE) ) {
00420                 return WERR_ACCESS_DENIED;
00421         }
00422 
00423         num_services = enumerate_status( p->mem_ctx, &services, token );
00424         if (num_services == -1 ) {
00425                 return WERR_NOMEM;
00426         }
00427 
00428         for ( i=0; i<num_services; i++ ) {
00429                 buffer_size += svcctl_sizeof_enum_services_status(&services[i]);
00430         }
00431 
00432         buffer_size += buffer_size % 4;
00433 
00434         if (buffer_size > q_u->buffer_size ) {
00435                 num_services = 0;
00436                 result = WERR_MORE_DATA;
00437         }
00438 
00439         rpcbuf_init(&r_u->buffer, q_u->buffer_size, p->mem_ctx);
00440 
00441         if ( W_ERROR_IS_OK(result) ) {
00442                 for ( i=0; i<num_services; i++ )
00443                         svcctl_io_enum_services_status( "", &services[i], &r_u->buffer, 0 );
00444         }
00445 
00446         r_u->needed      = (buffer_size > q_u->buffer_size) ? buffer_size : q_u->buffer_size;
00447         r_u->returned    = (uint32)num_services;
00448 
00449         if ( !(r_u->resume = TALLOC_P( p->mem_ctx, uint32 )) )
00450                 return WERR_NOMEM;
00451 
00452         *r_u->resume = 0x0;
00453 
00454         return result;
00455 }

WERROR _svcctl_start_service ( pipes_struct p,
SVCCTL_Q_START_SERVICE q_u,
SVCCTL_R_START_SERVICE r_u 
)

srv_svcctl_nt.c460 行で定義されています。

参照先 _ServiceInfo::access_grantedfind_service_info_by_hnd()SVCCTL_Q_START_SERVICE::handle_ServiceInfo::name_ServiceInfo::opsSERVICE_CONTROL_OPS::start_service_ServiceInfo::type.

参照元 api_svcctl_start_service().

00461 {
00462         SERVICE_INFO *info = find_service_info_by_hnd( p, &q_u->handle );
00463         
00464         /* perform access checks */
00465 
00466         if ( !info || (info->type != SVC_HANDLE_IS_SERVICE) )
00467                 return WERR_BADFID;
00468         
00469         if ( !(info->access_granted & SC_RIGHT_SVC_START) )
00470                 return WERR_ACCESS_DENIED;
00471                 
00472         return info->ops->start_service( info->name );
00473 }

WERROR _svcctl_control_service ( pipes_struct p,
SVCCTL_Q_CONTROL_SERVICE q_u,
SVCCTL_R_CONTROL_SERVICE r_u 
)

srv_svcctl_nt.c478 行で定義されています。

参照先 _ServiceInfo::access_grantedSVCCTL_Q_CONTROL_SERVICE::controlfind_service_info_by_hnd()SVCCTL_Q_CONTROL_SERVICE::handle_ServiceInfo::name_ServiceInfo::opsSERVICE_CONTROL_OPS::service_statusSERVICE_CONTROL_OPS::stop_serviceSVCCTL_R_CONTROL_SERVICE::svc_status_ServiceInfo::type.

参照元 api_svcctl_control_service().

00479 {
00480         SERVICE_INFO *info = find_service_info_by_hnd( p, &q_u->handle );
00481         
00482         /* perform access checks */
00483         
00484         if ( !info || (info->type != SVC_HANDLE_IS_SERVICE) )
00485                 return WERR_BADFID;     
00486         
00487         switch ( q_u->control ) {
00488         case SVCCTL_CONTROL_STOP:
00489                 if ( !(info->access_granted & SC_RIGHT_SVC_STOP) )
00490                         return WERR_ACCESS_DENIED;
00491                         
00492                 return info->ops->stop_service( info->name, &r_u->svc_status );
00493                 
00494         case SVCCTL_CONTROL_INTERROGATE:
00495                 if ( !(info->access_granted & SC_RIGHT_SVC_QUERY_STATUS) )
00496                         return WERR_ACCESS_DENIED;
00497                         
00498                 return info->ops->service_status( info->name, &r_u->svc_status );
00499         }
00500         
00501         /* default control action */
00502         
00503         return WERR_ACCESS_DENIED;
00504 }

WERROR _svcctl_enum_dependent_services ( pipes_struct p,
SVCCTL_Q_ENUM_DEPENDENT_SERVICES q_u,
SVCCTL_R_ENUM_DEPENDENT_SERVICES r_u 
)

srv_svcctl_nt.c509 行で定義されています。

参照先 _ServiceInfo::access_grantedSVCCTL_R_ENUM_DEPENDENT_SERVICES::bufferSVCCTL_Q_ENUM_DEPENDENT_SERVICES::buffer_sizefind_service_info_by_hnd()SVCCTL_Q_ENUM_DEPENDENT_SERVICES::handlepipes_struct::mem_ctxSVCCTL_R_ENUM_DEPENDENT_SERVICES::neededSVCCTL_R_ENUM_DEPENDENT_SERVICES::returnedrpcbuf_init()_ServiceInfo::type.

参照元 api_svcctl_enum_dependent_services().

00510 {
00511         SERVICE_INFO *info = find_service_info_by_hnd( p, &q_u->handle );
00512         
00513         /* perform access checks */
00514 
00515         if ( !info || (info->type != SVC_HANDLE_IS_SERVICE) )
00516                 return WERR_BADFID;     
00517         
00518         if ( !(info->access_granted & SC_RIGHT_SVC_ENUMERATE_DEPENDENTS) )
00519                 return WERR_ACCESS_DENIED;
00520                         
00521         /* we have to set the outgoing buffer size to the same as the 
00522            incoming buffer size (even in the case of failure */
00523 
00524         rpcbuf_init( &r_u->buffer, q_u->buffer_size, p->mem_ctx );
00525                                 
00526         r_u->needed      = q_u->buffer_size;
00527         
00528         /* no dependent services...basically a stub function */
00529         r_u->returned    = 0;
00530 
00531         return WERR_OK;
00532 }

WERROR _svcctl_query_service_status_ex ( pipes_struct p,
SVCCTL_Q_QUERY_SERVICE_STATUSEX q_u,
SVCCTL_R_QUERY_SERVICE_STATUSEX r_u 
)

srv_svcctl_nt.c537 行で定義されています。

参照先 _ServiceInfo::access_grantedSVCCTL_R_QUERY_SERVICE_STATUSEX::bufferSVCCTL_Q_QUERY_SERVICE_STATUSEX::buffer_sizefind_service_info_by_hnd()SVCCTL_Q_QUERY_SERVICE_STATUSEX::handleSVCCTL_Q_QUERY_SERVICE_STATUSEX::levelpipes_struct::mem_ctx_ServiceInfo::nameSVCCTL_R_QUERY_SERVICE_STATUSEX::needed_ServiceInfo::opsSERVICE_STATUS_PROCESS::process_idrpcbuf_init()SERVICE_STATUS_PROCESS::service_flagsSERVICE_CONTROL_OPS::service_statusSERVICE_STATUS_PROCESS::statussvcctl_io_service_status_process()sys_getpid()_ServiceInfo::type.

参照元 api_svcctl_query_service_status_ex().

00538 {
00539         SERVICE_INFO *info = find_service_info_by_hnd( p, &q_u->handle );
00540         uint32 buffer_size;
00541         
00542         /* perform access checks */
00543 
00544         if ( !info || (info->type != SVC_HANDLE_IS_SERVICE) )
00545                 return WERR_BADFID;     
00546         
00547         if ( !(info->access_granted & SC_RIGHT_SVC_QUERY_STATUS) )
00548                 return WERR_ACCESS_DENIED;
00549 
00550         /* we have to set the outgoing buffer size to the same as the 
00551            incoming buffer size (even in the case of failure) */
00552 
00553         rpcbuf_init( &r_u->buffer, q_u->buffer_size, p->mem_ctx );
00554         r_u->needed = q_u->buffer_size;
00555         
00556         switch ( q_u->level ) {
00557                 case SVC_STATUS_PROCESS_INFO:
00558                 {
00559                         SERVICE_STATUS_PROCESS svc_stat_proc;
00560 
00561                         /* Get the status of the service.. */
00562                         info->ops->service_status( info->name, &svc_stat_proc.status );
00563                         svc_stat_proc.process_id     = sys_getpid();
00564                         svc_stat_proc.service_flags  = 0x0;
00565 
00566                         svcctl_io_service_status_process( "", &svc_stat_proc, &r_u->buffer, 0 );
00567                         buffer_size = sizeof(SERVICE_STATUS_PROCESS);
00568                         break;
00569                 }
00570                         
00571                 default:
00572                         return WERR_UNKNOWN_LEVEL; 
00573         }
00574 
00575         
00576         buffer_size += buffer_size % 4;
00577         r_u->needed = (buffer_size > q_u->buffer_size) ? buffer_size : q_u->buffer_size;
00578 
00579         if (buffer_size > q_u->buffer_size ) 
00580                 return WERR_MORE_DATA;
00581         
00582         return WERR_OK;
00583 }

static WERROR fill_svc_config ( TALLOC_CTX ctx,
const char *  name,
SERVICE_CONFIG config,
NT_USER_TOKEN token 
) [static]

srv_svcctl_nt.c588 行で定義されています。

参照先 SERVICE_CONFIG::displaynameSERVICE_CONFIG::error_controlSERVICE_CONFIG::executablepathinit_unistr2()regval_ctr_getvalue()regval_sz()SERVICE_CONFIG::service_typeSERVICE_CONFIG::start_typeSERVICE_CONFIG::startnamestrequal()svcctl_fetch_regvalues()SERVICE_CONFIG::tag_idUNI_STR_TERMINATEvalues.

参照元 _svcctl_query_service_config().

00589 {
00590         REGVAL_CTR *values;
00591         REGISTRY_VALUE *val;
00592 
00593         /* retrieve the registry values for this service */
00594         
00595         if ( !(values = svcctl_fetch_regvalues( name, token )) )
00596                 return WERR_REG_CORRUPT;
00597         
00598         /* now fill in the individual values */
00599                 
00600         config->displayname = TALLOC_ZERO_P( ctx, UNISTR2 );
00601         if ( (val = regval_ctr_getvalue( values, "DisplayName" )) != NULL )
00602                 init_unistr2( config->displayname, regval_sz( val ), UNI_STR_TERMINATE );
00603         else
00604                 init_unistr2( config->displayname, name, UNI_STR_TERMINATE );
00605 
00606         if ( (val = regval_ctr_getvalue( values, "ObjectName" )) != NULL ) {
00607                 config->startname = TALLOC_ZERO_P( ctx, UNISTR2 );              
00608                 init_unistr2( config->startname, regval_sz( val ), UNI_STR_TERMINATE );
00609         }
00610                 
00611         if ( (val = regval_ctr_getvalue( values, "ImagePath" )) != NULL ) {
00612                 config->executablepath = TALLOC_ZERO_P( ctx, UNISTR2 );         
00613                 init_unistr2( config->executablepath, regval_sz( val ), UNI_STR_TERMINATE );
00614         }
00615 
00616         /* a few hard coded values */
00617         /* loadordergroup and dependencies are empty */
00618         
00619         config->tag_id           = 0x00000000;                  /* unassigned loadorder group */
00620         config->service_type     = SVCCTL_WIN32_OWN_PROC;
00621         config->error_control    = SVCCTL_SVC_ERROR_NORMAL;
00622 
00623         /* set the start type.  NetLogon and WINS are disabled to prevent 
00624            the client from showing the "Start" button (if of course the services
00625            are not running */
00626 
00627         if ( strequal( name, "NETLOGON" ) && ( lp_servicenumber(name) == -1 ) )
00628                 config->start_type = SVCCTL_DISABLED;
00629         else if ( strequal( name, "WINS" ) && ( !lp_wins_support() ))
00630                 config->start_type = SVCCTL_DISABLED;
00631         else
00632                 config->start_type = SVCCTL_DEMAND_START;
00633         
00634 
00635         TALLOC_FREE( values );
00636 
00637         return WERR_OK;
00638 }

WERROR _svcctl_query_service_config ( pipes_struct p,
SVCCTL_Q_QUERY_SERVICE_CONFIG q_u,
SVCCTL_R_QUERY_SERVICE_CONFIG r_u 
)

srv_svcctl_nt.c643 行で定義されています。

参照先 _ServiceInfo::access_grantedSVCCTL_Q_QUERY_SERVICE_CONFIG::buffer_sizeSVCCTL_R_QUERY_SERVICE_CONFIG::configfill_svc_config()find_service_info_by_hnd()SVCCTL_Q_QUERY_SERVICE_CONFIG::handlepipes_struct::mem_ctx_ServiceInfo::nameSVCCTL_R_QUERY_SERVICE_CONFIG::neededcurrent_user::nt_user_tokenpipes_struct::pipe_usersvcctl_sizeof_service_config()_ServiceInfo::type.

参照元 api_svcctl_query_service_config().

00644 {
00645         SERVICE_INFO *info = find_service_info_by_hnd( p, &q_u->handle );
00646         uint32 buffer_size;
00647         WERROR wresult;
00648         
00649         /* perform access checks */
00650 
00651         if ( !info || (info->type != SVC_HANDLE_IS_SERVICE) )
00652                 return WERR_BADFID;     
00653         
00654         if ( !(info->access_granted & SC_RIGHT_SVC_QUERY_CONFIG) )
00655                 return WERR_ACCESS_DENIED;
00656 
00657         /* we have to set the outgoing buffer size to the same as the 
00658            incoming buffer size (even in the case of failure */
00659 
00660         r_u->needed      = q_u->buffer_size;
00661         
00662         wresult = fill_svc_config( p->mem_ctx, info->name, &r_u->config, p->pipe_user.nt_user_token );
00663         if ( !W_ERROR_IS_OK(wresult) )
00664                 return wresult;
00665         
00666         buffer_size = svcctl_sizeof_service_config( &r_u->config );
00667         r_u->needed = (buffer_size > q_u->buffer_size) ? buffer_size : q_u->buffer_size;
00668 
00669         if (buffer_size > q_u->buffer_size ) {
00670                 ZERO_STRUCTP( &r_u->config );
00671                 return WERR_INSUFFICIENT_BUFFER;
00672         }
00673                 
00674         return WERR_OK;
00675 }

WERROR _svcctl_query_service_config2 ( pipes_struct p,
SVCCTL_Q_QUERY_SERVICE_CONFIG2 q_u,
SVCCTL_R_QUERY_SERVICE_CONFIG2 r_u 
)

srv_svcctl_nt.c680 行で定義されています。

参照先 _ServiceInfo::access_grantedSVCCTL_R_QUERY_SERVICE_CONFIG2::bufferSVCCTL_Q_QUERY_SERVICE_CONFIG2::buffer_sizedescriptionfind_service_info_by_hnd()SVCCTL_Q_QUERY_SERVICE_CONFIG2::handleinit_service_description_buffer()SVCCTL_Q_QUERY_SERVICE_CONFIG2::levelpipes_struct::mem_ctx_ServiceInfo::nameSVCCTL_R_QUERY_SERVICE_CONFIG2::neededcurrent_user::nt_user_tokenpipes_struct::pipe_userrpcbuf_init()svcctl_io_service_description()svcctl_io_service_fa()svcctl_lookup_description()svcctl_sizeof_service_description()svcctl_sizeof_service_fa()_ServiceInfo::type.

参照元 api_svcctl_query_service_config2().

00681 {
00682         SERVICE_INFO *info = find_service_info_by_hnd( p, &q_u->handle );
00683         uint32 buffer_size;
00684         
00685         /* perform access checks */
00686 
00687         if ( !info || (info->type != SVC_HANDLE_IS_SERVICE) )
00688                 return WERR_BADFID;     
00689         
00690         if ( !(info->access_granted & SC_RIGHT_SVC_QUERY_CONFIG) )
00691                 return WERR_ACCESS_DENIED;
00692  
00693         /* we have to set the outgoing buffer size to the same as the 
00694            incoming buffer size (even in the case of failure */
00695 
00696         rpcbuf_init( &r_u->buffer, q_u->buffer_size, p->mem_ctx );
00697         r_u->needed = q_u->buffer_size;
00698 
00699         switch ( q_u->level ) {
00700         case SERVICE_CONFIG_DESCRIPTION:
00701                 {
00702                         SERVICE_DESCRIPTION desc_buf;
00703                         const char *description;
00704                         
00705                         description = svcctl_lookup_description( info->name, p->pipe_user.nt_user_token );
00706                         
00707                         ZERO_STRUCTP( &desc_buf );
00708 
00709                         init_service_description_buffer( &desc_buf, description );
00710                         svcctl_io_service_description( "", &desc_buf, &r_u->buffer, 0 );
00711                         buffer_size = svcctl_sizeof_service_description( &desc_buf );
00712 
00713                         break;
00714                 }
00715                 break;
00716         case SERVICE_CONFIG_FAILURE_ACTIONS:
00717                 {
00718                         SERVICE_FAILURE_ACTIONS actions;
00719 
00720                         /* nothing to say...just service the request */
00721 
00722                         ZERO_STRUCTP( &actions );
00723                         svcctl_io_service_fa( "", &actions, &r_u->buffer, 0 );
00724                         buffer_size = svcctl_sizeof_service_fa( &actions );
00725 
00726                         break;
00727                 }
00728                 break;
00729 
00730         default:
00731                 return WERR_UNKNOWN_LEVEL;
00732         }
00733         
00734         buffer_size += buffer_size % 4;
00735         r_u->needed = (buffer_size > q_u->buffer_size) ? buffer_size : q_u->buffer_size;
00736 
00737         if (buffer_size > q_u->buffer_size )
00738                 return WERR_INSUFFICIENT_BUFFER;
00739 
00740         return WERR_OK;
00741 }

WERROR _svcctl_lock_service_db ( pipes_struct p,
SVCCTL_Q_LOCK_SERVICE_DB q_u,
SVCCTL_R_LOCK_SERVICE_DB r_u 
)

srv_svcctl_nt.c746 行で定義されています。

参照先 _ServiceInfo::access_grantedcreate_open_service_handle()find_service_info_by_hnd()SVCCTL_R_LOCK_SERVICE_DB::h_lockSVCCTL_Q_LOCK_SERVICE_DB::handle_ServiceInfo::type.

参照元 api_svcctl_lock_service_db().

00747 {
00748         SERVICE_INFO *info = find_service_info_by_hnd( p, &q_u->handle );
00749         
00750         /* perform access checks */
00751 
00752         if ( !info || (info->type != SVC_HANDLE_IS_SCM) )
00753                 return WERR_BADFID;     
00754         
00755         if ( !(info->access_granted & SC_RIGHT_MGR_LOCK) )
00756                 return WERR_ACCESS_DENIED;
00757 
00758         /* Just open a handle.  Doesn't actually lock anything */
00759         
00760         return create_open_service_handle( p, &r_u->h_lock, SVC_HANDLE_IS_DBLOCK, NULL, 0 );
00761 ;
00762 }

WERROR _svcctl_unlock_service_db ( pipes_struct p,
SVCCTL_Q_UNLOCK_SERVICE_DB q_u,
SVCCTL_R_UNLOCK_SERVICE_DB r_u 
)

srv_svcctl_nt.c767 行で定義されています。

参照先 close_policy_hnd()find_service_info_by_hnd()SVCCTL_Q_UNLOCK_SERVICE_DB::h_lock_ServiceInfo::type.

参照元 api_svcctl_unlock_service_db().

00768 {
00769         SERVICE_INFO *info = find_service_info_by_hnd( p, &q_u->h_lock );
00770 
00771 
00772         if ( !info || (info->type != SVC_HANDLE_IS_DBLOCK) )
00773                 return WERR_BADFID;     
00774                 
00775         return close_policy_hnd( p, &q_u->h_lock) ? WERR_OK : WERR_BADFID;
00776 }

WERROR _svcctl_query_service_sec ( pipes_struct p,
SVCCTL_Q_QUERY_SERVICE_SEC q_u,
SVCCTL_R_QUERY_SERVICE_SEC r_u 
)

srv_svcctl_nt.c781 行で定義されています。

参照先 _ServiceInfo::access_grantedSVCCTL_R_QUERY_SERVICE_SEC::bufferSVCCTL_Q_QUERY_SERVICE_SEC::buffer_sizefind_service_info_by_hnd()get_root_nt_token()SVCCTL_Q_QUERY_SERVICE_SEC::handlepipes_struct::mem_ctx_ServiceInfo::nameSVCCTL_R_QUERY_SERVICE_SEC::neededRPC_BUFFER::prsrpcbuf_init()sec_desc_size()sec_io_desc()SVCCTL_Q_QUERY_SERVICE_SEC::security_flagssvcctl_get_secdesc()_ServiceInfo::type.

参照元 api_svcctl_query_security_sec().

00782 {
00783         SERVICE_INFO *info = find_service_info_by_hnd( p, &q_u->handle );
00784         SEC_DESC *sec_desc;
00785 
00786 
00787         /* only support the SCM and individual services */
00788 
00789         if ( !info || !(info->type & (SVC_HANDLE_IS_SERVICE|SVC_HANDLE_IS_SCM)) )
00790                 return WERR_BADFID;     
00791 
00792         /* check access reights (according to MSDN) */
00793 
00794         if ( !(info->access_granted & STD_RIGHT_READ_CONTROL_ACCESS) )
00795                 return WERR_ACCESS_DENIED;
00796 
00797         /* TODO: handle something besides DACL_SECURITY_INFORMATION */
00798 
00799         if ( (q_u->security_flags & DACL_SECURITY_INFORMATION) != DACL_SECURITY_INFORMATION )
00800                 return WERR_INVALID_PARAM;
00801 
00802         /* lookup the security descriptor and marshall it up for a reply */
00803 
00804         if ( !(sec_desc = svcctl_get_secdesc( p->mem_ctx, info->name, get_root_nt_token() )) )
00805                 return WERR_NOMEM;
00806 
00807         r_u->needed = sec_desc_size( sec_desc );
00808 
00809         if ( r_u->needed > q_u->buffer_size ) {
00810                 ZERO_STRUCTP( &r_u->buffer );
00811                 return WERR_INSUFFICIENT_BUFFER;
00812         }
00813 
00814         rpcbuf_init( &r_u->buffer, q_u->buffer_size, p->mem_ctx );
00815 
00816         if ( !sec_io_desc("", &sec_desc, &r_u->buffer.prs, 0 ) )
00817                 return WERR_NOMEM;
00818                 
00819         return WERR_OK;
00820 }

WERROR _svcctl_set_service_sec ( pipes_struct p,
SVCCTL_Q_SET_SERVICE_SEC q_u,
SVCCTL_R_SET_SERVICE_SEC r_u 
)

srv_svcctl_nt.c825 行で定義されています。

参照先 _ServiceInfo::access_grantedSVCCTL_Q_SET_SERVICE_SEC::bufferfind_service_info_by_hnd()SVCCTL_Q_SET_SERVICE_SEC::handlepipes_struct::mem_ctx_ServiceInfo::namecurrent_user::nt_user_tokenpipes_struct::pipe_userRPC_BUFFER::prssec_io_desc()SVCCTL_Q_SET_SERVICE_SEC::security_flagssvcctl_set_secdesc()_ServiceInfo::type.

参照元 api_svcctl_set_security_sec().

00826 {
00827         SERVICE_INFO *info = find_service_info_by_hnd( p, &q_u->handle );
00828         SEC_DESC *sec_desc = NULL;
00829         uint32 required_access;
00830 
00831         if ( !info || !(info->type & (SVC_HANDLE_IS_SERVICE|SVC_HANDLE_IS_SCM))  )
00832                 return WERR_BADFID;
00833 
00834         /* can't set the security de4scriptor on the ServiceControlManager */
00835 
00836         if ( info->type == SVC_HANDLE_IS_SCM )
00837                 return WERR_ACCESS_DENIED;      
00838 
00839         /* check the access on the open handle */
00840         
00841         switch ( q_u->security_flags ) {
00842                 case DACL_SECURITY_INFORMATION:
00843                         required_access = STD_RIGHT_WRITE_DAC_ACCESS;
00844                         break;
00845                         
00846                 case OWNER_SECURITY_INFORMATION:
00847                 case GROUP_SECURITY_INFORMATION:
00848                         required_access = STD_RIGHT_WRITE_OWNER_ACCESS;
00849                         break;
00850                         
00851                 case SACL_SECURITY_INFORMATION:
00852                         return WERR_INVALID_PARAM;
00853                 default:
00854                         return WERR_INVALID_PARAM;
00855         }
00856         
00857         if ( !(info->access_granted & required_access) )
00858                 return WERR_ACCESS_DENIED;
00859         
00860         /* read the security descfriptor */
00861                 
00862         if ( !sec_io_desc("", &sec_desc, &q_u->buffer.prs, 0 ) )
00863                 return WERR_NOMEM;
00864                 
00865         /* store the new SD */
00866 
00867         if ( !svcctl_set_secdesc( p->mem_ctx, info->name, sec_desc, p->pipe_user.nt_user_token ) ) 
00868                 return WERR_ACCESS_DENIED;
00869 
00870         return WERR_OK;
00871 }


変数

SERVICE_CONTROL_OPS rcinit_svc_ops

svc_rcinit.c106 行で定義されています。

参照元 init_service_op_table().

SERVICE_CONTROL_OPS spoolss_svc_ops

svc_spoolss.c77 行で定義されています。

参照元 init_service_op_table().

SERVICE_CONTROL_OPS netlogon_svc_ops

svc_netlogon.c71 行で定義されています。

参照元 init_service_op_table().

SERVICE_CONTROL_OPS winreg_svc_ops

svc_winreg.c60 行で定義されています。

参照元 init_service_op_table().

SERVICE_CONTROL_OPS wins_svc_ops

svc_wins.c68 行で定義されています。

参照元 init_service_op_table().

struct service_control_op* svcctl_ops

srv_svcctl_nt.c51 行で定義されています。

参照元 enumerate_status()find_service_by_name()init_service_op_table().

struct generic_mapping scm_generic_map [static]

初期値:

        { SC_MANAGER_READ_ACCESS, SC_MANAGER_WRITE_ACCESS, SC_MANAGER_EXECUTE_ACCESS, SC_MANAGER_ALL_ACCESS }

srv_svcctl_nt.c53 行で定義されています。

参照元 _svcctl_open_scmanager().

struct generic_mapping svc_generic_map [static]

初期値:

        { SERVICE_READ_ACCESS, SERVICE_WRITE_ACCESS, SERVICE_EXECUTE_ACCESS, SERVICE_ALL_ACCESS }

srv_svcctl_nt.c55 行で定義されています。

参照元 _svcctl_open_service().


Sambaに対してSat Aug 29 21:24:23 2009に生成されました。  doxygen 1.4.7