source: branches/samba-3.0/source/utils/net_rpc_service.c

Last change on this file was 1, checked in by Paul Smedley, 18 years ago

Initial code import

File size: 16.8 KB
Line 
1/*
2 Samba Unix/Linux SMB client library
3 Distributed SMB/CIFS Server Management Utility
4 Copyright (C) Gerald (Jerry) Carter 2005
5
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 2 of the License, or
9 (at your option) any later version.
10
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.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
19
20#include "includes.h"
21#include "utils/net.h"
22
23
24/********************************************************************
25********************************************************************/
26
27static WERROR query_service_state(struct rpc_pipe_client *pipe_hnd,
28 TALLOC_CTX *mem_ctx,
29 POLICY_HND *hSCM,
30 const char *service,
31 uint32 *state )
32{
33 POLICY_HND hService;
34 SERVICE_STATUS service_status;
35 WERROR result = WERR_GENERAL_FAILURE;
36
37 /* now cycle until the status is actually 'watch_state' */
38
39 result = rpccli_svcctl_open_service(pipe_hnd, mem_ctx, hSCM, &hService,
40 service, SC_RIGHT_SVC_QUERY_STATUS );
41
42 if ( !W_ERROR_IS_OK(result) ) {
43 d_fprintf(stderr, "Failed to open service. [%s]\n", dos_errstr(result));
44 return result;
45 }
46
47 result = rpccli_svcctl_query_status(pipe_hnd, mem_ctx, &hService, &service_status );
48 if ( W_ERROR_IS_OK(result) ) {
49 *state = service_status.state;
50 }
51
52 rpccli_svcctl_close_service(pipe_hnd, mem_ctx, &hService );
53
54 return result;
55}
56
57/********************************************************************
58********************************************************************/
59
60static WERROR watch_service_state(struct rpc_pipe_client *pipe_hnd,
61 TALLOC_CTX *mem_ctx,
62 POLICY_HND *hSCM,
63 const char *service,
64 uint32 watch_state,
65 uint32 *final_state )
66{
67 uint32 i;
68 uint32 state = 0;
69 WERROR result = WERR_GENERAL_FAILURE;
70
71
72 i = 0;
73 while ( (state != watch_state ) && i<30 ) {
74 /* get the status */
75
76 result = query_service_state(pipe_hnd, mem_ctx, hSCM, service, &state );
77 if ( !W_ERROR_IS_OK(result) ) {
78 break;
79 }
80
81 d_printf(".");
82 i++;
83 sys_usleep( 100 );
84 }
85 d_printf("\n");
86
87 *final_state = state;
88
89 return result;
90}
91
92/********************************************************************
93********************************************************************/
94
95static WERROR control_service(struct rpc_pipe_client *pipe_hnd,
96 TALLOC_CTX *mem_ctx,
97 POLICY_HND *hSCM,
98 const char *service,
99 uint32 control,
100 uint32 watch_state )
101{
102 POLICY_HND hService;
103 WERROR result = WERR_GENERAL_FAILURE;
104 SERVICE_STATUS service_status;
105 uint32 state = 0;
106
107 /* Open the Service */
108
109 result = rpccli_svcctl_open_service(pipe_hnd, mem_ctx, hSCM, &hService,
110 service, (SC_RIGHT_SVC_STOP|SC_RIGHT_SVC_PAUSE_CONTINUE) );
111
112 if ( !W_ERROR_IS_OK(result) ) {
113 d_fprintf(stderr, "Failed to open service. [%s]\n", dos_errstr(result));
114 goto done;
115 }
116
117 /* get the status */
118
119 result = rpccli_svcctl_control_service(pipe_hnd, mem_ctx, &hService,
120 control, &service_status );
121
122 if ( !W_ERROR_IS_OK(result) ) {
123 d_fprintf(stderr, "Control service request failed. [%s]\n", dos_errstr(result));
124 goto done;
125 }
126
127 /* loop -- checking the state until we are where we want to be */
128
129 result = watch_service_state(pipe_hnd, mem_ctx, hSCM, service, watch_state, &state );
130
131 d_printf("%s service is %s.\n", service, svc_status_string(state));
132
133done:
134 rpccli_svcctl_close_service(pipe_hnd, mem_ctx, &hService );
135
136 return result;
137}
138
139/********************************************************************
140********************************************************************/
141
142static NTSTATUS rpc_service_list_internal(const DOM_SID *domain_sid,
143 const char *domain_name,
144 struct cli_state *cli,
145 struct rpc_pipe_client *pipe_hnd,
146 TALLOC_CTX *mem_ctx,
147 int argc,
148 const char **argv )
149{
150 POLICY_HND hSCM;
151 ENUM_SERVICES_STATUS *services;
152 WERROR result = WERR_GENERAL_FAILURE;
153 fstring servicename;
154 fstring displayname;
155 uint32 num_services = 0;
156 int i;
157
158 if (argc != 0 ) {
159 d_printf("Usage: net rpc service list\n");
160 return NT_STATUS_OK;
161 }
162
163 result = rpccli_svcctl_open_scm(pipe_hnd, mem_ctx, &hSCM, SC_RIGHT_MGR_ENUMERATE_SERVICE );
164 if ( !W_ERROR_IS_OK(result) ) {
165 d_fprintf(stderr, "Failed to open Service Control Manager. [%s]\n", dos_errstr(result));
166 return werror_to_ntstatus(result);
167 }
168
169 result = rpccli_svcctl_enumerate_services(pipe_hnd, mem_ctx, &hSCM, SVCCTL_TYPE_WIN32,
170 SVCCTL_STATE_ALL, &num_services, &services );
171
172 if ( !W_ERROR_IS_OK(result) ) {
173 d_fprintf(stderr, "Failed to enumerate services. [%s]\n", dos_errstr(result));
174 goto done;
175 }
176
177 if ( num_services == 0 )
178 d_printf("No services returned\n");
179
180 for ( i=0; i<num_services; i++ ) {
181 rpcstr_pull( servicename, services[i].servicename.buffer, sizeof(servicename), -1, STR_TERMINATE );
182 rpcstr_pull( displayname, services[i].displayname.buffer, sizeof(displayname), -1, STR_TERMINATE );
183
184 d_printf("%-20s \"%s\"\n", servicename, displayname);
185 }
186
187done:
188 rpccli_svcctl_close_service(pipe_hnd, mem_ctx, &hSCM );
189
190 return werror_to_ntstatus(result);
191}
192
193/********************************************************************
194********************************************************************/
195
196static NTSTATUS rpc_service_status_internal(const DOM_SID *domain_sid,
197 const char *domain_name,
198 struct cli_state *cli,
199 struct rpc_pipe_client *pipe_hnd,
200 TALLOC_CTX *mem_ctx,
201 int argc,
202 const char **argv )
203{
204 POLICY_HND hSCM, hService;
205 WERROR result = WERR_GENERAL_FAILURE;
206 fstring servicename;
207 SERVICE_STATUS service_status;
208 SERVICE_CONFIG config;
209 fstring ascii_string;
210
211 if (argc != 1 ) {
212 d_printf("Usage: net rpc service status <service>\n");
213 return NT_STATUS_OK;
214 }
215
216 fstrcpy( servicename, argv[0] );
217
218 /* Open the Service Control Manager */
219
220 result = rpccli_svcctl_open_scm(pipe_hnd, mem_ctx, &hSCM, SC_RIGHT_MGR_ENUMERATE_SERVICE );
221 if ( !W_ERROR_IS_OK(result) ) {
222 d_fprintf(stderr, "Failed to open Service Control Manager. [%s]\n", dos_errstr(result));
223 return werror_to_ntstatus(result);
224 }
225
226 /* Open the Service */
227
228 result = rpccli_svcctl_open_service(pipe_hnd, mem_ctx, &hSCM, &hService, servicename,
229 (SC_RIGHT_SVC_QUERY_STATUS|SC_RIGHT_SVC_QUERY_CONFIG) );
230
231 if ( !W_ERROR_IS_OK(result) ) {
232 d_fprintf(stderr, "Failed to open service. [%s]\n", dos_errstr(result));
233 goto done;
234 }
235
236 /* get the status */
237
238 result = rpccli_svcctl_query_status(pipe_hnd, mem_ctx, &hService, &service_status );
239 if ( !W_ERROR_IS_OK(result) ) {
240 d_fprintf(stderr, "Query status request failed. [%s]\n", dos_errstr(result));
241 goto done;
242 }
243
244 d_printf("%s service is %s.\n", servicename, svc_status_string(service_status.state));
245
246 /* get the config */
247
248 result = rpccli_svcctl_query_config(pipe_hnd, mem_ctx, &hService, &config );
249 if ( !W_ERROR_IS_OK(result) ) {
250 d_fprintf(stderr, "Query config request failed. [%s]\n", dos_errstr(result));
251 goto done;
252 }
253
254 /* print out the configuration information for the service */
255
256 d_printf("Configuration details:\n");
257 d_printf("\tControls Accepted = 0x%x\n", service_status.controls_accepted);
258 d_printf("\tService Type = 0x%x\n", config.service_type);
259 d_printf("\tStart Type = 0x%x\n", config.start_type);
260 d_printf("\tError Control = 0x%x\n", config.error_control);
261 d_printf("\tTag ID = 0x%x\n", config.tag_id);
262
263 if ( config.executablepath ) {
264 rpcstr_pull( ascii_string, config.executablepath->buffer, sizeof(ascii_string), -1, STR_TERMINATE );
265 d_printf("\tExecutable Path = %s\n", ascii_string);
266 }
267
268 if ( config.loadordergroup ) {
269 rpcstr_pull( ascii_string, config.loadordergroup->buffer, sizeof(ascii_string), -1, STR_TERMINATE );
270 d_printf("\tLoad Order Group = %s\n", ascii_string);
271 }
272
273 if ( config.dependencies ) {
274 rpcstr_pull( ascii_string, config.dependencies->buffer, sizeof(ascii_string), -1, STR_TERMINATE );
275 d_printf("\tDependencies = %s\n", ascii_string);
276 }
277
278 if ( config.startname ) {
279 rpcstr_pull( ascii_string, config.startname->buffer, sizeof(ascii_string), -1, STR_TERMINATE );
280 d_printf("\tStart Name = %s\n", ascii_string);
281 }
282
283 if ( config.displayname ) {
284 rpcstr_pull( ascii_string, config.displayname->buffer, sizeof(ascii_string), -1, STR_TERMINATE );
285 d_printf("\tDisplay Name = %s\n", ascii_string);
286 }
287
288done:
289 rpccli_svcctl_close_service(pipe_hnd, mem_ctx, &hService );
290 rpccli_svcctl_close_service(pipe_hnd, mem_ctx, &hSCM );
291
292 return werror_to_ntstatus(result);
293}
294
295/********************************************************************
296********************************************************************/
297
298static NTSTATUS rpc_service_stop_internal(const DOM_SID *domain_sid,
299 const char *domain_name,
300 struct cli_state *cli,
301 struct rpc_pipe_client *pipe_hnd,
302 TALLOC_CTX *mem_ctx,
303 int argc,
304 const char **argv )
305{
306 POLICY_HND hSCM;
307 WERROR result = WERR_GENERAL_FAILURE;
308 fstring servicename;
309
310 if (argc != 1 ) {
311 d_printf("Usage: net rpc service status <service>\n");
312 return NT_STATUS_OK;
313 }
314
315 fstrcpy( servicename, argv[0] );
316
317 /* Open the Service Control Manager */
318
319 result = rpccli_svcctl_open_scm(pipe_hnd, mem_ctx, &hSCM, SC_RIGHT_MGR_ENUMERATE_SERVICE );
320 if ( !W_ERROR_IS_OK(result) ) {
321 d_fprintf(stderr, "Failed to open Service Control Manager. [%s]\n", dos_errstr(result));
322 return werror_to_ntstatus(result);
323 }
324
325 result = control_service(pipe_hnd, mem_ctx, &hSCM, servicename,
326 SVCCTL_CONTROL_STOP, SVCCTL_STOPPED );
327
328 rpccli_svcctl_close_service(pipe_hnd, mem_ctx, &hSCM );
329
330 return werror_to_ntstatus(result);
331}
332
333/********************************************************************
334********************************************************************/
335
336static NTSTATUS rpc_service_pause_internal(const DOM_SID *domain_sid,
337 const char *domain_name,
338 struct cli_state *cli,
339 struct rpc_pipe_client *pipe_hnd,
340 TALLOC_CTX *mem_ctx,
341 int argc,
342 const char **argv )
343{
344 POLICY_HND hSCM;
345 WERROR result = WERR_GENERAL_FAILURE;
346 fstring servicename;
347
348 if (argc != 1 ) {
349 d_printf("Usage: net rpc service status <service>\n");
350 return NT_STATUS_OK;
351 }
352
353 fstrcpy( servicename, argv[0] );
354
355 /* Open the Service Control Manager */
356
357 result = rpccli_svcctl_open_scm(pipe_hnd, mem_ctx, &hSCM, SC_RIGHT_MGR_ENUMERATE_SERVICE );
358 if ( !W_ERROR_IS_OK(result) ) {
359 d_fprintf(stderr, "Failed to open Service Control Manager. [%s]\n", dos_errstr(result));
360 return werror_to_ntstatus(result);
361 }
362
363 result = control_service(pipe_hnd, mem_ctx, &hSCM, servicename,
364 SVCCTL_CONTROL_PAUSE, SVCCTL_PAUSED );
365
366 rpccli_svcctl_close_service(pipe_hnd, mem_ctx, &hSCM );
367
368 return werror_to_ntstatus(result);
369}
370
371/********************************************************************
372********************************************************************/
373
374static NTSTATUS rpc_service_resume_internal(const DOM_SID *domain_sid,
375 const char *domain_name,
376 struct cli_state *cli,
377 struct rpc_pipe_client *pipe_hnd,
378 TALLOC_CTX *mem_ctx,
379 int argc,
380 const char **argv )
381{
382 POLICY_HND hSCM;
383 WERROR result = WERR_GENERAL_FAILURE;
384 fstring servicename;
385
386 if (argc != 1 ) {
387 d_printf("Usage: net rpc service status <service>\n");
388 return NT_STATUS_OK;
389 }
390
391 fstrcpy( servicename, argv[0] );
392
393 /* Open the Service Control Manager */
394
395 result = rpccli_svcctl_open_scm(pipe_hnd, mem_ctx, &hSCM, SC_RIGHT_MGR_ENUMERATE_SERVICE );
396 if ( !W_ERROR_IS_OK(result) ) {
397 d_fprintf(stderr, "Failed to open Service Control Manager. [%s]\n", dos_errstr(result));
398 return werror_to_ntstatus(result);
399 }
400
401 result = control_service(pipe_hnd, mem_ctx, &hSCM, servicename,
402 SVCCTL_CONTROL_CONTINUE, SVCCTL_RUNNING );
403
404 rpccli_svcctl_close_service(pipe_hnd, mem_ctx, &hSCM );
405
406 return werror_to_ntstatus(result);
407}
408
409/********************************************************************
410********************************************************************/
411
412static NTSTATUS rpc_service_start_internal(const DOM_SID *domain_sid,
413 const char *domain_name,
414 struct cli_state *cli,
415 struct rpc_pipe_client *pipe_hnd,
416 TALLOC_CTX *mem_ctx,
417 int argc,
418 const char **argv )
419{
420 POLICY_HND hSCM, hService;
421 WERROR result = WERR_GENERAL_FAILURE;
422 fstring servicename;
423 uint32 state = 0;
424
425 if (argc != 1 ) {
426 d_printf("Usage: net rpc service status <service>\n");
427 return NT_STATUS_OK;
428 }
429
430 fstrcpy( servicename, argv[0] );
431
432 /* Open the Service Control Manager */
433
434 result = rpccli_svcctl_open_scm( pipe_hnd, mem_ctx, &hSCM, SC_RIGHT_MGR_ENUMERATE_SERVICE );
435 if ( !W_ERROR_IS_OK(result) ) {
436 d_fprintf(stderr, "Failed to open Service Control Manager. [%s]\n", dos_errstr(result));
437 return werror_to_ntstatus(result);
438 }
439
440 /* Open the Service */
441
442 result = rpccli_svcctl_open_service(pipe_hnd, mem_ctx, &hSCM, &hService,
443 servicename, SC_RIGHT_SVC_START );
444
445 if ( !W_ERROR_IS_OK(result) ) {
446 d_fprintf(stderr, "Failed to open service. [%s]\n", dos_errstr(result));
447 goto done;
448 }
449
450 /* get the status */
451
452 result = rpccli_svcctl_start_service(pipe_hnd, mem_ctx, &hService, NULL, 0 );
453 if ( !W_ERROR_IS_OK(result) ) {
454 d_fprintf(stderr, "Query status request failed. [%s]\n", dos_errstr(result));
455 goto done;
456 }
457
458 result = watch_service_state(pipe_hnd, mem_ctx, &hSCM, servicename, SVCCTL_RUNNING, &state );
459
460 if ( W_ERROR_IS_OK(result) && (state == SVCCTL_RUNNING) )
461 d_printf("Successfully started service: %s\n", servicename );
462 else
463 d_fprintf(stderr, "Failed to start service: %s [%s]\n", servicename, dos_errstr(result) );
464
465done:
466 rpccli_svcctl_close_service(pipe_hnd, mem_ctx, &hService );
467 rpccli_svcctl_close_service(pipe_hnd, mem_ctx, &hSCM );
468
469 return werror_to_ntstatus(result);
470}
471
472/********************************************************************
473********************************************************************/
474
475static int rpc_service_list( int argc, const char **argv )
476{
477 return run_rpc_command( NULL, PI_SVCCTL, 0,
478 rpc_service_list_internal, argc, argv );
479}
480
481/********************************************************************
482********************************************************************/
483
484static int rpc_service_start( int argc, const char **argv )
485{
486 return run_rpc_command( NULL, PI_SVCCTL, 0,
487 rpc_service_start_internal, argc, argv );
488}
489
490/********************************************************************
491********************************************************************/
492
493static int rpc_service_stop( int argc, const char **argv )
494{
495 return run_rpc_command( NULL, PI_SVCCTL, 0,
496 rpc_service_stop_internal, argc, argv );
497}
498
499/********************************************************************
500********************************************************************/
501
502static int rpc_service_resume( int argc, const char **argv )
503{
504 return run_rpc_command( NULL, PI_SVCCTL, 0,
505 rpc_service_resume_internal, argc, argv );
506}
507
508/********************************************************************
509********************************************************************/
510
511static int rpc_service_pause( int argc, const char **argv )
512{
513 return run_rpc_command( NULL, PI_SVCCTL, 0,
514 rpc_service_pause_internal, argc, argv );
515}
516
517/********************************************************************
518********************************************************************/
519
520static int rpc_service_status( int argc, const char **argv )
521{
522 return run_rpc_command( NULL, PI_SVCCTL, 0,
523 rpc_service_status_internal, argc, argv );
524}
525
526/********************************************************************
527********************************************************************/
528
529static int net_help_service( int argc, const char **argv )
530{
531 d_printf("net rpc service list View configured Win32 services\n");
532 d_printf("net rpc service start <service> Start a service\n");
533 d_printf("net rpc service stop <service> Stop a service\n");
534 d_printf("net rpc service pause <service> Pause a service\n");
535 d_printf("net rpc service resume <service> Resume a paused service\n");
536 d_printf("net rpc service status <service> View the current status of a service\n");
537
538 return -1;
539}
540
541/********************************************************************
542********************************************************************/
543
544int net_rpc_service(int argc, const char **argv)
545{
546 struct functable func[] = {
547 {"list", rpc_service_list},
548 {"start", rpc_service_start},
549 {"stop", rpc_service_stop},
550 {"pause", rpc_service_pause},
551 {"resume", rpc_service_resume},
552 {"status", rpc_service_status},
553 {NULL, NULL}
554 };
555
556 if ( argc )
557 return net_run_function( argc, argv, func, net_help_service );
558
559 return net_help_service( argc, argv );
560}
Note: See TracBrowser for help on using the repository browser.