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 status
= rpccli_svcctl_QueryServiceStatus(pipe_hnd
, mem_ctx
,
58 if (!NT_STATUS_IS_OK(status
) || !W_ERROR_IS_OK(result
) ) {
59 *state
= service_status
.state
;
62 rpccli_svcctl_CloseServiceHandle(pipe_hnd
, mem_ctx
, &hService
, NULL
);
67 /********************************************************************
68 ********************************************************************/
70 static WERROR
watch_service_state(struct rpc_pipe_client
*pipe_hnd
,
79 WERROR result
= WERR_GENERAL_FAILURE
;
83 while ( (state
!= watch_state
) && i
<30 ) {
86 result
= query_service_state(pipe_hnd
, mem_ctx
, hSCM
, service
, &state
);
87 if ( !W_ERROR_IS_OK(result
) ) {
102 /********************************************************************
103 ********************************************************************/
105 static WERROR
control_service(struct rpc_pipe_client
*pipe_hnd
,
113 WERROR result
= WERR_GENERAL_FAILURE
;
115 SERVICE_STATUS service_status
;
118 /* Open the Service */
120 status
= rpccli_svcctl_OpenServiceW(pipe_hnd
, mem_ctx
,
123 (SC_RIGHT_SVC_STOP
|SC_RIGHT_SVC_PAUSE_CONTINUE
),
127 if (!NT_STATUS_IS_OK(status
) || !W_ERROR_IS_OK(result
) ) {
128 d_fprintf(stderr
, "Failed to open service. [%s]\n", dos_errstr(result
));
134 status
= rpccli_svcctl_ControlService(pipe_hnd
, mem_ctx
,
140 if (!NT_STATUS_IS_OK(status
) || !W_ERROR_IS_OK(result
) ) {
141 d_fprintf(stderr
, "Control service request failed. [%s]\n", dos_errstr(result
));
145 /* loop -- checking the state until we are where we want to be */
147 result
= watch_service_state(pipe_hnd
, mem_ctx
, hSCM
, service
, watch_state
, &state
);
149 d_printf("%s service is %s.\n", service
, svc_status_string(state
));
152 rpccli_svcctl_CloseServiceHandle(pipe_hnd
, mem_ctx
, &hService
, NULL
);
157 /********************************************************************
158 ********************************************************************/
160 static NTSTATUS
rpc_service_list_internal(const DOM_SID
*domain_sid
,
161 const char *domain_name
,
162 struct cli_state
*cli
,
163 struct rpc_pipe_client
*pipe_hnd
,
169 ENUM_SERVICES_STATUS
*services
;
170 WERROR result
= WERR_GENERAL_FAILURE
;
174 uint32 num_services
= 0;
175 const char *server_name
;
179 d_printf("Usage: net rpc service list\n");
183 CLI_SERVER_NAME_SLASH(mem_ctx
, server_name
, pipe_hnd
);
184 NT_STATUS_HAVE_NO_MEMORY(server_name
);
186 status
= rpccli_svcctl_OpenSCManagerW(pipe_hnd
, mem_ctx
,
189 SC_RIGHT_MGR_ENUMERATE_SERVICE
,
192 if (!NT_STATUS_IS_OK(status
) || !W_ERROR_IS_OK(result
)) {
193 d_fprintf(stderr
, "Failed to open Service Control Manager. [%s]\n", dos_errstr(result
));
194 return werror_to_ntstatus(result
);
197 result
= rpccli_svcctl_enumerate_services(pipe_hnd
, mem_ctx
, &hSCM
, SVCCTL_TYPE_WIN32
,
198 SVCCTL_STATE_ALL
, &num_services
, &services
);
200 if ( !W_ERROR_IS_OK(result
) ) {
201 d_fprintf(stderr
, "Failed to enumerate services. [%s]\n", dos_errstr(result
));
205 if ( num_services
== 0 )
206 d_printf("No services returned\n");
208 for ( i
=0; i
<num_services
; i
++ ) {
209 rpcstr_pull( servicename
, services
[i
].servicename
.buffer
, sizeof(servicename
), -1, STR_TERMINATE
);
210 rpcstr_pull( displayname
, services
[i
].displayname
.buffer
, sizeof(displayname
), -1, STR_TERMINATE
);
212 d_printf("%-20s \"%s\"\n", servicename
, displayname
);
216 rpccli_svcctl_CloseServiceHandle(pipe_hnd
, mem_ctx
, &hSCM
, NULL
);
218 return werror_to_ntstatus(result
);
221 /********************************************************************
222 ********************************************************************/
224 static NTSTATUS
rpc_service_status_internal(const DOM_SID
*domain_sid
,
225 const char *domain_name
,
226 struct cli_state
*cli
,
227 struct rpc_pipe_client
*pipe_hnd
,
232 POLICY_HND hSCM
, hService
;
233 WERROR result
= WERR_GENERAL_FAILURE
;
235 SERVICE_STATUS service_status
;
236 SERVICE_CONFIG config
;
237 fstring ascii_string
;
238 const char *server_name
;
241 d_printf("Usage: net rpc service status <service>\n");
245 /* Open the Service Control Manager */
246 CLI_SERVER_NAME_SLASH(mem_ctx
, server_name
, pipe_hnd
);
247 NT_STATUS_HAVE_NO_MEMORY(server_name
);
249 status
= rpccli_svcctl_OpenSCManagerW(pipe_hnd
, mem_ctx
,
252 SC_RIGHT_MGR_ENUMERATE_SERVICE
,
255 if (!NT_STATUS_IS_OK(status
) || !W_ERROR_IS_OK(result
)) {
256 d_fprintf(stderr
, "Failed to open Service Control Manager. [%s]\n", dos_errstr(result
));
257 return werror_to_ntstatus(result
);
260 /* Open the Service */
262 status
= rpccli_svcctl_OpenServiceW(pipe_hnd
, mem_ctx
,
265 (SC_RIGHT_SVC_QUERY_STATUS
|SC_RIGHT_SVC_QUERY_CONFIG
),
269 if (!NT_STATUS_IS_OK(status
) || !W_ERROR_IS_OK(result
) ) {
270 d_fprintf(stderr
, "Failed to open service. [%s]\n", dos_errstr(result
));
276 status
= rpccli_svcctl_QueryServiceStatus(pipe_hnd
, mem_ctx
,
281 if (!NT_STATUS_IS_OK(status
) || !W_ERROR_IS_OK(result
) ) {
282 d_fprintf(stderr
, "Query status request failed. [%s]\n", dos_errstr(result
));
286 d_printf("%s service is %s.\n", argv
[0], svc_status_string(service_status
.state
));
290 result
= rpccli_svcctl_query_config(pipe_hnd
, mem_ctx
, &hService
, &config
);
291 if ( !W_ERROR_IS_OK(result
) ) {
292 d_fprintf(stderr
, "Query config request failed. [%s]\n", dos_errstr(result
));
296 /* print out the configuration information for the service */
298 d_printf("Configuration details:\n");
299 d_printf("\tControls Accepted = 0x%x\n", service_status
.controls_accepted
);
300 d_printf("\tService Type = 0x%x\n", config
.service_type
);
301 d_printf("\tStart Type = 0x%x\n", config
.start_type
);
302 d_printf("\tError Control = 0x%x\n", config
.error_control
);
303 d_printf("\tTag ID = 0x%x\n", config
.tag_id
);
305 if ( config
.executablepath
) {
306 rpcstr_pull( ascii_string
, config
.executablepath
->buffer
, sizeof(ascii_string
), -1, STR_TERMINATE
);
307 d_printf("\tExecutable Path = %s\n", ascii_string
);
310 if ( config
.loadordergroup
) {
311 rpcstr_pull( ascii_string
, config
.loadordergroup
->buffer
, sizeof(ascii_string
), -1, STR_TERMINATE
);
312 d_printf("\tLoad Order Group = %s\n", ascii_string
);
315 if ( config
.dependencies
) {
316 rpcstr_pull( ascii_string
, config
.dependencies
->buffer
, sizeof(ascii_string
), -1, STR_TERMINATE
);
317 d_printf("\tDependencies = %s\n", ascii_string
);
320 if ( config
.startname
) {
321 rpcstr_pull( ascii_string
, config
.startname
->buffer
, sizeof(ascii_string
), -1, STR_TERMINATE
);
322 d_printf("\tStart Name = %s\n", ascii_string
);
325 if ( config
.displayname
) {
326 rpcstr_pull( ascii_string
, config
.displayname
->buffer
, sizeof(ascii_string
), -1, STR_TERMINATE
);
327 d_printf("\tDisplay Name = %s\n", ascii_string
);
331 rpccli_svcctl_CloseServiceHandle(pipe_hnd
, mem_ctx
, &hService
, NULL
);
332 rpccli_svcctl_CloseServiceHandle(pipe_hnd
, mem_ctx
, &hSCM
, NULL
);
334 return werror_to_ntstatus(result
);
337 /********************************************************************
338 ********************************************************************/
340 static NTSTATUS
rpc_service_stop_internal(const DOM_SID
*domain_sid
,
341 const char *domain_name
,
342 struct cli_state
*cli
,
343 struct rpc_pipe_client
*pipe_hnd
,
349 WERROR result
= WERR_GENERAL_FAILURE
;
352 const char *server_name
;
355 d_printf("Usage: net rpc service status <service>\n");
359 fstrcpy( servicename
, argv
[0] );
361 /* Open the Service Control Manager */
362 CLI_SERVER_NAME_SLASH(mem_ctx
, server_name
, pipe_hnd
);
363 NT_STATUS_HAVE_NO_MEMORY(server_name
);
365 status
= rpccli_svcctl_OpenSCManagerW(pipe_hnd
, mem_ctx
,
368 SC_RIGHT_MGR_ENUMERATE_SERVICE
,
371 if (!NT_STATUS_IS_OK(status
) || !W_ERROR_IS_OK(result
)) {
372 d_fprintf(stderr
, "Failed to open Service Control Manager. [%s]\n", dos_errstr(result
));
373 return werror_to_ntstatus(result
);
376 result
= control_service(pipe_hnd
, mem_ctx
, &hSCM
, servicename
,
377 SVCCTL_CONTROL_STOP
, SVCCTL_STOPPED
);
379 rpccli_svcctl_CloseServiceHandle(pipe_hnd
, mem_ctx
, &hSCM
, NULL
);
381 return werror_to_ntstatus(result
);
384 /********************************************************************
385 ********************************************************************/
387 static NTSTATUS
rpc_service_pause_internal(const DOM_SID
*domain_sid
,
388 const char *domain_name
,
389 struct cli_state
*cli
,
390 struct rpc_pipe_client
*pipe_hnd
,
396 WERROR result
= WERR_GENERAL_FAILURE
;
399 const char *server_name
;
402 d_printf("Usage: net rpc service status <service>\n");
406 fstrcpy( servicename
, argv
[0] );
408 /* Open the Service Control Manager */
409 CLI_SERVER_NAME_SLASH(mem_ctx
, server_name
, pipe_hnd
);
410 NT_STATUS_HAVE_NO_MEMORY(server_name
);
412 status
= rpccli_svcctl_OpenSCManagerW(pipe_hnd
, mem_ctx
,
415 SC_RIGHT_MGR_ENUMERATE_SERVICE
,
418 if (!NT_STATUS_IS_OK(status
) || !W_ERROR_IS_OK(result
)) {
419 d_fprintf(stderr
, "Failed to open Service Control Manager. [%s]\n", dos_errstr(result
));
420 return werror_to_ntstatus(result
);
423 result
= control_service(pipe_hnd
, mem_ctx
, &hSCM
, servicename
,
424 SVCCTL_CONTROL_PAUSE
, SVCCTL_PAUSED
);
426 rpccli_svcctl_CloseServiceHandle(pipe_hnd
, mem_ctx
, &hSCM
, NULL
);
428 return werror_to_ntstatus(result
);
431 /********************************************************************
432 ********************************************************************/
434 static NTSTATUS
rpc_service_resume_internal(const DOM_SID
*domain_sid
,
435 const char *domain_name
,
436 struct cli_state
*cli
,
437 struct rpc_pipe_client
*pipe_hnd
,
443 WERROR result
= WERR_GENERAL_FAILURE
;
446 const char *server_name
;
449 d_printf("Usage: net rpc service status <service>\n");
453 fstrcpy( servicename
, argv
[0] );
455 /* Open the Service Control Manager */
456 CLI_SERVER_NAME_SLASH(mem_ctx
, server_name
, pipe_hnd
);
457 NT_STATUS_HAVE_NO_MEMORY(server_name
);
459 status
= rpccli_svcctl_OpenSCManagerW(pipe_hnd
, mem_ctx
,
462 SC_RIGHT_MGR_ENUMERATE_SERVICE
,
465 if (!NT_STATUS_IS_OK(status
) || !W_ERROR_IS_OK(result
)) {
466 d_fprintf(stderr
, "Failed to open Service Control Manager. [%s]\n", dos_errstr(result
));
467 return werror_to_ntstatus(result
);
470 result
= control_service(pipe_hnd
, mem_ctx
, &hSCM
, servicename
,
471 SVCCTL_CONTROL_CONTINUE
, SVCCTL_RUNNING
);
473 rpccli_svcctl_CloseServiceHandle(pipe_hnd
, mem_ctx
, &hSCM
, NULL
);
475 return werror_to_ntstatus(result
);
478 /********************************************************************
479 ********************************************************************/
481 static NTSTATUS
rpc_service_start_internal(const DOM_SID
*domain_sid
,
482 const char *domain_name
,
483 struct cli_state
*cli
,
484 struct rpc_pipe_client
*pipe_hnd
,
489 POLICY_HND hSCM
, hService
;
490 WERROR result
= WERR_GENERAL_FAILURE
;
493 const char *server_name
;
496 d_printf("Usage: net rpc service status <service>\n");
500 /* Open the Service Control Manager */
501 CLI_SERVER_NAME_SLASH(mem_ctx
, server_name
, pipe_hnd
);
502 NT_STATUS_HAVE_NO_MEMORY(server_name
);
504 status
= rpccli_svcctl_OpenSCManagerW(pipe_hnd
, mem_ctx
,
507 SC_RIGHT_MGR_ENUMERATE_SERVICE
,
510 if (!NT_STATUS_IS_OK(status
) || !W_ERROR_IS_OK(result
)) {
511 d_fprintf(stderr
, "Failed to open Service Control Manager. [%s]\n", dos_errstr(result
));
512 return werror_to_ntstatus(result
);
515 /* Open the Service */
517 status
= rpccli_svcctl_OpenServiceW(pipe_hnd
, mem_ctx
,
524 if (!NT_STATUS_IS_OK(status
) || !W_ERROR_IS_OK(result
) ) {
525 d_fprintf(stderr
, "Failed to open service. [%s]\n", dos_errstr(result
));
531 status
= rpccli_svcctl_StartServiceW(pipe_hnd
, mem_ctx
,
537 if (!NT_STATUS_IS_OK(status
) || !W_ERROR_IS_OK(result
) ) {
538 d_fprintf(stderr
, "Query status request failed. [%s]\n", dos_errstr(result
));
542 result
= watch_service_state(pipe_hnd
, mem_ctx
, &hSCM
, argv
[0], SVCCTL_RUNNING
, &state
);
544 if ( W_ERROR_IS_OK(result
) && (state
== SVCCTL_RUNNING
) )
545 d_printf("Successfully started service: %s\n", argv
[0] );
547 d_fprintf(stderr
, "Failed to start service: %s [%s]\n", argv
[0], dos_errstr(result
) );
550 rpccli_svcctl_CloseServiceHandle(pipe_hnd
, mem_ctx
, &hService
, NULL
);
551 rpccli_svcctl_CloseServiceHandle(pipe_hnd
, mem_ctx
, &hSCM
, NULL
);
553 return werror_to_ntstatus(result
);
556 /********************************************************************
557 ********************************************************************/
559 static int rpc_service_list( int argc
, const char **argv
)
561 return run_rpc_command( NULL
, PI_SVCCTL
, 0,
562 rpc_service_list_internal
, argc
, argv
);
565 /********************************************************************
566 ********************************************************************/
568 static int rpc_service_start( int argc
, const char **argv
)
570 return run_rpc_command( NULL
, PI_SVCCTL
, 0,
571 rpc_service_start_internal
, argc
, argv
);
574 /********************************************************************
575 ********************************************************************/
577 static int rpc_service_stop( int argc
, const char **argv
)
579 return run_rpc_command( NULL
, PI_SVCCTL
, 0,
580 rpc_service_stop_internal
, argc
, argv
);
583 /********************************************************************
584 ********************************************************************/
586 static int rpc_service_resume( int argc
, const char **argv
)
588 return run_rpc_command( NULL
, PI_SVCCTL
, 0,
589 rpc_service_resume_internal
, argc
, argv
);
592 /********************************************************************
593 ********************************************************************/
595 static int rpc_service_pause( int argc
, const char **argv
)
597 return run_rpc_command( NULL
, PI_SVCCTL
, 0,
598 rpc_service_pause_internal
, argc
, argv
);
601 /********************************************************************
602 ********************************************************************/
604 static int rpc_service_status( int argc
, const char **argv
)
606 return run_rpc_command( NULL
, PI_SVCCTL
, 0,
607 rpc_service_status_internal
, argc
, argv
);
610 /********************************************************************
611 ********************************************************************/
613 static int net_help_service( int argc
, const char **argv
)
615 d_printf("net rpc service list View configured Win32 services\n");
616 d_printf("net rpc service start <service> Start a service\n");
617 d_printf("net rpc service stop <service> Stop a service\n");
618 d_printf("net rpc service pause <service> Pause a service\n");
619 d_printf("net rpc service resume <service> Resume a paused service\n");
620 d_printf("net rpc service status <service> View the current status of a service\n");
625 /********************************************************************
626 ********************************************************************/
628 int net_rpc_service(int argc
, const char **argv
)
630 struct functable func
[] = {
631 {"list", rpc_service_list
},
632 {"start", rpc_service_start
},
633 {"stop", rpc_service_stop
},
634 {"pause", rpc_service_pause
},
635 {"resume", rpc_service_resume
},
636 {"status", rpc_service_status
},
641 return net_run_function( argc
, argv
, func
, net_help_service
);
643 return net_help_service( argc
, argv
);