source: branches/samba-3.2.x/source/utils/net_rpc_service.c

Last change on this file was 133, checked in by Paul Smedley, 17 years ago

Update trunk to 3.2.0pre3

File size: 18.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 3 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, see <http://www.gnu.org/licenses/>. */
18
19#include "includes.h"
20#include "utils/net.h"
21
22
23#define CLI_SERVER_NAME_SLASH(_ctx, _p, _cli) \
24 _p = talloc_asprintf(_ctx, "\\\\%s", _cli->cli->desthost);
25
26/********************************************************************
27********************************************************************/
28
29static WERROR query_service_state(struct rpc_pipe_client *pipe_hnd,
30 TALLOC_CTX *mem_ctx,
31 POLICY_HND *hSCM,
32 const char *service,
33 uint32 *state )
34{
35 POLICY_HND hService;
36 SERVICE_STATUS service_status;
37 WERROR result = WERR_GENERAL_FAILURE;
38 NTSTATUS status;
39
40 /* now cycle until the status is actually 'watch_state' */
41
42 status = rpccli_svcctl_OpenServiceW(pipe_hnd, mem_ctx,
43 hSCM,
44 service,
45 SC_RIGHT_SVC_QUERY_STATUS,
46 &hService,
47 &result);
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));
50 return result;
51 }
52
53 status = rpccli_svcctl_QueryServiceStatus(pipe_hnd, mem_ctx,
54 &hService,
55 &service_status,
56 &result);
57
58 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result) ) {
59 *state = service_status.state;
60 }
61
62 rpccli_svcctl_CloseServiceHandle(pipe_hnd, mem_ctx, &hService, NULL);
63
64 return result;
65}
66
67/********************************************************************
68********************************************************************/
69
70static WERROR watch_service_state(struct rpc_pipe_client *pipe_hnd,
71 TALLOC_CTX *mem_ctx,
72 POLICY_HND *hSCM,
73 const char *service,
74 uint32 watch_state,
75 uint32 *final_state )
76{
77 uint32 i;
78 uint32 state = 0;
79 WERROR result = WERR_GENERAL_FAILURE;
80
81
82 i = 0;
83 while ( (state != watch_state ) && i<30 ) {
84 /* get the status */
85
86 result = query_service_state(pipe_hnd, mem_ctx, hSCM, service, &state );
87 if ( !W_ERROR_IS_OK(result) ) {
88 break;
89 }
90
91 d_printf(".");
92 i++;
93 sys_usleep( 100 );
94 }
95 d_printf("\n");
96
97 *final_state = state;
98
99 return result;
100}
101
102/********************************************************************
103********************************************************************/
104
105static WERROR control_service(struct rpc_pipe_client *pipe_hnd,
106 TALLOC_CTX *mem_ctx,
107 POLICY_HND *hSCM,
108 const char *service,
109 uint32 control,
110 uint32 watch_state )
111{
112 POLICY_HND hService;
113 WERROR result = WERR_GENERAL_FAILURE;
114 NTSTATUS status;
115 SERVICE_STATUS service_status;
116 uint32 state = 0;
117
118 /* Open the Service */
119
120 status = rpccli_svcctl_OpenServiceW(pipe_hnd, mem_ctx,
121 hSCM,
122 service,
123 (SC_RIGHT_SVC_STOP|SC_RIGHT_SVC_PAUSE_CONTINUE),
124 &hService,
125 &result);
126
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));
129 goto done;
130 }
131
132 /* get the status */
133
134 status = rpccli_svcctl_ControlService(pipe_hnd, mem_ctx,
135 &hService,
136 control,
137 &service_status,
138 &result);
139
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));
142 goto done;
143 }
144
145 /* loop -- checking the state until we are where we want to be */
146
147 result = watch_service_state(pipe_hnd, mem_ctx, hSCM, service, watch_state, &state );
148
149 d_printf("%s service is %s.\n", service, svc_status_string(state));
150
151done:
152 rpccli_svcctl_CloseServiceHandle(pipe_hnd, mem_ctx, &hService, NULL);
153
154 return result;
155}
156
157/********************************************************************
158********************************************************************/
159
160static 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,
164 TALLOC_CTX *mem_ctx,
165 int argc,
166 const char **argv )
167{
168 POLICY_HND hSCM;
169 ENUM_SERVICES_STATUS *services;
170 WERROR result = WERR_GENERAL_FAILURE;
171 NTSTATUS status;
172 fstring servicename;
173 fstring displayname;
174 uint32 num_services = 0;
175 const char *server_name;
176 int i;
177
178 if (argc != 0 ) {
179 d_printf("Usage: net rpc service list\n");
180 return NT_STATUS_OK;
181 }
182
183 CLI_SERVER_NAME_SLASH(mem_ctx, server_name, pipe_hnd);
184 NT_STATUS_HAVE_NO_MEMORY(server_name);
185
186 status = rpccli_svcctl_OpenSCManagerW(pipe_hnd, mem_ctx,
187 server_name,
188 NULL,
189 SC_RIGHT_MGR_ENUMERATE_SERVICE,
190 &hSCM,
191 &result);
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);
195 }
196
197 result = rpccli_svcctl_enumerate_services(pipe_hnd, mem_ctx, &hSCM, SVCCTL_TYPE_WIN32,
198 SVCCTL_STATE_ALL, &num_services, &services );
199
200 if ( !W_ERROR_IS_OK(result) ) {
201 d_fprintf(stderr, "Failed to enumerate services. [%s]\n", dos_errstr(result));
202 goto done;
203 }
204
205 if ( num_services == 0 )
206 d_printf("No services returned\n");
207
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 );
211
212 d_printf("%-20s \"%s\"\n", servicename, displayname);
213 }
214
215done:
216 rpccli_svcctl_CloseServiceHandle(pipe_hnd, mem_ctx, &hSCM, NULL);
217
218 return werror_to_ntstatus(result);
219}
220
221/********************************************************************
222********************************************************************/
223
224static 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,
228 TALLOC_CTX *mem_ctx,
229 int argc,
230 const char **argv )
231{
232 POLICY_HND hSCM, hService;
233 WERROR result = WERR_GENERAL_FAILURE;
234 NTSTATUS status;
235 SERVICE_STATUS service_status;
236 SERVICE_CONFIG config;
237 fstring ascii_string;
238 const char *server_name;
239
240 if (argc != 1 ) {
241 d_printf("Usage: net rpc service status <service>\n");
242 return NT_STATUS_OK;
243 }
244
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);
248
249 status = rpccli_svcctl_OpenSCManagerW(pipe_hnd, mem_ctx,
250 server_name,
251 NULL,
252 SC_RIGHT_MGR_ENUMERATE_SERVICE,
253 &hSCM,
254 &result);
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);
258 }
259
260 /* Open the Service */
261
262 status = rpccli_svcctl_OpenServiceW(pipe_hnd, mem_ctx,
263 &hSCM,
264 argv[0],
265 (SC_RIGHT_SVC_QUERY_STATUS|SC_RIGHT_SVC_QUERY_CONFIG),
266 &hService,
267 &result);
268
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));
271 goto done;
272 }
273
274 /* get the status */
275
276 status = rpccli_svcctl_QueryServiceStatus(pipe_hnd, mem_ctx,
277 &hService,
278 &service_status,
279 &result);
280
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));
283 goto done;
284 }
285
286 d_printf("%s service is %s.\n", argv[0], svc_status_string(service_status.state));
287
288 /* get the config */
289
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));
293 goto done;
294 }
295
296 /* print out the configuration information for the service */
297
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);
304
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);
308 }
309
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);
313 }
314
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);
318 }
319
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);
323 }
324
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);
328 }
329
330done:
331 rpccli_svcctl_CloseServiceHandle(pipe_hnd, mem_ctx, &hService, NULL);
332 rpccli_svcctl_CloseServiceHandle(pipe_hnd, mem_ctx, &hSCM, NULL);
333
334 return werror_to_ntstatus(result);
335}
336
337/********************************************************************
338********************************************************************/
339
340static 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,
344 TALLOC_CTX *mem_ctx,
345 int argc,
346 const char **argv )
347{
348 POLICY_HND hSCM;
349 WERROR result = WERR_GENERAL_FAILURE;
350 NTSTATUS status;
351 fstring servicename;
352 const char *server_name;
353
354 if (argc != 1 ) {
355 d_printf("Usage: net rpc service status <service>\n");
356 return NT_STATUS_OK;
357 }
358
359 fstrcpy( servicename, argv[0] );
360
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);
364
365 status = rpccli_svcctl_OpenSCManagerW(pipe_hnd, mem_ctx,
366 server_name,
367 NULL,
368 SC_RIGHT_MGR_ENUMERATE_SERVICE,
369 &hSCM,
370 &result);
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);
374 }
375
376 result = control_service(pipe_hnd, mem_ctx, &hSCM, servicename,
377 SVCCTL_CONTROL_STOP, SVCCTL_STOPPED );
378
379 rpccli_svcctl_CloseServiceHandle(pipe_hnd, mem_ctx, &hSCM, NULL);
380
381 return werror_to_ntstatus(result);
382}
383
384/********************************************************************
385********************************************************************/
386
387static 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,
391 TALLOC_CTX *mem_ctx,
392 int argc,
393 const char **argv )
394{
395 POLICY_HND hSCM;
396 WERROR result = WERR_GENERAL_FAILURE;
397 NTSTATUS status;
398 fstring servicename;
399 const char *server_name;
400
401 if (argc != 1 ) {
402 d_printf("Usage: net rpc service status <service>\n");
403 return NT_STATUS_OK;
404 }
405
406 fstrcpy( servicename, argv[0] );
407
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);
411
412 status = rpccli_svcctl_OpenSCManagerW(pipe_hnd, mem_ctx,
413 server_name,
414 NULL,
415 SC_RIGHT_MGR_ENUMERATE_SERVICE,
416 &hSCM,
417 &result);
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);
421 }
422
423 result = control_service(pipe_hnd, mem_ctx, &hSCM, servicename,
424 SVCCTL_CONTROL_PAUSE, SVCCTL_PAUSED );
425
426 rpccli_svcctl_CloseServiceHandle(pipe_hnd, mem_ctx, &hSCM, NULL);
427
428 return werror_to_ntstatus(result);
429}
430
431/********************************************************************
432********************************************************************/
433
434static 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,
438 TALLOC_CTX *mem_ctx,
439 int argc,
440 const char **argv )
441{
442 POLICY_HND hSCM;
443 WERROR result = WERR_GENERAL_FAILURE;
444 NTSTATUS status;
445 fstring servicename;
446 const char *server_name;
447
448 if (argc != 1 ) {
449 d_printf("Usage: net rpc service status <service>\n");
450 return NT_STATUS_OK;
451 }
452
453 fstrcpy( servicename, argv[0] );
454
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);
458
459 status = rpccli_svcctl_OpenSCManagerW(pipe_hnd, mem_ctx,
460 server_name,
461 NULL,
462 SC_RIGHT_MGR_ENUMERATE_SERVICE,
463 &hSCM,
464 &result);
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);
468 }
469
470 result = control_service(pipe_hnd, mem_ctx, &hSCM, servicename,
471 SVCCTL_CONTROL_CONTINUE, SVCCTL_RUNNING );
472
473 rpccli_svcctl_CloseServiceHandle(pipe_hnd, mem_ctx, &hSCM, NULL);
474
475 return werror_to_ntstatus(result);
476}
477
478/********************************************************************
479********************************************************************/
480
481static 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,
485 TALLOC_CTX *mem_ctx,
486 int argc,
487 const char **argv )
488{
489 POLICY_HND hSCM, hService;
490 WERROR result = WERR_GENERAL_FAILURE;
491 NTSTATUS status;
492 uint32 state = 0;
493 const char *server_name;
494
495 if (argc != 1 ) {
496 d_printf("Usage: net rpc service status <service>\n");
497 return NT_STATUS_OK;
498 }
499
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);
503
504 status = rpccli_svcctl_OpenSCManagerW(pipe_hnd, mem_ctx,
505 server_name,
506 NULL,
507 SC_RIGHT_MGR_ENUMERATE_SERVICE,
508 &hSCM,
509 &result);
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);
513 }
514
515 /* Open the Service */
516
517 status = rpccli_svcctl_OpenServiceW(pipe_hnd, mem_ctx,
518 &hSCM,
519 argv[0],
520 SC_RIGHT_SVC_START,
521 &hService,
522 &result);
523
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));
526 goto done;
527 }
528
529 /* get the status */
530
531 status = rpccli_svcctl_StartServiceW(pipe_hnd, mem_ctx,
532 &hService,
533 0,
534 NULL,
535 &result);
536
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));
539 goto done;
540 }
541
542 result = watch_service_state(pipe_hnd, mem_ctx, &hSCM, argv[0], SVCCTL_RUNNING, &state );
543
544 if ( W_ERROR_IS_OK(result) && (state == SVCCTL_RUNNING) )
545 d_printf("Successfully started service: %s\n", argv[0] );
546 else
547 d_fprintf(stderr, "Failed to start service: %s [%s]\n", argv[0], dos_errstr(result) );
548
549done:
550 rpccli_svcctl_CloseServiceHandle(pipe_hnd, mem_ctx, &hService, NULL);
551 rpccli_svcctl_CloseServiceHandle(pipe_hnd, mem_ctx, &hSCM, NULL);
552
553 return werror_to_ntstatus(result);
554}
555
556/********************************************************************
557********************************************************************/
558
559static int rpc_service_list( int argc, const char **argv )
560{
561 return run_rpc_command( NULL, PI_SVCCTL, 0,
562 rpc_service_list_internal, argc, argv );
563}
564
565/********************************************************************
566********************************************************************/
567
568static int rpc_service_start( int argc, const char **argv )
569{
570 return run_rpc_command( NULL, PI_SVCCTL, 0,
571 rpc_service_start_internal, argc, argv );
572}
573
574/********************************************************************
575********************************************************************/
576
577static int rpc_service_stop( int argc, const char **argv )
578{
579 return run_rpc_command( NULL, PI_SVCCTL, 0,
580 rpc_service_stop_internal, argc, argv );
581}
582
583/********************************************************************
584********************************************************************/
585
586static int rpc_service_resume( int argc, const char **argv )
587{
588 return run_rpc_command( NULL, PI_SVCCTL, 0,
589 rpc_service_resume_internal, argc, argv );
590}
591
592/********************************************************************
593********************************************************************/
594
595static int rpc_service_pause( int argc, const char **argv )
596{
597 return run_rpc_command( NULL, PI_SVCCTL, 0,
598 rpc_service_pause_internal, argc, argv );
599}
600
601/********************************************************************
602********************************************************************/
603
604static int rpc_service_status( int argc, const char **argv )
605{
606 return run_rpc_command( NULL, PI_SVCCTL, 0,
607 rpc_service_status_internal, argc, argv );
608}
609
610/********************************************************************
611********************************************************************/
612
613static int net_help_service( int argc, const char **argv )
614{
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");
621
622 return -1;
623}
624
625/********************************************************************
626********************************************************************/
627
628int net_rpc_service(int argc, const char **argv)
629{
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},
637 {NULL, NULL}
638 };
639
640 if ( argc )
641 return net_run_function( argc, argv, func, net_help_service );
642
643 return net_help_service( argc, argv );
644}
Note: See TracBrowser for help on using the repository browser.