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 struct 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", win_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 struct 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", win_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", win_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(struct net_context
*c
,
194 const DOM_SID
*domain_sid
,
195 const char *domain_name
,
196 struct cli_state
*cli
,
197 struct rpc_pipe_client
*pipe_hnd
,
203 struct ENUM_SERVICE_STATUSW
*services
= NULL
;
204 WERROR result
= WERR_GENERAL_FAILURE
;
208 uint8_t *buffer
= NULL
;
209 uint32_t buf_size
= 0;
210 uint32_t bytes_needed
= 0;
211 uint32_t num_services
= 0;
212 uint32_t resume_handle
= 0;
215 d_printf("Usage: net rpc service list\n");
219 status
= rpccli_svcctl_OpenSCManagerW(pipe_hnd
, mem_ctx
,
220 pipe_hnd
->srv_name_slash
,
222 SC_RIGHT_MGR_ENUMERATE_SERVICE
,
225 if (!NT_STATUS_IS_OK(status
) || !W_ERROR_IS_OK(result
)) {
226 d_fprintf(stderr
, "Failed to open Service Control Manager. [%s]\n", win_errstr(result
));
227 return werror_to_ntstatus(result
);
231 status
= rpccli_svcctl_EnumServicesStatusW(pipe_hnd
, mem_ctx
,
242 if (NT_STATUS_IS_ERR(status
)) {
243 d_fprintf(stderr
, "Failed to enumerate services. [%s]\n",
248 if (W_ERROR_EQUAL(result
, WERR_MORE_DATA
) && bytes_needed
> 0) {
249 buffer
= talloc_array(mem_ctx
, uint8_t, bytes_needed
);
250 buf_size
= bytes_needed
;
254 if ( num_services
== 0 ) {
255 d_printf("No services returned\n");
260 enum ndr_err_code ndr_err
;
262 struct ndr_pull
*ndr
;
264 blob
.length
= buf_size
;
265 blob
.data
= talloc_steal(mem_ctx
, buffer
);
267 services
= talloc_array(mem_ctx
, struct ENUM_SERVICE_STATUSW
, num_services
);
269 status
= NT_STATUS_NO_MEMORY
;
273 ndr
= ndr_pull_init_blob(&blob
, mem_ctx
, NULL
);
275 status
= NT_STATUS_NO_MEMORY
;
279 ndr_err
= ndr_pull_ENUM_SERVICE_STATUSW_array(
280 ndr
, num_services
, services
);
281 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
282 status
= ndr_map_error2ntstatus(ndr_err
);
286 for ( i
=0; i
<num_services
; i
++ ) {
287 d_printf("%-20s \"%s\"\n",
288 services
[i
].service_name
,
289 services
[i
].display_name
);
293 } while (W_ERROR_EQUAL(result
, WERR_MORE_DATA
));
295 rpccli_svcctl_CloseServiceHandle(pipe_hnd
, mem_ctx
, &hSCM
, NULL
);
300 /********************************************************************
301 ********************************************************************/
303 static NTSTATUS
rpc_service_status_internal(struct net_context
*c
,
304 const DOM_SID
*domain_sid
,
305 const char *domain_name
,
306 struct cli_state
*cli
,
307 struct rpc_pipe_client
*pipe_hnd
,
312 POLICY_HND hSCM
, hService
;
313 WERROR result
= WERR_GENERAL_FAILURE
;
315 struct SERVICE_STATUS service_status
;
316 struct QUERY_SERVICE_CONFIG config
;
317 uint32_t buf_size
= sizeof(config
);
318 uint32_t ret_size
= 0;
321 d_printf("Usage: net rpc service status <service>\n");
325 /* Open the Service Control Manager */
326 status
= rpccli_svcctl_OpenSCManagerW(pipe_hnd
, mem_ctx
,
327 pipe_hnd
->srv_name_slash
,
329 SC_RIGHT_MGR_ENUMERATE_SERVICE
,
332 if (!NT_STATUS_IS_OK(status
) || !W_ERROR_IS_OK(result
)) {
333 d_fprintf(stderr
, "Failed to open Service Control Manager. [%s]\n", win_errstr(result
));
334 return werror_to_ntstatus(result
);
337 /* Open the Service */
339 status
= rpccli_svcctl_OpenServiceW(pipe_hnd
, mem_ctx
,
342 (SC_RIGHT_SVC_QUERY_STATUS
|SC_RIGHT_SVC_QUERY_CONFIG
),
346 if (!NT_STATUS_IS_OK(status
) || !W_ERROR_IS_OK(result
) ) {
347 d_fprintf(stderr
, "Failed to open service. [%s]\n", win_errstr(result
));
353 status
= rpccli_svcctl_QueryServiceStatus(pipe_hnd
, mem_ctx
,
358 if (!NT_STATUS_IS_OK(status
) || !W_ERROR_IS_OK(result
) ) {
359 d_fprintf(stderr
, "Query status request failed. [%s]\n", win_errstr(result
));
363 d_printf("%s service is %s.\n", argv
[0], svc_status_string(service_status
.state
));
367 status
= rpccli_svcctl_QueryServiceConfigW(pipe_hnd
, mem_ctx
,
373 if (W_ERROR_EQUAL(result
, WERR_INSUFFICIENT_BUFFER
)) {
375 status
= rpccli_svcctl_QueryServiceConfigW(pipe_hnd
, mem_ctx
,
383 if (!NT_STATUS_IS_OK(status
) || !W_ERROR_IS_OK(result
) ) {
384 d_fprintf(stderr
, "Query config request failed. [%s]\n", win_errstr(result
));
388 /* print out the configuration information for the service */
390 d_printf("Configuration details:\n");
391 d_printf("\tControls Accepted = 0x%x\n", service_status
.controls_accepted
);
392 d_printf("\tService Type = 0x%x\n", config
.service_type
);
393 d_printf("\tStart Type = 0x%x\n", config
.start_type
);
394 d_printf("\tError Control = 0x%x\n", config
.error_control
);
395 d_printf("\tTag ID = 0x%x\n", config
.tag_id
);
397 if (config
.executablepath
) {
398 d_printf("\tExecutable Path = %s\n", config
.executablepath
);
401 if (config
.loadordergroup
) {
402 d_printf("\tLoad Order Group = %s\n", config
.loadordergroup
);
405 if (config
.dependencies
) {
406 d_printf("\tDependencies = %s\n", config
.dependencies
);
409 if (config
.startname
) {
410 d_printf("\tStart Name = %s\n", config
.startname
);
413 if (config
.displayname
) {
414 d_printf("\tDisplay Name = %s\n", config
.displayname
);
418 rpccli_svcctl_CloseServiceHandle(pipe_hnd
, mem_ctx
, &hService
, NULL
);
419 rpccli_svcctl_CloseServiceHandle(pipe_hnd
, mem_ctx
, &hSCM
, NULL
);
421 return werror_to_ntstatus(result
);
424 /********************************************************************
425 ********************************************************************/
427 static NTSTATUS
rpc_service_stop_internal(struct net_context
*c
,
428 const DOM_SID
*domain_sid
,
429 const char *domain_name
,
430 struct cli_state
*cli
,
431 struct rpc_pipe_client
*pipe_hnd
,
437 WERROR result
= WERR_GENERAL_FAILURE
;
442 d_printf("Usage: net rpc service status <service>\n");
446 fstrcpy( servicename
, argv
[0] );
448 /* Open the Service Control Manager */
449 status
= rpccli_svcctl_OpenSCManagerW(pipe_hnd
, mem_ctx
,
450 pipe_hnd
->srv_name_slash
,
452 SC_RIGHT_MGR_ENUMERATE_SERVICE
,
455 if (!NT_STATUS_IS_OK(status
) || !W_ERROR_IS_OK(result
)) {
456 d_fprintf(stderr
, "Failed to open Service Control Manager. [%s]\n", win_errstr(result
));
457 return werror_to_ntstatus(result
);
460 result
= control_service(pipe_hnd
, mem_ctx
, &hSCM
, servicename
,
461 SVCCTL_CONTROL_STOP
, SVCCTL_STOPPED
);
463 rpccli_svcctl_CloseServiceHandle(pipe_hnd
, mem_ctx
, &hSCM
, NULL
);
465 return werror_to_ntstatus(result
);
468 /********************************************************************
469 ********************************************************************/
471 static NTSTATUS
rpc_service_pause_internal(struct net_context
*c
,
472 const DOM_SID
*domain_sid
,
473 const char *domain_name
,
474 struct cli_state
*cli
,
475 struct rpc_pipe_client
*pipe_hnd
,
481 WERROR result
= WERR_GENERAL_FAILURE
;
486 d_printf("Usage: net rpc service status <service>\n");
490 fstrcpy( servicename
, argv
[0] );
492 /* Open the Service Control Manager */
493 status
= rpccli_svcctl_OpenSCManagerW(pipe_hnd
, mem_ctx
,
494 pipe_hnd
->srv_name_slash
,
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", win_errstr(result
));
501 return werror_to_ntstatus(result
);
504 result
= control_service(pipe_hnd
, mem_ctx
, &hSCM
, servicename
,
505 SVCCTL_CONTROL_PAUSE
, SVCCTL_PAUSED
);
507 rpccli_svcctl_CloseServiceHandle(pipe_hnd
, mem_ctx
, &hSCM
, NULL
);
509 return werror_to_ntstatus(result
);
512 /********************************************************************
513 ********************************************************************/
515 static NTSTATUS
rpc_service_resume_internal(struct net_context
*c
,
516 const DOM_SID
*domain_sid
,
517 const char *domain_name
,
518 struct cli_state
*cli
,
519 struct rpc_pipe_client
*pipe_hnd
,
525 WERROR result
= WERR_GENERAL_FAILURE
;
530 d_printf("Usage: net rpc service status <service>\n");
534 fstrcpy( servicename
, argv
[0] );
536 /* Open the Service Control Manager */
537 status
= rpccli_svcctl_OpenSCManagerW(pipe_hnd
, mem_ctx
,
538 pipe_hnd
->srv_name_slash
,
540 SC_RIGHT_MGR_ENUMERATE_SERVICE
,
543 if (!NT_STATUS_IS_OK(status
) || !W_ERROR_IS_OK(result
)) {
544 d_fprintf(stderr
, "Failed to open Service Control Manager. [%s]\n", win_errstr(result
));
545 return werror_to_ntstatus(result
);
548 result
= control_service(pipe_hnd
, mem_ctx
, &hSCM
, servicename
,
549 SVCCTL_CONTROL_CONTINUE
, SVCCTL_RUNNING
);
551 rpccli_svcctl_CloseServiceHandle(pipe_hnd
, mem_ctx
, &hSCM
, NULL
);
553 return werror_to_ntstatus(result
);
556 /********************************************************************
557 ********************************************************************/
559 static NTSTATUS
rpc_service_start_internal(struct net_context
*c
,
560 const DOM_SID
*domain_sid
,
561 const char *domain_name
,
562 struct cli_state
*cli
,
563 struct rpc_pipe_client
*pipe_hnd
,
568 POLICY_HND hSCM
, hService
;
569 WERROR result
= WERR_GENERAL_FAILURE
;
574 d_printf("Usage: net rpc service status <service>\n");
578 /* Open the Service Control Manager */
579 status
= rpccli_svcctl_OpenSCManagerW(pipe_hnd
, mem_ctx
,
580 pipe_hnd
->srv_name_slash
,
582 SC_RIGHT_MGR_ENUMERATE_SERVICE
,
585 if (!NT_STATUS_IS_OK(status
) || !W_ERROR_IS_OK(result
)) {
586 d_fprintf(stderr
, "Failed to open Service Control Manager. [%s]\n", win_errstr(result
));
587 return werror_to_ntstatus(result
);
590 /* Open the Service */
592 status
= rpccli_svcctl_OpenServiceW(pipe_hnd
, mem_ctx
,
599 if (!NT_STATUS_IS_OK(status
) || !W_ERROR_IS_OK(result
) ) {
600 d_fprintf(stderr
, "Failed to open service. [%s]\n", win_errstr(result
));
606 status
= rpccli_svcctl_StartServiceW(pipe_hnd
, mem_ctx
,
612 if (!NT_STATUS_IS_OK(status
) || !W_ERROR_IS_OK(result
) ) {
613 d_fprintf(stderr
, "Query status request failed. [%s]\n", win_errstr(result
));
617 result
= watch_service_state(pipe_hnd
, mem_ctx
, &hSCM
, argv
[0], SVCCTL_RUNNING
, &state
);
619 if ( W_ERROR_IS_OK(result
) && (state
== SVCCTL_RUNNING
) )
620 d_printf("Successfully started service: %s\n", argv
[0] );
622 d_fprintf(stderr
, "Failed to start service: %s [%s]\n", argv
[0], win_errstr(result
) );
625 rpccli_svcctl_CloseServiceHandle(pipe_hnd
, mem_ctx
, &hService
, NULL
);
626 rpccli_svcctl_CloseServiceHandle(pipe_hnd
, mem_ctx
, &hSCM
, NULL
);
628 return werror_to_ntstatus(result
);
631 /********************************************************************
632 ********************************************************************/
634 static int rpc_service_list(struct net_context
*c
, int argc
, const char **argv
)
636 if (c
->display_usage
) {
638 "net rpc service list\n"
639 " View configured Win32 services\n");
643 return run_rpc_command(c
, NULL
, &ndr_table_svcctl
.syntax_id
, 0,
644 rpc_service_list_internal
, argc
, argv
);
647 /********************************************************************
648 ********************************************************************/
650 static int rpc_service_start(struct net_context
*c
, int argc
, const char **argv
)
652 if (c
->display_usage
) {
654 "net rpc service start <service>\n"
655 " Start a Win32 service\n");
659 return run_rpc_command(c
, NULL
, &ndr_table_svcctl
.syntax_id
, 0,
660 rpc_service_start_internal
, argc
, argv
);
663 /********************************************************************
664 ********************************************************************/
666 static int rpc_service_stop(struct net_context
*c
, int argc
, const char **argv
)
668 if (c
->display_usage
) {
670 "net rpc service stop <service>\n"
671 " Stop a Win32 service\n");
675 return run_rpc_command(c
, NULL
, &ndr_table_svcctl
.syntax_id
, 0,
676 rpc_service_stop_internal
, argc
, argv
);
679 /********************************************************************
680 ********************************************************************/
682 static int rpc_service_resume(struct net_context
*c
, int argc
, const char **argv
)
684 if (c
->display_usage
) {
686 "net rpc service resume <service>\n"
687 " Resume a Win32 service\n");
691 return run_rpc_command(c
, NULL
, &ndr_table_svcctl
.syntax_id
, 0,
692 rpc_service_resume_internal
, argc
, argv
);
695 /********************************************************************
696 ********************************************************************/
698 static int rpc_service_pause(struct net_context
*c
, int argc
, const char **argv
)
700 if (c
->display_usage
) {
702 "net rpc service pause <service>\n"
703 " Pause a Win32 service\n");
707 return run_rpc_command(c
, NULL
, &ndr_table_svcctl
.syntax_id
, 0,
708 rpc_service_pause_internal
, argc
, argv
);
711 /********************************************************************
712 ********************************************************************/
714 static int rpc_service_status(struct net_context
*c
, int argc
, const char **argv
)
716 if (c
->display_usage
) {
718 "net rpc service status <service>\n"
719 " Show the current status of a service\n");
723 return run_rpc_command(c
, NULL
, &ndr_table_svcctl
.syntax_id
, 0,
724 rpc_service_status_internal
, argc
, argv
);
727 /********************************************************************
728 ********************************************************************/
730 int net_rpc_service(struct net_context
*c
, int argc
, const char **argv
)
732 struct functable func
[] = {
737 "View configured Win32 services",
738 "net rpc service list\n"
739 " View configured Win32 services"
746 "net rpc service start\n"
754 "net rpc service stop\n"
762 "net rpc service pause\n"
769 "Resume a paused service",
770 "net rpc service resume\n"
777 "View current status of a service",
778 "net rpc service status\n"
779 " View current status of a service"
781 {NULL
, NULL
, 0, NULL
, NULL
}
784 return net_run_function(c
, argc
, argv
, "net rpc service",func
);