~zulcss/samba/server-dailies-3.4

« back to all changes in this revision

Viewing changes to source3/utils/net_rpc_service.c

  • Committer: Chuck Short
  • Date: 2010-09-28 20:38:39 UTC
  • Revision ID: zulcss@ubuntu.com-20100928203839-pgjulytsi9ue63x1
Initial version

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
                                struct policy_handle *hSCM,
 
65
                                const char *service,
 
66
                                uint32 *state )
 
67
{
 
68
        struct policy_handle hService;
 
69
        struct 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", win_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
                                struct policy_handle *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
                                struct policy_handle *hSCM,
 
141
                                const char *service,
 
142
                                uint32 control,
 
143
                                uint32 watch_state )
 
144
{
 
145
        struct policy_handle hService;
 
146
        WERROR result = WERR_GENERAL_FAILURE;
 
147
        NTSTATUS status;
 
148
        struct 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", win_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", win_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
        struct policy_handle hSCM;
 
203
        struct ENUM_SERVICE_STATUSW *services = NULL;
 
204
        WERROR result = WERR_GENERAL_FAILURE;
 
205
        NTSTATUS status;
 
206
        int i;
 
207
 
 
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;
 
213
 
 
214
        if (argc != 0 ) {
 
215
                d_printf("Usage: net rpc service list\n");
 
216
                return NT_STATUS_OK;
 
217
        }
 
218
 
 
219
        status = rpccli_svcctl_OpenSCManagerW(pipe_hnd, mem_ctx,
 
220
                                              pipe_hnd->srv_name_slash,
 
221
                                              NULL,
 
222
                                              SC_RIGHT_MGR_ENUMERATE_SERVICE,
 
223
                                              &hSCM,
 
224
                                              &result);
 
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);
 
228
        }
 
229
 
 
230
        do {
 
231
                status = rpccli_svcctl_EnumServicesStatusW(pipe_hnd, mem_ctx,
 
232
                                                           &hSCM,
 
233
                                                           SERVICE_TYPE_WIN32,
 
234
                                                           SERVICE_STATE_ALL,
 
235
                                                           buffer,
 
236
                                                           buf_size,
 
237
                                                           &bytes_needed,
 
238
                                                           &num_services,
 
239
                                                           &resume_handle,
 
240
                                                           &result);
 
241
 
 
242
                if (NT_STATUS_IS_ERR(status)) {
 
243
                        d_fprintf(stderr, "Failed to enumerate services.  [%s]\n",
 
244
                                win_errstr(result));
 
245
                        break;
 
246
                }
 
247
 
 
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;
 
251
                        continue;
 
252
                }
 
253
 
 
254
                if ( num_services == 0 ) {
 
255
                        d_printf("No services returned\n");
 
256
                        break;
 
257
                }
 
258
 
 
259
                {
 
260
                        enum ndr_err_code ndr_err;
 
261
                        DATA_BLOB blob;
 
262
                        struct ndr_pull *ndr;
 
263
 
 
264
                        blob.length = buf_size;
 
265
                        blob.data = talloc_steal(mem_ctx, buffer);
 
266
 
 
267
                        services = talloc_array(mem_ctx, struct ENUM_SERVICE_STATUSW, num_services);
 
268
                        if (!services) {
 
269
                                status = NT_STATUS_NO_MEMORY;
 
270
                                break;
 
271
                        }
 
272
 
 
273
                        ndr = ndr_pull_init_blob(&blob, mem_ctx, NULL);
 
274
                        if (ndr == NULL) {
 
275
                                status = NT_STATUS_NO_MEMORY;
 
276
                                break;
 
277
                        }
 
278
 
 
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);
 
283
                                break;
 
284
                        }
 
285
 
 
286
                        for ( i=0; i<num_services; i++ ) {
 
287
                                d_printf("%-20s    \"%s\"\n",
 
288
                                        services[i].service_name,
 
289
                                        services[i].display_name);
 
290
                        }
 
291
                }
 
292
 
 
293
        } while (W_ERROR_EQUAL(result, WERR_MORE_DATA));
 
294
 
 
295
        rpccli_svcctl_CloseServiceHandle(pipe_hnd, mem_ctx, &hSCM, NULL);
 
