📄 srv_svcctl_nt.c
字号:
if ( W_ERROR_IS_OK(result) ) { for ( i=0; i<num_services; i++ ) svcctl_io_enum_services_status( "", &services[i], &r_u->buffer, 0 ); } r_u->needed = (buffer_size > q_u->buffer_size) ? buffer_size : q_u->buffer_size; r_u->returned = num_services; if ( !(r_u->resume = TALLOC_P( p->mem_ctx, uint32 )) ) return WERR_NOMEM; *r_u->resume = 0x0; return result;}/****************************************************************************************************************************************/WERROR _svcctl_start_service(pipes_struct *p, SVCCTL_Q_START_SERVICE *q_u, SVCCTL_R_START_SERVICE *r_u){ SERVICE_INFO *info = find_service_info_by_hnd( p, &q_u->handle ); /* perform access checks */ if ( !info || (info->type != SVC_HANDLE_IS_SERVICE) ) return WERR_BADFID; if ( !(info->access_granted & SC_RIGHT_SVC_START) ) return WERR_ACCESS_DENIED; return info->ops->start_service( info->name );}/****************************************************************************************************************************************/WERROR _svcctl_control_service(pipes_struct *p, SVCCTL_Q_CONTROL_SERVICE *q_u, SVCCTL_R_CONTROL_SERVICE *r_u){ SERVICE_INFO *info = find_service_info_by_hnd( p, &q_u->handle ); /* perform access checks */ if ( !info || (info->type != SVC_HANDLE_IS_SERVICE) ) return WERR_BADFID; switch ( q_u->control ) { case SVCCTL_CONTROL_STOP: if ( !(info->access_granted & SC_RIGHT_SVC_STOP) ) return WERR_ACCESS_DENIED; return info->ops->stop_service( info->name, &r_u->svc_status ); case SVCCTL_CONTROL_INTERROGATE: if ( !(info->access_granted & SC_RIGHT_SVC_QUERY_STATUS) ) return WERR_ACCESS_DENIED; return info->ops->service_status( info->name, &r_u->svc_status ); } /* default control action */ return WERR_ACCESS_DENIED;}/****************************************************************************************************************************************/WERROR _svcctl_enum_dependent_services( pipes_struct *p, SVCCTL_Q_ENUM_DEPENDENT_SERVICES *q_u, SVCCTL_R_ENUM_DEPENDENT_SERVICES *r_u ){ SERVICE_INFO *info = find_service_info_by_hnd( p, &q_u->handle ); /* perform access checks */ if ( !info || (info->type != SVC_HANDLE_IS_SERVICE) ) return WERR_BADFID; if ( !(info->access_granted & SC_RIGHT_SVC_ENUMERATE_DEPENDENTS) ) return WERR_ACCESS_DENIED; /* we have to set the outgoing buffer size to the same as the incoming buffer size (even in the case of failure */ rpcbuf_init( &r_u->buffer, q_u->buffer_size, p->mem_ctx ); r_u->needed = q_u->buffer_size; /* no dependent services...basically a stub function */ r_u->returned = 0; return WERR_OK;}/****************************************************************************************************************************************/WERROR _svcctl_query_service_status_ex( pipes_struct *p, SVCCTL_Q_QUERY_SERVICE_STATUSEX *q_u, SVCCTL_R_QUERY_SERVICE_STATUSEX *r_u ){ SERVICE_INFO *info = find_service_info_by_hnd( p, &q_u->handle ); uint32 buffer_size; /* perform access checks */ if ( !info || (info->type != SVC_HANDLE_IS_SERVICE) ) return WERR_BADFID; if ( !(info->access_granted & SC_RIGHT_SVC_QUERY_STATUS) ) return WERR_ACCESS_DENIED; /* we have to set the outgoing buffer size to the same as the incoming buffer size (even in the case of failure) */ rpcbuf_init( &r_u->buffer, q_u->buffer_size, p->mem_ctx ); r_u->needed = q_u->buffer_size; switch ( q_u->level ) { case SVC_STATUS_PROCESS_INFO: { SERVICE_STATUS_PROCESS svc_stat_proc; /* Get the status of the service.. */ info->ops->service_status( info->name, &svc_stat_proc.status ); svc_stat_proc.process_id = sys_getpid(); svc_stat_proc.service_flags = 0x0; svcctl_io_service_status_process( "", &svc_stat_proc, &r_u->buffer, 0 ); buffer_size = sizeof(SERVICE_STATUS_PROCESS); break; } default: return WERR_UNKNOWN_LEVEL; } buffer_size += buffer_size % 4; r_u->needed = (buffer_size > q_u->buffer_size) ? buffer_size : q_u->buffer_size; if (buffer_size > q_u->buffer_size ) return WERR_MORE_DATA; return WERR_OK;}/****************************************************************************************************************************************/static WERROR fill_svc_config( TALLOC_CTX *ctx, const char *name, SERVICE_CONFIG *config, NT_USER_TOKEN *token ){ REGVAL_CTR *values; REGISTRY_VALUE *val; /* retrieve the registry values for this service */ if ( !(values = svcctl_fetch_regvalues( name, token )) ) return WERR_REG_CORRUPT; /* now fill in the individual values */ config->displayname = TALLOC_ZERO_P( ctx, UNISTR2 ); if ( (val = regval_ctr_getvalue( values, "DisplayName" )) != NULL ) init_unistr2( config->displayname, regval_sz( val ), UNI_STR_TERMINATE ); else init_unistr2( config->displayname, name, UNI_STR_TERMINATE ); if ( (val = regval_ctr_getvalue( values, "ObjectName" )) != NULL ) { config->startname = TALLOC_ZERO_P( ctx, UNISTR2 ); init_unistr2( config->startname, regval_sz( val ), UNI_STR_TERMINATE ); } if ( (val = regval_ctr_getvalue( values, "ImagePath" )) != NULL ) { config->executablepath = TALLOC_ZERO_P( ctx, UNISTR2 ); init_unistr2( config->executablepath, regval_sz( val ), UNI_STR_TERMINATE ); } /* a few hard coded values */ /* loadordergroup and dependencies are empty */ config->tag_id = 0x00000000; /* unassigned loadorder group */ config->service_type = SVCCTL_WIN32_OWN_PROC; config->error_control = SVCCTL_SVC_ERROR_NORMAL; /* set the start type. NetLogon and WINS are disabled to prevent the client from showing the "Start" button (if of course the services are not running */ if ( strequal( name, "NETLOGON" ) && ( lp_servicenumber(name) == -1 ) ) config->start_type = SVCCTL_DISABLED; else if ( strequal( name, "WINS" ) && ( !lp_wins_support() )) config->start_type = SVCCTL_DISABLED; else config->start_type = SVCCTL_DEMAND_START; TALLOC_FREE( values ); return WERR_OK;}/****************************************************************************************************************************************/WERROR _svcctl_query_service_config( pipes_struct *p, SVCCTL_Q_QUERY_SERVICE_CONFIG *q_u, SVCCTL_R_QUERY_SERVICE_CONFIG *r_u ){ SERVICE_INFO *info = find_service_info_by_hnd( p, &q_u->handle ); uint32 buffer_size; WERROR wresult; /* perform access checks */ if ( !info || (info->type != SVC_HANDLE_IS_SERVICE) ) return WERR_BADFID; if ( !(info->access_granted & SC_RIGHT_SVC_QUERY_CONFIG) ) return WERR_ACCESS_DENIED; /* we have to set the outgoing buffer size to the same as the incoming buffer size (even in the case of failure */ r_u->needed = q_u->buffer_size; wresult = fill_svc_config( p->mem_ctx, info->name, &r_u->config, p->pipe_user.nt_user_token ); if ( !W_ERROR_IS_OK(wresult) ) return wresult; buffer_size = svcctl_sizeof_service_config( &r_u->config ); r_u->needed = (buffer_size > q_u->buffer_size) ? buffer_size : q_u->buffer_size; if (buffer_size > q_u->buffer_size ) { ZERO_STRUCTP( &r_u->config ); return WERR_INSUFFICIENT_BUFFER; } return WERR_OK;}/****************************************************************************************************************************************/WERROR _svcctl_query_service_config2( pipes_struct *p, SVCCTL_Q_QUERY_SERVICE_CONFIG2 *q_u, SVCCTL_R_QUERY_SERVICE_CONFIG2 *r_u ){ SERVICE_INFO *info = find_service_info_by_hnd( p, &q_u->handle ); uint32 buffer_size; /* perform access checks */ if ( !info || (info->type != SVC_HANDLE_IS_SERVICE) ) return WERR_BADFID; if ( !(info->access_granted & SC_RIGHT_SVC_QUERY_CONFIG) ) return WERR_ACCESS_DENIED; /* we have to set the outgoing buffer size to the same as the incoming buffer size (even in the case of failure */ rpcbuf_init( &r_u->buffer, q_u->buffer_size, p->mem_ctx ); r_u->needed = q_u->buffer_size; switch ( q_u->level ) { case SERVICE_CONFIG_DESCRIPTION: { SERVICE_DESCRIPTION desc_buf; const char *description; description = svcctl_lookup_description( info->name, p->pipe_user.nt_user_token ); ZERO_STRUCTP( &desc_buf ); init_service_description_buffer( &desc_buf, description ); svcctl_io_service_description( "", &desc_buf, &r_u->buffer, 0 ); buffer_size = svcctl_sizeof_service_description( &desc_buf ); break; } break; case SERVICE_CONFIG_FAILURE_ACTIONS: { SERVICE_FAILURE_ACTIONS actions; /* nothing to say...just service the request */ ZERO_STRUCTP( &actions ); svcctl_io_service_fa( "", &actions, &r_u->buffer, 0 ); buffer_size = svcctl_sizeof_service_fa( &actions ); break; } break; default: return WERR_UNKNOWN_LEVEL; } buffer_size += buffer_size % 4; r_u->needed = (buffer_size > q_u->buffer_size) ? buffer_size : q_u->buffer_size; if (buffer_size > q_u->buffer_size ) return WERR_INSUFFICIENT_BUFFER; return WERR_OK;}/****************************************************************************************************************************************/WERROR _svcctl_lock_service_db( pipes_struct *p, SVCCTL_Q_LOCK_SERVICE_DB *q_u, SVCCTL_R_LOCK_SERVICE_DB *r_u ){ SERVICE_INFO *info = find_service_info_by_hnd( p, &q_u->handle ); /* perform access checks */ if ( !info || (info->type != SVC_HANDLE_IS_SCM) ) return WERR_BADFID; if ( !(info->access_granted & SC_RIGHT_MGR_LOCK) ) return WERR_ACCESS_DENIED; /* Just open a handle. Doesn't actually lock anything */ return create_open_service_handle( p, &r_u->h_lock, SVC_HANDLE_IS_DBLOCK, NULL, 0 );;}/****************************************************************************************************************************************/WERROR _svcctl_unlock_service_db( pipes_struct *p, SVCCTL_Q_UNLOCK_SERVICE_DB *q_u, SVCCTL_R_UNLOCK_SERVICE_DB *r_u ){ SERVICE_INFO *info = find_service_info_by_hnd( p, &q_u->h_lock ); if ( !info || (info->type != SVC_HANDLE_IS_DBLOCK) ) return WERR_BADFID; return close_policy_hnd( p, &q_u->h_lock) ? WERR_OK : WERR_BADFID;}/****************************************************************************************************************************************/WERROR _svcctl_query_service_sec( pipes_struct *p, SVCCTL_Q_QUERY_SERVICE_SEC *q_u, SVCCTL_R_QUERY_SERVICE_SEC *r_u ){ SERVICE_INFO *info = find_service_info_by_hnd( p, &q_u->handle ); SEC_DESC *sec_desc; /* only support the SCM and individual services */ if ( !info || !(info->type & (SVC_HANDLE_IS_SERVICE|SVC_HANDLE_IS_SCM)) ) return WERR_BADFID; /* check access reights (according to MSDN) */ if ( !(info->access_granted & STD_RIGHT_READ_CONTROL_ACCESS) ) return WERR_ACCESS_DENIED; /* TODO: handle something besides DACL_SECURITY_INFORMATION */ if ( (q_u->security_flags & DACL_SECURITY_INFORMATION) != DACL_SECURITY_INFORMATION ) return WERR_INVALID_PARAM; /* lookup the security descriptor and marshall it up for a reply */ if ( !(sec_desc = svcctl_get_secdesc( p->mem_ctx, info->name, get_root_nt_token() )) ) return WERR_NOMEM; r_u->needed = sec_desc_size( sec_desc ); if ( r_u->needed > q_u->buffer_size ) { ZERO_STRUCTP( &r_u->buffer ); return WERR_INSUFFICIENT_BUFFER; } rpcbuf_init( &r_u->buffer, q_u->buffer_size, p->mem_ctx ); if ( !sec_io_desc("", &sec_desc, &r_u->buffer.prs, 0 ) ) return WERR_NOMEM; return WERR_OK;}/****************************************************************************************************************************************/WERROR _svcctl_set_service_sec( pipes_struct *p, SVCCTL_Q_SET_SERVICE_SEC *q_u, SVCCTL_R_SET_SERVICE_SEC *r_u ){ SERVICE_INFO *info = find_service_info_by_hnd( p, &q_u->handle ); SEC_DESC *sec_desc = NULL; uint32 required_access; if ( !info || !(info->type & (SVC_HANDLE_IS_SERVICE|SVC_HANDLE_IS_SCM)) ) return WERR_BADFID; /* can't set the security de4scriptor on the ServiceControlManager */ if ( info->type == SVC_HANDLE_IS_SCM ) return WERR_ACCESS_DENIED; /* check the access on the open handle */ switch ( q_u->security_flags ) { case DACL_SECURITY_INFORMATION: required_access = STD_RIGHT_WRITE_DAC_ACCESS; break; case OWNER_SECURITY_INFORMATION: case GROUP_SECURITY_INFORMATION: required_access = STD_RIGHT_WRITE_OWNER_ACCESS; break; case SACL_SECURITY_INFORMATION: return WERR_INVALID_PARAM; default: return WERR_INVALID_PARAM; } if ( !(info->access_granted & required_access) ) return WERR_ACCESS_DENIED; /* read the security descfriptor */ if ( !sec_io_desc("", &sec_desc, &q_u->buffer.prs, 0 ) ) return WERR_NOMEM; /* store the new SD */ if ( !svcctl_set_secdesc( p->mem_ctx, info->name, sec_desc, p->pipe_user.nt_user_token ) ) return WERR_ACCESS_DENIED; return WERR_OK;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -