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 struct svc_state_msg
{
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" },
40 /********************************************************************
41 ********************************************************************/
42 const char *svc_status_string( uint32 state
)
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
);
56 return talloc_strdup(talloc_tos(), msg
);
59 /********************************************************************
60 ********************************************************************/
62 static WERROR
query_service_state(struct rpc_pipe_client
*pipe_hnd
,
69 SERVICE_STATUS service_status
;
70 WERROR result
= WERR_GENERAL_FAILURE
;
73 /* now cycle until the status is actually 'watch_state' */
75 status
= rpccli_svcctl_OpenServiceW(pipe_hnd
, mem_ctx
,
78 SC_RIGHT_SVC_QUERY_STATUS
,
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
));
86 status
= rpccli_svcctl_QueryServiceStatus(pipe_hnd
, mem_ctx
,
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
);
100 /********************************************************************
101 ********************************************************************/
103 static WERROR
watch_service_state(struct rpc_pipe_client
*pipe_hnd
,
108 uint32
*final_state
)
112 WERROR result
= WERR_GENERAL_FAILURE
;
116 while ( (state
!= watch_state
) && i
<30 ) {
119 result
= query_service_state(pipe_hnd
, mem_ctx
, hSCM
, service
, &state
);
120 if ( !W_ERROR_IS_OK(result
) ) {
130 *final_state
= state
;
135 /********************************************************************
136 ********************************************************************/
138 static WERROR
control_service(struct rpc_pipe_client
*pipe_hnd
,
146 WERROR result
= WERR_GENERAL_FAILURE
;
148 SERVICE_STATUS service_status
;
151 /* Open the Service */
153 status
= rpccli_svcctl_OpenServiceW(pipe_hnd
, mem_ctx
,
156 (SC_RIGHT_SVC_STOP
|SC_RIGHT_SVC_PAUSE_CONTINUE
),
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
));
167 status
= rpccli_svcctl_ControlService(pipe_hnd
, mem_ctx
,
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
));
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
));
185 rpccli_svcctl_CloseServiceHandle(pipe_hnd
, mem_ctx
, &hService
, NULL
);
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
,
202 ENUM_SERVICES_STATUS
*services
;
203 WERROR result
= WERR_GENERAL_FAILURE
;
207 uint32 num_services
= 0;
211 d_printf("Usage: net rpc service list\n");
215 status
= rpccli_svcctl_OpenSCManagerW(pipe_hnd
, mem_ctx
,
216 pipe_hnd
->srv_name_slash
,
218 SC_RIGHT_MGR_ENUMERATE_SERVICE
,
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
));
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
);
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
,
261 POLICY_HND hSCM
, hService
;
262 WERROR result
= WERR_GENERAL_FAILURE
;
264 SERVICE_STATUS service_status
;
265 SERVICE_CONFIG config
;
266 fstring ascii_string
;
269 d_printf("Usage: net rpc service status <service>\n");
273 /* Open the Service Control Manager */
274 status
= rpccli_svcctl_OpenSCManagerW(pipe_hnd
, mem_ctx
,
275 pipe_hnd
->srv_name_slash
,
277 SC_RIGHT_MGR_ENUMERATE_SERVICE
,
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
,
290 (SC_RIGHT_SVC_QUERY_STATUS
|SC_RIGHT_SVC_QUERY_CONFIG
),
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
));
301 status
= rpccli_svcctl_QueryServiceStatus(pipe_hnd
, mem_ctx
,
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
));
311 d_printf("%s service is %s.\n", argv
[0], svc_status_string(service_status
.state
));
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
));
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
);
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
,
374 WERROR result
= WERR_GENERAL_FAILURE
;
379 d_printf("Usage: net rpc service status <service>\n");
383 fstrcpy( servicename
, argv
[0] );
385 /* Open the Service Control Manager */
386 status
= rpccli_svcctl_OpenSCManagerW(pipe_hnd
, mem_ctx
,
387 pipe_hnd
->srv_name_slash
,
389 SC_RIGHT_MGR_ENUMERATE_SERVICE
,
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
,
417 WERROR result
= WERR_GENERAL_FAILURE
;
422 d_printf("Usage: net rpc service status <service>\n");
426 fstrcpy( servicename
, argv
[0] );
428 /* Open the Service Control Manager */
429 status
= rpccli_svcctl_OpenSCManagerW(pipe_hnd
, mem_ctx
,
430 pipe_hnd
->srv_name_slash
,
432 SC_RIGHT_MGR_ENUMERATE_SERVICE
,
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
,
460 WERROR result
= WERR_GENERAL_FAILURE
;
465 d_printf("Usage: net rpc service status <service>\n");
469 fstrcpy( servicename
, argv
[0] );
471 /* Open the Service Control Manager */
472 status
= rpccli_svcctl_OpenSCManagerW(pipe_hnd
, mem_ctx
,
473 pipe_hnd
->srv_name_slash
,
475 SC_RIGHT_MGR_ENUMERATE_SERVICE
,
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
,
502 POLICY_HND hSCM
, hService
;
503 WERROR result
= WERR_GENERAL_FAILURE
;
508 d_printf("Usage: net rpc service status <service>\n");
512 /* Open the Service Control Manager */
513 status
= rpccli_svcctl_OpenSCManagerW(pipe_hnd
, mem_ctx
,
514 pipe_hnd
->srv_name_slash
,
516 SC_RIGHT_MGR_ENUMERATE_SERVICE
,
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
,
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
));
540 status
= rpccli_svcctl_StartServiceW(pipe_hnd
, mem_ctx
,
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
));
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] );
556 d_fprintf(stderr
, "Failed to start service: %s [%s]\n", argv
[0], dos_errstr(result
) );
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");
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
},
650 return net_run_function( argc
, argv
, func
, net_help_service
);
652 return net_help_service( argc
, argv
);