2 Unix SMB/Netbios implementation.
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.
29 #include "rpc_parse.h"
30 #include "rpc_client.h"
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
;
67 static void cmd_set_free(struct command_set
*item
)
70 safe_free(item
->name
);
75 static struct command_set
*cmd_set_dup(const struct command_set
*from
)
79 struct command_set
*copy
;
81 copy
= (struct command_set
*)malloc(sizeof(struct command_set
));
84 memcpy(copy
, from
, sizeof(struct command_set
));
85 if (from
->name
!= NULL
)
86 copy
->name
= strdup(from
->name
);
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
,
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
);
124 /****************************************************************************
125 This defines the commands supported by this client
126 ****************************************************************************/
127 static struct command_set general_commands
[] = {
132 {"General", NULL
, NULL
, {NULL
, NULL
}},
135 "run rpcclient inside rpcclient (change options etc.)",
140 "net use and net view",
170 "[command] give help on a command",
174 "[command] give help on a command",
183 "run a shell command on the local system",
197 /****************************************************************************
198 do a (presumably graceful) quit...
199 ****************************************************************************/
200 static uint32
cmd_quit(struct client_info
*info
, int argc
, char *argv
[])
205 smb_mem_write_status(dbf
);
206 smb_mem_write_errors(dbf
);
207 smb_mem_write_verbose(dbf
);
219 /****************************************************************************
221 ****************************************************************************/
222 static uint32
cmd_help(struct client_info
*info
, int argc
, char *argv
[])
226 /* get help on a specific command */
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
);
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");
244 fprintf (out_hnd
, "\t");
246 fprintf(out_hnd
, "%s\n", commands
[i
]->name
);
252 /*******************************************************************
253 lookup a command string in the list of commands, including
255 ******************************************************************/
256 static int process_tok(char *tok
)
258 int i
= 0, matches
= 0;
260 int tok_len
= strlen(tok
);
262 for (i
= 0; i
< num_commands
; i
++)
264 if (strequal(commands
[i
]->name
, tok
))
270 else if (strnequal(commands
[i
]->name
, tok
, tok_len
))
279 else if (matches
== 1)
285 /****************************************************************************
286 turn command line into command argument array
287 ****************************************************************************/
288 static BOOL
get_cmd_args(char *line
)
295 /* get the first part of the command */
296 if (!next_token(&ptr
, tok
, NULL
, sizeof(tok
)))
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
);
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
)
321 if (!get_cmd_args(line
))
327 i
= process_tok(cmd_argv
[0]);
330 int argc
= ((int)cmd_argc
);
331 char **argv
= cmd_argv
;
334 status
= commands
[i
]->fn(info
, argc
, argv
);
338 fprintf(out_hnd
, "%s: command abbreviation ambiguous\n",
339 CNV_LANG(cmd_argv
[0]));
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. */
354 /****************************************************************************
355 process commands from the client
356 ****************************************************************************/
357 static uint32
process(struct client_info
*info
, char *cmd_str
)
365 while (cmd
[0] != '\0')
369 if ((p
= strchr(cmd
, ';')) == 0)
371 strncpy(line
, cmd
, 999);
379 strncpy(line
, cmd
, p
- cmd
);
380 line
[p
- cmd
] = '\0';
384 /* input language code to internal one */
387 status
= do_command(info
, line
);
398 #ifdef HAVE_LIBREADLINE
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
,
412 safe_strcat(pline
, "\\", sizeof(pline
) - 1);
415 if (usr
.ntc
.user_name
[0] != 0)
417 safe_strcat(pline
, usr
.ntc
.user_name
,
422 safe_strcat(pline
, "@", sizeof(pline
) - 1);
424 safe_strcat(pline
, cli_info
.dest_host
,
426 safe_strcat(pline
, "]$ ", sizeof(pline
) - 1);
428 #ifndef HAVE_LIBREADLINE
430 /* display a prompt */
431 fprintf(out_hnd
, "%s", CNV_LANG(pline
));
434 cli_use_wait_keyboard();
436 /* and get a response */
437 if (!fgets(line
, 1000, stdin
))
442 #else /* HAVE_LIBREADLINE */
444 if (!(ret_line
= readline(pline
)))
448 /* Copy read line to samba buffer */
450 pstrcpy(line
, rl_line_buffer
);
454 if (strlen(line
) > 0)
457 /* input language code to internal one */
460 /* special case - first char is ! */
467 fprintf(out_hnd
, "%s\n", line
);
469 status
= do_command(info
, line
);
479 /****************************************************************************
481 ****************************************************************************/
482 static void usage(char *pname
)
485 "Usage: %s [\\server] [password] [-U user] -[W domain] [-l log] ",
488 fprintf(out_hnd
, "\nVersion %s\n", VERSION
);
489 fprintf(out_hnd
, "\t-d debuglevel set the debuglevel\n");
491 "\t-S <\\>server Server to connect to\n");
493 "\t-l log basename. Basename for log/debug files\n");
495 "\t-n netbios name. Use this name as my netbios name\n");
497 "\t-N don't ask for a password\n");
499 "\t-m max protocol set the max protocol level\n");
501 "\t-I dest IP use this IP to connect to\n");
503 "\t-E write messages to stderr instead of stdout\n");
505 "\t-A filename file from which to read the authentication credentials\n");
507 "\t-P hide prompt (used for shell scripts)\n");
509 "\t-U username set the network username\n");
511 "\t-U username%%pass set the network username and password\n");
512 fprintf(out_hnd
, "\t-W domain set the domain name\n");
514 "\t-c 'command string' execute semicolon separated commands\n");
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
;
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)
550 /* Main completion function */
552 static char **completion_fn(char *text
, int start
, int end
)
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 */
569 return completion_matches(text
, complete_cmd
);
571 /* Count # of words in command */
574 for (i
= 0; i
<= end
; i
++)
576 if ((rl_line_buffer
[i
] != ' ') && (lastch
== ' '))
578 lastch
= rl_line_buffer
[i
];
581 if (rl_line_buffer
[end
] == ' ')
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];
601 return completion_matches(text
, fn
);
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
)
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 */
627 if (password
== NULL
)
629 DEBUG(10, ("set_user_password: NULL pwd\n"));
630 pwd_set_nullpwd(&u
->pwd
);
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
);
639 pwd_set_cleartext(&u
->pwd
, password
);
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
[])
652 BOOL net_use
= False
;
653 BOOL net_use_add
= True
;
654 BOOL force_close
= False
;
657 BOOL null_pwd
= False
;
658 BOOL got_pwd
= False
;
662 if (usr_creds
!= NULL
)
663 copy_nt_creds(&usr
.ntc
, &usr_creds
->ntc
);
665 copy_nt_creds(&usr
.ntc
, NULL
);
667 pstrcpy(dest_host
, cli_info
.dest_host
);
668 pstrcpy(usr
.ntc
.user_name
, optarg
);
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");
681 if (argc
> 1 && (*argv
[1] != '-'))
683 if (strnequal("\\\\", argv
[1], 2) ||
684 strnequal("//", argv
[1], 2))
686 pstrcpy(dest_host
, argv
[1] + 2);
692 while ((opt
= getopt(argc
, argv
, "udU:W:")) != EOF
)
705 pstrcpy(usr
.ntc
.user_name
, optarg
);
706 if ((lp
= strchr(usr
.ntc
.user_name
, '%')))
709 pstrcpy(password
, lp
+ 1);
710 memset(strchr(optarg
, '%') + 1, 'X',
714 if (usr
.ntc
.user_name
[0] == 0
728 pstrcpy(usr
.ntc
.domain
, optarg
);
747 "net -S \\server [-U user%%pass] [-W domain] [-d] [-f]\n");
748 report(out_hnd
, "net -u\n");
754 if (strnequal("\\\\", dest_host
, 2))
756 fstrcpy(srv_name
, dest_host
);
760 fstrcpy(srv_name
, "\\\\");
761 fstrcat(srv_name
, dest_host
);
769 struct use_info
**use
;
770 cli_net_use_enum(&num_uses
, &use
);
774 report(out_hnd
, "No connections\n");
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
)
796 set_user_password(&usr
.ntc
, True
, NULL
);
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");
810 report(out_hnd
, "FAILED\n");
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");
824 report(out_hnd
, ": Terminated\n");
826 report(out_hnd
, ": Unlinked\n");
829 /* paranoia: destroy the local copy of the password */
830 ZERO_STRUCT(password
);
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
;
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
)
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"));
881 /* get a line from the file */
882 if (!fgets (buf
, sizeof(buf
), auth
))
887 /* skip empty lines */
888 if ((len
) && (buf
[len
-1]=='\n'))
896 /* break up the line into parameter & value.
897 will need to eat a little whitespace possibly */
899 if (!(ptr
= strchr (buf
, '=')))
904 /* eat leading white space */
905 while ((*val
!='\0') && ((*val
==' ') || (*val
=='\t')))
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
));
926 static uint32
cmd_set(CLIENT_INFO
*info
, int argc
, char *argv
[])
928 BOOL interactive
= True
;
929 char *cmd_str
= NULL
;
933 static pstring servicesf
= CONFIGFILE
;
935 pstring password
; /* local copy only, if one is entered */
937 int new_debuglevel
= -1;
943 pstrcpy(term_code
, 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
);
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]));
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
)
974 /* reuse connections in the case of a previous authentication */
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");
995 cmd_set_options
|= CMD_SOCK
;
996 pstrcpy(user_socket_options
, optarg
);
1000 /* define the server to connect to */
1003 cmd_set_options
|= CMD_HOST
;
1004 pstrcpy(cli_info
.dest_host
, optarg
);
1005 strupper(cli_info
.dest_host
);
1009 /* username for the connection -- support the
1010 username%password format as well */
1014 cmd_set_options
|= CMD_USER
;
1015 pstrcpy(usr
.ntc
.user_name
, optarg
);
1016 if ((lp
= strchr(usr
.ntc
.user_name
, '%')))
1019 pstrcpy(password
, lp
+ 1);
1020 cmd_set_options
|= CMD_PASS
;
1021 memset(lp
+1, 'X', strlen(password
));
1026 /* authfile -- only get the username and password from the file */
1029 read_authfile (optarg
, usr
.ntc
.user_name
, password
);
1033 /* define the workgroup/domain name */
1036 cmd_set_options
|= CMD_DOM
;
1037 pstrcpy(usr
.ntc
.domain
, optarg
);
1041 /* should we display a command prompt at all */
1043 { /* optarg == prompt string ? */
1044 info
->show_prompt
= False
;
1048 /* send to stderr instaed of stdout */
1051 cmd_set_options
|= CMD_DBG
;
1056 /* IP address of destination host */
1059 cmd_set_options
|= CMD_IP
;
1060 cli_info
.dest_ip
= *interpret_addr2(optarg
);
1061 if (zero_ip(cli_info
.dest_ip
))
1069 /* define netbios name of client machine we are on */
1072 cmd_set_options
|= CMD_NAME
;
1073 fstrcpy(global_myname
, optarg
);
1077 /* do not prompt for a password. Implies anonymous connection
1078 unless the password was passed in username%password form */
1081 cmd_set_options
|= CMD_NOPW
| CMD_PASS
;
1088 cmd_set_options
|= CMD_DBLV
;
1090 new_debuglevel
= 10000;
1092 new_debuglevel
= atoi(optarg
);
1099 cmd_set_options
|= CMD_INTER
;
1100 slprintf(debugf
, sizeof(debugf
) - 1, "%s.client", optarg
);
1101 interactive
= False
;
1105 /* command string to be executed */
1108 cmd_set_options
|= CMD_STR
;
1113 /* program usage/help screen */
1116 cmd_set_options
|= CMD_HELP
;
1121 /* config file to use */
1124 cmd_set_options
|= CMD_SVC
;
1125 pstrcpy(servicesf
, optarg
);
1132 cmd_set_options
|= CMD_TERM
;
1133 pstrcpy(term_code
, optarg
);
1139 cmd_set_options
|= CMD_HELP
;
1147 if (cmd_set_options
& CMD_INTER
)
1149 setup_logging(debugf
, interactive
);
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",
1167 if (new_debuglevel
!= -1) {
1168 DEBUGLEVEL
= new_debuglevel
;
1171 if (cmd_set_options
& CMD_INTER
)
1176 DEBUG(10, ("cmd_set: options: %x\n", cmd_set_options
));
1178 if (cmd_set_options
& CMD_HELP
) {
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
);
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 */
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");
1201 fstrcpy(srv_name
, "\\\\");
1202 fstrcat(srv_name
, cli_info
.dest_host
);
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");
1219 report(out_hnd
, "FAILED\n");
1222 usr_creds = NULL; */
1225 if (cmd_str
!= NULL
)
1226 return process(&cli_info
, cmd_str
);
1231 static void read_user_env(struct ntuser_creds
*u
)
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
, '%')))
1248 pstrcpy(password
, p
+ 1);
1249 memset(strchr(getenv("USER"), '%') + 1, 'X',
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 */
1281 x
= 0; /* stop compiler warnings */
1282 #endif /* HAVE_LIBREADLINE */
1285 /****************************************************************************
1287 ****************************************************************************/
1288 int command_main(int argc
, char *argv
[])
1291 mode_t myumask
= 0755;
1292 char progname
[255], path
[255], *s
;
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
);
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
, "");
1341 if (!get_myname(global_myname
))
1343 fprintf(stderr
, "Failed to get my hostname.\n");
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
)) {
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
);
1386 free_cmd_set_array(num_commands
, commands
);
1390 /* report and exit */
1391 get_safe_nt_error_msg(status
, msg
, sizeof(msg
));
1392 report(out_hnd
, "Exit Status: %s\n", msg
);