Line data Source code
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 "../libcli/auth/netlogon_creds_cli.h"
24 : #include "rpcclient.h"
25 : #include "../libcli/auth/libcli_auth.h"
26 : #include "../librpc/gen_ndr/ndr_lsa_c.h"
27 : #include "rpc_client/cli_lsarpc.h"
28 : #include "../librpc/gen_ndr/ndr_netlogon.h"
29 : #include "rpc_client/cli_netlogon.h"
30 : #include "../libcli/smbreadline/smbreadline.h"
31 : #include "../libcli/security/security.h"
32 : #include "passdb.h"
33 : #include "libsmb/libsmb.h"
34 : #include "auth/gensec/gensec.h"
35 : #include "../libcli/smb/smbXcli_base.h"
36 : #include "messages.h"
37 : #include "cmdline_contexts.h"
38 : #include "../librpc/gen_ndr/ndr_samr.h"
39 : #include "lib/cmdline/cmdline.h"
40 : #include "lib/param/param.h"
41 :
42 : enum pipe_auth_type_spnego {
43 : PIPE_AUTH_TYPE_SPNEGO_NONE = 0,
44 : PIPE_AUTH_TYPE_SPNEGO_NTLMSSP,
45 : PIPE_AUTH_TYPE_SPNEGO_KRB5
46 : };
47 :
48 : static unsigned int timeout = 10000;
49 :
50 : struct messaging_context *rpcclient_msg_ctx;
51 : struct netlogon_creds_cli_context *rpcclient_netlogon_creds;
52 : static const char *rpcclient_netlogon_domain;
53 :
54 : /* List to hold groups of commands.
55 : *
56 : * Commands are defined in a list of arrays: arrays are easy to
57 : * statically declare, and lists are easier to dynamically extend.
58 : */
59 :
60 : static struct cmd_list {
61 : struct cmd_list *prev, *next;
62 : struct cmd_set *cmd_set;
63 : } *cmd_list;
64 :
65 : /****************************************************************************
66 : handle completion of commands for readline
67 : ****************************************************************************/
68 0 : static char **completion_fn(const char *text, int start, int end)
69 : {
70 : #define MAX_COMPLETIONS 1000
71 : char **matches;
72 0 : size_t i, count=0;
73 0 : struct cmd_list *commands = cmd_list;
74 :
75 : #if 0 /* JERRY */
76 : /* FIXME!!! -- what to do when completing argument? */
77 : /* for words not at the start of the line fallback
78 : to filename completion */
79 : if (start)
80 : return NULL;
81 : #endif
82 :
83 : /* make sure we have a list of valid commands */
84 0 : if (!commands) {
85 0 : return NULL;
86 : }
87 :
88 0 : matches = SMB_MALLOC_ARRAY(char *, MAX_COMPLETIONS);
89 0 : if (!matches) {
90 0 : return NULL;
91 : }
92 :
93 0 : matches[count++] = SMB_STRDUP(text);
94 0 : if (!matches[0]) {
95 0 : SAFE_FREE(matches);
96 0 : return NULL;
97 : }
98 :
99 0 : while (commands && count < MAX_COMPLETIONS-1) {
100 0 : if (!commands->cmd_set) {
101 0 : break;
102 : }
103 :
104 0 : for (i=0; commands->cmd_set[i].name; i++) {
105 0 : if ((strncmp(text, commands->cmd_set[i].name, strlen(text)) == 0) &&
106 0 : (( commands->cmd_set[i].returntype == RPC_RTYPE_NTSTATUS &&
107 0 : commands->cmd_set[i].ntfn ) ||
108 0 : ( commands->cmd_set[i].returntype == RPC_RTYPE_WERROR &&
109 0 : commands->cmd_set[i].wfn))) {
110 0 : matches[count] = SMB_STRDUP(commands->cmd_set[i].name);
111 0 : if (!matches[count]) {
112 0 : for (i = 0; i < count; i++) {
113 0 : SAFE_FREE(matches[count]);
114 : }
115 0 : SAFE_FREE(matches);
116 0 : return NULL;
117 : }
118 0 : count++;
119 : }
120 : }
121 0 : commands = commands->next;
122 : }
123 :
124 0 : if (count == 2) {
125 0 : SAFE_FREE(matches[0]);
126 0 : matches[0] = SMB_STRDUP(matches[1]);
127 : }
128 0 : matches[count] = NULL;
129 0 : return matches;
130 : }
131 :
132 1408 : static char *next_command (char **cmdstr)
133 : {
134 : char *command;
135 : char *p;
136 :
137 1408 : if (!cmdstr || !(*cmdstr))
138 692 : return NULL;
139 :
140 716 : p = strchr_m(*cmdstr, ';');
141 716 : if (p)
142 24 : *p = '\0';
143 716 : command = SMB_STRDUP(*cmdstr);
144 716 : if (p)
145 24 : *cmdstr = p + 1;
146 : else
147 692 : *cmdstr = NULL;
148 :
149 716 : return command;
150 : }
151 :
152 554 : static void binding_get_auth_info(
153 : const struct dcerpc_binding *b,
154 : enum dcerpc_AuthType *_auth_type,
155 : enum dcerpc_AuthLevel *_auth_level,
156 : enum credentials_use_kerberos *_krb5_state)
157 : {
158 554 : uint32_t bflags = dcerpc_binding_get_flags(b);
159 554 : enum dcerpc_AuthLevel auth_level = DCERPC_AUTH_LEVEL_NONE;
160 554 : enum dcerpc_AuthType auth_type = DCERPC_AUTH_TYPE_NONE;
161 554 : enum credentials_use_kerberos krb5_state = CRED_USE_KERBEROS_DESIRED;
162 :
163 554 : if (_krb5_state != NULL) {
164 540 : krb5_state = *_krb5_state;
165 : }
166 :
167 554 : if (bflags & DCERPC_CONNECT) {
168 30 : auth_level = DCERPC_AUTH_LEVEL_CONNECT;
169 : }
170 554 : if (bflags & DCERPC_PACKET) {
171 54 : auth_level = DCERPC_AUTH_LEVEL_PACKET;
172 : }
173 554 : if (bflags & DCERPC_SIGN) {
174 68 : auth_level = DCERPC_AUTH_LEVEL_INTEGRITY;
175 : }
176 554 : if (bflags & DCERPC_SEAL) {
177 68 : auth_level = DCERPC_AUTH_LEVEL_PRIVACY;
178 : }
179 :
180 554 : if (bflags & DCERPC_SCHANNEL) {
181 32 : auth_type = DCERPC_AUTH_TYPE_SCHANNEL;
182 : }
183 :
184 554 : if ((auth_level != DCERPC_AUTH_LEVEL_NONE) &&
185 : (auth_type == DCERPC_AUTH_TYPE_NONE)) {
186 192 : auth_type = (krb5_state == CRED_USE_KERBEROS_REQUIRED) ?
187 192 : DCERPC_AUTH_TYPE_KRB5 : DCERPC_AUTH_TYPE_NTLMSSP;
188 : }
189 :
190 554 : if (bflags & DCERPC_AUTH_SPNEGO) {
191 159 : auth_type = DCERPC_AUTH_TYPE_SPNEGO;
192 :
193 159 : if (bflags & DCERPC_AUTH_NTLM) {
194 36 : krb5_state = CRED_USE_KERBEROS_DISABLED;
195 : }
196 159 : if (bflags & DCERPC_AUTH_KRB5) {
197 15 : krb5_state = CRED_USE_KERBEROS_REQUIRED;
198 : }
199 : }
200 :
201 554 : if (auth_type != DCERPC_AUTH_TYPE_NONE) {
202 : /* If nothing is requested then default to integrity */
203 259 : if (auth_level == DCERPC_AUTH_LEVEL_NONE) {
204 39 : auth_level = DCERPC_AUTH_LEVEL_INTEGRITY;
205 : }
206 : }
207 :
208 554 : if (_auth_type != NULL) {
209 554 : *_auth_type = auth_type;
210 : }
211 554 : if (_auth_level != NULL) {
212 554 : *_auth_level = auth_level;
213 : }
214 554 : if (_krb5_state != NULL) {
215 540 : *_krb5_state = krb5_state;
216 : }
217 554 : }
218 :
219 : /* List the available commands on a given pipe */
220 :
221 0 : static NTSTATUS cmd_listcommands(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
222 : int argc, const char **argv)
223 : {
224 : struct cmd_list *tmp;
225 : struct cmd_set *tmp_set;
226 : int i;
227 :
228 : /* Usage */
229 :
230 0 : if (argc != 2) {
231 0 : printf("Usage: %s <pipe>\n", argv[0]);
232 0 : return NT_STATUS_OK;
233 : }
234 :
235 : /* Help on one command */
236 :
237 0 : for (tmp = cmd_list; tmp; tmp = tmp->next)
238 : {
239 0 : tmp_set = tmp->cmd_set;
240 :
241 0 : if (!strcasecmp_m(argv[1], tmp_set->name))
242 : {
243 0 : printf("Available commands on the %s pipe:\n\n", tmp_set->name);
244 :
245 0 : i = 0;
246 0 : tmp_set++;
247 0 : while(tmp_set->name) {
248 0 : printf("%30s", tmp_set->name);
249 0 : tmp_set++;
250 0 : i++;
251 0 : if (i%3 == 0)
252 0 : printf("\n");
253 : }
254 :
255 : /* drop out of the loop */
256 0 : break;
257 : }
258 : }
259 0 : printf("\n\n");
260 :
261 0 : return NT_STATUS_OK;
262 : }
263 :
264 : /* Display help on commands */
265 :
266 0 : static NTSTATUS cmd_help(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
267 : int argc, const char **argv)
268 : {
269 : struct cmd_list *tmp;
270 : struct cmd_set *tmp_set;
271 :
272 : /* Usage */
273 :
274 0 : if (argc > 2) {
275 0 : printf("Usage: %s [command]\n", argv[0]);
276 0 : return NT_STATUS_OK;
277 : }
278 :
279 : /* Help on one command */
280 :
281 0 : if (argc == 2) {
282 0 : for (tmp = cmd_list; tmp; tmp = tmp->next) {
283 :
284 0 : tmp_set = tmp->cmd_set;
285 :
286 0 : while(tmp_set->name) {
287 0 : if (strequal(argv[1], tmp_set->name)) {
288 0 : if (tmp_set->usage &&
289 0 : tmp_set->usage[0])
290 0 : printf("%s\n", tmp_set->usage);
291 : else
292 0 : printf("No help for %s\n", tmp_set->name);
293 :
294 0 : return NT_STATUS_OK;
295 : }
296 :
297 0 : tmp_set++;
298 : }
299 : }
300 :
301 0 : printf("No such command: %s\n", argv[1]);
302 0 : return NT_STATUS_OK;
303 : }
304 :
305 : /* List all commands */
306 :
307 0 : for (tmp = cmd_list; tmp; tmp = tmp->next) {
308 :
309 0 : tmp_set = tmp->cmd_set;
310 :
311 0 : while(tmp_set->name) {
312 :
313 0 : printf("%15s\t\t%s\n", tmp_set->name,
314 0 : tmp_set->description ? tmp_set->description:
315 : "");
316 :
317 0 : tmp_set++;
318 : }
319 : }
320 :
321 0 : return NT_STATUS_OK;
322 : }
323 :
324 : /* Change the debug level */
325 :
326 0 : static NTSTATUS cmd_debuglevel(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
327 : int argc, const char **argv)
328 : {
329 0 : if (argc > 2) {
330 0 : printf("Usage: %s [debuglevel]\n", argv[0]);
331 0 : return NT_STATUS_OK;
332 : }
333 :
334 0 : if (argc == 2) {
335 0 : struct loadparm_context *lp_ctx = samba_cmdline_get_lp_ctx();
336 0 : lpcfg_set_cmdline(lp_ctx, "log level", argv[1]);
337 : }
338 :
339 0 : printf("debuglevel is %d\n", DEBUGLEVEL);
340 :
341 0 : return NT_STATUS_OK;
342 : }
343 :
344 0 : static NTSTATUS cmd_quit(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
345 : int argc, const char **argv)
346 : {
347 0 : exit(0);
348 : return NT_STATUS_OK; /* NOTREACHED */
349 : }
350 :
351 14 : static NTSTATUS cmd_set_ss_level(struct dcerpc_binding *binding)
352 : {
353 : struct cmd_list *tmp;
354 : enum dcerpc_AuthType auth_type;
355 : enum dcerpc_AuthLevel auth_level;
356 :
357 : /* Close any existing connections not at this level. */
358 :
359 14 : binding_get_auth_info(binding, &auth_type, &auth_level, NULL);
360 :
361 630 : for (tmp = cmd_list; tmp; tmp = tmp->next) {
362 : struct cmd_set *tmp_set;
363 :
364 4508 : for (tmp_set = tmp->cmd_set; tmp_set->name; tmp_set++) {
365 3892 : if (tmp_set->rpc_pipe == NULL) {
366 3892 : continue;
367 : }
368 :
369 0 : if ((tmp_set->rpc_pipe->auth->auth_type
370 0 : != auth_type)
371 0 : || (tmp_set->rpc_pipe->auth->auth_level
372 0 : != auth_level)) {
373 0 : TALLOC_FREE(tmp_set->rpc_pipe);
374 0 : tmp_set->rpc_pipe = NULL;
375 : }
376 : }
377 : }
378 14 : return NT_STATUS_OK;
379 : }
380 :
381 0 : static NTSTATUS cmd_set_transport(struct dcerpc_binding *b)
382 : {
383 0 : enum dcerpc_transport_t t = dcerpc_binding_get_transport(b);
384 : struct cmd_list *tmp;
385 :
386 : /* Close any existing connections not at this level. */
387 :
388 0 : for (tmp = cmd_list; tmp; tmp = tmp->next) {
389 : struct cmd_set *tmp_set;
390 :
391 0 : for (tmp_set = tmp->cmd_set; tmp_set->name; tmp_set++) {
392 0 : if (tmp_set->rpc_pipe == NULL) {
393 0 : continue;
394 : }
395 :
396 0 : if (tmp_set->rpc_pipe->transport->transport != t) {
397 0 : TALLOC_FREE(tmp_set->rpc_pipe);
398 0 : tmp_set->rpc_pipe = NULL;
399 : }
400 : }
401 : }
402 0 : return NT_STATUS_OK;
403 : }
404 :
405 14 : static NTSTATUS binding_reset_auth(struct dcerpc_binding *b)
406 : {
407 14 : NTSTATUS status = dcerpc_binding_set_flags(
408 : b,
409 : 0,
410 : DCERPC_PACKET|
411 : DCERPC_CONNECT|
412 : DCERPC_SIGN|
413 : DCERPC_SEAL|
414 : DCERPC_SCHANNEL|
415 : DCERPC_AUTH_SPNEGO|
416 : DCERPC_AUTH_KRB5|
417 : DCERPC_AUTH_NTLM);
418 14 : return status;
419 : }
420 :
421 14 : static NTSTATUS binding_set_auth(
422 : struct dcerpc_binding *b, const char *level, const char *type)
423 : {
424 : NTSTATUS status;
425 :
426 14 : status = binding_reset_auth(b);
427 14 : if (!NT_STATUS_IS_OK(status)) {
428 0 : return status;
429 : }
430 :
431 14 : if (level != NULL) {
432 14 : status = dcerpc_binding_set_string_option(b, level, level);
433 14 : if (!NT_STATUS_IS_OK(status)) {
434 0 : return status;
435 : }
436 : }
437 :
438 14 : if (strequal(type, "SPNEGO")) {
439 0 : status = dcerpc_binding_set_string_option(
440 : b, "spnego", "spnego");
441 0 : return status;
442 : }
443 14 : if (strequal(type, "NTLMSSP")) {
444 0 : status = dcerpc_binding_set_string_option(b, "ntlm", "ntlm");
445 0 : return status;
446 : }
447 14 : if (strequal(type, "NTLMSSP_SPNEGO")) {
448 0 : status = dcerpc_binding_set_string_option(
449 : b, "spnego", "spnego");
450 0 : if (!NT_STATUS_IS_OK(status)) {
451 0 : return status;
452 : }
453 0 : status = dcerpc_binding_set_string_option(b, "ntlm", "ntlm");
454 0 : return status;
455 : }
456 14 : if (strequal(type, "KRB5")) {
457 0 : status = dcerpc_binding_set_string_option(b, "krb5", "krb5");
458 0 : return status;
459 : }
460 14 : if (strequal(type, "KRB5_SPNEGO")) {
461 0 : status = dcerpc_binding_set_string_option(
462 : b, "spnego", "spnego");
463 0 : if (!NT_STATUS_IS_OK(status)) {
464 0 : return status;
465 : }
466 0 : status = dcerpc_binding_set_string_option(b, "krb5", "krb5");
467 0 : return status;
468 : }
469 14 : if (strequal(type, "SCHANNEL")) {
470 14 : status = dcerpc_binding_set_string_option(
471 : b, "schannel", "schannel");
472 14 : return status;
473 : }
474 :
475 0 : return NT_STATUS_INVALID_PARAMETER;
476 : }
477 :
478 14 : static NTSTATUS cmd_set_auth(
479 : struct dcerpc_binding *binding,
480 : const char *level,
481 : const char *display,
482 : int argc,
483 : const char **argv)
484 : {
485 14 : const char *p = "[KRB5|KRB5_SPNEGO|NTLMSSP|NTLMSSP_SPNEGO|SCHANNEL]";
486 14 : const char *type = "NTLMSSP";
487 : NTSTATUS status;
488 :
489 14 : if (argc > 2) {
490 0 : printf("Usage: %s %s\n", argv[0], p);
491 0 : return NT_STATUS_OK;
492 : }
493 :
494 14 : if (argc == 2) {
495 14 : type = argv[1];
496 : }
497 :
498 14 : status = binding_set_auth(binding, level, type);
499 14 : if (!NT_STATUS_IS_OK(status)) {
500 0 : printf("Usage: %s %s\n", argv[0], p);
501 0 : return status;
502 : }
503 :
504 14 : d_printf("Setting %s - %s: %s\n", type, display, nt_errstr(status));
505 :
506 14 : status = cmd_set_ss_level(binding);
507 14 : return status;
508 : }
509 :
510 0 : static NTSTATUS cmd_sign(
511 : struct dcerpc_binding *binding,
512 : TALLOC_CTX *mem_ctx,
513 : int argc,
514 : const char **argv)
515 : {
516 0 : NTSTATUS status = cmd_set_auth(binding, "sign", "sign", argc, argv);
517 0 : return status;
518 : }
519 :
520 0 : static NTSTATUS cmd_seal(
521 : struct dcerpc_binding *binding,
522 : TALLOC_CTX *mem_ctx,
523 : int argc,
524 : const char **argv)
525 : {
526 0 : NTSTATUS status = cmd_set_auth(
527 : binding, "seal", "sign and seal", argc, argv);
528 0 : return status;
529 : }
530 :
531 0 : static NTSTATUS cmd_packet(
532 : struct dcerpc_binding *binding,
533 : TALLOC_CTX *mem_ctx,
534 : int argc,
535 : const char **argv)
536 : {
537 0 : NTSTATUS status = cmd_set_auth(
538 : binding, "packet", "packet", argc, argv);
539 0 : return status;
540 : }
541 :
542 0 : static NTSTATUS cmd_timeout(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
543 : int argc, const char **argv)
544 : {
545 0 : if (argc > 2) {
546 0 : printf("Usage: %s timeout\n", argv[0]);
547 0 : return NT_STATUS_OK;
548 : }
549 :
550 0 : if (argc == 2) {
551 0 : timeout = atoi(argv[1]);
552 : }
553 :
554 0 : printf("timeout is %d\n", timeout);
555 :
556 0 : return NT_STATUS_OK;
557 : }
558 :
559 :
560 0 : static NTSTATUS cmd_none(
561 : struct dcerpc_binding *binding,
562 : TALLOC_CTX *mem_ctx,
563 : int argc,
564 : const char **argv)
565 : {
566 0 : NTSTATUS status = binding_reset_auth(binding);
567 0 : if (!NT_STATUS_IS_OK(status)) {
568 0 : return status;
569 : }
570 0 : status = cmd_set_ss_level(binding);
571 0 : return status;
572 : }
573 :
574 7 : static NTSTATUS cmd_schannel(
575 : struct dcerpc_binding *binding,
576 : TALLOC_CTX *mem_ctx,
577 : int argc,
578 : const char **_argv)
579 : {
580 7 : const char *argv[] = { "schannel", "SCHANNEL" };
581 7 : NTSTATUS status = cmd_set_auth(
582 : binding, "seal", "sign and seal", 2, argv);
583 7 : return status;
584 : }
585 :
586 7 : static NTSTATUS cmd_schannel_sign(
587 : struct dcerpc_binding *binding,
588 : TALLOC_CTX *mem_ctx,
589 : int argc,
590 : const char **_argv)
591 : {
592 7 : const char *argv[] = { "schannel_sign", "SCHANNEL" };
593 7 : NTSTATUS status = cmd_set_auth(binding, "sign", "sign only", 2, argv);
594 7 : return status;
595 : }
596 :
597 0 : static NTSTATUS cmd_choose_transport(
598 : struct dcerpc_binding *binding,
599 : TALLOC_CTX *mem_ctx,
600 : int argc,
601 : const char **argv)
602 : {
603 : NTSTATUS status;
604 : enum dcerpc_transport_t transport;
605 :
606 0 : if (argc != 2) {
607 0 : printf("Usage: %s [NCACN_NP|NCACN_IP_TCP]\n", argv[0]);
608 0 : return NT_STATUS_OK;
609 : }
610 :
611 0 : transport = dcerpc_transport_by_name(argv[1]);
612 0 : if (transport == NCA_UNKNOWN) {
613 0 : printf("transport type %s unknown\n", argv[1]);
614 0 : return NT_STATUS_NOT_SUPPORTED;
615 : }
616 0 : if (!((transport == NCACN_IP_TCP) ||
617 : (transport == NCACN_NP) ||
618 : (transport == NCALRPC))) {
619 0 : printf("transport %s not supported\n", argv[1]);
620 0 : return NT_STATUS_NOT_SUPPORTED;
621 : }
622 :
623 0 : status = dcerpc_binding_set_transport(binding, transport);
624 0 : if (!NT_STATUS_IS_OK(status)) {
625 0 : return status;
626 : }
627 :
628 0 : status = cmd_set_transport(binding);
629 0 : if (!NT_STATUS_IS_OK(status)) {
630 0 : return status;
631 : }
632 :
633 0 : printf("default transport is now: %s\n", argv[1]);
634 :
635 0 : return NT_STATUS_OK;
636 : }
637 :
638 : /* Built in rpcclient commands */
639 :
640 : static struct cmd_set rpcclient_commands[] = {
641 :
642 : {
643 : .name = "GENERAL OPTIONS",
644 : },
645 :
646 : {
647 : .name = "help",
648 : .returntype = RPC_RTYPE_NTSTATUS,
649 : .ntfn = cmd_help,
650 : .description = "Get help on commands",
651 : .usage = "[command]",
652 : },
653 : {
654 : .name = "?",
655 : .returntype = RPC_RTYPE_NTSTATUS,
656 : .ntfn = cmd_help,
657 : .description = "Get help on commands",
658 : .usage = "[command]",
659 : },
660 : {
661 : .name = "debuglevel",
662 : .returntype = RPC_RTYPE_NTSTATUS,
663 : .ntfn = cmd_debuglevel,
664 : .description = "Set debug level",
665 : .usage = "level",
666 : },
667 : {
668 : .name = "debug",
669 : .returntype = RPC_RTYPE_NTSTATUS,
670 : .ntfn = cmd_debuglevel,
671 : .description = "Set debug level",
672 : .usage = "level",
673 : },
674 : {
675 : .name = "list",
676 : .returntype = RPC_RTYPE_NTSTATUS,
677 : .ntfn = cmd_listcommands,
678 : .description = "List available commands on <pipe>",
679 : .usage = "pipe",
680 : },
681 : {
682 : .name = "exit",
683 : .returntype = RPC_RTYPE_NTSTATUS,
684 : .ntfn = cmd_quit,
685 : .description = "Exit program",
686 : .usage = "",
687 : },
688 : {
689 : .name = "quit",
690 : .returntype = RPC_RTYPE_NTSTATUS,
691 : .ntfn = cmd_quit,
692 : .description = "Exit program",
693 : .usage = "",
694 : },
695 : {
696 : .name = "sign",
697 : .returntype = RPC_RTYPE_BINDING,
698 : .bfn = cmd_sign,
699 : .description = "Force RPC pipe connections to be signed",
700 : .usage = "",
701 : },
702 : {
703 : .name = "seal",
704 : .returntype = RPC_RTYPE_BINDING,
705 : .bfn = cmd_seal,
706 : .description = "Force RPC pipe connections to be sealed",
707 : .usage = "",
708 : },
709 : {
710 : .name = "packet",
711 : .returntype = RPC_RTYPE_BINDING,
712 : .bfn = cmd_packet,
713 : .description = "Force RPC pipe connections with packet authentication level",
714 : .usage = "",
715 : },
716 : {
717 : .name = "schannel",
718 : .returntype = RPC_RTYPE_BINDING,
719 : .bfn = cmd_schannel,
720 : .description = "Force RPC pipe connections to be sealed with 'schannel'. "
721 : "Assumes valid machine account to this domain controller.",
722 : .usage = "",
723 : },
724 : {
725 : .name = "schannelsign",
726 : .returntype = RPC_RTYPE_BINDING,
727 : .bfn = cmd_schannel_sign,
728 : .description = "Force RPC pipe connections to be signed (not sealed) with "
729 : "'schannel'. Assumes valid machine account to this domain "
730 : "controller.",
731 : .usage = "",
732 : },
733 : {
734 : .name = "timeout",
735 : .returntype = RPC_RTYPE_NTSTATUS,
736 : .ntfn = cmd_timeout,
737 : .description = "Set timeout (in milliseconds) for RPC operations",
738 : .usage = "",
739 : },
740 : {
741 : .name = "transport",
742 : .returntype = RPC_RTYPE_BINDING,
743 : .bfn = cmd_choose_transport,
744 : .description = "Choose ncacn transport for RPC operations",
745 : .usage = "",
746 : },
747 : {
748 : .name = "none",
749 : .returntype = RPC_RTYPE_BINDING,
750 : .bfn = cmd_none,
751 : .description = "Force RPC pipe connections to have no special properties",
752 : .usage = "",
753 : },
754 :
755 : { .name = NULL, },
756 : };
757 :
758 : static struct cmd_set separator_command[] = {
759 : {
760 : .name = "---------------",
761 : .returntype = MAX_RPC_RETURN_TYPE,
762 : .description = "----------------------"
763 : },
764 : { .name = NULL, },
765 : };
766 :
767 :
768 : /* Various pipe commands */
769 :
770 : extern struct cmd_set lsarpc_commands[];
771 : extern struct cmd_set samr_commands[];
772 : extern struct cmd_set spoolss_commands[];
773 : extern struct cmd_set iremotewinspool_commands[];
774 : extern struct cmd_set netlogon_commands[];
775 : extern struct cmd_set srvsvc_commands[];
776 : extern struct cmd_set dfs_commands[];
777 : extern struct cmd_set ds_commands[];
778 : extern struct cmd_set echo_commands[];
779 : extern struct cmd_set epmapper_commands[];
780 : extern struct cmd_set shutdown_commands[];
781 : extern struct cmd_set wkssvc_commands[];
782 : extern struct cmd_set ntsvcs_commands[];
783 : extern struct cmd_set drsuapi_commands[];
784 : extern struct cmd_set eventlog_commands[];
785 : extern struct cmd_set winreg_commands[];
786 : extern struct cmd_set fss_commands[];
787 : extern struct cmd_set witness_commands[];
788 : extern struct cmd_set clusapi_commands[];
789 : extern struct cmd_set spotlight_commands[];
790 : extern struct cmd_set unixinfo_commands[];
791 :
792 : static struct cmd_set *rpcclient_command_list[] = {
793 : rpcclient_commands,
794 : lsarpc_commands,
795 : ds_commands,
796 : samr_commands,
797 : spoolss_commands,
798 : iremotewinspool_commands,
799 : netlogon_commands,
800 : srvsvc_commands,
801 : dfs_commands,
802 : echo_commands,
803 : epmapper_commands,
804 : shutdown_commands,
805 : wkssvc_commands,
806 : ntsvcs_commands,
807 : drsuapi_commands,
808 : eventlog_commands,
809 : winreg_commands,
810 : fss_commands,
811 : witness_commands,
812 : clusapi_commands,
813 : spotlight_commands,
814 : unixinfo_commands,
815 : NULL
816 : };
817 :
818 30448 : static void add_command_set(struct cmd_set *cmd_set)
819 : {
820 : struct cmd_list *entry;
821 :
822 30448 : if (!(entry = SMB_MALLOC_P(struct cmd_list))) {
823 0 : DEBUG(0, ("out of memory\n"));
824 0 : return;
825 : }
826 :
827 30448 : ZERO_STRUCTP(entry);
828 :
829 30448 : entry->cmd_set = cmd_set;
830 30448 : DLIST_ADD(cmd_list, entry);
831 : }
832 :
833 152 : static NTSTATUS rpccli_ncalrpc_connect(
834 : const struct ndr_interface_table *iface,
835 : TALLOC_CTX *mem_ctx,
836 : struct rpc_pipe_client **prpccli)
837 : {
838 152 : struct rpc_pipe_client *rpccli = NULL;
839 152 : struct pipe_auth_data *auth = NULL;
840 : NTSTATUS status;
841 :
842 152 : status = rpc_pipe_open_ncalrpc(mem_ctx, iface, &rpccli);
843 152 : if (!NT_STATUS_IS_OK(status)) {
844 16 : DBG_DEBUG("rpc_pipe_open_ncalrpc failed: %s\n",
845 : nt_errstr(status));
846 16 : goto fail;
847 : }
848 :
849 136 : status = rpccli_ncalrpc_bind_data(rpccli, &auth);
850 136 : if (!NT_STATUS_IS_OK(status)) {
851 0 : DBG_DEBUG("rpccli_ncalrpc_bind_data failed: %s\n",
852 : nt_errstr(status));
853 0 : goto fail;
854 : }
855 :
856 136 : status = rpc_pipe_bind(rpccli, auth);
857 136 : if (!NT_STATUS_IS_OK(status)) {
858 0 : DBG_DEBUG("rpc_pipe_bind failed: %s\n", nt_errstr(status));
859 0 : goto fail;
860 : }
861 :
862 136 : *prpccli = rpccli;
863 136 : return NT_STATUS_OK;
864 16 : fail:
865 16 : TALLOC_FREE(rpccli);
866 16 : return status;
867 : }
868 : /**
869 : * Call an rpcclient function, passing an argv array.
870 : *
871 : * @param cmd Command to run, as a single string.
872 : **/
873 716 : static NTSTATUS do_cmd(struct cli_state *cli,
874 : struct cli_credentials *creds,
875 : struct cmd_set *cmd_entry,
876 : struct dcerpc_binding *binding,
877 : int argc, const char **argv)
878 : {
879 : NTSTATUS ntresult;
880 : WERROR wresult;
881 : enum dcerpc_transport_t transport;
882 :
883 716 : TALLOC_CTX *mem_ctx = talloc_stackframe();
884 716 : const char *remote_name = NULL;
885 716 : const struct sockaddr_storage *remote_sockaddr = NULL;
886 716 : struct sockaddr_storage remote_ss = {
887 : .ss_family = AF_UNSPEC,
888 : };
889 :
890 716 : transport = dcerpc_binding_get_transport(binding);
891 :
892 716 : if (cli != NULL) {
893 466 : remote_name = smbXcli_conn_remote_name(cli->conn);
894 466 : remote_sockaddr = smbXcli_conn_remote_sockaddr(cli->conn);
895 : } else {
896 : const char *remote_host =
897 250 : dcerpc_binding_get_string_option(binding, "host");
898 250 : remote_name = dcerpc_binding_get_string_option(
899 : binding, "target_hostname");
900 :
901 250 : if (remote_host != NULL) {
902 98 : bool ok = interpret_string_addr(
903 : &remote_ss, remote_host, 0);
904 98 : if (ok) {
905 98 : remote_sockaddr = &remote_ss;
906 : }
907 : }
908 : }
909 :
910 : /* Open pipe */
911 :
912 716 : if ((cmd_entry->table != NULL) && (cmd_entry->rpc_pipe == NULL)) {
913 692 : if (transport == NCALRPC) {
914 152 : ntresult = rpccli_ncalrpc_connect(
915 : cmd_entry->table, cli, &cmd_entry->rpc_pipe);
916 152 : if (!NT_STATUS_IS_OK(ntresult)) {
917 16 : TALLOC_FREE(mem_ctx);
918 16 : return ntresult;
919 : }
920 : } else {
921 : enum dcerpc_AuthType auth_type;
922 : enum dcerpc_AuthLevel auth_level;
923 540 : enum credentials_use_kerberos krb5_state =
924 540 : cli_credentials_get_kerberos_state(creds);
925 :
926 540 : binding_get_auth_info(
927 : binding, &auth_type, &auth_level, &krb5_state);
928 :
929 540 : switch (auth_type) {
930 295 : case DCERPC_AUTH_TYPE_NONE:
931 295 : ntresult = cli_rpc_pipe_open_noauth_transport(
932 : cli, transport,
933 : cmd_entry->table,
934 : remote_name,
935 : remote_sockaddr,
936 : &cmd_entry->rpc_pipe);
937 295 : break;
938 227 : case DCERPC_AUTH_TYPE_SPNEGO:
939 : case DCERPC_AUTH_TYPE_NTLMSSP:
940 : case DCERPC_AUTH_TYPE_KRB5:
941 227 : cli_credentials_set_kerberos_state(creds,
942 : krb5_state,
943 : CRED_SPECIFIED);
944 :
945 227 : ntresult = cli_rpc_pipe_open_with_creds(
946 : cli, cmd_entry->table,
947 : transport,
948 : auth_type,
949 : auth_level,
950 : remote_name,
951 : remote_sockaddr,
952 : creds,
953 : &cmd_entry->rpc_pipe);
954 227 : break;
955 18 : case DCERPC_AUTH_TYPE_SCHANNEL:
956 18 : TALLOC_FREE(rpcclient_netlogon_creds);
957 18 : ntresult = cli_rpc_pipe_open_schannel(
958 : cli, rpcclient_msg_ctx,
959 : cmd_entry->table,
960 : transport,
961 : rpcclient_netlogon_domain,
962 : remote_name,
963 : remote_sockaddr,
964 : &cmd_entry->rpc_pipe,
965 : rpcclient_msg_ctx,
966 : &rpcclient_netlogon_creds);
967 18 : break;
968 0 : default:
969 0 : DEBUG(0, ("Could not initialise %s. Invalid "
970 : "auth type %u\n",
971 : cmd_entry->table->name,
972 : auth_type ));
973 0 : talloc_free(mem_ctx);
974 0 : return NT_STATUS_UNSUCCESSFUL;
975 : }
976 540 : if (!NT_STATUS_IS_OK(ntresult)) {
977 0 : DBG_ERR("Could not initialise %s. "
978 : "Error was %s\n",
979 : cmd_entry->table->name,
980 : nt_errstr(ntresult));
981 0 : talloc_free(mem_ctx);
982 0 : return ntresult;
983 : }
984 :
985 540 : if (rpcclient_netlogon_creds == NULL &&
986 522 : cmd_entry->use_netlogon_creds) {
987 18 : const char *dc_name =
988 18 : cmd_entry->rpc_pipe->desthost;
989 18 : const char *domain = rpcclient_netlogon_domain;
990 18 : struct cli_credentials *trust_creds = NULL;
991 :
992 18 : ntresult = pdb_get_trust_credentials(
993 : domain,
994 : NULL,
995 : mem_ctx,
996 : &trust_creds);
997 18 : if (!NT_STATUS_IS_OK(ntresult)) {
998 0 : DBG_ERR("Failed to fetch trust "
999 : "credentials for "
1000 : "%s to connect to %s: %s\n",
1001 : domain,
1002 : cmd_entry->table->name,
1003 : nt_errstr(ntresult));
1004 0 : TALLOC_FREE(cmd_entry->rpc_pipe);
1005 0 : talloc_free(mem_ctx);
1006 0 : return ntresult;
1007 : }
1008 :
1009 18 : ntresult = rpccli_create_netlogon_creds_ctx(
1010 : trust_creds,
1011 : dc_name,
1012 : rpcclient_msg_ctx,
1013 : rpcclient_msg_ctx,
1014 : &rpcclient_netlogon_creds);
1015 18 : if (!NT_STATUS_IS_OK(ntresult)) {
1016 0 : DBG_ERR("Could not initialise "
1017 : "credentials for %s.\n",
1018 : cmd_entry->table->name);
1019 0 : TALLOC_FREE(cmd_entry->rpc_pipe);
1020 0 : TALLOC_FREE(mem_ctx);
1021 0 : return ntresult;
1022 : }
1023 :
1024 18 : ntresult = rpccli_setup_netlogon_creds(
1025 : cli,
1026 : NCACN_NP,
1027 : rpcclient_netlogon_creds,
1028 : false, /* force_reauth */
1029 : trust_creds);
1030 18 : TALLOC_FREE(trust_creds);
1031 18 : if (!NT_STATUS_IS_OK(ntresult)) {
1032 0 : DBG_ERR("Could not initialise "
1033 : "credentials for %s.\n",
1034 : cmd_entry->table->name);
1035 0 : TALLOC_FREE(cmd_entry->rpc_pipe);
1036 0 : TALLOC_FREE(rpcclient_netlogon_creds);
1037 0 : TALLOC_FREE(mem_ctx);
1038 0 : return ntresult;
1039 : }
1040 : }
1041 : }
1042 : }
1043 :
1044 : /* Set timeout for new connections */
1045 700 : if (cmd_entry->rpc_pipe) {
1046 686 : rpccli_set_timeout(cmd_entry->rpc_pipe, timeout);
1047 : }
1048 :
1049 : /* Run command */
1050 :
1051 700 : if ( cmd_entry->returntype == RPC_RTYPE_NTSTATUS ) {
1052 609 : ntresult = cmd_entry->ntfn(cmd_entry->rpc_pipe, mem_ctx, argc, argv);
1053 609 : if (!NT_STATUS_IS_OK(ntresult)) {
1054 64 : printf("result was %s\n", nt_errstr(ntresult));
1055 : }
1056 91 : } else if (cmd_entry->returntype == RPC_RTYPE_BINDING) {
1057 14 : ntresult = cmd_entry->bfn(binding, mem_ctx, argc, argv);
1058 14 : if (!NT_STATUS_IS_OK(ntresult)) {
1059 0 : printf("result was %s\n", nt_errstr(ntresult));
1060 : }
1061 : } else {
1062 77 : wresult = cmd_entry->wfn(cmd_entry->rpc_pipe, mem_ctx, argc, argv);
1063 : /* print out the DOS error */
1064 77 : if (!W_ERROR_IS_OK(wresult)) {
1065 5 : printf( "result was %s\n", win_errstr(wresult));
1066 : }
1067 77 : ntresult = W_ERROR_IS_OK(wresult)?NT_STATUS_OK:NT_STATUS_UNSUCCESSFUL;
1068 : }
1069 :
1070 : /* Cleanup */
1071 :
1072 700 : talloc_free(mem_ctx);
1073 :
1074 700 : return ntresult;
1075 : }
1076 :
1077 :
1078 : /**
1079 : * Process a command entered at the prompt or as part of -c
1080 : *
1081 : * @returns The NTSTATUS from running the command.
1082 : **/
1083 716 : static NTSTATUS process_cmd(struct cli_credentials *creds,
1084 : struct cli_state *cli,
1085 : struct dcerpc_binding *binding,
1086 : char *cmd)
1087 : {
1088 : struct cmd_list *temp_list;
1089 716 : NTSTATUS result = NT_STATUS_OK;
1090 : int ret;
1091 : int argc;
1092 716 : const char **argv = NULL;
1093 :
1094 716 : if ((ret = poptParseArgvString(cmd, &argc, &argv)) != 0) {
1095 0 : fprintf(stderr, "rpcclient: %s\n", poptStrerror(ret));
1096 0 : return NT_STATUS_UNSUCCESSFUL;
1097 : }
1098 :
1099 :
1100 : /* Walk through a dlist of arrays of commands. */
1101 24324 : for (temp_list = cmd_list; temp_list; temp_list = temp_list->next) {
1102 24324 : struct cmd_set *set = temp_list->cmd_set;
1103 :
1104 143632 : while (set->name != NULL) {
1105 120024 : if (!strequal(argv[0], set->name)) {
1106 119308 : set += 1;
1107 119308 : continue;
1108 : }
1109 :
1110 716 : if (((set->returntype == RPC_RTYPE_NTSTATUS) &&
1111 625 : (set->ntfn == NULL)) ||
1112 716 : ((set->returntype == RPC_RTYPE_WERROR) &&
1113 77 : (set->wfn == NULL)) ||
1114 716 : ((set->returntype == RPC_RTYPE_BINDING) &&
1115 14 : (set->bfn == NULL))) {
1116 0 : fprintf (stderr, "Invalid command\n");
1117 0 : goto out_free;
1118 : }
1119 :
1120 716 : result = do_cmd(
1121 : cli, creds, set, binding, argc, argv);
1122 716 : goto out_free;
1123 : }
1124 : }
1125 :
1126 0 : if (argv[0]) {
1127 0 : printf("command not found: %s\n", argv[0]);
1128 : }
1129 :
1130 0 : out_free:
1131 : /* moved to do_cmd()
1132 : if (!NT_STATUS_IS_OK(result)) {
1133 : printf("result was %s\n", nt_errstr(result));
1134 : }
1135 : */
1136 :
1137 : /* NOTE: popt allocates the whole argv, including the
1138 : * strings, as a single block. So a single free is
1139 : * enough to release it -- we don't free the
1140 : * individual strings. rtfm. */
1141 716 : free(argv);
1142 :
1143 716 : return result;
1144 : }
1145 :
1146 :
1147 : /* Main function */
1148 :
1149 719 : int main(int argc, char *argv[])
1150 : {
1151 719 : const char **const_argv = discard_const_p(const char *, argv);
1152 : int opt;
1153 : static char *cmdstr = NULL;
1154 : const char *server;
1155 719 : struct cli_state *cli = NULL;
1156 : static char *opt_ipaddr=NULL;
1157 : struct cmd_set **cmd_set;
1158 : struct sockaddr_storage server_ss;
1159 : NTSTATUS nt_status;
1160 : static int opt_port = 0;
1161 719 : int result = 0;
1162 719 : TALLOC_CTX *frame = talloc_stackframe();
1163 719 : uint32_t flags = CLI_FULL_CONNECTION_IPC;
1164 719 : struct dcerpc_binding *binding = NULL;
1165 : enum dcerpc_transport_t transport;
1166 719 : const char *binding_string = NULL;
1167 : const char *host;
1168 719 : struct cli_credentials *creds = NULL;
1169 719 : struct loadparm_context *lp_ctx = NULL;
1170 : bool ok;
1171 :
1172 : /* make sure the vars that get altered (4th field) are in
1173 : a fixed location or certain compilers complain */
1174 : poptContext pc;
1175 4314 : struct poptOption long_options[] = {
1176 : POPT_AUTOHELP
1177 : {"command", 'c', POPT_ARG_STRING, &cmdstr, 'c', "Execute semicolon separated cmds", "COMMANDS"},
1178 : {"dest-ip", 'I', POPT_ARG_STRING, &opt_ipaddr, 'I', "Specify destination IP address", "IP"},
1179 : {"port", 'p', POPT_ARG_INT, &opt_port, 'p', "Specify port number", "PORT"},
1180 719 : POPT_COMMON_SAMBA
1181 719 : POPT_COMMON_CONNECTION
1182 719 : POPT_COMMON_CREDENTIALS
1183 719 : POPT_LEGACY_S3
1184 719 : POPT_COMMON_VERSION
1185 : POPT_TABLEEND
1186 : };
1187 :
1188 719 : smb_init_locale();
1189 :
1190 719 : zero_sockaddr(&server_ss);
1191 :
1192 719 : setlinebuf(stdout);
1193 :
1194 719 : ok = samba_cmdline_init(frame,
1195 : SAMBA_CMDLINE_CONFIG_CLIENT,
1196 : false /* require_smbconf */);
1197 719 : if (!ok) {
1198 0 : DBG_ERR("Failed to init cmdline parser!\n");
1199 : }
1200 719 : lp_ctx = samba_cmdline_get_lp_ctx();
1201 719 : lpcfg_set_cmdline(lp_ctx, "log level", "0");
1202 :
1203 : /* Parse options */
1204 719 : pc = samba_popt_get_context(getprogname(),
1205 : argc,
1206 : const_argv,
1207 : long_options,
1208 : 0);
1209 719 : if (pc == NULL) {
1210 0 : DBG_ERR("Failed to setup popt context!\n");
1211 0 : exit(1);
1212 : }
1213 :
1214 719 : poptSetOtherOptionHelp(pc, "[OPTION...] BINDING-STRING|HOST\nOptions:");
1215 :
1216 719 : if (argc == 1) {
1217 0 : poptPrintHelp(pc, stderr, 0);
1218 0 : goto done;
1219 : }
1220 :
1221 1553 : while((opt = poptGetNextOpt(pc)) != -1) {
1222 719 : switch (opt) {
1223 :
1224 0 : case 'I':
1225 0 : if (!interpret_string_addr(&server_ss,
1226 : opt_ipaddr,
1227 : AI_NUMERICHOST)) {
1228 0 : fprintf(stderr, "%s not a valid IP address\n",
1229 : opt_ipaddr);
1230 0 : result = 1;
1231 0 : goto done;
1232 : }
1233 0 : break;
1234 0 : case POPT_ERROR_BADOPT:
1235 0 : fprintf(stderr, "\nInvalid option %s: %s\n\n",
1236 : poptBadOption(pc, 0), poptStrerror(opt));
1237 0 : poptPrintUsage(pc, stderr, 0);
1238 0 : exit(1);
1239 : }
1240 : }
1241 :
1242 : /* Get server as remaining unparsed argument. Print usage if more
1243 : than one unparsed argument is present. */
1244 :
1245 719 : server = talloc_strdup(frame, poptGetArg(pc));
1246 :
1247 719 : if (!server || poptGetArg(pc)) {
1248 0 : poptPrintHelp(pc, stderr, 0);
1249 0 : result = 1;
1250 0 : goto done;
1251 : }
1252 :
1253 719 : poptFreeContext(pc);
1254 719 : samba_cmdline_burn(argc, argv);
1255 :
1256 719 : rpcclient_msg_ctx = cmdline_messaging_context(get_dyn_CONFIGFILE());
1257 719 : creds = samba_cmdline_get_creds();
1258 :
1259 : /*
1260 : * Get password
1261 : * from stdin if necessary
1262 : */
1263 :
1264 719 : if ((server[0] == '/' && server[1] == '/') ||
1265 711 : (server[0] == '\\' && server[1] == '\\')) {
1266 8 : server += 2;
1267 : }
1268 :
1269 719 : nt_status = dcerpc_parse_binding(frame, server, &binding);
1270 :
1271 719 : if (!NT_STATUS_IS_OK(nt_status)) {
1272 :
1273 0 : binding_string = talloc_asprintf(frame, "ncacn_np:%s",
1274 : strip_hostname(server));
1275 0 : if (!binding_string) {
1276 0 : result = 1;
1277 0 : goto done;
1278 : }
1279 :
1280 0 : nt_status = dcerpc_parse_binding(frame, binding_string, &binding);
1281 0 : if (!NT_STATUS_IS_OK(nt_status)) {
1282 0 : result = -1;
1283 0 : goto done;
1284 : }
1285 : }
1286 :
1287 719 : transport = dcerpc_binding_get_transport(binding);
1288 :
1289 719 : if (transport == NCA_UNKNOWN) {
1290 249 : transport = NCACN_NP;
1291 249 : nt_status = dcerpc_binding_set_transport(binding, transport);
1292 249 : if (!NT_STATUS_IS_OK(nt_status)) {
1293 0 : result = -1;
1294 0 : goto done;
1295 : }
1296 : }
1297 :
1298 719 : host = dcerpc_binding_get_string_option(binding, "host");
1299 :
1300 719 : rpcclient_netlogon_domain = cli_credentials_get_domain(creds);
1301 719 : if (rpcclient_netlogon_domain == NULL ||
1302 719 : rpcclient_netlogon_domain[0] == '\0')
1303 : {
1304 46 : rpcclient_netlogon_domain = lp_workgroup();
1305 : }
1306 :
1307 719 : if (transport == NCACN_NP) {
1308 469 : nt_status = cli_full_connection_creds(
1309 : &cli,
1310 : lp_netbios_name(),
1311 : host,
1312 469 : opt_ipaddr ? &server_ss : NULL,
1313 : opt_port,
1314 : "IPC$",
1315 : "IPC",
1316 : creds,
1317 : flags);
1318 :
1319 469 : if (!NT_STATUS_IS_OK(nt_status)) {
1320 27 : DEBUG(0, ("Cannot connect to server. Error was %s\n",
1321 : nt_errstr(nt_status)));
1322 27 : result = 1;
1323 27 : goto done;
1324 : }
1325 :
1326 : /* Load command lists */
1327 442 : cli_set_timeout(cli, timeout);
1328 : }
1329 :
1330 : #if 0 /* COMMENT OUT FOR TESTING */
1331 : memset(cmdline_auth_info.password,'X',sizeof(cmdline_auth_info.password));
1332 : #endif
1333 :
1334 692 : cmd_set = rpcclient_command_list;
1335 :
1336 15916 : while(*cmd_set) {
1337 15224 : add_command_set(*cmd_set);
1338 15224 : add_command_set(separator_command);
1339 15224 : cmd_set++;
1340 : }
1341 :
1342 : /* Do anything specified with -c */
1343 692 : if (cmdstr && cmdstr[0]) {
1344 : char *cmd;
1345 692 : char *p = cmdstr;
1346 :
1347 692 : result = 0;
1348 :
1349 1408 : while((cmd=next_command(&p)) != NULL) {
1350 716 : NTSTATUS cmd_result = process_cmd(creds,
1351 : cli,
1352 : binding,
1353 : cmd);
1354 716 : SAFE_FREE(cmd);
1355 716 : result = NT_STATUS_IS_ERR(cmd_result);
1356 : }
1357 :
1358 692 : goto done;
1359 : }
1360 :
1361 : /* Loop around accepting commands */
1362 :
1363 0 : while(1) {
1364 0 : char *line = NULL;
1365 :
1366 0 : line = smb_readline("rpcclient $> ", NULL, completion_fn);
1367 :
1368 0 : if (line == NULL) {
1369 0 : printf("\n");
1370 0 : break;
1371 : }
1372 :
1373 0 : if (line[0] != '\n')
1374 0 : process_cmd(creds,
1375 : cli,
1376 : binding,
1377 : line);
1378 0 : SAFE_FREE(line);
1379 : }
1380 :
1381 719 : done:
1382 719 : if (cli != NULL) {
1383 442 : cli_shutdown(cli);
1384 : }
1385 719 : netlogon_creds_cli_close_global_db();
1386 719 : TALLOC_FREE(rpcclient_msg_ctx);
1387 719 : TALLOC_FREE(frame);
1388 719 : return result;
1389 : }
|