~zulcss/samba/server-dailies-3.4

« back to all changes in this revision

Viewing changes to source3/rpcclient/rpcclient.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
   Unix SMB/CIFS implementation.
 
3
   RPC pipe client
 
4
 
 
5
   Copyright (C) Tim Potter 2000-2001
 
6
   Copyright (C) Martin Pool 2003
 
7
 
 
8
   This program is free software; you can redistribute it and/or modify
 
9
   it under the terms of the GNU General Public License as published by
 
10
   the Free Software Foundation; either version 3 of the License, or
 
11
   (at your option) any later version.
 
12
   
 
13
   This program is distributed in the hope that it will be useful,
 
14
   but WITHOUT ANY WARRANTY; without even the implied warranty of
 
15
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
16
   GNU General Public License for more details.
 
17
   
 
18
   You should have received a copy of the GNU General Public License
 
19
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
20
*/
 
21
 
 
22
#include "includes.h"
 
23
#include "rpcclient.h"
 
24
 
 
25
DOM_SID domain_sid;
 
26
 
 
27
static enum pipe_auth_type pipe_default_auth_type = PIPE_AUTH_TYPE_NONE;
 
28
static enum pipe_auth_level pipe_default_auth_level = PIPE_AUTH_LEVEL_NONE;
 
29
static unsigned int timeout = 0;
 
30
 
 
31
struct user_auth_info *rpcclient_auth_info;
 
32
 
 
33
/* List to hold groups of commands.
 
34
 *
 
35
 * Commands are defined in a list of arrays: arrays are easy to
 
36
 * statically declare, and lists are easier to dynamically extend.
 
37
 */
 
38
 
 
39
static struct cmd_list {
 
40
        struct cmd_list *prev, *next;
 
41
        struct cmd_set *cmd_set;
 
42
} *cmd_list;
 
43
 
 
44
/****************************************************************************
 
45
handle completion of commands for readline
 
46
****************************************************************************/
 
47
static char **completion_fn(const char *text, int start, int end)
 
48
{
 
49
#define MAX_COMPLETIONS 100
 
50
        char **matches;
 
51
        int i, count=0;
 
52
        struct cmd_list *commands = cmd_list;
 
53
 
 
54
#if 0   /* JERRY */
 
55
        /* FIXME!!!  -- what to do when completing argument? */
 
56
        /* for words not at the start of the line fallback 
 
57
           to filename completion */
 
58
        if (start) 
 
59
                return NULL;
 
60
#endif
 
61
 
 
62
        /* make sure we have a list of valid commands */
 
63
        if (!commands) {
 
64
                return NULL;
 
65
        }
 
66
 
 
67
        matches = SMB_MALLOC_ARRAY(char *, MAX_COMPLETIONS);
 
68
        if (!matches) {
 
69
                return NULL;
 
70
        }
 
71
 
 
72
        matches[count++] = SMB_STRDUP(text);
 
73
        if (!matches[0]) {
 
74
                SAFE_FREE(matches);
 
75
                return NULL;
 
76
        }
 
77
 
 
78
        while (commands && count < MAX_COMPLETIONS-1) {
 
79
                if (!commands->cmd_set) {
 
80
                        break;
 
81
                }
 
82
                
 
83
                for (i=0; commands->cmd_set[i].name; i++) {
 
84
                        if ((strncmp(text, commands->cmd_set[i].name, strlen(text)) == 0) &&
 
85
                                (( commands->cmd_set[i].returntype == RPC_RTYPE_NTSTATUS &&
 
86
                        commands->cmd_set[i].ntfn ) || 
 
87
                      ( commands->cmd_set[i].returntype == RPC_RTYPE_WERROR &&
 
88
                        commands->cmd_set[i].wfn))) {
 
89
                                matches[count] = SMB_STRDUP(commands->cmd_set[i].name);
 
90
                                if (!matches[count]) {
 
91
                                        for (i = 0; i < count; i++) {
 
92
                                                SAFE_FREE(matches[count]);
 
93
                                        }
 
94
                                        SAFE_FREE(matches);
 
95
                                        return NULL;
 
96
                                }
 
97
                                count++;
 
98
                        }
 
99
                }
 
100
                commands = commands->next;
 
101
                
 
102
        }
 
103
 
 
104
        if (count == 2) {
 
105
                SAFE_FREE(matches[0]);
 
106
                matches[0] = SMB_STRDUP(matches[1]);
 
107
        }
 
108
        matches[count] = NULL;
 
109
        return matches;
 
110
}
 
111
 
 
112
static char *next_command (char **cmdstr)
 
113
{
 
114
        char *command;
 
115
        char                    *p;
 
116
        
 
117
        if (!cmdstr || !(*cmdstr))
 
118
                return NULL;
 
119
        
 
120
        p = strchr_m(*cmdstr, ';');
 
121
        if (p)
 
122
                *p = '\0';
 
123
        command = SMB_STRDUP(*cmdstr);
 
124
        if (p)
 
125
                *cmdstr = p + 1;
 
126
        else
 
127
                *cmdstr = NULL;
 
128
        
 
129
        return command;
 
130
}
 
131
 
 
132
/* Fetch the SID for this computer */
 
133
 
 
134
static void fetch_machine_sid(struct cli_state *cli)
 
