summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/lib/cmd_interp.c299
1 files changed, 140 insertions, 159 deletions
diff --git a/source3/lib/cmd_interp.c b/source3/lib/cmd_interp.c
index 15fa49d1ad..2c422f577e 100644
--- a/source3/lib/cmd_interp.c
+++ b/source3/lib/cmd_interp.c
@@ -2,7 +2,9 @@
Unix SMB/Netbios implementation.
Version 1.9.
SMB client
- Copyright (C) Andrew Tridgell 1994-1998
+ Copyright (C) Andrew Tridgell 1994-1998
+ Copyright (C) Luke Kenneth Casson Leighton 1998-2000
+ Copyright (C) Gerald Carter 2000
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -65,9 +67,8 @@ FILE *out_hnd;
static void cmd_set_free(struct command_set *item)
{
if (item != NULL)
- {
safe_free(item->name);
- }
+
safe_free(item);
}
@@ -75,16 +76,14 @@ static struct command_set *cmd_set_dup(const struct command_set *from)
{
if (from != NULL)
{
- struct command_set *copy =
- (struct command_set
- *)malloc(sizeof(struct command_set));
+ struct command_set *copy;
+
+ copy = (struct command_set*)malloc(sizeof(struct command_set));
if (copy != NULL)
{
memcpy(copy, from, sizeof(struct command_set));
if (from->name != NULL)
- {
copy->name = strdup(from->name);
- }
}
return copy;
}
@@ -97,13 +96,11 @@ void free_cmd_set_array(uint32 num_entries, struct command_set **entries)
free_void_array(num_entries, (void **)entries, *fn);
}
-struct command_set *add_cmd_set_to_array(uint32 *len,
- struct command_set ***array,
+struct command_set *add_cmd_set_to_array(uint32 *len, struct command_set ***array,
const struct command_set *cmd)
{
void *(*fn) (const void *) = (void *(*)(const void *))&cmd_set_dup;
- return (struct command_set *)add_copy_to_array(len,
- (void ***)array,
+ return (struct command_set *)add_copy_to_array(len, (void ***)array,
(const void *)cmd, *fn,
False);
@@ -214,6 +211,7 @@ static uint32 cmd_quit(struct client_info *info, int argc, char *argv[])
free_connections();
exit(0);
+
/* NOTREACHED */
return 0;
}
@@ -230,8 +228,8 @@ static uint32 cmd_help(struct client_info *info, int argc, char *argv[])
{
if ((i = process_tok(argv[0])) >= 0)
{
- fprintf(out_hnd, "HELP %s:\n\t%s\n\n",
- commands[i]->name, commands[i]->description);
+ fprintf(out_hnd, "HELP %s:\n\t%s\n\n", commands[i]->name,
+ commands[i]->description);
}
return 0;
@@ -296,9 +294,7 @@ static BOOL get_cmd_args(char *line)
/* get the first part of the command */
if (!next_token(&ptr, tok, NULL, sizeof(tok)))
- {
return False;
- }
do
{
@@ -326,9 +322,7 @@ static uint32 do_command(struct client_info *info, char *line)
return False;
if (cmd_argc == 0)
- {
return False;
- }
i = process_tok(cmd_argv[0]);
if (i >= 0)
@@ -539,9 +533,7 @@ static char *complete_cmd(char *text, int state)
/* Initialise */
if (state == 0)
- {
cmd_index = 0;
- }
/* Return the next name which partially matches the list of commands */
@@ -549,9 +541,7 @@ static char *complete_cmd(char *text, int state)
&& (strlen(name = commands[cmd_index++]->name) > 0))
{
if (strncmp(name, text, strlen(text)) == 0)
- {
return strdup(name);
- }
}
return NULL;
@@ -576,9 +566,7 @@ static char **completion_fn(char *text, int start, int end)
/* Complete rpcclient command */
if (start == 0)
- {
return completion_matches(text, complete_cmd);
- }
/* Count # of words in command */
@@ -586,9 +574,7 @@ static char **completion_fn(char *text, int start, int end)
for (i = 0; i <= end; i++)
{
if ((rl_line_buffer[i] != ' ') && (lastch == ' '))
- {
num_words++;
- }
lastch = rl_line_buffer[i];
}
@@ -605,25 +591,19 @@ static char **completion_fn(char *text, int start, int end)
if (strncmp(rl_line_buffer, commands[cmd_index]->name,
strlen(commands[cmd_index]->name)) == 0)
{
-
/* Call appropriate completion function */
if (num_words == 2 || num_words == 3)
{
char *(*fn) (char *, int);
- fn =
- commands[cmd_index]->compl_args
- [num_words - 2];
+ fn = commands[cmd_index]->compl_args[num_words - 2];
if (fn != NULL)
- {
return completion_matches(text, fn);
- }
}
}
}
/* Eeek! */
-
return NULL;
}
@@ -680,13 +660,9 @@ static uint32 cmd_use(struct client_info *info, int argc, char *argv[])
if (usr_creds != NULL)
- {
copy_nt_creds(&usr.ntc, &usr_creds->ntc);
- }
else
- {
copy_nt_creds(&usr.ntc, NULL);
- }
pstrcpy(dest_host, cli_info.dest_host);
pstrcpy(usr.ntc.user_name, optarg);
@@ -805,15 +781,10 @@ static uint32 cmd_use(struct client_info *info, int argc, char *argv[])
{
if (use[i] != NULL && use[i]->connected)
{
- report(out_hnd, "Server:\t%s\t",
- use[i]->srv_name);
- report(out_hnd, "Key:\t[%d,%x]\t",
- use[i]->key.pid,
- use[i]->key.vuid);
- report(out_hnd, "User:\t%s\t",
- use[i]->user_name);
- report(out_hnd, "Domain:\t%s\n",
- use[i]->domain);
+ report(out_hnd, "Server:\t%s\t",use[i]->srv_name);
+ report(out_hnd, "Key:\t[%d,%x]\t",use[i]->key.pid, use[i]->key.vuid);
+ report(out_hnd, "User:\t%s\t", use[i]->user_name);
+ report(out_hnd, "Domain:\t%s\n", use[i]->domain);
}
}
}
@@ -822,13 +793,9 @@ static uint32 cmd_use(struct client_info *info, int argc, char *argv[])
{
BOOL isnew;
if (null_pwd)
- {
set_user_password(&usr.ntc, True, NULL);
- }
else
- {
set_user_password(&usr.ntc, got_pwd, password);
- }
/* paranoia: destroy the local copy of the password */
ZERO_STRUCT(password);
@@ -837,15 +804,10 @@ static uint32 cmd_use(struct client_info *info, int argc, char *argv[])
srv_name, usr.ntc.user_name, usr.ntc.domain);
report(out_hnd, "Connection:\t");
- if (cli_net_use_add(srv_name, &usr.ntc,
- info->reuse, &isnew) != NULL)
- {
+ if (cli_net_use_add(srv_name, &usr.ntc, info->reuse, &isnew) != NULL)
report(out_hnd, "OK\n");
- }
else
- {
report(out_hnd, "FAILED\n");
- }
}
else
{
@@ -854,23 +816,14 @@ static uint32 cmd_use(struct client_info *info, int argc, char *argv[])
srv_name, usr.ntc.user_name, usr.ntc.domain);
report(out_hnd, "Connection:\t");
- if (!cli_net_use_del(srv_name, &usr.ntc,
- force_close, &closed))
- {
+ if (!cli_net_use_del(srv_name, &usr.ntc, force_close, &closed))
report(out_hnd, ": Does not exist\n");
- }
else if (force_close && closed)
- {
report(out_hnd, ": Forcibly terminated\n");
- }
else if (closed)
- {
report(out_hnd, ": Terminated\n");
- }
else
- {
report(out_hnd, ": Unlinked\n");
- }
}
/* paranoia: destroy the local copy of the password */
@@ -909,7 +862,68 @@ void cmd_set_no_autoconnect(void)
#define CMD_SCOPE 0x10000
#define CMD_INTER 0x20000
-static uint32 cmd_set(struct client_info *info, int argc, char *argv[])
+static void read_authfile (char *filename, char* username, char* password)
+{
+ FILE *auth;
+ fstring buf;
+ uint16 len = 0;
+ char *ptr, *val, *param;
+
+ if ((auth=sys_fopen(filename, "r")) == NULL)
+ {
+ /* fail if we can't open the credentials file */
+ DEBUG(0,("ERROR: Unable to open credentials file!\n"));
+ return;
+ }
+
+ while (!feof(auth))
+ {
+ /* get a line from the file */
+ if (!fgets (buf, sizeof(buf), auth))
+ continue;
+
+ len = strlen(buf);
+
+ /* skip empty lines */
+ if ((len) && (buf[len-1]=='\n'))
+ {
+ buf[len-1] = '\0';
+ len--;
+ }
+ if (len == 0)
+ continue;
+
+ /* break up the line into parameter & value.
+ will need to eat a little whitespace possibly */
+ param = buf;
+ if (!(ptr = strchr (buf, '=')))
+ continue;
+ val = ptr+1;
+ *ptr = '\0';
+
+ /* eat leading white space */
+ while ((*val!='\0') && ((*val==' ') || (*val=='\t')))
+ val++;
+
+ if (strwicmp("password", param) == 0)
+ {
+ pstrcpy(password, val);
+ cmd_set_options |= CMD_PASS;
+ }
+ else if (strwicmp("username", param) == 0)
+ {
+ pstrcpy(username, val);
+ cmd_set_options |= CMD_USER;
+ }
+
+ memset(buf, 0, sizeof(buf));
+ }
+ fclose(auth);
+
+ return;
+}
+
+static uint32 cmd_set(CLIENT_INFO *info, int argc, char *argv[])
{
BOOL interactive = True;
char *cmd_str = NULL;
@@ -942,6 +956,7 @@ static uint32 cmd_set(struct client_info *info, int argc, char *argv[])
argc--;
argv++;
}
+
if (argc > 1 && (*argv[1] != '-'))
{
cmd_set_options |= CMD_PASS;
@@ -951,31 +966,29 @@ static uint32 cmd_set(struct client_info *info, int argc, char *argv[])
argv++;
}
- 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)
+ 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)
{
switch (opt)
{
+ /* reuse connections in the case of a previous authentication */
case 'R':
{
info->reuse = True;
break;
}
+ /* max protocol */
case 'm':
{
/* FIXME ... max_protocol seems to be funny here */
int max_protocol = 0;
- max_protocol =
- interpret_protocol(optarg,
- max_protocol);
- fprintf(stderr,
- "max protocol not currently supported\n");
+ max_protocol = interpret_protocol(optarg, max_protocol);
+ fprintf(stderr, "max protocol not currently supported\n");
break;
}
+ /* socket options */
case 'O':
{
cmd_set_options |= CMD_SOCK;
@@ -983,6 +996,7 @@ static uint32 cmd_set(struct client_info *info, int argc, char *argv[])
break;
}
+ /* define the server to connect to */
case 'S':
{
cmd_set_options |= CMD_HOST;
@@ -991,6 +1005,8 @@ static uint32 cmd_set(struct client_info *info, int argc, char *argv[])
break;
}
+ /* username for the connection -- support the
+ username%password format as well */
case 'U':
{
char *lp;
@@ -1005,64 +1021,15 @@ static uint32 cmd_set(struct client_info *info, int argc, char *argv[])
}
break;
}
+
+ /* authfile -- only get the username and password from the file */
case 'A':
{
- FILE *auth;
- fstring buf;
- uint16 len = 0;
- char *ptr, *val, *param;
-
- if ((auth=sys_fopen(optarg, "r")) == NULL)
- {
- /* fail if we can't open the credentials file */
- DEBUG(0,("ERROR: Unable to open credentials file!\n"));
- exit (-1);
- }
-
- while (!feof(auth))
- {
- /* get a line from the file */
- if (!fgets (buf, sizeof(buf), auth))
- continue;
- len = strlen(buf);
-
- if ((len) && (buf[len-1]=='\n'))
- {
- buf[len-1] = '\0';
- len--;
- }
- if (len == 0)
- continue;
-
- /* break up the line into parameter & value.
- will need to eat a little whitespace possibly */
- param = buf;
- if (!(ptr = strchr (buf, '=')))
- continue;
- val = ptr+1;
- *ptr = '\0';
-
- /* eat leading white space */
- while ((*val!='\0') && ((*val==' ') || (*val=='\t')))
- val++;
-
- if (strwicmp("password", param) == 0)
- {
- pstrcpy(password, val);
- cmd_set_options |= CMD_PASS;
- }
- else if (strwicmp("username", param) == 0)
- {
- pstrcpy(usr.ntc.user_name, val);
- cmd_set_options |= CMD_USER;
- }
-
- memset(buf, 0, sizeof(buf));
- }
- fclose(auth);
+ read_authfile (optarg, usr.ntc.user_name, password);
break;
}
+ /* define the workgroup/domain name */
case 'W':
{
cmd_set_options |= CMD_DOM;
@@ -1070,12 +1037,14 @@ static uint32 cmd_set(struct client_info *info, int argc, char *argv[])
break;
}
+ /* should we display a command prompt at all */
case 'P':
{ /* optarg == prompt string ? */
info->show_prompt = False;
break;
}
+ /* send to stderr instaed of stdout */
case 'E':
{
cmd_set_options |= CMD_DBG;
@@ -1083,6 +1052,7 @@ static uint32 cmd_set(struct client_info *info, int argc, char *argv[])
break;
}
+ /* IP address of destination host */
case 'I':
{
cmd_set_options |= CMD_IP;
@@ -1095,6 +1065,7 @@ static uint32 cmd_set(struct client_info *info, int argc, char *argv[])
break;
}
+ /* define netbios name of client machine we are on */
case 'n':
{
cmd_set_options |= CMD_NAME;
@@ -1102,12 +1073,15 @@ static uint32 cmd_set(struct client_info *info, int argc, char *argv[])
break;
}
+ /* do not prompt for a password. Implies anonymous connection
+ unless the password was passed in username%password form */
case 'N':
{
cmd_set_options |= CMD_NOPW | CMD_PASS;
break;
}
+ /* debug level */
case 'd':
{
cmd_set_options |= CMD_DBLV;
@@ -1118,15 +1092,16 @@ static uint32 cmd_set(struct client_info *info, int argc, char *argv[])
break;
}
+ /* log file name */
case 'l':
{
cmd_set_options |= CMD_INTER;
- slprintf(debugf, sizeof(debugf) - 1,
- "%s.client", optarg);
+ slprintf(debugf, sizeof(debugf) - 1, "%s.client", optarg);
interactive = False;
break;
}
+ /* command string to be executed */
case 'c':
{
cmd_set_options |= CMD_STR;
@@ -1134,6 +1109,7 @@ static uint32 cmd_set(struct client_info *info, int argc, char *argv[])
break;
}
+ /* program usage/help screen */
case 'h':
{
cmd_set_options |= CMD_HELP;
@@ -1141,6 +1117,7 @@ static uint32 cmd_set(struct client_info *info, int argc, char *argv[])
break;
}
+ /* config file to use */
case 's':
{
cmd_set_options |= CMD_SVC;
@@ -1148,6 +1125,7 @@ static uint32 cmd_set(struct client_info *info, int argc, char *argv[])
break;
}
+ /* terminal code */
case 't':
{
cmd_set_options |= CMD_TERM;
@@ -1164,7 +1142,9 @@ static uint32 cmd_set(struct client_info *info, int argc, char *argv[])
}
}
- if (cmd_set_options & CMD_INTER) {
+
+ if (cmd_set_options & CMD_INTER)
+ {
setup_logging(debugf, interactive);
if (!interactive)
reopen_logs();
@@ -1173,17 +1153,18 @@ static uint32 cmd_set(struct client_info *info, int argc, char *argv[])
strupper(global_myname);
fstrcpy(cli_info.myhostname, global_myname);
- if (cmd_set_options & CMD_SVC) {
+ if (cmd_set_options & CMD_SVC)
+ {
if (!lp_load(servicesf, True, False, False))
{
- fprintf(stderr,
- "Can't load %s - run testparm to debug it\n",
+ fprintf(stderr, "Can't load %s - run testparm to debug it\n",
servicesf);
}
}
- if (cmd_set_options & CMD_INTER) {
+ if (cmd_set_options & CMD_INTER)
+ {
load_interfaces();
}
@@ -1194,20 +1175,16 @@ static uint32 cmd_set(struct client_info *info, int argc, char *argv[])
}
/* NULL password if specified or is username is empty */
- if ((cmd_set_options & CMD_NOPW) || (strlen(usr.ntc.user_name) == 0)) {
+ if ((cmd_set_options & CMD_NOPW) || (strlen(usr.ntc.user_name) == 0))
set_user_password(&usr.ntc, True, NULL);
- }
else
- {
- set_user_password(&usr.ntc,
- ((cmd_set_options & CMD_PASS) != 0),
- password);
- }
+ set_user_password(&usr.ntc, ((cmd_set_options & CMD_PASS) != 0), password);
/* paranoia: destroy the local copy of the password */
ZERO_STRUCT(password);
- if (strcmp(cli_info.dest_host, "*") == 0) {
+ if (strcmp(cli_info.dest_host, "*") == 0)
+ {
/* special case - we want the PDC */
struct in_addr ip;
if (!resolve_srv_name(cli_info.dest_host, cli_info.dest_host, &ip)) {
@@ -1221,7 +1198,7 @@ static uint32 cmd_set(struct client_info *info, int argc, char *argv[])
strupper(srv_name);
- if (auto_connect && !strequal(srv_name, "\\\\."))
+ if (auto_connect)
{
BOOL isnew;
report(out_hnd, "Server:\t%s:\tUser:\t%s\tDomain:\t%s\n",
@@ -1239,10 +1216,9 @@ static uint32 cmd_set(struct client_info *info, int argc, char *argv[])
/* ???? --jerry
usr_creds = NULL; */
}
+
if (cmd_str != NULL)
- {
return process(&cli_info, cmd_str);
- }
return 0;
}
@@ -1268,21 +1244,15 @@ static void read_user_env(struct ntuser_creds *u)
memset(strchr(getenv("USER"), '%') + 1, 'X',
strlen(password));
}
- strupper(u->user_name);
}
/* modification to support PASSWD environmental var
25.Aug.97, jdblair@uab.edu */
if (getenv("PASSWD"))
- {
pstrcpy(password, getenv("PASSWD"));
- }
if (*u->user_name == 0 && getenv("LOGNAME"))
- {
pstrcpy(u->user_name, getenv("LOGNAME"));
- strupper(u->user_name);
- }
set_user_password(u, True, password);
@@ -1320,15 +1290,21 @@ int command_main(int argc, char *argv[])
DEBUGLEVEL = 2;
charset_initialise();
+
+ /* add in the internal command set and the various
+ client RPC groups--spoolss, lsa, etc... */
add_command_set(general_commands);
+ /* usr_creds is a global most recently used set of user credentials
+ retrieved from the connection list. */
copy_user_creds(&usr, NULL);
-
usr_creds = &usr;
usr.ptr_ntc = 1;
-
+
out_hnd = stdout;
+ /* retrieve the binary name used when invoking the program
+ for instances like samedit, etc... */
strncpy(path, argv[0], 255);
for (s = strtok(path, "/"); s; s = strtok(NULL, "/"))
fstrcpy(progname, s);
@@ -1336,15 +1312,15 @@ int command_main(int argc, char *argv[])
slprintf(debugf, sizeof(debugf) - 1,
"%s/log.%s", LOGFILEBASE, progname);
+ /* initialize usr */
pstrcpy(usr.ntc.domain, "");
pstrcpy(usr.ntc.user_name, "");
-
pstrcpy(cli_info.myhostname, "");
pstrcpy(cli_info.dest_host, "");
- cli_info.dest_ip.s_addr = 0;
+ /* init client_info struct */
+ cli_info.dest_ip.s_addr = 0;
cli_info.show_prompt = True;
-
ZERO_STRUCT(cli_info.dom.level3_sid);
ZERO_STRUCT(cli_info.dom.level5_sid);
fstrcpy(cli_info.dom.level3_dom, "");
@@ -1379,8 +1355,12 @@ int command_main(int argc, char *argv[])
codepage_initialise(lp_client_code_page());
+ /* parse the command line args
+ init the first connection if possible
+ process a command if passed in on the command line */
status = cmd_set(&cli_info, argc, argv);
+ /* Should we exit? Are we done? */
if (cmd_set_options & (CMD_HELP|CMD_STR)) {
free_connections();
get_safe_nt_error_msg(status, msg, sizeof(msg));
@@ -1393,16 +1373,17 @@ int command_main(int argc, char *argv[])
DEBUG(3, ("%s client started (version %s)\n",
timestring(False), VERSION));
+ /* enter shell mode */
status = process(&cli_info, NULL);
+ /* cleanup */
free_connections();
-
free_cmd_set_array(num_commands, commands);
num_commands = 0;
commands = NULL;
+ /* report and exit */
get_safe_nt_error_msg(status, msg, sizeof(msg));
report(out_hnd, "Exit Status: %s\n", msg);
-
return status;
}