s3: Simplify check_reduced_name a bit
[Samba/gebeck_regimport.git] / source3 / rpcclient / rpcclient.c
blob43df6723fcb59773ab74848fde650d1b05513307
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 "popt_common.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"
36 enum pipe_auth_type_spnego {
37 PIPE_AUTH_TYPE_SPNEGO_NONE = 0,
38 PIPE_AUTH_TYPE_SPNEGO_NTLMSSP,
39 PIPE_AUTH_TYPE_SPNEGO_KRB5
42 struct dom_sid domain_sid;
44 static enum dcerpc_AuthType pipe_default_auth_type = DCERPC_AUTH_TYPE_NONE;
45 static enum pipe_auth_type_spnego pipe_default_auth_spnego_type = 0;
46 static enum dcerpc_AuthLevel pipe_default_auth_level = DCERPC_AUTH_LEVEL_NONE;
47 static unsigned int timeout = 0;
48 static enum dcerpc_transport_t default_transport = NCACN_NP;
50 struct user_auth_info *rpcclient_auth_info;
52 /* List to hold groups of commands.
54 * Commands are defined in a list of arrays: arrays are easy to
55 * statically declare, and lists are easier to dynamically extend.
58 static struct cmd_list {
59 struct cmd_list *prev, *next;
60 struct cmd_set *cmd_set;
61 } *cmd_list;
63 /****************************************************************************
64 handle completion of commands for readline
65 ****************************************************************************/
66 static char **completion_fn(const char *text, int start, int end)
68 #define MAX_COMPLETIONS 1000
69 char **matches;
70 int i, count=0;
71 struct cmd_list *commands = cmd_list;
73 #if 0 /* JERRY */
74 /* FIXME!!! -- what to do when completing argument? */
75 /* for words not at the start of the line fallback
76 to filename completion */
77 if (start)
78 return NULL;
79 #endif
81 /* make sure we have a list of valid commands */
82 if (!commands) {
83 return NULL;
86 matches = SMB_MALLOC_ARRAY(char *, MAX_COMPLETIONS);
87 if (!matches) {
88 return NULL;
91 matches[count++] = SMB_STRDUP(text);
92 if (!matches[0]) {
93 SAFE_FREE(matches);
94 return NULL;
97 while (commands && count < MAX_COMPLETIONS-1) {
98 if (!commands->cmd_set) {
99 break;
102 for (i=0; commands->cmd_set[i].name; i++) {
103 if ((strncmp(text, commands->cmd_set[i].name, strlen(text)) == 0) &&
104 (( commands->cmd_set[i].returntype == RPC_RTYPE_NTSTATUS &&
105 commands->cmd_set[i].ntfn ) ||
106 ( commands->cmd_set[i].returntype == RPC_RTYPE_WERROR &&
107 commands->cmd_set[i].wfn))) {
108 matches[count] = SMB_STRDUP(commands->cmd_set[i].name);
109 if (!matches[count]) {
110 for (i = 0; i < count; i++) {
111 SAFE_FREE(matches[count]);
113 SAFE_FREE(matches);
114 return NULL;
116 count++;
119 commands = commands->next;
122 if (count == 2) {
123 SAFE_FREE(matches[0]);
124 matches[0] = SMB_STRDUP(matches[1]);
126 matches[count] = NULL;
127 return matches;
130 static char *next_command (char **cmdstr)
132 char *command;
133 char *p;
135 if (!cmdstr || !(*cmdstr))
136 return NULL;
138 p = strchr_m(*cmdstr, ';');
139 if (p)
140 *p = '\0';
141 command = SMB_STRDUP(*cmdstr);
142 if (p)
143 *cmdstr = p + 1;
144 else
145 *cmdstr = NULL;
147 return command;
150 /* Fetch the SID for this computer */
152 static void fetch_machine_sid(struct cli_state *cli)
154 struct policy_handle pol;
155 NTSTATUS result = NT_STATUS_OK, status;
156 static bool got_domain_sid;
157 TALLOC_CTX *mem_ctx;
158 struct rpc_pipe_client *lsapipe = NULL;
159 union lsa_PolicyInformation *info = NULL;
160 struct dcerpc_binding_handle *b;
162 if (got_domain_sid) return;
164 if (!(mem_ctx=talloc_init("fetch_machine_sid"))) {
165 DEBUG(0,("fetch_machine_sid: talloc_init returned NULL!\n"));
166 goto error;
169 result = cli_rpc_pipe_open_noauth(cli, &ndr_table_lsarpc.syntax_id,
170 &lsapipe);
171 if (!NT_STATUS_IS_OK(result)) {
172 fprintf(stderr, "could not initialise lsa pipe. Error was %s\n", nt_errstr(result) );
173 goto error;
176 b = lsapipe->binding_handle;
178 result = rpccli_lsa_open_policy(lsapipe, mem_ctx, True,
179 SEC_FLAG_MAXIMUM_ALLOWED,
180 &pol);
181 if (!NT_STATUS_IS_OK(result)) {
182 goto error;
185 status = dcerpc_lsa_QueryInfoPolicy(b, mem_ctx,
186 &pol,
187 LSA_POLICY_INFO_ACCOUNT_DOMAIN,
188 &info,
189 &result);
190 if (!NT_STATUS_IS_OK(status)) {
191 result = status;
192 goto error;
194 if (!NT_STATUS_IS_OK(result)) {
195 goto error;
198 got_domain_sid = True;
199 sid_copy(&domain_sid, info->account_domain.sid);
201 dcerpc_lsa_Close(b, mem_ctx, &pol, &result);
202 TALLOC_FREE(lsapipe);
203 talloc_destroy(mem_ctx);
205 return;
207 error:
209 if (lsapipe) {
210 TALLOC_FREE(lsapipe);
213 fprintf(stderr, "could not obtain sid for domain %s\n", cli->domain);
215 if (!NT_STATUS_IS_OK(result)) {
216 fprintf(stderr, "error: %s\n", nt_errstr(result));
219 exit(1);
222 /* List the available commands on a given pipe */
224 static NTSTATUS cmd_listcommands(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
225 int argc, const char **argv)
227 struct cmd_list *tmp;
228 struct cmd_set *tmp_set;
229 int i;
231 /* Usage */
233 if (argc != 2) {
234 printf("Usage: %s <pipe>\n", argv[0]);
235 return NT_STATUS_OK;
238 /* Help on one command */
240 for (tmp = cmd_list; tmp; tmp = tmp->next)
242 tmp_set = tmp->cmd_set;
244 if (!strcasecmp_m(argv[1], tmp_set->name))
246 printf("Available commands on the %s pipe:\n\n", tmp_set->name);
248 i = 0;
249 tmp_set++;
250 while(tmp_set->name) {
251 printf("%30s", tmp_set->name);
252 tmp_set++;
253 i++;
254 if (i%3 == 0)
255 printf("\n");
258 /* drop out of the loop */
259 break;
262 printf("\n\n");
264 return NT_STATUS_OK;
267 /* Display help on commands */
269 static NTSTATUS cmd_help(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
270 int argc, const char **argv)
272 struct cmd_list *tmp;
273 struct cmd_set *tmp_set;
275 /* Usage */
277 if (argc > 2) {
278 printf("Usage: %s [command]\n", argv[0]);
279 return NT_STATUS_OK;
282 /* Help on one command */
284 if (argc == 2) {
285 for (tmp = cmd_list; tmp; tmp = tmp->next) {
287 tmp_set = tmp->cmd_set;
289 while(tmp_set->name) {
290 if (strequal(argv[1], tmp_set->name)) {
291 if (tmp_set->usage &&
292 tmp_set->usage[0])
293 printf("%s\n", tmp_set->usage);
294 else
295 printf("No help for %s\n", tmp_set->name);
297 return NT_STATUS_OK;
300 tmp_set++;
304 printf("No such command: %s\n", argv[1]);
305 return NT_STATUS_OK;
308 /* List all commands */
310 for (tmp = cmd_list; tmp; tmp = tmp->next) {
312 tmp_set = tmp->cmd_set;
314 while(tmp_set->name) {
316 printf("%15s\t\t%s\n", tmp_set->name,
317 tmp_set->description ? tmp_set->description:
318 "");
320 tmp_set++;
324 return NT_STATUS_OK;
327 /* Change the debug level */
329 static NTSTATUS cmd_debuglevel(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
330 int argc, const char **argv)
332 if (argc > 2) {
333 printf("Usage: %s [debuglevel]\n", argv[0]);
334 return NT_STATUS_OK;
337 if (argc == 2) {
338 lp_set_cmdline("log level", argv[1]);
341 printf("debuglevel is %d\n", DEBUGLEVEL);
343 return NT_STATUS_OK;
346 static NTSTATUS cmd_quit(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
347 int argc, const char **argv)
349 exit(0);
350 return NT_STATUS_OK; /* NOTREACHED */
353 static NTSTATUS cmd_set_ss_level(void)
355 struct cmd_list *tmp;
357 /* Close any existing connections not at this level. */
359 for (tmp = cmd_list; tmp; tmp = tmp->next) {
360 struct cmd_set *tmp_set;
362 for (tmp_set = tmp->cmd_set; tmp_set->name; tmp_set++) {
363 if (tmp_set->rpc_pipe == NULL) {
364 continue;
367 if ((tmp_set->rpc_pipe->auth->auth_type
368 != pipe_default_auth_type)
369 || (tmp_set->rpc_pipe->auth->auth_level
370 != pipe_default_auth_level)) {
371 TALLOC_FREE(tmp_set->rpc_pipe);
372 tmp_set->rpc_pipe = NULL;
376 return NT_STATUS_OK;
379 static NTSTATUS cmd_set_transport(void)
381 struct cmd_list *tmp;
383 /* Close any existing connections not at this level. */
385 for (tmp = cmd_list; tmp; tmp = tmp->next) {
386 struct cmd_set *tmp_set;
388 for (tmp_set = tmp->cmd_set; tmp_set->name; tmp_set++) {
389 if (tmp_set->rpc_pipe == NULL) {
390 continue;
393 if (tmp_set->rpc_pipe->transport->transport != default_transport) {
394 TALLOC_FREE(tmp_set->rpc_pipe);
395 tmp_set->rpc_pipe = NULL;
399 return NT_STATUS_OK;
402 static NTSTATUS cmd_sign(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
403 int argc, const char **argv)
405 const char *p = "[KRB5|KRB5_SPNEGO|NTLMSSP|NTLMSSP_SPNEGO|SCHANNEL]";
406 const char *type = "NTLMSSP";
408 pipe_default_auth_level = DCERPC_AUTH_LEVEL_INTEGRITY;
409 pipe_default_auth_type = DCERPC_AUTH_TYPE_NTLMSSP;
411 if (argc > 2) {
412 printf("Usage: %s %s\n", argv[0], p);
413 return NT_STATUS_OK;
416 if (argc == 2) {
417 type = argv[1];
418 if (strequal(type, "KRB5")) {
419 pipe_default_auth_type = DCERPC_AUTH_TYPE_KRB5;
420 } else if (strequal(type, "KRB5_SPNEGO")) {
421 pipe_default_auth_type = DCERPC_AUTH_TYPE_SPNEGO;
422 pipe_default_auth_spnego_type = PIPE_AUTH_TYPE_SPNEGO_KRB5;
423 } else if (strequal(type, "NTLMSSP")) {
424 pipe_default_auth_type = DCERPC_AUTH_TYPE_NTLMSSP;
425 } else if (strequal(type, "NTLMSSP_SPNEGO")) {
426 pipe_default_auth_type = DCERPC_AUTH_TYPE_SPNEGO;
427 pipe_default_auth_spnego_type = PIPE_AUTH_TYPE_SPNEGO_NTLMSSP;
428 } else if (strequal(type, "SCHANNEL")) {
429 pipe_default_auth_type = DCERPC_AUTH_TYPE_SCHANNEL;
430 } else {
431 printf("unknown type %s\n", type);
432 printf("Usage: %s %s\n", argv[0], p);
433 return NT_STATUS_INVALID_LEVEL;
437 d_printf("Setting %s - sign\n", type);
439 return cmd_set_ss_level();
442 static NTSTATUS cmd_seal(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
443 int argc, const char **argv)
445 const char *p = "[KRB5|KRB5_SPNEGO|NTLMSSP|NTLMSSP_SPNEGO|SCHANNEL]";
446 const char *type = "NTLMSSP";
448 pipe_default_auth_level = DCERPC_AUTH_LEVEL_PRIVACY;
449 pipe_default_auth_type = DCERPC_AUTH_TYPE_NTLMSSP;
451 if (argc > 2) {
452 printf("Usage: %s %s\n", argv[0], p);
453 return NT_STATUS_OK;
456 if (argc == 2) {
457 type = argv[1];
458 if (strequal(type, "KRB5")) {
459 pipe_default_auth_type = DCERPC_AUTH_TYPE_KRB5;
460 } else if (strequal(type, "KRB5_SPNEGO")) {
461 pipe_default_auth_type = DCERPC_AUTH_TYPE_SPNEGO;
462 pipe_default_auth_spnego_type = PIPE_AUTH_TYPE_SPNEGO_KRB5;
463 } else if (strequal(type, "NTLMSSP")) {
464 pipe_default_auth_type = DCERPC_AUTH_TYPE_NTLMSSP;
465 } else if (strequal(type, "NTLMSSP_SPNEGO")) {
466 pipe_default_auth_type = DCERPC_AUTH_TYPE_SPNEGO;
467 pipe_default_auth_spnego_type = PIPE_AUTH_TYPE_SPNEGO_NTLMSSP;
468 } else if (strequal(type, "SCHANNEL")) {
469 pipe_default_auth_type = DCERPC_AUTH_TYPE_SCHANNEL;
470 } else {
471 printf("unknown type %s\n", type);
472 printf("Usage: %s %s\n", argv[0], p);
473 return NT_STATUS_INVALID_LEVEL;
477 d_printf("Setting %s - sign and seal\n", type);
479 return cmd_set_ss_level();
482 static NTSTATUS cmd_timeout(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
483 int argc, const char **argv)
485 struct cmd_list *tmp;
487 if (argc > 2) {
488 printf("Usage: %s timeout\n", argv[0]);
489 return NT_STATUS_OK;
492 if (argc == 2) {
493 timeout = atoi(argv[1]);
495 for (tmp = cmd_list; tmp; tmp = tmp->next) {
497 struct cmd_set *tmp_set;
499 for (tmp_set = tmp->cmd_set; tmp_set->name; tmp_set++) {
500 if (tmp_set->rpc_pipe == NULL) {
501 continue;
504 rpccli_set_timeout(tmp_set->rpc_pipe, timeout);
509 printf("timeout is %d\n", timeout);
511 return NT_STATUS_OK;
515 static NTSTATUS cmd_none(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
516 int argc, const char **argv)
518 pipe_default_auth_level = DCERPC_AUTH_LEVEL_NONE;
519 pipe_default_auth_type = DCERPC_AUTH_TYPE_NONE;
520 pipe_default_auth_spnego_type = PIPE_AUTH_TYPE_SPNEGO_NONE;
522 return cmd_set_ss_level();
525 static NTSTATUS cmd_schannel(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
526 int argc, const char **argv)
528 d_printf("Setting schannel - sign and seal\n");
529 pipe_default_auth_level = DCERPC_AUTH_LEVEL_PRIVACY;
530 pipe_default_auth_type = DCERPC_AUTH_TYPE_SCHANNEL;
532 return cmd_set_ss_level();
535 static NTSTATUS cmd_schannel_sign(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
536 int argc, const char **argv)
538 d_printf("Setting schannel - sign only\n");
539 pipe_default_auth_level = DCERPC_AUTH_LEVEL_INTEGRITY;
540 pipe_default_auth_type = DCERPC_AUTH_TYPE_SCHANNEL;
542 return cmd_set_ss_level();
545 static NTSTATUS cmd_choose_transport(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
546 int argc, const char **argv)
548 NTSTATUS status;
550 if (argc != 2) {
551 printf("Usage: %s [NCACN_NP|NCACN_IP_TCP]\n", argv[0]);
552 return NT_STATUS_OK;
555 if (strequal(argv[1], "NCACN_NP")) {
556 default_transport = NCACN_NP;
557 } else if (strequal(argv[1], "NCACN_IP_TCP")) {
558 default_transport = NCACN_IP_TCP;
559 } else {
560 printf("transport type: %s unknown or not supported\n", argv[1]);
561 return NT_STATUS_NOT_SUPPORTED;
564 status = cmd_set_transport();
565 if (!NT_STATUS_IS_OK(status)) {
566 return status;
569 printf("default transport is now: %s\n", argv[1]);
571 return NT_STATUS_OK;
574 /* Built in rpcclient commands */
576 static struct cmd_set rpcclient_commands[] = {
578 { "GENERAL OPTIONS" },
580 { "help", RPC_RTYPE_NTSTATUS, cmd_help, NULL, NULL, NULL, "Get help on commands", "[command]" },
581 { "?", RPC_RTYPE_NTSTATUS, cmd_help, NULL, NULL, NULL, "Get help on commands", "[command]" },
582 { "debuglevel", RPC_RTYPE_NTSTATUS, cmd_debuglevel, NULL, NULL, NULL, "Set debug level", "level" },
583 { "debug", RPC_RTYPE_NTSTATUS, cmd_debuglevel, NULL, NULL, NULL, "Set debug level", "level" },
584 { "list", RPC_RTYPE_NTSTATUS, cmd_listcommands, NULL, NULL, NULL, "List available commands on <pipe>", "pipe" },
585 { "exit", RPC_RTYPE_NTSTATUS, cmd_quit, NULL, NULL, NULL, "Exit program", "" },
586 { "quit", RPC_RTYPE_NTSTATUS, cmd_quit, NULL, NULL, NULL, "Exit program", "" },
587 { "sign", RPC_RTYPE_NTSTATUS, cmd_sign, NULL, NULL, NULL, "Force RPC pipe connections to be signed", "" },
588 { "seal", RPC_RTYPE_NTSTATUS, cmd_seal, NULL, NULL, NULL, "Force RPC pipe connections to be sealed", "" },
589 { "schannel", RPC_RTYPE_NTSTATUS, cmd_schannel, NULL, NULL, NULL, "Force RPC pipe connections to be sealed with 'schannel'. Assumes valid machine account to this domain controller.", "" },
590 { "schannelsign", RPC_RTYPE_NTSTATUS, cmd_schannel_sign, NULL, NULL, NULL, "Force RPC pipe connections to be signed (not sealed) with 'schannel'. Assumes valid machine account to this domain controller.", "" },
591 { "timeout", RPC_RTYPE_NTSTATUS, cmd_timeout, NULL, NULL, NULL, "Set timeout (in milliseconds) for RPC operations", "" },
592 { "transport", RPC_RTYPE_NTSTATUS, cmd_choose_transport, NULL, NULL, NULL, "Choose ncacn transport for RPC operations", "" },
593 { "none", RPC_RTYPE_NTSTATUS, cmd_none, NULL, NULL, NULL, "Force RPC pipe connections to have no special properties", "" },
595 { NULL }
598 static struct cmd_set separator_command[] = {
599 { "---------------", MAX_RPC_RETURN_TYPE, NULL, NULL, NULL, NULL, "----------------------" },
600 { NULL }
604 /* Various pipe commands */
606 extern struct cmd_set lsarpc_commands[];
607 extern struct cmd_set samr_commands[];
608 extern struct cmd_set spoolss_commands[];
609 extern struct cmd_set netlogon_commands[];
610 extern struct cmd_set srvsvc_commands[];
611 extern struct cmd_set dfs_commands[];
612 extern struct cmd_set ds_commands[];
613 extern struct cmd_set echo_commands[];
614 extern struct cmd_set epmapper_commands[];
615 extern struct cmd_set shutdown_commands[];
616 extern struct cmd_set test_commands[];
617 extern struct cmd_set wkssvc_commands[];
618 extern struct cmd_set ntsvcs_commands[];
619 extern struct cmd_set drsuapi_commands[];
620 extern struct cmd_set eventlog_commands[];
621 extern struct cmd_set winreg_commands[];
623 static struct cmd_set *rpcclient_command_list[] = {
624 rpcclient_commands,
625 lsarpc_commands,
626 ds_commands,
627 samr_commands,
628 spoolss_commands,
629 netlogon_commands,
630 srvsvc_commands,
631 dfs_commands,
632 echo_commands,
633 epmapper_commands,
634 shutdown_commands,
635 test_commands,
636 wkssvc_commands,
637 ntsvcs_commands,
638 drsuapi_commands,
639 eventlog_commands,
640 winreg_commands,
641 NULL
644 static void add_command_set(struct cmd_set *cmd_set)
646 struct cmd_list *entry;
648 if (!(entry = SMB_MALLOC_P(struct cmd_list))) {
649 DEBUG(0, ("out of memory\n"));
650 return;
653 ZERO_STRUCTP(entry);
655 entry->cmd_set = cmd_set;
656 DLIST_ADD(cmd_list, entry);
661 * Call an rpcclient function, passing an argv array.
663 * @param cmd Command to run, as a single string.
665 static NTSTATUS do_cmd(struct cli_state *cli,
666 struct user_auth_info *auth_info,
667 struct cmd_set *cmd_entry,
668 struct dcerpc_binding *binding,
669 int argc, char **argv)
671 NTSTATUS ntresult;
672 WERROR wresult;
674 TALLOC_CTX *mem_ctx;
676 /* Create mem_ctx */
678 if (!(mem_ctx = talloc_init("do_cmd"))) {
679 DEBUG(0, ("talloc_init() failed\n"));
680 return NT_STATUS_NO_MEMORY;
683 /* Open pipe */
685 if ((cmd_entry->table != NULL) && (cmd_entry->rpc_pipe == NULL)) {
686 switch (pipe_default_auth_type) {
687 case DCERPC_AUTH_TYPE_NONE:
688 ntresult = cli_rpc_pipe_open_noauth_transport(
689 cli, default_transport,
690 &cmd_entry->table->syntax_id,
691 &cmd_entry->rpc_pipe);
692 break;
693 case DCERPC_AUTH_TYPE_SPNEGO:
695 /* won't happen, but if it does it will fail in cli_rpc_pipe_open_spnego() eventually */
696 const char *oid = "INVALID";
697 switch (pipe_default_auth_spnego_type) {
698 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
699 oid = GENSEC_OID_NTLMSSP;
700 break;
701 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
702 oid = GENSEC_OID_KERBEROS5;
703 break;
705 ntresult = cli_rpc_pipe_open_spnego(
706 cli, cmd_entry->table,
707 default_transport,
708 oid,
709 pipe_default_auth_level,
710 cli_state_remote_name(cli),
711 get_cmdline_auth_info_domain(auth_info),
712 get_cmdline_auth_info_username(auth_info),
713 get_cmdline_auth_info_password(auth_info),
714 &cmd_entry->rpc_pipe);
715 break;
717 case DCERPC_AUTH_TYPE_NTLMSSP:
718 case DCERPC_AUTH_TYPE_KRB5:
719 ntresult = cli_rpc_pipe_open_generic_auth(
720 cli, cmd_entry->table,
721 default_transport,
722 pipe_default_auth_type,
723 pipe_default_auth_level,
724 cli_state_remote_name(cli),
725 get_cmdline_auth_info_domain(auth_info),
726 get_cmdline_auth_info_username(auth_info),
727 get_cmdline_auth_info_password(auth_info),
728 &cmd_entry->rpc_pipe);
729 break;
730 case DCERPC_AUTH_TYPE_SCHANNEL:
731 ntresult = cli_rpc_pipe_open_schannel(
732 cli, &cmd_entry->table->syntax_id,
733 default_transport,
734 pipe_default_auth_level,
735 get_cmdline_auth_info_domain(auth_info),
736 &cmd_entry->rpc_pipe);
737 break;
738 default:
739 DEBUG(0, ("Could not initialise %s. Invalid "
740 "auth type %u\n",
741 cmd_entry->table->name,
742 pipe_default_auth_type ));
743 return NT_STATUS_UNSUCCESSFUL;
745 if (!NT_STATUS_IS_OK(ntresult)) {
746 DEBUG(0, ("Could not initialise %s. Error was %s\n",
747 cmd_entry->table->name,
748 nt_errstr(ntresult) ));
749 return ntresult;
752 if (ndr_syntax_id_equal(&cmd_entry->table->syntax_id,
753 &ndr_table_netlogon.syntax_id)) {
754 uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
755 enum netr_SchannelType sec_channel_type;
756 uchar trust_password[16];
757 const char *machine_account;
759 if (!get_trust_pw_hash(get_cmdline_auth_info_domain(auth_info),
760 trust_password, &machine_account,
761 &sec_channel_type))
763 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
766 ntresult = rpccli_netlogon_setup_creds(cmd_entry->rpc_pipe,
767 cmd_entry->rpc_pipe->desthost, /* server name */
768 get_cmdline_auth_info_domain(auth_info), /* domain */
769 lp_netbios_name(), /* client name */
770 machine_account, /* machine account name */
771 trust_password,
772 sec_channel_type,
773 &neg_flags);
775 if (!NT_STATUS_IS_OK(ntresult)) {
776 DEBUG(0, ("Could not initialise credentials for %s.\n",
777 cmd_entry->table->name));
778 return ntresult;
783 /* Run command */
785 if ( cmd_entry->returntype == RPC_RTYPE_NTSTATUS ) {
786 ntresult = cmd_entry->ntfn(cmd_entry->rpc_pipe, mem_ctx, argc, (const char **) argv);
787 if (!NT_STATUS_IS_OK(ntresult)) {
788 printf("result was %s\n", nt_errstr(ntresult));
790 } else {
791 wresult = cmd_entry->wfn(cmd_entry->rpc_pipe, mem_ctx, argc, (const char **) argv);
792 /* print out the DOS error */
793 if (!W_ERROR_IS_OK(wresult)) {
794 printf( "result was %s\n", win_errstr(wresult));
796 ntresult = W_ERROR_IS_OK(wresult)?NT_STATUS_OK:NT_STATUS_UNSUCCESSFUL;
799 /* Cleanup */
801 talloc_destroy(mem_ctx);
803 return ntresult;
808 * Process a command entered at the prompt or as part of -c
810 * @returns The NTSTATUS from running the command.
812 static NTSTATUS process_cmd(struct user_auth_info *auth_info,
813 struct cli_state *cli,
814 struct dcerpc_binding *binding,
815 char *cmd)
817 struct cmd_list *temp_list;
818 NTSTATUS result = NT_STATUS_OK;
819 int ret;
820 int argc;
821 char **argv = NULL;
823 if ((ret = poptParseArgvString(cmd, &argc, (const char ***) &argv)) != 0) {
824 fprintf(stderr, "rpcclient: %s\n", poptStrerror(ret));
825 return NT_STATUS_UNSUCCESSFUL;
829 /* Walk through a dlist of arrays of commands. */
830 for (temp_list = cmd_list; temp_list; temp_list = temp_list->next) {
831 struct cmd_set *temp_set = temp_list->cmd_set;
833 while (temp_set->name) {
834 if (strequal(argv[0], temp_set->name)) {
835 if (!(temp_set->returntype == RPC_RTYPE_NTSTATUS && temp_set->ntfn ) &&
836 !(temp_set->returntype == RPC_RTYPE_WERROR && temp_set->wfn )) {
837 fprintf (stderr, "Invalid command\n");
838 goto out_free;
841 result = do_cmd(cli, auth_info, temp_set,
842 binding, argc, argv);
844 goto out_free;
846 temp_set++;
850 if (argv[0]) {
851 printf("command not found: %s\n", argv[0]);
854 out_free:
855 /* moved to do_cmd()
856 if (!NT_STATUS_IS_OK(result)) {
857 printf("result was %s\n", nt_errstr(result));
861 /* NOTE: popt allocates the whole argv, including the
862 * strings, as a single block. So a single free is
863 * enough to release it -- we don't free the
864 * individual strings. rtfm. */
865 free(argv);
867 return result;
871 /* Main function */
873 int main(int argc, char *argv[])
875 int opt;
876 static char *cmdstr = NULL;
877 const char *server;
878 struct cli_state *cli = NULL;
879 static char *opt_ipaddr=NULL;
880 struct cmd_set **cmd_set;
881 struct sockaddr_storage server_ss;
882 NTSTATUS nt_status;
883 static int opt_port = 0;
884 int result = 0;
885 TALLOC_CTX *frame = talloc_stackframe();
886 uint32_t flags = 0;
887 struct dcerpc_binding *binding = NULL;
888 const char *binding_string = NULL;
889 char *user, *domain, *q;
891 /* make sure the vars that get altered (4th field) are in
892 a fixed location or certain compilers complain */
893 poptContext pc;
894 struct poptOption long_options[] = {
895 POPT_AUTOHELP
896 {"command", 'c', POPT_ARG_STRING, &cmdstr, 'c', "Execute semicolon separated cmds", "COMMANDS"},
897 {"dest-ip", 'I', POPT_ARG_STRING, &opt_ipaddr, 'I', "Specify destination IP address", "IP"},
898 {"port", 'p', POPT_ARG_INT, &opt_port, 'p', "Specify port number", "PORT"},
899 POPT_COMMON_SAMBA
900 POPT_COMMON_CONNECTION
901 POPT_COMMON_CREDENTIALS
902 POPT_TABLEEND
905 load_case_tables();
907 zero_sockaddr(&server_ss);
909 setlinebuf(stdout);
911 /* the following functions are part of the Samba debugging
912 facilities. See lib/debug.c */
913 setup_logging("rpcclient", DEBUG_STDOUT);
915 rpcclient_auth_info = user_auth_info_init(frame);
916 if (rpcclient_auth_info == NULL) {
917 exit(1);
919 popt_common_set_auth_info(rpcclient_auth_info);
921 /* Parse options */
923 pc = poptGetContext("rpcclient", argc, (const char **) argv,
924 long_options, 0);
926 if (argc == 1) {
927 poptPrintHelp(pc, stderr, 0);
928 goto done;
931 while((opt = poptGetNextOpt(pc)) != -1) {
932 switch (opt) {
934 case 'I':
935 if (!interpret_string_addr(&server_ss,
936 opt_ipaddr,
937 AI_NUMERICHOST)) {
938 fprintf(stderr, "%s not a valid IP address\n",
939 opt_ipaddr);
940 result = 1;
941 goto done;
946 /* Get server as remaining unparsed argument. Print usage if more
947 than one unparsed argument is present. */
949 server = poptGetArg(pc);
951 if (!server || poptGetArg(pc)) {
952 poptPrintHelp(pc, stderr, 0);
953 result = 1;
954 goto done;
957 poptFreeContext(pc);
959 if (!init_names()) {
960 result = 1;
961 goto done;
964 /* Load smb.conf file */
966 if (!lp_load_global(get_dyn_CONFIGFILE()))
967 fprintf(stderr, "Can't load %s\n", get_dyn_CONFIGFILE());
969 /* We must load interfaces after we load the smb.conf */
970 load_interfaces();
973 * Get password
974 * from stdin if necessary
977 if (get_cmdline_auth_info_use_machine_account(rpcclient_auth_info) &&
978 !set_cmdline_auth_info_machine_account_creds(rpcclient_auth_info)) {
979 result = 1;
980 goto done;
983 set_cmdline_auth_info_getpass(rpcclient_auth_info);
985 if ((server[0] == '/' && server[1] == '/') ||
986 (server[0] == '\\' && server[1] == '\\')) {
987 server += 2;
990 nt_status = dcerpc_parse_binding(frame, server, &binding);
992 if (!NT_STATUS_IS_OK(nt_status)) {
994 binding_string = talloc_asprintf(frame, "ncacn_np:%s",
995 strip_hostname(server));
996 if (!binding_string) {
997 result = 1;
998 goto done;
1001 nt_status = dcerpc_parse_binding(frame, binding_string, &binding);
1002 if (!NT_STATUS_IS_OK(nt_status)) {
1003 result = -1;
1004 goto done;
1008 if (binding->transport == NCA_UNKNOWN) {
1009 binding->transport = NCACN_NP;
1012 if (binding->flags & DCERPC_SIGN) {
1013 pipe_default_auth_level = DCERPC_AUTH_LEVEL_INTEGRITY;
1014 pipe_default_auth_type = DCERPC_AUTH_TYPE_NTLMSSP;
1016 if (binding->flags & DCERPC_SEAL) {
1017 pipe_default_auth_level = DCERPC_AUTH_LEVEL_PRIVACY;
1018 pipe_default_auth_type = DCERPC_AUTH_TYPE_NTLMSSP;
1020 if (binding->flags & DCERPC_AUTH_SPNEGO) {
1021 pipe_default_auth_type = DCERPC_AUTH_TYPE_SPNEGO;
1022 pipe_default_auth_spnego_type = PIPE_AUTH_TYPE_SPNEGO_NTLMSSP;
1024 if (binding->flags & DCERPC_AUTH_NTLM) {
1025 /* If neither Integrity or Privacy are requested then
1026 * Use just Connect level */
1027 if (pipe_default_auth_level == DCERPC_AUTH_LEVEL_NONE) {
1028 pipe_default_auth_level = DCERPC_AUTH_LEVEL_CONNECT;
1031 if (pipe_default_auth_type == DCERPC_AUTH_TYPE_SPNEGO) {
1032 pipe_default_auth_spnego_type = PIPE_AUTH_TYPE_SPNEGO_NTLMSSP;
1033 } else {
1034 pipe_default_auth_type = DCERPC_AUTH_TYPE_NTLMSSP;
1037 if (binding->flags & DCERPC_AUTH_KRB5) {
1038 /* If neither Integrity or Privacy are requested then
1039 * Use just Connect level */
1040 if (pipe_default_auth_level == DCERPC_AUTH_LEVEL_NONE) {
1041 pipe_default_auth_level = DCERPC_AUTH_LEVEL_CONNECT;
1044 if (pipe_default_auth_type == DCERPC_AUTH_TYPE_SPNEGO) {
1045 pipe_default_auth_spnego_type = PIPE_AUTH_TYPE_SPNEGO_KRB5;
1046 } else {
1047 pipe_default_auth_type = DCERPC_AUTH_TYPE_KRB5;
1051 if (get_cmdline_auth_info_use_kerberos(rpcclient_auth_info)) {
1052 flags |= CLI_FULL_CONNECTION_USE_KERBEROS |
1053 CLI_FULL_CONNECTION_FALLBACK_AFTER_KERBEROS;
1055 if (get_cmdline_auth_info_use_ccache(rpcclient_auth_info)) {
1056 flags |= CLI_FULL_CONNECTION_USE_CCACHE;
1059 user = talloc_strdup(frame, get_cmdline_auth_info_username(rpcclient_auth_info));
1060 SMB_ASSERT(user != NULL);
1061 domain = talloc_strdup(frame, lp_workgroup());
1062 SMB_ASSERT(domain != NULL);
1063 set_cmdline_auth_info_domain(rpcclient_auth_info, domain);
1065 if ((q = strchr_m(user,'\\'))) {
1066 *q = 0;
1067 set_cmdline_auth_info_domain(rpcclient_auth_info, user);
1068 set_cmdline_auth_info_username(rpcclient_auth_info, q+1);
1072 nt_status = cli_full_connection(&cli, lp_netbios_name(), binding->host,
1073 opt_ipaddr ? &server_ss : NULL, opt_port,
1074 "IPC$", "IPC",
1075 get_cmdline_auth_info_username(rpcclient_auth_info),
1076 get_cmdline_auth_info_domain(rpcclient_auth_info),
1077 get_cmdline_auth_info_password(rpcclient_auth_info),
1078 flags,
1079 get_cmdline_auth_info_signing_state(rpcclient_auth_info));
1081 if (!NT_STATUS_IS_OK(nt_status)) {
1082 DEBUG(0,("Cannot connect to server. Error was %s\n", nt_errstr(nt_status)));
1083 result = 1;
1084 goto done;
1087 if (get_cmdline_auth_info_smb_encrypt(rpcclient_auth_info)) {
1088 nt_status = cli_cm_force_encryption(cli,
1089 get_cmdline_auth_info_username(rpcclient_auth_info),
1090 get_cmdline_auth_info_password(rpcclient_auth_info),
1091 get_cmdline_auth_info_domain(rpcclient_auth_info),
1092 "IPC$");
1093 if (!NT_STATUS_IS_OK(nt_status)) {
1094 result = 1;
1095 goto done;
1099 #if 0 /* COMMENT OUT FOR TESTING */
1100 memset(cmdline_auth_info.password,'X',sizeof(cmdline_auth_info.password));
1101 #endif
1103 /* Load command lists */
1105 timeout = cli_set_timeout(cli, 10000);
1107 cmd_set = rpcclient_command_list;
1109 while(*cmd_set) {
1110 add_command_set(*cmd_set);
1111 add_command_set(separator_command);
1112 cmd_set++;
1115 default_transport = binding->transport;
1117 fetch_machine_sid(cli);
1119 /* Do anything specified with -c */
1120 if (cmdstr && cmdstr[0]) {
1121 char *cmd;
1122 char *p = cmdstr;
1124 result = 0;
1126 while((cmd=next_command(&p)) != NULL) {
1127 NTSTATUS cmd_result = process_cmd(rpcclient_auth_info, cli,
1128 binding, cmd);
1129 SAFE_FREE(cmd);
1130 result = NT_STATUS_IS_ERR(cmd_result);
1133 goto done;
1136 /* Loop around accepting commands */
1138 while(1) {
1139 char *line = NULL;
1141 line = smb_readline("rpcclient $> ", NULL, completion_fn);
1143 if (line == NULL)
1144 break;
1146 if (line[0] != '\n')
1147 process_cmd(rpcclient_auth_info, cli, binding, line);
1148 SAFE_FREE(line);
1151 done:
1152 if (cli != NULL) {
1153 cli_shutdown(cli);
1155 TALLOC_FREE(frame);
1156 return result;