135
{
 
136
        struct policy_handle pol;
 
137
        NTSTATUS result = NT_STATUS_OK;
 
138
        static bool got_domain_sid;
 
139
        TALLOC_CTX *mem_ctx;
 
140
        struct rpc_pipe_client *lsapipe = NULL;
 
141
        union lsa_PolicyInformation *info = NULL;
 
142
 
 
143
        if (got_domain_sid) return;
 
144
 
 
145
        if (!(mem_ctx=talloc_init("fetch_machine_sid"))) {
 
146
                DEBUG(0,("fetch_machine_sid: talloc_init returned NULL!\n"));
 
147
                goto error;
 
148
        }
 
149
 
 
150
        result = cli_rpc_pipe_open_noauth(cli, &ndr_table_lsarpc.syntax_id,
 
151
                                          &lsapipe);
 
152
        if (!NT_STATUS_IS_OK(result)) {
 
153
                fprintf(stderr, "could not initialise lsa pipe. Error was %s\n", nt_errstr(result) );
 
154
                goto error;
 
155
        }
 
156
        
 
157
        result = rpccli_lsa_open_policy(lsapipe, mem_ctx, True, 
 
158
                                     SEC_FLAG_MAXIMUM_ALLOWED,
 
159
                                     &pol);
 
160
        if (!NT_STATUS_IS_OK(result)) {
 
161
                goto error;
 
162
        }
 
163
 
 
164
        result = rpccli_lsa_QueryInfoPolicy(lsapipe, mem_ctx,
 
165
                                            &pol,
 
166
                                            LSA_POLICY_INFO_ACCOUNT_DOMAIN,
 
167
                                            &info);
 
168
        if (!NT_STATUS_IS_OK(result)) {
 
169
                goto error;
 
170
        }
 
171
 
 
172
        got_domain_sid = True;
 
173
        sid_copy(&domain_sid, info->account_domain.sid);
 
174
 
 
175
        rpccli_lsa_Close(lsapipe, mem_ctx, &pol);
 
176
        TALLOC_FREE(lsapipe);
 
177
        talloc_destroy(mem_ctx);
 
178
 
 
179
        return;
 
180
 
 
181
 error:
 
182
 
 
183
        if (lsapipe) {
 
184
                TALLOC_FREE(lsapipe);
 
185
        }
 
186
 
 
187
        fprintf(stderr, "could not obtain sid for domain %s\n", cli->domain);
 
188
 
 
189
        if (!NT_STATUS_IS_OK(result)) {
 
190
                fprintf(stderr, "error: %s\n", nt_errstr(result));
 
191
        }
 
192
 
 
193
        exit(1);
 
194
}
 
195
 
 
196
/* List the available commands on a given pipe */
 
197
 
 
198
static NTSTATUS cmd_listcommands(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
 
199
                                 int argc, const char **argv)
 
200
{
 
201
        struct cmd_list *tmp;
 
202
        struct cmd_set *tmp_set;
 
203
        int i;
 
204
 
 
205
        /* Usage */
 
206
 
 
207
        if (argc != 2) {
 
208
                printf("Usage: %s <pipe>\n", argv[0]);
 
209
                return NT_STATUS_OK;
 
210
        }
 
211
 
 
212
        /* Help on one command */
 
213
 
 
214
        for (tmp = cmd_list; tmp; tmp = tmp->next) 
 
215
        {
 
216
                tmp_set = tmp->cmd_set;
 
217
                
 
218
                if (!StrCaseCmp(argv[1], tmp_set->name))
 
219
                {
 
220
                        printf("Available commands on the %s pipe:\n\n", tmp_set->name);
 
221
 
 
222
                        i = 0;
 
223
                        tmp_set++;
 
224
                        while(tmp_set->name) {
 
225
                                printf("%30s", tmp_set->name);
 
226
                                tmp_set++;
 
227
                                i++;
 
228
                                if (i%3 == 0)
 
229
                                        printf("\n");
 
230
                        }
 
231
                        
 
232
                        /* drop out of the loop */
 
233
                        break;
 
234
                }
 
235
        }
 
236
        printf("\n\n");
 
237
 
 
238
        return NT_STATUS_OK;
 
239
}
 
240
 
 
241
/* Display help on commands */
 
242
 
 
243
static NTSTATUS cmd_help(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
 
244
                         int argc, const char **argv)
 
