Remove whitespace, no code changes.
[samba.git] / source3 / utils / net_rpc_service.c
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 /********************************************************************
24 ********************************************************************/
25
26 static WERROR query_service_state(struct rpc_pipe_client *pipe_hnd,
27                                 TALLOC_CTX *mem_ctx,
28                                 POLICY_HND *hSCM,
29                                 const char *service,
30                                 uint32 *state )
31 {
32         POLICY_HND hService;
33         SERVICE_STATUS service_status;
34         WERROR result = WERR_GENERAL_FAILURE;
35
36         /* now cycle until the status is actually 'watch_state' */
37
38         result = rpccli_svcctl_open_service(pipe_hnd, mem_ctx, hSCM, &hService,
39                 service, SC_RIGHT_SVC_QUERY_STATUS );
40
41         if ( !W_ERROR_IS_OK(result) ) {
42                 d_fprintf(stderr, "Failed to open service.  [%s]\n", dos_errstr(result));
43                 return result;
44         }
45
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;
49         }
50
51         rpccli_svcctl_CloseServiceHandle(pipe_hnd, mem_ctx, &hService, NULL);
52
53         return result;
54 }
55
56 /********************************************************************
57 ********************************************************************/
58
59 static WERROR watch_service_state(struct rpc_pipe_client *pipe_hnd,
60                                 TALLOC_CTX *mem_ctx,
61                                 POLICY_HND *hSCM,
62                                 const char *service,
63                                 uint32 watch_state,
64                                 uint32 *final_state )
65 {
66         uint32 i;
67         uint32 state = 0;
68         WERROR result = WERR_GENERAL_FAILURE;
69
70
71         i = 0;
72         while ( (state != watch_state ) && i<30 ) {
73                 /* get the status */
74
75                 result = query_service_state(pipe_hnd, mem_ctx, hSCM, service, &state  );
76                 if ( !W_ERROR_IS_OK(result) ) {
77                         break;
78                 }
79
80                 d_printf(".");
81                 i++;
82                 sys_usleep( 100 );
83         }
84         d_printf("\n");
85
86         *final_state = state;
87
88         return result;
89 }
90
91 /********************************************************************
92 ********************************************************************/
93
94 static WERROR control_service(struct rpc_pipe_client *pipe_hnd,
95                                 TALLOC_CTX *mem_ctx,
96                                 POLICY_HND *hSCM,
97                                 const char *service,
98                                 uint32 control,
99                                 uint32 watch_state )
100 {
101         POLICY_HND hService;
102         WERROR result = WERR_GENERAL_FAILURE;
103         SERVICE_STATUS service_status;
104         uint32 state = 0;
105
106         /* Open the Service */
107
108         result = rpccli_svcctl_open_service(pipe_hnd, mem_ctx, hSCM, &hService,
109                 service, (SC_RIGHT_SVC_STOP|SC_RIGHT_SVC_PAUSE_CONTINUE) );
110
111         if ( !W_ERROR_IS_OK(result) ) {
112                 d_fprintf(stderr, "Failed to open service.  [%s]\n", dos_errstr(result));
113                 goto done;
114         }
115
116         /* get the status */
117
118         result = rpccli_svcctl_control_service(pipe_hnd, mem_ctx, &hService,
119                 control, &service_status  );
120
121         if ( !W_ERROR_IS_OK(result) ) {
122                 d_fprintf(stderr, "Control service request failed.  [%s]\n", dos_errstr(result));
123                 goto done;
124         }
125
126         /* loop -- checking the state until we are where we want to be */
127
128         result = watch_service_state(pipe_hnd, mem_ctx, hSCM, service, watch_state, &state );
129
130         d_printf("%s service is %s.\n", service, svc_status_string(state));
131
132 done:
133         rpccli_svcctl_CloseServiceHandle(pipe_hnd, mem_ctx, &hService, NULL);
134
135         return result;
136 }
137
138 /********************************************************************
139 ********************************************************************/
140
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,
145                                         TALLOC_CTX *mem_ctx,
146                                         int argc,
147                                         const char **argv )
148 {
149         POLICY_HND hSCM;
150         ENUM_SERVICES_STATUS *services;
151         WERROR result = WERR_GENERAL_FAILURE;
152         fstring servicename;
153         fstring displayname;
154         uint32 num_services = 0;
155         int i;
156
157         if (argc != 0 ) {
158                 d_printf("Usage: net rpc service list\n");
159                 return NT_STATUS_OK;
160         }
161
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);
166         }
167
168         result = rpccli_svcctl_enumerate_services(pipe_hnd, mem_ctx, &hSCM, SVCCTL_TYPE_WIN32,
169                 SVCCTL_STATE_ALL, &num_services, &services );
170
171         if ( !W_ERROR_IS_OK(result) ) {
172                 d_fprintf(stderr, "Failed to enumerate services.  [%s]\n", dos_errstr(result));
173                 goto done;
174         }
175
176         if ( num_services == 0 )
177                 d_printf("No services returned\n");
178
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 );
182
183                 d_printf("%-20s    \"%s\"\n", servicename, displayname);
184         }
185
186 done:
187         rpccli_svcctl_CloseServiceHandle(pipe_hnd, mem_ctx, &hSCM, NULL);
188
189         return werror_to_ntstatus(result);
190 }
191
192 /********************************************************************
193 ********************************************************************/
194
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,
199                                                 TALLOC_CTX *mem_ctx,
200                                                 int argc,
201                                                 const char **argv )
202 {
203         POLICY_HND hSCM, hService;
204         WERROR result = WERR_GENERAL_FAILURE;
205         fstring servicename;
206         SERVICE_STATUS service_status;
207         SERVICE_CONFIG config;
208         fstring ascii_string;
209
210         if (argc != 1 ) {
211                 d_printf("Usage: net rpc service status <service>\n");
212                 return NT_STATUS_OK;
213         }
214
215         fstrcpy( servicename, argv[0] );
216
217         /* Open the Service Control Manager */
218
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);
223         }
224
225         /* Open the Service */
226
227         result = rpccli_svcctl_open_service(pipe_hnd, mem_ctx, &hSCM, &hService, servicename,
228                 (SC_RIGHT_SVC_QUERY_STATUS|SC_RIGHT_SVC_QUERY_CONFIG) );
229
230         if ( !W_ERROR_IS_OK(result) ) {
231                 d_fprintf(stderr, "Failed to open service.  [%s]\n", dos_errstr(result));
232                 goto done;
233         }
234
235         /* get the status */
236
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));
240                 goto done;
241         }
242
243         d_printf("%s service is %s.\n", servicename, svc_status_string(service_status.state));
244
245         /* get the config */
246
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));
250                 goto done;
251         }
252
253         /* print out the configuration information for the service */
254
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);
261
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);
265         }
266
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);
270         }
271
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);
275         }
276
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);
280         }
281
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);
285         }
286
287 done:
288         rpccli_svcctl_CloseServiceHandle(pipe_hnd, mem_ctx, &hService, NULL);
289         rpccli_svcctl_CloseServiceHandle(pipe_hnd, mem_ctx, &hSCM, NULL);
290
291         return werror_to_ntstatus(result);
292 }
293
294 /********************************************************************
295 ********************************************************************/
296
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,
301                                         TALLOC_CTX *mem_ctx,
302                                         int argc,
303                                         const char **argv )
304 {
305         POLICY_HND hSCM;
306         WERROR result = WERR_GENERAL_FAILURE;
307         fstring servicename;
308
309         if (argc != 1 ) {
310                 d_printf("Usage: net rpc service status <service>\n");
311                 return NT_STATUS_OK;
312         }
313
314         fstrcpy( servicename, argv[0] );
315
316         /* Open the Service Control Manager */
317
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);
322         }
323
324         result = control_service(pipe_hnd, mem_ctx, &hSCM, servicename,
325                 SVCCTL_CONTROL_STOP, SVCCTL_STOPPED );
326
327         rpccli_svcctl_CloseServiceHandle(pipe_hnd, mem_ctx, &hSCM, NULL);
328
329         return werror_to_ntstatus(result);
330 }
331
332 /********************************************************************
333 ********************************************************************/
334
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,
339                                         TALLOC_CTX *mem_ctx,
340                                         int argc,
341                                         const char **argv )
342 {
343         POLICY_HND hSCM;
344         WERROR result = WERR_GENERAL_FAILURE;
345         fstring servicename;
346
347         if (argc != 1 ) {
348                 d_printf("Usage: net rpc service status <service>\n");
349                 return NT_STATUS_OK;
350         }
351
352         fstrcpy( servicename, argv[0] );
353
354         /* Open the Service Control Manager */
355
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);
360         }
361
362         result = control_service(pipe_hnd, mem_ctx, &hSCM, servicename,
363                 SVCCTL_CONTROL_PAUSE, SVCCTL_PAUSED );
364
365         rpccli_svcctl_CloseServiceHandle(pipe_hnd, mem_ctx, &hSCM, NULL);
366
367         return werror_to_ntstatus(result);
368 }
369
370 /********************************************************************
371 ********************************************************************/
372
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,
377                                         TALLOC_CTX *mem_ctx,
378                                         int argc,
379                                         const char **argv )
380 {
381         POLICY_HND hSCM;
382         WERROR result = WERR_GENERAL_FAILURE;
383         fstring servicename;
384
385         if (argc != 1 ) {
386                 d_printf("Usage: net rpc service status <service>\n");
387                 return NT_STATUS_OK;
388         }
389
390         fstrcpy( servicename, argv[0] );
391
392         /* Open the Service Control Manager */
393
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);
398         }
399
400         result = control_service(pipe_hnd, mem_ctx, &hSCM, servicename,
401                 SVCCTL_CONTROL_CONTINUE, SVCCTL_RUNNING );
402
403         rpccli_svcctl_CloseServiceHandle(pipe_hnd, mem_ctx, &hSCM, NULL);
404
405         return werror_to_ntstatus(result);
406 }
407
408 /********************************************************************
409 ********************************************************************/
410
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,
415                                         TALLOC_CTX *mem_ctx,
416                                         int argc,
417                                         const char **argv )
418 {
419         POLICY_HND hSCM, hService;
420         WERROR result = WERR_GENERAL_FAILURE;
421         fstring servicename;
422         uint32 state = 0;
423
424         if (argc != 1 ) {
425                 d_printf("Usage: net rpc service status <service>\n");
426                 return NT_STATUS_OK;
427         }
428
429         fstrcpy( servicename, argv[0] );
430
431         /* Open the Service Control Manager */
432
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);
437         }
438
439         /* Open the Service */
440
441         result = rpccli_svcctl_open_service(pipe_hnd, mem_ctx, &hSCM, &hService,
442                 servicename, SC_RIGHT_SVC_START );
443
444         if ( !W_ERROR_IS_OK(result) ) {
445                 d_fprintf(stderr, "Failed to open service.  [%s]\n", dos_errstr(result));
446                 goto done;
447         }
448
449         /* get the status */
450
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));
454                 goto done;
455         }
456
457         result = watch_service_state(pipe_hnd, mem_ctx, &hSCM, servicename, SVCCTL_RUNNING, &state  );
458
459         if ( W_ERROR_IS_OK(result) && (state == SVCCTL_RUNNING) )
460                 d_printf("Successfully started service: %s\n", servicename );
461         else
462                 d_fprintf(stderr, "Failed to start service: %s [%s]\n", servicename, dos_errstr(result) );
463
464 done:
465         rpccli_svcctl_CloseServiceHandle(pipe_hnd, mem_ctx, &hService, NULL);
466         rpccli_svcctl_CloseServiceHandle(pipe_hnd, mem_ctx, &hSCM, NULL);
467
468         return werror_to_ntstatus(result);
469 }
470
471 /********************************************************************
472 ********************************************************************/
473
474 static int rpc_service_list( int argc, const char **argv )
475 {
476         return run_rpc_command( NULL, PI_SVCCTL, 0,
477                 rpc_service_list_internal, argc, argv );
478 }
479
480 /********************************************************************
481 ********************************************************************/
482
483 static int rpc_service_start( int argc, const char **argv )
484 {
485         return run_rpc_command( NULL, PI_SVCCTL, 0,
486                 rpc_service_start_internal, argc, argv );
487 }
488
489 /********************************************************************
490 ********************************************************************/
491
492 static int rpc_service_stop( int argc, const char **argv )
493 {
494         return run_rpc_command( NULL, PI_SVCCTL, 0,
495                 rpc_service_stop_internal, argc, argv );
496 }
497
498 /********************************************************************
499 ********************************************************************/
500
501 static int rpc_service_resume( int argc, const char **argv )
502 {
503         return run_rpc_command( NULL, PI_SVCCTL, 0,
504                 rpc_service_resume_internal, argc, argv );
505 }
506
507 /********************************************************************
508 ********************************************************************/
509
510 static int rpc_service_pause( int argc, const char **argv )
511 {
512         return run_rpc_command( NULL, PI_SVCCTL, 0,
513                 rpc_service_pause_internal, argc, argv );
514 }
515
516 /********************************************************************
517 ********************************************************************/
518
519 static int rpc_service_status( int argc, const char **argv )
520 {
521         return run_rpc_command( NULL, PI_SVCCTL, 0,
522                 rpc_service_status_internal, argc, argv );
523 }
524
525 /********************************************************************
526 ********************************************************************/
527
528 static int net_help_service( int argc, const char **argv )
529 {
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");
536
537         return -1;
538 }
539
540 /********************************************************************
541 ********************************************************************/
542
543 int net_rpc_service(int argc, const char **argv)
544 {
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},
552                 {NULL, NULL}
553         };
554
555         if ( argc )
556                 return net_run_function( argc, argv, func, net_help_service );
557
558         return net_help_service( argc, argv );
559 }