Merge branch 'master' of ssh://git.samba.org/data/git/samba into regsrv
[kai/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 struct svc_state_msg {
24         uint32 flag;
25         const char *message;
26 };
27
28 static struct svc_state_msg state_msg_table[] = {
29         { SVCCTL_STOPPED,            "stopped" },
30         { SVCCTL_START_PENDING,      "start pending" },
31         { SVCCTL_STOP_PENDING,       "stop pending" },
32         { SVCCTL_RUNNING,            "running" },
33         { SVCCTL_CONTINUE_PENDING,   "resume pending" },
34         { SVCCTL_PAUSE_PENDING,      "pause pending" },
35         { SVCCTL_PAUSED,             "paused" },
36         { 0,                          NULL }
37 };
38
39
40 /********************************************************************
41 ********************************************************************/
42 const char *svc_status_string( uint32 state )
43 {
44         fstring msg;
45         int i;
46
47         fstr_sprintf( msg, "Unknown State [%d]", state );
48
49         for ( i=0; state_msg_table[i].message; i++ ) {
50                 if ( state_msg_table[i].flag == state ) {
51                         fstrcpy( msg, state_msg_table[i].message );
52                         break;
53                 }
54         }
55
56         return talloc_strdup(talloc_tos(), msg);
57 }
58
59 /********************************************************************
60 ********************************************************************/
61
62 static WERROR query_service_state(struct rpc_pipe_client *pipe_hnd,
63                                 TALLOC_CTX *mem_ctx,
64                                 POLICY_HND *hSCM,
65                                 const char *service,
66                                 uint32 *state )
67 {
68         POLICY_HND hService;
69         SERVICE_STATUS service_status;
70         WERROR result = WERR_GENERAL_FAILURE;
71         NTSTATUS status;
72
73         /* now cycle until the status is actually 'watch_state' */
74
75         status = rpccli_svcctl_OpenServiceW(pipe_hnd, mem_ctx,
76                                             hSCM,
77                                             service,
78                                             SC_RIGHT_SVC_QUERY_STATUS,
79                                             &hService,
80                                             &result);
81         if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result) ) {
82                 d_fprintf(stderr, "Failed to open service.  [%s]\n", dos_errstr(result));
83                 return result;
84         }
85
86         status = rpccli_svcctl_QueryServiceStatus(pipe_hnd, mem_ctx,
87                                                   &hService,
88                                                   &service_status,
89                                                   &result);
90
91         if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result) ) {
92                 *state = service_status.state;
93         }
94
95         rpccli_svcctl_CloseServiceHandle(pipe_hnd, mem_ctx, &hService, NULL);
96
97         return result;
98 }
99
100 /********************************************************************
101 ********************************************************************/
102
103 static WERROR watch_service_state(struct rpc_pipe_client *pipe_hnd,
104                                 TALLOC_CTX *mem_ctx,
105                                 POLICY_HND *hSCM,
106                                 const char *service,
107                                 uint32 watch_state,
108                                 uint32 *final_state )
109 {
110         uint32 i;
111         uint32 state = 0;
112         WERROR result = WERR_GENERAL_FAILURE;
113
114
115         i = 0;
116         while ( (state != watch_state ) && i<30 ) {
117                 /* get the status */
118
119                 result = query_service_state(pipe_hnd, mem_ctx, hSCM, service, &state  );
120                 if ( !W_ERROR_IS_OK(result) ) {
121                         break;
122                 }
123
124                 d_printf(".");
125                 i++;
126                 sys_usleep( 100 );
127         }
128         d_printf("\n");
129
130         *final_state = state;
131
132         return result;
133 }
134
135 /********************************************************************
136 ********************************************************************/
137
138 static WERROR control_service(struct rpc_pipe_client *pipe_hnd,
139                                 TALLOC_CTX *mem_ctx,
140                                 POLICY_HND *hSCM,
141                                 const char *service,
142                                 uint32 control,
143                                 uint32 watch_state )
144 {
145         POLICY_HND hService;
146         WERROR result = WERR_GENERAL_FAILURE;
147         NTSTATUS status;
148         SERVICE_STATUS service_status;
149         uint32 state = 0;
150
151         /* Open the Service */
152
153         status = rpccli_svcctl_OpenServiceW(pipe_hnd, mem_ctx,
154                                             hSCM,
155                                             service,
156                                             (SC_RIGHT_SVC_STOP|SC_RIGHT_SVC_PAUSE_CONTINUE),
157                                             &hService,
158                                             &result);
159
160         if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result) ) {
161                 d_fprintf(stderr, "Failed to open service.  [%s]\n", dos_errstr(result));
162                 goto done;
163         }
164
165         /* get the status */
166
167         status = rpccli_svcctl_ControlService(pipe_hnd, mem_ctx,
168                                               &hService,
169                                               control,
170                                               &service_status,
171                                               &result);
172
173         if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result) ) {
174                 d_fprintf(stderr, "Control service request failed.  [%s]\n", dos_errstr(result));
175                 goto done;
176         }
177
178         /* loop -- checking the state until we are where we want to be */
179
180         result = watch_service_state(pipe_hnd, mem_ctx, hSCM, service, watch_state, &state );
181
182         d_printf("%s service is %s.\n", service, svc_status_string(state));
183
184 done:
185         rpccli_svcctl_CloseServiceHandle(pipe_hnd, mem_ctx, &hService, NULL);
186
187         return result;
188 }
189
190 /********************************************************************
191 ********************************************************************/
192
193 static NTSTATUS rpc_service_list_internal(struct net_context *c,
194                                         const DOM_SID *domain_sid,
195                                         const char *domain_name,
196                                         struct cli_state *cli,
197                                         struct rpc_pipe_client *pipe_hnd,
198                                         TALLOC_CTX *mem_ctx,
199                                         int argc,
200                                         const char **argv )
201 {
202         POLICY_HND hSCM;
203         ENUM_SERVICES_STATUS *services;
204         WERROR result = WERR_GENERAL_FAILURE;
205         NTSTATUS status;
206         fstring servicename;
207         fstring displayname;
208         uint32 num_services = 0;
209         int i;
210
211         if (argc != 0 ) {
212                 d_printf("Usage: net rpc service list\n");
213                 return NT_STATUS_OK;
214         }
215
216         status = rpccli_svcctl_OpenSCManagerW(pipe_hnd, mem_ctx,
217                                               pipe_hnd->srv_name_slash,
218                                               NULL,
219                                               SC_RIGHT_MGR_ENUMERATE_SERVICE,
220                                               &hSCM,
221                                               &result);
222         if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result)) {
223                 d_fprintf(stderr, "Failed to open Service Control Manager.  [%s]\n", dos_errstr(result));
224                 return werror_to_ntstatus(result);
225         }
226
227         result = rpccli_svcctl_enumerate_services(pipe_hnd, mem_ctx, &hSCM, SVCCTL_TYPE_WIN32,
228                 SVCCTL_STATE_ALL, &num_services, &services );
229
230         if ( !W_ERROR_IS_OK(result) ) {
231                 d_fprintf(stderr, "Failed to enumerate services.  [%s]\n", dos_errstr(result));
232                 goto done;
233         }
234
235         if ( num_services == 0 )
236                 d_printf("No services returned\n");
237
238         for ( i=0; i<num_services; i++ ) {
239                 rpcstr_pull( servicename, services[i].servicename.buffer, sizeof(servicename), -1, STR_TERMINATE );
240                 rpcstr_pull( displayname, services[i].displayname.buffer, sizeof(displayname), -1, STR_TERMINATE );
241
242                 d_printf("%-20s    \"%s\"\n", servicename, displayname);
243         }
244
245 done:
246         rpccli_svcctl_CloseServiceHandle(pipe_hnd, mem_ctx, &hSCM, NULL);
247
248         return werror_to_ntstatus(result);
249 }
250
251 /********************************************************************
252 ********************************************************************/
253
254 static NTSTATUS rpc_service_status_internal(struct net_context *c,
255                                                 const DOM_SID *domain_sid,
256                                                 const char *domain_name,
257                                                 struct cli_state *cli,
258                                                 struct rpc_pipe_client *pipe_hnd,
259                                                 TALLOC_CTX *mem_ctx,
260                                                 int argc,
261                                                 const char **argv )
262 {
263         POLICY_HND hSCM, hService;
264         WERROR result = WERR_GENERAL_FAILURE;
265         NTSTATUS status;
266         SERVICE_STATUS service_status;
267         struct QUERY_SERVICE_CONFIG config;
268         uint32_t buf_size = sizeof(config);
269         uint32_t ret_size = 0;
270
271         if (argc != 1 ) {
272                 d_printf("Usage: net rpc service status <service>\n");
273                 return NT_STATUS_OK;
274         }
275
276         /* Open the Service Control Manager */
277         status = rpccli_svcctl_OpenSCManagerW(pipe_hnd, mem_ctx,
278                                               pipe_hnd->srv_name_slash,
279                                               NULL,
280                                               SC_RIGHT_MGR_ENUMERATE_SERVICE,
281                                               &hSCM,
282                                               &result);
283         if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result)) {
284                 d_fprintf(stderr, "Failed to open Service Control Manager.  [%s]\n", dos_errstr(result));
285                 return werror_to_ntstatus(result);
286         }
287
288         /* Open the Service */
289
290         status = rpccli_svcctl_OpenServiceW(pipe_hnd, mem_ctx,
291                                             &hSCM,
292                                             argv[0],
293                                             (SC_RIGHT_SVC_QUERY_STATUS|SC_RIGHT_SVC_QUERY_CONFIG),
294                                             &hService,
295                                             &result);
296
297         if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result) ) {
298                 d_fprintf(stderr, "Failed to open service.  [%s]\n", dos_errstr(result));
299                 goto done;
300         }
301
302         /* get the status */
303
304         status = rpccli_svcctl_QueryServiceStatus(pipe_hnd, mem_ctx,
305                                                   &hService,
306                                                   &service_status,
307                                                   &result);
308
309         if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result) ) {
310                 d_fprintf(stderr, "Query status request failed.  [%s]\n", dos_errstr(result));
311                 goto done;
312         }
313
314         d_printf("%s service is %s.\n", argv[0], svc_status_string(service_status.state));
315
316         /* get the config */
317
318         status = rpccli_svcctl_QueryServiceConfigW(pipe_hnd, mem_ctx,
319                                                    &hService,
320                                                    &config,
321                                                    buf_size,
322                                                    &ret_size,
323                                                    &result);
324         if (W_ERROR_EQUAL(result, WERR_INSUFFICIENT_BUFFER)) {
325                 buf_size = ret_size;
326                 status = rpccli_svcctl_QueryServiceConfigW(pipe_hnd, mem_ctx,
327                                                            &hService,
328                                                            &config,
329                                                            buf_size,
330                                                            &ret_size,
331                                                            &result);
332         }
333
334         if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result) ) {
335                 d_fprintf(stderr, "Query config request failed.  [%s]\n", dos_errstr(result));
336                 goto done;
337         }
338
339         /* print out the configuration information for the service */
340
341         d_printf("Configuration details:\n");
342         d_printf("\tControls Accepted    = 0x%x\n", service_status.controls_accepted);
343         d_printf("\tService Type         = 0x%x\n", config.service_type);
344         d_printf("\tStart Type           = 0x%x\n", config.start_type);
345         d_printf("\tError Control        = 0x%x\n", config.error_control);
346         d_printf("\tTag ID               = 0x%x\n", config.tag_id);
347
348         if (config.executablepath) {
349                 d_printf("\tExecutable Path      = %s\n", config.executablepath);
350         }
351
352         if (config.loadordergroup) {
353                 d_printf("\tLoad Order Group     = %s\n", config.loadordergroup);
354         }
355
356         if (config.dependencies) {
357                 d_printf("\tDependencies         = %s\n", config.dependencies);
358         }
359
360         if (config.startname) {
361                 d_printf("\tStart Name           = %s\n", config.startname);
362         }
363
364         if (config.displayname) {
365                 d_printf("\tDisplay Name         = %s\n", config.displayname);
366         }
367
368 done:
369         rpccli_svcctl_CloseServiceHandle(pipe_hnd, mem_ctx, &hService, NULL);
370         rpccli_svcctl_CloseServiceHandle(pipe_hnd, mem_ctx, &hSCM, NULL);
371
372         return werror_to_ntstatus(result);
373 }
374
375 /********************************************************************
376 ********************************************************************/
377
378 static NTSTATUS rpc_service_stop_internal(struct net_context *c,
379                                         const DOM_SID *domain_sid,
380                                         const char *domain_name,
381                                         struct cli_state *cli,
382                                         struct rpc_pipe_client *pipe_hnd,
383                                         TALLOC_CTX *mem_ctx,
384                                         int argc,
385                                         const char **argv )
386 {
387         POLICY_HND hSCM;
388         WERROR result = WERR_GENERAL_FAILURE;
389         NTSTATUS status;
390         fstring servicename;
391
392         if (argc != 1 ) {
393                 d_printf("Usage: net rpc service status <service>\n");
394                 return NT_STATUS_OK;
395         }
396
397         fstrcpy( servicename, argv[0] );
398
399         /* Open the Service Control Manager */
400         status = rpccli_svcctl_OpenSCManagerW(pipe_hnd, mem_ctx,
401                                               pipe_hnd->srv_name_slash,
402                                               NULL,
403                                               SC_RIGHT_MGR_ENUMERATE_SERVICE,
404                                               &hSCM,
405                                               &result);
406         if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result)) {
407                 d_fprintf(stderr, "Failed to open Service Control Manager.  [%s]\n", dos_errstr(result));
408                 return werror_to_ntstatus(result);
409         }
410
411         result = control_service(pipe_hnd, mem_ctx, &hSCM, servicename,
412                 SVCCTL_CONTROL_STOP, SVCCTL_STOPPED );
413
414         rpccli_svcctl_CloseServiceHandle(pipe_hnd, mem_ctx, &hSCM, NULL);
415
416         return werror_to_ntstatus(result);
417 }
418
419 /********************************************************************
420 ********************************************************************/
421
422 static NTSTATUS rpc_service_pause_internal(struct net_context *c,
423                                         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
436         if (argc != 1 ) {
437                 d_printf("Usage: net rpc service status <service>\n");
438                 return NT_STATUS_OK;
439         }
440
441         fstrcpy( servicename, argv[0] );
442
443         /* Open the Service Control Manager */
444         status = rpccli_svcctl_OpenSCManagerW(pipe_hnd, mem_ctx,
445                                               pipe_hnd->srv_name_slash,
446                                               NULL,
447                                               SC_RIGHT_MGR_ENUMERATE_SERVICE,
448                                               &hSCM,
449                                               &result);
450         if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result)) {
451                 d_fprintf(stderr, "Failed to open Service Control Manager.  [%s]\n", dos_errstr(result));
452                 return werror_to_ntstatus(result);
453         }
454
455         result = control_service(pipe_hnd, mem_ctx, &hSCM, servicename,
456                 SVCCTL_CONTROL_PAUSE, SVCCTL_PAUSED );
457
458         rpccli_svcctl_CloseServiceHandle(pipe_hnd, mem_ctx, &hSCM, NULL);
459
460         return werror_to_ntstatus(result);
461 }
462
463 /********************************************************************
464 ********************************************************************/
465
466 static NTSTATUS rpc_service_resume_internal(struct net_context *c,
467                                         const DOM_SID *domain_sid,
468                                         const char *domain_name,
469                                         struct cli_state *cli,
470                                         struct rpc_pipe_client *pipe_hnd,
471                                         TALLOC_CTX *mem_ctx,
472                                         int argc,
473                                         const char **argv )
474 {
475         POLICY_HND hSCM;
476         WERROR result = WERR_GENERAL_FAILURE;
477         NTSTATUS status;
478         fstring servicename;
479
480         if (argc != 1 ) {
481                 d_printf("Usage: net rpc service status <service>\n");
482                 return NT_STATUS_OK;
483         }
484
485         fstrcpy( servicename, argv[0] );
486
487         /* Open the Service Control Manager */
488         status = rpccli_svcctl_OpenSCManagerW(pipe_hnd, mem_ctx,
489                                               pipe_hnd->srv_name_slash,
490                                               NULL,
491                                               SC_RIGHT_MGR_ENUMERATE_SERVICE,
492                                               &hSCM,
493                                               &result);
494         if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result)) {
495                 d_fprintf(stderr, "Failed to open Service Control Manager.  [%s]\n", dos_errstr(result));
496                 return werror_to_ntstatus(result);
497         }
498
499         result = control_service(pipe_hnd, mem_ctx, &hSCM, servicename,
500                 SVCCTL_CONTROL_CONTINUE, SVCCTL_RUNNING );
501
502         rpccli_svcctl_CloseServiceHandle(pipe_hnd, mem_ctx, &hSCM, NULL);
503
504         return werror_to_ntstatus(result);
505 }
506
507 /********************************************************************
508 ********************************************************************/
509
510 static NTSTATUS rpc_service_start_internal(struct net_context *c,
511                                         const DOM_SID *domain_sid,
512                                         const char *domain_name,
513                                         struct cli_state *cli,
514                                         struct rpc_pipe_client *pipe_hnd,
515                                         TALLOC_CTX *mem_ctx,
516                                         int argc,
517                                         const char **argv )
518 {
519         POLICY_HND hSCM, hService;
520         WERROR result = WERR_GENERAL_FAILURE;
521         NTSTATUS status;
522         uint32 state = 0;
523
524         if (argc != 1 ) {
525                 d_printf("Usage: net rpc service status <service>\n");
526                 return NT_STATUS_OK;
527         }
528
529         /* Open the Service Control Manager */
530         status = rpccli_svcctl_OpenSCManagerW(pipe_hnd, mem_ctx,
531                                               pipe_hnd->srv_name_slash,
532                                               NULL,
533                                               SC_RIGHT_MGR_ENUMERATE_SERVICE,
534                                               &hSCM,
535                                               &result);
536         if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result)) {
537                 d_fprintf(stderr, "Failed to open Service Control Manager.  [%s]\n", dos_errstr(result));
538                 return werror_to_ntstatus(result);
539         }
540
541         /* Open the Service */
542
543         status = rpccli_svcctl_OpenServiceW(pipe_hnd, mem_ctx,
544                                             &hSCM,
545                                             argv[0],
546                                             SC_RIGHT_SVC_START,
547                                             &hService,
548                                             &result);
549
550         if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result) ) {
551                 d_fprintf(stderr, "Failed to open service.  [%s]\n", dos_errstr(result));
552                 goto done;
553         }
554
555         /* get the status */
556
557         status = rpccli_svcctl_StartServiceW(pipe_hnd, mem_ctx,
558                                              &hService,
559                                              0,
560                                              NULL,
561                                              &result);
562
563         if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result) ) {
564                 d_fprintf(stderr, "Query status request failed.  [%s]\n", dos_errstr(result));
565                 goto done;
566         }
567
568         result = watch_service_state(pipe_hnd, mem_ctx, &hSCM, argv[0], SVCCTL_RUNNING, &state  );
569
570         if ( W_ERROR_IS_OK(result) && (state == SVCCTL_RUNNING) )
571                 d_printf("Successfully started service: %s\n", argv[0] );
572         else
573                 d_fprintf(stderr, "Failed to start service: %s [%s]\n", argv[0], dos_errstr(result) );
574
575 done:
576         rpccli_svcctl_CloseServiceHandle(pipe_hnd, mem_ctx, &hService, NULL);
577         rpccli_svcctl_CloseServiceHandle(pipe_hnd, mem_ctx, &hSCM, NULL);
578
579         return werror_to_ntstatus(result);
580 }
581
582 /********************************************************************
583 ********************************************************************/
584
585 static int rpc_service_list(struct net_context *c, int argc, const char **argv )
586 {
587         if (c->display_usage) {
588                 d_printf("Usage:\n"
589                          "net rpc service list\n"
590                          "    View configured Win32 services\n");
591                 return 0;
592         }
593
594         return run_rpc_command(c, NULL, &ndr_table_svcctl.syntax_id, 0,
595                 rpc_service_list_internal, argc, argv );
596 }
597
598 /********************************************************************
599 ********************************************************************/
600
601 static int rpc_service_start(struct net_context *c, int argc, const char **argv )
602 {
603         if (c->display_usage) {
604                 d_printf("Usage:\n"
605                          "net rpc service start <service>\n"
606                          "    Start a Win32 service\n");
607                 return 0;
608         }
609
610         return run_rpc_command(c, NULL, &ndr_table_svcctl.syntax_id, 0,
611                 rpc_service_start_internal, argc, argv );
612 }
613
614 /********************************************************************
615 ********************************************************************/
616
617 static int rpc_service_stop(struct net_context *c, int argc, const char **argv )
618 {
619         if (c->display_usage) {
620                 d_printf("Usage:\n"
621                          "net rpc service stop <service>\n"
622                          "    Stop a Win32 service\n");
623                 return 0;
624         }
625
626         return run_rpc_command(c, NULL, &ndr_table_svcctl.syntax_id, 0,
627                 rpc_service_stop_internal, argc, argv );
628 }
629
630 /********************************************************************
631 ********************************************************************/
632
633 static int rpc_service_resume(struct net_context *c, int argc, const char **argv )
634 {
635         if (c->display_usage) {
636                 d_printf("Usage:\n"
637                          "net rpc service resume <service>\n"
638                          "    Resume a Win32 service\n");
639                 return 0;
640         }
641
642         return run_rpc_command(c, NULL, &ndr_table_svcctl.syntax_id, 0,
643                 rpc_service_resume_internal, argc, argv );
644 }
645
646 /********************************************************************
647 ********************************************************************/
648
649 static int rpc_service_pause(struct net_context *c, int argc, const char **argv )
650 {
651         if (c->display_usage) {
652                 d_printf("Usage:\n"
653                          "net rpc service pause <service>\n"
654                          "    Pause a Win32 service\n");
655                 return 0;
656         }
657
658         return run_rpc_command(c, NULL, &ndr_table_svcctl.syntax_id, 0,
659                 rpc_service_pause_internal, argc, argv );
660 }
661
662 /********************************************************************
663 ********************************************************************/
664
665 static int rpc_service_status(struct net_context *c, int argc, const char **argv )
666 {
667         if (c->display_usage) {
668                 d_printf("Usage:\n"
669                          "net rpc service status <service>\n"
670                          "     Show the current status of a service\n");
671                 return 0;
672         }
673
674         return run_rpc_command(c, NULL, &ndr_table_svcctl.syntax_id, 0,
675                 rpc_service_status_internal, argc, argv );
676 }
677
678 /********************************************************************
679 ********************************************************************/
680
681 int net_rpc_service(struct net_context *c, int argc, const char **argv)
682 {
683         struct functable func[] = {
684                 {
685                         "list",
686                         rpc_service_list,
687                         NET_TRANSPORT_RPC,
688                         "View configured Win32 services",
689                         "net rpc service list\n"
690                         "    View configured Win32 services"
691                 },
692                 {
693                         "start",
694                         rpc_service_start,
695                         NET_TRANSPORT_RPC,
696                         "Start a service",
697                         "net rpc service start\n"
698                         "    Start a service"
699                 },
700                 {
701                         "stop",
702                         rpc_service_stop,
703                         NET_TRANSPORT_RPC,
704                         "Stop a service",
705                         "net rpc service stop\n"
706                         "    Stop a service"
707                 },
708                 {
709                         "pause",
710                         rpc_service_pause,
711                         NET_TRANSPORT_RPC,
712                         "Pause a service",
713                         "net rpc service pause\n"
714                         "    Pause a service"
715                 },
716                 {
717                         "resume",
718                         rpc_service_resume,
719                         NET_TRANSPORT_RPC,
720                         "Resume a paused service",
721                         "net rpc service resume\n"
722                         "    Resume a service"
723                 },
724                 {
725                         "status",
726                         rpc_service_status,
727                         NET_TRANSPORT_RPC,
728                         "View current status of a service",
729                         "net rpc service status\n"
730                         "    View current status of a service"
731                 },
732                 {NULL, NULL, 0, NULL, NULL}
733         };
734
735         return net_run_function(c, argc, argv, "net rpc service",func);
736 }