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 );