2 Unix SMB/CIFS implementation.
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/>.
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"
34 #include "libsmb/libsmb.h"
35 #include "auth/gensec/gensec.h"
36 #include "../libcli/smb/smbXcli_base.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;
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
76 struct cmd_list *commands = cmd_list;
79 /* FIXME!!! -- what to do when completing argument? */
80 /* for words not at the start of the line fallback
81 to filename completion */
86 /* make sure we have a list of valid commands */
91 matches = SMB_MALLOC_ARRAY(char *, MAX_COMPLETIONS);
96 matches[count++] = SMB_STRDUP(text);
102 while (commands && count < MAX_COMPLETIONS-1) {
103 if (!commands->cmd_set) {
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]);
124 commands = commands->next;
128 SAFE_FREE(matches[0]);
129 matches[0] = SMB_STRDUP(matches[1]);
131 matches[count] = NULL;
135 static char *next_command (char **cmdstr)
140 if (!cmdstr || !(*cmdstr))
143 p = strchr_m(*cmdstr, ';');
146 command = SMB_STRDUP(*cmdstr);
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;
167 printf("Usage: %s <pipe>\n", argv[0]);
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);
183 while(tmp_set->name) {
184 printf("%30s", tmp_set->name);
191 /* drop out of the loop */
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;
211 printf("Usage: %s [command]\n", argv[0]);
215 /* Help on one command */
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 &&
226 printf("%s\n", tmp_set->usage);
228 printf("No help for %s\n", tmp_set->name);
237 printf("No such command: %s\n", argv[1]);
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:
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)
266 printf("Usage: %s [debuglevel]\n", argv[0]);
271 lp_set_cmdline("log level", argv[1]);
274 printf("debuglevel is %d\n", DEBUGLEVEL);
279 static NTSTATUS cmd_quit(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
280 int argc, const char **argv)
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) {
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;
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) {
326 if (tmp_set->rpc_pipe->transport->transport != default_transport) {
327 TALLOC_FREE(tmp_set->rpc_pipe);
328 tmp_set->rpc_pipe = NULL;
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;
345 printf("Usage: %s %s\n", argv[0], p);
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;
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;
385 printf("Usage: %s %s\n", argv[0], p);
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;
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;
425 printf("Usage: %s %s\n", argv[0], p);
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;
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)
460 printf("Usage: %s timeout\n", argv[0]);
465 timeout = atoi(argv[1]);
468 printf("timeout is %d\n", timeout);
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)
510 printf("Usage: %s [NCACN_NP|NCACN_IP_TCP]\n", argv[0]);
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;
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)) {
528 printf("default transport is now: %s\n", argv[1]);
533 /* Built in rpcclient commands */
535 static struct cmd_set rpcclient_commands[] = {
538 .name = "GENERAL OPTIONS",
543 .returntype = RPC_RTYPE_NTSTATUS,
548 .description = "Get help on commands",
549 .usage = "[command]",
553 .returntype = RPC_RTYPE_NTSTATUS,
558 .description = "Get help on commands",
559 .usage = "[command]",
562 .name = "debuglevel",
563 .returntype = RPC_RTYPE_NTSTATUS,
564 .ntfn = cmd_debuglevel,
568 .description = "Set debug level",
573 .returntype = RPC_RTYPE_NTSTATUS,
574 .ntfn = cmd_debuglevel,
578 .description = "Set debug level",
583 .returntype = RPC_RTYPE_NTSTATUS,
584 .ntfn = cmd_listcommands,
588 .description = "List available commands on <pipe>",
593 .returntype = RPC_RTYPE_NTSTATUS,
598 .description = "Exit program",
603 .returntype = RPC_RTYPE_NTSTATUS,
608 .description = "Exit program",
613 .returntype = RPC_RTYPE_NTSTATUS,
618 .description = "Force RPC pipe connections to be signed",
623 .returntype = RPC_RTYPE_NTSTATUS,
628 .description = "Force RPC pipe connections to be sealed",
633 .returntype = RPC_RTYPE_NTSTATUS,
638 .description = "Force RPC pipe connections with packet authentication level",
643 .returntype = RPC_RTYPE_NTSTATUS,
644 .ntfn = cmd_schannel,
648 .description = "Force RPC pipe connections to be sealed with 'schannel'. "
649 "Assumes valid machine account to this domain controller.",
653 .name = "schannelsign",
654 .returntype = RPC_RTYPE_NTSTATUS,
655 .ntfn = cmd_schannel_sign,
659 .description = "Force RPC pipe connections to be signed (not sealed) with "
660 "'schannel'. Assumes valid machine account to this domain "
666 .returntype = RPC_RTYPE_NTSTATUS,
671 .description = "Set timeout (in milliseconds) for RPC operations",
676 .returntype = RPC_RTYPE_NTSTATUS,
677 .ntfn = cmd_choose_transport,
681 .description = "Choose ncacn transport for RPC operations",
686 .returntype = RPC_RTYPE_NTSTATUS,
691 .description = "Force RPC pipe connections to have no special properties",
698 static struct cmd_set separator_command[] = {
700 .name = "---------------",
701 .returntype = MAX_RPC_RETURN_TYPE,
702 .description = "----------------------"
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[] = {
737 iremotewinspool_commands,
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"));
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)
790 if (!(mem_ctx = talloc_stackframe())) {
791 DEBUG(0, ("talloc_init() failed\n"));
792 return NT_STATUS_NO_MEMORY;
797 if ((cmd_entry->table != NULL) && (cmd_entry->rpc_pipe == NULL)) {
798 struct cli_credentials *creds =
799 get_cmdline_auth_info_creds(auth_info);
800 enum credentials_use_kerberos krb5_state =
801 cli_credentials_get_kerberos_state(creds);
803 switch (pipe_default_auth_type) {
804 case DCERPC_AUTH_TYPE_NONE:
805 ntresult = cli_rpc_pipe_open_noauth_transport(
806 cli, default_transport,
808 &cmd_entry->rpc_pipe);
810 case DCERPC_AUTH_TYPE_SPNEGO:
811 switch (pipe_default_auth_spnego_type) {
812 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
813 krb5_state = CRED_USE_KERBEROS_DISABLED;
815 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
816 krb5_state = CRED_USE_KERBEROS_REQUIRED;
818 case PIPE_AUTH_TYPE_SPNEGO_NONE:
819 krb5_state = CRED_USE_KERBEROS_DESIRED;
823 case DCERPC_AUTH_TYPE_NTLMSSP:
824 case DCERPC_AUTH_TYPE_KRB5:
825 if (krb5_state != CRED_USE_KERBEROS_DESIRED) {
826 cli_credentials_set_kerberos_state(creds,
829 ntresult = cli_rpc_pipe_open_with_creds(
830 cli, cmd_entry->table,
832 pipe_default_auth_type,
833 pipe_default_auth_level,
834 smbXcli_conn_remote_name(cli->conn),
836 &cmd_entry->rpc_pipe);
838 case DCERPC_AUTH_TYPE_SCHANNEL:
839 TALLOC_FREE(rpcclient_netlogon_creds);
840 ntresult = cli_rpc_pipe_open_schannel(
841 cli, rpcclient_msg_ctx,
844 rpcclient_netlogon_domain,
845 &cmd_entry->rpc_pipe,
847 &rpcclient_netlogon_creds);
850 DEBUG(0, ("Could not initialise %s. Invalid "
852 cmd_entry->table->name,
853 pipe_default_auth_type ));
854 talloc_free(mem_ctx);
855 return NT_STATUS_UNSUCCESSFUL;
857 if (!NT_STATUS_IS_OK(ntresult)) {
858 DEBUG(0, ("Could not initialise %s. Error was %s\n",
859 cmd_entry->table->name,
860 nt_errstr(ntresult) ));
861 talloc_free(mem_ctx);
865 if (rpcclient_netlogon_creds == NULL && cmd_entry->use_netlogon_creds) {
866 const char *dc_name = cmd_entry->rpc_pipe->desthost;
867 const char *domain = rpcclient_netlogon_domain;
868 struct cli_credentials *trust_creds = NULL;
870 ntresult = pdb_get_trust_credentials(domain, NULL,
871 mem_ctx, &trust_creds);
872 if (!NT_STATUS_IS_OK(ntresult)) {
873 DEBUG(0, ("Failed to fetch trust credentials for "
874 "%s to connect to %s: %s\n",
875 domain, cmd_entry->table->name,
876 nt_errstr(ntresult)));
877 TALLOC_FREE(cmd_entry->rpc_pipe);
878 talloc_free(mem_ctx);
882 ntresult = rpccli_create_netlogon_creds_ctx(trust_creds,
886 &rpcclient_netlogon_creds);
887 if (!NT_STATUS_IS_OK(ntresult)) {
888 DEBUG(0, ("Could not initialise credentials for %s.\n",
889 cmd_entry->table->name));
890 TALLOC_FREE(cmd_entry->rpc_pipe);
891 TALLOC_FREE(mem_ctx);
895 ntresult = rpccli_setup_netlogon_creds(
898 rpcclient_netlogon_creds,
899 false, /* force_reauth */
901 TALLOC_FREE(trust_creds);
902 if (!NT_STATUS_IS_OK(ntresult)) {
903 DEBUG(0, ("Could not initialise credentials for %s.\n",
904 cmd_entry->table->name));
905 TALLOC_FREE(cmd_entry->rpc_pipe);
906 TALLOC_FREE(rpcclient_netlogon_creds);
907 TALLOC_FREE(mem_ctx);
913 /* Set timeout for new connections */
914 if (cmd_entry->rpc_pipe) {
915 rpccli_set_timeout(cmd_entry->rpc_pipe, timeout);
920 if ( cmd_entry->returntype == RPC_RTYPE_NTSTATUS ) {
921 ntresult = cmd_entry->ntfn(cmd_entry->rpc_pipe, mem_ctx, argc, argv);
922 if (!NT_STATUS_IS_OK(ntresult)) {
923 printf("result was %s\n", nt_errstr(ntresult));
926 wresult = cmd_entry->wfn(cmd_entry->rpc_pipe, mem_ctx, argc, argv);
927 /* print out the DOS error */
928 if (!W_ERROR_IS_OK(wresult)) {
929 printf( "result was %s\n", win_errstr(wresult));
931 ntresult = W_ERROR_IS_OK(wresult)?NT_STATUS_OK:NT_STATUS_UNSUCCESSFUL;
936 talloc_free(mem_ctx);
943 * Process a command entered at the prompt or as part of -c
945 * @returns The NTSTATUS from running the command.
947 static NTSTATUS process_cmd(struct user_auth_info *auth_info,
948 struct cli_state *cli,
949 struct dcerpc_binding *binding,
952 struct cmd_list *temp_list;
953 NTSTATUS result = NT_STATUS_OK;
956 const char **argv = NULL;
958 if ((ret = poptParseArgvString(cmd, &argc, &argv)) != 0) {
959 fprintf(stderr, "rpcclient: %s\n", poptStrerror(ret));
960 return NT_STATUS_UNSUCCESSFUL;
964 /* Walk through a dlist of arrays of commands. */
965 for (temp_list = cmd_list; temp_list; temp_list = temp_list->next) {
966 struct cmd_set *temp_set = temp_list->cmd_set;
968 while (temp_set->name) {
969 if (strequal(argv[0], temp_set->name)) {
970 if (!(temp_set->returntype == RPC_RTYPE_NTSTATUS && temp_set->ntfn ) &&
971 !(temp_set->returntype == RPC_RTYPE_WERROR && temp_set->wfn )) {
972 fprintf (stderr, "Invalid command\n");
976 result = do_cmd(cli, auth_info, temp_set,
977 binding, argc, argv);
986 printf("command not found: %s\n", argv[0]);
991 if (!NT_STATUS_IS_OK(result)) {
992 printf("result was %s\n", nt_errstr(result));
996 /* NOTE: popt allocates the whole argv, including the
997 * strings, as a single block. So a single free is
998 * enough to release it -- we don't free the
999 * individual strings. rtfm. */
1008 int main(int argc, char *argv[])
1010 const char **const_argv = discard_const_p(const char *, argv);
1012 static char *cmdstr = NULL;
1014 struct cli_state *cli = NULL;
1015 static char *opt_ipaddr=NULL;
1016 struct cmd_set **cmd_set;
1017 struct sockaddr_storage server_ss;
1019 static int opt_port = 0;
1021 TALLOC_CTX *frame = talloc_stackframe();
1022 uint32_t flags = CLI_FULL_CONNECTION_IPC;
1023 struct dcerpc_binding *binding = NULL;
1024 enum dcerpc_transport_t transport;
1025 uint32_t bflags = 0;
1026 const char *binding_string = NULL;
1028 int signing_state = SMB_SIGNING_IPC_DEFAULT;
1030 /* make sure the vars that get altered (4th field) are in
1031 a fixed location or certain compilers complain */
1033 struct poptOption long_options[] = {
1035 {"command", 'c', POPT_ARG_STRING, &cmdstr, 'c', "Execute semicolon separated cmds", "COMMANDS"},
1036 {"dest-ip", 'I', POPT_ARG_STRING, &opt_ipaddr, 'I', "Specify destination IP address", "IP"},
1037 {"port", 'p', POPT_ARG_INT, &opt_port, 'p', "Specify port number", "PORT"},
1039 POPT_COMMON_CONNECTION
1040 POPT_COMMON_CREDENTIALS
1046 zero_sockaddr(&server_ss);
1050 /* the following functions are part of the Samba debugging
1051 facilities. See lib/debug.c */
1052 setup_logging("rpcclient", DEBUG_STDOUT);
1053 lp_set_cmdline("log level", "0");
1057 pc = poptGetContext("rpcclient", argc, const_argv,
1060 poptSetOtherOptionHelp(pc, "[OPTION...] <server>\nOptions:");
1063 poptPrintHelp(pc, stderr, 0);
1067 while((opt = poptGetNextOpt(pc)) != -1) {
1071 if (!interpret_string_addr(&server_ss,
1074 fprintf(stderr, "%s not a valid IP address\n",
1082 /* Get server as remaining unparsed argument. Print usage if more
1083 than one unparsed argument is present. */
1085 server = poptGetArg(pc);
1087 if (!server || poptGetArg(pc)) {
1088 poptPrintHelp(pc, stderr, 0);
1093 poptFreeContext(pc);
1094 popt_burn_cmdline_password(argc, argv);
1096 rpcclient_msg_ctx = cmdline_messaging_context(get_dyn_CONFIGFILE());
1098 if (!init_names()) {
1105 * from stdin if necessary
1108 if ((server[0] == '/' && server[1] == '/') ||
1109 (server[0] == '\\' && server[1] == '\\')) {
1113 nt_status = dcerpc_parse_binding(frame, server, &binding);
1115 if (!NT_STATUS_IS_OK(nt_status)) {
1117 binding_string = talloc_asprintf(frame, "ncacn_np:%s",
1118 strip_hostname(server));
1119 if (!binding_string) {
1124 nt_status = dcerpc_parse_binding(frame, binding_string, &binding);
1125 if (!NT_STATUS_IS_OK(nt_status)) {
1131 transport = dcerpc_binding_get_transport(binding);
1133 if (transport == NCA_UNKNOWN) {
1134 nt_status = dcerpc_binding_set_transport(binding, NCACN_NP);
1135 if (!NT_STATUS_IS_OK(nt_status)) {
1141 host = dcerpc_binding_get_string_option(binding, "host");
1143 bflags = dcerpc_binding_get_flags(binding);
1144 if (bflags & DCERPC_CONNECT) {
1145 pipe_default_auth_level = DCERPC_AUTH_LEVEL_CONNECT;
1146 pipe_default_auth_type = DCERPC_AUTH_TYPE_NTLMSSP;
1148 if (bflags & DCERPC_PACKET) {
1149 pipe_default_auth_level = DCERPC_AUTH_LEVEL_PACKET;
1150 pipe_default_auth_type = DCERPC_AUTH_TYPE_NTLMSSP;
1152 if (bflags & DCERPC_SIGN) {
1153 pipe_default_auth_level = DCERPC_AUTH_LEVEL_INTEGRITY;
1154 pipe_default_auth_type = DCERPC_AUTH_TYPE_NTLMSSP;
1156 if (bflags & DCERPC_SEAL) {
1157 pipe_default_auth_level = DCERPC_AUTH_LEVEL_PRIVACY;
1158 pipe_default_auth_type = DCERPC_AUTH_TYPE_NTLMSSP;
1160 if (bflags & DCERPC_AUTH_SPNEGO) {
1161 pipe_default_auth_type = DCERPC_AUTH_TYPE_SPNEGO;
1162 pipe_default_auth_spnego_type = PIPE_AUTH_TYPE_SPNEGO_NTLMSSP;
1164 if (bflags & DCERPC_AUTH_NTLM) {
1165 if (pipe_default_auth_type == DCERPC_AUTH_TYPE_SPNEGO) {
1166 pipe_default_auth_spnego_type = PIPE_AUTH_TYPE_SPNEGO_NTLMSSP;
1168 pipe_default_auth_type = DCERPC_AUTH_TYPE_NTLMSSP;
1171 if (bflags & DCERPC_AUTH_KRB5) {
1172 if (pipe_default_auth_type == DCERPC_AUTH_TYPE_SPNEGO) {
1173 pipe_default_auth_spnego_type = PIPE_AUTH_TYPE_SPNEGO_KRB5;
1175 pipe_default_auth_type = DCERPC_AUTH_TYPE_KRB5;
1178 if (pipe_default_auth_type != DCERPC_AUTH_TYPE_NONE) {
1179 /* If nothing is requested then default to integrity */
1180 if (pipe_default_auth_level == DCERPC_AUTH_LEVEL_NONE) {
1181 pipe_default_auth_level = DCERPC_AUTH_LEVEL_INTEGRITY;
1185 signing_state = get_cmdline_auth_info_signing_state(
1186 popt_get_cmdline_auth_info());
1187 switch (signing_state) {
1188 case SMB_SIGNING_OFF:
1189 lp_set_cmdline("client ipc signing", "no");
1191 case SMB_SIGNING_REQUIRED:
1192 lp_set_cmdline("client ipc signing", "required");
1196 rpcclient_netlogon_domain = get_cmdline_auth_info_domain(
1197 popt_get_cmdline_auth_info());
1198 if (rpcclient_netlogon_domain == NULL ||
1199 rpcclient_netlogon_domain[0] == '\0')
1201 rpcclient_netlogon_domain = lp_workgroup();
1204 nt_status = cli_full_connection_creds(&cli, lp_netbios_name(), host,
1205 opt_ipaddr ? &server_ss : NULL, opt_port,
1207 get_cmdline_auth_info_creds(
1208 popt_get_cmdline_auth_info()),
1211 if (!NT_STATUS_IS_OK(nt_status)) {
1212 DEBUG(0,("Cannot connect to server. Error was %s\n", nt_errstr(nt_status)));
1217 #if 0 /* COMMENT OUT FOR TESTING */
1218 memset(cmdline_auth_info.password,'X',sizeof(cmdline_auth_info.password));
1221 /* Load command lists */
1224 cli_set_timeout(cli, timeout);
1226 cmd_set = rpcclient_command_list;
1229 add_command_set(*cmd_set);
1230 add_command_set(separator_command);
1234 default_transport = dcerpc_binding_get_transport(binding);
1236 /* Do anything specified with -c */
1237 if (cmdstr && cmdstr[0]) {
1243 while((cmd=next_command(&p)) != NULL) {
1244 NTSTATUS cmd_result = process_cmd(
1245 popt_get_cmdline_auth_info(),
1248 result = NT_STATUS_IS_ERR(cmd_result);
1254 /* Loop around accepting commands */
1259 line = smb_readline("rpcclient $> ", NULL, completion_fn);
1266 if (line[0] != '\n')
1267 process_cmd(popt_get_cmdline_auth_info(), cli,
1276 popt_free_cmdline_auth_info();
1277 netlogon_creds_cli_close_global_db();
1278 TALLOC_FREE(rpcclient_msg_ctx);