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