296
 
 
297
        return status;
 
298
}
 
299
 
 
300
/********************************************************************
 
301
********************************************************************/
 
302
 
 
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,
 
308
                                                TALLOC_CTX *mem_ctx,
 
309
                                                int argc,
 
310
                                                const char **argv )
 
311
{
 
312
        struct policy_handle hSCM, hService;
 
313
        WERROR result = WERR_GENERAL_FAILURE;
 
314
        NTSTATUS status;
 
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;
 
319
 
 
320
        if (argc != 1 ) {
 
321
                d_printf("Usage: net rpc service status <service>\n");
 
322
                return NT_STATUS_OK;
 
323
        }
 
324
 
 
325
        /* Open the Service Control Manager */
 
326
        status = rpccli_svcctl_OpenSCManagerW(pipe_hnd, mem_ctx,
 
327
                                              pipe_hnd->srv_name_slash,
 
328
                                              NULL,
 
329
                                              SC_RIGHT_MGR_ENUMERATE_SERVICE,
 
330
                                              &hSCM,
 
331
                                              &result);
 
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);
 
335
        }
 
336
 
 
337
        /* Open the Service */
 
338
 
 
339
        status = rpccli_svcctl_OpenServiceW(pipe_hnd, mem_ctx,
 
340
                                            &hSCM,
 
341
                                            argv[0],
 
342
                                            (SC_RIGHT_SVC_QUERY_STATUS|SC_RIGHT_SVC_QUERY_CONFIG),
 
343
                                            &hService,
 
344
                                            &result);
 
345
 
 
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));
 
348
                goto done;
 
349
        }
 
350
 
 
351
        /* get the status */
 
352
 
 
353
        status = rpccli_svcctl_QueryServiceStatus(pipe_hnd, mem_ctx,
 
354
                                                  &hService,
 
355
                                                  &service_status,
 
356
                                                  &result);
 
357
 
 
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));
 
360
                goto done;
 
361
        }
 
362
 
 
363
        d_printf("%s service is %s.\n", argv[0], svc_status_string(service_status.state));
 
364
 
 
365
        /* get the config */
 
366
 
 
367
        status = rpccli_svcctl_QueryServiceConfigW(pipe_hnd, mem_ctx,
 
368
                                                   &hService,
 
369
                                                   &config,
 
370
                                                   buf_size,
 
371
                                                   &ret_size,
 
372
                                                   &result);
 
373
        if (W_ERROR_EQUAL(result, WERR_INSUFFICIENT_BUFFER)) {
 
374
                buf_size = ret_size;
 
375
                status = rpccli_svcctl_QueryServiceConfigW(pipe_hnd, mem_ctx,
 
376
                                                           &hService,
 
377
                                                           &config,
 
378
                                                           buf_size,
 
379
                                                           &ret_size,
 
380
                                                           &result);
 
381
        }
 
382
 
 
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));
 
385
                goto done;
 
386
        }
 
387
 
 
388
        /* print out the configuration information for the service */
 
389
 
 
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);
 
396
 
 
397
        if (config.executablepath) {
 
398
                d_printf("\tExecutable Path      = %s\n", config.executablepath);
 
399
        }
 
400
 
 
401
        if (config.loadordergroup) {
 
402
                d_printf("\tLoad Order Group     = %s\n", config.loadordergroup);
 
403
        }
 
404
 
 
405
        if (config.dependencies) {
 
406
                d_printf("\tDependencies         = %s\n", config.dependencies);
 
407
        }
 
408
 
 
409
        if (config.startname) {
 
410
                d_printf("\tStart Name           = %s\n", config.startname);
 
411
        }
 
412
 
 
413
        if (config.displayname) {
 
414
                d_printf("\tDisplay Name         = %s\n", config.displayname);
 
415
        }
 
416
 
 
417
done:
 
418
        rpccli_svcctl_CloseServiceHandle(pipe_hnd, mem_ctx, &hService, NULL);
 
419
        rpccli_svcctl_CloseServiceHandle(pipe_hnd, mem_ctx, &hSCM, NULL);
 
420
 
 
421
        return werror_to_ntstatus(result);
 
422
}
 
423
 
 
424
/********************************************************************
 
425
********************************************************************/
 
