r10656: BIG merge from trunk. Features not copied over
[ira/wip.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 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
27 static 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_printf("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
60 static 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                 usleep( 100 );
84         }
85         d_printf("\n");
86         
87         *final_state = state;
88         
89         return result;
90 }
91
92 /********************************************************************
93 ********************************************************************/
94
95 static 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_printf("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_printf("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
133 done:   
134         rpccli_svcctl_close_service(pipe_hnd, mem_ctx, &hService  );
135                 
136         return result;
137 }       
138
139 /********************************************************************
140 ********************************************************************/
141
142 static 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_printf("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_printf("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
187 done:   
188         rpccli_svcctl_close_service(pipe_hnd, mem_ctx, &hSCM  );
189                 
190         return werror_to_ntstatus(result);
191 }       
192
193 /********************************************************************
194 ********************************************************************/
195
196 static 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_printf("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_printf("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_printf("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_printf("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("\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_close_service(pipe_hnd, mem_ctx, &hService  );
289         rpccli_svcctl_close_service(pipe_hnd, mem_ctx, &hSCM  );
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_printf("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_close_service(pipe_hnd, mem_ctx, &hSCM  );
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_printf("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_close_service(pipe_hnd, mem_ctx, &hSCM  );
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_printf("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_close_service(pipe_hnd, mem_ctx, &hSCM  );
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_printf("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_printf("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_printf("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_printf("Failed to start service: %s [%s]\n", servicename, dos_errstr(result) );
463         
464 done:   
465         rpccli_svcctl_close_service(pipe_hnd, mem_ctx, &hService  );
466         rpccli_svcctl_close_service(pipe_hnd, mem_ctx, &hSCM  );
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 }