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/>. */
20 #include "utils/net.h"
23 #define CLI_SERVER_NAME_SLASH(_ctx, _p, _cli) \
24 _p = talloc_asprintf(_ctx, "\\\\%s", _cli->cli->desthost);
26 /********************************************************************
27 ********************************************************************/
29 static WERROR query_service_state(struct rpc_pipe_client *pipe_hnd,
36 SERVICE_STATUS service_status;
37 WERROR result = WERR_GENERAL_FAILURE;
40 /* now cycle until the status is actually 'watch_state' */
42 status = rpccli_svcctl_OpenServiceW(pipe_hnd, mem_ctx,
45 SC_RIGHT_SVC_QUERY_STATUS,
48 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result) ) {
49 d_fprintf(stderr, "Failed to open service. [%s]\n", dos_errstr(result));
53 result = rpccli_svcctl_query_status(pipe_hnd, mem_ctx, &hService, &service_status );
54 if ( W_ERROR_IS_OK(result) ) {
55 *state = service_status.state;
58 rpccli_svcctl_CloseServiceHandle(pipe_hnd, mem_ctx, &hService, NULL);
63 /********************************************************************
64 ********************************************************************/
66 static WERROR watch_service_state(struct rpc_pipe_client *pipe_hnd,
75 WERROR result = WERR_GENERAL_FAILURE;
79 while ( (state != watch_state ) && i<30 ) {
82 result = query_service_state(pipe_hnd, mem_ctx, hSCM, service, &state );
83 if ( !W_ERROR_IS_OK(result) ) {
98 /********************************************************************
99 ********************************************************************/
101 static WERROR control_service(struct rpc_pipe_client *pipe_hnd,
109 WERROR result = WERR_GENERAL_FAILURE;
111 SERVICE_STATUS service_status;
114 /* Open the Service */
116 status = rpccli_svcctl_OpenServiceW(pipe_hnd, mem_ctx,
119 (SC_RIGHT_SVC_STOP|SC_RIGHT_SVC_PAUSE_CONTINUE),
123 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result) ) {
124 d_fprintf(stderr, "Failed to open service. [%s]\n", dos_errstr(result));
130 result = rpccli_svcctl_control_service(pipe_hnd, mem_ctx, &hService,
131 control, &service_status );
133 if ( !W_ERROR_IS_OK(result) ) {
134 d_fprintf(stderr, "Control service request failed. [%s]\n", dos_errstr(result));
138 /* loop -- checking the state until we are where we want to be */
140 result = watch_service_state(pipe_hnd, mem_ctx, hSCM, service, watch_state, &state );
142 d_printf("%s service is %s.\n", service, svc_status_string(state));
145 rpccli_svcctl_CloseServiceHandle(pipe_hnd, mem_ctx, &hService, NULL);
150 /********************************************************************
151 ********************************************************************/
153 static NTSTATUS rpc_service_list_internal(const DOM_SID *domain_sid,
154 const char *domain_name,
155 struct cli_state *cli,
156 struct rpc_pipe_client *pipe_hnd,
162 ENUM_SERVICES_STATUS *services;
163 WERROR result = WERR_GENERAL_FAILURE;
167 uint32 num_services = 0;
168 const char *server_name;
172 d_printf("Usage: net rpc service list\n");
176 CLI_SERVER_NAME_SLASH(mem_ctx, server_name, pipe_hnd);
177 NT_STATUS_HAVE_NO_MEMORY(server_name);
179 status = rpccli_svcctl_OpenSCManagerW(pipe_hnd, mem_ctx,
182 SC_RIGHT_MGR_ENUMERATE_SERVICE,
185 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result)) {
186 d_fprintf(stderr, "Failed to open Service Control Manager. [%s]\n", dos_errstr(result));
187 return werror_to_ntstatus(result);
190 result = rpccli_svcctl_enumerate_services(pipe_hnd, mem_ctx, &hSCM, SVCCTL_TYPE_WIN32,
191 SVCCTL_STATE_ALL, &num_services, &services );
193 if ( !W_ERROR_IS_OK(result) ) {
194 d_fprintf(stderr, "Failed to enumerate services. [%s]\n", dos_errstr(result));
198 if ( num_services == 0 )
199 d_printf("No services returned\n");
201 for ( i=0; i<num_services; i++ ) {
202 rpcstr_pull( servicename, services[i].servicename.buffer, sizeof(servicename), -1, STR_TERMINATE );
203 rpcstr_pull( displayname, services[i].displayname.buffer, sizeof(displayname), -1, STR_TERMINATE );
205 d_printf("%-20s \"%s\"\n", servicename, displayname);
209 rpccli_svcctl_CloseServiceHandle(pipe_hnd, mem_ctx, &hSCM, NULL);
211 return werror_to_ntstatus(result);
214 /********************************************************************
215 ********************************************************************/
217 static NTSTATUS rpc_service_status_internal(const DOM_SID *domain_sid,
218 const char *domain_name,
219 struct cli_state *cli,
220 struct rpc_pipe_client *pipe_hnd,
225 POLICY_HND hSCM, hService;
226 WERROR result = WERR_GENERAL_FAILURE;
228 SERVICE_STATUS service_status;
229 SERVICE_CONFIG config;
230 fstring ascii_string;
231 const char *server_name;
234 d_printf("Usage: net rpc service status <service>\n");
238 /* Open the Service Control Manager */
239 CLI_SERVER_NAME_SLASH(mem_ctx, server_name, pipe_hnd);
240 NT_STATUS_HAVE_NO_MEMORY(server_name);
242 status = rpccli_svcctl_OpenSCManagerW(pipe_hnd, mem_ctx,
245 SC_RIGHT_MGR_ENUMERATE_SERVICE,
248 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result)) {
249 d_fprintf(stderr, "Failed to open Service Control Manager. [%s]\n", dos_errstr(result));
250 return werror_to_ntstatus(result);
253 /* Open the Service */
255 status = rpccli_svcctl_OpenServiceW(pipe_hnd, mem_ctx,
258 (SC_RIGHT_SVC_QUERY_STATUS|SC_RIGHT_SVC_QUERY_CONFIG),
262 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result) ) {
263 d_fprintf(stderr, "Failed to open service. [%s]\n", dos_errstr(result));
269 result = rpccli_svcctl_query_status(pipe_hnd, mem_ctx, &hService, &service_status );
270 if ( !W_ERROR_IS_OK(result) ) {
271 d_fprintf(stderr, "Query status request failed. [%s]\n", dos_errstr(result));
275 d_printf("%s service is %s.\n", argv[0], svc_status_string(service_status.state));
279 result = rpccli_svcctl_query_config(pipe_hnd, mem_ctx, &hService, &config );
280 if ( !W_ERROR_IS_OK(result) ) {
281 d_fprintf(stderr, "Query config request failed. [%s]\n", dos_errstr(result));
285 /* print out the configuration information for the service */
287 d_printf("Configuration details:\n");
288 d_printf("\tControls Accepted = 0x%x\n", service_status.controls_accepted);
289 d_printf("\tService Type = 0x%x\n", config.service_type);
290 d_printf("\tStart Type = 0x%x\n", config.start_type);
291 d_printf("\tError Control = 0x%x\n", config.error_control);
292 d_printf("\tTag ID = 0x%x\n", config.tag_id);
294 if ( config.executablepath ) {
295 rpcstr_pull( ascii_string, config.executablepath->buffer, sizeof(ascii_string), -1, STR_TERMINATE );
296 d_printf("\tExecutable Path = %s\n", ascii_string);
299 if ( config.loadordergroup ) {
300 rpcstr_pull( ascii_string, config.loadordergroup->buffer, sizeof(ascii_string), -1, STR_TERMINATE );
301 d_printf("\tLoad Order Group = %s\n", ascii_string);
304 if ( config.dependencies ) {
305 rpcstr_pull( ascii_string, config.dependencies->buffer, sizeof(ascii_string), -1, STR_TERMINATE );
306 d_printf("\tDependencies = %s\n", ascii_string);
309 if ( config.startname ) {
310 rpcstr_pull( ascii_string, config.startname->buffer, sizeof(ascii_string), -1, STR_TERMINATE );
311 d_printf("\tStart Name = %s\n", ascii_string);
314 if ( config.displayname ) {
315 rpcstr_pull( ascii_string, config.displayname->buffer, sizeof(ascii_string), -1, STR_TERMINATE );
316 d_printf("\tDisplay Name = %s\n", ascii_string);
320 rpccli_svcctl_CloseServiceHandle(pipe_hnd, mem_ctx, &hService, NULL);
321 rpccli_svcctl_CloseServiceHandle(pipe_hnd, mem_ctx, &hSCM, NULL);
323 return werror_to_ntstatus(result);
326 /********************************************************************
327 ********************************************************************/
329 static NTSTATUS rpc_service_stop_internal(const DOM_SID *domain_sid,
330 const char *domain_name,
331 struct cli_state *cli,
332 struct rpc_pipe_client *pipe_hnd,
338 WERROR result = WERR_GENERAL_FAILURE;
341 const char *server_name;
344 d_printf("Usage: net rpc service status <service>\n");
348 fstrcpy( servicename, argv[0] );
350 /* Open the Service Control Manager */
351 CLI_SERVER_NAME_SLASH(mem_ctx, server_name, pipe_hnd);
352 NT_STATUS_HAVE_NO_MEMORY(server_name);
354 status = rpccli_svcctl_OpenSCManagerW(pipe_hnd, mem_ctx,
357 SC_RIGHT_MGR_ENUMERATE_SERVICE,
360 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result)) {
361 d_fprintf(stderr, "Failed to open Service Control Manager. [%s]\n", dos_errstr(result));
362 return werror_to_ntstatus(result);
365 result = control_service(pipe_hnd, mem_ctx, &hSCM, servicename,
366 SVCCTL_CONTROL_STOP, SVCCTL_STOPPED );
368 rpccli_svcctl_CloseServiceHandle(pipe_hnd, mem_ctx, &hSCM, NULL);
370 return werror_to_ntstatus(result);
373 /********************************************************************
374 ********************************************************************/
376 static NTSTATUS rpc_service_pause_internal(const DOM_SID *domain_sid,
377 const char *domain_name,
378 struct cli_state *cli,
379 struct rpc_pipe_client *pipe_hnd,
385 WERROR result = WERR_GENERAL_FAILURE;
388 const char *server_name;
391 d_printf("Usage: net rpc service status <service>\n");
395 fstrcpy( servicename, argv[0] );
397 /* Open the Service Control Manager */
398 CLI_SERVER_NAME_SLASH(mem_ctx, server_name, pipe_hnd);
399 NT_STATUS_HAVE_NO_MEMORY(server_name);
401 status = rpccli_svcctl_OpenSCManagerW(pipe_hnd, mem_ctx,
404 SC_RIGHT_MGR_ENUMERATE_SERVICE,
407 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result)) {
408 d_fprintf(stderr, "Failed to open Service Control Manager. [%s]\n", dos_errstr(result));
409 return werror_to_ntstatus(result);
412 result = control_service(pipe_hnd, mem_ctx, &hSCM, servicename,
413 SVCCTL_CONTROL_PAUSE, SVCCTL_PAUSED );
415 rpccli_svcctl_CloseServiceHandle(pipe_hnd, mem_ctx, &hSCM, NULL);
417 return werror_to_ntstatus(result);
420 /********************************************************************
421 ********************************************************************/
423 static NTSTATUS rpc_service_resume_internal(const DOM_SID *domain_sid,
424 const char *domain_name,
425 struct cli_state *cli,
426 struct rpc_pipe_client *pipe_hnd,
432 WERROR result = WERR_GENERAL_FAILURE;
435 const char *server_name;
438 d_printf("Usage: net rpc service status <service>\n");
442 fstrcpy( servicename, argv[0] );
444 /* Open the Service Control Manager */
445 CLI_SERVER_NAME_SLASH(mem_ctx, server_name, pipe_hnd);
446 NT_STATUS_HAVE_NO_MEMORY(server_name);
448 status = rpccli_svcctl_OpenSCManagerW(pipe_hnd, mem_ctx,
451 SC_RIGHT_MGR_ENUMERATE_SERVICE,
454 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result)) {
455 d_fprintf(stderr, "Failed to open Service Control Manager. [%s]\n", dos_errstr(result));
456 return werror_to_ntstatus(result);
459 result = control_service(pipe_hnd, mem_ctx, &hSCM, servicename,
460 SVCCTL_CONTROL_CONTINUE, SVCCTL_RUNNING );
462 rpccli_svcctl_CloseServiceHandle(pipe_hnd, mem_ctx, &hSCM, NULL);
464 return werror_to_ntstatus(result);
467 /********************************************************************
468 ********************************************************************/
470 static NTSTATUS rpc_service_start_internal(const DOM_SID *domain_sid,
471 const char *domain_name,
472 struct cli_state *cli,
473 struct rpc_pipe_client *pipe_hnd,
478 POLICY_HND hSCM, hService;
479 WERROR result = WERR_GENERAL_FAILURE;
482 const char *server_name;
485 d_printf("Usage: net rpc service status <service>\n");
489 /* Open the Service Control Manager */
490 CLI_SERVER_NAME_SLASH(mem_ctx, server_name, pipe_hnd);
491 NT_STATUS_HAVE_NO_MEMORY(server_name);
493 status = rpccli_svcctl_OpenSCManagerW(pipe_hnd, mem_ctx,
496 SC_RIGHT_MGR_ENUMERATE_SERVICE,
499 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result)) {
500 d_fprintf(stderr, "Failed to open Service Control Manager. [%s]\n", dos_errstr(result));
501 return werror_to_ntstatus(result);
504 /* Open the Service */
506 status = rpccli_svcctl_OpenServiceW(pipe_hnd, mem_ctx,
513 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result) ) {
514 d_fprintf(stderr, "Failed to open service. [%s]\n", dos_errstr(result));
520 status = rpccli_svcctl_StartServiceW(pipe_hnd, mem_ctx,
526 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result) ) {
527 d_fprintf(stderr, "Query status request failed. [%s]\n", dos_errstr(result));
531 result = watch_service_state(pipe_hnd, mem_ctx, &hSCM, argv[0], SVCCTL_RUNNING, &state );
533 if ( W_ERROR_IS_OK(result) && (state == SVCCTL_RUNNING) )
534 d_printf("Successfully started service: %s\n", argv[0] );
536 d_fprintf(stderr, "Failed to start service: %s [%s]\n", argv[0], dos_errstr(result) );
539 rpccli_svcctl_CloseServiceHandle(pipe_hnd, mem_ctx, &hService, NULL);
540 rpccli_svcctl_CloseServiceHandle(pipe_hnd, mem_ctx, &hSCM, NULL);
542 return werror_to_ntstatus(result);
545 /********************************************************************
546 ********************************************************************/
548 static int rpc_service_list( int argc, const char **argv )
550 return run_rpc_command( NULL, PI_SVCCTL, 0,
551 rpc_service_list_internal, argc, argv );
554 /********************************************************************
555 ********************************************************************/
557 static int rpc_service_start( int argc, const char **argv )
559 return run_rpc_command( NULL, PI_SVCCTL, 0,
560 rpc_service_start_internal, argc, argv );
563 /********************************************************************
564 ********************************************************************/
566 static int rpc_service_stop( int argc, const char **argv )
568 return run_rpc_command( NULL, PI_SVCCTL, 0,
569 rpc_service_stop_internal, argc, argv );
572 /********************************************************************
573 ********************************************************************/
575 static int rpc_service_resume( int argc, const char **argv )
577 return run_rpc_command( NULL, PI_SVCCTL, 0,
578 rpc_service_resume_internal, argc, argv );
581 /********************************************************************
582 ********************************************************************/
584 static int rpc_service_pause( int argc, const char **argv )
586 return run_rpc_command( NULL, PI_SVCCTL, 0,
587 rpc_service_pause_internal, argc, argv );
590 /********************************************************************
591 ********************************************************************/
593 static int rpc_service_status( int argc, const char **argv )
595 return run_rpc_command( NULL, PI_SVCCTL, 0,
596 rpc_service_status_internal, argc, argv );
599 /********************************************************************
600 ********************************************************************/
602 static int net_help_service( int argc, const char **argv )
604 d_printf("net rpc service list View configured Win32 services\n");
605 d_printf("net rpc service start <service> Start a service\n");
606 d_printf("net rpc service stop <service> Stop a service\n");
607 d_printf("net rpc service pause <service> Pause a service\n");
608 d_printf("net rpc service resume <service> Resume a paused service\n");
609 d_printf("net rpc service status <service> View the current status of a service\n");
614 /********************************************************************
615 ********************************************************************/
617 int net_rpc_service(int argc, const char **argv)
619 struct functable func[] = {
620 {"list", rpc_service_list},
621 {"start", rpc_service_start},
622 {"stop", rpc_service_stop},
623 {"pause", rpc_service_pause},
624 {"resume", rpc_service_resume},
625 {"status", rpc_service_status},
630 return net_run_function( argc, argv, func, net_help_service );
632 return net_help_service( argc, argv );