245
{
 
246
        struct cmd_list *tmp;
 
247
        struct cmd_set *tmp_set;
 
248
 
 
249
        /* Usage */
 
250
 
 
251
        if (argc > 2) {
 
252
                printf("Usage: %s [command]\n", argv[0]);
 
253
                return NT_STATUS_OK;
 
254
        }
 
255
 
 
256
        /* Help on one command */
 
257
 
 
258
        if (argc == 2) {
 
259
                for (tmp = cmd_list; tmp; tmp = tmp->next) {
 
260
                        
 
261
                        tmp_set = tmp->cmd_set;
 
262
 
 
263
                        while(tmp_set->name) {
 
264
                                if (strequal(argv[1], tmp_set->name)) {
 
265
                                        if (tmp_set->usage &&
 
266
                                            tmp_set->usage[0])
 
267
                                                printf("%s\n", tmp_set->usage);
 
268
                                        else
 
269
                                                printf("No help for %s\n", tmp_set->name);
 
270
 
 
271
                                        return NT_STATUS_OK;
 
272
                                }
 
273
 
 
274
                                tmp_set++;
 
275
                        }
 
276
                }
 
277
 
 
278
                printf("No such command: %s\n", argv[1]);
 
279
                return NT_STATUS_OK;
 
280
        }
 
281
 
 
282
        /* List all commands */
 
283
 
 
284
        for (tmp = cmd_list; tmp; tmp = tmp->next) {
 
285
 
 
286
                tmp_set = tmp->cmd_set;
 
287
 
 
288
                while(tmp_set->name) {
 
289
 
 
290
                        printf("%15s\t\t%s\n", tmp_set->name,
 
291
                               tmp_set->description ? tmp_set->description:
 
292
                               "");
 
293
 
 
294
                        tmp_set++;
 
295
                }
 
296
        }
 
297
 
 
298
        return NT_STATUS_OK;
 
299
}
 
300
 
 
301
/* Change the debug level */
 
302
 
 
303
static NTSTATUS cmd_debuglevel(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
 
304
                               int argc, const char **argv)
 
305
{
 
306
        if (argc > 2) {
 
307
                printf("Usage: %s [debuglevel]\n", argv[0]);
 
308
                return NT_STATUS_OK;
 
309
        }
 
310
 
 
311
        if (argc == 2) {
 
312
                DEBUGLEVEL = atoi(argv[1]);
 
313
        }
 
314
 
 
315
        printf("debuglevel is %d\n", DEBUGLEVEL);
 
316
 
 
317
        return NT_STATUS_OK;
 
318
}
 
319
 
 
320
static NTSTATUS cmd_quit(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
 
321
                         int argc, const char **argv)
 
322
{
 
323
        exit(0);
 
324
        return NT_STATUS_OK; /* NOTREACHED */
 
325
}
 
326
 
 
327
static NTSTATUS cmd_set_ss_level(void)
 
328
{
 
329
        struct cmd_list *tmp;
 
330
 
 
331
        /* Close any existing connections not at this level. */
 
332
 
 
333
        for (tmp = cmd_list; tmp; tmp = tmp->next) {
 
334
                struct cmd_set *tmp_set;
 
335
 
 
336
                for (tmp_set = tmp->cmd_set; tmp_set->name; tmp_set++) {
 
337
                        if (tmp_set->rpc_pipe == NULL) {
 
338
                                continue;
 
339
                        }
 
340
 
 
341
                        if ((tmp_set->rpc_pipe->auth->auth_type
 
342
                             != pipe_default_auth_type)
 
343
                            || (tmp_set->rpc_pipe->auth->auth_level
 
344
                                != pipe_default_auth_level)) {
 
345
                                TALLOC_FREE(tmp_set->rpc_pipe);
 
346
                                tmp_set->rpc_pipe = NULL;
 
347
                        }
 
348
                }
 
349
        }
 
350
        return NT_STATUS_OK;
 
351
}
 
352
 
 
353
static NTSTATUS cmd_sign(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
 
354
                         int argc, const char **argv)
 
355
{
 
356
        const char *type = "NTLMSSP";
 
357
 
 
358
        pipe_default_auth_level = PIPE_AUTH_LEVEL_INTEGRITY;
 
359
        pipe_default_auth_type = PIPE_AUTH_TYPE_NTLMSSP;
 
360
 
 
361
        if (argc > 2) {
 
362
                printf("Usage: %s [NTLMSSP|NTLMSSP_SPNEGO|SCHANNEL]\n", argv[0]);
 
363
                return NT_STATUS_OK;
 
364
        }
 
365
 
 
366
        if (argc == 2) {
 
367
                type = argv[1];
 
368
                if (strequal(type, "NTLMSSP")) {
 
369
                        pipe_default_auth_type = PIPE_AUTH_TYPE_NTLMSSP;
 
370
                } else if (strequal(type, "NTLMSSP_SPNEGO")) {
 
371
                        pipe_default_auth_type = PIPE_AUTH_TYPE_SPNEGO_NTLMSSP;
 
372
                } else if (strequal(type, "SCHANNEL")) {
 
373
                        pipe_default_auth_type = PIPE_AUTH_TYPE_SCHANNEL;
 
374
                } else {
 
375
                        printf("unknown type %s\n", type);
 
376
                        return NT_STATUS_INVALID_LEVEL;
 
377
                }
 
378
        }
 
379
 
 
380
        d_printf("Setting %s - sign\n", type);
 
381
 
 
382
        return cmd_set_ss_level();
 
383
}
 
384
 
 
385
static NTSTATUS cmd_seal(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
 
386
                         int argc, const char **argv)
 