426
 
 
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,
 
432
                                        TALLOC_CTX *mem_ctx,
 
433
                                        int argc,
 
434
                                        const char **argv )
 
435
{
 
436
        struct policy_handle hSCM;
 
437
        WERROR result = WERR_GENERAL_FAILURE;
 
438
        NTSTATUS status;
 
439
        fstring servicename;
 
440
 
 
441
        if (argc != 1 ) {
 
442
                d_printf("Usage: net rpc service status <service>\n");
 
443
                return NT_STATUS_OK;
 
444
        }
 
445
 
 
446
        fstrcpy( servicename, argv[0] );
 
447
 
 
448
        /* Open the Service Control Manager */
 
449
        status = rpccli_svcctl_OpenSCManagerW(pipe_hnd, mem_ctx,
 
450
                                              pipe_hnd->srv_name_slash,
 
451
                                              NULL,
 
452
                                              SC_RIGHT_MGR_ENUMERATE_SERVICE,
 
453
                                              &hSCM,
 
454
                                              &result);
 
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);
 
458
        }
 
459
 
 
460
        result = control_service(pipe_hnd, mem_ctx, &hSCM, servicename,
 
461
                SVCCTL_CONTROL_STOP, SVCCTL_STOPPED );
 
462
 
 
463
        rpccli_svcctl_CloseServiceHandle(pipe_hnd, mem_ctx, &hSCM, NULL);
 
464
 
 
465
        return werror_to_ntstatus(result);
 
466
}
 
467
 
 
468
/********************************************************************
 
469
********************************************************************/
 
470
 
 
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,
 
476
                                        TALLOC_CTX *mem_ctx,
 
477
                                        int argc,
 
478
                                        const char **argv )
 
479
{
 
480
        struct policy_handle hSCM;
 
481
        WERROR result = WERR_GENERAL_FAILURE;
 
482
        NTSTATUS status;
 
483
        fstring servicename;
 
484
 
 
485
        if (argc != 1 ) {
 
486
                d_printf("Usage: net rpc service status <service>\n");
 
487
                return NT_STATUS_OK;
 
488
        }
 
489
 
 
490
        fstrcpy( servicename, argv[0] );
 
491
 
 
492
        /* Open the Service Control Manager */
 
493
        status = rpccli_svcctl_OpenSCManagerW(pipe_hnd, mem_ctx,
 
494
                                              pipe_hnd->srv_name_slash,
 
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", win_errstr(result));
 
501
                return werror_to_ntstatus(result);
 
502
        }
 
503
 
 
504
        result = control_service(pipe_hnd, mem_ctx, &hSCM, servicename,
 
505
                SVCCTL_CONTROL_PAUSE, SVCCTL_PAUSED );
 
506
 
 
507
        rpccli_svcctl_CloseServiceHandle(pipe_hnd, mem_ctx, &hSCM, NULL);
 
508
 
 
509
        return werror_to_ntstatus(result);
 
510
}
 
511
 
 
512
/********************************************************************
 
513
********************************************************************/
 
514
 
 
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,
 
520
                                        TALLOC_CTX *mem_ctx,
 
521
                                        int argc,
 
522
                                        const char **argv )
 
523
{
 
524
        struct policy_handle hSCM;
 
525
        WERROR result = WERR_GENERAL_FAILURE;
 
526
        NTSTATUS status;
 
527
        fstring servicename;
 
528
 
 
529
        if (argc != 1 ) {
 
530
                d_printf("Usage: net rpc service status <service>\n");
 
531
                return NT_STATUS_OK;
 
532
        }
 
533
 
 
534
        fstrcpy( servicename, argv[0] );
 
535
 
 
536
        /* Open the Service Control Manager */
 
537
        status = rpccli_svcctl_OpenSCManagerW(pipe_hnd, mem_ctx,
 
538
                                              pipe_hnd->srv_name_slash,
 
539
                                              NULL,
 
540
                                              SC_RIGHT_MGR_ENUMERATE_SERVICE,
 
541
                                              &hSCM,
 
542
                                              &result);
 
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);
 
546
        }
 
