2
Samba Unix/Linux SMB client library
3
Distributed SMB/CIFS Server Management Utility
4
Copyright (C) Gerald (Jerry) Carter 2005
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.
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.
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/>. */
20
#include "utils/net.h"
23
struct svc_state_msg {
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" },
40
/********************************************************************
41
********************************************************************/
42
const char *svc_status_string( uint32 state )
47
fstr_sprintf( msg, "Unknown State [%d]", state );
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 );
56
return talloc_strdup(talloc_tos(), msg);
59
/********************************************************************
60
********************************************************************/
62
static WERROR query_service_state(struct rpc_pipe_client *pipe_hnd,
64
struct policy_handle *hSCM,
68
struct policy_handle hService;
69
struct SERVICE_STATUS service_status;
70
WERROR result = WERR_GENERAL_FAILURE;
73
/* now cycle until the status is actually 'watch_state' */
75
status = rpccli_svcctl_OpenServiceW(pipe_hnd, mem_ctx,
78
SC_RIGHT_SVC_QUERY_STATUS,
81
if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result) ) {
82
d_fprintf(stderr, "Failed to open service. [%s]\n", win_errstr(result));
86
status = rpccli_svcctl_QueryServiceStatus(pipe_hnd, mem_ctx,
91
if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result) ) {
92
*state = service_status.state;
95
rpccli_svcctl_CloseServiceHandle(pipe_hnd, mem_ctx, &hService, NULL);
100
/********************************************************************
101
********************************************************************/
103
static WERROR watch_service_state(struct rpc_pipe_client *pipe_hnd,
105
struct policy_handle *hSCM,
108
uint32 *final_state )
112
WERROR result = WERR_GENERAL_FAILURE;
116
while ( (state != watch_state ) && i<30 ) {
119
result = query_service_state(pipe_hnd, mem_ctx, hSCM, service, &state );
120
if ( !W_ERROR_IS_OK(result) ) {
130
*final_state = state;
135
/********************************************************************
136
********************************************************************/
138
static WERROR control_service(struct rpc_pipe_client *pipe_hnd,
140
struct policy_handle *hSCM,
145
struct policy_handle hService;
146
WERROR result = WERR_GENERAL_FAILURE;
148
struct SERVICE_STATUS service_status;
151
/* Open the Service */
153
status = rpccli_svcctl_OpenServiceW(pipe_hnd, mem_ctx,
156
(SC_RIGHT_SVC_STOP|SC_RIGHT_SVC_PAUSE_CONTINUE),
160
if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result) ) {
161
d_fprintf(stderr, "Failed to open service. [%s]\n", win_errstr(result));
167
status = rpccli_svcctl_ControlService(pipe_hnd, mem_ctx,
173
if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result) ) {
174
d_fprintf(stderr, "Control service request failed. [%s]\n", win_errstr(result));
178
/* loop -- checking the state until we are where we want to be */
180
result = watch_service_state(pipe_hnd, mem_ctx, hSCM, service, watch_state, &state );
182
d_printf("%s service is %s.\n", service, svc_status_string(state));
185
rpccli_svcctl_CloseServiceHandle(pipe_hnd, mem_ctx, &hService, NULL);
190
/********************************************************************
191
********************************************************************/
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,
202
struct policy_handle hSCM;
203
struct ENUM_SERVICE_STATUSW *services = NULL;
204
WERROR result = WERR_GENERAL_FAILURE;
208
uint8_t *buffer = NULL;
209
uint32_t buf_size = 0;
210
uint32_t bytes_needed = 0;
211
uint32_t num_services = 0;
212
uint32_t resume_handle = 0;
215
d_printf("Usage: net rpc service list\n");
219
status = rpccli_svcctl_OpenSCManagerW(pipe_hnd, mem_ctx,
220
pipe_hnd->srv_name_slash,
222
SC_RIGHT_MGR_ENUMERATE_SERVICE,
225
if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result)) {
226
d_fprintf(stderr, "Failed to open Service Control Manager. [%s]\n", win_errstr(result));
227
return werror_to_ntstatus(result);
231
status = rpccli_svcctl_EnumServicesStatusW(pipe_hnd, mem_ctx,
242
if (NT_STATUS_IS_ERR(status)) {
243
d_fprintf(stderr, "Failed to enumerate services. [%s]\n",
248
if (W_ERROR_EQUAL(result, WERR_MORE_DATA) && bytes_needed > 0) {
249
buffer = talloc_array(mem_ctx, uint8_t, bytes_needed);
250
buf_size = bytes_needed;
254
if ( num_services == 0 ) {
255
d_printf("No services returned\n");
260
enum ndr_err_code ndr_err;
262
struct ndr_pull *ndr;
264
blob.length = buf_size;
265
blob.data = talloc_steal(mem_ctx, buffer);
267
services = talloc_array(mem_ctx, struct ENUM_SERVICE_STATUSW, num_services);
269
status = NT_STATUS_NO_MEMORY;
273
ndr = ndr_pull_init_blob(&blob, mem_ctx, NULL);
275
status = NT_STATUS_NO_MEMORY;
279
ndr_err = ndr_pull_ENUM_SERVICE_STATUSW_array(
280
ndr, num_services, services);
281
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
282
status = ndr_map_error2ntstatus(ndr_err);
286
for ( i=0; i<num_services; i++ ) {
287
d_printf("%-20s \"%s\"\n",
288
services[i].service_name,
289
services[i].display_name);
293
} while (W_ERROR_EQUAL(result, WERR_MORE_DATA));
295
rpccli_svcctl_CloseServiceHandle(pipe_hnd, mem_ctx, &hSCM, NULL);
300
/********************************************************************
301
********************************************************************/
303
static NTSTATUS rpc_service_status_internal(struct net_context *c,
304
const DOM_SID *domain_sid,
305
const char *domain_name,
306
struct cli_state *cli,
307
struct rpc_pipe_client *pipe_hnd,
312
struct policy_handle hSCM, hService;
313
WERROR result = WERR_GENERAL_FAILURE;
315
struct SERVICE_STATUS service_status;
316
struct QUERY_SERVICE_CONFIG config;
317
uint32_t buf_size = sizeof(config);
318
uint32_t ret_size = 0;
321
d_printf("Usage: net rpc service status <service>\n");
325
/* Open the Service Control Manager */
326
status = rpccli_svcctl_OpenSCManagerW(pipe_hnd, mem_ctx,
327
pipe_hnd->srv_name_slash,
329
SC_RIGHT_MGR_ENUMERATE_SERVICE,
332
if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result)) {
333
d_fprintf(stderr, "Failed to open Service Control Manager. [%s]\n", win_errstr(result));
334
return werror_to_ntstatus(result);
337
/* Open the Service */
339
status = rpccli_svcctl_OpenServiceW(pipe_hnd, mem_ctx,
342
(SC_RIGHT_SVC_QUERY_STATUS|SC_RIGHT_SVC_QUERY_CONFIG),
346
if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result) ) {
347
d_fprintf(stderr, "Failed to open service. [%s]\n", win_errstr(result));
353
status = rpccli_svcctl_QueryServiceStatus(pipe_hnd, mem_ctx,
358
if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result) ) {
359
d_fprintf(stderr, "Query status request failed. [%s]\n", win_errstr(result));
363
d_printf("%s service is %s.\n", argv[0], svc_status_string(service_status.state));
367
status = rpccli_svcctl_QueryServiceConfigW(pipe_hnd, mem_ctx,
373
if (W_ERROR_EQUAL(result, WERR_INSUFFICIENT_BUFFER)) {
375
status = rpccli_svcctl_QueryServiceConfigW(pipe_hnd, mem_ctx,
383
if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result) ) {
384
d_fprintf(stderr, "Query config request failed. [%s]\n", win_errstr(result));
388
/* print out the configuration information for the service */
390
d_printf("Configuration details:\n");
391
d_printf("\tControls Accepted = 0x%x\n", service_status.controls_accepted);
392
d_printf("\tService Type = 0x%x\n", config.service_type);
393
d_printf("\tStart Type = 0x%x\n", config.start_type);
394
d_printf("\tError Control = 0x%x\n", config.error_control);
395
d_printf("\tTag ID = 0x%x\n", config.tag_id);
397
if (config.executablepath) {
398
d_printf("\tExecutable Path = %s\n", config.executablepath);
401
if (config.loadordergroup) {
402
d_printf("\tLoad Order Group = %s\n", config.loadordergroup);
405
if (config.dependencies) {
406
d_printf("\tDependencies = %s\n", config.dependencies);
409
if (config.startname) {
410
d_printf("\tStart Name = %s\n", config.startname);
413
if (config.displayname) {
414
d_printf("\tDisplay Name = %s\n", config.displayname);
418
rpccli_svcctl_CloseServiceHandle(pipe_hnd, mem_ctx, &hService, NULL);
419
rpccli_svcctl_CloseServiceHandle(pipe_hnd, mem_ctx, &hSCM, NULL);
421
return werror_to_ntstatus(result);
424
/********************************************************************
425
********************************************************************/
427
static NTSTATUS rpc_service_stop_internal(struct net_context *c,
428
const DOM_SID *domain_sid,
429
const char *domain_name,
430
struct cli_state *cli,
431
struct rpc_pipe_client *pipe_hnd,
436
struct policy_handle hSCM;
437
WERROR result = WERR_GENERAL_FAILURE;
442
d_printf("Usage: net rpc service status <service>\n");
446
fstrcpy( servicename, argv[0] );
448
/* Open the Service Control Manager */
449
status = rpccli_svcctl_OpenSCManagerW(pipe_hnd, mem_ctx,
450
pipe_hnd->srv_name_slash,
452
SC_RIGHT_MGR_ENUMERATE_SERVICE,
455
if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result)) {
456
d_fprintf(stderr, "Failed to open Service Control Manager. [%s]\n", win_errstr(result));
457
return werror_to_ntstatus(result);
460
result = control_service(pipe_hnd, mem_ctx, &hSCM, servicename,
461
SVCCTL_CONTROL_STOP, SVCCTL_STOPPED );
463
rpccli_svcctl_CloseServiceHandle(pipe_hnd, mem_ctx, &hSCM, NULL);
465
return werror_to_ntstatus(result);
468
/********************************************************************
469
********************************************************************/
471
static NTSTATUS rpc_service_pause_internal(struct net_context *c,
472
const DOM_SID *domain_sid,
473
const char *domain_name,
474
struct cli_state *cli,
475
struct rpc_pipe_client *pipe_hnd,
480
struct policy_handle hSCM;
481
WERROR result = WERR_GENERAL_FAILURE;
486
d_printf("Usage: net rpc service status <service>\n");
490
fstrcpy( servicename, argv[0] );
492
/* Open the Service Control Manager */
493
status = rpccli_svcctl_OpenSCManagerW(pipe_hnd, mem_ctx,
494
pipe_hnd->srv_name_slash,
496
SC_RIGHT_MGR_ENUMERATE_SERVICE,
499
if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result)) {
500
d_fprintf(stderr, "Failed to open Service Control Manager. [%s]\n", win_errstr(result));
501
return werror_to_ntstatus(result);
504
result = control_service(pipe_hnd, mem_ctx, &hSCM, servicename,
505
SVCCTL_CONTROL_PAUSE, SVCCTL_PAUSED );
507
rpccli_svcctl_CloseServiceHandle(pipe_hnd, mem_ctx, &hSCM, NULL);
509
return werror_to_ntstatus(result);
512
/********************************************************************
513
********************************************************************/
515
static NTSTATUS rpc_service_resume_internal(struct net_context *c,
516
const DOM_SID *domain_sid,
517
const char *domain_name,
518
struct cli_state *cli,
519
struct rpc_pipe_client *pipe_hnd,
524
struct policy_handle hSCM;
525
WERROR result = WERR_GENERAL_FAILURE;
530
d_printf("Usage: net rpc service status <service>\n");
534
fstrcpy( servicename, argv[0] );
536
/* Open the Service Control Manager */
537
status = rpccli_svcctl_OpenSCManagerW(pipe_hnd, mem_ctx,
538
pipe_hnd->srv_name_slash,
540
SC_RIGHT_MGR_ENUMERATE_SERVICE,
543
if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result)) {
544
d_fprintf(stderr, "Failed to open Service Control Manager. [%s]\n", win_errstr(result));
545
return werror_to_ntstatus(result);
548
result = control_service(pipe_hnd, mem_ctx, &hSCM, servicename,
549
SVCCTL_CONTROL_CONTINUE, SVCCTL_RUNNING );
551
rpccli_svcctl_CloseServiceHandle(pipe_hnd, mem_ctx, &hSCM, NULL);
553
return werror_to_ntstatus(result);
556
/********************************************************************
557
********************************************************************/
559
static NTSTATUS rpc_service_start_internal(struct net_context *c,
560
const DOM_SID *domain_sid,
561
const char *domain_name,
562
struct cli_state *cli,
563
struct rpc_pipe_client *pipe_hnd,
568
struct policy_handle hSCM, hService;
569
WERROR result = WERR_GENERAL_FAILURE;
574
d_printf("Usage: net rpc service status <service>\n");
578
/* Open the Service Control Manager */
579
status = rpccli_svcctl_OpenSCManagerW(pipe_hnd, mem_ctx,
580
pipe_hnd->srv_name_slash,
582
SC_RIGHT_MGR_ENUMERATE_SERVICE,
585
if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result)) {
586
d_fprintf(stderr, "Failed to open Service Control Manager. [%s]\n", win_errstr(result));
587
return werror_to_ntstatus(result);
590
/* Open the Service */
592
status = rpccli_svcctl_OpenServiceW(pipe_hnd, mem_ctx,
599
if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result) ) {
600
d_fprintf(stderr, "Failed to open service. [%s]\n", win_errstr(result));
606
status = rpccli_svcctl_StartServiceW(pipe_hnd, mem_ctx,
612
if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result) ) {
613
d_fprintf(stderr, "Query status request failed. [%s]\n", win_errstr(result));
617
result = watch_service_state(pipe_hnd, mem_ctx, &hSCM, argv[0], SVCCTL_RUNNING, &state );
619
if ( W_ERROR_IS_OK(result) && (state == SVCCTL_RUNNING) )
620
d_printf("Successfully started service: %s\n", argv[0] );
622
d_fprintf(stderr, "Failed to start service: %s [%s]\n", argv[0], win_errstr(result) );
625
rpccli_svcctl_CloseServiceHandle(pipe_hnd, mem_ctx, &hService, NULL);
626
rpccli_svcctl_CloseServiceHandle(pipe_hnd, mem_ctx, &hSCM, NULL);
628
return werror_to_ntstatus(result);
631
/********************************************************************
632
********************************************************************/
634
static NTSTATUS rpc_service_delete_internal(struct net_context *c,
635
const DOM_SID *domain_sid,
636
const char *domain_name,
637
struct cli_state *cli,
638
struct rpc_pipe_client *pipe_hnd,
643
struct policy_handle hSCM, hService;
644
WERROR result = WERR_GENERAL_FAILURE;
648
d_printf("Usage: net rpc service delete <service>\n");
652
/* Open the Service Control Manager */
653
status = rpccli_svcctl_OpenSCManagerW(pipe_hnd, mem_ctx,
654
pipe_hnd->srv_name_slash,
656
SC_RIGHT_MGR_ENUMERATE_SERVICE,
659
if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result)) {
660
d_fprintf(stderr, "Failed to open Service Control Manager. [%s]\n",
662
return werror_to_ntstatus(result);
665
/* Open the Service */
667
status = rpccli_svcctl_OpenServiceW(pipe_hnd, mem_ctx,
674
if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result) ) {
675
d_fprintf(stderr, "Failed to open service. [%s]\n",
680
/* Delete the Service */
682
status = rpccli_svcctl_DeleteService(pipe_hnd, mem_ctx,
686
if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result) ) {
687
d_fprintf(stderr, "Delete service request failed. [%s]\n",
692
d_printf("Successfully deleted Service: %s\n", argv[0]);
695
if (is_valid_policy_hnd(&hService)) {
696
rpccli_svcctl_CloseServiceHandle(pipe_hnd, mem_ctx, &hService, NULL);
698
if (is_valid_policy_hnd(&hSCM)) {
699
rpccli_svcctl_CloseServiceHandle(pipe_hnd, mem_ctx, &hSCM, NULL);
702
return werror_to_ntstatus(result);
705
/********************************************************************
706
********************************************************************/
708
static NTSTATUS rpc_service_create_internal(struct net_context *c,
709
const DOM_SID *domain_sid,
710
const char *domain_name,
711
struct cli_state *cli,
712
struct rpc_pipe_client *pipe_hnd,
717
struct policy_handle hSCM, hService;
718
WERROR result = WERR_GENERAL_FAILURE;
720
const char *ServiceName;
721
const char *DisplayName;
722
const char *binary_path;
725
d_printf("Usage: net rpc service create <service> <displayname> <binarypath>\n");
729
/* Open the Service Control Manager */
730
status = rpccli_svcctl_OpenSCManagerW(pipe_hnd, mem_ctx,
731
pipe_hnd->srv_name_slash,
733
SC_RIGHT_MGR_CREATE_SERVICE,
736
if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result)) {
737
d_fprintf(stderr, "Failed to open Service Control Manager. [%s]\n",
739
return werror_to_ntstatus(result);
742
/* Create the service */
744
ServiceName = argv[0];
745
DisplayName = argv[1];
746
binary_path = argv[2];
748
status = rpccli_svcctl_CreateServiceW(pipe_hnd, mem_ctx,
753
SERVICE_TYPE_WIN32_OWN_PROCESS,
755
SVCCTL_SVC_ERROR_NORMAL,
757
NULL, /* LoadOrderGroupKey */
759
NULL, /* dependencies */
760
0, /* dependencies_size */
761
NULL, /* service_start_name */
763
0, /* password_size */
767
if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result) ) {
768
d_fprintf(stderr, "Create service request failed. [%s]\n",
773
d_printf("Successfully created Service: %s\n", argv[0]);
776
if (is_valid_policy_hnd(&hService)) {
777
rpccli_svcctl_CloseServiceHandle(pipe_hnd, mem_ctx, &hService, NULL);
779
if (is_valid_policy_hnd(&hSCM)) {
780
rpccli_svcctl_CloseServiceHandle(pipe_hnd, mem_ctx, &hSCM, NULL);
783
return werror_to_ntstatus(result);
786
/********************************************************************
787
********************************************************************/
789
static int rpc_service_list(struct net_context *c, int argc, const char **argv )
791
if (c->display_usage) {
793
"net rpc service list\n"
794
" View configured Win32 services\n");
798
return run_rpc_command(c, NULL, &ndr_table_svcctl.syntax_id, 0,
799
rpc_service_list_internal, argc, argv );
802
/********************************************************************
803
********************************************************************/
805
static int rpc_service_start(struct net_context *c, int argc, const char **argv )
807
if (c->display_usage) {
809
"net rpc service start <service>\n"
810
" Start a Win32 service\n");
814
return run_rpc_command(c, NULL, &ndr_table_svcctl.syntax_id, 0,
815
rpc_service_start_internal, argc, argv );
818
/********************************************************************
819
********************************************************************/
821
static int rpc_service_stop(struct net_context *c, int argc, const char **argv )
823
if (c->display_usage) {
825
"net rpc service stop <service>\n"
826
" Stop a Win32 service\n");
830
return run_rpc_command(c, NULL, &ndr_table_svcctl.syntax_id, 0,
831
rpc_service_stop_internal, argc, argv );
834
/********************************************************************
835
********************************************************************/
837
static int rpc_service_resume(struct net_context *c, int argc, const char **argv )
839
if (c->display_usage) {
841
"net rpc service resume <service>\n"
842
" Resume a Win32 service\n");
846
return run_rpc_command(c, NULL, &ndr_table_svcctl.syntax_id, 0,
847
rpc_service_resume_internal, argc, argv );
850
/********************************************************************
851
********************************************************************/
853
static int rpc_service_pause(struct net_context *c, int argc, const char **argv )
855
if (c->display_usage) {
857
"net rpc service pause <service>\n"
858
" Pause a Win32 service\n");
862
return run_rpc_command(c, NULL, &ndr_table_svcctl.syntax_id, 0,
863
rpc_service_pause_internal, argc, argv );
866
/********************************************************************
867
********************************************************************/
869
static int rpc_service_status(struct net_context *c, int argc, const char **argv )
871
if (c->display_usage) {
873
"net rpc service status <service>\n"
874
" Show the current status of a service\n");
878
return run_rpc_command(c, NULL, &ndr_table_svcctl.syntax_id, 0,
879
rpc_service_status_internal, argc, argv );
882
/********************************************************************
883
********************************************************************/
885
static int rpc_service_delete(struct net_context *c, int argc, const char **argv)
887
if (c->display_usage) {
889
"net rpc service delete <service>\n"
890
" Delete a Win32 service\n");
894
return run_rpc_command(c, NULL, &ndr_table_svcctl.syntax_id, 0,
895
rpc_service_delete_internal, argc, argv);
898
/********************************************************************
899
********************************************************************/
901
static int rpc_service_create(struct net_context *c, int argc, const char **argv)
903
if (c->display_usage) {
905
"net rpc service create <service>\n"
906
" Create a Win32 service\n");
910
return run_rpc_command(c, NULL, &ndr_table_svcctl.syntax_id, 0,
911
rpc_service_create_internal, argc, argv);
914
/********************************************************************
915
********************************************************************/
917
int net_rpc_service(struct net_context *c, int argc, const char **argv)
919
struct functable func[] = {
924
"View configured Win32 services",
925
"net rpc service list\n"
926
" View configured Win32 services"
933
"net rpc service start\n"
941
"net rpc service stop\n"
949
"net rpc service pause\n"
956
"Resume a paused service",
957
"net rpc service resume\n"
964
"View current status of a service",
965
"net rpc service status\n"
966
" View current status of a service"
973
"net rpc service delete\n"
981
"net rpc service create\n"
985
{NULL, NULL, 0, NULL, NULL}
988
return net_run_function(c, argc, argv, "net rpc service",func);