387
{
 
388
        const char *type = "NTLMSSP";
 
389
 
 
390
        pipe_default_auth_level = PIPE_AUTH_LEVEL_PRIVACY;
 
391
        pipe_default_auth_type = PIPE_AUTH_TYPE_NTLMSSP;
 
392
 
 
393
        if (argc > 2) {
 
394
                printf("Usage: %s [NTLMSSP|NTLMSSP_SPNEGO|SCHANNEL]\n", argv[0]);
 
395
                return NT_STATUS_OK;
 
396
        }
 
397
 
 
398
        if (argc == 2) {
 
399
                type = argv[1];
 
400
                if (strequal(type, "NTLMSSP")) {
 
401
                        pipe_default_auth_type = PIPE_AUTH_TYPE_NTLMSSP;
 
402
                } else if (strequal(type, "NTLMSSP_SPNEGO")) {
 
403
                        pipe_default_auth_type = PIPE_AUTH_TYPE_SPNEGO_NTLMSSP;
 
404
                } else if (strequal(type, "SCHANNEL")) {
 
405
                        pipe_default_auth_type = PIPE_AUTH_TYPE_SCHANNEL;
 
406
                } else {
 
407
                        printf("unknown type %s\n", type);
 
408
                        return NT_STATUS_INVALID_LEVEL;
 
409
                }
 
410
        }
 
411
 
 
412
        d_printf("Setting %s - sign and seal\n", type);
 
413
 
 
414
        return cmd_set_ss_level();
 
415
}
 
416
 
 
417
static NTSTATUS cmd_timeout(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
 
418
                            int argc, const char **argv)
 
419
{
 
420
        struct cmd_list *tmp;
 
421
 
 
422
        if (argc > 2) {
 
423
                printf("Usage: %s timeout\n", argv[0]);
 
424
                return NT_STATUS_OK;
 
425
        }
 
426
 
 
427
        if (argc == 2) {
 
428
                timeout = atoi(argv[1]);
 
429
 
 
430
                for (tmp = cmd_list; tmp; tmp = tmp->next) {
 
431
                        
 
432
                        struct cmd_set *tmp_set;
 
433
 
 
434
                        for (tmp_set = tmp->cmd_set; tmp_set->name; tmp_set++) {
 
435
                                if (tmp_set->rpc_pipe == NULL) {
 
436
                                        continue;
 
437
                                }
 
438
 
 
439
                                rpccli_set_timeout(tmp_set->rpc_pipe, timeout);
 
440
                        }
 
441
                }
 
442
        }
 
443
 
 
444
        printf("timeout is %d\n", timeout);
 
445
 
 
446
        return NT_STATUS_OK;
 
447
}
 
448
 
 
449
 
 
450
static NTSTATUS cmd_none(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
 
451
                         int argc, const char **argv)
 
452
{
 
453
        pipe_default_auth_level = PIPE_AUTH_LEVEL_NONE;
 
454
        pipe_default_auth_type = PIPE_AUTH_TYPE_NONE;
 
455
 
 
456
        return cmd_set_ss_level();
 
457
}
 
458
 
 
459
static NTSTATUS cmd_schannel(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
 
460
                             int argc, const char **argv)
 
461
{
 
462
        d_printf("Setting schannel - sign and seal\n");
 
463
        pipe_default_auth_level = PIPE_AUTH_LEVEL_PRIVACY;
 
464
        pipe_default_auth_type = PIPE_AUTH_TYPE_SCHANNEL;
 
465
 
 
466
        return cmd_set_ss_level();
 
467
}
 
468
 
 
469
static NTSTATUS cmd_schannel_sign(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
 
470
                             int argc, const char **argv)
 
471
{
 
472
        d_printf("Setting schannel - sign only\n");
 
473
        pipe_default_auth_level = PIPE_AUTH_LEVEL_INTEGRITY;
 
474
        pipe_default_auth_type = PIPE_AUTH_TYPE_SCHANNEL;
 
475
 
 
476
        return cmd_set_ss_level();
 
477
}
 
478
 
 
479
 
 
480
/* Built in rpcclient commands */
 
481
 
 
482
static struct cmd_set rpcclient_commands[] = {
 
483
 
 
484
        { "GENERAL OPTIONS" },
 
485
 
 
486
        { "help", RPC_RTYPE_NTSTATUS, cmd_help, NULL,     NULL, NULL,   "Get help on commands", "[command]" },
 
487
        { "?",  RPC_RTYPE_NTSTATUS, cmd_help, NULL,       NULL, NULL,   "Get help on commands", "[command]" },
 
488
        { "debuglevel", RPC_RTYPE_NTSTATUS, cmd_debuglevel, NULL,   NULL,       NULL, "Set debug level", "level" },
 
489
        { "debug", RPC_RTYPE_NTSTATUS, cmd_debuglevel, NULL,   NULL,    NULL, "Set debug level", "level" },
 
490
        { "list",       RPC_RTYPE_NTSTATUS, cmd_listcommands, NULL, NULL,       NULL, "List available commands on <pipe>", "pipe" },
 
491
        { "exit", RPC_RTYPE_NTSTATUS, cmd_quit, NULL,   NULL,   NULL,   "Exit program", "" },
 
492
        { "quit", RPC_RTYPE_NTSTATUS, cmd_quit, NULL,     NULL, NULL, "Exit program", "" },
 
493
        { "sign", RPC_RTYPE_NTSTATUS, cmd_sign, NULL,     NULL, NULL, "Force RPC pipe connections to be signed", "" },
 
494
        { "seal", RPC_RTYPE_NTSTATUS, cmd_seal, NULL,     NULL, NULL, "Force RPC pipe connections to be sealed", "" },
 
495
        { "schannel", RPC_RTYPE_NTSTATUS, cmd_schannel, NULL,     NULL, NULL,   "Force RPC pipe connections to be sealed with 'schannel'.  Assumes valid machine account to this domain controller.", "" },
 
496
        { "schannelsign", RPC_RTYPE_NTSTATUS, cmd_schannel_sign, NULL,    NULL, NULL, "Force RPC pipe connections to be signed (not sealed) with 'schannel'.  Assumes valid machine account to this domain controller.", "" },
 
497
        { "timeout", RPC_RTYPE_NTSTATUS, cmd_timeout, NULL,       NULL, NULL, "Set timeout (in milliseonds) for RPC operations", "" },
 
498
        { "none", RPC_RTYPE_NTSTATUS, cmd_none, NULL,     NULL, NULL, "Force RPC pipe connections to have no special properties", "" },
 
499
 
 
500
        { NULL }
 
501
};
 