547
 
 
548
        result = control_service(pipe_hnd, mem_ctx, &hSCM, servicename,
 
549
                SVCCTL_CONTROL_CONTINUE, SVCCTL_RUNNING );
 
550
 
 
551
        rpccli_svcctl_CloseServiceHandle(pipe_hnd, mem_ctx, &hSCM, NULL);
 
552
 
 
553
        return werror_to_ntstatus(result);
 
554
}
 
555
 
 
556
/********************************************************************
 
557
********************************************************************/
 
558
 
 
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,
 
564
                                        TALLOC_CTX *mem_ctx,
 
565
                                        int argc,
 
566
                                        const char **argv )
 
567
{
 
568
        struct policy_handle hSCM, hService;
 
569
        WERROR result = WERR_GENERAL_FAILURE;
 
570
        NTSTATUS status;
 
571
        uint32 state = 0;
 
572
 
 
573
        if (argc != 1 ) {
 
574
                d_printf("Usage: net rpc service status <service>\n");
 
575
                return NT_STATUS_OK;
 
576
        }
 
577
 
 
578
        /* Open the Service Control Manager */
 
579
        status = rpccli_svcctl_OpenSCManagerW(pipe_hnd, mem_ctx,
 
580
                                              pipe_hnd->srv_name_slash,
 
581
                                              NULL,
 
582
                                              SC_RIGHT_MGR_ENUMERATE_SERVICE,
 
583
                                              &hSCM,
 
584
                                              &result);
 
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);
 
588
        }
 
589
 
 
590
        /* Open the Service */
 
591
 
 
592
        status = rpccli_svcctl_OpenServiceW(pipe_hnd, mem_ctx,
 
593
                                            &hSCM,
 
594
                                            argv[0],
 
595
                                            SC_RIGHT_SVC_START,
 
596
                                            &hService,
 
597
                                            &result);
 
598
 
 
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));
 
601
                goto done;
 
602
        }
 
603
 
 
604
        /* get the status */
 
605
 
 
606
        status = rpccli_svcctl_StartServiceW(pipe_hnd, mem_ctx,
 
607
                                             &hService,
 
608
                                             0,
 
609
                                             NULL,
 
610
                                             &result);
 
611
 
 
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));
 
614
                goto done;
 
615
        }
 
616
 
 
617
        result = watch_service_state(pipe_hnd, mem_ctx, &hSCM, argv[0], SVCCTL_RUNNING, &state  );
 
618
 
 
619
        if ( W_ERROR_IS_OK(result) && (state == SVCCTL_RUNNING) )
 
620
                d_printf("Successfully started service: %s\n", argv[0] );
 
621
        else
 
622
                d_fprintf(stderr, "Failed to start service: %s [%s]\n", argv[0], win_errstr(result) );
 
623
 
 
624
done:
 
625
        rpccli_svcctl_CloseServiceHandle(pipe_hnd, mem_ctx, &hService, NULL);
 
626
        rpccli_svcctl_CloseServiceHandle(pipe_hnd, mem_ctx, &hSCM, NULL);
 
627
 
 
628
        return werror_to_ntstatus(result);
 
629
}
 
630
 
 
631
/********************************************************************
 
632
********************************************************************/
 
633
 
 
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,
 
639
                                            TALLOC_CTX *mem_ctx,
 
640
                                            int argc,
 
641
                                            const char **argv)
 
642
{
 
643
        struct policy_handle hSCM, hService;
 
644
        WERROR result = WERR_GENERAL_FAILURE;
 
645
        NTSTATUS status;
 
646
 
 
647
        if (argc != 1 ) {
 
648
                d_printf("Usage: net rpc service delete <service>\n");
 
649
                return NT_STATUS_OK;
 
650
        }
 
651
 
 
652
        /* Open the Service Control Manager */
 
653
        status = rpccli_svcctl_OpenSCManagerW(pipe_hnd, mem_ctx,
 
654
                                              pipe_hnd->srv_name_slash,
 
655
                                              NULL,
 
656
                                              SC_RIGHT_MGR_ENUMERATE_SERVICE,
 
657
                                              &hSCM,
 
658
                                              &result);
 
659
        if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result)) {
 
660
                d_fprintf(stderr, "Failed to open Service Control Manager.  [%s]\n",
 
661
                        win_errstr(result));
 
662
                return werror_to_ntstatus(result);
 
663
        }
 
