Use rpccli_svcctl_StartServiceW() in net.
[bbaumbach/samba-autobuild/.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 #define CLI_SERVER_NAME_SLASH(_ctx, _p, _cli) \
24         _p = talloc_asprintf(_ctx, "\\\\%s", _cli->cli->desthost);
25
26 /********************************************************************
27 ********************************************************************/
28
29 static 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         result = rpccli_svcctl_query_status(pipe_hnd, mem_ctx, &hService, &service_status  );
54         if ( W_ERROR_IS_OK(result) ) {
55                 *state = service_status.state;
56         }
57
58         rpccli_svcctl_CloseServiceHandle(pipe_hnd, mem_ctx, &hService, NULL);
59
60         return result;
61 }
62
63 /********************************************************************
64 ********************************************************************/
65
66 static WERROR watch_service_state(struct rpc_pipe_client *pipe_hnd,
67                                 TALLOC_CTX *mem_ctx,
68                                 POLICY_HND *hSCM,
69                                 const char *service,
70                                 uint32 watch_state,
71                                 uint32 *final_state )
72 {
73         uint32 i;
74         uint32 state = 0;
75         WERROR result = WERR_GENERAL_FAILURE;
76
77
78         i = 0;
79         while ( (state != watch_state ) && i<30 ) {
80                 /* get the status */
81
82                 result = query_service_state(pipe_hnd, mem_ctx, hSCM, service, &state  );
83                 if ( !W_ERROR_IS_OK(result) ) {
84                         break;
85                 }
86
87                 d_printf(".");
88                 i++;
89                 sys_usleep( 100 );
90         }
91         d_printf("\n");
92
93         *final_state = state;
94
95         return result;
96 }
97
98 /********************************************************************
99 ********************************************************************/
100
101 static WERROR control_service(struct rpc_pipe_client *pipe_hnd,
102                                 TALLOC_CTX *mem_ctx,
103                                 POLICY_HND *hSCM,
104                                 const char *service,
105                                 uint32 control,
106                                 uint32 watch_state )
107 {
108         POLICY_HND hService;
109         WERROR result = WERR_GENERAL_FAILURE;
110         NTSTATUS status;
111         SERVICE_STATUS service_status;
112         uint32 state = 0;
113
114         /* Open the Service */
115
116         status = rpccli_svcctl_OpenServiceW(pipe_hnd, mem_ctx,
117                                             hSCM,
118                                             service,
119                                             (SC_RIGHT_SVC_STOP|SC_RIGHT_SVC_PAUSE_CONTINUE),
120                                             &hService,
121                                             &result);
122
123         if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result) ) {
124                 d_fprintf(stderr, "Failed to open service.  [%s]\n", dos_errstr(result));
125                 goto done;
126         }
127
128         /* get the status */
129
130         result = rpccli_svcctl_control_service(pipe_hnd, mem_ctx, &hService,
131                 control, &service_status  );
132
133         if ( !W_ERROR_IS_OK(result) ) {
134                 d_fprintf(stderr, "Control service request failed.  [%s]\n", dos_errstr(result));
135                 goto done;
136         }
137
138         /* loop -- checking the state until we are where we want to be */
139
140         result = watch_service_state(pipe_hnd, mem_ctx, hSCM, service, watch_state, &state );
141
142         d_printf("%s service is %s.\n", service, svc_status_string(state));
143
144 done:
145         rpccli_svcctl_CloseServiceHandle(pipe_hnd, mem_ctx, &hService, NULL);
146
147         return result;
148 }
149
150 /********************************************************************
151 ********************************************************************/
152
153 static NTSTATUS rpc_service_list_internal(const DOM_SID *domain_sid,
154                                         const char *domain_name,
155                                         struct cli_state *cli,
156                                         struct rpc_pipe_client *pipe_hnd,
157                                         TALLOC_CTX *mem_ctx,
158                                         int argc,
159                                         const char **argv )
160 {
161         POLICY_HND hSCM;
162         ENUM_SERVICES_STATUS *services;
163         WERROR result = WERR_GENERAL_FAILURE;
164         NTSTATUS status;
165         fstring servicename;
166         fstring displayname;
167         uint32 num_services = 0;
168         const char *server_name;
169         int i;
170
171         if (argc != 0 ) {
172                 d_printf("Usage: net rpc service list\n");
173                 return NT_STATUS_OK;
174         }
175
176         CLI_SERVER_NAME_SLASH(mem_ctx, server_name, pipe_hnd);
177         NT_STATUS_HAVE_NO_MEMORY(server_name);
178
179         status = rpccli_svcctl_OpenSCManagerW(pipe_hnd, mem_ctx,
180                                               server_name,
181                                               NULL,
182                                               SC_RIGHT_MGR_ENUMERATE_SERVICE,
183                                               &hSCM,
184                                               &result);
185         if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result)) {
186                 d_fprintf(stderr, "Failed to open Service Control Manager.  [%s]\n", dos_errstr(result));
187                 return werror_to_ntstatus(result);
188         }
189
190         result = rpccli_svcctl_enumerate_services(pipe_hnd, mem_ctx, &hSCM, SVCCTL_TYPE_WIN32,
191                 SVCCTL_STATE_ALL, &num_services, &services );
192
193         if ( !W_ERROR_IS_OK(result) ) {
194                 d_fprintf(stderr, "Failed to enumerate services.  [%s]\n", dos_errstr(result));
195                 goto done;
196         }
197
198         if ( num_services == 0 )
199                 d_printf("No services returned\n");
200
201         for ( i=0; i<num_services; i++ ) {
202                 rpcstr_pull( servicename, services[i].servicename.buffer, sizeof(servicename), -1, STR_TERMINATE );
203                 rpcstr_pull( displayname, services[i].displayname.buffer, sizeof(displayname), -1, STR_TERMINATE );
204
205                 d_printf("%-20s    \"%s\"\n", servicename, displayname);
206         }
207
208 done:
209         rpccli_svcctl_CloseServiceHandle(pipe_hnd, mem_ctx, &hSCM, NULL);
210
211         return werror_to_ntstatus(result);
212 }
213
214 /********************************************************************
215 ********************************************************************/
216
217 static NTSTATUS rpc_service_status_internal(const DOM_SID *domain_sid,
218                                                 const char *domain_name,
219                                                 struct cli_state *cli,
220                                                 struct rpc_pipe_client *pipe_hnd,
221                                                 TALLOC_CTX *mem_ctx,
222                                                 int argc,
223                                                 const char **argv )
224 {
225         POLICY_HND hSCM, hService;
226         WERROR result = WERR_GENERAL_FAILURE;
227         NTSTATUS status;
228         SERVICE_STATUS service_status;
229         SERVICE_CONFIG config;
230         fstring ascii_string;
231         const char *server_name;
232
233         if (argc != 1 ) {
234                 d_printf("Usage: net rpc service status <service>\n");
235                 return NT_STATUS_OK;
236         }
237
238         /* Open the Service Control Manager */
239         CLI_SERVER_NAME_SLASH(mem_ctx, server_name, pipe_hnd);
240         NT_STATUS_HAVE_NO_MEMORY(server_name);
241
242         status = rpccli_svcctl_OpenSCManagerW(pipe_hnd, mem_ctx,
243                                               server_name,
244                                               NULL,
245                                               SC_RIGHT_MGR_ENUMERATE_SERVICE,
246                                               &hSCM,
247                                               &result);
248         if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result)) {
249                 d_fprintf(stderr, "Failed to open Service Control Manager.  [%s]\n", dos_errstr(result));
250                 return werror_to_ntstatus(result);
251         }
252
253         /* Open the Service */
254
255         status = rpccli_svcctl_OpenServiceW(pipe_hnd, mem_ctx,
256                                             &hSCM,
257                                             argv[0],
258                                             (SC_RIGHT_SVC_QUERY_STATUS|SC_RIGHT_SVC_QUERY_CONFIG),
259                                             &hService,
260                                             &result);
261
262         if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result) ) {
263                 d_fprintf(stderr, "Failed to open service.  [%s]\n", dos_errstr(result));
264                 goto done;
265         }
266
267         /* get the status */
268
269         result = rpccli_svcctl_query_status(pipe_hnd, mem_ctx, &hService, &service_status  );
270         if ( !W_ERROR_IS_OK(result) ) {
271                 d_fprintf(stderr, "Query status request failed.  [%s]\n", dos_errstr(result));
272                 goto done;
273         }
274
275         d_printf("%s service is %s.\n", argv[0], svc_status_string(service_status.state));
276
277         /* get the config */
278
279         result = rpccli_svcctl_query_config(pipe_hnd, mem_ctx, &hService, &config  );
280         if ( !W_ERROR_IS_OK(result) ) {
281                 d_fprintf(stderr, "Query config request failed.  [%s]\n", dos_errstr(result));
282                 goto done;
283         }
284
285         /* print out the configuration information for the service */
286
287         d_printf("Configuration details:\n");
288         d_printf("\tControls Accepted    = 0x%x\n", service_status.controls_accepted);
289         d_printf("\tService Type         = 0x%x\n", config.service_type);
290         d_printf("\tStart Type           = 0x%x\n", config.start_type);
291         d_printf("\tError Control        = 0x%x\n", config.error_control);
292         d_printf("\tTag ID               = 0x%x\n", config.tag_id);
293
294         if ( config.executablepath ) {
295                 rpcstr_pull( ascii_string, config.executablepath->buffer, sizeof(ascii_string), -1, STR_TERMINATE );
296                 d_printf("\tExecutable Path      = %s\n", ascii_string);
297         }
298
299         if ( config.loadordergroup ) {
300                 rpcstr_pull( ascii_string, config.loadordergroup->buffer, sizeof(ascii_string), -1, STR_TERMINATE );
301                 d_printf("\tLoad Order Group     = %s\n", ascii_string);
302         }
303
304         if ( config.dependencies ) {
305                 rpcstr_pull( ascii_string, config.dependencies->buffer, sizeof(ascii_string), -1, STR_TERMINATE );
306                 d_printf("\tDependencies         = %s\n", ascii_string);
307         }
308
309         if ( config.startname ) {
310                 rpcstr_pull( ascii_string, config.startname->buffer, sizeof(ascii_string), -1, STR_TERMINATE );
311                 d_printf("\tStart Name           = %s\n", ascii_string);
312         }
313
314         if ( config.displayname ) {
315                 rpcstr_pull( ascii_string, config.displayname->buffer, sizeof(ascii_string), -1, STR_TERMINATE );
316                 d_printf("\tDisplay Name         = %s\n", ascii_string);
317         }
318
319 done:
320         rpccli_svcctl_CloseServiceHandle(pipe_hnd, mem_ctx, &hService, NULL);
321         rpccli_svcctl_CloseServiceHandle(pipe_hnd, mem_ctx, &hSCM, NULL);
322
323         return werror_to_ntstatus(result);
324 }
325
326 /********************************************************************
327 ********************************************************************/
328
329 static NTSTATUS rpc_service_stop_internal(const DOM_SID *domain_sid,
330                                         const char *domain_name,
331                                         struct cli_state *cli,
332                                         struct rpc_pipe_client *pipe_hnd,
333                                         TALLOC_CTX *mem_ctx,
334                                         int argc,
335                                         const char **argv )
336 {
337         POLICY_HND hSCM;
338         WERROR result = WERR_GENERAL_FAILURE;
339         NTSTATUS status;
340         fstring servicename;
341         const char *server_name;
342
343         if (argc != 1 ) {
344                 d_printf("Usage: net rpc service status <service>\n");
345                 return NT_STATUS_OK;
346         }
347
348         fstrcpy( servicename, argv[0] );
349
350         /* Open the Service Control Manager */
351         CLI_SERVER_NAME_SLASH(mem_ctx, server_name, pipe_hnd);
352         NT_STATUS_HAVE_NO_MEMORY(server_name);
353
354         status = rpccli_svcctl_OpenSCManagerW(pipe_hnd, mem_ctx,
355                                               server_name,
356                                               NULL,
357                                               SC_RIGHT_MGR_ENUMERATE_SERVICE,
358                                               &hSCM,
359                                               &result);
360         if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result)) {
361                 d_fprintf(stderr, "Failed to open Service Control Manager.  [%s]\n", dos_errstr(result));
362                 return werror_to_ntstatus(result);
363         }
364
365         result = control_service(pipe_hnd, mem_ctx, &hSCM, servicename,
366                 SVCCTL_CONTROL_STOP, SVCCTL_STOPPED );
367
368         rpccli_svcctl_CloseServiceHandle(pipe_hnd, mem_ctx, &hSCM, NULL);
369
370         return werror_to_ntstatus(result);
371 }
372
373 /********************************************************************
374 ********************************************************************/
375
376 static NTSTATUS rpc_service_pause_internal(const DOM_SID *domain_sid,
377                                         const char *domain_name,
378                                         struct cli_state *cli,
379                                         struct rpc_pipe_client *pipe_hnd,
380                                         TALLOC_CTX *mem_ctx,
381                                         int argc,
382                                         const char **argv )
383 {
384         POLICY_HND hSCM;
385         WERROR result = WERR_GENERAL_FAILURE;
386         NTSTATUS status;
387         fstring servicename;
388         const char *server_name;
389
390         if (argc != 1 ) {
391                 d_printf("Usage: net rpc service status <service>\n");
392                 return NT_STATUS_OK;
393         }
394
395         fstrcpy( servicename, argv[0] );
396
397         /* Open the Service Control Manager */
398         CLI_SERVER_NAME_SLASH(mem_ctx, server_name, pipe_hnd);
399         NT_STATUS_HAVE_NO_MEMORY(server_name);
400
401         status = rpccli_svcctl_OpenSCManagerW(pipe_hnd, mem_ctx,
402                                               server_name,
403                                               NULL,
404                                               SC_RIGHT_MGR_ENUMERATE_SERVICE,
405                                               &hSCM,
406                                               &result);
407         if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result)) {
408                 d_fprintf(stderr, "Failed to open Service Control Manager.  [%s]\n", dos_errstr(result));
409                 return werror_to_ntstatus(result);
410         }
411
412         result = control_service(pipe_hnd, mem_ctx, &hSCM, servicename,
413                 SVCCTL_CONTROL_PAUSE, SVCCTL_PAUSED );
414
415         rpccli_svcctl_CloseServiceHandle(pipe_hnd, mem_ctx, &hSCM, NULL);
416
417         return werror_to_ntstatus(result);
418 }
419
420 /********************************************************************
421 ********************************************************************/
422
423 static NTSTATUS rpc_service_resume_internal(const DOM_SID *domain_sid,
424                                         const char *domain_name,
425                                         struct cli_state *cli,
426                                         struct rpc_pipe_client *pipe_hnd,
427                                         TALLOC_CTX *mem_ctx,
428                                         int argc,
429                                         const char **argv )
430 {
431         POLICY_HND hSCM;
432         WERROR result = WERR_GENERAL_FAILURE;
433         NTSTATUS status;
434         fstring servicename;
435         const char *server_name;
436
437         if (argc != 1 ) {
438                 d_printf("Usage: net rpc service status <service>\n");
439                 return NT_STATUS_OK;
440         }
441
442         fstrcpy( servicename, argv[0] );
443
444         /* Open the Service Control Manager */
445         CLI_SERVER_NAME_SLASH(mem_ctx, server_name, pipe_hnd);
446         NT_STATUS_HAVE_NO_MEMORY(server_name);
447
448         status = rpccli_svcctl_OpenSCManagerW(pipe_hnd, mem_ctx,
449                                               server_name,
450                                               NULL,
451                                               SC_RIGHT_MGR_ENUMERATE_SERVICE,
452                                               &hSCM,
453                                               &result);
454         if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result)) {
455                 d_fprintf(stderr, "Failed to open Service Control Manager.  [%s]\n", dos_errstr(result));
456                 return werror_to_ntstatus(result);
457         }
458
459         result = control_service(pipe_hnd, mem_ctx, &hSCM, servicename,
460                 SVCCTL_CONTROL_CONTINUE, SVCCTL_RUNNING );
461
462         rpccli_svcctl_CloseServiceHandle(pipe_hnd, mem_ctx, &hSCM, NULL);
463
464         return werror_to_ntstatus(result);
465 }
466
467 /********************************************************************
468 ********************************************************************/
469
470 static NTSTATUS rpc_service_start_internal(const DOM_SID *domain_sid,
471                                         const char *domain_name,
472                                         struct cli_state *cli,
473                                         struct rpc_pipe_client *pipe_hnd,
474                                         TALLOC_CTX *mem_ctx,
475                                         int argc,
476                                         const char **argv )
477 {
478         POLICY_HND hSCM, hService;
479         WERROR result = WERR_GENERAL_FAILURE;
480         NTSTATUS status;
481         uint32 state = 0;
482         const char *server_name;
483
484         if (argc != 1 ) {
485                 d_printf("Usage: net rpc service status <service>\n");
486                 return NT_STATUS_OK;
487         }
488
489         /* Open the Service Control Manager */
490         CLI_SERVER_NAME_SLASH(mem_ctx, server_name, pipe_hnd);
491         NT_STATUS_HAVE_NO_MEMORY(server_name);
492
493         status = rpccli_svcctl_OpenSCManagerW(pipe_hnd, mem_ctx,
494                                               server_name,
495                                               NULL,
496                                               SC_RIGHT_MGR_ENUMERATE_SERVICE,
497                                               &hSCM,
498                                               &result);
499         if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result)) {
500                 d_fprintf(stderr, "Failed to open Service Control Manager.  [%s]\n", dos_errstr(result));
501                 return werror_to_ntstatus(result);
502         }
503
504         /* Open the Service */
505
506         status = rpccli_svcctl_OpenServiceW(pipe_hnd, mem_ctx,
507                                             &hSCM,
508                                             argv[0],
509                                             SC_RIGHT_SVC_START,
510                                             &hService,
511                                             &result);
512
513         if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result) ) {
514                 d_fprintf(stderr, "Failed to open service.  [%s]\n", dos_errstr(result));
515                 goto done;
516         }
517
518         /* get the status */
519
520         status = rpccli_svcctl_StartServiceW(pipe_hnd, mem_ctx,
521                                              &hService,
522                                              0,
523                                              NULL,
524                                              &result);
525
526         if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result) ) {
527                 d_fprintf(stderr, "Query status request failed.  [%s]\n", dos_errstr(result));
528                 goto done;
529         }
530
531         result = watch_service_state(pipe_hnd, mem_ctx, &hSCM, argv[0], SVCCTL_RUNNING, &state  );
532
533         if ( W_ERROR_IS_OK(result) && (state == SVCCTL_RUNNING) )
534                 d_printf("Successfully started service: %s\n", argv[0] );
535         else
536                 d_fprintf(stderr, "Failed to start service: %s [%s]\n", argv[0], dos_errstr(result) );
537
538 done:
539         rpccli_svcctl_CloseServiceHandle(pipe_hnd, mem_ctx, &hService, NULL);
540         rpccli_svcctl_CloseServiceHandle(pipe_hnd, mem_ctx, &hSCM, NULL);
541
542         return werror_to_ntstatus(result);
543 }
544
545 /********************************************************************
546 ********************************************************************/
547
548 static int rpc_service_list( int argc, const char **argv )
549 {
550         return run_rpc_command( NULL, PI_SVCCTL, 0,
551                 rpc_service_list_internal, argc, argv );
552 }
553
554 /********************************************************************
555 ********************************************************************/
556
557 static int rpc_service_start( int argc, const char **argv )
558 {
559         return run_rpc_command( NULL, PI_SVCCTL, 0,
560                 rpc_service_start_internal, argc, argv );
561 }
562
563 /********************************************************************
564 ********************************************************************/
565
566 static int rpc_service_stop( int argc, const char **argv )
567 {
568         return run_rpc_command( NULL, PI_SVCCTL, 0,
569                 rpc_service_stop_internal, argc, argv );
570 }
571
572 /********************************************************************
573 ********************************************************************/
574
575 static int rpc_service_resume( int argc, const char **argv )
576 {
577         return run_rpc_command( NULL, PI_SVCCTL, 0,
578                 rpc_service_resume_internal, argc, argv );
579 }
580
581 /********************************************************************
582 ********************************************************************/
583
584 static int rpc_service_pause( int argc, const char **argv )
585 {
586         return run_rpc_command( NULL, PI_SVCCTL, 0,
587                 rpc_service_pause_internal, argc, argv );
588 }
589
590 /********************************************************************
591 ********************************************************************/
592
593 static int rpc_service_status( int argc, const char **argv )
594 {
595         return run_rpc_command( NULL, PI_SVCCTL, 0,
596                 rpc_service_status_internal, argc, argv );
597 }
598
599 /********************************************************************
600 ********************************************************************/
601
602 static int net_help_service( int argc, const char **argv )
603 {
604         d_printf("net rpc service list               View configured Win32 services\n");
605         d_printf("net rpc service start <service>    Start a service\n");
606         d_printf("net rpc service stop <service>     Stop a service\n");
607         d_printf("net rpc service pause <service>    Pause a service\n");
608         d_printf("net rpc service resume <service>   Resume a paused service\n");
609         d_printf("net rpc service status <service>   View the current status of a service\n");
610
611         return -1;
612 }
613
614 /********************************************************************
615 ********************************************************************/
616
617 int net_rpc_service(int argc, const char **argv)
618 {
619         struct functable func[] = {
620                 {"list", rpc_service_list},
621                 {"start", rpc_service_start},
622                 {"stop", rpc_service_stop},
623                 {"pause", rpc_service_pause},
624                 {"resume", rpc_service_resume},
625                 {"status", rpc_service_status},
626                 {NULL, NULL}
627         };
628
629         if ( argc )
630                 return net_run_function( argc, argv, func, net_help_service );
631
632         return net_help_service( argc, argv );
633 }