00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "includes.h"
00021 #include "utils/net.h"
00022
00023
00024
00025
00026
00027 static WERROR query_service_state(struct rpc_pipe_client *pipe_hnd,
00028 TALLOC_CTX *mem_ctx,
00029 POLICY_HND *hSCM,
00030 const char *service,
00031 uint32 *state )
00032 {
00033 POLICY_HND hService;
00034 SERVICE_STATUS service_status;
00035 WERROR result = WERR_GENERAL_FAILURE;
00036
00037
00038
00039 result = rpccli_svcctl_open_service(pipe_hnd, mem_ctx, hSCM, &hService,
00040 service, SC_RIGHT_SVC_QUERY_STATUS );
00041
00042 if ( !W_ERROR_IS_OK(result) ) {
00043 d_fprintf(stderr, "Failed to open service. [%s]\n", dos_errstr(result));
00044 return result;
00045 }
00046
00047 result = rpccli_svcctl_query_status(pipe_hnd, mem_ctx, &hService, &service_status );
00048 if ( W_ERROR_IS_OK(result) ) {
00049 *state = service_status.state;
00050 }
00051
00052 rpccli_svcctl_close_service(pipe_hnd, mem_ctx, &hService );
00053
00054 return result;
00055 }
00056
00057
00058
00059
00060 static WERROR watch_service_state(struct rpc_pipe_client *pipe_hnd,
00061 TALLOC_CTX *mem_ctx,
00062 POLICY_HND *hSCM,
00063 const char *service,
00064 uint32 watch_state,
00065 uint32 *final_state )
00066 {
00067 uint32 i;
00068 uint32 state = 0;
00069 WERROR result = WERR_GENERAL_FAILURE;
00070
00071
00072 i = 0;
00073 while ( (state != watch_state ) && i<30 ) {
00074
00075
00076 result = query_service_state(pipe_hnd, mem_ctx, hSCM, service, &state );
00077 if ( !W_ERROR_IS_OK(result) ) {
00078 break;
00079 }
00080
00081 d_printf(".");
00082 i++;
00083 sys_usleep( 100 );
00084 }
00085 d_printf("\n");
00086
00087 *final_state = state;
00088
00089 return result;
00090 }
00091
00092
00093
00094
00095 static WERROR control_service(struct rpc_pipe_client *pipe_hnd,
00096 TALLOC_CTX *mem_ctx,
00097 POLICY_HND *hSCM,
00098 const char *service,
00099 uint32 control,
00100 uint32 watch_state )
00101 {
00102 POLICY_HND hService;
00103 WERROR result = WERR_GENERAL_FAILURE;
00104 SERVICE_STATUS service_status;
00105 uint32 state = 0;
00106
00107
00108
00109 result = rpccli_svcctl_open_service(pipe_hnd, mem_ctx, hSCM, &hService,
00110 service, (SC_RIGHT_SVC_STOP|SC_RIGHT_SVC_PAUSE_CONTINUE) );
00111
00112 if ( !W_ERROR_IS_OK(result) ) {
00113 d_fprintf(stderr, "Failed to open service. [%s]\n", dos_errstr(result));
00114 goto done;
00115 }
00116
00117
00118
00119 result = rpccli_svcctl_control_service(pipe_hnd, mem_ctx, &hService,
00120 control, &service_status );
00121
00122 if ( !W_ERROR_IS_OK(result) ) {
00123 d_fprintf(stderr, "Control service request failed. [%s]\n", dos_errstr(result));
00124 goto done;
00125 }
00126
00127
00128
00129 result = watch_service_state(pipe_hnd, mem_ctx, hSCM, service, watch_state, &state );
00130
00131 d_printf("%s service is %s.\n", service, svc_status_string(state));
00132
00133 done:
00134 rpccli_svcctl_close_service(pipe_hnd, mem_ctx, &hService );
00135
00136 return result;
00137 }
00138
00139
00140
00141
00142 static NTSTATUS rpc_service_list_internal(const DOM_SID *domain_sid,
00143 const char *domain_name,
00144 struct cli_state *cli,
00145 struct rpc_pipe_client *pipe_hnd,
00146 TALLOC_CTX *mem_ctx,
00147 int argc,
00148 const char **argv )
00149 {
00150 POLICY_HND hSCM;
00151 ENUM_SERVICES_STATUS *services;
00152 WERROR result = WERR_GENERAL_FAILURE;
00153 fstring servicename;
00154 fstring displayname;
00155 uint32 num_services = 0;
00156 int i;
00157
00158 if (argc != 0 ) {
00159 d_printf("Usage: net rpc service list\n");
00160 return NT_STATUS_OK;
00161 }
00162
00163 result = rpccli_svcctl_open_scm(pipe_hnd, mem_ctx, &hSCM, SC_RIGHT_MGR_ENUMERATE_SERVICE );
00164 if ( !W_ERROR_IS_OK(result) ) {
00165 d_fprintf(stderr, "Failed to open Service Control Manager. [%s]\n", dos_errstr(result));
00166 return werror_to_ntstatus(result);
00167 }
00168
00169 result = rpccli_svcctl_enumerate_services(pipe_hnd, mem_ctx, &hSCM, SVCCTL_TYPE_WIN32,
00170 SVCCTL_STATE_ALL, &num_services, &services );
00171
00172 if ( !W_ERROR_IS_OK(result) ) {
00173 d_fprintf(stderr, "Failed to enumerate services. [%s]\n", dos_errstr(result));
00174 goto done;
00175 }
00176
00177 if ( num_services == 0 )
00178 d_printf("No services returned\n");
00179
00180 for ( i=0; i<num_services; i++ ) {
00181 rpcstr_pull( servicename, services[i].servicename.buffer, sizeof(servicename), -1, STR_TERMINATE );
00182 rpcstr_pull( displayname, services[i].displayname.buffer, sizeof(displayname), -1, STR_TERMINATE );
00183
00184 d_printf("%-20s \"%s\"\n", servicename, displayname);
00185 }
00186
00187 done:
00188 rpccli_svcctl_close_service(pipe_hnd, mem_ctx, &hSCM );
00189
00190 return werror_to_ntstatus(result);
00191 }
00192
00193
00194
00195
00196 static NTSTATUS rpc_service_status_internal(const DOM_SID *domain_sid,
00197 const char *domain_name,
00198 struct cli_state *cli,
00199 struct rpc_pipe_client *pipe_hnd,
00200 TALLOC_CTX *mem_ctx,
00201 int argc,
00202 const char **argv )
00203 {
00204 POLICY_HND hSCM, hService;
00205 WERROR result = WERR_GENERAL_FAILURE;
00206 fstring servicename;
00207 SERVICE_STATUS service_status;
00208 SERVICE_CONFIG config;
00209 fstring ascii_string;
00210
00211 if (argc != 1 ) {
00212 d_printf("Usage: net rpc service status <service>\n");
00213 return NT_STATUS_OK;
00214 }
00215
00216 fstrcpy( servicename, argv[0] );
00217
00218
00219
00220 result = rpccli_svcctl_open_scm(pipe_hnd, mem_ctx, &hSCM, SC_RIGHT_MGR_ENUMERATE_SERVICE );
00221 if ( !W_ERROR_IS_OK(result) ) {
00222 d_fprintf(stderr, "Failed to open Service Control Manager. [%s]\n", dos_errstr(result));
00223 return werror_to_ntstatus(result);
00224 }
00225
00226
00227
00228 result = rpccli_svcctl_open_service(pipe_hnd, mem_ctx, &hSCM, &hService, servicename,
00229 (SC_RIGHT_SVC_QUERY_STATUS|SC_RIGHT_SVC_QUERY_CONFIG) );
00230
00231 if ( !W_ERROR_IS_OK(result) ) {
00232 d_fprintf(stderr, "Failed to open service. [%s]\n", dos_errstr(result));
00233 goto done;
00234 }
00235
00236
00237
00238 result = rpccli_svcctl_query_status(pipe_hnd, mem_ctx, &hService, &service_status );
00239 if ( !W_ERROR_IS_OK(result) ) {
00240 d_fprintf(stderr, "Query status request failed. [%s]\n", dos_errstr(result));
00241 goto done;
00242 }
00243
00244 d_printf("%s service is %s.\n", servicename, svc_status_string(service_status.state));
00245
00246
00247
00248 result = rpccli_svcctl_query_config(pipe_hnd, mem_ctx, &hService, &config );
00249 if ( !W_ERROR_IS_OK(result) ) {
00250 d_fprintf(stderr, "Query config request failed. [%s]\n", dos_errstr(result));
00251 goto done;
00252 }
00253
00254
00255
00256 d_printf("Configuration details:\n");
00257 d_printf("\tControls Accepted = 0x%x\n", service_status.controls_accepted);
00258 d_printf("\tService Type = 0x%x\n", config.service_type);
00259 d_printf("\tStart Type = 0x%x\n", config.start_type);
00260 d_printf("\tError Control = 0x%x\n", config.error_control);
00261 d_printf("\tTag ID = 0x%x\n", config.tag_id);
00262
00263 if ( config.executablepath ) {
00264 rpcstr_pull( ascii_string, config.executablepath->buffer, sizeof(ascii_string), -1, STR_TERMINATE );
00265 d_printf("\tExecutable Path = %s\n", ascii_string);
00266 }
00267
00268 if ( config.loadordergroup ) {
00269 rpcstr_pull( ascii_string, config.loadordergroup->buffer, sizeof(ascii_string), -1, STR_TERMINATE );
00270 d_printf("\tLoad Order Group = %s\n", ascii_string);
00271 }
00272
00273 if ( config.dependencies ) {
00274 rpcstr_pull( ascii_string, config.dependencies->buffer, sizeof(ascii_string), -1, STR_TERMINATE );
00275 d_printf("\tDependencies = %s\n", ascii_string);
00276 }
00277
00278 if ( config.startname ) {
00279 rpcstr_pull( ascii_string, config.startname->buffer, sizeof(ascii_string), -1, STR_TERMINATE );
00280 d_printf("\tStart Name = %s\n", ascii_string);
00281 }
00282
00283 if ( config.displayname ) {
00284 rpcstr_pull( ascii_string, config.displayname->buffer, sizeof(ascii_string), -1, STR_TERMINATE );
00285 d_printf("\tDisplay Name = %s\n", ascii_string);
00286 }
00287
00288 done:
00289 rpccli_svcctl_close_service(pipe_hnd, mem_ctx, &hService );
00290 rpccli_svcctl_close_service(pipe_hnd, mem_ctx, &hSCM );
00291
00292 return werror_to_ntstatus(result);
00293 }
00294
00295
00296
00297
00298 static NTSTATUS rpc_service_stop_internal(const DOM_SID *domain_sid,
00299 const char *domain_name,
00300 struct cli_state *cli,
00301 struct rpc_pipe_client *pipe_hnd,
00302 TALLOC_CTX *mem_ctx,
00303 int argc,
00304 const char **argv )
00305 {
00306 POLICY_HND hSCM;
00307 WERROR result = WERR_GENERAL_FAILURE;
00308 fstring servicename;
00309
00310 if (argc != 1 ) {
00311 d_printf("Usage: net rpc service status <service>\n");
00312 return NT_STATUS_OK;
00313 }
00314
00315 fstrcpy( servicename, argv[0] );
00316
00317
00318
00319 result = rpccli_svcctl_open_scm(pipe_hnd, mem_ctx, &hSCM, SC_RIGHT_MGR_ENUMERATE_SERVICE );
00320 if ( !W_ERROR_IS_OK(result) ) {
00321 d_fprintf(stderr, "Failed to open Service Control Manager. [%s]\n", dos_errstr(result));
00322 return werror_to_ntstatus(result);
00323 }
00324
00325 result = control_service(pipe_hnd, mem_ctx, &hSCM, servicename,
00326 SVCCTL_CONTROL_STOP, SVCCTL_STOPPED );
00327
00328 rpccli_svcctl_close_service(pipe_hnd, mem_ctx, &hSCM );
00329
00330 return werror_to_ntstatus(result);
00331 }
00332
00333
00334
00335
00336 static NTSTATUS rpc_service_pause_internal(const DOM_SID *domain_sid,
00337 const char *domain_name,
00338 struct cli_state *cli,
00339 struct rpc_pipe_client *pipe_hnd,
00340 TALLOC_CTX *mem_ctx,
00341 int argc,
00342 const char **argv )
00343 {
00344 POLICY_HND hSCM;
00345 WERROR result = WERR_GENERAL_FAILURE;
00346 fstring servicename;
00347
00348 if (argc != 1 ) {
00349 d_printf("Usage: net rpc service status <service>\n");
00350 return NT_STATUS_OK;
00351 }
00352
00353 fstrcpy( servicename, argv[0] );
00354
00355
00356
00357 result = rpccli_svcctl_open_scm(pipe_hnd, mem_ctx, &hSCM, SC_RIGHT_MGR_ENUMERATE_SERVICE );
00358 if ( !W_ERROR_IS_OK(result) ) {
00359 d_fprintf(stderr, "Failed to open Service Control Manager. [%s]\n", dos_errstr(result));
00360 return werror_to_ntstatus(result);
00361 }
00362
00363 result = control_service(pipe_hnd, mem_ctx, &hSCM, servicename,
00364 SVCCTL_CONTROL_PAUSE, SVCCTL_PAUSED );
00365
00366 rpccli_svcctl_close_service(pipe_hnd, mem_ctx, &hSCM );
00367
00368 return werror_to_ntstatus(result);
00369 }
00370
00371
00372
00373
00374 static NTSTATUS rpc_service_resume_internal(const DOM_SID *domain_sid,
00375 const char *domain_name,
00376 struct cli_state *cli,
00377 struct rpc_pipe_client *pipe_hnd,
00378 TALLOC_CTX *mem_ctx,
00379 int argc,
00380 const char **argv )
00381 {
00382 POLICY_HND hSCM;
00383 WERROR result = WERR_GENERAL_FAILURE;
00384 fstring servicename;
00385
00386 if (argc != 1 ) {
00387 d_printf("Usage: net rpc service status <service>\n");
00388 return NT_STATUS_OK;
00389 }
00390
00391 fstrcpy( servicename, argv[0] );
00392
00393
00394
00395 result = rpccli_svcctl_open_scm(pipe_hnd, mem_ctx, &hSCM, SC_RIGHT_MGR_ENUMERATE_SERVICE );
00396 if ( !W_ERROR_IS_OK(result) ) {
00397 d_fprintf(stderr, "Failed to open Service Control Manager. [%s]\n", dos_errstr(result));
00398 return werror_to_ntstatus(result);
00399 }
00400
00401 result = control_service(pipe_hnd, mem_ctx, &hSCM, servicename,
00402 SVCCTL_CONTROL_CONTINUE, SVCCTL_RUNNING );
00403
00404 rpccli_svcctl_close_service(pipe_hnd, mem_ctx, &hSCM );
00405
00406 return werror_to_ntstatus(result);
00407 }
00408
00409
00410
00411
00412 static NTSTATUS rpc_service_start_internal(const DOM_SID *domain_sid,
00413 const char *domain_name,
00414 struct cli_state *cli,
00415 struct rpc_pipe_client *pipe_hnd,
00416 TALLOC_CTX *mem_ctx,
00417 int argc,
00418 const char **argv )
00419 {
00420 POLICY_HND hSCM, hService;
00421 WERROR result = WERR_GENERAL_FAILURE;
00422 fstring servicename;
00423 uint32 state = 0;
00424
00425 if (argc != 1 ) {
00426 d_printf("Usage: net rpc service status <service>\n");
00427 return NT_STATUS_OK;
00428 }
00429
00430 fstrcpy( servicename, argv[0] );
00431
00432
00433
00434 result = rpccli_svcctl_open_scm( pipe_hnd, mem_ctx, &hSCM, SC_RIGHT_MGR_ENUMERATE_SERVICE );
00435 if ( !W_ERROR_IS_OK(result) ) {
00436 d_fprintf(stderr, "Failed to open Service Control Manager. [%s]\n", dos_errstr(result));
00437 return werror_to_ntstatus(result);
00438 }
00439
00440
00441
00442 result = rpccli_svcctl_open_service(pipe_hnd, mem_ctx, &hSCM, &hService,
00443 servicename, SC_RIGHT_SVC_START );
00444
00445 if ( !W_ERROR_IS_OK(result) ) {
00446 d_fprintf(stderr, "Failed to open service. [%s]\n", dos_errstr(result));
00447 goto done;
00448 }
00449
00450
00451
00452 result = rpccli_svcctl_start_service(pipe_hnd, mem_ctx, &hService, NULL, 0 );
00453 if ( !W_ERROR_IS_OK(result) ) {
00454 d_fprintf(stderr, "Query status request failed. [%s]\n", dos_errstr(result));
00455 goto done;
00456 }
00457
00458 result = watch_service_state(pipe_hnd, mem_ctx, &hSCM, servicename, SVCCTL_RUNNING, &state );
00459
00460 if ( W_ERROR_IS_OK(result) && (state == SVCCTL_RUNNING) )
00461 d_printf("Successfully started service: %s\n", servicename );
00462 else
00463 d_fprintf(stderr, "Failed to start service: %s [%s]\n", servicename, dos_errstr(result) );
00464
00465 done:
00466 rpccli_svcctl_close_service(pipe_hnd, mem_ctx, &hService );
00467 rpccli_svcctl_close_service(pipe_hnd, mem_ctx, &hSCM );
00468
00469 return werror_to_ntstatus(result);
00470 }
00471
00472
00473
00474
00475 static int rpc_service_list( int argc, const char **argv )
00476 {
00477 return run_rpc_command( NULL, PI_SVCCTL, 0,
00478 rpc_service_list_internal, argc, argv );
00479 }
00480
00481
00482
00483
00484 static int rpc_service_start( int argc, const char **argv )
00485 {
00486 return run_rpc_command( NULL, PI_SVCCTL, 0,
00487 rpc_service_start_internal, argc, argv );
00488 }
00489
00490
00491
00492
00493 static int rpc_service_stop( int argc, const char **argv )
00494 {
00495 return run_rpc_command( NULL, PI_SVCCTL, 0,
00496 rpc_service_stop_internal, argc, argv );
00497 }
00498
00499
00500
00501
00502 static int rpc_service_resume( int argc, const char **argv )
00503 {
00504 return run_rpc_command( NULL, PI_SVCCTL, 0,
00505 rpc_service_resume_internal, argc, argv );
00506 }
00507
00508
00509
00510
00511 static int rpc_service_pause( int argc, const char **argv )
00512 {
00513 return run_rpc_command( NULL, PI_SVCCTL, 0,
00514 rpc_service_pause_internal, argc, argv );
00515 }
00516
00517
00518
00519
00520 static int rpc_service_status( int argc, const char **argv )
00521 {
00522 return run_rpc_command( NULL, PI_SVCCTL, 0,
00523 rpc_service_status_internal, argc, argv );
00524 }
00525
00526
00527
00528
00529 static int net_help_service( int argc, const char **argv )
00530 {
00531 d_printf("net rpc service list View configured Win32 services\n");
00532 d_printf("net rpc service start <service> Start a service\n");
00533 d_printf("net rpc service stop <service> Stop a service\n");
00534 d_printf("net rpc service pause <service> Pause a service\n");
00535 d_printf("net rpc service resume <service> Resume a paused service\n");
00536 d_printf("net rpc service status <service> View the current status of a service\n");
00537
00538 return -1;
00539 }
00540
00541
00542
00543
00544 int net_rpc_service(int argc, const char **argv)
00545 {
00546 struct functable func[] = {
00547 {"list", rpc_service_list},
00548 {"start", rpc_service_start},
00549 {"stop", rpc_service_stop},
00550 {"pause", rpc_service_pause},
00551 {"resume", rpc_service_resume},
00552 {"status", rpc_service_status},
00553 {NULL, NULL}
00554 };
00555
00556 if ( argc )
00557 return net_run_function( argc, argv, func, net_help_service );
00558
00559 return net_help_service( argc, argv );
00560 }