Fixed -d option for rpcclient.
[Samba/gebeck_regimport.git] / source3 / lib / cmd_interp.c
blob7d40a381361b8a276598424a6c6f54c7ce5672ba
1 /*
2 Unix SMB/Netbios implementation.
3 Version 1.9.
4 SMB client
5 Copyright (C) Andrew Tridgell 1994-1998
6 Copyright (C) Luke Kenneth Casson Leighton 1998-2000
7 Copyright (C) Gerald Carter 2000
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 #ifdef SYSLOG
25 #undef SYSLOG
26 #endif
28 #include "includes.h"
29 #include "rpc_parse.h"
30 #include "rpc_client.h"
32 #ifndef REGISTER
33 #define REGISTER 0
34 #endif
36 extern pstring debugf;
37 extern pstring global_myname;
39 extern pstring user_socket_options;
41 /* found in rpc_client/cli_connect.c */
42 extern struct user_creds *usr_creds;
45 extern int DEBUGLEVEL;
48 #define CNV_LANG(s) dos2unix_format(s,False)
49 #define CNV_INPUT(s) unix2dos_format(s,True)
51 static int process_tok(fstring tok);
52 static uint32 cmd_help(struct client_info *info, int argc, char *argv[]);
53 static uint32 cmd_quit(struct client_info *info, int argc, char *argv[]);
54 static uint32 cmd_set(struct client_info *info, int argc, char *argv[]);
55 static uint32 cmd_use(struct client_info *info, int argc, char *argv[]);
57 static struct user_creds usr;
59 struct client_info cli_info;
61 char **cmd_argv = NULL;
62 uint32 cmd_argc = 0;
64 FILE *out_hnd;
67 static void cmd_set_free(struct command_set *item)
69 if (item != NULL)
70 safe_free(item->name);
72 safe_free(item);
75 static struct command_set *cmd_set_dup(const struct command_set *from)
77 if (from != NULL)
79 struct command_set *copy;
81 copy = (struct command_set*)malloc(sizeof(struct command_set));
82 if (copy != NULL)
84 memcpy(copy, from, sizeof(struct command_set));
85 if (from->name != NULL)
86 copy->name = strdup(from->name);
88 return copy;
90 return NULL;
93 void free_cmd_set_array(uint32 num_entries, struct command_set **entries)
95 void (*fn) (void *) = (void (*)(void *))&cmd_set_free;
96 free_void_array(num_entries, (void **)entries, *fn);
99 struct command_set *add_cmd_set_to_array(uint32 *len, struct command_set ***array,
100 const struct command_set *cmd)
102 void *(*fn) (const void *) = (void *(*)(const void *))&cmd_set_dup;
103 return (struct command_set *)add_copy_to_array(len, (void ***)array,
104 (const void *)cmd, *fn,
105 False);
109 static struct command_set **commands = NULL;
110 static uint32 num_commands = 0;
112 /****************************************************************************
113 add in individual command-sets.
114 ****************************************************************************/
115 void add_command_set(const struct command_set *cmds)
117 while (! ((cmds->fn==NULL) && (strlen(cmds->name)==0)))
119 add_cmd_set_to_array(&num_commands, &commands, cmds);
120 cmds++;
124 /****************************************************************************
125 This defines the commands supported by this client
126 ****************************************************************************/
127 static struct command_set general_commands[] = {
129 * maintenance
132 {"General", NULL, NULL, {NULL, NULL}},
134 { "set", cmd_set,
135 "run rpcclient inside rpcclient (change options etc.)",
136 {NULL, NULL}
139 { "use", cmd_use,
140 "net use and net view",
141 {NULL, NULL}
145 * bye bye
148 { "quit", cmd_quit,
149 "logoff the server",
150 {NULL, NULL}
152 { "q", cmd_quit,
153 "logoff the server",
154 {NULL, NULL}
156 { "exit", cmd_quit,
157 "logoff the server",
158 {NULL, NULL}
160 { "bye", cmd_quit,
161 "logoff the server",
162 {NULL, NULL}
166 * eek!
169 { "help", cmd_help,
170 "[command] give help on a command",
171 {NULL, NULL}
173 { "?", cmd_help,
174 "[command] give help on a command",
175 {NULL, NULL}
179 * shell
182 { "!", NULL,
183 "run a shell command on the local system",
184 {NULL, NULL}
188 * oop!
191 { "", NULL, NULL,
192 {NULL, NULL}
197 /****************************************************************************
198 do a (presumably graceful) quit...
199 ****************************************************************************/
200 static uint32 cmd_quit(struct client_info *info, int argc, char *argv[])
202 #ifdef MEM_MAN
204 extern FILE *dbf;
205 smb_mem_write_status(dbf);
206 smb_mem_write_errors(dbf);
207 smb_mem_write_verbose(dbf);
208 dbgflush();
210 #endif
212 free_connections();
213 exit(0);
215 /* NOTREACHED */
216 return 0;
219 /****************************************************************************
220 help
221 ****************************************************************************/
222 static uint32 cmd_help(struct client_info *info, int argc, char *argv[])
224 int i = 0;
226 /* get help on a specific command */
227 if (argc > 1)
229 if ((i = process_tok(argv[0])) >= 0)
231 fprintf(out_hnd, "HELP %s:\n\t%s\n\n", commands[i]->name,
232 commands[i]->description);
235 return 0;
238 /* Print out the list of available commands */
239 for (i = 0; i < num_commands; i++)
241 if (commands[i]->fn == NULL)
242 fprintf (out_hnd, "\n");
243 else
244 fprintf (out_hnd, "\t");
246 fprintf(out_hnd, "%s\n", commands[i]->name);
249 return 0;
252 /*******************************************************************
253 lookup a command string in the list of commands, including
254 abbreviations
255 ******************************************************************/
256 static int process_tok(char *tok)
258 int i = 0, matches = 0;
259 int cmd = 0;
260 int tok_len = strlen(tok);
262 for (i = 0; i < num_commands; i++)
264 if (strequal(commands[i]->name, tok))
266 matches = 1;
267 cmd = i;
268 break;
270 else if (strnequal(commands[i]->name, tok, tok_len))
272 matches++;
273 cmd = i;
277 if (matches == 0)
278 return (-1);
279 else if (matches == 1)
280 return (cmd);
281 else
282 return (-2);
285 /****************************************************************************
286 turn command line into command argument array
287 ****************************************************************************/
288 static BOOL get_cmd_args(char *line)
290 char *ptr = line;
291 pstring tok;
292 cmd_argc = 0;
293 cmd_argv = NULL;
295 /* get the first part of the command */
296 if (!next_token(&ptr, tok, NULL, sizeof(tok)))
297 return False;
301 add_chars_to_array(&cmd_argc, &cmd_argv, tok);
303 while (next_token(NULL, tok, NULL, sizeof(tok)));
305 add_chars_to_array(&cmd_argc, &cmd_argv, NULL);
307 return True;
310 /* command options mask */
311 static uint32 cmd_set_options = 0xffffffff;
313 /****************************************************************************
314 process commands from the client
315 ****************************************************************************/
316 static uint32 do_command(struct client_info *info, char *line)
318 uint32 status = 0x0;
319 int i;
321 if (!get_cmd_args(line))
322 return False;
324 if (cmd_argc == 0)
325 return False;
327 i = process_tok(cmd_argv[0]);
328 if (i >= 0)
330 int argc = ((int)cmd_argc);
331 char **argv = cmd_argv;
332 optind = 0;
334 status = commands[i]->fn(info, argc, argv);
336 else if (i == -2)
338 fprintf(out_hnd, "%s: command abbreviation ambiguous\n",
339 CNV_LANG(cmd_argv[0]));
341 else
343 fprintf(out_hnd, "%s: command not found\n",
344 CNV_LANG(cmd_argv[0]));
347 free_char_array(cmd_argc, cmd_argv);
348 parse_talloc_free(); /* Free up init_XXX memory. */
350 return status;
354 /****************************************************************************
355 process commands from the client
356 ****************************************************************************/
357 static uint32 process(struct client_info *info, char *cmd_str)
359 uint32 status = 0;
360 pstring line;
361 char *cmd = cmd_str;
363 if (cmd != NULL)
365 while (cmd[0] != '\0')
367 char *p;
369 if ((p = strchr(cmd, ';')) == 0)
371 strncpy(line, cmd, 999);
372 line[1000] = '\0';
373 cmd += strlen(cmd);
375 else
377 if (p - cmd > 999)
378 p = cmd + 999;
379 strncpy(line, cmd, p - cmd);
380 line[p - cmd] = '\0';
381 cmd = p + 1;
384 /* input language code to internal one */
385 CNV_INPUT(line);
387 status = do_command(info, line);
388 if (status == 0x0)
390 continue;
394 else
396 while (!feof(stdin))
398 #ifdef HAVE_LIBREADLINE
399 char *ret_line;
400 #endif
401 pstring pline;
402 BOOL at_sym = False;
404 pline[0] = 0;
405 if (info->show_prompt)
407 safe_strcat(pline, "[", sizeof(pline) - 1);
408 if (usr.ntc.domain[0] != 0)
410 safe_strcat(pline, usr.ntc.domain,
411 sizeof(pline) - 1);
412 safe_strcat(pline, "\\", sizeof(pline) - 1);
413 at_sym = True;
415 if (usr.ntc.user_name[0] != 0)
417 safe_strcat(pline, usr.ntc.user_name,
418 sizeof(pline) - 1);
419 at_sym = True;
421 if (at_sym)
422 safe_strcat(pline, "@", sizeof(pline) - 1);
424 safe_strcat(pline, cli_info.dest_host,
425 sizeof(pline) - 1);
426 safe_strcat(pline, "]$ ", sizeof(pline) - 1);
428 #ifndef HAVE_LIBREADLINE
430 /* display a prompt */
431 fprintf(out_hnd, "%s", CNV_LANG(pline));
432 fflush(out_hnd);
434 cli_use_wait_keyboard();
436 /* and get a response */
437 if (!fgets(line, 1000, stdin))
439 break;
442 #else /* HAVE_LIBREADLINE */
444 if (!(ret_line = readline(pline)))
445 break;
446 safe_free(ret_line);
448 /* Copy read line to samba buffer */
450 pstrcpy(line, rl_line_buffer);
452 /* Add to history */
454 if (strlen(line) > 0)
455 add_history(line);
456 #endif
457 /* input language code to internal one */
458 CNV_INPUT(line);
460 /* special case - first char is ! */
461 if (*line == '!')
463 system(line + 1);
464 continue;
467 fprintf(out_hnd, "%s\n", line);
469 status = do_command(info, line);
470 if (status == 0x0)
472 continue;
476 return status;
479 /****************************************************************************
480 usage on the program
481 ****************************************************************************/
482 static void usage(char *pname)
484 fprintf(out_hnd,
485 "Usage: %s [\\server] [password] [-U user] -[W domain] [-l log] ",
486 pname);
488 fprintf(out_hnd, "\nVersion %s\n", VERSION);
489 fprintf(out_hnd, "\t-d debuglevel set the debuglevel\n");
490 fprintf(out_hnd,
491 "\t-S <\\>server Server to connect to\n");
492 fprintf(out_hnd,
493 "\t-l log basename. Basename for log/debug files\n");
494 fprintf(out_hnd,
495 "\t-n netbios name. Use this name as my netbios name\n");
496 fprintf(out_hnd,
497 "\t-N don't ask for a password\n");
498 fprintf(out_hnd,
499 "\t-m max protocol set the max protocol level\n");
500 fprintf(out_hnd,
501 "\t-I dest IP use this IP to connect to\n");
502 fprintf(out_hnd,
503 "\t-E write messages to stderr instead of stdout\n");
504 fprintf(out_hnd,
505 "\t-A filename file from which to read the authentication credentials\n");
506 fprintf(out_hnd,
507 "\t-P hide prompt (used for shell scripts)\n");
508 fprintf(out_hnd,
509 "\t-U username set the network username\n");
510 fprintf(out_hnd,
511 "\t-U username%%pass set the network username and password\n");
512 fprintf(out_hnd, "\t-W domain set the domain name\n");
513 fprintf(out_hnd,
514 "\t-c 'command string' execute semicolon separated commands\n");
515 fprintf(out_hnd,
516 "\t-t terminal code terminal i/o code {sjis|euc|jis7|jis8|junet|hex}\n");
517 fprintf(out_hnd, "\n");
520 #ifdef HAVE_LIBREADLINE
522 /****************************************************************************
523 GNU readline completion functions
524 ****************************************************************************/
526 /* Complete an rpcclient command */
528 static char *complete_cmd(char *text, int state)
530 static int cmd_index;
531 char *name;
533 /* Initialise */
535 if (state == 0)
536 cmd_index = 0;
538 /* Return the next name which partially matches the list of commands */
540 while ((cmd_index < num_commands)
541 && (strlen(name = commands[cmd_index++]->name) > 0))
543 if (strncmp(name, text, strlen(text)) == 0)
544 return strdup(name);
547 return NULL;
550 /* Main completion function */
552 static char **completion_fn(char *text, int start, int end)
554 pstring cmd_partial;
555 int cmd_index;
556 int num_words;
558 int i;
559 char lastch = ' ';
561 (void)get_cmd_args(rl_line_buffer);
563 safe_strcpy(cmd_partial, rl_line_buffer,
564 MAX(sizeof(cmd_partial), end) - 1);
566 /* Complete rpcclient command */
568 if (start == 0)
569 return completion_matches(text, complete_cmd);
571 /* Count # of words in command */
573 num_words = 0;
574 for (i = 0; i <= end; i++)
576 if ((rl_line_buffer[i] != ' ') && (lastch == ' '))
577 num_words++;
578 lastch = rl_line_buffer[i];
581 if (rl_line_buffer[end] == ' ')
582 num_words++;
584 /* Work out which command we are completing for */
586 for (cmd_index = 0; cmd_index < num_commands; cmd_index++)
589 /* Check each command in array */
591 if (strncmp(rl_line_buffer, commands[cmd_index]->name,
592 strlen(commands[cmd_index]->name)) == 0)
594 /* Call appropriate completion function */
596 if (num_words == 2 || num_words == 3)
598 char *(*fn) (char *, int);
599 fn = commands[cmd_index]->compl_args[num_words - 2];
600 if (fn != NULL)
601 return completion_matches(text, fn);
606 /* Eeek! */
607 return NULL;
610 /* To avoid filename completion being activated when no valid
611 completions are found, we assign this stub completion function
612 to the rl_completion_entry_function variable. */
614 static char *complete_cmd_null(char *text, int state)
616 return NULL;
619 #endif /* HAVE_LIBREADLINE */
621 static void set_user_password(struct ntuser_creds *u,
622 BOOL got_pass, char *password)
624 /* set the password cache info */
625 if (got_pass)
627 if (password == NULL)
629 DEBUG(10, ("set_user_password: NULL pwd\n"));
630 pwd_set_nullpwd(&u->pwd);
632 else
634 /* generate 16 byte hashes */
635 DEBUG(10, ("set_user_password: generate\n"));
636 if (lp_encrypted_passwords())
637 pwd_make_lm_nt_16(&u->pwd, password);
638 else
639 pwd_set_cleartext(&u->pwd, password);
642 else
644 DEBUG(10, ("set_user_password: read\n"));
645 pwd_read(&u->pwd, "Enter Password:", True);
649 static uint32 cmd_use(struct client_info *info, int argc, char *argv[])
651 int opt;
652 BOOL net_use = False;
653 BOOL net_use_add = True;
654 BOOL force_close = False;
655 fstring dest_host;
656 fstring srv_name;
657 BOOL null_pwd = False;
658 BOOL got_pwd = False;
659 pstring password;
662 if (usr_creds != NULL)
663 copy_nt_creds(&usr.ntc, &usr_creds->ntc);
664 else
665 copy_nt_creds(&usr.ntc, NULL);
667 pstrcpy(dest_host, cli_info.dest_host);
668 pstrcpy(usr.ntc.user_name, optarg);
669 info->reuse = False;
671 if (argc <= 1)
673 report(out_hnd,
674 "net [\\\\Server] [-U user%%pass] [-W domain] [-d] [-f]\n");
675 report(out_hnd, " -d Deletes a connection\n");
676 report(out_hnd, " -f Forcibly deletes a connection\n");
677 report(out_hnd, "net -u Shows all connections\n");
678 return 0;
681 if (argc > 1 && (*argv[1] != '-'))
683 if (strnequal("\\\\", argv[1], 2) ||
684 strnequal("//", argv[1], 2))
686 pstrcpy(dest_host, argv[1] + 2);
688 argc--;
689 argv++;
692 while ((opt = getopt(argc, argv, "udU:W:")) != EOF)
694 switch (opt)
696 case 'u':
698 net_use = True;
699 break;
702 case 'U':
704 char *lp;
705 pstrcpy(usr.ntc.user_name, optarg);
706 if ((lp = strchr(usr.ntc.user_name, '%')))
708 *lp = 0;
709 pstrcpy(password, lp + 1);
710 memset(strchr(optarg, '%') + 1, 'X',
711 strlen(password));
712 got_pwd = True;
714 if (usr.ntc.user_name[0] == 0
715 && password[0] == 0)
717 null_pwd = True;
719 break;
722 case 'N':
724 null_pwd = True;
726 case 'W':
728 pstrcpy(usr.ntc.domain, optarg);
729 break;
732 case 'd':
734 net_use_add = False;
735 break;
738 case 'f':
740 force_close = True;
741 break;
744 default:
746 report(out_hnd,
747 "net -S \\server [-U user%%pass] [-W domain] [-d] [-f]\n");
748 report(out_hnd, "net -u\n");
749 break;
754 if (strnequal("\\\\", dest_host, 2))
756 fstrcpy(srv_name, dest_host);
758 else
760 fstrcpy(srv_name, "\\\\");
761 fstrcat(srv_name, dest_host);
763 strupper(srv_name);
765 if (net_use)
767 int i;
768 uint32 num_uses;
769 struct use_info **use;
770 cli_net_use_enum(&num_uses, &use);
772 if (num_uses == 0)
774 report(out_hnd, "No connections\n");
776 else
778 report(out_hnd, "Connections:\n");
780 for (i = 0; i < num_uses; i++)
782 if (use[i] != NULL && use[i]->connected)
784 report(out_hnd, "Server:\t%s\t",use[i]->srv_name);
785 report(out_hnd, "Key:\t[%d,%x]\t",use[i]->key.pid, use[i]->key.vuid);
786 report(out_hnd, "User:\t%s\t", use[i]->user_name);
787 report(out_hnd, "Domain:\t%s\n", use[i]->domain);
792 else if (net_use_add)
794 BOOL isnew;
795 if (null_pwd)
796 set_user_password(&usr.ntc, True, NULL);
797 else
798 set_user_password(&usr.ntc, got_pwd, password);
800 /* paranoia: destroy the local copy of the password */
801 ZERO_STRUCT(password);
803 report(out_hnd, "Server:\t%s:\tUser:\t%s\tDomain:\t%s\n",
804 srv_name, usr.ntc.user_name, usr.ntc.domain);
805 report(out_hnd, "Connection:\t");
807 if (cli_net_use_add(srv_name, &usr.ntc, info->reuse, &isnew) != NULL)
808 report(out_hnd, "OK\n");
809 else
810 report(out_hnd, "FAILED\n");
812 else
814 BOOL closed;
815 report(out_hnd, "Server:\t%s:\tUser:\t%s\tDomain:\t%s\n",
816 srv_name, usr.ntc.user_name, usr.ntc.domain);
817 report(out_hnd, "Connection:\t");
819 if (!cli_net_use_del(srv_name, &usr.ntc, force_close, &closed))
820 report(out_hnd, ": Does not exist\n");
821 else if (force_close && closed)
822 report(out_hnd, ": Forcibly terminated\n");
823 else if (closed)
824 report(out_hnd, ": Terminated\n");
825 else
826 report(out_hnd, ": Unlinked\n");
829 /* paranoia: destroy the local copy of the password */
830 ZERO_STRUCT(password);
832 return 0;
835 /******************************************************************
836 allow or disallow automatic connections. rpctorture, because it
837 does not reestablish connections after sys_fork(), fails unless the
838 connection is established AFTER the sys_fork()
839 ******************************************************************/
840 static BOOL auto_connect = True;
841 void cmd_set_no_autoconnect(void)
843 auto_connect = False;
846 #define CMD_STR 0x1
847 #define CMD_DBF 0x2
848 #define CMD_SVC 0x4
849 #define CMD_TERM 0x8
850 #define CMD_PASS 0x10
851 #define CMD_USER 0x20
852 #define CMD_NOPW 0x40
853 #define CMD_DBLV 0x80
854 #define CMD_HELP 0x100
855 #define CMD_SOCK 0x200
856 #define CMD_IFACE 0x400
857 #define CMD_DOM 0x800
858 #define CMD_IP 0x1000
859 #define CMD_HOST 0x2000
860 #define CMD_NAME 0x4000
861 #define CMD_DBG 0x8000
862 #define CMD_SCOPE 0x10000
863 #define CMD_INTER 0x20000
865 static void read_authfile (char *filename, char* username, char* password)
867 FILE *auth;
868 fstring buf;
869 uint16 len = 0;
870 char *ptr, *val, *param;
872 if ((auth=sys_fopen(filename, "r")) == NULL)
874 /* fail if we can't open the credentials file */
875 DEBUG(0,("ERROR: Unable to open credentials file!\n"));
876 return;
879 while (!feof(auth))
881 /* get a line from the file */
882 if (!fgets (buf, sizeof(buf), auth))
883 continue;
885 len = strlen(buf);
887 /* skip empty lines */
888 if ((len) && (buf[len-1]=='\n'))
890 buf[len-1] = '\0';
891 len--;
893 if (len == 0)
894 continue;
896 /* break up the line into parameter & value.
897 will need to eat a little whitespace possibly */
898 param = buf;
899 if (!(ptr = strchr (buf, '=')))
900 continue;
901 val = ptr+1;
902 *ptr = '\0';
904 /* eat leading white space */
905 while ((*val!='\0') && ((*val==' ') || (*val=='\t')))
906 val++;
908 if (strwicmp("password", param) == 0)
910 pstrcpy(password, val);
911 cmd_set_options |= CMD_PASS;
913 else if (strwicmp("username", param) == 0)
915 pstrcpy(username, val);
916 cmd_set_options |= CMD_USER;
919 memset(buf, 0, sizeof(buf));
921 fclose(auth);
923 return;
926 static uint32 cmd_set(CLIENT_INFO *info, int argc, char *argv[])
928 BOOL interactive = True;
929 char *cmd_str = NULL;
930 int opt;
931 extern FILE *dbf;
932 extern char *optarg;
933 static pstring servicesf = CONFIGFILE;
934 pstring term_code;
935 pstring password; /* local copy only, if one is entered */
936 fstring srv_name;
937 int new_debuglevel = -1;
939 password[0] = 0;
940 usr_creds = &usr;
941 info->reuse = False;
942 #ifdef KANJI
943 pstrcpy(term_code, KANJI);
944 #else /* KANJI */
945 *term_code = 0;
946 #endif /* KANJI */
948 if (argc > 1 && (*argv[1] != '-'))
950 if (strnequal("\\\\", argv[1], 2) ||
951 strnequal("//", argv[1], 2))
953 cmd_set_options |= CMD_HOST;
954 pstrcpy(cli_info.dest_host, argv[1] + 2);
955 strupper(cli_info.dest_host);
957 argc--;
958 argv++;
961 if (argc > 1 && (*argv[1] != '-'))
963 cmd_set_options |= CMD_PASS;
964 pstrcpy(password, argv[1]);
965 memset(argv[1], 'X', strlen(argv[1]));
966 argc--;
967 argv++;
970 while ((opt = getopt(argc, argv,"PRs:O:M:S:i:Nn:d:l:hI:EB:U:L:t:m:W:T:D:c:A:")) != EOF)
972 switch (opt)
974 /* reuse connections in the case of a previous authentication */
975 case 'R':
977 info->reuse = True;
978 break;
981 /* max protocol */
982 case 'm':
984 /* FIXME ... max_protocol seems to be funny here */
986 int max_protocol = 0;
987 max_protocol = interpret_protocol(optarg, max_protocol);
988 fprintf(stderr, "max protocol not currently supported\n");
989 break;
992 /* socket options */
993 case 'O':
995 cmd_set_options |= CMD_SOCK;
996 pstrcpy(user_socket_options, optarg);
997 break;
1000 /* define the server to connect to */
1001 case 'S':
1003 cmd_set_options |= CMD_HOST;
1004 pstrcpy(cli_info.dest_host, optarg);
1005 strupper(cli_info.dest_host);
1006 break;
1009 /* username for the connection -- support the
1010 username%password format as well */
1011 case 'U':
1013 char *lp;
1014 cmd_set_options |= CMD_USER;
1015 pstrcpy(usr.ntc.user_name, optarg);
1016 if ((lp = strchr(usr.ntc.user_name, '%')))
1018 *lp = 0;
1019 pstrcpy(password, lp + 1);
1020 cmd_set_options |= CMD_PASS;
1021 memset(lp+1, 'X', strlen(password));
1023 break;
1026 /* authfile -- only get the username and password from the file */
1027 case 'A':
1029 read_authfile (optarg, usr.ntc.user_name, password);
1030 break;
1033 /* define the workgroup/domain name */
1034 case 'W':
1036 cmd_set_options |= CMD_DOM;
1037 pstrcpy(usr.ntc.domain, optarg);
1038 break;
1041 /* should we display a command prompt at all */
1042 case 'P':
1043 { /* optarg == prompt string ? */
1044 info->show_prompt = False;
1045 break;
1048 /* send to stderr instaed of stdout */
1049 case 'E':
1051 cmd_set_options |= CMD_DBG;
1052 dbf = stderr;
1053 break;
1056 /* IP address of destination host */
1057 case 'I':
1059 cmd_set_options |= CMD_IP;
1060 cli_info.dest_ip = *interpret_addr2(optarg);
1061 if (zero_ip(cli_info.dest_ip))
1063 free_connections();
1064 exit(1);
1066 break;
1069 /* define netbios name of client machine we are on */
1070 case 'n':
1072 cmd_set_options |= CMD_NAME;
1073 fstrcpy(global_myname, optarg);
1074 break;
1077 /* do not prompt for a password. Implies anonymous connection
1078 unless the password was passed in username%password form */
1079 case 'N':
1081 cmd_set_options |= CMD_NOPW | CMD_PASS;
1082 break;
1085 /* debug level */
1086 case 'd':
1088 cmd_set_options |= CMD_DBLV;
1089 if (*optarg == 'A')
1090 new_debuglevel = 10000;
1091 else
1092 new_debuglevel = atoi(optarg);
1093 break;
1096 /* log file name */
1097 case 'l':
1099 cmd_set_options |= CMD_INTER;
1100 slprintf(debugf, sizeof(debugf) - 1, "%s.client", optarg);
1101 interactive = False;
1102 break;
1105 /* command string to be executed */
1106 case 'c':
1108 cmd_set_options |= CMD_STR;
1109 cmd_str = optarg;
1110 break;
1113 /* program usage/help screen */
1114 case 'h':
1116 cmd_set_options |= CMD_HELP;
1117 usage(argv[0]);
1118 break;
1121 /* config file to use */
1122 case 's':
1124 cmd_set_options |= CMD_SVC;
1125 pstrcpy(servicesf, optarg);
1126 break;
1129 /* terminal code */
1130 case 't':
1132 cmd_set_options |= CMD_TERM;
1133 pstrcpy(term_code, optarg);
1134 break;
1137 default:
1139 cmd_set_options |= CMD_HELP;
1140 usage(argv[0]);
1141 break;
1147 if (cmd_set_options & CMD_INTER)
1149 setup_logging(debugf, interactive);
1150 if (!interactive)
1151 reopen_logs();
1154 strupper(global_myname);
1155 fstrcpy(cli_info.myhostname, global_myname);
1157 if (cmd_set_options & CMD_SVC)
1159 if (!lp_load(servicesf, True, False, False))
1161 fprintf(stderr, "Can't load %s - run testparm to debug it\n",
1162 servicesf);
1167 if (new_debuglevel != -1) {
1168 DEBUGLEVEL = new_debuglevel;
1171 if (cmd_set_options & CMD_INTER)
1173 load_interfaces();
1176 DEBUG(10, ("cmd_set: options: %x\n", cmd_set_options));
1178 if (cmd_set_options & CMD_HELP) {
1179 return 0;
1182 /* NULL password if specified or is username is empty */
1183 if ((cmd_set_options & CMD_NOPW) || (strlen(usr.ntc.user_name) == 0))
1184 set_user_password(&usr.ntc, True, NULL);
1185 else
1186 set_user_password(&usr.ntc, ((cmd_set_options & CMD_PASS) != 0), password);
1188 /* paranoia: destroy the local copy of the password */
1189 ZERO_STRUCT(password);
1191 if (strcmp(cli_info.dest_host, "*") == 0)
1193 /* special case - we want the PDC */
1194 struct in_addr ip;
1195 if (!resolve_srv_name(cli_info.dest_host, cli_info.dest_host, &ip)) {
1196 report(out_hnd, "ERROR: Failed to find the PDC\n");
1197 return 1;
1201 fstrcpy(srv_name, "\\\\");
1202 fstrcat(srv_name, cli_info.dest_host);
1203 strupper(srv_name);
1206 if (auto_connect)
1208 BOOL isnew;
1209 report(out_hnd, "Server:\t%s:\tUser:\t%s\tDomain:\t%s\n",
1210 srv_name, usr.ntc.user_name, usr.ntc.domain);
1211 report(out_hnd, "Connection:\t");
1213 if (cli_net_use_add(srv_name, &usr.ntc, info->reuse, &isnew) != NULL)
1215 report(out_hnd, "OK\n");
1217 else
1219 report(out_hnd, "FAILED\n");
1221 /* ???? --jerry
1222 usr_creds = NULL; */
1225 if (cmd_str != NULL)
1226 return process(&cli_info, cmd_str);
1228 return 0;
1231 static void read_user_env(struct ntuser_creds *u)
1233 pstring password;
1235 password[0] = 0;
1237 if (getenv("USER"))
1239 char *p;
1240 pstrcpy(u->user_name, getenv("USER"));
1242 /* modification to support userid%passwd syntax in the USER var
1243 25.Aug.97, jdblair@uab.edu */
1245 if ((p = strchr(u->user_name, '%')))
1247 *p = 0;
1248 pstrcpy(password, p + 1);
1249 memset(strchr(getenv("USER"), '%') + 1, 'X',
1250 strlen(password));
1254 /* modification to support PASSWD environmental var
1255 25.Aug.97, jdblair@uab.edu */
1256 if (getenv("PASSWD"))
1257 pstrcpy(password, getenv("PASSWD"));
1259 if (*u->user_name == 0 && getenv("LOGNAME"))
1260 pstrcpy(u->user_name, getenv("LOGNAME"));
1262 set_user_password(u, True, password);
1264 /* paranoia: destroy the local copy of the password */
1265 ZERO_STRUCT(password);
1268 static void readline_init(void)
1270 #ifdef HAVE_LIBREADLINE
1271 /* Initialise GNU Readline */ rl_readline_name = "rpcclient";
1272 rl_attempted_completion_function = completion_fn;
1273 rl_completion_entry_function = (Function *) complete_cmd_null;
1275 /* Initialise history list */
1277 using_history();
1279 #else
1280 int x;
1281 x = 0; /* stop compiler warnings */
1282 #endif /* HAVE_LIBREADLINE */
1285 /****************************************************************************
1286 main program
1287 ****************************************************************************/
1288 int command_main(int argc, char *argv[])
1290 uint32 status;
1291 mode_t myumask = 0755;
1292 char progname[255], path[255], *s;
1293 pstring msg;
1295 DEBUGLEVEL = 2;
1297 charset_initialise();
1299 /* add in the internal command set and the various
1300 client RPC groups--spoolss, lsa, etc... */
1301 add_command_set(general_commands);
1303 /* usr_creds is a global most recently used set of user credentials
1304 retrieved from the connection list. */
1305 copy_user_creds(&usr, NULL);
1306 usr_creds = &usr;
1307 usr.ptr_ntc = 1;
1309 out_hnd = stdout;
1311 /* retrieve the binary name used when invoking the program
1312 for instances like samedit, etc... */
1313 strncpy(path, argv[0], 255);
1314 for (s = strtok(path, "/"); s; s = strtok(NULL, "/"))
1315 fstrcpy(progname, s);
1317 slprintf(debugf, sizeof(debugf) - 1,
1318 "%s/log.%s", LOGFILEBASE, progname);
1320 /* initialize usr */
1321 pstrcpy(usr.ntc.domain, "");
1322 pstrcpy(usr.ntc.user_name, "");
1323 pstrcpy(cli_info.myhostname, "");
1324 pstrcpy(cli_info.dest_host, "");
1326 /* init client_info struct */
1327 cli_info.dest_ip.s_addr = 0;
1328 cli_info.show_prompt = True;
1329 ZERO_STRUCT(cli_info.dom.level3_sid);
1330 ZERO_STRUCT(cli_info.dom.level5_sid);
1331 fstrcpy(cli_info.dom.level3_dom, "");
1332 fstrcpy(cli_info.dom.level5_dom, "");
1334 readline_init();
1335 TimeInit();
1336 init_connections();
1338 myumask = umask(0);
1339 umask(myumask);
1341 if (!get_myname(global_myname))
1343 fprintf(stderr, "Failed to get my hostname.\n");
1346 if (argc < 2)
1348 usage(argv[0]);
1349 free_connections();
1350 exit(1);
1353 read_user_env(&usr.ntc);
1355 cmd_set_options &= ~CMD_HELP;
1356 cmd_set_options &= ~CMD_STR;
1357 cmd_set_options &= ~CMD_NOPW;
1358 cmd_set_options &= ~CMD_USER;
1359 cmd_set_options &= ~CMD_PASS;
1361 codepage_initialise(lp_client_code_page());
1363 /* parse the command line args
1364 init the first connection if possible
1365 process a command if passed in on the command line */
1366 status = cmd_set(&cli_info, argc, argv);
1368 /* Should we exit? Are we done? */
1369 if (cmd_set_options & (CMD_HELP|CMD_STR)) {
1370 free_connections();
1371 get_safe_nt_error_msg(status, msg, sizeof(msg));
1373 report(out_hnd, "Exit Status: %s\n", msg);
1374 /* unix only has 8 bit error codes - blergh */
1375 exit(status & 0xFF);
1378 DEBUG(3, ("%s client started (version %s)\n",
1379 timestring(False), VERSION));
1381 /* enter shell mode */
1382 status = process(&cli_info, NULL);
1384 /* cleanup */
1385 free_connections();
1386 free_cmd_set_array(num_commands, commands);
1387 num_commands = 0;
1388 commands = NULL;
1390 /* report and exit */
1391 get_safe_nt_error_msg(status, msg, sizeof(msg));
1392 report(out_hnd, "Exit Status: %s\n", msg);
1393 return status;