502
 
 
503
static struct cmd_set separator_command[] = {
 
504
        { "---------------", MAX_RPC_RETURN_TYPE, NULL, NULL,   NULL, NULL, "----------------------" },
 
505
        { NULL }
 
506
};
 
507
 
 
508
 
 
509
/* Various pipe commands */
 
510
 
 
511
extern struct cmd_set lsarpc_commands[];
 
512
extern struct cmd_set samr_commands[];
 
513
extern struct cmd_set spoolss_commands[];
 
514
extern struct cmd_set netlogon_commands[];
 
515
extern struct cmd_set srvsvc_commands[];
 
516
extern struct cmd_set dfs_commands[];
 
517
extern struct cmd_set ds_commands[];
 
518
extern struct cmd_set echo_commands[];
 
519
extern struct cmd_set epmapper_commands[];
 
520
extern struct cmd_set shutdown_commands[];
 
521
extern struct cmd_set test_commands[];
 
522
extern struct cmd_set wkssvc_commands[];
 
523
extern struct cmd_set ntsvcs_commands[];
 
524
extern struct cmd_set drsuapi_commands[];
 
525
extern struct cmd_set eventlog_commands[];
 
526
 
 
527
static struct cmd_set *rpcclient_command_list[] = {
 
528
        rpcclient_commands,
 
529
        lsarpc_commands,
 
530
        ds_commands,
 
531
        samr_commands,
 
532
        spoolss_commands,
 
533
        netlogon_commands,
 
534
        srvsvc_commands,
 
535
        dfs_commands,
 
536
        echo_commands,
 
537
        epmapper_commands,
 
538
        shutdown_commands,
 
539
        test_commands,
 
540
        wkssvc_commands,
 
541
        ntsvcs_commands,
 
542
        drsuapi_commands,
 
543
        eventlog_commands,
 
544
        NULL
 
545
};
 
546
 
 
547
static void add_command_set(struct cmd_set *cmd_set)
 
548
{
 
549
        struct cmd_list *entry;
 
550
 
 
551
        if (!(entry = SMB_MALLOC_P(struct cmd_list))) {
 
552
                DEBUG(0, ("out of memory\n"));
 
553
                return;
 
554
        }
 
555
 
 
556
        ZERO_STRUCTP(entry);
 
557
 
 
558
        entry->cmd_set = cmd_set;
 
559
        DLIST_ADD(cmd_list, entry);
 
560
}
 
561
 
 
562
 
 
563
/**
 
564
 * Call an rpcclient function, passing an argv array.
 
565
 *
 
566
 * @param cmd Command to run, as a single string.
 
567
 **/
 
568
static NTSTATUS do_cmd(struct cli_state *cli,
 
569
                       struct user_auth_info *auth_info,
 
570
                       struct cmd_set *cmd_entry,
 
571
                       int argc, char **argv)
 
