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,
64 struct policy_handle *hSCM,
68 struct policy_handle hService;
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,
105 struct policy_handle *hSCM,
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,
140 struct policy_handle *hSCM,
145 struct policy_handle hService;
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,
202 struct policy_handle hSCM;
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 struct policy_handle 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,
436 struct policy_handle hSCM;
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,
480 struct policy_handle hSCM;
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,
524 struct policy_handle hSCM;
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 struct policy_handle 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);