lib: util: Add sys_valid_io_range()
[Samba.git] / source3 / rpcclient / rpcclient.c
blob9d4f16531c2574e5190d32fcb24e48bcce9475ad
1 /*
2 Unix SMB/CIFS implementation.
3 RPC pipe client
5 Copyright (C) Tim Potter 2000-2001
6 Copyright (C) Martin Pool 2003
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.
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.
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/>.
22 #include "includes.h"
23 #include "../libcli/auth/netlogon_creds_cli.h"
24 #include "popt_common_cmdline.h"
25 #include "rpcclient.h"
26 #include "../libcli/auth/libcli_auth.h"
27 #include "../librpc/gen_ndr/ndr_lsa_c.h"
28 #include "rpc_client/cli_lsarpc.h"
29 #include "../librpc/gen_ndr/ndr_netlogon.h"
30 #include "rpc_client/cli_netlogon.h"
31 #include "../libcli/smbreadline/smbreadline.h"
32 #include "../libcli/security/security.h"
33 #include "passdb.h"
34 #include "libsmb/libsmb.h"
35 #include "auth/gensec/gensec.h"
36 #include "../libcli/smb/smbXcli_base.h"
37 #include "messages.h"
38 #include "cmdline_contexts.h"
39 #include "../librpc/gen_ndr/ndr_samr.h"
41 enum pipe_auth_type_spnego {
42 PIPE_AUTH_TYPE_SPNEGO_NONE = 0,
43 PIPE_AUTH_TYPE_SPNEGO_NTLMSSP,
44 PIPE_AUTH_TYPE_SPNEGO_KRB5
47 static enum dcerpc_AuthType pipe_default_auth_type = DCERPC_AUTH_TYPE_NONE;
48 static enum pipe_auth_type_spnego pipe_default_auth_spnego_type = 0;
49 static enum dcerpc_AuthLevel pipe_default_auth_level = DCERPC_AUTH_LEVEL_NONE;
50 static unsigned int timeout = 0;
51 static enum dcerpc_transport_t default_transport = NCACN_NP;
53 struct messaging_context *rpcclient_msg_ctx;
54 struct netlogon_creds_cli_context *rpcclient_netlogon_creds;
55 static const char *rpcclient_netlogon_domain;
57 /* List to hold groups of commands.
59 * Commands are defined in a list of arrays: arrays are easy to
60 * statically declare, and lists are easier to dynamically extend.
63 static struct cmd_list {
64 struct cmd_list *prev, *next;
65 struct cmd_set *cmd_set;
66 } *cmd_list;
68 /****************************************************************************
69 handle completion of commands for readline
70 ****************************************************************************/
71 static char **completion_fn(const char *text, int start, int end)
73 #define MAX_COMPLETIONS 1000
74 char **matches;
75 size_t i, count=0;
76 struct cmd_list *commands = cmd_list;
78 #if 0 /* JERRY */
79 /* FIXME!!! -- what to do when completing argument? */
80 /* for words not at the start of the line fallback
81 to filename completion */
82 if (start)
83 return NULL;
84 #endif
86 /* make sure we have a list of valid commands */
87 if (!commands) {
88 return NULL;
91 matches = SMB_MALLOC_ARRAY(char *, MAX_COMPLETIONS);
92 if (!matches) {
93 return NULL;
96 matches[count++] = SMB_STRDUP(text);
97 if (!matches[0]) {
98 SAFE_FREE(matches);
99 return NULL;
102 while (commands && count < MAX_COMPLETIONS-1) {
103 if (!commands->cmd_set) {
104 break;
107 for (i=0; commands->cmd_set[i].name; i++) {
108 if ((strncmp(text, commands->cmd_set[i].name, strlen(text)) == 0) &&
109 (( commands->cmd_set[i].returntype == RPC_RTYPE_NTSTATUS &&
110 commands->cmd_set[i].ntfn ) ||
111 ( commands->cmd_set[i].returntype == RPC_RTYPE_WERROR &&
112 commands->cmd_set[i].wfn))) {
113 matches[count] = SMB_STRDUP(commands->cmd_set[i].name);
114 if (!matches[count]) {
115 for (i = 0; i < count; i++) {
116 SAFE_FREE(matches[count]);
118 SAFE_FREE(matches);
119 return NULL;
121 count++;
124 commands = commands->next;
127 if (count == 2) {
128 SAFE_FREE(matches[0]);
129 matches[0] = SMB_STRDUP(matches[1]);
131 matches[count] = NULL;
132 return matches;
135 static char *next_command (char **cmdstr)
137 char *command;
138 char *p;
140 if (!cmdstr || !(*cmdstr))
141 return NULL;
143 p = strchr_m(*cmdstr, ';');
144 if (p)
145 *p = '\0';
146 command = SMB_STRDUP(*cmdstr);
147 if (p)
148 *cmdstr = p + 1;
149 else
150 *cmdstr = NULL;
152 return command;
155 /* List the available commands on a given pipe */
157 static NTSTATUS cmd_listcommands(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
158 int argc, const char **argv)
160 struct cmd_list *tmp;
161 struct cmd_set *tmp_set;
162 int i;
164 /* Usage */
166 if (argc != 2) {
167 printf("Usage: %s <pipe>\n", argv[0]);
168 return NT_STATUS_OK;
171 /* Help on one command */
173 for (tmp = cmd_list; tmp; tmp = tmp->next)
175 tmp_set = tmp->cmd_set;
177 if (!strcasecmp_m(argv[1], tmp_set->name))
179 printf("Available commands on the %s pipe:\n\n", tmp_set->name);
181 i = 0;
182 tmp_set++;
183 while(tmp_set->name) {
184 printf("%30s", tmp_set->name);
185 tmp_set++;
186 i++;
187 if (i%3 == 0)
188 printf("\n");
191 /* drop out of the loop */
192 break;
195 printf("\n\n");
197 return NT_STATUS_OK;
200 /* Display help on commands */
202 static NTSTATUS cmd_help(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
203 int argc, const char **argv)
205 struct cmd_list *tmp;
206 struct cmd_set *tmp_set;
208 /* Usage */
210 if (argc > 2) {
211 printf("Usage: %s [command]\n", argv[0]);
212 return NT_STATUS_OK;
215 /* Help on one command */
217 if (argc == 2) {
218 for (tmp = cmd_list; tmp; tmp = tmp->next) {
220 tmp_set = tmp->cmd_set;
222 while(tmp_set->name) {
223 if (strequal(argv[1], tmp_set->name)) {
224 if (tmp_set->usage &&
225 tmp_set->usage[0])
226 printf("%s\n", tmp_set->usage);
227 else
228 printf("No help for %s\n", tmp_set->name);
230 return NT_STATUS_OK;
233 tmp_set++;
237 printf("No such command: %s\n", argv[1]);
238 return NT_STATUS_OK;
241 /* List all commands */
243 for (tmp = cmd_list; tmp; tmp = tmp->next) {
245 tmp_set = tmp->cmd_set;
247 while(tmp_set->name) {
249 printf("%15s\t\t%s\n", tmp_set->name,
250 tmp_set->description ? tmp_set->description:
251 "");
253 tmp_set++;
257 return NT_STATUS_OK;
260 /* Change the debug level */
262 static NTSTATUS cmd_debuglevel(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
263 int argc, const char **argv)
265 if (argc > 2) {
266 printf("Usage: %s [debuglevel]\n", argv[0]);
267 return NT_STATUS_OK;
270 if (argc == 2) {
271 lp_set_cmdline("log level", argv[1]);
274 printf("debuglevel is %d\n", DEBUGLEVEL);
276 return NT_STATUS_OK;
279 static NTSTATUS cmd_quit(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
280 int argc, const char **argv)
282 exit(0);
283 return NT_STATUS_OK; /* NOTREACHED */
286 static NTSTATUS cmd_set_ss_level(void)
288 struct cmd_list *tmp;
290 /* Close any existing connections not at this level. */
292 for (tmp = cmd_list; tmp; tmp = tmp->next) {
293 struct cmd_set *tmp_set;
295 for (tmp_set = tmp->cmd_set; tmp_set->name; tmp_set++) {
296 if (tmp_set->rpc_pipe == NULL) {
297 continue;
300 if ((tmp_set->rpc_pipe->auth->auth_type
301 != pipe_default_auth_type)
302 || (tmp_set->rpc_pipe->auth->auth_level
303 != pipe_default_auth_level)) {
304 TALLOC_FREE(tmp_set->rpc_pipe);
305 tmp_set->rpc_pipe = NULL;
309 return NT_STATUS_OK;
312 static NTSTATUS cmd_set_transport(void)
314 struct cmd_list *tmp;
316 /* Close any existing connections not at this level. */
318 for (tmp = cmd_list; tmp; tmp = tmp->next) {
319 struct cmd_set *tmp_set;
321 for (tmp_set = tmp->cmd_set; tmp_set->name; tmp_set++) {
322 if (tmp_set->rpc_pipe == NULL) {
323 continue;
326 if (tmp_set->rpc_pipe->transport->transport != default_transport) {
327 TALLOC_FREE(tmp_set->rpc_pipe);
328 tmp_set->rpc_pipe = NULL;
332 return NT_STATUS_OK;
335 static NTSTATUS cmd_sign(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
336 int argc, const char **argv)
338 const char *p = "[KRB5|KRB5_SPNEGO|NTLMSSP|NTLMSSP_SPNEGO|SCHANNEL]";
339 const char *type = "NTLMSSP";
341 pipe_default_auth_level = DCERPC_AUTH_LEVEL_INTEGRITY;
342 pipe_default_auth_type = DCERPC_AUTH_TYPE_NTLMSSP;
344 if (argc > 2) {
345 printf("Usage: %s %s\n", argv[0], p);
346 return NT_STATUS_OK;
349 if (argc == 2) {
350 type = argv[1];
351 if (strequal(type, "KRB5")) {
352 pipe_default_auth_type = DCERPC_AUTH_TYPE_KRB5;
353 } else if (strequal(type, "KRB5_SPNEGO")) {
354 pipe_default_auth_type = DCERPC_AUTH_TYPE_SPNEGO;
355 pipe_default_auth_spnego_type = PIPE_AUTH_TYPE_SPNEGO_KRB5;
356 } else if (strequal(type, "NTLMSSP")) {
357 pipe_default_auth_type = DCERPC_AUTH_TYPE_NTLMSSP;
358 } else if (strequal(type, "NTLMSSP_SPNEGO")) {
359 pipe_default_auth_type = DCERPC_AUTH_TYPE_SPNEGO;
360 pipe_default_auth_spnego_type = PIPE_AUTH_TYPE_SPNEGO_NTLMSSP;
361 } else if (strequal(type, "SCHANNEL")) {
362 pipe_default_auth_type = DCERPC_AUTH_TYPE_SCHANNEL;
363 } else {
364 printf("unknown type %s\n", type);
365 printf("Usage: %s %s\n", argv[0], p);
366 return NT_STATUS_INVALID_LEVEL;
370 d_printf("Setting %s - sign\n", type);
372 return cmd_set_ss_level();
375 static NTSTATUS cmd_seal(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
376 int argc, const char **argv)
378 const char *p = "[KRB5|KRB5_SPNEGO|NTLMSSP|NTLMSSP_SPNEGO|SCHANNEL]";
379 const char *type = "NTLMSSP";
381 pipe_default_auth_level = DCERPC_AUTH_LEVEL_PRIVACY;
382 pipe_default_auth_type = DCERPC_AUTH_TYPE_NTLMSSP;
384 if (argc > 2) {
385 printf("Usage: %s %s\n", argv[0], p);
386 return NT_STATUS_OK;
389 if (argc == 2) {
390 type = argv[1];
391 if (strequal(type, "KRB5")) {
392 pipe_default_auth_type = DCERPC_AUTH_TYPE_KRB5;
393 } else if (strequal(type, "KRB5_SPNEGO")) {
394 pipe_default_auth_type = DCERPC_AUTH_TYPE_SPNEGO;
395 pipe_default_auth_spnego_type = PIPE_AUTH_TYPE_SPNEGO_KRB5;
396 } else if (strequal(type, "NTLMSSP")) {
397 pipe_default_auth_type = DCERPC_AUTH_TYPE_NTLMSSP;
398 } else if (strequal(type, "NTLMSSP_SPNEGO")) {
399 pipe_default_auth_type = DCERPC_AUTH_TYPE_SPNEGO;
400 pipe_default_auth_spnego_type = PIPE_AUTH_TYPE_SPNEGO_NTLMSSP;
401 } else if (strequal(type, "SCHANNEL")) {
402 pipe_default_auth_type = DCERPC_AUTH_TYPE_SCHANNEL;
403 } else {
404 printf("unknown type %s\n", type);
405 printf("Usage: %s %s\n", argv[0], p);
406 return NT_STATUS_INVALID_LEVEL;
410 d_printf("Setting %s - sign and seal\n", type);
412 return cmd_set_ss_level();
415 static NTSTATUS cmd_packet(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
416 int argc, const char **argv)
418 const char *p = "[KRB5|KRB5_SPNEGO|NTLMSSP|NTLMSSP_SPNEGO|SCHANNEL]";
419 const char *type = "NTLMSSP";
421 pipe_default_auth_level = DCERPC_AUTH_LEVEL_PACKET;
422 pipe_default_auth_type = DCERPC_AUTH_TYPE_NTLMSSP;
424 if (argc > 2) {
425 printf("Usage: %s %s\n", argv[0], p);
426 return NT_STATUS_OK;
429 if (argc == 2) {
430 type = argv[1];
431 if (strequal(type, "KRB5")) {
432 pipe_default_auth_type = DCERPC_AUTH_TYPE_KRB5;
433 } else if (strequal(type, "KRB5_SPNEGO")) {
434 pipe_default_auth_type = DCERPC_AUTH_TYPE_SPNEGO;
435 pipe_default_auth_spnego_type = PIPE_AUTH_TYPE_SPNEGO_KRB5;
436 } else if (strequal(type, "NTLMSSP")) {
437 pipe_default_auth_type = DCERPC_AUTH_TYPE_NTLMSSP;
438 } else if (strequal(type, "NTLMSSP_SPNEGO")) {
439 pipe_default_auth_type = DCERPC_AUTH_TYPE_SPNEGO;
440 pipe_default_auth_spnego_type = PIPE_AUTH_TYPE_SPNEGO_NTLMSSP;
441 } else if (strequal(type, "SCHANNEL")) {
442 pipe_default_auth_type = DCERPC_AUTH_TYPE_SCHANNEL;
443 } else {
444 printf("unknown type %s\n", type);
445 printf("Usage: %s %s\n", argv[0], p);
446 return NT_STATUS_INVALID_LEVEL;
450 d_printf("Setting %s - packet\n", type);
452 return cmd_set_ss_level();
456 static NTSTATUS cmd_timeout(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
457 int argc, const char **argv)
459 if (argc > 2) {
460 printf("Usage: %s timeout\n", argv[0]);
461 return NT_STATUS_OK;
464 if (argc == 2) {
465 timeout = atoi(argv[1]);
468 printf("timeout is %d\n", timeout);
470 return NT_STATUS_OK;
474 static NTSTATUS cmd_none(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
475 int argc, const char **argv)
477 pipe_default_auth_level = DCERPC_AUTH_LEVEL_NONE;
478 pipe_default_auth_type = DCERPC_AUTH_TYPE_NONE;
479 pipe_default_auth_spnego_type = PIPE_AUTH_TYPE_SPNEGO_NONE;
481 return cmd_set_ss_level();
484 static NTSTATUS cmd_schannel(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
485 int argc, const char **argv)
487 d_printf("Setting schannel - sign and seal\n");
488 pipe_default_auth_level = DCERPC_AUTH_LEVEL_PRIVACY;
489 pipe_default_auth_type = DCERPC_AUTH_TYPE_SCHANNEL;
491 return cmd_set_ss_level();
494 static NTSTATUS cmd_schannel_sign(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
495 int argc, const char **argv)
497 d_printf("Setting schannel - sign only\n");
498 pipe_default_auth_level = DCERPC_AUTH_LEVEL_INTEGRITY;
499 pipe_default_auth_type = DCERPC_AUTH_TYPE_SCHANNEL;
501 return cmd_set_ss_level();
504 static NTSTATUS cmd_choose_transport(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
505 int argc, const char **argv)
507 NTSTATUS status;
509 if (argc != 2) {
510 printf("Usage: %s [NCACN_NP|NCACN_IP_TCP]\n", argv[0]);
511 return NT_STATUS_OK;
514 if (strequal(argv[1], "NCACN_NP")) {
515 default_transport = NCACN_NP;
516 } else if (strequal(argv[1], "NCACN_IP_TCP")) {
517 default_transport = NCACN_IP_TCP;
518 } else {
519 printf("transport type: %s unknown or not supported\n", argv[1]);
520 return NT_STATUS_NOT_SUPPORTED;
523 status = cmd_set_transport();
524 if (!NT_STATUS_IS_OK(status)) {
525 return status;
528 printf("default transport is now: %s\n", argv[1]);
530 return NT_STATUS_OK;
533 /* Built in rpcclient commands */
535 static struct cmd_set rpcclient_commands[] = {
538 .name = "GENERAL OPTIONS",
542 .name = "help",
543 .returntype = RPC_RTYPE_NTSTATUS,
544 .ntfn = cmd_help,
545 .wfn = NULL,
546 .table = NULL,
547 .rpc_pipe = NULL,
548 .description = "Get help on commands",
549 .usage = "[command]",
552 .name = "?",
553 .returntype = RPC_RTYPE_NTSTATUS,
554 .ntfn = cmd_help,
555 .wfn = NULL,
556 .table = NULL,
557 .rpc_pipe = NULL,
558 .description = "Get help on commands",
559 .usage = "[command]",
562 .name = "debuglevel",
563 .returntype = RPC_RTYPE_NTSTATUS,
564 .ntfn = cmd_debuglevel,
565 .wfn = NULL,
566 .table = NULL,
567 .rpc_pipe = NULL,
568 .description = "Set debug level",
569 .usage = "level",
572 .name = "debug",
573 .returntype = RPC_RTYPE_NTSTATUS,
574 .ntfn = cmd_debuglevel,
575 .wfn = NULL,
576 .table = NULL,
577 .rpc_pipe = NULL,
578 .description = "Set debug level",
579 .usage = "level",
582 .name = "list",
583 .returntype = RPC_RTYPE_NTSTATUS,
584 .ntfn = cmd_listcommands,
585 .wfn = NULL,
586 .table = NULL,
587 .rpc_pipe = NULL,
588 .description = "List available commands on <pipe>",
589 .usage = "pipe",
592 .name = "exit",
593 .returntype = RPC_RTYPE_NTSTATUS,
594 .ntfn = cmd_quit,
595 .wfn = NULL,
596 .table = NULL,
597 .rpc_pipe = NULL,
598 .description = "Exit program",
599 .usage = "",
602 .name = "quit",
603 .returntype = RPC_RTYPE_NTSTATUS,
604 .ntfn = cmd_quit,
605 .wfn = NULL,
606 .table = NULL,
607 .rpc_pipe = NULL,
608 .description = "Exit program",
609 .usage = "",
612 .name = "sign",
613 .returntype = RPC_RTYPE_NTSTATUS,
614 .ntfn = cmd_sign,
615 .wfn = NULL,
616 .table = NULL,
617 .rpc_pipe = NULL,
618 .description = "Force RPC pipe connections to be signed",
619 .usage = "",
622 .name = "seal",
623 .returntype = RPC_RTYPE_NTSTATUS,
624 .ntfn = cmd_seal,
625 .wfn = NULL,
626 .table = NULL,
627 .rpc_pipe = NULL,
628 .description = "Force RPC pipe connections to be sealed",
629 .usage = "",
632 .name = "packet",
633 .returntype = RPC_RTYPE_NTSTATUS,
634 .ntfn = cmd_packet,
635 .wfn = NULL,
636 .table = NULL,
637 .rpc_pipe = NULL,
638 .description = "Force RPC pipe connections with packet authentication level",
639 .usage = "",
642 .name = "schannel",
643 .returntype = RPC_RTYPE_NTSTATUS,
644 .ntfn = cmd_schannel,
645 .wfn = NULL,
646 .table = NULL,
647 .rpc_pipe = NULL,
648 .description = "Force RPC pipe connections to be sealed with 'schannel'. "
649 "Assumes valid machine account to this domain controller.",
650 .usage = "",
653 .name = "schannelsign",
654 .returntype = RPC_RTYPE_NTSTATUS,
655 .ntfn = cmd_schannel_sign,
656 .wfn = NULL,
657 .table = NULL,
658 .rpc_pipe = NULL,
659 .description = "Force RPC pipe connections to be signed (not sealed) with "
660 "'schannel'. Assumes valid machine account to this domain "
661 "controller.",
662 .usage = "",
665 .name = "timeout",
666 .returntype = RPC_RTYPE_NTSTATUS,
667 .ntfn = cmd_timeout,
668 .wfn = NULL,
669 .table = NULL,
670 .rpc_pipe = NULL,
671 .description = "Set timeout (in milliseconds) for RPC operations",
672 .usage = "",
675 .name = "transport",
676 .returntype = RPC_RTYPE_NTSTATUS,
677 .ntfn = cmd_choose_transport,
678 .wfn = NULL,
679 .table = NULL,
680 .rpc_pipe = NULL,
681 .description = "Choose ncacn transport for RPC operations",
682 .usage = "",
685 .name = "none",
686 .returntype = RPC_RTYPE_NTSTATUS,
687 .ntfn = cmd_none,
688 .wfn = NULL,
689 .table = NULL,
690 .rpc_pipe = NULL,
691 .description = "Force RPC pipe connections to have no special properties",
692 .usage = "",
695 { .name = NULL, },
698 static struct cmd_set separator_command[] = {
700 .name = "---------------",
701 .returntype = MAX_RPC_RETURN_TYPE,
702 .description = "----------------------"
704 { .name = NULL, },
708 /* Various pipe commands */
710 extern struct cmd_set lsarpc_commands[];
711 extern struct cmd_set samr_commands[];
712 extern struct cmd_set spoolss_commands[];
713 extern struct cmd_set iremotewinspool_commands[];
714 extern struct cmd_set netlogon_commands[];
715 extern struct cmd_set srvsvc_commands[];
716 extern struct cmd_set dfs_commands[];
717 extern struct cmd_set ds_commands[];
718 extern struct cmd_set echo_commands[];
719 extern struct cmd_set epmapper_commands[];
720 extern struct cmd_set shutdown_commands[];
721 extern struct cmd_set wkssvc_commands[];
722 extern struct cmd_set ntsvcs_commands[];
723 extern struct cmd_set drsuapi_commands[];
724 extern struct cmd_set eventlog_commands[];
725 extern struct cmd_set winreg_commands[];
726 extern struct cmd_set fss_commands[];
727 extern struct cmd_set witness_commands[];
728 extern struct cmd_set clusapi_commands[];
729 extern struct cmd_set spotlight_commands[];
731 static struct cmd_set *rpcclient_command_list[] = {
732 rpcclient_commands,
733 lsarpc_commands,
734 ds_commands,
735 samr_commands,
736 spoolss_commands,
737 iremotewinspool_commands,
738 netlogon_commands,
739 srvsvc_commands,
740 dfs_commands,
741 echo_commands,
742 epmapper_commands,
743 shutdown_commands,
744 wkssvc_commands,
745 ntsvcs_commands,
746 drsuapi_commands,
747 eventlog_commands,
748 winreg_commands,
749 fss_commands,
750 witness_commands,
751 clusapi_commands,
752 spotlight_commands,
753 NULL
756 static void add_command_set(struct cmd_set *cmd_set)
758 struct cmd_list *entry;
760 if (!(entry = SMB_MALLOC_P(struct cmd_list))) {
761 DEBUG(0, ("out of memory\n"));
762 return;
765 ZERO_STRUCTP(entry);
767 entry->cmd_set = cmd_set;
768 DLIST_ADD(cmd_list, entry);
773 * Call an rpcclient function, passing an argv array.
775 * @param cmd Command to run, as a single string.
777 static NTSTATUS do_cmd(struct cli_state *cli,
778 struct user_auth_info *auth_info,
779 struct cmd_set *cmd_entry,
780 struct dcerpc_binding *binding,
781 int argc, const char **argv)
783 NTSTATUS ntresult;
784 WERROR wresult;
786 TALLOC_CTX *mem_ctx;
788 /* Create mem_ctx */
790 if (!(mem_ctx = talloc_stackframe())) {
791 DEBUG(0, ("talloc_init() failed\n"));
792 return NT_STATUS_NO_MEMORY;
795 /* Open pipe */
797 if ((cmd_entry->table != NULL) && (cmd_entry->rpc_pipe == NULL)) {
798 enum credentials_use_kerberos use_kerberos = CRED_AUTO_USE_KERBEROS;
799 switch (pipe_default_auth_type) {
800 case DCERPC_AUTH_TYPE_NONE:
801 ntresult = cli_rpc_pipe_open_noauth_transport(
802 cli, default_transport,
803 cmd_entry->table,
804 &cmd_entry->rpc_pipe);
805 break;
806 case DCERPC_AUTH_TYPE_SPNEGO:
807 switch (pipe_default_auth_spnego_type) {
808 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
809 use_kerberos = CRED_DONT_USE_KERBEROS;
810 break;
811 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
812 use_kerberos = CRED_MUST_USE_KERBEROS;
813 break;
814 case PIPE_AUTH_TYPE_SPNEGO_NONE:
815 use_kerberos = CRED_AUTO_USE_KERBEROS;
816 break;
818 FALL_THROUGH;
819 case DCERPC_AUTH_TYPE_NTLMSSP:
820 case DCERPC_AUTH_TYPE_KRB5:
821 ntresult = cli_rpc_pipe_open_generic_auth(
822 cli, cmd_entry->table,
823 default_transport,
824 use_kerberos,
825 pipe_default_auth_type,
826 pipe_default_auth_level,
827 smbXcli_conn_remote_name(cli->conn),
828 get_cmdline_auth_info_domain(auth_info),
829 get_cmdline_auth_info_username(auth_info),
830 get_cmdline_auth_info_password(auth_info),
831 &cmd_entry->rpc_pipe);
832 break;
833 case DCERPC_AUTH_TYPE_SCHANNEL:
834 TALLOC_FREE(rpcclient_netlogon_creds);
835 ntresult = cli_rpc_pipe_open_schannel(
836 cli, rpcclient_msg_ctx,
837 cmd_entry->table,
838 default_transport,
839 rpcclient_netlogon_domain,
840 &cmd_entry->rpc_pipe,
841 rpcclient_msg_ctx,
842 &rpcclient_netlogon_creds);
843 break;
844 default:
845 DEBUG(0, ("Could not initialise %s. Invalid "
846 "auth type %u\n",
847 cmd_entry->table->name,
848 pipe_default_auth_type ));
849 talloc_free(mem_ctx);
850 return NT_STATUS_UNSUCCESSFUL;
852 if (!NT_STATUS_IS_OK(ntresult)) {
853 DEBUG(0, ("Could not initialise %s. Error was %s\n",
854 cmd_entry->table->name,
855 nt_errstr(ntresult) ));
856 talloc_free(mem_ctx);
857 return ntresult;
860 if (rpcclient_netlogon_creds == NULL && cmd_entry->use_netlogon_creds) {
861 const char *dc_name = cmd_entry->rpc_pipe->desthost;
862 const char *domain = rpcclient_netlogon_domain;
863 struct cli_credentials *creds = NULL;
865 ntresult = pdb_get_trust_credentials(domain, NULL,
866 mem_ctx, &creds);
867 if (!NT_STATUS_IS_OK(ntresult)) {
868 DEBUG(0, ("Failed to fetch trust credentials for "
869 "%s to connect to %s: %s\n",
870 domain, cmd_entry->table->name,
871 nt_errstr(ntresult)));
872 TALLOC_FREE(cmd_entry->rpc_pipe);
873 talloc_free(mem_ctx);
874 return ntresult;
877 ntresult = rpccli_create_netlogon_creds_ctx(creds,
878 dc_name,
879 rpcclient_msg_ctx,
880 rpcclient_msg_ctx,
881 &rpcclient_netlogon_creds);
882 if (!NT_STATUS_IS_OK(ntresult)) {
883 DEBUG(0, ("Could not initialise credentials for %s.\n",
884 cmd_entry->table->name));
885 TALLOC_FREE(cmd_entry->rpc_pipe);
886 TALLOC_FREE(mem_ctx);
887 return ntresult;
890 ntresult = rpccli_setup_netlogon_creds(
891 cli,
892 NCACN_NP,
893 rpcclient_netlogon_creds,
894 false, /* force_reauth */
895 creds);
896 TALLOC_FREE(creds);
897 if (!NT_STATUS_IS_OK(ntresult)) {
898 DEBUG(0, ("Could not initialise credentials for %s.\n",
899 cmd_entry->table->name));
900 TALLOC_FREE(cmd_entry->rpc_pipe);
901 TALLOC_FREE(rpcclient_netlogon_creds);
902 TALLOC_FREE(mem_ctx);
903 return ntresult;
908 /* Set timeout for new connections */
909 if (cmd_entry->rpc_pipe) {
910 rpccli_set_timeout(cmd_entry->rpc_pipe, timeout);
913 /* Run command */
915 if ( cmd_entry->returntype == RPC_RTYPE_NTSTATUS ) {
916 ntresult = cmd_entry->ntfn(cmd_entry->rpc_pipe, mem_ctx, argc, argv);
917 if (!NT_STATUS_IS_OK(ntresult)) {
918 printf("result was %s\n", nt_errstr(ntresult));
920 } else {
921 wresult = cmd_entry->wfn(cmd_entry->rpc_pipe, mem_ctx, argc, argv);
922 /* print out the DOS error */
923 if (!W_ERROR_IS_OK(wresult)) {
924 printf( "result was %s\n", win_errstr(wresult));
926 ntresult = W_ERROR_IS_OK(wresult)?NT_STATUS_OK:NT_STATUS_UNSUCCESSFUL;
929 /* Cleanup */
931 talloc_free(mem_ctx);
933 return ntresult;
938 * Process a command entered at the prompt or as part of -c
940 * @returns The NTSTATUS from running the command.
942 static NTSTATUS process_cmd(struct user_auth_info *auth_info,
943 struct cli_state *cli,
944 struct dcerpc_binding *binding,
945 char *cmd)
947 struct cmd_list *temp_list;
948 NTSTATUS result = NT_STATUS_OK;
949 int ret;
950 int argc;
951 const char **argv = NULL;
953 if ((ret = poptParseArgvString(cmd, &argc, &argv)) != 0) {
954 fprintf(stderr, "rpcclient: %s\n", poptStrerror(ret));
955 return NT_STATUS_UNSUCCESSFUL;
959 /* Walk through a dlist of arrays of commands. */
960 for (temp_list = cmd_list; temp_list; temp_list = temp_list->next) {
961 struct cmd_set *temp_set = temp_list->cmd_set;
963 while (temp_set->name) {
964 if (strequal(argv[0], temp_set->name)) {
965 if (!(temp_set->returntype == RPC_RTYPE_NTSTATUS && temp_set->ntfn ) &&
966 !(temp_set->returntype == RPC_RTYPE_WERROR && temp_set->wfn )) {
967 fprintf (stderr, "Invalid command\n");
968 goto out_free;
971 result = do_cmd(cli, auth_info, temp_set,
972 binding, argc, argv);
974 goto out_free;
976 temp_set++;
980 if (argv[0]) {
981 printf("command not found: %s\n", argv[0]);
984 out_free:
985 /* moved to do_cmd()
986 if (!NT_STATUS_IS_OK(result)) {
987 printf("result was %s\n", nt_errstr(result));
991 /* NOTE: popt allocates the whole argv, including the
992 * strings, as a single block. So a single free is
993 * enough to release it -- we don't free the
994 * individual strings. rtfm. */
995 free(argv);
997 return result;
1001 /* Main function */
1003 int main(int argc, char *argv[])
1005 const char **const_argv = discard_const_p(const char *, argv);
1006 int opt;
1007 static char *cmdstr = NULL;
1008 const char *server;
1009 struct cli_state *cli = NULL;
1010 static char *opt_ipaddr=NULL;
1011 struct cmd_set **cmd_set;
1012 struct sockaddr_storage server_ss;
1013 NTSTATUS nt_status;
1014 static int opt_port = 0;
1015 int result = 0;
1016 TALLOC_CTX *frame = talloc_stackframe();
1017 uint32_t flags = 0;
1018 struct dcerpc_binding *binding = NULL;
1019 enum dcerpc_transport_t transport;
1020 uint32_t bflags = 0;
1021 const char *binding_string = NULL;
1022 const char *host;
1023 int signing_state = SMB_SIGNING_IPC_DEFAULT;
1025 /* make sure the vars that get altered (4th field) are in
1026 a fixed location or certain compilers complain */
1027 poptContext pc;
1028 struct poptOption long_options[] = {
1029 POPT_AUTOHELP
1030 {"command", 'c', POPT_ARG_STRING, &cmdstr, 'c', "Execute semicolon separated cmds", "COMMANDS"},
1031 {"dest-ip", 'I', POPT_ARG_STRING, &opt_ipaddr, 'I', "Specify destination IP address", "IP"},
1032 {"port", 'p', POPT_ARG_INT, &opt_port, 'p', "Specify port number", "PORT"},
1033 POPT_COMMON_SAMBA
1034 POPT_COMMON_CONNECTION
1035 POPT_COMMON_CREDENTIALS
1036 POPT_TABLEEND
1039 smb_init_locale();
1041 zero_sockaddr(&server_ss);
1043 setlinebuf(stdout);
1045 /* the following functions are part of the Samba debugging
1046 facilities. See lib/debug.c */
1047 setup_logging("rpcclient", DEBUG_STDOUT);
1048 lp_set_cmdline("log level", "0");
1050 /* Parse options */
1052 pc = poptGetContext("rpcclient", argc, const_argv,
1053 long_options, 0);
1055 poptSetOtherOptionHelp(pc, "[OPTION...] <server>\nOptions:");
1057 if (argc == 1) {
1058 poptPrintHelp(pc, stderr, 0);
1059 goto done;
1062 while((opt = poptGetNextOpt(pc)) != -1) {
1063 switch (opt) {
1065 case 'I':
1066 if (!interpret_string_addr(&server_ss,
1067 opt_ipaddr,
1068 AI_NUMERICHOST)) {
1069 fprintf(stderr, "%s not a valid IP address\n",
1070 opt_ipaddr);
1071 result = 1;
1072 goto done;
1077 /* Get server as remaining unparsed argument. Print usage if more
1078 than one unparsed argument is present. */
1080 server = poptGetArg(pc);
1082 if (!server || poptGetArg(pc)) {
1083 poptPrintHelp(pc, stderr, 0);
1084 result = 1;
1085 goto done;
1088 poptFreeContext(pc);
1089 popt_burn_cmdline_password(argc, argv);
1091 rpcclient_msg_ctx = cmdline_messaging_context(get_dyn_CONFIGFILE());
1093 if (!init_names()) {
1094 result = 1;
1095 goto done;
1099 * Get password
1100 * from stdin if necessary
1103 if ((server[0] == '/' && server[1] == '/') ||
1104 (server[0] == '\\' && server[1] == '\\')) {
1105 server += 2;
1108 nt_status = dcerpc_parse_binding(frame, server, &binding);
1110 if (!NT_STATUS_IS_OK(nt_status)) {
1112 binding_string = talloc_asprintf(frame, "ncacn_np:%s",
1113 strip_hostname(server));
1114 if (!binding_string) {
1115 result = 1;
1116 goto done;
1119 nt_status = dcerpc_parse_binding(frame, binding_string, &binding);
1120 if (!NT_STATUS_IS_OK(nt_status)) {
1121 result = -1;
1122 goto done;
1126 transport = dcerpc_binding_get_transport(binding);
1128 if (transport == NCA_UNKNOWN) {
1129 nt_status = dcerpc_binding_set_transport(binding, NCACN_NP);
1130 if (!NT_STATUS_IS_OK(nt_status)) {
1131 result = -1;
1132 goto done;
1136 host = dcerpc_binding_get_string_option(binding, "host");
1138 bflags = dcerpc_binding_get_flags(binding);
1139 if (bflags & DCERPC_CONNECT) {
1140 pipe_default_auth_level = DCERPC_AUTH_LEVEL_CONNECT;
1141 pipe_default_auth_type = DCERPC_AUTH_TYPE_NTLMSSP;
1143 if (bflags & DCERPC_PACKET) {
1144 pipe_default_auth_level = DCERPC_AUTH_LEVEL_PACKET;
1145 pipe_default_auth_type = DCERPC_AUTH_TYPE_NTLMSSP;
1147 if (bflags & DCERPC_SIGN) {
1148 pipe_default_auth_level = DCERPC_AUTH_LEVEL_INTEGRITY;
1149 pipe_default_auth_type = DCERPC_AUTH_TYPE_NTLMSSP;
1151 if (bflags & DCERPC_SEAL) {
1152 pipe_default_auth_level = DCERPC_AUTH_LEVEL_PRIVACY;
1153 pipe_default_auth_type = DCERPC_AUTH_TYPE_NTLMSSP;
1155 if (bflags & DCERPC_AUTH_SPNEGO) {
1156 pipe_default_auth_type = DCERPC_AUTH_TYPE_SPNEGO;
1157 pipe_default_auth_spnego_type = PIPE_AUTH_TYPE_SPNEGO_NTLMSSP;
1159 if (bflags & DCERPC_AUTH_NTLM) {
1160 if (pipe_default_auth_type == DCERPC_AUTH_TYPE_SPNEGO) {
1161 pipe_default_auth_spnego_type = PIPE_AUTH_TYPE_SPNEGO_NTLMSSP;
1162 } else {
1163 pipe_default_auth_type = DCERPC_AUTH_TYPE_NTLMSSP;
1166 if (bflags & DCERPC_AUTH_KRB5) {
1167 if (pipe_default_auth_type == DCERPC_AUTH_TYPE_SPNEGO) {
1168 pipe_default_auth_spnego_type = PIPE_AUTH_TYPE_SPNEGO_KRB5;
1169 } else {
1170 pipe_default_auth_type = DCERPC_AUTH_TYPE_KRB5;
1173 if (pipe_default_auth_type != DCERPC_AUTH_TYPE_NONE) {
1174 /* If nothing is requested then default to integrity */
1175 if (pipe_default_auth_level == DCERPC_AUTH_LEVEL_NONE) {
1176 pipe_default_auth_level = DCERPC_AUTH_LEVEL_INTEGRITY;
1180 signing_state = get_cmdline_auth_info_signing_state(
1181 popt_get_cmdline_auth_info());
1182 switch (signing_state) {
1183 case SMB_SIGNING_OFF:
1184 lp_set_cmdline("client ipc signing", "no");
1185 break;
1186 case SMB_SIGNING_REQUIRED:
1187 lp_set_cmdline("client ipc signing", "required");
1188 break;
1191 if (get_cmdline_auth_info_use_kerberos(popt_get_cmdline_auth_info())) {
1192 flags |= CLI_FULL_CONNECTION_USE_KERBEROS |
1193 CLI_FULL_CONNECTION_FALLBACK_AFTER_KERBEROS;
1195 if (get_cmdline_auth_info_use_ccache(popt_get_cmdline_auth_info())) {
1196 flags |= CLI_FULL_CONNECTION_USE_CCACHE;
1198 if (get_cmdline_auth_info_use_pw_nt_hash(
1199 popt_get_cmdline_auth_info())) {
1200 flags |= CLI_FULL_CONNECTION_USE_NT_HASH;
1203 rpcclient_netlogon_domain = get_cmdline_auth_info_domain(
1204 popt_get_cmdline_auth_info());
1205 if (rpcclient_netlogon_domain == NULL ||
1206 rpcclient_netlogon_domain[0] == '\0')
1208 rpcclient_netlogon_domain = lp_workgroup();
1211 nt_status = cli_full_connection(&cli, lp_netbios_name(), host,
1212 opt_ipaddr ? &server_ss : NULL, opt_port,
1213 "IPC$", "IPC",
1214 get_cmdline_auth_info_username(
1215 popt_get_cmdline_auth_info()),
1216 get_cmdline_auth_info_domain(
1217 popt_get_cmdline_auth_info()),
1218 get_cmdline_auth_info_password(
1219 popt_get_cmdline_auth_info()),
1220 flags,
1221 SMB_SIGNING_IPC_DEFAULT);
1223 if (!NT_STATUS_IS_OK(nt_status)) {
1224 DEBUG(0,("Cannot connect to server. Error was %s\n", nt_errstr(nt_status)));
1225 result = 1;
1226 goto done;
1229 if (get_cmdline_auth_info_smb_encrypt(popt_get_cmdline_auth_info())) {
1230 nt_status = cli_cm_force_encryption(cli,
1231 get_cmdline_auth_info_username(
1232 popt_get_cmdline_auth_info()),
1233 get_cmdline_auth_info_password(
1234 popt_get_cmdline_auth_info()),
1235 get_cmdline_auth_info_domain(
1236 popt_get_cmdline_auth_info()),
1237 "IPC$");
1238 if (!NT_STATUS_IS_OK(nt_status)) {
1239 result = 1;
1240 goto done;
1244 #if 0 /* COMMENT OUT FOR TESTING */
1245 memset(cmdline_auth_info.password,'X',sizeof(cmdline_auth_info.password));
1246 #endif
1248 /* Load command lists */
1250 timeout = 10000;
1251 cli_set_timeout(cli, timeout);
1253 cmd_set = rpcclient_command_list;
1255 while(*cmd_set) {
1256 add_command_set(*cmd_set);
1257 add_command_set(separator_command);
1258 cmd_set++;
1261 default_transport = dcerpc_binding_get_transport(binding);
1263 /* Do anything specified with -c */
1264 if (cmdstr && cmdstr[0]) {
1265 char *cmd;
1266 char *p = cmdstr;
1268 result = 0;
1270 while((cmd=next_command(&p)) != NULL) {
1271 NTSTATUS cmd_result = process_cmd(
1272 popt_get_cmdline_auth_info(),
1273 cli, binding, cmd);
1274 SAFE_FREE(cmd);
1275 result = NT_STATUS_IS_ERR(cmd_result);
1278 goto done;
1281 /* Loop around accepting commands */
1283 while(1) {
1284 char *line = NULL;
1286 line = smb_readline("rpcclient $> ", NULL, completion_fn);
1288 if (line == NULL) {
1289 printf("\n");
1290 break;
1293 if (line[0] != '\n')
1294 process_cmd(popt_get_cmdline_auth_info(), cli,
1295 binding, line);
1296 SAFE_FREE(line);
1299 done:
1300 if (cli != NULL) {
1301 cli_shutdown(cli);
1303 popt_free_cmdline_auth_info();
1304 netlogon_creds_cli_close_global_db();
1305 TALLOC_FREE(rpcclient_msg_ctx);
1306 TALLOC_FREE(frame);
1307 return result;