572
{
 
573
        NTSTATUS ntresult;
 
574
        WERROR wresult;
 
575
        
 
576
        TALLOC_CTX *mem_ctx;
 
577
 
 
578
        /* Create mem_ctx */
 
579
 
 
580
        if (!(mem_ctx = talloc_init("do_cmd"))) {
 
581
                DEBUG(0, ("talloc_init() failed\n"));
 
582
                return NT_STATUS_NO_MEMORY;
 
583
        }
 
584
 
 
585
        /* Open pipe */
 
586
 
 
587
        if ((cmd_entry->interface != NULL) && (cmd_entry->rpc_pipe == NULL)) {
 
588
                switch (pipe_default_auth_type) {
 
589
                        case PIPE_AUTH_TYPE_NONE:
 
590
                                ntresult = cli_rpc_pipe_open_noauth(
 
591
                                        cli, cmd_entry->interface,
 
592
                                        &cmd_entry->rpc_pipe);
 
593
                                break;
 
594
                        case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
 
595
                                ntresult = cli_rpc_pipe_open_spnego_ntlmssp(
 
596
                                        cli, cmd_entry->interface,
 
597
                                        NCACN_NP,
 
598
                                        pipe_default_auth_level,
 
599
                                        lp_workgroup(),
 
600
                                        get_cmdline_auth_info_username(auth_info),
 
601
                                        get_cmdline_auth_info_password(auth_info),
 
602
                                        &cmd_entry->rpc_pipe);
 
603
                                break;
 
604
                        case PIPE_AUTH_TYPE_NTLMSSP:
 
605
                                ntresult = cli_rpc_pipe_open_ntlmssp(
 
606
                                        cli, cmd_entry->interface,
 
607
                                        NCACN_NP,
 
608
                                        pipe_default_auth_level,
 
609
                                        lp_workgroup(),
 
610
                                        get_cmdline_auth_info_username(auth_info),
 
611
                                        get_cmdline_auth_info_password(auth_info),
 
612
                                        &cmd_entry->rpc_pipe);
 
613
                                break;
 
614
                        case PIPE_AUTH_TYPE_SCHANNEL:
 
615
                                ntresult = cli_rpc_pipe_open_schannel(
 
616
                                        cli, cmd_entry->interface,
 
617
                                        NCACN_NP,
 
618
                                        pipe_default_auth_level,
 
619
                                        lp_workgroup(),
 
620
                                        &cmd_entry->rpc_pipe);
 
621
                                break;
 
622
                        default:
 
623
                                DEBUG(0, ("Could not initialise %s. Invalid "
 
624
                                          "auth type %u\n",
 
625
                                          get_pipe_name_from_iface(
 
626
                                                  cmd_entry->interface),
 
627
                                          pipe_default_auth_type ));
 
628
                                return NT_STATUS_UNSUCCESSFUL;
 
629
                }
 
630
                if (!NT_STATUS_IS_OK(ntresult)) {
 
631
                        DEBUG(0, ("Could not initialise %s. Error was %s\n",
 
632
                                  get_pipe_name_from_iface(
 
633
                                          cmd_entry->interface),
 
634
                                  nt_errstr(ntresult) ));
 
635
                        return ntresult;
 
636
                }
 
637
 
 
638
                if (ndr_syntax_id_equal(cmd_entry->interface,
 
639
                                        &ndr_table_netlogon.syntax_id)) {
 
640
                        uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
 
641
                        uint32 sec_channel_type;
 
642
                        uchar trust_password[16];
 
643
        
 
644
                        if (!secrets_fetch_trust_account_password(lp_workgroup(),
 
645
                                                        trust_password,
 
646
                                                        NULL, &sec_channel_type)) {
 
647
                                return NT_STATUS_UNSUCCESSFUL;
 
648
                        }
 
649
                
 
650
                        ntresult = rpccli_netlogon_setup_creds(cmd_entry->rpc_pipe,
 
651
                                                cli->desthost,   /* server name */
 
652
                                                lp_workgroup(),  /* domain */
 
653
                                                global_myname(), /* client name */
 
654
                                                global_myname(), /* machine account name */
 
655
                                                trust_password,
 
656
                                                sec_channel_type,
 
657
                                                &neg_flags);
 
658
 
 
659
                        if (!NT_STATUS_IS_OK(ntresult)) {
 
660
                                DEBUG(0, ("Could not initialise credentials for %s.\n",
 
661
                                          get_pipe_name_from_iface(
 
662
                                                  cmd_entry->interface)));
 
663
                                return ntresult;
 
664
                        }
 
665
                }
 
666
        }
 
667
 
 
668
        /* Run command */
 
669
 
 
670
        if ( cmd_entry->returntype == RPC_RTYPE_NTSTATUS ) {
 
671
                ntresult = cmd_entry->ntfn(cmd_entry->rpc_pipe, mem_ctx, argc, (const char **) argv);
 
672
                if (!NT_STATUS_IS_OK(ntresult)) {
 
673
                        printf("result was %s\n", nt_errstr(ntresult));
 
674
                }
 
675
        } else {
 
676
                wresult = cmd_entry->wfn(cmd_entry->rpc_pipe, mem_ctx, argc, (const char **) argv);
 
677
                /* print out the DOS error */
 
678
                if (!W_ERROR_IS_OK(wresult)) {
 
679
                        printf( "result was %s\n", win_errstr(wresult));
 
680
                }
 
681
                ntresult = W_ERROR_IS_OK(wresult)?NT_STATUS_OK:NT_STATUS_UNSUCCESSFUL;
 
682
        }
 
683
 
 
684
        /* Cleanup */
 
685
 
 
686
        talloc_destroy(mem_ctx);
 
687
 
 
688
        return ntresult;
 
689
}
 
690
 
 
691
 
 
692
/**
 
693
 * Process a command entered at the prompt or as part of -c
 
694
 *
 
695
 * @returns The NTSTATUS from running the command.
 
696
 **/
 
697
static NTSTATUS process_cmd(struct user_auth_info *auth_info,
 
698
                            struct cli_state *cli, char *cmd)
 
