r17915: Saturn fixes
[Samba/gbeck.git] / source / utils / net_rpc_service.c
blob27127a1c3f9f9caa82ae6646bca4fd004d88ae02
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 2 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, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
20 #include "includes.h"
21 #include "utils/net.h"
24 /********************************************************************
25 ********************************************************************/
27 static WERROR query_service_state(struct rpc_pipe_client *pipe_hnd,
28 TALLOC_CTX *mem_ctx,
29 POLICY_HND *hSCM,
30 const char *service,
31 uint32 *state )
33 POLICY_HND hService;
34 SERVICE_STATUS service_status;
35 WERROR result = WERR_GENERAL_FAILURE;
37 /* now cycle until the status is actually 'watch_state' */
39 result = rpccli_svcctl_open_service(pipe_hnd, mem_ctx, hSCM, &hService,
40 service, SC_RIGHT_SVC_QUERY_STATUS );
42 if ( !W_ERROR_IS_OK(result) ) {
43 d_fprintf(stderr, "Failed to open service. [%s]\n", dos_errstr(result));
44 return result;
47 result = rpccli_svcctl_query_status(pipe_hnd, mem_ctx, &hService, &service_status );
48 if ( W_ERROR_IS_OK(result) ) {
49 *state = service_status.state;
52 rpccli_svcctl_close_service(pipe_hnd, mem_ctx, &hService );
54 return result;
57 /********************************************************************
58 ********************************************************************/
60 static WERROR watch_service_state(struct rpc_pipe_client *pipe_hnd,
61 TALLOC_CTX *mem_ctx,
62 POLICY_HND *hSCM,
63 const char *service,
64 uint32 watch_state,
65 uint32 *final_state )
67 uint32 i;
68 uint32 state = 0;
69 WERROR result = WERR_GENERAL_FAILURE;
72 i = 0;
73 while ( (state != watch_state ) && i<30 ) {
74 /* get the status */
76 result = query_service_state(pipe_hnd, mem_ctx, hSCM, service, &state );
77 if ( !W_ERROR_IS_OK(result) ) {
78 break;
81 d_printf(".");
82 i++;
83 usleep( 100 );
85 d_printf("\n");
87 *final_state = state;
89 return result;
92 /********************************************************************
93 ********************************************************************/
95 static WERROR control_service(struct rpc_pipe_client *pipe_hnd,
96 TALLOC_CTX *mem_ctx,
97 POLICY_HND *hSCM,
98 const char *service,
99 uint32 control,
100 uint32 watch_state )
102 POLICY_HND hService;
103 WERROR result = WERR_GENERAL_FAILURE;
104 SERVICE_STATUS service_status;
105 uint32 state = 0;
107 /* Open the Service */
109 result = rpccli_svcctl_open_service(pipe_hnd, mem_ctx, hSCM, &hService,
110 service, (SC_RIGHT_SVC_STOP|SC_RIGHT_SVC_PAUSE_CONTINUE) );
112 if ( !W_ERROR_IS_OK(result) ) {
113 d_fprintf(stderr, "Failed to open service. [%s]\n", dos_errstr(result));
114 goto done;
117 /* get the status */
119 result = rpccli_svcctl_control_service(pipe_hnd, mem_ctx, &hService,
120 control, &service_status );
122 if ( !W_ERROR_IS_OK(result) ) {
123 d_fprintf(stderr, "Control service request failed. [%s]\n", dos_errstr(result));
124 goto done;
127 /* loop -- checking the state until we are where we want to be */
129 result = watch_service_state(pipe_hnd, mem_ctx, hSCM, service, watch_state, &state );
131 d_printf("%s service is %s.\n", service, svc_status_string(state));
133 done:
134 rpccli_svcctl_close_service(pipe_hnd, mem_ctx, &hService );
136 return result;
139 /********************************************************************
140 ********************************************************************/
142 static NTSTATUS rpc_service_list_internal(const DOM_SID *domain_sid,
143 const char *domain_name,
144 struct cli_state *cli,
145 struct rpc_pipe_client *pipe_hnd,
146 TALLOC_CTX *mem_ctx,
147 int argc,
148 const char **argv )
150 POLICY_HND hSCM;
151 ENUM_SERVICES_STATUS *services;
152 WERROR result = WERR_GENERAL_FAILURE;
153 fstring servicename;
154 fstring displayname;
155 uint32 num_services = 0;
156 int i;
158 if (argc != 0 ) {
159 d_printf("Usage: net rpc service list\n");
160 return NT_STATUS_OK;
163 result = rpccli_svcctl_open_scm(pipe_hnd, mem_ctx, &hSCM, SC_RIGHT_MGR_ENUMERATE_SERVICE );
164 if ( !W_ERROR_IS_OK(result) ) {
165 d_fprintf(stderr, "Failed to open Service Control Manager. [%s]\n", dos_errstr(result));
166 return werror_to_ntstatus(result);
169 result = rpccli_svcctl_enumerate_services(pipe_hnd, mem_ctx, &hSCM, SVCCTL_TYPE_WIN32,
170 SVCCTL_STATE_ALL, &num_services, &services );
172 if ( !W_ERROR_IS_OK(result) ) {
173 d_fprintf(stderr, "Failed to enumerate services. [%s]\n", dos_errstr(result));
174 goto done;
177 if ( num_services == 0 )
178 d_printf("No services returned\n");
180 for ( i=0; i<num_services; i++ ) {
181 rpcstr_pull( servicename, services[i].servicename.buffer, sizeof(servicename), -1, STR_TERMINATE );
182 rpcstr_pull( displayname, services[i].displayname.buffer, sizeof(displayname), -1, STR_TERMINATE );
184 d_printf("%-20s \"%s\"\n", servicename, displayname);
187 done:
188 rpccli_svcctl_close_service(pipe_hnd, mem_ctx, &hSCM );
190 return werror_to_ntstatus(result);
193 /********************************************************************
194 ********************************************************************/
196 static NTSTATUS rpc_service_status_internal(const DOM_SID *domain_sid,
197 const char *domain_name,
198 struct cli_state *cli,
199 struct rpc_pipe_client *pipe_hnd,
200 TALLOC_CTX *mem_ctx,
201 int argc,
202 const char **argv )
204 POLICY_HND hSCM, hService;
205 WERROR result = WERR_GENERAL_FAILURE;
206 fstring servicename;
207 SERVICE_STATUS service_status;
208 SERVICE_CONFIG config;
209 fstring ascii_string;
211 if (argc != 1 ) {
212 d_printf("Usage: net rpc service status <service>\n");
213 return NT_STATUS_OK;
216 fstrcpy( servicename, argv[0] );
218 /* Open the Service Control Manager */
220 result = rpccli_svcctl_open_scm(pipe_hnd, mem_ctx, &hSCM, SC_RIGHT_MGR_ENUMERATE_SERVICE );
221 if ( !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 /* Open the Service */
228 result = rpccli_svcctl_open_service(pipe_hnd, mem_ctx, &hSCM, &hService, servicename,
229 (SC_RIGHT_SVC_QUERY_STATUS|SC_RIGHT_SVC_QUERY_CONFIG) );
231 if ( !W_ERROR_IS_OK(result) ) {
232 d_fprintf(stderr, "Failed to open service. [%s]\n", dos_errstr(result));
233 goto done;
236 /* get the status */
238 result = rpccli_svcctl_query_status(pipe_hnd, mem_ctx, &hService, &service_status );
239 if ( !W_ERROR_IS_OK(result) ) {
240 d_fprintf(stderr, "Query status request failed. [%s]\n", dos_errstr(result));
241 goto done;
244 d_printf("%s service is %s.\n", servicename, svc_status_string(service_status.state));
246 /* get the config */
248 result = rpccli_svcctl_query_config(pipe_hnd, mem_ctx, &hService, &config );
249 if ( !W_ERROR_IS_OK(result) ) {
250 d_fprintf(stderr, "Query config request failed. [%s]\n", dos_errstr(result));
251 goto done;
254 /* print out the configuration information for the service */
256 d_printf("Configuration details:\n");
257 d_printf("\tControls Accepted = 0x%x\n", service_status.controls_accepted);
258 d_printf("\tService Type = 0x%x\n", config.service_type);
259 d_printf("\tStart Type = 0x%x\n", config.start_type);
260 d_printf("\tError Control = 0x%x\n", config.error_control);
261 d_printf("\tTag ID = 0x%x\n", config.tag_id);
263 if ( config.executablepath ) {
264 rpcstr_pull( ascii_string, config.executablepath->buffer, sizeof(ascii_string), -1, STR_TERMINATE );
265 d_printf("\tExecutable Path = %s\n", ascii_string);
268 if ( config.loadordergroup ) {
269 rpcstr_pull( ascii_string, config.loadordergroup->buffer, sizeof(ascii_string), -1, STR_TERMINATE );
270 d_printf("\tLoad Order Group = %s\n", ascii_string);
273 if ( config.dependencies ) {
274 rpcstr_pull( ascii_string, config.dependencies->buffer, sizeof(ascii_string), -1, STR_TERMINATE );
275 d_printf("\tDependencies = %s\n", ascii_string);
278 if ( config.startname ) {
279 rpcstr_pull( ascii_string, config.startname->buffer, sizeof(ascii_string), -1, STR_TERMINATE );
280 d_printf("\tStart Name = %s\n", ascii_string);
283 if ( config.displayname ) {
284 rpcstr_pull( ascii_string, config.displayname->buffer, sizeof(ascii_string), -1, STR_TERMINATE );
285 d_printf("\tDisplay Name = %s\n", ascii_string);
288 done:
289 rpccli_svcctl_close_service(pipe_hnd, mem_ctx, &hService );
290 rpccli_svcctl_close_service(pipe_hnd, mem_ctx, &hSCM );
292 return werror_to_ntstatus(result);
295 /********************************************************************
296 ********************************************************************/
298 static NTSTATUS rpc_service_stop_internal(const DOM_SID *domain_sid,
299 const char *domain_name,
300 struct cli_state *cli,
301 struct rpc_pipe_client *pipe_hnd,
302 TALLOC_CTX *mem_ctx,
303 int argc,
304 const char **argv )
306 POLICY_HND hSCM;
307 WERROR result = WERR_GENERAL_FAILURE;
308 fstring servicename;
310 if (argc != 1 ) {
311 d_printf("Usage: net rpc service status <service>\n");
312 return NT_STATUS_OK;
315 fstrcpy( servicename, argv[0] );
317 /* Open the Service Control Manager */
319 result = rpccli_svcctl_open_scm(pipe_hnd, mem_ctx, &hSCM, SC_RIGHT_MGR_ENUMERATE_SERVICE );
320 if ( !W_ERROR_IS_OK(result) ) {
321 d_fprintf(stderr, "Failed to open Service Control Manager. [%s]\n", dos_errstr(result));
322 return werror_to_ntstatus(result);
325 result = control_service(pipe_hnd, mem_ctx, &hSCM, servicename,
326 SVCCTL_CONTROL_STOP, SVCCTL_STOPPED );
328 rpccli_svcctl_close_service(pipe_hnd, mem_ctx, &hSCM );
330 return werror_to_ntstatus(result);
333 /********************************************************************
334 ********************************************************************/
336 static NTSTATUS rpc_service_pause_internal(const DOM_SID *domain_sid,
337 const char *domain_name,
338 struct cli_state *cli,
339 struct rpc_pipe_client *pipe_hnd,
340 TALLOC_CTX *mem_ctx,
341 int argc,
342 const char **argv )
344 POLICY_HND hSCM;
345 WERROR result = WERR_GENERAL_FAILURE;
346 fstring servicename;
348 if (argc != 1 ) {
349 d_printf("Usage: net rpc service status <service>\n");
350 return NT_STATUS_OK;
353 fstrcpy( servicename, argv[0] );
355 /* Open the Service Control Manager */
357 result = rpccli_svcctl_open_scm(pipe_hnd, mem_ctx, &hSCM, SC_RIGHT_MGR_ENUMERATE_SERVICE );
358 if ( !W_ERROR_IS_OK(result) ) {
359 d_fprintf(stderr, "Failed to open Service Control Manager. [%s]\n", dos_errstr(result));
360 return werror_to_ntstatus(result);
363 result = control_service(pipe_hnd, mem_ctx, &hSCM, servicename,
364 SVCCTL_CONTROL_PAUSE, SVCCTL_PAUSED );
366 rpccli_svcctl_close_service(pipe_hnd, mem_ctx, &hSCM );
368 return werror_to_ntstatus(result);
371 /********************************************************************
372 ********************************************************************/
374 static NTSTATUS rpc_service_resume_internal(const DOM_SID *domain_sid,
375 const char *domain_name,
376 struct cli_state *cli,
377 struct rpc_pipe_client *pipe_hnd,
378 TALLOC_CTX *mem_ctx,
379 int argc,
380 const char **argv )
382 POLICY_HND hSCM;
383 WERROR result = WERR_GENERAL_FAILURE;
384 fstring servicename;
386 if (argc != 1 ) {
387 d_printf("Usage: net rpc service status <service>\n");
388 return NT_STATUS_OK;
391 fstrcpy( servicename, argv[0] );
393 /* Open the Service Control Manager */
395 result = rpccli_svcctl_open_scm(pipe_hnd, mem_ctx, &hSCM, SC_RIGHT_MGR_ENUMERATE_SERVICE );
396 if ( !W_ERROR_IS_OK(result) ) {
397 d_fprintf(stderr, "Failed to open Service Control Manager. [%s]\n", dos_errstr(result));
398 return werror_to_ntstatus(result);
401 result = control_service(pipe_hnd, mem_ctx, &hSCM, servicename,
402 SVCCTL_CONTROL_CONTINUE, SVCCTL_RUNNING );
404 rpccli_svcctl_close_service(pipe_hnd, mem_ctx, &hSCM );
406 return werror_to_ntstatus(result);
409 /********************************************************************
410 ********************************************************************/
412 static NTSTATUS rpc_service_start_internal(const DOM_SID *domain_sid,
413 const char *domain_name,
414 struct cli_state *cli,
415 struct rpc_pipe_client *pipe_hnd,
416 TALLOC_CTX *mem_ctx,
417 int argc,
418 const char **argv )
420 POLICY_HND hSCM, hService;
421 WERROR result = WERR_GENERAL_FAILURE;
422 fstring servicename;
423 uint32 state = 0;
425 if (argc != 1 ) {
426 d_printf("Usage: net rpc service status <service>\n");
427 return NT_STATUS_OK;
430 fstrcpy( servicename, argv[0] );
432 /* Open the Service Control Manager */
434 result = rpccli_svcctl_open_scm( pipe_hnd, mem_ctx, &hSCM, SC_RIGHT_MGR_ENUMERATE_SERVICE );
435 if ( !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 /* Open the Service */
442 result = rpccli_svcctl_open_service(pipe_hnd, mem_ctx, &hSCM, &hService,
443 servicename, SC_RIGHT_SVC_START );
445 if ( !W_ERROR_IS_OK(result) ) {
446 d_fprintf(stderr, "Failed to open service. [%s]\n", dos_errstr(result));
447 goto done;
450 /* get the status */
452 result = rpccli_svcctl_start_service(pipe_hnd, mem_ctx, &hService, NULL, 0 );
453 if ( !W_ERROR_IS_OK(result) ) {
454 d_fprintf(stderr, "Query status request failed. [%s]\n", dos_errstr(result));
455 goto done;
458 result = watch_service_state(pipe_hnd, mem_ctx, &hSCM, servicename, SVCCTL_RUNNING, &state );
460 if ( W_ERROR_IS_OK(result) && (state == SVCCTL_RUNNING) )
461 d_printf("Successfully started service: %s\n", servicename );
462 else
463 d_fprintf(stderr, "Failed to start service: %s [%s]\n", servicename, dos_errstr(result) );
465 done:
466 rpccli_svcctl_close_service(pipe_hnd, mem_ctx, &hService );
467 rpccli_svcctl_close_service(pipe_hnd, mem_ctx, &hSCM );
469 return werror_to_ntstatus(result);
472 /********************************************************************
473 ********************************************************************/
475 static int rpc_service_list( int argc, const char **argv )
477 return run_rpc_command( NULL, PI_SVCCTL, 0,
478 rpc_service_list_internal, argc, argv );
481 /********************************************************************
482 ********************************************************************/
484 static int rpc_service_start( int argc, const char **argv )
486 return run_rpc_command( NULL, PI_SVCCTL, 0,
487 rpc_service_start_internal, argc, argv );
490 /********************************************************************
491 ********************************************************************/
493 static int rpc_service_stop( int argc, const char **argv )
495 return run_rpc_command( NULL, PI_SVCCTL, 0,
496 rpc_service_stop_internal, argc, argv );
499 /********************************************************************
500 ********************************************************************/
502 static int rpc_service_resume( int argc, const char **argv )
504 return run_rpc_command( NULL, PI_SVCCTL, 0,
505 rpc_service_resume_internal, argc, argv );
508 /********************************************************************
509 ********************************************************************/
511 static int rpc_service_pause( int argc, const char **argv )
513 return run_rpc_command( NULL, PI_SVCCTL, 0,
514 rpc_service_pause_internal, argc, argv );
517 /********************************************************************
518 ********************************************************************/
520 static int rpc_service_status( int argc, const char **argv )
522 return run_rpc_command( NULL, PI_SVCCTL, 0,
523 rpc_service_status_internal, argc, argv );
526 /********************************************************************
527 ********************************************************************/
529 static int net_help_service( int argc, const char **argv )
531 d_printf("net rpc service list View configured Win32 services\n");
532 d_printf("net rpc service start <service> Start a service\n");
533 d_printf("net rpc service stop <service> Stop a service\n");
534 d_printf("net rpc service pause <service> Pause a service\n");
535 d_printf("net rpc service resume <service> Resume a paused service\n");
536 d_printf("net rpc service status <service> View the current status of a service\n");
538 return -1;
541 /********************************************************************
542 ********************************************************************/
544 int net_rpc_service(int argc, const char **argv)
546 struct functable func[] = {
547 {"list", rpc_service_list},
548 {"start", rpc_service_start},
549 {"stop", rpc_service_stop},
550 {"pause", rpc_service_pause},
551 {"resume", rpc_service_resume},
552 {"status", rpc_service_status},
553 {NULL, NULL}
556 if ( argc )
557 return net_run_function( argc, argv, func, net_help_service );
559 return net_help_service( argc, argv );