664
 
 
665
        /* Open the Service */
 
666
 
 
667
        status = rpccli_svcctl_OpenServiceW(pipe_hnd, mem_ctx,
 
668
                                            &hSCM,
 
669
                                            argv[0],
 
670
                                            SERVICE_ALL_ACCESS,
 
671
                                            &hService,
 
672
                                            &result);
 
673
 
 
674
        if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result) ) {
 
675
                d_fprintf(stderr, "Failed to open service.  [%s]\n",
 
676
                        win_errstr(result));
 
677
                goto done;
 
678
        }
 
679
 
 
680
        /* Delete the Service */
 
681
 
 
682
        status = rpccli_svcctl_DeleteService(pipe_hnd, mem_ctx,
 
683
                                             &hService,
 
684
                                             &result);
 
685
 
 
686
        if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result) ) {
 
687
                d_fprintf(stderr, "Delete service request failed.  [%s]\n",
 
688
                        win_errstr(result));
 
689
                goto done;
 
690
        }
 
691
 
 
692
        d_printf("Successfully deleted Service: %s\n", argv[0]);
 
693
 
 
694
 done:
 
695
        if (is_valid_policy_hnd(&hService)) {
 
696
                rpccli_svcctl_CloseServiceHandle(pipe_hnd, mem_ctx, &hService, NULL);
 
697
        }
 
698
        if (is_valid_policy_hnd(&hSCM)) {
 
699
                rpccli_svcctl_CloseServiceHandle(pipe_hnd, mem_ctx, &hSCM, NULL);
 
700
        }
 
701
 
 
702
        return werror_to_ntstatus(result);
 
703
}
 
704
 
 
705
/********************************************************************
 
706
********************************************************************/
 
707
 
 
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,
 
713
                                            TALLOC_CTX *mem_ctx,
 
714
                                            int argc,
 
715
                                            const char **argv)
 
716
{
 
717
        struct policy_handle hSCM, hService;
 
718
        WERROR result = WERR_GENERAL_FAILURE;
 
719
        NTSTATUS status;
 
720
        const char *ServiceName;
 
721
        const char *DisplayName;
 
722
        const char *binary_path;
 
723
 
 
724
        if (argc != 3) {
 
725
                d_printf("Usage: net rpc service create <service> <displayname> <binarypath>\n");
 
726
                return NT_STATUS_OK;
 
727
        }
 
728
 
 
729
        /* Open the Service Control Manager */
 
730
        status = rpccli_svcctl_OpenSCManagerW(pipe_hnd, mem_ctx,
 
731
                                              pipe_hnd->srv_name_slash,
 
732
                                              NULL,
 
733
                                              SC_RIGHT_MGR_CREATE_SERVICE,
 
734
                                              &hSCM,
 
735
                                              &result);
 
736
        if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result)) {
 
737
                d_fprintf(stderr, "Failed to open Service Control Manager.  [%s]\n",
 
738
                        win_errstr(result));
 
739
                return werror_to_ntstatus(result);
 
740
        }
 
741
 
 
742
        /* Create the service */
 
743
 
 
744
        ServiceName = argv[0];
 
745
        DisplayName = argv[1];
 
746
        binary_path = argv[2];
 
747
 
 
748
        status = rpccli_svcctl_CreateServiceW(pipe_hnd, mem_ctx,
 
749
                                              &hSCM,
 
750
                                              ServiceName,
 
751
                                              DisplayName,
 
752
                                              SERVICE_ALL_ACCESS,
 
753
                                              SERVICE_TYPE_WIN32_OWN_PROCESS,
 
754
                                              SVCCTL_DEMAND_START,
 
755
                                              SVCCTL_SVC_ERROR_NORMAL,
 
756
                                              binary_path,
 
757
                                              NULL, /* LoadOrderGroupKey */
 
758
                                              NULL, /* TagId */
 
759
                                              NULL, /* dependencies */
 
760
                                              0, /* dependencies_size */
 
761
                                              NULL, /* service_start_name */
 
762
                                              NULL, /* password */
 
763
                                              0, /* password_size */
 
764
                                              &hService,
 
765
                                              &result);
 
