From c9d38e177bf6b519458a5ba497f69f3336366c6f Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Mon, 11 Dec 2000 18:13:19 +0000 Subject: code review of rpcclient o added some comments o abstracted a few code bits o cleaned up some code by removing unused code paths -- jerry (This used to be commit 679453af36c06ae9c82dd20742a56272ec73f427) --- source3/lib/cmd_interp.c | 299 ++++++++++++++++++++++------------------------- 1 file changed, 140 insertions(+), 159 deletions(-) (limited to 'source3') 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; } -- cgit