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 status = rpccli_svcctl_ControlService(pipe_hnd, mem_ctx,
136 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result) ) {
137 d_fprintf(stderr, "Control service request failed. [%s]\n", dos_errstr(result));
141 /* loop -- checking the state until we are where we want to be */
143 result = watch_service_state(pipe_hnd, mem_ctx, hSCM, service, watch_state, &state );
145 d_printf("%s service is %s.\n", service, svc_status_string(state));
148 rpccli_svcctl_CloseServiceHandle(pipe_hnd, mem_ctx, &hService, NULL);
153 /********************************************************************
154 ********************************************************************/
156 static NTSTATUS rpc_service_list_internal(const DOM_SID *domain_sid,
157 const char *domain_name,
158 struct cli_state *cli,
159 struct rpc_pipe_client *pipe_hnd,
165 ENUM_SERVICES_STATUS *services;
166 WERROR result = WERR_GENERAL_FAILURE;
170 uint32 num_services = 0;
171 const char *server_name;
175 d_printf("Usage: net rpc service list\n");
179 CLI_SERVER_NAME_SLASH(mem_ctx, server_name, pipe_hnd);
180 NT_STATUS_HAVE_NO_MEMORY(server_name);
182 status = rpccli_svcctl_OpenSCManagerW(pipe_hnd, mem_ctx,
185 SC_RIGHT_MGR_ENUMERATE_SERVICE,
188 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result)) {
189 d_fprintf(stderr, "Failed to open Service Control Manager. [%s]\n", dos_errstr(result));
190 return werror_to_ntstatus(result);
193 result = rpccli_svcctl_enumerate_services(pipe_hnd, mem_ctx, &hSCM, SVCCTL_TYPE_WIN32,
194 SVCCTL_STATE_ALL, &num_services, &services );
196 if ( !W_ERROR_IS_OK(result) ) {
197 d_fprintf(stderr, "Failed to enumerate services. [%s]\n", dos_errstr(result));
201 if ( num_services == 0 )
202 d_printf("No services returned\n");
204 for ( i=0; i<num_services; i++ ) {
205 rpcstr_pull( servicename, services[i].servicename.buffer, sizeof(servicename), -1, STR_TERMINATE );
206 rpcstr_pull( displayname, services[i].displayname.buffer, sizeof(displayname), -1, STR_TERMINATE );
208 d_printf("%-20s \"%s\"\n", servicename, displayname);
212 rpccli_svcctl_CloseServiceHandle(pipe_hnd, mem_ctx, &hSCM, NULL);
214 return werror_to_ntstatus(result);
217 /********************************************************************
218 ********************************************************************/
220 static NTSTATUS rpc_service_status_internal(const DOM_SID *domain_sid,
221 const char *domain_name,
222 struct cli_state *cli,
223 struct rpc_pipe_client *pipe_hnd,
228 POLICY_HND hSCM, hService;
229 WERROR result = WERR_GENERAL_FAILURE;
231 SERVICE_STATUS service_status;
232 SERVICE_CONFIG config;
233 fstring ascii_string;
234 const char *server_name;
237 d_printf("Usage: net rpc service status <service>\n");
241 /* Open the Service Control Manager */
242 CLI_SERVER_NAME_SLASH(mem_ctx, server_name, pipe_hnd);
243 NT_STATUS_HAVE_NO_MEMORY(server_name);
245 status = rpccli_svcctl_OpenSCManagerW(pipe_hnd, mem_ctx,
248 SC_RIGHT_MGR_ENUMERATE_SERVICE,
251 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result)) {
252 d_fprintf(stderr, "Failed to open Service Control Manager. [%s]\n", dos_errstr(result));
253 return werror_to_ntstatus(result);
256 /* Open the Service */
258 status = rpccli_svcctl_OpenServiceW(pipe_hnd, mem_ctx,
261 (SC_RIGHT_SVC_QUERY_STATUS|SC_RIGHT_SVC_QUERY_CONFIG),
265 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result) ) {
266 d_fprintf(stderr, "Failed to open service. [%s]\n", dos_errstr(result));
272 result = rpccli_svcctl_query_status(pipe_hnd, mem_ctx, &hService, &service_status );
273 if ( !W_ERROR_IS_OK(result) ) {
274 d_fprintf(stderr, "Query status request failed. [%s]\n", dos_errstr(result));
278 d_printf("%s service is %s.\n", argv[0], svc_status_string(service_status.state));
282 result = rpccli_svcctl_query_config(pipe_hnd, mem_ctx, &hService, &config );
283 if ( !W_ERROR_IS_OK(result) ) {
284 d_fprintf(stderr, "Query config request failed. [%s]\n", dos_errstr(result));
288 /* print out the configuration information for the service */
290 d_printf("Configuration details:\n");
291 d_printf("\tControls Accepted = 0x%x\n", service_status.controls_accepted);
292 d_printf("\tService Type = 0x%x\n", config.service_type);
293 d_printf("\tStart Type = 0x%x\n", config.start_type);
294 d_printf("\tError Control = 0x%x\n", config.error_control);
295 d_printf("\tTag ID = 0x%x\n", config.tag_id);
297 if ( config.executablepath ) {
298 rpcstr_pull( ascii_string, config.executablepath->buffer, sizeof(ascii_string), -1, STR_TERMINATE );
299 d_printf("\tExecutable Path = %s\n", ascii_string);
302 if ( config.loadordergroup ) {
303 rpcstr_pull( ascii_string, config.loadordergroup->buffer, sizeof(ascii_string), -1, STR_TERMINATE );
304 d_printf("\tLoad Order Group = %s\n", ascii_string);
307 if ( config.dependencies ) {
308 rpcstr_pull( ascii_string, config.dependencies->buffer, sizeof(ascii_string), -1, STR_TERMINATE );
309 d_printf("\tDependencies = %s\n", ascii_string);
312 if ( config.startname ) {
313 rpcstr_pull( ascii_string, config.startname->buffer, sizeof(ascii_string), -1, STR_TERMINATE );
314 d_printf("\tStart Name = %s\n", ascii_string);
317 if ( config.displayname ) {
318 rpcstr_pull( ascii_string, config.displayname->buffer, sizeof(ascii_string), -1, STR_TERMINATE );
319 d_printf("\tDisplay Name = %s\n", ascii_string);
323 rpccli_svcctl_CloseServiceHandle(pipe_hnd, mem_ctx, &hService, NULL);
324 rpccli_svcctl_CloseServiceHandle(pipe_hnd, mem_ctx, &hSCM, NULL);
326 return werror_to_ntstatus(result);
329 /********************************************************************
330 ********************************************************************/
332 static NTSTATUS rpc_service_stop_internal(const DOM_SID *domain_sid,
333 const char *domain_name,
334 struct cli_state *cli,
335 struct rpc_pipe_client *pipe_hnd,
341 WERROR result = WERR_GENERAL_FAILURE;
344 const char *server_name;
347 d_printf("Usage: net rpc service status <service>\n");
351 fstrcpy( servicename, argv[0] );
353 /* Open the Service Control Manager */
354 CLI_SERVER_NAME_SLASH(mem_ctx, server_name, pipe_hnd);
355 NT_STATUS_HAVE_NO_MEMORY(server_name);
357 status = rpccli_svcctl_OpenSCManagerW(pipe_hnd, mem_ctx,
360 SC_RIGHT_MGR_ENUMERATE_SERVICE,
363 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result)) {
364 d_fprintf(stderr, "Failed to open Service Control Manager. [%s]\n", dos_errstr(result));
365 return werror_to_ntstatus(result);
368 result = control_service(pipe_hnd, mem_ctx, &hSCM, servicename,
369 SVCCTL_CONTROL_STOP, SVCCTL_STOPPED );
371 rpccli_svcctl_CloseServiceHandle(pipe_hnd, mem_ctx, &hSCM, NULL);
373 return werror_to_ntstatus(result);
376 /********************************************************************
377 ********************************************************************/
379 static NTSTATUS rpc_service_pause_internal(const DOM_SID *domain_sid,
380 const char *domain_name,
381 struct cli_state *cli,
382 struct rpc_pipe_client *pipe_hnd,
388 WERROR result = WERR_GENERAL_FAILURE;
391 const char *server_name;
394 d_printf("Usage: net rpc service status <service>\n");
398 fstrcpy( servicename, argv[0] );
400 /* Open the Service Control Manager */
401 CLI_SERVER_NAME_SLASH(mem_ctx, server_name, pipe_hnd);
402 NT_STATUS_HAVE_NO_MEMORY(server_name);
404 status = rpccli_svcctl_OpenSCManagerW(pipe_hnd, mem_ctx,
407 SC_RIGHT_MGR_ENUMERATE_SERVICE,
410 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result)) {
411 d_fprintf(stderr, "Failed to open Service Control Manager. [%s]\n", dos_errstr(result));
412 return werror_to_ntstatus(result);
415 result = control_service(pipe_hnd, mem_ctx, &hSCM, servicename,
416 SVCCTL_CONTROL_PAUSE, SVCCTL_PAUSED );
418 rpccli_svcctl_CloseServiceHandle(pipe_hnd, mem_ctx, &hSCM, NULL);
420 return werror_to_ntstatus(result);
423 /********************************************************************
424 ********************************************************************/
426 static NTSTATUS rpc_service_resume_internal(const DOM_SID *domain_sid,
427 const char *domain_name,
428 struct cli_state *cli,
429 struct rpc_pipe_client *pipe_hnd,
435 WERROR result = WERR_GENERAL_FAILURE;
438 const char *server_name;
441 d_printf("Usage: net rpc service status <service>\n");
445 fstrcpy( servicename, argv[0] );
447 /* Open the Service Control Manager */
448 CLI_SERVER_NAME_SLASH(mem_ctx, server_name, pipe_hnd);
449 NT_STATUS_HAVE_NO_MEMORY(server_name);
451 status = rpccli_svcctl_OpenSCManagerW(pipe_hnd, mem_ctx,
454 SC_RIGHT_MGR_ENUMERATE_SERVICE,
457 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result)) {
458 d_fprintf(stderr, "Failed to open Service Control Manager. [%s]\n", dos_errstr(result));
459 return werror_to_ntstatus(result);
462 result = control_service(pipe_hnd, mem_ctx, &hSCM, servicename,
463 SVCCTL_CONTROL_CONTINUE, SVCCTL_RUNNING );
465 rpccli_svcctl_CloseServiceHandle(pipe_hnd, mem_ctx, &hSCM, NULL);
467 return werror_to_ntstatus(result);
470 /********************************************************************
471 ********************************************************************/
473 static NTSTATUS rpc_service_start_internal(const DOM_SID *domain_sid,
474 const char *domain_name,
475 struct cli_state *cli,
476 struct rpc_pipe_client *pipe_hnd,
481 POLICY_HND hSCM, hService;
482 WERROR result = WERR_GENERAL_FAILURE;
485 const char *server_name;
488 d_printf("Usage: net rpc service status <service>\n");
492 /* Open the Service Control Manager */
493 CLI_SERVER_NAME_SLASH(mem_ctx, server_name, pipe_hnd);
494 NT_STATUS_HAVE_NO_MEMORY(server_name);
496 status = rpccli_svcctl_OpenSCManagerW(pipe_hnd, mem_ctx,
499 SC_RIGHT_MGR_ENUMERATE_SERVICE,
502 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result)) {
503 d_fprintf(stderr, "Failed to open Service Control Manager. [%s]\n", dos_errstr(result));
504 return werror_to_ntstatus(result);
507 /* Open the Service */
509 status = rpccli_svcctl_OpenServiceW(pipe_hnd, mem_ctx,
516 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result) ) {
517 d_fprintf(stderr, "Failed to open service. [%s]\n", dos_errstr(result));
523 status = rpccli_svcctl_StartServiceW(pipe_hnd, mem_ctx,
529 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result) ) {
530 d_fprintf(stderr, "Query status request failed. [%s]\n", dos_errstr(result));
534 result = watch_service_state(pipe_hnd, mem_ctx, &hSCM, argv[0], SVCCTL_RUNNING, &state );
536 if ( W_ERROR_IS_OK(result) && (state == SVCCTL_RUNNING) )
537 d_printf("Successfully started service: %s\n", argv[0] );
539 d_fprintf(stderr, "Failed to start service: %s [%s]\n", argv[0], dos_errstr(result) );
542 rpccli_svcctl_CloseServiceHandle(pipe_hnd, mem_ctx, &hService, NULL);
543 rpccli_svcctl_CloseServiceHandle(pipe_hnd, mem_ctx, &hSCM, NULL);
545 return werror_to_ntstatus(result);
548 /********************************************************************
549 ********************************************************************/
551 static int rpc_service_list( int argc, const char **argv )
553 return run_rpc_command( NULL, PI_SVCCTL, 0,
554 rpc_service_list_internal, argc, argv );
557 /********************************************************************
558 ********************************************************************/
560 static int rpc_service_start( int argc, const char **argv )
562 return run_rpc_command( NULL, PI_SVCCTL, 0,
563 rpc_service_start_internal, argc, argv );
566 /********************************************************************
567 ********************************************************************/
569 static int rpc_service_stop( int argc, const char **argv )
571 return run_rpc_command( NULL, PI_SVCCTL, 0,
572 rpc_service_stop_internal, argc, argv );
575 /********************************************************************
576 ********************************************************************/
578 static int rpc_service_resume( int argc, const char **argv )
580 return run_rpc_command( NULL, PI_SVCCTL, 0,
581 rpc_service_resume_internal, argc, argv );
584 /********************************************************************
585 ********************************************************************/
587 static int rpc_service_pause( int argc, const char **argv )
589 return run_rpc_command( NULL, PI_SVCCTL, 0,
590 rpc_service_pause_internal, argc, argv );
593 /********************************************************************
594 ********************************************************************/
596 static int rpc_service_status( int argc, const char **argv )
598 return run_rpc_command( NULL, PI_SVCCTL, 0,
599 rpc_service_status_internal, argc, argv );
602 /********************************************************************
603 ********************************************************************/
605 static int net_help_service( int argc, const char **argv )
607 d_printf("net rpc service list View configured Win32 services\n");
608 d_printf("net rpc service start <service> Start a service\n");
609 d_printf("net rpc service stop <service> Stop a service\n");
610 d_printf("net rpc service pause <service> Pause a service\n");
611 d_printf("net rpc service resume <service> Resume a paused service\n");
612 d_printf("net rpc service status <service> View the current status of a service\n");
617 /********************************************************************
618 ********************************************************************/
620 int net_rpc_service(int argc, const char **argv)
622 struct functable func[] = {
623 {"list", rpc_service_list},
624 {"start", rpc_service_start},
625 {"stop", rpc_service_stop},
626 {"pause", rpc_service_pause},
627 {"resume", rpc_service_resume},
628 {"status", rpc_service_status},
633 return net_run_function( argc, argv, func, net_help_service );
635 return net_help_service( argc, argv );