766
 
 
767
        if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result) ) {
 
768
                d_fprintf(stderr, "Create service request failed.  [%s]\n",
 
769
                        win_errstr(result));
 
770
                goto done;
 
771
        }
 
772
 
 
773
        d_printf("Successfully created Service: %s\n", argv[0]);
 
774
 
 
775
 done:
 
776
        if (is_valid_policy_hnd(&hService)) {
 
777
                rpccli_svcctl_CloseServiceHandle(pipe_hnd, mem_ctx, &hService, NULL);
 
778
        }
 
779
        if (is_valid_policy_hnd(&hSCM)) {
 
780
                rpccli_svcctl_CloseServiceHandle(pipe_hnd, mem_ctx, &hSCM, NULL);
 
781
        }
 
782
 
 
783
        return werror_to_ntstatus(result);
 
784
}
 
785
 
 
786
/********************************************************************
 
787
********************************************************************/
 
788
 
 
789
static int rpc_service_list(struct net_context *c, int argc, const char **argv )
 
790
{
 
791
        if (c->display_usage) {
 
792
                d_printf("Usage:\n"
 
793
                         "net rpc service list\n"
 
794
                         "    View configured Win32 services\n");
 
795
                return 0;
 
796
        }
 
797
 
 
798
        return run_rpc_command(c, NULL, &ndr_table_svcctl.syntax_id, 0,
 
799
                rpc_service_list_internal, argc, argv );
 
800
}
 
801
 
 
802
/********************************************************************
 
803
********************************************************************/
 
804
 
 
805
static int rpc_service_start(struct net_context *c, int argc, const char **argv )
 
806
{
 
807
        if (c->display_usage) {
 
808
                d_printf("Usage:\n"
 
809
                         "net rpc service start <service>\n"
 
810
                         "    Start a Win32 service\n");
 
811
                return 0;
 
812
        }
 
813
 
 
814
        return run_rpc_command(c, NULL, &ndr_table_svcctl.syntax_id, 0,
 
815
                rpc_service_start_internal, argc, argv );
 
816
}
 
817
 
 
818
/********************************************************************
 
819
********************************************************************/
 
820
 
 
821
static int rpc_service_stop(struct net_context *c, int argc, const char **argv )
 
822
{
 
823
        if (c->display_usage) {
 
824
                d_printf("Usage:\n"
 
825
                         "net rpc service stop <service>\n"
 
826
                         "    Stop a Win32 service\n");
 
827
                return 0;
 
828
        }
 
829
 
 
830
        return run_rpc_command(c, NULL, &ndr_table_svcctl.syntax_id, 0,
 
831
                rpc_service_stop_internal, argc, argv );
 
832
}
 
833
 
 
834
/********************************************************************
 
835
********************************************************************/
 
836
 
 
837
static int rpc_service_resume(struct net_context *c, int argc, const char **argv )
 
838
{
 
839
        if (c->display_usage) {
 
840
                d_printf("Usage:\n"
 
841
                         "net rpc service resume <service>\n"
 
842
                         "    Resume a Win32 service\n");
 
843
                return 0;
 
844
        }
 
845
 
 
846
        return run_rpc_command(c, NULL, &ndr_table_svcctl.syntax_id, 0,
 
847
                rpc_service_resume_internal, argc, argv );
 
848
}
 
849
 
 
850
/********************************************************************
 
851
********************************************************************/
 
852
 
 
853
static int rpc_service_pause(struct net_context *c, int argc, const char **argv )
 
854
{
 
855
        if (c->display_usage) {
 
856
                d_printf("Usage:\n"
 
857
                         "net rpc service pause <service>\n"
 
858
                         "    Pause a Win32 service\n");
 
859
                return 0;
 
860
        }
 
861
 
 
862
        return run_rpc_command(c, NULL, &ndr_table_svcctl.syntax_id, 0,
 
863
                rpc_service_pause_internal, argc, argv );
 
864
}
 
865
 
 
866
/********************************************************************
 
867
********************************************************************/
 
868
 
 
869
static int rpc_service_status(struct net_context *c, int argc, const char **argv )
 
