Samba Shared Repository - branch v3-3-test updated - release-3-2-0pre2-2279-gd077ef6
[Samba.git] / source / utils / net_rpc_service.c
blob1b12bd311485a9dd5e40d4c4020a679d32ef9383
1 /*
2 Samba Unix/Linux SMB client library
3 Distributed SMB/CIFS Server Management Utility
4 Copyright (C) Gerald (Jerry) Carter 2005
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>. */
19 #include "includes.h"
20 #include "utils/net.h"
23 struct svc_state_msg {
24 uint32 flag;
25 const char *message;
28 static struct svc_state_msg state_msg_table[] = {
29 { SVCCTL_STOPPED, "stopped" },
30 { SVCCTL_START_PENDING, "start pending" },
31 { SVCCTL_STOP_PENDING, "stop pending" },
32 { SVCCTL_RUNNING, "running" },
33 { SVCCTL_CONTINUE_PENDING, "resume pending" },
34 { SVCCTL_PAUSE_PENDING, "pause pending" },
35 { SVCCTL_PAUSED, "paused" },
36 { 0, NULL }
40 /********************************************************************
41 ********************************************************************/
42 const char *svc_status_string( uint32 state )
44 fstring msg;
45 int i;
47 fstr_sprintf( msg, "Unknown State [%d]", state );
49 for ( i=0; state_msg_table[i].message; i++ ) {
50 if ( state_msg_table[i].flag == state ) {
51 fstrcpy( msg, state_msg_table[i].message );
52 break;
56 return talloc_strdup(talloc_tos(), msg);
59 /********************************************************************
60 ********************************************************************/
62 static WERROR query_service_state(struct rpc_pipe_client *pipe_hnd,
63 TALLOC_CTX *mem_ctx,
64 POLICY_HND *hSCM,
65 const char *service,
66 uint32 *state )
68 POLICY_HND hService;
69 SERVICE_STATUS service_status;
70 WERROR result = WERR_GENERAL_FAILURE;
71 NTSTATUS status;
73 /* now cycle until the status is actually 'watch_state' */
75 status = rpccli_svcctl_OpenServiceW(pipe_hnd, mem_ctx,
76 hSCM,
77 service,
78 SC_RIGHT_SVC_QUERY_STATUS,
79 &hService,
80 &result);
81 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result) ) {
82 d_fprintf(stderr, "Failed to open service. [%s]\n", dos_errstr(result));
83 return result;
86 status = rpccli_svcctl_QueryServiceStatus(pipe_hnd, mem_ctx,
87 &hService,
88 &service_status,
89 &result);
91 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result) ) {
92 *state = service_status.state;
95 rpccli_svcctl_CloseServiceHandle(pipe_hnd, mem_ctx, &hService, NULL);
97 return result;
100 /********************************************************************
101 ********************************************************************/
103 static WERROR watch_service_state(struct rpc_pipe_client *pipe_hnd,
104 TALLOC_CTX *mem_ctx,
105 POLICY_HND *hSCM,
106 const char *service,
107 uint32 watch_state,
108 uint32 *final_state )
110 uint32 i;
111 uint32 state = 0;
112 WERROR result = WERR_GENERAL_FAILURE;
115 i = 0;
116 while ( (state != watch_state ) && i<30 ) {
117 /* get the status */
119 result = query_service_state(pipe_hnd, mem_ctx, hSCM, service, &state );
120 if ( !W_ERROR_IS_OK(result) ) {
121 break;
124 d_printf(".");
125 i++;
126 sys_usleep( 100 );
128 d_printf("\n");
130 *final_state = state;
132 return result;
135 /********************************************************************
136 ********************************************************************/
138 static WERROR control_service(struct rpc_pipe_client *pipe_hnd,
139 TALLOC_CTX *mem_ctx,
140 POLICY_HND *hSCM,
141 const char *service,
142 uint32 control,
143 uint32 watch_state )
145 POLICY_HND hService;
146 WERROR result = WERR_GENERAL_FAILURE;
147 NTSTATUS status;
148 SERVICE_STATUS service_status;
149 uint32 state = 0;
151 /* Open the Service */
153 status = rpccli_svcctl_OpenServiceW(pipe_hnd, mem_ctx,
154 hSCM,
155 service,
156 (SC_RIGHT_SVC_STOP|SC_RIGHT_SVC_PAUSE_CONTINUE),
157 &hService,
158 &result);
160 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result) ) {
161 d_fprintf(stderr, "Failed to open service. [%s]\n", dos_errstr(result));
162 goto done;
165 /* get the status */
167 status = rpccli_svcctl_ControlService(pipe_hnd, mem_ctx,
168 &hService,
169 control,
170 &service_status,
171 &result);
173 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result) ) {
174 d_fprintf(stderr, "Control service request failed. [%s]\n", dos_errstr(result));
175 goto done;
178 /* loop -- checking the state until we are where we want to be */
180 result = watch_service_state(pipe_hnd, mem_ctx, hSCM, service, watch_state, &state );
182 d_printf("%s service is %s.\n", service, svc_status_string(state));
184 done:
185 rpccli_svcctl_CloseServiceHandle(pipe_hnd, mem_ctx, &hService, NULL);
187 return result;
190 /********************************************************************
191 ********************************************************************/
193 static NTSTATUS rpc_service_list_internal(const DOM_SID *domain_sid,
194 const char *domain_name,
195 struct cli_state *cli,
196 struct rpc_pipe_client *pipe_hnd,
197 TALLOC_CTX *mem_ctx,
198 int argc,
199 const char **argv )
201 POLICY_HND hSCM;
202 ENUM_SERVICES_STATUS *services;
203 WERROR result = WERR_GENERAL_FAILURE;
204 NTSTATUS status;
205 fstring servicename;
206 fstring displayname;
207 uint32 num_services = 0;
208 int i;
210 if (argc != 0 ) {
211 d_printf("Usage: net rpc service list\n");
212 return NT_STATUS_OK;
215 status = rpccli_svcctl_OpenSCManagerW(pipe_hnd, mem_ctx,
216 pipe_hnd->cli->srv_name_slash,
217 NULL,
218 SC_RIGHT_MGR_ENUMERATE_SERVICE,
219 &hSCM,
220 &result);
221 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result)) {
222 d_fprintf(stderr, "Failed to open Service Control Manager. [%s]\n", dos_errstr(result));
223 return werror_to_ntstatus(result);
226 result = rpccli_svcctl_enumerate_services(pipe_hnd, mem_ctx, &hSCM, SVCCTL_TYPE_WIN32,
227 SVCCTL_STATE_ALL, &num_services, &services );
229 if ( !W_ERROR_IS_OK(result) ) {
230 d_fprintf(stderr, "Failed to enumerate services. [%s]\n", dos_errstr(result));
231 goto done;
234 if ( num_services == 0 )
235 d_printf("No services returned\n");
237 for ( i=0; i<num_services; i++ ) {
238 rpcstr_pull( servicename, services[i].servicename.buffer, sizeof(servicename), -1, STR_TERMINATE );
239 rpcstr_pull( displayname, services[i].displayname.buffer, sizeof(displayname), -1, STR_TERMINATE );
241 d_printf("%-20s \"%s\"\n", servicename, displayname);
244 done:
245 rpccli_svcctl_CloseServiceHandle(pipe_hnd, mem_ctx, &hSCM, NULL);
247 return werror_to_ntstatus(result);
250 /********************************************************************
251 ********************************************************************/
253 static NTSTATUS rpc_service_status_internal(const DOM_SID *domain_sid,
254 const char *domain_name,
255 struct cli_state *cli,
256 struct rpc_pipe_client *pipe_hnd,
257 TALLOC_CTX *mem_ctx,
258 int argc,
259 const char **argv )
261 POLICY_HND hSCM, hService;
262 WERROR result = WERR_GENERAL_FAILURE;
263 NTSTATUS status;
264 SERVICE_STATUS service_status;
265 SERVICE_CONFIG config;
266 fstring ascii_string;
268 if (argc != 1 ) {
269 d_printf("Usage: net rpc service status <service>\n");
270 return NT_STATUS_OK;
273 /* Open the Service Control Manager */
274 status = rpccli_svcctl_OpenSCManagerW(pipe_hnd, mem_ctx,
275 pipe_hnd->cli->srv_name_slash,
276 NULL,
277 SC_RIGHT_MGR_ENUMERATE_SERVICE,
278 &hSCM,
279 &result);
280 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result)) {
281 d_fprintf(stderr, "Failed to open Service Control Manager. [%s]\n", dos_errstr(result));
282 return werror_to_ntstatus(result);
285 /* Open the Service */
287 status = rpccli_svcctl_OpenServiceW(pipe_hnd, mem_ctx,
288 &hSCM,
289 argv[0],
290 (SC_RIGHT_SVC_QUERY_STATUS|SC_RIGHT_SVC_QUERY_CONFIG),
291 &hService,
292 &result);
294 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result) ) {
295 d_fprintf(stderr, "Failed to open service. [%s]\n", dos_errstr(result));
296 goto done;
299 /* get the status */
301 status = rpccli_svcctl_QueryServiceStatus(pipe_hnd, mem_ctx,
302 &hService,
303 &service_status,
304 &result);
306 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result) ) {
307 d_fprintf(stderr, "Query status request failed. [%s]\n", dos_errstr(result));
308 goto done;
311 d_printf("%s service is %s.\n", argv[0], svc_status_string(service_status.state));
313 /* get the config */
315 result = rpccli_svcctl_query_config(pipe_hnd, mem_ctx, &hService, &config );
316 if ( !W_ERROR_IS_OK(result) ) {
317 d_fprintf(stderr, "Query config request failed. [%s]\n", dos_errstr(result));
318 goto done;
321 /* print out the configuration information for the service */
323 d_printf("Configuration details:\n");
324 d_printf("\tControls Accepted = 0x%x\n", service_status.controls_accepted);
325 d_printf("\tService Type = 0x%x\n", config.service_type);
326 d_printf("\tStart Type = 0x%x\n", config.start_type);
327 d_printf("\tError Control = 0x%x\n", config.error_control);
328 d_printf("\tTag ID = 0x%x\n", config.tag_id);
330 if ( config.executablepath ) {
331 rpcstr_pull( ascii_string, config.executablepath->buffer, sizeof(ascii_string), -1, STR_TERMINATE );
332 d_printf("\tExecutable Path = %s\n", ascii_string);
335 if ( config.loadordergroup ) {
336 rpcstr_pull( ascii_string, config.loadordergroup->buffer, sizeof(ascii_string), -1, STR_TERMINATE );
337 d_printf("\tLoad Order Group = %s\n", ascii_string);
340 if ( config.dependencies ) {
341 rpcstr_pull( ascii_string, config.dependencies->buffer, sizeof(ascii_string), -1, STR_TERMINATE );
342 d_printf("\tDependencies = %s\n", ascii_string);
345 if ( config.startname ) {
346 rpcstr_pull( ascii_string, config.startname->buffer, sizeof(ascii_string), -1, STR_TERMINATE );
347 d_printf("\tStart Name = %s\n", ascii_string);
350 if ( config.displayname ) {
351 rpcstr_pull( ascii_string, config.displayname->buffer, sizeof(ascii_string), -1, STR_TERMINATE );
352 d_printf("\tDisplay Name = %s\n", ascii_string);
355 done:
356 rpccli_svcctl_CloseServiceHandle(pipe_hnd, mem_ctx, &hService, NULL);
357 rpccli_svcctl_CloseServiceHandle(pipe_hnd, mem_ctx, &hSCM, NULL);
359 return werror_to_ntstatus(result);
362 /********************************************************************
363 ********************************************************************/
365 static NTSTATUS rpc_service_stop_internal(const DOM_SID *domain_sid,
366 const char *domain_name,
367 struct cli_state *cli,
368 struct rpc_pipe_client *pipe_hnd,
369 TALLOC_CTX *mem_ctx,
370 int argc,
371 const char **argv )
373 POLICY_HND hSCM;
374 WERROR result = WERR_GENERAL_FAILURE;
375 NTSTATUS status;
376 fstring servicename;
378 if (argc != 1 ) {
379 d_printf("Usage: net rpc service status <service>\n");
380 return NT_STATUS_OK;
383 fstrcpy( servicename, argv[0] );
385 /* Open the Service Control Manager */
386 status = rpccli_svcctl_OpenSCManagerW(pipe_hnd, mem_ctx,
387 pipe_hnd->cli->srv_name_slash,
388 NULL,
389 SC_RIGHT_MGR_ENUMERATE_SERVICE,
390 &hSCM,
391 &result);
392 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result)) {
393 d_fprintf(stderr, "Failed to open Service Control Manager. [%s]\n", dos_errstr(result));
394 return werror_to_ntstatus(result);
397 result = control_service(pipe_hnd, mem_ctx, &hSCM, servicename,
398 SVCCTL_CONTROL_STOP, SVCCTL_STOPPED );
400 rpccli_svcctl_CloseServiceHandle(pipe_hnd, mem_ctx, &hSCM, NULL);
402 return werror_to_ntstatus(result);
405 /********************************************************************
406 ********************************************************************/
408 static NTSTATUS rpc_service_pause_internal(const DOM_SID *domain_sid,
409 const char *domain_name,
410 struct cli_state *cli,
411 struct rpc_pipe_client *pipe_hnd,
412 TALLOC_CTX *mem_ctx,
413 int argc,
414 const char **argv )
416 POLICY_HND hSCM;
417 WERROR result = WERR_GENERAL_FAILURE;
418 NTSTATUS status;
419 fstring servicename;
421 if (argc != 1 ) {
422 d_printf("Usage: net rpc service status <service>\n");
423 return NT_STATUS_OK;
426 fstrcpy( servicename, argv[0] );
428 /* Open the Service Control Manager */
429 status = rpccli_svcctl_OpenSCManagerW(pipe_hnd, mem_ctx,
430 pipe_hnd->cli->srv_name_slash,
431 NULL,
432 SC_RIGHT_MGR_ENUMERATE_SERVICE,
433 &hSCM,
434 &result);
435 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result)) {
436 d_fprintf(stderr, "Failed to open Service Control Manager. [%s]\n", dos_errstr(result));
437 return werror_to_ntstatus(result);
440 result = control_service(pipe_hnd, mem_ctx, &hSCM, servicename,
441 SVCCTL_CONTROL_PAUSE, SVCCTL_PAUSED );
443 rpccli_svcctl_CloseServiceHandle(pipe_hnd, mem_ctx, &hSCM, NULL);
445 return werror_to_ntstatus(result);
448 /********************************************************************
449 ********************************************************************/
451 static NTSTATUS rpc_service_resume_internal(const DOM_SID *domain_sid,
452 const char *domain_name,
453 struct cli_state *cli,
454 struct rpc_pipe_client *pipe_hnd,
455 TALLOC_CTX *mem_ctx,
456 int argc,
457 const char **argv )
459 POLICY_HND hSCM;
460 WERROR result = WERR_GENERAL_FAILURE;
461 NTSTATUS status;
462 fstring servicename;
464 if (argc != 1 ) {
465 d_printf("Usage: net rpc service status <service>\n");
466 return NT_STATUS_OK;
469 fstrcpy( servicename, argv[0] );
471 /* Open the Service Control Manager */
472 status = rpccli_svcctl_OpenSCManagerW(pipe_hnd, mem_ctx,
473 pipe_hnd->cli->srv_name_slash,
474 NULL,
475 SC_RIGHT_MGR_ENUMERATE_SERVICE,
476 &hSCM,
477 &result);
478 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result)) {
479 d_fprintf(stderr, "Failed to open Service Control Manager. [%s]\n", dos_errstr(result));
480 return werror_to_ntstatus(result);
483 result = control_service(pipe_hnd, mem_ctx, &hSCM, servicename,
484 SVCCTL_CONTROL_CONTINUE, SVCCTL_RUNNING );
486 rpccli_svcctl_CloseServiceHandle(pipe_hnd, mem_ctx, &hSCM, NULL);
488 return werror_to_ntstatus(result);
491 /********************************************************************
492 ********************************************************************/
494 static NTSTATUS rpc_service_start_internal(const DOM_SID *domain_sid,
495 const char *domain_name,
496 struct cli_state *cli,
497 struct rpc_pipe_client *pipe_hnd,
498 TALLOC_CTX *mem_ctx,
499 int argc,
500 const char **argv )
502 POLICY_HND hSCM, hService;
503 WERROR result = WERR_GENERAL_FAILURE;
504 NTSTATUS status;
505 uint32 state = 0;
507 if (argc != 1 ) {
508 d_printf("Usage: net rpc service status <service>\n");
509 return NT_STATUS_OK;
512 /* Open the Service Control Manager */
513 status = rpccli_svcctl_OpenSCManagerW(pipe_hnd, mem_ctx,
514 pipe_hnd->cli->srv_name_slash,
515 NULL,
516 SC_RIGHT_MGR_ENUMERATE_SERVICE,
517 &hSCM,
518 &result);
519 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result)) {
520 d_fprintf(stderr, "Failed to open Service Control Manager. [%s]\n", dos_errstr(result));
521 return werror_to_ntstatus(result);
524 /* Open the Service */
526 status = rpccli_svcctl_OpenServiceW(pipe_hnd, mem_ctx,
527 &hSCM,
528 argv[0],
529 SC_RIGHT_SVC_START,
530 &hService,
531 &result);
533 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result) ) {
534 d_fprintf(stderr, "Failed to open service. [%s]\n", dos_errstr(result));
535 goto done;
538 /* get the status */
540 status = rpccli_svcctl_StartServiceW(pipe_hnd, mem_ctx,
541 &hService,
543 NULL,
544 &result);
546 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result) ) {
547 d_fprintf(stderr, "Query status request failed. [%s]\n", dos_errstr(result));
548 goto done;
551 result = watch_service_state(pipe_hnd, mem_ctx, &hSCM, argv[0], SVCCTL_RUNNING, &state );
553 if ( W_ERROR_IS_OK(result) && (state == SVCCTL_RUNNING) )
554 d_printf("Successfully started service: %s\n", argv[0] );
555 else
556 d_fprintf(stderr, "Failed to start service: %s [%s]\n", argv[0], dos_errstr(result) );
558 done:
559 rpccli_svcctl_CloseServiceHandle(pipe_hnd, mem_ctx, &hService, NULL);
560 rpccli_svcctl_CloseServiceHandle(pipe_hnd, mem_ctx, &hSCM, NULL);
562 return werror_to_ntstatus(result);
565 /********************************************************************
566 ********************************************************************/
568 static int rpc_service_list( int argc, const char **argv )
570 return run_rpc_command( NULL, PI_SVCCTL, 0,
571 rpc_service_list_internal, argc, argv );
574 /********************************************************************
575 ********************************************************************/
577 static int rpc_service_start( int argc, const char **argv )
579 return run_rpc_command( NULL, PI_SVCCTL, 0,
580 rpc_service_start_internal, argc, argv );
583 /********************************************************************
584 ********************************************************************/
586 static int rpc_service_stop( int argc, const char **argv )
588 return run_rpc_command( NULL, PI_SVCCTL, 0,
589 rpc_service_stop_internal, argc, argv );
592 /********************************************************************
593 ********************************************************************/
595 static int rpc_service_resume( int argc, const char **argv )
597 return run_rpc_command( NULL, PI_SVCCTL, 0,
598 rpc_service_resume_internal, argc, argv );
601 /********************************************************************
602 ********************************************************************/
604 static int rpc_service_pause( int argc, const char **argv )
606 return run_rpc_command( NULL, PI_SVCCTL, 0,
607 rpc_service_pause_internal, argc, argv );
610 /********************************************************************
611 ********************************************************************/
613 static int rpc_service_status( int argc, const char **argv )
615 return run_rpc_command( NULL, PI_SVCCTL, 0,
616 rpc_service_status_internal, argc, argv );
619 /********************************************************************
620 ********************************************************************/
622 static int net_help_service( int argc, const char **argv )
624 d_printf("net rpc service list View configured Win32 services\n");
625 d_printf("net rpc service start <service> Start a service\n");
626 d_printf("net rpc service stop <service> Stop a service\n");
627 d_printf("net rpc service pause <service> Pause a service\n");
628 d_printf("net rpc service resume <service> Resume a paused service\n");
629 d_printf("net rpc service status <service> View the current status of a service\n");
631 return -1;
634 /********************************************************************
635 ********************************************************************/
637 int net_rpc_service(int argc, const char **argv)
639 struct functable func[] = {
640 {"list", rpc_service_list},
641 {"start", rpc_service_start},
642 {"stop", rpc_service_stop},
643 {"pause", rpc_service_pause},
644 {"resume", rpc_service_resume},
645 {"status", rpc_service_status},
646 {NULL, NULL}
649 if ( argc )
650 return net_run_function( argc, argv, func, net_help_service );
652 return net_help_service( argc, argv );