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"
35 extern pstring debugf
;
36 extern pstring global_myname
;
38 extern pstring user_socket_options
;
40 /* found in rpc_client/cli_connect.c */
41 extern struct user_creds
*usr_creds
;
44 extern int DEBUGLEVEL
;
47 #define CNV_LANG(s) dos2unix_format(s,False)
48 #define CNV_INPUT(s) unix2dos_format(s,True)
50 static int process_tok(fstring tok
);
51 static uint32
cmd_help(struct client_info
*info
, int argc
, char *argv
[]);
52 static uint32
cmd_quit(struct client_info
*info
, int argc
, char *argv
[]);
53 static uint32
cmd_set(struct client_info
*info
, int argc
, char *argv
[]);
54 static uint32
cmd_use(struct client_info
*info
, int argc
, char *argv
[]);
56 static struct user_creds usr
;
58 struct client_info cli_info
;
60 char **cmd_argv
= NULL
;
66 static void cmd_set_free(struct command_set
*item
)
69 safe_free(item
->name
);
74 static struct command_set
*cmd_set_dup(const struct command_set
*from
)
78 struct command_set
*copy
;
80 copy
= (struct command_set
*)malloc(sizeof(struct command_set
));
83 memcpy(copy
, from
, sizeof(struct command_set
));
84 if (from
->name
!= NULL
)
85 copy
->name
= strdup(from
->name
);
92 void free_cmd_set_array(uint32 num_entries
, struct command_set
**entries
)
94 void (*fn
) (void *) = (void (*)(void *))&cmd_set_free
;
95 free_void_array(num_entries
, (void **)entries
, *fn
);
98 struct command_set
*add_cmd_set_to_array(uint32
*len
, struct command_set
***array
,
99 const struct command_set
*cmd
)
101 void *(*fn
) (const void *) = (void *(*)(const void *))&cmd_set_dup
;
102 return (struct command_set
*)add_copy_to_array(len
, (void ***)array
,
103 (const void *)cmd
, *fn
,
108 static struct command_set
**commands
= NULL
;
109 static uint32 num_commands
= 0;
111 /****************************************************************************
112 add in individual command-sets.
113 ****************************************************************************/
114 void add_command_set(const struct command_set
*cmds
)
116 while (! ((cmds
->fn
==NULL
) && (strlen(cmds
->name
)==0)))
118 add_cmd_set_to_array(&num_commands
, &commands
, cmds
);
123 /****************************************************************************
124 This defines the commands supported by this client
125 ****************************************************************************/
126 static struct command_set general_commands
[] = {
131 {"General", NULL
, NULL
, {NULL
, NULL
}},
134 "run rpcclient inside rpcclient (change options etc.)",
139 "net use and net view",
169 "[command] give help on a command",
173 "[command] give help on a command",
182 "run a shell command on the local system",
196 /****************************************************************************
197 do a (presumably graceful) quit...
198 ****************************************************************************/
199 static uint32
cmd_quit(struct client_info
*info
, int argc
, char *argv
[])
204 smb_mem_write_status(dbf
);
205 smb_mem_write_errors(dbf
);
206 smb_mem_write_verbose(dbf
);
218 /****************************************************************************
220 ****************************************************************************/
221 static uint32
cmd_help(struct client_info
*info
, int argc
, char *argv
[])
225 /* get help on a specific command */
228 if ((i
= process_tok(argv
[0])) >= 0)
230 fprintf(out_hnd
, "HELP %s:\n\t%s\n\n", commands
[i
]->name
,
231 commands
[i
]->description
);
237 /* Print out the list of available commands */
238 for (i
= 0; i
< num_commands
; i
++)
240 if (commands
[i
]->fn
== NULL
)
241 fprintf (out_hnd
, "\n");
243 fprintf (out_hnd
, "\t");
245 fprintf(out_hnd
, "%s\n", commands
[i
]->name
);
251 /*******************************************************************
252 lookup a command string in the list of commands, including
254 ******************************************************************/
255 static int process_tok(char *tok
)
257 int i
= 0, matches
= 0;
259 int tok_len
= strlen(tok
);
261 for (i
= 0; i
< num_commands
; i
++)
263 if (strequal(commands
[i
]->name
, tok
))
269 else if (strnequal(commands
[i
]->name
, tok
, tok_len
))
278 else if (matches
== 1)
284 /****************************************************************************
285 turn command line into command argument array
286 ****************************************************************************/
287 static BOOL
get_cmd_args(char *line
)
294 /* get the first part of the command */
295 if (!next_token(&ptr
, tok
, NULL
, sizeof(tok
)))
300 add_chars_to_array(&cmd_argc
, &cmd_argv
, tok
);
302 while (next_token(NULL
, tok
, NULL
, sizeof(tok
)));
304 add_chars_to_array(&cmd_argc
, &cmd_argv
, NULL
);
309 /* command options mask */
310 static uint32 cmd_set_options
= 0xffffffff;
312 /****************************************************************************
313 process commands from the client
314 ****************************************************************************/
315 static uint32
do_command(struct client_info
*info
, char *line
)
320 if (!get_cmd_args(line
))
326 i
= process_tok(cmd_argv
[0]);
329 int argc
= ((int)cmd_argc
);
330 char **argv
= cmd_argv
;
333 status
= commands
[i
]->fn(info
, argc
, argv
);
337 fprintf(out_hnd
, "%s: command abbreviation ambiguous\n",
338 CNV_LANG(cmd_argv
[0]));
342 fprintf(out_hnd
, "%s: command not found\n",
343 CNV_LANG(cmd_argv
[0]));
346 free_char_array(cmd_argc
, cmd_argv
);
347 parse_talloc_free(); /* Free up init_XXX memory. */
353 /****************************************************************************
354 process commands from the client
355 ****************************************************************************/
356 static uint32
process(struct client_info
*info
, char *cmd_str
)
364 while (cmd
[0] != '\0')
368 if ((p
= strchr(cmd
, ';')) == 0)
370 strncpy(line
, cmd
, 999);
378 strncpy(line
, cmd
, p
- cmd
);
379 line
[p
- cmd
] = '\0';
383 /* input language code to internal one */
386 status
= do_command(info
, line
);
397 #ifdef HAVE_LIBREADLINE
404 if (info
->show_prompt
)
406 safe_strcat(pline
, "[", sizeof(pline
) - 1);
407 if (usr
.ntc
.domain
[0] != 0)
409 safe_strcat(pline
, usr
.ntc
.domain
,
411 safe_strcat(pline
, "\\", sizeof(pline
) - 1);
414 if (usr
.ntc
.user_name
[0] != 0)
416 safe_strcat(pline
, usr
.ntc
.user_name
,
421 safe_strcat(pline
, "@", sizeof(pline
) - 1);
423 safe_strcat(pline
, cli_info
.dest_host
,
425 safe_strcat(pline
, "]$ ", sizeof(pline
) - 1);
427 #ifndef HAVE_LIBREADLINE
429 /* display a prompt */
430 fprintf(out_hnd
, "%s", CNV_LANG(pline
));
433 cli_use_wait_keyboard();
435 /* and get a response */
436 if (!fgets(line
, 1000, stdin
))
441 #else /* HAVE_LIBREADLINE */
443 if (!(ret_line
= readline(pline
)))
447 /* Copy read line to samba buffer */
449 pstrcpy(line
, rl_line_buffer
);
453 if (strlen(line
) > 0)
456 /* input language code to internal one */
459 /* special case - first char is ! */
466 fprintf(out_hnd
, "%s\n", line
);
468 status
= do_command(info
, line
);
478 /****************************************************************************
480 ****************************************************************************/
481 static void usage(char *pname
)
484 "Usage: %s [\\server] [password] [-U user] -[W domain] [-l log] ",
487 fprintf(out_hnd
, "\nVersion %s\n", VERSION
);
488 fprintf(out_hnd
, "\t-d debuglevel set the debuglevel\n");
490 "\t-S <\\>server Server to connect to\n");
492 "\t-l log basename. Basename for log/debug files\n");
494 "\t-n netbios name. Use this name as my netbios name\n");
496 "\t-N don't ask for a password\n");
498 "\t-m max protocol set the max protocol level\n");
500 "\t-I dest IP use this IP to connect to\n");
502 "\t-E write messages to stderr instead of stdout\n");
504 "\t-A filename file from which to read the authentication credentials\n");
506 "\t-P hide prompt (used for shell scripts)\n");
508 "\t-U username set the network username\n");
510 "\t-U username%%pass set the network username and password\n");
511 fprintf(out_hnd
, "\t-W domain set the domain name\n");
513 "\t-c 'command string' execute semicolon separated commands\n");
515 "\t-t terminal code terminal i/o code {sjis|euc|jis7|jis8|junet|hex}\n");
516 fprintf(out_hnd
, "\n");
519 #ifdef HAVE_LIBREADLINE
521 /****************************************************************************
522 GNU readline completion functions
523 ****************************************************************************/
525 /* Complete an rpcclient command */
527 static char *complete_cmd(char *text
, int state
)
529 static int cmd_index
;
537 /* Return the next name which partially matches the list of commands */
539 while ((cmd_index
< num_commands
)
540 && (strlen(name
= commands
[cmd_index
++]->name
) > 0))
542 if (strncmp(name
, text
, strlen(text
)) == 0)
549 /* Main completion function */
551 static char **completion_fn(char *text
, int start
, int end
)
560 (void)get_cmd_args(rl_line_buffer
);
562 safe_strcpy(cmd_partial
, rl_line_buffer
,
563 MAX(sizeof(cmd_partial
), end
) - 1);
565 /* Complete rpcclient command */
568 return completion_matches(text
, complete_cmd
);
570 /* Count # of words in command */
573 for (i
= 0; i
<= end
; i
++)
575 if ((rl_line_buffer
[i
] != ' ') && (lastch
== ' '))
577 lastch
= rl_line_buffer
[i
];
580 if (rl_line_buffer
[end
] == ' ')
583 /* Work out which command we are completing for */
585 for (cmd_index
= 0; cmd_index
< num_commands
; cmd_index
++)
588 /* Check each command in array */
590 if (strncmp(rl_line_buffer
, commands
[cmd_index
]->name
,
591 strlen(commands
[cmd_index
]->name
)) == 0)
593 /* Call appropriate completion function */
595 if (num_words
== 2 || num_words
== 3)
597 char *(*fn
) (char *, int);
598 fn
= commands
[cmd_index
]->compl_args
[num_words
- 2];
600 return completion_matches(text
, fn
);
609 /* To avoid filename completion being activated when no valid
610 completions are found, we assign this stub completion function
611 to the rl_completion_entry_function variable. */
613 static char *complete_cmd_null(char *text
, int state
)
618 #endif /* HAVE_LIBREADLINE */
620 static void set_user_password(struct ntuser_creds
*u
,
621 BOOL got_pass
, char *password
)
623 /* set the password cache info */
626 if (password
== NULL
)
628 DEBUG(10, ("set_user_password: NULL pwd\n"));
629 pwd_set_nullpwd(&u
->pwd
);
633 /* generate 16 byte hashes */
634 DEBUG(10, ("set_user_password: generate\n"));
635 if (lp_encrypted_passwords())
636 pwd_make_lm_nt_16(&u
->pwd
, password
);
638 pwd_set_cleartext(&u
->pwd
, password
);
643 DEBUG(10, ("set_user_password: read\n"));
644 pwd_read(&u
->pwd
, "Enter Password:", True
);
648 static uint32
cmd_use(struct client_info
*info
, int argc
, char *argv
[])
651 BOOL net_use
= False
;
652 BOOL net_use_add
= True
;
653 BOOL force_close
= False
;
656 BOOL null_pwd
= False
;
657 BOOL got_pwd
= False
;
661 if (usr_creds
!= NULL
)
662 copy_nt_creds(&usr
.ntc
, &usr_creds
->ntc
);
664 copy_nt_creds(&usr
.ntc
, NULL
);
666 pstrcpy(dest_host
, cli_info
.dest_host
);
667 pstrcpy(usr
.ntc
.user_name
, optarg
);
673 "net [\\\\Server] [-U user%%pass] [-W domain] [-d] [-f]\n");
674 report(out_hnd
, " -d Deletes a connection\n");
675 report(out_hnd
, " -f Forcibly deletes a connection\n");
676 report(out_hnd
, "net -u Shows all connections\n");
680 if (argc
> 1 && (*argv
[1] != '-'))
682 if (strnequal("\\\\", argv
[1], 2) ||
683 strnequal("//", argv
[1], 2))
685 pstrcpy(dest_host
, argv
[1] + 2);
691 while ((opt
= getopt(argc
, argv
, "udU:W:")) != EOF
)
704 pstrcpy(usr
.ntc
.user_name
, optarg
);
705 if ((lp
= strchr(usr
.ntc
.user_name
, '%')))
708 pstrcpy(password
, lp
+ 1);
709 memset(strchr(optarg
, '%') + 1, 'X',
713 if (usr
.ntc
.user_name
[0] == 0
727 pstrcpy(usr
.ntc
.domain
, optarg
);
746 "net -S \\server [-U user%%pass] [-W domain] [-d] [-f]\n");
747 report(out_hnd
, "net -u\n");
753 if (strnequal("\\\\", dest_host
, 2))
755 fstrcpy(srv_name
, dest_host
);
759 fstrcpy(srv_name
, "\\\\");
760 fstrcat(srv_name
, dest_host
);
768 struct use_info
**use
;
769 cli_net_use_enum(&num_uses
, &use
);
773 report(out_hnd
, "No connections\n");
777 report(out_hnd
, "Connections:\n");
779 for (i
= 0; i
< num_uses
; i
++)
781 if (use
[i
] != NULL
&& use
[i
]->connected
)
783 report(out_hnd
, "Server:\t%s\t",use
[i
]->srv_name
);
784 report(out_hnd
, "Key:\t[%d,%x]\t",use
[i
]->key
.pid
, use
[i
]->key
.vuid
);
785 report(out_hnd
, "User:\t%s\t", use
[i
]->user_name
);
786 report(out_hnd
, "Domain:\t%s\n", use
[i
]->domain
);
791 else if (net_use_add
)
795 set_user_password(&usr
.ntc
, True
, NULL
);
797 set_user_password(&usr
.ntc
, got_pwd
, password
);
799 /* paranoia: destroy the local copy of the password */
800 ZERO_STRUCT(password
);
802 report(out_hnd
, "Server:\t%s:\tUser:\t%s\tDomain:\t%s\n",
803 srv_name
, usr
.ntc
.user_name
, usr
.ntc
.domain
);
804 report(out_hnd
, "Connection:\t");
806 if (cli_net_use_add(srv_name
, &usr
.ntc
, info
->reuse
, &isnew
) != NULL
)
807 report(out_hnd
, "OK\n");
809 report(out_hnd
, "FAILED\n");
814 report(out_hnd
, "Server:\t%s:\tUser:\t%s\tDomain:\t%s\n",
815 srv_name
, usr
.ntc
.user_name
, usr
.ntc
.domain
);
816 report(out_hnd
, "Connection:\t");
818 if (!cli_net_use_del(srv_name
, &usr
.ntc
, force_close
, &closed
))
819 report(out_hnd
, ": Does not exist\n");
820 else if (force_close
&& closed
)
821 report(out_hnd
, ": Forcibly terminated\n");
823 report(out_hnd
, ": Terminated\n");
825 report(out_hnd
, ": Unlinked\n");
828 /* paranoia: destroy the local copy of the password */
829 ZERO_STRUCT(password
);
834 /******************************************************************
835 allow or disallow automatic connections. rpctorture, because it
836 does not reestablish connections after sys_fork(), fails unless the
837 connection is established AFTER the sys_fork()
838 ******************************************************************/
839 static BOOL auto_connect
= True
;
840 void cmd_set_no_autoconnect(void)
842 auto_connect
= False
;
849 #define CMD_PASS 0x10
850 #define CMD_USER 0x20
851 #define CMD_NOPW 0x40
852 #define CMD_DBLV 0x80
853 #define CMD_HELP 0x100
854 #define CMD_SOCK 0x200
855 #define CMD_IFACE 0x400
856 #define CMD_DOM 0x800
857 #define CMD_IP 0x1000
858 #define CMD_HOST 0x2000
859 #define CMD_NAME 0x4000
860 #define CMD_DBG 0x8000
861 #define CMD_SCOPE 0x10000
862 #define CMD_INTER 0x20000
864 static void read_authfile (char *filename
, char* username
, char* password
)
869 char *ptr
, *val
, *param
;
871 if ((auth
=sys_fopen(filename
, "r")) == NULL
)
873 /* fail if we can't open the credentials file */
874 DEBUG(0,("ERROR: Unable to open credentials file!\n"));
880 /* get a line from the file */
881 if (!fgets (buf
, sizeof(buf
), auth
))
886 /* skip empty lines */
887 if ((len
) && (buf
[len
-1]=='\n'))
895 /* break up the line into parameter & value.
896 will need to eat a little whitespace possibly */
898 if (!(ptr
= strchr (buf
, '=')))
903 /* eat leading white space */
904 while ((*val
!='\0') && ((*val
==' ') || (*val
=='\t')))
907 if (strwicmp("password", param
) == 0)
909 pstrcpy(password
, val
);
910 cmd_set_options
|= CMD_PASS
;
912 else if (strwicmp("username", param
) == 0)
914 pstrcpy(username
, val
);
915 cmd_set_options
|= CMD_USER
;
918 memset(buf
, 0, sizeof(buf
));
925 static uint32
cmd_set(CLIENT_INFO
*info
, int argc
, char *argv
[])
927 BOOL interactive
= True
;
928 char *cmd_str
= NULL
;
932 static pstring servicesf
= CONFIGFILE
;
934 pstring password
; /* local copy only, if one is entered */
936 int new_debuglevel
= -1;
942 pstrcpy(term_code
, KANJI
);
947 if (argc
> 1 && (*argv
[1] != '-'))
949 if (strnequal("\\\\", argv
[1], 2) ||
950 strnequal("//", argv
[1], 2))
952 cmd_set_options
|= CMD_HOST
;
953 pstrcpy(cli_info
.dest_host
, argv
[1] + 2);
954 strupper(cli_info
.dest_host
);
960 if (argc
> 1 && (*argv
[1] != '-'))
962 cmd_set_options
|= CMD_PASS
;
963 pstrcpy(password
, argv
[1]);
964 memset(argv
[1], 'X', strlen(argv
[1]));
969 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
)
973 /* reuse connections in the case of a previous authentication */
983 /* FIXME ... max_protocol seems to be funny here */
985 int max_protocol
= 0;
986 max_protocol
= interpret_protocol(optarg
, max_protocol
);
987 fprintf(stderr
, "max protocol not currently supported\n");
994 cmd_set_options
|= CMD_SOCK
;
995 pstrcpy(user_socket_options
, optarg
);
999 /* define the server to connect to */
1002 cmd_set_options
|= CMD_HOST
;
1003 pstrcpy(cli_info
.dest_host
, optarg
);
1004 strupper(cli_info
.dest_host
);
1008 /* username for the connection -- support the
1009 username%password format as well */
1013 cmd_set_options
|= CMD_USER
;
1014 pstrcpy(usr
.ntc
.user_name
, optarg
);
1015 if ((lp
= strchr(usr
.ntc
.user_name
, '%')))
1018 pstrcpy(password
, lp
+ 1);
1019 cmd_set_options
|= CMD_PASS
;
1020 memset(lp
+1, 'X', strlen(password
));
1025 /* authfile -- only get the username and password from the file */
1028 read_authfile (optarg
, usr
.ntc
.user_name
, password
);
1032 /* define the workgroup/domain name */
1035 cmd_set_options
|= CMD_DOM
;
1036 pstrcpy(usr
.ntc
.domain
, optarg
);
1040 /* should we display a command prompt at all */
1042 { /* optarg == prompt string ? */
1043 info
->show_prompt
= False
;
1047 /* send to stderr instaed of stdout */
1050 cmd_set_options
|= CMD_DBG
;
1055 /* IP address of destination host */
1058 cmd_set_options
|= CMD_IP
;
1059 cli_info
.dest_ip
= *interpret_addr2(optarg
);
1060 if (zero_ip(cli_info
.dest_ip
))
1068 /* define netbios name of client machine we are on */
1071 cmd_set_options
|= CMD_NAME
;
1072 fstrcpy(global_myname
, optarg
);
1076 /* do not prompt for a password. Implies anonymous connection
1077 unless the password was passed in username%password form */
1080 cmd_set_options
|= CMD_NOPW
| CMD_PASS
;
1087 cmd_set_options
|= CMD_DBLV
;
1089 new_debuglevel
= 10000;
1091 new_debuglevel
= atoi(optarg
);
1098 cmd_set_options
|= CMD_INTER
;
1099 slprintf(debugf
, sizeof(debugf
) - 1, "%s.client", optarg
);
1100 interactive
= False
;
1104 /* command string to be executed */
1107 cmd_set_options
|= CMD_STR
;
1112 /* program usage/help screen */
1115 cmd_set_options
|= CMD_HELP
;
1120 /* config file to use */
1123 cmd_set_options
|= CMD_SVC
;
1124 pstrcpy(servicesf
, optarg
);
1131 cmd_set_options
|= CMD_TERM
;
1132 pstrcpy(term_code
, optarg
);
1138 cmd_set_options
|= CMD_HELP
;
1146 if (cmd_set_options
& CMD_INTER
)
1148 setup_logging(debugf
, interactive
);
1153 strupper(global_myname
);
1154 fstrcpy(cli_info
.myhostname
, global_myname
);
1156 if (cmd_set_options
& CMD_SVC
)
1158 if (!lp_load(servicesf
, True
, False
, False
))
1160 fprintf(stderr
, "Can't load %s - run testparm to debug it\n",
1166 if (new_debuglevel
!= -1) {
1167 DEBUGLEVEL
= new_debuglevel
;
1170 if (cmd_set_options
& CMD_INTER
)
1175 DEBUG(10, ("cmd_set: options: %x\n", cmd_set_options
));
1177 if (cmd_set_options
& CMD_HELP
) {
1181 /* NULL password if specified or is username is empty */
1182 if ((cmd_set_options
& CMD_NOPW
) || (strlen(usr
.ntc
.user_name
) == 0))
1183 set_user_password(&usr
.ntc
, True
, NULL
);
1185 set_user_password(&usr
.ntc
, ((cmd_set_options
& CMD_PASS
) != 0), password
);
1187 /* paranoia: destroy the local copy of the password */
1188 ZERO_STRUCT(password
);
1190 if (strcmp(cli_info
.dest_host
, "*") == 0)
1192 /* special case - we want the PDC */
1194 if (!resolve_srv_name(cli_info
.dest_host
, cli_info
.dest_host
, &ip
)) {
1195 report(out_hnd
, "ERROR: Failed to find the PDC\n");
1200 fstrcpy(srv_name
, "\\\\");
1201 fstrcat(srv_name
, cli_info
.dest_host
);
1208 report(out_hnd
, "Server:\t%s:\tUser:\t%s\tDomain:\t%s\n",
1209 srv_name
, usr
.ntc
.user_name
, usr
.ntc
.domain
);
1210 report(out_hnd
, "Connection:\t");
1212 if (cli_net_use_add(srv_name
, &usr
.ntc
, info
->reuse
, &isnew
) != NULL
)
1214 report(out_hnd
, "OK\n");
1218 report(out_hnd
, "FAILED\n");
1221 usr_creds = NULL; */
1224 if (cmd_str
!= NULL
)
1225 return process(&cli_info
, cmd_str
);
1230 static void read_user_env(struct ntuser_creds
*u
)
1239 pstrcpy(u
->user_name
, getenv("USER"));
1241 /* modification to support userid%passwd syntax in the USER var
1242 25.Aug.97, jdblair@uab.edu */
1244 if ((p
= strchr(u
->user_name
, '%')))
1247 pstrcpy(password
, p
+ 1);
1248 memset(strchr(getenv("USER"), '%') + 1, 'X',
1253 /* modification to support PASSWD environmental var
1254 25.Aug.97, jdblair@uab.edu */
1255 if (getenv("PASSWD"))
1256 pstrcpy(password
, getenv("PASSWD"));
1258 if (*u
->user_name
== 0 && getenv("LOGNAME"))
1259 pstrcpy(u
->user_name
, getenv("LOGNAME"));
1261 set_user_password(u
, True
, password
);
1263 /* paranoia: destroy the local copy of the password */
1264 ZERO_STRUCT(password
);
1267 static void readline_init(void)
1269 #ifdef HAVE_LIBREADLINE
1270 /* Initialise GNU Readline */ rl_readline_name
= "rpcclient";
1271 rl_attempted_completion_function
= completion_fn
;
1272 rl_completion_entry_function
= (Function
*) complete_cmd_null
;
1274 /* Initialise history list */
1280 x
= 0; /* stop compiler warnings */
1281 #endif /* HAVE_LIBREADLINE */
1284 /****************************************************************************
1286 ****************************************************************************/
1287 int command_main(int argc
, char *argv
[])
1290 mode_t myumask
= 0755;
1291 char progname
[255], path
[255], *s
;
1296 charset_initialise();
1298 /* add in the internal command set and the various
1299 client RPC groups--spoolss, lsa, etc... */
1300 add_command_set(general_commands
);
1302 /* usr_creds is a global most recently used set of user credentials
1303 retrieved from the connection list. */
1304 copy_user_creds(&usr
, NULL
);
1310 /* retrieve the binary name used when invoking the program
1311 for instances like samedit, etc... */
1312 strncpy(path
, argv
[0], 255);
1313 for (s
= strtok(path
, "/"); s
; s
= strtok(NULL
, "/"))
1314 fstrcpy(progname
, s
);
1316 slprintf(debugf
, sizeof(debugf
) - 1,
1317 "%s/log.%s", LOGFILEBASE
, progname
);
1319 /* initialize usr */
1320 pstrcpy(usr
.ntc
.domain
, "");
1321 pstrcpy(usr
.ntc
.user_name
, "");
1322 pstrcpy(cli_info
.myhostname
, "");
1323 pstrcpy(cli_info
.dest_host
, "");
1325 /* init client_info struct */
1326 cli_info
.dest_ip
.s_addr
= 0;
1327 cli_info
.show_prompt
= True
;
1328 ZERO_STRUCT(cli_info
.dom
.level3_sid
);
1329 ZERO_STRUCT(cli_info
.dom
.level5_sid
);
1330 fstrcpy(cli_info
.dom
.level3_dom
, "");
1331 fstrcpy(cli_info
.dom
.level5_dom
, "");
1340 if (!get_myname(global_myname
))
1342 fprintf(stderr
, "Failed to get my hostname.\n");
1352 read_user_env(&usr
.ntc
);
1354 cmd_set_options
&= ~CMD_HELP
;
1355 cmd_set_options
&= ~CMD_STR
;
1356 cmd_set_options
&= ~CMD_NOPW
;
1357 cmd_set_options
&= ~CMD_USER
;
1358 cmd_set_options
&= ~CMD_PASS
;
1360 codepage_initialise(lp_client_code_page());
1362 /* parse the command line args
1363 init the first connection if possible
1364 process a command if passed in on the command line */
1365 status
= cmd_set(&cli_info
, argc
, argv
);
1367 /* Should we exit? Are we done? */
1368 if (cmd_set_options
& (CMD_HELP
|CMD_STR
)) {
1370 get_safe_nt_error_msg(status
, msg
, sizeof(msg
));
1372 report(out_hnd
, "Exit Status: %s\n", msg
);
1373 /* unix only has 8 bit error codes - blergh */
1374 exit(status
& 0xFF);
1377 DEBUG(3, ("%s client started (version %s)\n",
1378 timestring(False
), VERSION
));
1380 /* enter shell mode */
1381 status
= process(&cli_info
, NULL
);
1385 free_cmd_set_array(num_commands
, commands
);
1389 /* report and exit */
1390 get_safe_nt_error_msg(status
, msg
, sizeof(msg
));
1391 report(out_hnd
, "Exit Status: %s\n", msg
);