870
{
 
871
        if (c->display_usage) {
 
872
                d_printf("Usage:\n"
 
873
                         "net rpc service status <service>\n"
 
874
                         "     Show the current status of a service\n");
 
875
                return 0;
 
876
        }
 
877
 
 
878
        return run_rpc_command(c, NULL, &ndr_table_svcctl.syntax_id, 0,
 
879
                rpc_service_status_internal, argc, argv );
 
880
}
 
881
 
 
882
/********************************************************************
 
883
********************************************************************/
 
884
 
 
885
static int rpc_service_delete(struct net_context *c, int argc, const char **argv)
 
886
{
 
887
        if (c->display_usage) {
 
888
                d_printf("Usage:\n"
 
889
                         "net rpc service delete <service>\n"
 
890
                         "    Delete a Win32 service\n");
 
891
                return 0;
 
892
        }
 
893
 
 
894
        return run_rpc_command(c, NULL, &ndr_table_svcctl.syntax_id, 0,
 
895
                rpc_service_delete_internal, argc, argv);
 
896
}
 
897
 
 
898
/********************************************************************
 
899
********************************************************************/
 
900
 
 
901
static int rpc_service_create(struct net_context *c, int argc, const char **argv)
 
902
{
 
903
        if (c->display_usage) {
 
904
                d_printf("Usage:\n"
 
905
                         "net rpc service create <service>\n"
 
906
                         "    Create a Win32 service\n");
 
907
                return 0;
 
908
        }
 
909
 
 
910
        return run_rpc_command(c, NULL, &ndr_table_svcctl.syntax_id, 0,
 
911
                rpc_service_create_internal, argc, argv);
 
912
}
 
913
 
 
914
/********************************************************************
 
915
********************************************************************/
 
916
 
 
917
int net_rpc_service(struct net_context *c, int argc, const char **argv)
 
918
{
 
919
        struct functable func[] = {
 
920
                {
 
921
                        "list",
 
922
                        rpc_service_list,
 
923
                        NET_TRANSPORT_RPC,
 
924
                        "View configured Win32 services",
 
925
                        "net rpc service list\n"
 
926
                        "    View configured Win32 services"
 
927
                },
 
928
                {
 
929
                        "start",
 
930
                        rpc_service_start,
 
931
                        NET_TRANSPORT_RPC,
 
932
                        "Start a service",
 
933
                        "net rpc service start\n"
 
934
                        "    Start a service"
 
935
                },
 
936
                {
 
937
                        "stop",
 
938
                        rpc_service_stop,
 
939
                        NET_TRANSPORT_RPC,
 
940
                        "Stop a service",
 
941
                        "net rpc service stop\n"
 
942
                        "    Stop a service"
 
943
                },
 
944
                {
 
945
                        "pause",
 
946
                        rpc_service_pause,
 
947
                        NET_TRANSPORT_RPC,
 
948
                        "Pause a service",
 
949
                        "net rpc service pause\n"
 
950
                        "    Pause a service"
 
951
                },
 
952
                {
 
953
                        "resume",
 
954
                        rpc_service_resume,
 
955
                        NET_TRANSPORT_RPC,
 
956
                        "Resume a paused service",
 
957
                        "net rpc service resume\n"
 
958
                        "    Resume a service"
 
959
                },
 
960
                {
 
961
                        "status",
 
962
                        rpc_service_status,
 
963
                        NET_TRANSPORT_RPC,
 
964
                        "View current status of a service",
 
965
                        "net rpc service status\n"
 
966
                        "    View current status of a service"
 
967
                },
 
968
                {
 
969
                        "delete",
 
970
                        rpc_service_delete,
 
971
                        NET_TRANSPORT_RPC,
 
972
                        "Delete a service",
 
973
                        "net rpc service delete\n"
 
974
                        "    Deletes a service"
 
975
                },
 
976
                {
 
977
                        "create",
 
978
                        rpc_service_create,
 
979
                        NET_TRANSPORT_RPC,
 
980
                        "Create a service",
 
981
                        "net rpc service create\n"
 
982
                        "    Creates a service"
 
983
                },
 
984
 
 
985
                {NULL, NULL, 0, NULL, NULL}
 
986
        };
 
987
 
 
988
        return net_run_function(c, argc, argv, "net rpc service",func);
 
989
}