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 /********************************************************************
24 ********************************************************************/
26 static WERROR
query_service_state(struct rpc_pipe_client
*pipe_hnd
,
33 SERVICE_STATUS service_status
;
34 WERROR result
= WERR_GENERAL_FAILURE
;
36 /* now cycle until the status is actually 'watch_state' */
38 result
= rpccli_svcctl_open_service(pipe_hnd
, mem_ctx
, hSCM
, &hService
,
39 service
, SC_RIGHT_SVC_QUERY_STATUS
);
41 if ( !W_ERROR_IS_OK(result
) ) {
42 d_fprintf(stderr
, "Failed to open service. [%s]\n", dos_errstr(result
));
46 result
= rpccli_svcctl_query_status(pipe_hnd
, mem_ctx
, &hService
, &service_status
);
47 if ( W_ERROR_IS_OK(result
) ) {
48 *state
= service_status
.state
;
51 rpccli_svcctl_CloseServiceHandle(pipe_hnd
, mem_ctx
, &hService
);
56 /********************************************************************
57 ********************************************************************/
59 static WERROR
watch_service_state(struct rpc_pipe_client
*pipe_hnd
,
68 WERROR result
= WERR_GENERAL_FAILURE
;
72 while ( (state
!= watch_state
) && i
<30 ) {
75 result
= query_service_state(pipe_hnd
, mem_ctx
, hSCM
, service
, &state
);
76 if ( !W_ERROR_IS_OK(result
) ) {
91 /********************************************************************
92 ********************************************************************/
94 static WERROR
control_service(struct rpc_pipe_client
*pipe_hnd
,
102 WERROR result
= WERR_GENERAL_FAILURE
;
103 SERVICE_STATUS service_status
;
106 /* Open the Service */
108 result
= rpccli_svcctl_open_service(pipe_hnd
, mem_ctx
, hSCM
, &hService
,
109 service
, (SC_RIGHT_SVC_STOP
|SC_RIGHT_SVC_PAUSE_CONTINUE
) );
111 if ( !W_ERROR_IS_OK(result
) ) {
112 d_fprintf(stderr
, "Failed to open service. [%s]\n", dos_errstr(result
));
118 result
= rpccli_svcctl_control_service(pipe_hnd
, mem_ctx
, &hService
,
119 control
, &service_status
);
121 if ( !W_ERROR_IS_OK(result
) ) {
122 d_fprintf(stderr
, "Control service request failed. [%s]\n", dos_errstr(result
));
126 /* loop -- checking the state until we are where we want to be */
128 result
= watch_service_state(pipe_hnd
, mem_ctx
, hSCM
, service
, watch_state
, &state
);
130 d_printf("%s service is %s.\n", service
, svc_status_string(state
));
133 rpccli_svcctl_CloseServiceHandle(pipe_hnd
, mem_ctx
, &hService
);
138 /********************************************************************
139 ********************************************************************/
141 static NTSTATUS
rpc_service_list_internal(const DOM_SID
*domain_sid
,
142 const char *domain_name
,
143 struct cli_state
*cli
,
144 struct rpc_pipe_client
*pipe_hnd
,
150 ENUM_SERVICES_STATUS
*services
;
151 WERROR result
= WERR_GENERAL_FAILURE
;
154 uint32 num_services
= 0;
158 d_printf("Usage: net rpc service list\n");
162 result
= rpccli_svcctl_open_scm(pipe_hnd
, mem_ctx
, &hSCM
, SC_RIGHT_MGR_ENUMERATE_SERVICE
);
163 if ( !W_ERROR_IS_OK(result
) ) {
164 d_fprintf(stderr
, "Failed to open Service Control Manager. [%s]\n", dos_errstr(result
));
165 return werror_to_ntstatus(result
);
168 result
= rpccli_svcctl_enumerate_services(pipe_hnd
, mem_ctx
, &hSCM
, SVCCTL_TYPE_WIN32
,
169 SVCCTL_STATE_ALL
, &num_services
, &services
);
171 if ( !W_ERROR_IS_OK(result
) ) {
172 d_fprintf(stderr
, "Failed to enumerate services. [%s]\n", dos_errstr(result
));
176 if ( num_services
== 0 )
177 d_printf("No services returned\n");
179 for ( i
=0; i
<num_services
; i
++ ) {
180 rpcstr_pull( servicename
, services
[i
].servicename
.buffer
, sizeof(servicename
), -1, STR_TERMINATE
);
181 rpcstr_pull( displayname
, services
[i
].displayname
.buffer
, sizeof(displayname
), -1, STR_TERMINATE
);
183 d_printf("%-20s \"%s\"\n", servicename
, displayname
);
187 rpccli_svcctl_CloseServiceHandle(pipe_hnd
, mem_ctx
, &hSCM
);
189 return werror_to_ntstatus(result
);
192 /********************************************************************
193 ********************************************************************/
195 static NTSTATUS
rpc_service_status_internal(const DOM_SID
*domain_sid
,
196 const char *domain_name
,
197 struct cli_state
*cli
,
198 struct rpc_pipe_client
*pipe_hnd
,
203 POLICY_HND hSCM
, hService
;
204 WERROR result
= WERR_GENERAL_FAILURE
;
206 SERVICE_STATUS service_status
;
207 SERVICE_CONFIG config
;
208 fstring ascii_string
;
211 d_printf("Usage: net rpc service status <service>\n");
215 fstrcpy( servicename
, argv
[0] );
217 /* Open the Service Control Manager */
219 result
= rpccli_svcctl_open_scm(pipe_hnd
, mem_ctx
, &hSCM
, SC_RIGHT_MGR_ENUMERATE_SERVICE
);
220 if ( !W_ERROR_IS_OK(result
) ) {
221 d_fprintf(stderr
, "Failed to open Service Control Manager. [%s]\n", dos_errstr(result
));
222 return werror_to_ntstatus(result
);
225 /* Open the Service */
227 result
= rpccli_svcctl_open_service(pipe_hnd
, mem_ctx
, &hSCM
, &hService
, servicename
,
228 (SC_RIGHT_SVC_QUERY_STATUS
|SC_RIGHT_SVC_QUERY_CONFIG
) );
230 if ( !W_ERROR_IS_OK(result
) ) {
231 d_fprintf(stderr
, "Failed to open service. [%s]\n", dos_errstr(result
));
237 result
= rpccli_svcctl_query_status(pipe_hnd
, mem_ctx
, &hService
, &service_status
);
238 if ( !W_ERROR_IS_OK(result
) ) {
239 d_fprintf(stderr
, "Query status request failed. [%s]\n", dos_errstr(result
));
243 d_printf("%s service is %s.\n", servicename
, svc_status_string(service_status
.state
));
247 result
= rpccli_svcctl_query_config(pipe_hnd
, mem_ctx
, &hService
, &config
);
248 if ( !W_ERROR_IS_OK(result
) ) {
249 d_fprintf(stderr
, "Query config request failed. [%s]\n", dos_errstr(result
));
253 /* print out the configuration information for the service */
255 d_printf("Configuration details:\n");
256 d_printf("\tControls Accepted = 0x%x\n", service_status
.controls_accepted
);
257 d_printf("\tService Type = 0x%x\n", config
.service_type
);
258 d_printf("\tStart Type = 0x%x\n", config
.start_type
);
259 d_printf("\tError Control = 0x%x\n", config
.error_control
);
260 d_printf("\tTag ID = 0x%x\n", config
.tag_id
);
262 if ( config
.executablepath
) {
263 rpcstr_pull( ascii_string
, config
.executablepath
->buffer
, sizeof(ascii_string
), -1, STR_TERMINATE
);
264 d_printf("\tExecutable Path = %s\n", ascii_string
);
267 if ( config
.loadordergroup
) {
268 rpcstr_pull( ascii_string
, config
.loadordergroup
->buffer
, sizeof(ascii_string
), -1, STR_TERMINATE
);
269 d_printf("\tLoad Order Group = %s\n", ascii_string
);
272 if ( config
.dependencies
) {
273 rpcstr_pull( ascii_string
, config
.dependencies
->buffer
, sizeof(ascii_string
), -1, STR_TERMINATE
);
274 d_printf("\tDependencies = %s\n", ascii_string
);
277 if ( config
.startname
) {
278 rpcstr_pull( ascii_string
, config
.startname
->buffer
, sizeof(ascii_string
), -1, STR_TERMINATE
);
279 d_printf("\tStart Name = %s\n", ascii_string
);
282 if ( config
.displayname
) {
283 rpcstr_pull( ascii_string
, config
.displayname
->buffer
, sizeof(ascii_string
), -1, STR_TERMINATE
);
284 d_printf("\tDisplay Name = %s\n", ascii_string
);
288 rpccli_svcctl_CloseServiceHandle(pipe_hnd
, mem_ctx
, &hService
);
289 rpccli_svcctl_CloseServiceHandle(pipe_hnd
, mem_ctx
, &hSCM
);
291 return werror_to_ntstatus(result
);
294 /********************************************************************
295 ********************************************************************/
297 static NTSTATUS
rpc_service_stop_internal(const DOM_SID
*domain_sid
,
298 const char *domain_name
,
299 struct cli_state
*cli
,
300 struct rpc_pipe_client
*pipe_hnd
,
306 WERROR result
= WERR_GENERAL_FAILURE
;
310 d_printf("Usage: net rpc service status <service>\n");
314 fstrcpy( servicename
, argv
[0] );
316 /* Open the Service Control Manager */
318 result
= rpccli_svcctl_open_scm(pipe_hnd
, mem_ctx
, &hSCM
, SC_RIGHT_MGR_ENUMERATE_SERVICE
);
319 if ( !W_ERROR_IS_OK(result
) ) {
320 d_fprintf(stderr
, "Failed to open Service Control Manager. [%s]\n", dos_errstr(result
));
321 return werror_to_ntstatus(result
);
324 result
= control_service(pipe_hnd
, mem_ctx
, &hSCM
, servicename
,
325 SVCCTL_CONTROL_STOP
, SVCCTL_STOPPED
);
327 rpccli_svcctl_CloseServiceHandle(pipe_hnd
, mem_ctx
, &hSCM
);
329 return werror_to_ntstatus(result
);
332 /********************************************************************
333 ********************************************************************/
335 static NTSTATUS
rpc_service_pause_internal(const DOM_SID
*domain_sid
,
336 const char *domain_name
,
337 struct cli_state
*cli
,
338 struct rpc_pipe_client
*pipe_hnd
,
344 WERROR result
= WERR_GENERAL_FAILURE
;
348 d_printf("Usage: net rpc service status <service>\n");
352 fstrcpy( servicename
, argv
[0] );
354 /* Open the Service Control Manager */
356 result
= rpccli_svcctl_open_scm(pipe_hnd
, mem_ctx
, &hSCM
, SC_RIGHT_MGR_ENUMERATE_SERVICE
);
357 if ( !W_ERROR_IS_OK(result
) ) {
358 d_fprintf(stderr
, "Failed to open Service Control Manager. [%s]\n", dos_errstr(result
));
359 return werror_to_ntstatus(result
);
362 result
= control_service(pipe_hnd
, mem_ctx
, &hSCM
, servicename
,
363 SVCCTL_CONTROL_PAUSE
, SVCCTL_PAUSED
);
365 rpccli_svcctl_CloseServiceHandle(pipe_hnd
, mem_ctx
, &hSCM
);
367 return werror_to_ntstatus(result
);
370 /********************************************************************
371 ********************************************************************/
373 static NTSTATUS
rpc_service_resume_internal(const DOM_SID
*domain_sid
,
374 const char *domain_name
,
375 struct cli_state
*cli
,
376 struct rpc_pipe_client
*pipe_hnd
,
382 WERROR result
= WERR_GENERAL_FAILURE
;
386 d_printf("Usage: net rpc service status <service>\n");
390 fstrcpy( servicename
, argv
[0] );
392 /* Open the Service Control Manager */
394 result
= rpccli_svcctl_open_scm(pipe_hnd
, mem_ctx
, &hSCM
, SC_RIGHT_MGR_ENUMERATE_SERVICE
);
395 if ( !W_ERROR_IS_OK(result
) ) {
396 d_fprintf(stderr
, "Failed to open Service Control Manager. [%s]\n", dos_errstr(result
));
397 return werror_to_ntstatus(result
);
400 result
= control_service(pipe_hnd
, mem_ctx
, &hSCM
, servicename
,
401 SVCCTL_CONTROL_CONTINUE
, SVCCTL_RUNNING
);
403 rpccli_svcctl_CloseServiceHandle(pipe_hnd
, mem_ctx
, &hSCM
);
405 return werror_to_ntstatus(result
);
408 /********************************************************************
409 ********************************************************************/
411 static NTSTATUS
rpc_service_start_internal(const DOM_SID
*domain_sid
,
412 const char *domain_name
,
413 struct cli_state
*cli
,
414 struct rpc_pipe_client
*pipe_hnd
,
419 POLICY_HND hSCM
, hService
;
420 WERROR result
= WERR_GENERAL_FAILURE
;
425 d_printf("Usage: net rpc service status <service>\n");
429 fstrcpy( servicename
, argv
[0] );
431 /* Open the Service Control Manager */
433 result
= rpccli_svcctl_open_scm( pipe_hnd
, mem_ctx
, &hSCM
, SC_RIGHT_MGR_ENUMERATE_SERVICE
);
434 if ( !W_ERROR_IS_OK(result
) ) {
435 d_fprintf(stderr
, "Failed to open Service Control Manager. [%s]\n", dos_errstr(result
));
436 return werror_to_ntstatus(result
);
439 /* Open the Service */
441 result
= rpccli_svcctl_open_service(pipe_hnd
, mem_ctx
, &hSCM
, &hService
,
442 servicename
, SC_RIGHT_SVC_START
);
444 if ( !W_ERROR_IS_OK(result
) ) {
445 d_fprintf(stderr
, "Failed to open service. [%s]\n", dos_errstr(result
));
451 result
= rpccli_svcctl_start_service(pipe_hnd
, mem_ctx
, &hService
, NULL
, 0 );
452 if ( !W_ERROR_IS_OK(result
) ) {
453 d_fprintf(stderr
, "Query status request failed. [%s]\n", dos_errstr(result
));
457 result
= watch_service_state(pipe_hnd
, mem_ctx
, &hSCM
, servicename
, SVCCTL_RUNNING
, &state
);
459 if ( W_ERROR_IS_OK(result
) && (state
== SVCCTL_RUNNING
) )
460 d_printf("Successfully started service: %s\n", servicename
);
462 d_fprintf(stderr
, "Failed to start service: %s [%s]\n", servicename
, dos_errstr(result
) );
465 rpccli_svcctl_CloseServiceHandle(pipe_hnd
, mem_ctx
, &hService
);
466 rpccli_svcctl_CloseServiceHandle(pipe_hnd
, mem_ctx
, &hSCM
);
468 return werror_to_ntstatus(result
);
471 /********************************************************************
472 ********************************************************************/
474 static int rpc_service_list( int argc
, const char **argv
)
476 return run_rpc_command( NULL
, PI_SVCCTL
, 0,
477 rpc_service_list_internal
, argc
, argv
);
480 /********************************************************************
481 ********************************************************************/
483 static int rpc_service_start( int argc
, const char **argv
)
485 return run_rpc_command( NULL
, PI_SVCCTL
, 0,
486 rpc_service_start_internal
, argc
, argv
);
489 /********************************************************************
490 ********************************************************************/
492 static int rpc_service_stop( int argc
, const char **argv
)
494 return run_rpc_command( NULL
, PI_SVCCTL
, 0,
495 rpc_service_stop_internal
, argc
, argv
);
498 /********************************************************************
499 ********************************************************************/
501 static int rpc_service_resume( int argc
, const char **argv
)
503 return run_rpc_command( NULL
, PI_SVCCTL
, 0,
504 rpc_service_resume_internal
, argc
, argv
);
507 /********************************************************************
508 ********************************************************************/
510 static int rpc_service_pause( int argc
, const char **argv
)
512 return run_rpc_command( NULL
, PI_SVCCTL
, 0,
513 rpc_service_pause_internal
, argc
, argv
);
516 /********************************************************************
517 ********************************************************************/
519 static int rpc_service_status( int argc
, const char **argv
)
521 return run_rpc_command( NULL
, PI_SVCCTL
, 0,
522 rpc_service_status_internal
, argc
, argv
);
525 /********************************************************************
526 ********************************************************************/
528 static int net_help_service( int argc
, const char **argv
)
530 d_printf("net rpc service list View configured Win32 services\n");
531 d_printf("net rpc service start <service> Start a service\n");
532 d_printf("net rpc service stop <service> Stop a service\n");
533 d_printf("net rpc service pause <service> Pause a service\n");
534 d_printf("net rpc service resume <service> Resume a paused service\n");
535 d_printf("net rpc service status <service> View the current status of a service\n");
540 /********************************************************************
541 ********************************************************************/
543 int net_rpc_service(int argc
, const char **argv
)
545 struct functable func
[] = {
546 {"list", rpc_service_list
},
547 {"start", rpc_service_start
},
548 {"stop", rpc_service_stop
},
549 {"pause", rpc_service_pause
},
550 {"resume", rpc_service_resume
},
551 {"status", rpc_service_status
},
556 return net_run_function( argc
, argv
, func
, net_help_service
);
558 return net_help_service( argc
, argv
);