699
{
 
700
        struct cmd_list *temp_list;
 
701
        NTSTATUS result = NT_STATUS_OK;
 
702
        int ret;
 
703
        int argc;
 
704
        char **argv = NULL;
 
705
 
 
706
        if ((ret = poptParseArgvString(cmd, &argc, (const char ***) &argv)) != 0) {
 
707
                fprintf(stderr, "rpcclient: %s\n", poptStrerror(ret));
 
708
                return NT_STATUS_UNSUCCESSFUL;
 
709
        }
 
710
 
 
711
 
 
712
        /* Walk through a dlist of arrays of commands. */
 
713
        for (temp_list = cmd_list; temp_list; temp_list = temp_list->next) {
 
714
                struct cmd_set *temp_set = temp_list->cmd_set;
 
715
 
 
716
                while (temp_set->name) {
 
717
                        if (strequal(argv[0], temp_set->name)) {
 
718
                                if (!(temp_set->returntype == RPC_RTYPE_NTSTATUS && temp_set->ntfn ) &&
 
719
                         !(temp_set->returntype == RPC_RTYPE_WERROR && temp_set->wfn )) {
 
720
                                        fprintf (stderr, "Invalid command\n");
 
721
                                        goto out_free;
 
722
                                }
 
723
 
 
724
                                result = do_cmd(cli, auth_info, temp_set,
 
725
                                                argc, argv);
 
726
 
 
727
                                goto out_free;
 
728
                        }
 
729
                        temp_set++;
 
730
                }
 
731
        }
 
732
 
 
733
        if (argv[0]) {
 
734
                printf("command not found: %s\n", argv[0]);
 
735
        }
 
736
 
 
737
out_free:
 
738
/* moved to do_cmd()
 
739
        if (!NT_STATUS_IS_OK(result)) {
 
740
                printf("result was %s\n", nt_errstr(result));
 
741
        }
 
742
*/
 
743
 
 
744
        /* NOTE: popt allocates the whole argv, including the
 
745
         * strings, as a single block.  So a single free is
 
746
         * enough to release it -- we don't free the
 
747
         * individual strings.  rtfm. */
 
748
        free(argv);
 
749
 
 
750
        return result;
 
751
}
 
752
 
 
753
 
 
754
/* Main function */
 
755
 
 
756
 int main(int argc, char *argv[])
 
757
{
 
758
        int                     opt;
 
759
        static char             *cmdstr = NULL;
 
760
        const char *server;
 
761
        struct cli_state        *cli = NULL;
 
762
        static char             *opt_ipaddr=NULL;
 
763
        struct cmd_set          **cmd_set;
 
764
        struct sockaddr_storage server_ss;
 
765
        NTSTATUS                nt_status;
 
766
        static int              opt_port = 0;
 
767
        fstring new_workgroup;
 
768
        int result = 0;
 
769
        TALLOC_CTX *frame = talloc_stackframe();
 
770
        uint32_t flags = 0;
 
771
 
 
772
        /* make sure the vars that get altered (4th field) are in
 
773
           a fixed location or certain compilers complain */
 
774
        poptContext pc;
 
775
        struct poptOption long_options[] = {
 
776
                POPT_AUTOHELP
 
777
                {"command",     'c', POPT_ARG_STRING,   &cmdstr, 'c', "Execute semicolon separated cmds", "COMMANDS"},
 
778
                {"dest-ip", 'I', POPT_ARG_STRING,   &opt_ipaddr, 'I', "Specify destination IP address", "IP"},
 
779
                {"port", 'p', POPT_ARG_INT,   &opt_port, 'p', "Specify port number", "PORT"},
 
780
                POPT_COMMON_SAMBA
 
781
                POPT_COMMON_CONNECTION
 
782
                POPT_COMMON_CREDENTIALS
 
783
                POPT_TABLEEND
 
784
        };
 
785
 
 
786
        load_case_tables();
 
787
 
 
788
        zero_sockaddr(&server_ss);
 
789
 
 
790
        setlinebuf(stdout);
 
791
 
 
792
        /* the following functions are part of the Samba debugging
 
793
           facilities.  See lib/debug.c */
 
794
        setup_logging("rpcclient", True);
 
795
 
 
796
        rpcclient_auth_info = user_auth_info_init(frame);
 
797
        if (rpcclient_auth_info == NULL) {
 
798
                exit(1);
 
799
        }
 
800
        popt_common_set_auth_info(rpcclient_auth_info);
 
801
 
 
802
        /* Parse options */
 
803
 
 
804
        pc = poptGetContext("rpcclient", argc, (const char **) argv,
 
805
                            long_options, 0);
 
806
 
 
807
        if (argc == 1) {
 
808
                poptPrintHelp(pc, stderr, 0);
 
809
                goto done;
 
810
        }
 
811
 
 
812
        while((opt = poptGetNextOpt(pc)) != -1) {
 
813
                switch (opt) {
 
814
 
 
815
                case 'I':
 
816
                        if (!interpret_string_addr(&server_ss,
 
817
                                                opt_ipaddr,
 
818
                                                AI_NUMERICHOST)) {
 
819
                                fprintf(stderr, "%s not a valid IP address\n",
 
820
                                        opt_ipaddr);
 
821
                                result = 1;
 
822
                                goto done;
 
823
                        }
 
824
                }
 
825
        }
 
826
 
 
827
        /* Get server as remaining unparsed argument.  Print usage if more
 
828
           than one unparsed argument is present. */
 
829
 
 
830
        server = poptGetArg(pc);
 
831
 
 
832
        if (!server || poptGetArg(pc)) {
 
833
                poptPrintHelp(pc, stderr, 0);
 
834
                result = 1;
 
835
                goto done;
 
836
        }
 
837
 
 
838
        poptFreeContext(pc);
 
839
 
 
840
        load_interfaces();
 
841
 
 
842
        if (!init_names()) {
 
843
                result = 1;
 
844
                goto done;
 
845
        }
 
846
 
 
847
        /* save the workgroup...
 
848
 
 
849
           FIXME!! do we need to do this for other options as well
 
850
           (or maybe a generic way to keep lp_load() from overwriting
 
851
           everything)?  */
 
852
 
 
853
        fstrcpy( new_workgroup, lp_workgroup() );
 
854
 
 
855
        /* Load smb.conf file */
 
856
 
 
857
        if (!lp_load(get_dyn_CONFIGFILE(),True,False,False,True))
 
858
                fprintf(stderr, "Can't load %s\n", get_dyn_CONFIGFILE());
 
859
 
 
860
        if ( strlen(new_workgroup) != 0 )
 
861
                set_global_myworkgroup( new_workgroup );
 
862
 
 
863
        /*
 
864
         * Get password
 
865
         * from stdin if necessary
 
866
         */
 
867
 
 
868
        if (get_cmdline_auth_info_use_machine_account(rpcclient_auth_info) &&
 
869
            !set_cmdline_auth_info_machine_account_creds(rpcclient_auth_info)) {
 
870
                result = 1;
 
871
                goto done;
 
872
        }
 
873
 
 
874
        set_cmdline_auth_info_getpass(rpcclient_auth_info);
 
875
 
 
876
        if ((server[0] == '/' && server[1] == '/') ||
 
877
                        (server[0] == '\\' && server[1] ==  '\\')) {
 
878
                server += 2;
 
879
        }
 
880
 
 
881
        if (get_cmdline_auth_info_use_kerberos(rpcclient_auth_info)) {
 
882
                flags |= CLI_FULL_CONNECTION_USE_KERBEROS |
 
883
                         CLI_FULL_CONNECTION_FALLBACK_AFTER_KERBEROS;
 
884
        }
 
885
 
 
886
 
 
887
        nt_status = cli_full_connection(&cli, global_myname(), server,
 
888
                                        opt_ipaddr ? &server_ss : NULL, opt_port,
 
889
                                        "IPC$", "IPC",
 
890
                                        get_cmdline_auth_info_username(rpcclient_auth_info),
 
891
                                        lp_workgroup(),
 
892
                                        get_cmdline_auth_info_password(rpcclient_auth_info),
 
893
                                        flags,
 
894
                                        get_cmdline_auth_info_signing_state(rpcclient_auth_info),
 
895
                                        NULL);
 
896
 
 
897
        if (!NT_STATUS_IS_OK(nt_status)) {
 
898
                DEBUG(0,("Cannot connect to server.  Error was %s\n", nt_errstr(nt_status)));
 
899
                result = 1;
 
900
                goto done;
 
901
        }
 
902
 
 
903
        if (get_cmdline_auth_info_smb_encrypt(rpcclient_auth_info)) {
 
904
                nt_status = cli_cm_force_encryption(cli,
 
905
                                        get_cmdline_auth_info_username(rpcclient_auth_info),
 
906
                                        get_cmdline_auth_info_password(rpcclient_auth_info),
 
907
                                        lp_workgroup(),
 
908
                                        "IPC$");
 
909
                if (!NT_STATUS_IS_OK(nt_status)) {
 
910
                        result = 1;
 
911
                        goto done;
 
912
                }
 
913
        }
 
914
 
 
915
#if 0   /* COMMENT OUT FOR TESTING */
 
916
        memset(cmdline_auth_info.password,'X',sizeof(cmdline_auth_info.password));
 
917
#endif
 
918
 
 
919
        /* Load command lists */
 
920
 
 
921
        timeout = cli_set_timeout(cli, 10000);
 
922
 
 
923
        cmd_set = rpcclient_command_list;
 
924
 
 
925
        while(*cmd_set) {
 
926
                add_command_set(*cmd_set);
 
927
                add_command_set(separator_command);
 
928
                cmd_set++;
 
929
        }
 
930
 
 
931
        fetch_machine_sid(cli);
 
932
 
 
933
       /* Do anything specified with -c */
 
934
        if (cmdstr && cmdstr[0]) {
 
935
                char    *cmd;
 
936
                char    *p = cmdstr;
 
937
 
 
938
                result = 0;
 
939
 
 
940
                while((cmd=next_command(&p)) != NULL) {
 
941
                        NTSTATUS cmd_result = process_cmd(rpcclient_auth_info, cli, cmd);
 
942
                        SAFE_FREE(cmd);
 
943
                        result = NT_STATUS_IS_ERR(cmd_result);
 
944
                }
 
945
 
 
946
                goto done;
 
947
        }
 
948
 
 
949
        /* Loop around accepting commands */
 
950
 
 
951
        while(1) {
 
952
                char *line = NULL;
 
953
 
 
954
                line = smb_readline("rpcclient $> ", NULL, completion_fn);
 
955
 
 
956
                if (line == NULL)
 
957
                        break;
 
958
 
 
959
                if (line[0] != '\n')
 
960
                        process_cmd(rpcclient_auth_info, cli, line);
 
961
                SAFE_FREE(line);
 
962
        }
 
963
 
 
964
done:
 
965
        if (cli != NULL) {
 
966
                cli_shutdown(cli);
 
967
        }
 
968
        TALLOC_FREE(frame);
 
969
        return result;
 
970
}