From 33f6a1d9bb7ffed681085261a78d5ef4297f73de Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Mon, 3 Jul 2000 04:28:29 +0000 Subject: first pass at merging rpcclient from TNG to HEAD. You can get a semi-connection and a rpcclient prompt, but no functionality there yet. Will be a few more days on that. --jerry (This used to be commit 269051aa0c52728278a1d290148564f11cf7f189) --- source3/lib/cmd_interp.c | 1363 ++++++++++++++++++++++++++++++++++++ source3/lib/msrpc-client.c | 32 + source3/rpc_client/cli_connect.c | 190 +++++ source3/rpc_client/cli_use.c | 448 ++++++++++++ source3/rpc_client/ncacn_np_use.c | 173 +++++ source3/rpc_client/ncalrpc_l_use.c | 127 ++++ source3/rpcclient/rpcclient.c | 761 +------------------- source3/script/mkproto.awk | 8 +- source3/script/mkproto.sh | 41 ++ 9 files changed, 2396 insertions(+), 747 deletions(-) create mode 100644 source3/lib/cmd_interp.c create mode 100644 source3/rpc_client/cli_connect.c create mode 100644 source3/rpc_client/cli_use.c create mode 100644 source3/rpc_client/ncacn_np_use.c create mode 100644 source3/rpc_client/ncalrpc_l_use.c create mode 100755 source3/script/mkproto.sh (limited to 'source3') diff --git a/source3/lib/cmd_interp.c b/source3/lib/cmd_interp.c new file mode 100644 index 0000000000..7b90daa06f --- /dev/null +++ b/source3/lib/cmd_interp.c @@ -0,0 +1,1363 @@ +/* + Unix SMB/Netbios implementation. + Version 1.9. + SMB client + Copyright (C) Andrew Tridgell 1994-1998 + + 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifdef SYSLOG +#undef SYSLOG +#endif + +#include "includes.h" +#include "rpc_parse.h" +#include "rpc_client.h" + +#ifndef REGISTER +#define REGISTER 0 +#endif + +extern pstring debugf; +extern pstring global_myname; + +extern pstring user_socket_options; + +/* found in rpc_client/cli_connect.c */ +extern struct user_creds *usr_creds; + + +extern int DEBUGLEVEL; + + +#define CNV_LANG(s) dos2unix_format(s,False) +#define CNV_INPUT(s) unix2dos_format(s,True) + +static int process_tok(fstring tok); +static uint32 cmd_help(struct client_info *info, int argc, char *argv[]); +static uint32 cmd_quit(struct client_info *info, int argc, char *argv[]); +static uint32 cmd_set(struct client_info *info, int argc, char *argv[]); +static uint32 cmd_use(struct client_info *info, int argc, char *argv[]); + +static struct user_creds usr; + +struct client_info cli_info; + +char **cmd_argv = NULL; +uint32 cmd_argc = 0; + +FILE *out_hnd; + + +static void cmd_set_free(struct command_set *item) +{ + if (item != NULL) + { + safe_free(item->name); + } + safe_free(item); +} + +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)); + if (copy != NULL) + { + memcpy(copy, from, sizeof(struct command_set)); + if (from->name != NULL) + { + copy->name = strdup(from->name); + } + } + return copy; + } + return NULL; +} + +void free_cmd_set_array(uint32 num_entries, struct command_set **entries) +{ + void (*fn) (void *) = (void (*)(void *))&cmd_set_free; + free_void_array(num_entries, (void **)entries, *fn); +} + +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, + (const void *)cmd, *fn, + False); + +} + +static struct command_set **commands = NULL; +static uint32 num_commands = 0; + +/**************************************************************************** + add in individual command-sets. + ****************************************************************************/ +void add_command_set(const struct command_set *cmds) +{ + while (cmds->fn != NULL) + { + add_cmd_set_to_array(&num_commands, &commands, cmds); + cmds++; + } +} + +/**************************************************************************** + This defines the commands supported by this client + ****************************************************************************/ +static struct command_set general_commands[] = { + /* + * maintenance + */ + + { + "set", + cmd_set, + "run rpcclient inside rpcclient (change options etc.)", + {NULL, NULL} + }, + + { + "use", + cmd_use, + "net use and net view", + {NULL, NULL} + }, + + /* + * bye bye + */ + + { + "quit", + cmd_quit, + "logoff the server", + {NULL, NULL} + }, + { + "q", + cmd_quit, + "logoff the server", + {NULL, NULL} + }, + { + "exit", + cmd_quit, + "logoff the server", + {NULL, NULL} + }, + { + "bye", + cmd_quit, + "logoff the server", + {NULL, NULL} + }, + + /* + * eek! + */ + + { + "help", + cmd_help, + "[command] give help on a command", + {NULL, NULL} + }, + { + "?", + cmd_help, + "[command] give help on a command", + {NULL, NULL} + }, + + /* + * shell + */ + + { + "!", + NULL, + "run a shell command on the local system", + {NULL, NULL} + }, + + /* + * oop! + */ + + { + "", + NULL, + NULL, + {NULL, NULL} + } +}; + + +/**************************************************************************** +do a (presumably graceful) quit... +****************************************************************************/ +static uint32 cmd_quit(struct client_info *info, int argc, char *argv[]) +{ +#ifdef MEM_MAN + { + extern FILE *dbf; + smb_mem_write_status(dbf); + smb_mem_write_errors(dbf); + smb_mem_write_verbose(dbf); + dbgflush(); + } +#endif + + free_connections(); + exit(0); +} + +/**************************************************************************** +help +****************************************************************************/ +static uint32 cmd_help(struct client_info *info, int argc, char *argv[]) +{ + int i = 0, j = 0; + + if (argc > 1) + { + if ((i = process_tok(argv[1])) >= 0) + { + fprintf(out_hnd, "HELP %s:\n\t%s\n\n", + commands[i]->name, commands[i]->description); + } + } + else + { + for (i = 0; i < num_commands; i++) + { + fprintf(out_hnd, "%-15s", commands[i]->name); + j++; + if (j == 5) + { + fprintf(out_hnd, "\n"); + j = 0; + } + } + if (j != 0) + { + fprintf(out_hnd, "\n"); + } + } + return 0; +} + +/******************************************************************* + lookup a command string in the list of commands, including + abbreviations + ******************************************************************/ +static int process_tok(char *tok) +{ + int i = 0, matches = 0; + int cmd = 0; + int tok_len = strlen(tok); + + for (i = 0; i < num_commands; i++) + { + if (strequal(commands[i]->name, tok)) + { + matches = 1; + cmd = i; + break; + } + else if (strnequal(commands[i]->name, tok, tok_len)) + { + matches++; + cmd = i; + } + } + + if (matches == 0) + return (-1); + else if (matches == 1) + return (cmd); + else + return (-2); +} + +/**************************************************************************** + turn command line into command argument array +****************************************************************************/ +static BOOL get_cmd_args(char *line) +{ + char *ptr = line; + pstring tok; + cmd_argc = 0; + cmd_argv = NULL; + + /* get the first part of the command */ + if (!next_token(&ptr, tok, NULL, sizeof(tok))) + { + return False; + } + + do + { + add_chars_to_array(&cmd_argc, &cmd_argv, tok); + } + while (next_token(NULL, tok, NULL, sizeof(tok))); + + add_chars_to_array(&cmd_argc, &cmd_argv, NULL); + + return True; +} + +/* command options mask */ +static uint32 cmd_set_options = 0xffffffff; + +/**************************************************************************** + process commands from the client +****************************************************************************/ +static uint32 do_command(struct client_info *info, char *line) +{ + uint32 status = 0x0; + int i; + + if (!get_cmd_args(line)) + return False; + + if (cmd_argc == 0) + { + return False; + } + + if ((i = process_tok(cmd_argv[0])) >= 0) + { + int argc = ((int)cmd_argc)-1; + char **argv = cmd_argv; + optind = 0; + + status = commands[i]->fn(info, argc, argv); + } + else if (i == -2) + { + fprintf(out_hnd, "%s: command abbreviation ambiguous\n", + CNV_LANG(cmd_argv[0])); + } + else + { + fprintf(out_hnd, "%s: command not found\n", + CNV_LANG(cmd_argv[0])); + } + + free_char_array(cmd_argc, cmd_argv); + + return status; +} + + +/**************************************************************************** + process commands from the client +****************************************************************************/ +static uint32 process(struct client_info *info, char *cmd_str) +{ + uint32 status = 0; + pstring line; + char *cmd = cmd_str; + + if (cmd != NULL) + { + while (cmd[0] != '\0') + { + char *p; + + if ((p = strchr(cmd, ';')) == 0) + { + strncpy(line, cmd, 999); + line[1000] = '\0'; + cmd += strlen(cmd); + } + else + { + if (p - cmd > 999) + p = cmd + 999; + strncpy(line, cmd, p - cmd); + line[p - cmd] = '\0'; + cmd = p + 1; + } + + /* input language code to internal one */ + CNV_INPUT(line); + + status = do_command(info, line); + if (status == 0x0) + { + continue; + } + } + } + else + { + while (!feof(stdin)) + { +#ifdef HAVE_READLINE + char *ret_line; +#endif + pstring pline; + BOOL at_sym = False; + pline[0] = 0; + safe_strcat(pline, "[", sizeof(pline) - 1); + if (usr.ntc.domain[0] != 0) + { + safe_strcat(pline, usr.ntc.domain, + sizeof(pline) - 1); + safe_strcat(pline, "\\", sizeof(pline) - 1); + at_sym = True; + } + if (usr.ntc.user_name[0] != 0) + { + safe_strcat(pline, usr.ntc.user_name, + sizeof(pline) - 1); + at_sym = True; + } + if (at_sym) + { + safe_strcat(pline, "@", sizeof(pline) - 1); + } + + safe_strcat(pline, cli_info.dest_host, + sizeof(pline) - 1); + safe_strcat(pline, "]$ ", sizeof(pline) - 1); + +#ifndef HAVE_READLINE + + /* display a prompt */ + fprintf(out_hnd, "%s", CNV_LANG(pline)); + fflush(out_hnd); + + cli_use_wait_keyboard(); + + /* and get a response */ + if (!fgets(line, 1000, stdin)) + { + break; + } + +#else /* HAVE_READLINE */ + + if (!(ret_line = readline(pline))) + break; + safe_free(ret_line); + + /* Copy read line to samba buffer */ + + pstrcpy(line, rl_line_buffer); + + /* Add to history */ + + if (strlen(line) > 0) + add_history(line); +#endif + /* input language code to internal one */ + CNV_INPUT(line); + + /* special case - first char is ! */ + if (*line == '!') + { + system(line + 1); + continue; + } + + fprintf(out_hnd, "%s\n", line); + + status = do_command(info, line); + if (status == 0x0) + { + continue; + } + } + } + return status; +} + +/**************************************************************************** +usage on the program +****************************************************************************/ +static void usage(char *pname) +{ + fprintf(out_hnd, + "Usage: %s [\\server] [password] [-U user] -[W domain] [-l log] ", + pname); + + fprintf(out_hnd, "\nVersion %s\n", VERSION); + fprintf(out_hnd, "\t-d debuglevel set the debuglevel\n"); + fprintf(out_hnd, + "\t-S <\\>server Server to connect to (\\. or . for localhost)\n"); + fprintf(out_hnd, + "\t-l log basename. Basename for log/debug files\n"); + fprintf(out_hnd, + "\t-n netbios name. Use this name as my netbios name\n"); + fprintf(out_hnd, + "\t-N don't ask for a password\n"); + fprintf(out_hnd, + "\t-m max protocol set the max protocol level\n"); + fprintf(out_hnd, + "\t-I dest IP use this IP to connect to\n"); + fprintf(out_hnd, + "\t-E write messages to stderr instead of stdout\n"); + fprintf(out_hnd, + "\t-U username set the network username\n"); + fprintf(out_hnd, + "\t-U username%%pass set the network username and password\n"); + fprintf(out_hnd, "\t-W domain set the domain name\n"); + fprintf(out_hnd, + "\t-c 'command string' execute semicolon separated commands\n"); + fprintf(out_hnd, + "\t-t terminal code terminal i/o code {sjis|euc|jis7|jis8|junet|hex}\n"); + fprintf(out_hnd, "\n"); +} + +#ifdef HAVE_READLINE + +/**************************************************************************** +GNU readline completion functions +****************************************************************************/ + +/* Complete an rpcclient command */ + +static char *complete_cmd(char *text, int state) +{ + static int cmd_index; + char *name; + + /* Initialise */ + + if (state == 0) + { + cmd_index = 0; + } + + /* Return the next name which partially matches the list of commands */ + + while ((cmd_index < num_commands) + && (strlen(name = commands[cmd_index++]->name) > 0)) + { + if (strncmp(name, text, strlen(text)) == 0) + { + return strdup(name); + } + } + + return NULL; +} + +/* Main completion function */ + +static char **completion_fn(char *text, int start, int end) +{ + pstring cmd_partial; + int cmd_index; + int num_words; + + int i; + char lastch = ' '; + + (void)get_cmd_args(rl_line_buffer); + + safe_strcpy(cmd_partial, rl_line_buffer, + MAX(sizeof(cmd_partial), end) - 1); + + /* Complete rpcclient command */ + + if (start == 0) + { + return completion_matches(text, complete_cmd); + } + + /* Count # of words in command */ + + num_words = 0; + for (i = 0; i <= end; i++) + { + if ((rl_line_buffer[i] != ' ') && (lastch == ' ')) + { + num_words++; + } + lastch = rl_line_buffer[i]; + } + + if (rl_line_buffer[end] == ' ') + num_words++; + + /* Work out which command we are completing for */ + + for (cmd_index = 0; cmd_index < num_commands; cmd_index++) + { + + /* Check each command in array */ + + 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]; + if (fn != NULL) + { + return completion_matches(text, fn); + } + } + } + } + + /* Eeek! */ + + return NULL; +} + +/* To avoid filename completion being activated when no valid + completions are found, we assign this stub completion function + to the rl_completion_entry_function variable. */ + +static char *complete_cmd_null(char *text, int state) +{ + return NULL; +} + +#endif /* HAVE_READLINE */ + +static void set_user_password(struct ntuser_creds *u, + BOOL got_pass, char *password) +{ + /* set the password cache info */ + if (got_pass) + { + if (password == NULL) + { + DEBUG(10, ("set_user_password: NULL pwd\n")); + pwd_set_nullpwd(&(u->pwd)); + } + else + { + /* generate 16 byte hashes */ + DEBUG(10, ("set_user_password: generate\n")); + pwd_make_lm_nt_16(&(u->pwd), password); + } + } + else + { + DEBUG(10, ("set_user_password: read\n")); + pwd_read(&(u->pwd), "Enter Password:", True); + } +} + +static uint32 cmd_use(struct client_info *info, int argc, char *argv[]) +{ + int opt; + BOOL net_use = False; + BOOL net_use_add = True; + BOOL force_close = False; + fstring dest_host; + fstring srv_name; + BOOL null_pwd = False; + BOOL got_pwd = False; + pstring password; + + + 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); + info->reuse = False; + + if (argc <= 1) + { + report(out_hnd, + "net [\\\\Server] [-U user%%pass] [-W domain] [-d] [-f]\n"); + report(out_hnd, " -d Deletes a connection\n"); + report(out_hnd, " -f Forcibly deletes a connection\n"); + report(out_hnd, "net -u Shows all connections\n"); + } + + if (argc > 1 && (*argv[1] != '-')) + { + if (strnequal("\\\\", argv[1], 2) || + strnequal("//", argv[1], 2)) + { + pstrcpy(dest_host, argv[1] + 2); + } + argc--; + argv++; + } + + while ((opt = getopt(argc, argv, "udU:W:")) != EOF) + { + switch (opt) + { + case 'u': + { + net_use = True; + break; + } + + case 'U': + { + char *lp; + pstrcpy(usr.ntc.user_name, optarg); + if ((lp = strchr(usr.ntc.user_name, '%'))) + { + *lp = 0; + pstrcpy(password, lp + 1); + memset(strchr(optarg, '%') + 1, 'X', + strlen(password)); + got_pwd = True; + } + if (usr.ntc.user_name[0] == 0 + && password[0] == 0) + { + null_pwd = True; + } + break; + } + + case 'N': + { + null_pwd = True; + } + case 'W': + { + pstrcpy(usr.ntc.domain, optarg); + break; + } + + case 'd': + { + net_use_add = False; + break; + } + + case 'f': + { + force_close = True; + break; + } + + default: + { + report(out_hnd, + "net -S \\server [-U user%%pass] [-W domain] [-d] [-f]\n"); + report(out_hnd, "net -u\n"); + break; + } + } + } + + if (strnequal("\\\\", dest_host, 2)) + { + fstrcpy(srv_name, dest_host); + } + else + { + fstrcpy(srv_name, "\\\\"); + fstrcat(srv_name, dest_host); + } + strupper(srv_name); + + if (net_use) + { + int i; + uint32 num_uses; + struct use_info **use; + cli_net_use_enum(&num_uses, &use); + + if (num_uses == 0) + { + report(out_hnd, "No connections\n"); + } + else + { + report(out_hnd, "Connections:\n"); + + for (i = 0; i < num_uses; i++) + { + 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); + } + } + } + } + else if (net_use_add) + { + 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); + + report(out_hnd, "Server:\t%s:\tUser:\t%s\tDomain:\t%s\n", + 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) + { + report(out_hnd, "OK\n"); + } + else + { + report(out_hnd, "FAILED\n"); + } + } + else + { + BOOL closed; + report(out_hnd, "Server:\t%s:\tUser:\t%s\tDomain:\t%s\n", + 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)) + { + 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 */ + ZERO_STRUCT(password); + + return 0; +} + +/****************************************************************** + allow or disallow automatic connections. rpctorture, because it + does not reestablish connections after sys_fork(), fails unless the + connection is established AFTER the sys_fork() + ******************************************************************/ +static BOOL auto_connect = True; +void cmd_set_no_autoconnect(void) +{ + auto_connect = False; +} + +#define CMD_STR 0x1 +#define CMD_DBF 0x2 +#define CMD_SVC 0x4 +#define CMD_TERM 0x8 +#define CMD_PASS 0x10 +#define CMD_USER 0x20 +#define CMD_NOPW 0x40 +#define CMD_DBLV 0x80 +#define CMD_HELP 0x100 +#define CMD_SOCK 0x200 +#define CMD_IFACE 0x400 +#define CMD_DOM 0x800 +#define CMD_IP 0x1000 +#define CMD_HOST 0x2000 +#define CMD_NAME 0x4000 +#define CMD_DBG 0x8000 +#define CMD_SCOPE 0x10000 +#define CMD_INTER 0x20000 + +static uint32 cmd_set(struct client_info *info, int argc, char *argv[]) +{ + BOOL interactive = True; + char *cmd_str = NULL; + int opt; + extern FILE *dbf; + extern char *optarg; + static pstring servicesf = CONFIGFILE; + pstring term_code; + pstring password; /* local copy only, if one is entered */ + fstring srv_name; + + password[0] = 0; + usr_creds = &usr; + info->reuse = False; +#ifdef KANJI + pstrcpy(term_code, KANJI); +#else /* KANJI */ + *term_code = 0; +#endif /* KANJI */ + + if (argc > 1 && (*argv[1] != '-')) + { + if (strnequal("\\\\", argv[1], 2) || + strnequal("//", argv[1], 2)) + { + cmd_set_options |= CMD_HOST; + pstrcpy(cli_info.dest_host, argv[1] + 2); + strupper(cli_info.dest_host); + } + argc--; + argv++; + } + if (argc > 1 && (*argv[1] != '-')) + { + cmd_set_options |= CMD_PASS; + pstrcpy(password, argv[1]); + memset(argv[1], 'X', strlen(argv[1])); + argc--; + argv++; + } + + while ((opt = getopt(argc, argv, + "Rs:O:M:S:i:Nn:d:l:hI:EB:U:L:t:m:W:T:D:c:")) != + EOF) + { + switch (opt) + { + case 'R': + { + info->reuse = True; + break; + } + + 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"); + break; + } + + case 'O': + { + cmd_set_options |= CMD_SOCK; + pstrcpy(user_socket_options, optarg); + break; + } + + case 'S': + { + cmd_set_options |= CMD_HOST; + pstrcpy(cli_info.dest_host, optarg); + strupper(cli_info.dest_host); + break; + } + + case 'U': + { + char *lp; + cmd_set_options |= CMD_USER; + pstrcpy(usr.ntc.user_name, optarg); + if ((lp = strchr(usr.ntc.user_name, '%'))) + { + *lp = 0; + pstrcpy(password, lp + 1); + cmd_set_options |= CMD_PASS; + memset(strchr(optarg, '%') + 1, 'X', + strlen(password)); + } + if (usr.ntc.user_name[0] == 0 + && password[0] == 0) + { + cmd_set_options |= CMD_NOPW; + } + break; + } + + case 'W': + { + cmd_set_options |= CMD_DOM; + pstrcpy(usr.ntc.domain, optarg); + break; + } + + case 'E': + { + cmd_set_options |= CMD_DBG; + dbf = stderr; + break; + } + + case 'I': + { + cmd_set_options |= CMD_IP; + cli_info.dest_ip = *interpret_addr2(optarg); + if (zero_ip(cli_info.dest_ip)) + { + free_connections(); + exit(1); + } + break; + } + + case 'n': + { + cmd_set_options |= CMD_NAME; + fstrcpy(global_myname, optarg); + break; + } + + case 'N': + { + cmd_set_options |= CMD_NOPW | CMD_PASS; + break; + } + + case 'd': + { + cmd_set_options |= CMD_DBLV; + if (*optarg == 'A') + DEBUGLEVEL = 10000; + else + DEBUGLEVEL = atoi(optarg); + break; + } + + case 'l': + { + cmd_set_options |= CMD_INTER; + slprintf(debugf, sizeof(debugf) - 1, + "%s.client", optarg); + interactive = False; + break; + } + + case 'c': + { + cmd_set_options |= CMD_STR | CMD_PASS; + cmd_str = optarg; + break; + } + + case 'h': + { + cmd_set_options |= CMD_HELP; + usage(argv[0]); + break; + } + + case 's': + { + cmd_set_options |= CMD_SVC; + pstrcpy(servicesf, optarg); + break; + } + + case 't': + { + cmd_set_options |= CMD_TERM; + pstrcpy(term_code, optarg); + break; + } + + default: + { + cmd_set_options |= CMD_HELP; + usage(argv[0]); + break; + } + } + } + + if (IS_BITS_SET_ALL(cmd_set_options, CMD_INTER)) + { + setup_logging(debugf, interactive); + if (!interactive) + reopen_logs(); + } + + strupper(global_myname); + fstrcpy(cli_info.myhostname, global_myname); + + if (IS_BITS_SET_ALL(cmd_set_options, CMD_SVC)) + { + if (!lp_load(servicesf, True, False, False)) + { + fprintf(stderr, + "Can't load %s - run testparm to debug it\n", + servicesf); + } + + } + + if (IS_BITS_SET_ALL(cmd_set_options, CMD_INTER)) + { + load_interfaces(); + } + + DEBUG(10, ("cmd_set: options: %x\n", cmd_set_options)); + + if (IS_BITS_SET_ALL(cmd_set_options, CMD_HELP)) + { + return 0; + } + + if (IS_BITS_SET_ALL(cmd_set_options, CMD_NOPW)) + { + set_user_password(&usr.ntc, True, NULL); + } + else + { + set_user_password(&usr.ntc, + IS_BITS_SET_ALL(cmd_set_options, CMD_PASS), + password); + } + + /* paranoia: destroy the local copy of the password */ + ZERO_STRUCT(password); + + 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)) { + report(out_hnd, "ERROR: Failed to find the PDC\n"); + return 1; + } + } + + fstrcpy(srv_name, "\\\\"); + fstrcat(srv_name, cli_info.dest_host); + strupper(srv_name); + + + if (auto_connect && !strequal(srv_name, "\\\\.")) + { + BOOL isnew; + report(out_hnd, "Server:\t%s:\tUser:\t%s\tDomain:\t%s\n", + 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) + { + report(out_hnd, "OK\n"); + } + else + { + report(out_hnd, "FAILED\n"); + } + usr_creds = NULL; + } + if (cmd_str != NULL) + { + return process(&cli_info, cmd_str); + } + + return 0; +} + +static void read_user_env(struct ntuser_creds *u) +{ + pstring password; + + password[0] = 0; + + if (getenv("USER")) + { + char *p; + pstrcpy(u->user_name, getenv("USER")); + + /* modification to support userid%passwd syntax in the USER var + 25.Aug.97, jdblair@uab.edu */ + + if ((p = strchr(u->user_name, '%'))) + { + *p = 0; + pstrcpy(password, p + 1); + 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); + + /* paranoia: destroy the local copy of the password */ + ZERO_STRUCT(password); +} + +static void readline_init(void) +{ +#ifdef HAVE_READLINE + /* Initialise GNU Readline */ rl_readline_name = "rpcclient"; + rl_attempted_completion_function = completion_fn; + rl_completion_entry_function = (Function *) complete_cmd_null; + + /* Initialise history list */ + + using_history(); + +#else + int x; + x = 0; /* stop compiler warnings */ +#endif /* HAVE_READLINE */ +} + +/**************************************************************************** + main program +****************************************************************************/ +int command_main(int argc, char *argv[]) +{ + uint32 status; + mode_t myumask = 0755; + char progname[255], path[255], *s; + pstring msg; + + DEBUGLEVEL = 2; + + charset_initialise(); + add_command_set(general_commands); + + copy_user_creds(&usr, NULL); + + usr_creds = &usr; + usr.ptr_ntc = 1; + + out_hnd = stdout; + + strncpy(path, argv[0], 255); + for (s = strtok(path, "/"); s; s = strtok(NULL, "/")) + fstrcpy(progname, s); + + slprintf(debugf, sizeof(debugf) - 1, + "%s/log.%s", LOGFILEBASE, progname); + + 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; + + ZERO_STRUCT(cli_info.dom.level3_sid); + ZERO_STRUCT(cli_info.dom.level5_sid); + fstrcpy(cli_info.dom.level3_dom, ""); + fstrcpy(cli_info.dom.level5_dom, ""); + + readline_init(); + TimeInit(); + init_connections(); + + myumask = umask(0); + umask(myumask); + + if (!get_myname(global_myname)) + { + fprintf(stderr, "Failed to get my hostname.\n"); + } + + if (argc < 2) + { + usage(argv[0]); + free_connections(); + exit(1); + } + + read_user_env(&usr.ntc); + + cmd_set_options &= ~CMD_HELP; + cmd_set_options &= ~CMD_STR; + cmd_set_options &= ~CMD_NOPW; + cmd_set_options &= ~CMD_USER; + cmd_set_options &= ~CMD_PASS; + + codepage_initialise(lp_client_code_page()); + + status = cmd_set(&cli_info, argc, argv); + + if (IS_BITS_SET_SOME(cmd_set_options, CMD_HELP|CMD_STR)) + { + free_connections(); + get_safe_nt_error_msg(status, msg, sizeof(msg)); + + report(out_hnd, "Exit Status: %s\n", msg); + /* unix only has 8 bit error codes - blergh */ + exit(status & 0xFF); + } + + DEBUG(3, ("%s client started (version %s)\n", + timestring(False), VERSION)); + + status = process(&cli_info, NULL); + + free_connections(); + + free_cmd_set_array(num_commands, commands); + num_commands = 0; + commands = NULL; + + get_safe_nt_error_msg(status, msg, sizeof(msg)); + report(out_hnd, "Exit Status: %s\n", msg); + + return status; +} diff --git a/source3/lib/msrpc-client.c b/source3/lib/msrpc-client.c index 60924ed81c..696413b4f9 100644 --- a/source3/lib/msrpc-client.c +++ b/source3/lib/msrpc-client.c @@ -129,6 +129,38 @@ BOOL msrpc_receive(int fd, prs_struct *ps) return True; } +/**************************************************************************** +close the socket descriptor +****************************************************************************/ +static void ncalrpc_l_close_socket(struct msrpc_local *msrpc) +{ + if (msrpc->fd != -1) + { + close(msrpc->fd); + } + msrpc->fd = -1; +} + + +/**************************************************************************** +shutdown a msrpcent structure +****************************************************************************/ +void ncalrpc_l_shutdown(struct msrpc_local *msrpc) +{ + DEBUG(10, ("msrpc_shutdown\n")); + if (msrpc->outbuf) + { + free(msrpc->outbuf); + } + if (msrpc->inbuf) + { + free(msrpc->inbuf); + } + ncalrpc_l_close_socket(msrpc); + memset(msrpc, 0, sizeof(*msrpc)); +} + + /**************************************************************************** open the msrpcent sockets ****************************************************************************/ diff --git a/source3/rpc_client/cli_connect.c b/source3/rpc_client/cli_connect.c new file mode 100644 index 0000000000..ded3e50354 --- /dev/null +++ b/source3/rpc_client/cli_connect.c @@ -0,0 +1,190 @@ +/* + Unix SMB/Netbios implementation. + Version 1.9. + SMB client generic functions + Copyright (C) Andrew Tridgell 1994-2000 + Copyright (C) Luke Kenneth Casson Leighton 1996-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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#define NO_SYSLOG + +#include "includes.h" +#include "rpc_parse.h" +#include "rpc_client.h" + +enum +{ MSRPC_NONE, MSRPC_LOCAL, MSRPC_SMB }; + +struct cli_connection +{ + uint32 num_connections; + char *srv_name; + char *pipe_name; + struct user_creds usr_creds; + + int type; + + union + { + struct ncacn_np *smb; + struct msrpc_local *local; + void *cli; + } msrpc; + + cli_auth_fns *auth; + void *auth_info; + void *auth_creds; +}; + +static struct cli_connection **con_list = NULL; +static uint32 num_cons = 0; + +struct user_creds *usr_creds = NULL; +vuser_key *user_key = NULL; + +extern int DEBUGLEVEL; + + +void init_connections(void) +{ + con_list = NULL; + num_cons = 0; + + init_cli_use(); +} + +static void free_con_array(uint32 num_entries, + struct cli_connection **entries) +{ + void (*fn) (void *) = (void (*)(void *))&cli_connection_free; + free_void_array(num_entries, (void **)entries, *fn); +} + + +void free_connections(void) +{ + DEBUG(3, ("free_connections: closing all MSRPC connections\n")); + free_con_array(num_cons, con_list); + free_cli_use(); + + init_connections(); +} + +/**************************************************************************** +terminate client connection +****************************************************************************/ +void cli_connection_free(struct cli_connection *con) +{ + BOOL closed = False; + void *oldcli = NULL; + int i; + + DEBUG(10, ("cli_connection_free: %d\n", __LINE__)); + + if (con->msrpc.cli != NULL) + { + switch (con->type) + { + case MSRPC_LOCAL: + { + DEBUG(10, ("msrpc local connection\n")); + ncalrpc_l_use_del(con->pipe_name, + &con->msrpc.local->nt.key, + False, &closed); + oldcli = con->msrpc.local; + con->msrpc.local = NULL; + break; + } + case MSRPC_SMB: + { + DEBUG(10, ("msrpc smb connection\n")); + ncacn_np_use_del(con->srv_name, + con->pipe_name, + &con->msrpc.smb->smb->key, + False, &closed); + oldcli = con->msrpc.local; + con->msrpc.smb = NULL; + break; + } + } + } + + DEBUG(10, ("cli_connection_free: closed: %s\n", BOOLSTR(closed))); + + if (closed) + { + for (i = 0; i < num_cons; i++) + { + struct cli_connection *c = con_list[i]; + if (c != NULL && con != c && c->msrpc.cli == oldcli) + { + /* WHOOPS! fnum already open: too bad!!! + get rid of all other connections that + were using that connection + */ + switch (c->type) + { + case MSRPC_LOCAL: + { + c->msrpc.local = NULL; + break; + } + case MSRPC_SMB: + { + c->msrpc.smb = NULL; + break; + } + } + } + } + } + + if (con->msrpc.cli != NULL) + { + free(con->msrpc.cli); + } + con->msrpc.cli = NULL; + + if (con->srv_name != NULL) + { + free(con->srv_name); + con->srv_name = NULL; + } + if (con->pipe_name != NULL) + { + free(con->pipe_name); + con->pipe_name = NULL; + } + + if (con->auth_info != NULL) + { + free(con->auth_info); + con->auth_info = NULL; + } + + memset(&con->usr_creds, 0, sizeof(con->usr_creds)); + + for (i = 0; i < num_cons; i++) + { + if (con == con_list[i]) + { + con_list[i] = NULL; + } + } + + free(con); +} diff --git a/source3/rpc_client/cli_use.c b/source3/rpc_client/cli_use.c new file mode 100644 index 0000000000..10997f028f --- /dev/null +++ b/source3/rpc_client/cli_use.c @@ -0,0 +1,448 @@ +/* + Unix SMB/Netbios implementation. + Version 1.9. + SMB client generic functions + Copyright (C) Andrew Tridgell 1994-1999 + Copyright (C) Luke Kenneth Casson Leighton 1996-1999 + + 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#define NO_SYSLOG + +#include "includes.h" +#include "trans2.h" +#include "rpc_client.h" + +extern int DEBUGLEVEL; +extern pstring scope; +extern pstring global_myname; + +struct cli_use +{ + struct cli_state *cli; + uint32 num_users; +}; + +static struct cli_use **clis = NULL; +static uint32 num_clis = 0; + +/**************************************************************************** +terminate client connection +****************************************************************************/ +static void cli_use_free(struct cli_use *cli) +{ + if (cli->cli != NULL) + { + if (cli->cli->initialised) + { + cli_ulogoff(cli->cli); + cli_shutdown(cli->cli); + } + free(cli->cli); + } + + free(cli); +} + +/**************************************************************************** +free a client array +****************************************************************************/ +static void free_cli_array(uint32 num_entries, struct cli_use **entries) +{ + void (*fn) (void *) = (void (*)(void *))&cli_use_free; + free_void_array(num_entries, (void **)entries, *fn); +} + +/**************************************************************************** +add a client state to the array +****************************************************************************/ +static struct cli_use *add_cli_to_array(uint32 *len, + struct cli_use ***array, + struct cli_use *cli) +{ + int i; + for (i = 0; i < num_clis; i++) + { + if (clis[i] == NULL) + { + clis[i] = cli; + return cli; + } + } + + return (struct cli_use *)add_item_to_array(len, + (void ***)array, + (void *)cli); + +} + +/**************************************************************************** +initiate client array +****************************************************************************/ +void init_cli_use(void) +{ + clis = NULL; + num_clis = 0; +} + +/**************************************************************************** +terminate client array +****************************************************************************/ +void free_cli_use(void) +{ + free_cli_array(num_clis, clis); + init_cli_use(); +} + +/**************************************************************************** +find client state. server name, user name, domain name and password must all +match. +****************************************************************************/ +static struct cli_use *cli_find(const char *srv_name, + const struct ntuser_creds *usr_creds, + BOOL reuse) +{ + int i; + const char *sv_name = srv_name; + struct ntuser_creds null_usr; + + if (usr_creds == NULL) + { + copy_nt_creds(&null_usr, usr_creds); + usr_creds = &null_usr; + } + + if (strnequal("\\\\", sv_name, 2)) + { + sv_name = &sv_name[2]; + } + + DEBUG(10, ("cli_find: %s %s %s reuse: %s\n", + srv_name, usr_creds->user_name, usr_creds->domain, + BOOLSTR(reuse))); + + + for (i = 0; i < num_clis; i++) + { + char *cli_name = NULL; + struct cli_use *c = clis[i]; + + if (c == NULL || !c->cli->initialised || c->cli->fd == -1) + { + continue; + } + + cli_name = c->cli->desthost; + + DEBUG(10, ("cli_find[%d]: %s %s %s\n", + i, cli_name, + c->cli->user_name, c->cli->domain)); + + if (strnequal("\\\\", cli_name, 2)) + { + cli_name = &cli_name[2]; + } + + if (!strequal(cli_name, sv_name)) + { + continue; + } + if (strequal(usr_creds->user_name, "") && + strequal(usr_creds->domain, "") && + pwd_is_nullpwd(&usr_creds->pwd)) + { + return c; + } + if (!strequal(usr_creds->user_name, c->cli->user_name)) + { + continue; + } + if (!reuse && !pwd_compare(&usr_creds->pwd, &c->cli->pwd)) + { + DEBUG(100, ("password doesn't match\n")); + continue; + } + if (usr_creds->domain[0] == 0) + { + return c; + } + if (strequal(usr_creds->domain, c->cli->domain)) + { + return c; + } + } + + return NULL; +} + +/**************************************************************************** +create a new client state from user credentials +****************************************************************************/ +static struct cli_use *cli_use_get(const char *srv_name, + const struct ntuser_creds *usr_creds) +{ + struct cli_use *cli = (struct cli_use *)malloc(sizeof(*cli)); + + if (cli == NULL) + { + return NULL; + } + + memset(cli, 0, sizeof(*cli)); + + cli->cli = cli_initialise(NULL); + + if (cli->cli == NULL) + { + return NULL; + } + + cli_init_creds(cli->cli, usr_creds); + + return cli; +} + +/**************************************************************************** +init client state +****************************************************************************/ +struct cli_state *cli_net_use_add(const char *srv_name, + const struct ntuser_creds *usr_creds, + BOOL reuse, BOOL *is_new) +{ + struct nmb_name calling; + struct nmb_name called; + struct in_addr *dest_ip = NULL; + fstring dest_host; + struct in_addr ip; + struct cli_use *cli; + + DEBUG(10, ("cli_net_use_add\n")); + + cli = cli_find(srv_name, usr_creds, reuse); + + if (cli != NULL) + { + cli->num_users++; + DEBUG(10, + ("cli_net_use_add: num_users: %d\n", cli->num_users)); + (*is_new) = False; + return cli->cli; + } + + /* reuse an existing connection requested, and one was not found */ + if (usr_creds != NULL && reuse) + { + return False; + } + + /* + * allocate + */ + + cli = cli_use_get(srv_name, usr_creds); + + if (resolve_srv_name(srv_name, dest_host, &ip)) + { + dest_ip = &ip; + } + else + { + cli_use_free(cli); + return NULL; + } + + make_nmb_name(&called, dns_to_netbios_name(dest_host), 0x20); + make_nmb_name(&calling, dns_to_netbios_name(global_myname), 0); + + /* + * connect + */ + + if (!cli_establish_connection(cli->cli, + dest_host, dest_ip, + &calling, &called, + "IPC$", "IPC", False, True)) + { + DEBUG(0, ("cli_net_use_add: connection failed\n")); + cli_use_free(cli); + return NULL; + } + + add_cli_to_array(&num_clis, &clis, cli); + cli->num_users++; + + DEBUG(10, ("cli_net_use_add: num_users: %d\n", cli->num_users)); + + (*is_new) = True; + + return cli->cli; +} + +/**************************************************************************** +delete a client state +****************************************************************************/ +BOOL cli_net_use_del(const char *srv_name, + const struct ntuser_creds *usr_creds, + BOOL force_close, BOOL *connection_closed) +{ + int i; + const char *sv_name = srv_name; + + DEBUG(10, ("cli_net_use_del: %s. %s. %s. force close: %s\n", + srv_name, + usr_creds ? usr_creds->user_name : "", + usr_creds ? usr_creds->domain : "", BOOLSTR(force_close))); + + if (strnequal("\\\\", sv_name, 2)) + { + sv_name = &sv_name[2]; + } + + if (connection_closed != NULL) + { + *connection_closed = False; + } + + for (i = 0; i < num_clis; i++) + { + char *cli_name = NULL; + + if (clis[i] == NULL) + continue; + if (clis[i]->cli == NULL) + continue; + + cli_name = clis[i]->cli->desthost; + + DEBUG(10, ("connection: %s %s %s\n", cli_name, + clis[i]->cli->user_name, + clis[i]->cli->domain)); + + if (strnequal("\\\\", cli_name, 2)) + { + cli_name = &cli_name[2]; + } + + if (!strequal(cli_name, sv_name)) + continue; + + if (strequal(usr_creds ? usr_creds->user_name : "", + clis[i]->cli->user_name) && + strequal(usr_creds ? usr_creds->domain : "", + clis[i]->cli->domain)) + { + /* decrement number of users */ + clis[i]->num_users--; + + DEBUG(10, ("idx: %i num_users now: %d\n", + i, clis[i]->num_users)); + + if (force_close || clis[i]->num_users == 0) + { + cli_use_free(clis[i]); + clis[i] = NULL; + if (connection_closed != NULL) + { + *connection_closed = True; + } + } + return True; + } + } + + return False; +} + +/**************************************************************************** +enumerate client states +****************************************************************************/ +void cli_net_use_enum(uint32 *num_cons, struct use_info ***use) +{ + int i; + + *num_cons = 0; + *use = NULL; + + for (i = 0; i < num_clis; i++) + { + struct use_info item; + + ZERO_STRUCT(item); + + if (clis[i] == NULL) + continue; + + item.connected = clis[i]->cli != NULL ? True : False; + + if (item.connected) + { + item.srv_name = clis[i]->cli->desthost; + item.user_name = clis[i]->cli->user_name; + item.key = clis[i]->cli->key; + item.domain = clis[i]->cli->domain; + } + + add_use_info_to_array(num_cons, use, &item); + } +} + + +/**************************************************************************** +wait for keyboard activity, swallowing network packets on all client states. +****************************************************************************/ +void cli_use_wait_keyboard(void) +{ + fd_set fds; + struct timeval timeout; + + while (1) + { + int i; + int maxfd = fileno(stdin); + FD_ZERO(&fds); + FD_SET(fileno(stdin), &fds); + for (i = 0; i < num_clis; i++) + { + if (clis[i] != NULL && clis[i]->cli != NULL) + { + int fd = clis[i]->cli->fd; + FD_SET(fd, &fds); + maxfd = MAX(fd, maxfd); + } + } + + timeout.tv_sec = 20; + timeout.tv_usec = 0; + sys_select(maxfd + 1, &fds, &timeout); + + if (FD_ISSET(fileno(stdin), &fds)) + return; + + /* We deliberately use receive_smb instead of + client_receive_smb as we want to receive + session keepalives and then drop them here. + */ + for (i = 0; i < num_clis; i++) + { + int fd; + if (clis[i] == NULL || clis[i]->cli == NULL) + continue; + fd = clis[i]->cli->fd; + if (FD_ISSET(fd, &fds)) + receive_smb(fd, clis[i]->cli->inbuf, 0); + } + } +} diff --git a/source3/rpc_client/ncacn_np_use.c b/source3/rpc_client/ncacn_np_use.c new file mode 100644 index 0000000000..e658edbd63 --- /dev/null +++ b/source3/rpc_client/ncacn_np_use.c @@ -0,0 +1,173 @@ +/* + Unix SMB/Netbios implementation. + Version 1.9. + SMB client generic functions + Copyright (C) Andrew Tridgell 1994-2000 + Copyright (C) Luke Kenneth Casson Leighton 1996-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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#define NO_SYSLOG + +#include "includes.h" +#include "rpc_parse.h" +#include "rpc_client.h" +#include "trans2.h" + +extern int DEBUGLEVEL; +extern pstring global_myname; + +struct ncacn_np_use +{ + struct ncacn_np *cli; + uint32 num_users; +}; + +static struct ncacn_np_use **msrpcs = NULL; +static uint32 num_msrpcs = 0; + +/**************************************************************************** +terminate client connection +****************************************************************************/ +static void ncacn_np_shutdown(struct ncacn_np *cli) +{ + if (cli != NULL) + { + if (cli->smb != NULL) + { + if (cli->smb->initialised) + { + /* cli_nt_session_close(cli->smb, cli->fnum); JERRY */ + cli_nt_session_close(cli->smb); + } +#if 0 /* commented out by JERRY */ + cli_net_use_del(cli->smb->desthost, + &cli->smb->usr, False, False); +#endif + } + } +} + + +/**************************************************************************** +terminate client connection +****************************************************************************/ +static void ncacn_np_use_free(struct ncacn_np_use *cli) +{ + if (cli->cli != NULL) + { + if (cli->cli->initialised) + { + ncacn_np_shutdown(cli->cli); + } + ZERO_STRUCTP(cli->cli); + free(cli->cli); + } + ZERO_STRUCTP(cli); + free(cli); +} + + +/**************************************************************************** +delete a client state +****************************************************************************/ +BOOL ncacn_np_use_del(const char *srv_name, const char *pipe_name, + const vuser_key * key, + BOOL force_close, BOOL *connection_closed) +{ + int i; + DEBUG(10, ("ncacn_np_net_use_del: %s. force close: %s ", + pipe_name, BOOLSTR(force_close))); + if (key != NULL) + { + DEBUG(10, ("[%d,%x]", key->pid, key->vuid)); + } + DEBUG(10, ("\n")); + + if (connection_closed != NULL) + { + *connection_closed = False; + } + + if (strnequal("\\PIPE\\", pipe_name, 6)) + { + pipe_name = &pipe_name[6]; + } + + if (strnequal("\\\\", srv_name, 2)) + { + srv_name = &srv_name[6]; + } + + for (i = 0; i < num_msrpcs; i++) + { + char *ncacn_np_name = NULL; + char *ncacn_np_srv_name = NULL; + struct ncacn_np_use *c = msrpcs[i]; + vuser_key k; + + if (c == NULL || c->cli == NULL || c->cli->smb == NULL) + continue; + + ncacn_np_name = c->cli->pipe_name; + ncacn_np_srv_name = c->cli->smb->desthost; + + k = c->cli->smb->key; + + DEBUG(10, ("use_del[%d]: %s %s %s %s [%d,%x]\n", + i, ncacn_np_name, ncacn_np_srv_name, + c->cli->smb->user_name, + c->cli->smb->domain, k.pid, k.vuid)); + + if (strnequal("\\PIPE\\", ncacn_np_name, 6)) + { + ncacn_np_name = &ncacn_np_name[6]; + } + if (!strequal(ncacn_np_srv_name, srv_name)) + { + continue; + } + if (strnequal("\\\\", ncacn_np_srv_name, 2)) + { + ncacn_np_srv_name = &ncacn_np_srv_name[6]; + } + if (!strequal(ncacn_np_name, pipe_name)) + { + continue; + } + if (key->pid != k.pid || key->vuid != k.vuid) + { + continue; + } + /* decrement number of users */ + c->num_users--; + DEBUG(10, ("idx: %i num_users now: %d\n", + i, c->num_users)); + if (force_close || c->num_users == 0) + { + ncacn_np_use_free(c); + msrpcs[i] = NULL; + if (connection_closed != NULL) + { + *connection_closed = True; + } + } + return True; + } + + return False; +} + diff --git a/source3/rpc_client/ncalrpc_l_use.c b/source3/rpc_client/ncalrpc_l_use.c new file mode 100644 index 0000000000..81ade8e1a6 --- /dev/null +++ b/source3/rpc_client/ncalrpc_l_use.c @@ -0,0 +1,127 @@ +/* + Unix SMB/Netbios implementation. + Version 1.9. + SMB client generic functions + Copyright (C) Andrew Tridgell 1994-1999 + Copyright (C) Luke Kenneth Casson Leighton 1996-1999 + + 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#define NO_SYSLOG + +#include "includes.h" +#include "rpc_parse.h" + +extern int DEBUGLEVEL; + +struct ncalrpc_use +{ + struct msrpc_local *cli; + uint32 num_users; +}; + +static struct ncalrpc_use **clis = NULL; +static uint32 num_clis = 0; + +/**************************************************************************** +terminate client connection +****************************************************************************/ +static void ncalrpc_use_free(struct ncalrpc_use *cli) +{ + if (cli->cli != NULL) + { + if (cli->cli->initialised) + { + ncalrpc_l_shutdown(cli->cli); + } + free(cli->cli); + } + + free(cli); +} + +/**************************************************************************** +delete a client state +****************************************************************************/ +BOOL ncalrpc_l_use_del(const char *pipe_name, + const vuser_key * key, + BOOL force_close, BOOL *connection_closed) +{ + int i; + + if (strnequal("\\PIPE\\", pipe_name, 6)) + { + pipe_name = &pipe_name[6]; + } + + DEBUG(10, ("ncalrpc_l_use_del: %s. [%d,%x] force close: %s\n", + pipe_name, key->pid, key->vuid, BOOLSTR(force_close))); + + if (connection_closed != NULL) + { + *connection_closed = False; + } + + for (i = 0; i < num_clis; i++) + { + char *ncalrpc_name = NULL; + + if (clis[i] == NULL) + continue; + if (clis[i]->cli == NULL) + continue; + + ncalrpc_name = clis[i]->cli->pipe_name; + + if (strnequal("\\PIPE\\", pipe_name, 6)) + { + ncalrpc_name = &ncalrpc_name[6]; + } + + DEBUG(10, ("connection: %s [%d,%x]", ncalrpc_name, + clis[i]->cli->nt.key.pid, + clis[i]->cli->nt.key.vuid)); + + if (!strequal(ncalrpc_name, pipe_name)) + continue; + + if (key->pid != clis[i]->cli->nt.key.pid || + key->vuid != clis[i]->cli->nt.key.vuid) + { + continue; + } + /* decrement number of users */ + clis[i]->num_users--; + + DEBUG(10, ("idx: %i num_users now: %d\n", + i, clis[i]->num_users)); + + if (force_close || clis[i]->num_users == 0) + { + ncalrpc_use_free(clis[i]); + clis[i] = NULL; + if (connection_closed != NULL) + { + *connection_closed = True; + } + } + return True; + } + + return False; +} + + diff --git a/source3/rpcclient/rpcclient.c b/source3/rpcclient/rpcclient.c index 0a91f255c1..b30d2b2da0 100644 --- a/source3/rpcclient/rpcclient.c +++ b/source3/rpcclient/rpcclient.c @@ -2,7 +2,8 @@ Unix SMB/Netbios implementation. Version 1.9. SMB client - Copyright (C) Andrew Tridgell 1994-1998 + Copyright (C) Andrew Tridgell 1994-2000 + Copyright (C) Luke Kenneth Casson Leighton 1996-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 @@ -19,754 +20,24 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#ifdef SYSLOG -#undef SYSLOG -#endif - #include "includes.h" +#include "ntdomain.h" +#include "rpcclient.h" -#ifndef REGISTER -#define REGISTER 0 -#endif - -extern pstring debugf; -extern pstring global_myname; - -extern pstring user_socket_options; - - -extern int DEBUGLEVEL; - - -extern file_info def_finfo; - -#define CNV_LANG(s) dos2unix_format(s,False) -#define CNV_INPUT(s) unix2dos_format(s,True) - -static int process_tok(fstring tok); -static void cmd_help(struct client_info *info); -static void cmd_quit(struct client_info *info); - -static struct cli_state smbcli; -struct cli_state *smb_cli = &smbcli; - -FILE *out_hnd; - -/**************************************************************************** -initialise smb client structure -****************************************************************************/ -void rpcclient_init(void) -{ - memset((char *)smb_cli, '\0', sizeof(smb_cli)); - cli_initialise(smb_cli); - smb_cli->capabilities |= CAP_NT_SMBS | CAP_STATUS32; -} - -/**************************************************************************** -make smb client connection -****************************************************************************/ -static BOOL rpcclient_connect(struct client_info *info) -{ - struct nmb_name calling; - struct nmb_name called; - - make_nmb_name(&called , dns_to_netbios_name(info->dest_host ), info->name_type); - make_nmb_name(&calling, dns_to_netbios_name(info->myhostname), 0x0 ); - - if (!cli_establish_connection(smb_cli, - info->dest_host, &info->dest_ip, - &calling, &called, - info->share, info->svc_type, - False, True)) - { - DEBUG(0,("rpcclient_connect: connection failed\n")); - cli_shutdown(smb_cli); - return False; - } - - return True; -} - -/**************************************************************************** -stop the smb connection(s?) -****************************************************************************/ -static void rpcclient_stop(void) + int main(int argc, char *argv[]) { - cli_shutdown(smb_cli); -} -/**************************************************************************** - This defines the commands supported by this client - ****************************************************************************/ -struct -{ - char *name; - void (*fn)(struct client_info*); - char *description; -} commands[] = -{ - {"regenum", cmd_reg_enum, " Registry Enumeration (keys, values)"}, - {"regdeletekey",cmd_reg_delete_key, " Registry Key Delete"}, - {"regcreatekey",cmd_reg_create_key, " [keyclass] Registry Key Create"}, - {"regquerykey",cmd_reg_query_key, " Registry Key Query"}, - {"regdeleteval",cmd_reg_delete_val, " Registry Value Delete"}, - {"regcreateval",cmd_reg_create_val, " Registry Key Create"}, - {"reggetsec", cmd_reg_get_key_sec, " Registry Key Security"}, - {"regtestsec", cmd_reg_test_key_sec, " Test Registry Key Security"}, - {"ntlogin", cmd_netlogon_login_test, "[username] [password] NT Domain login test"}, - {"wksinfo", cmd_wks_query_info, "Workstation Query Info"}, - {"srvinfo", cmd_srv_query_info, "Server Query Info"}, - {"srvsessions",cmd_srv_enum_sess, "List sessions on a server"}, - {"srvshares", cmd_srv_enum_shares, "List shares on a server"}, - {"srvconnections",cmd_srv_enum_conn, "List connections on a server"}, - {"srvfiles", cmd_srv_enum_files, "List files on a server"}, - {"lsaquery", cmd_lsa_query_info, "Query Info Policy (domain member or server)"}, - {"lookupsids", cmd_lsa_lookup_sids, "Resolve names from SIDs"}, - {"enumusers", cmd_sam_enum_users, "SAM User Database Query (experimental!)"}, - {"ntpass", cmd_sam_ntchange_pwd, "NT SAM Password Change"}, - {"samuser", cmd_sam_query_user, " SAM User Query (experimental!)"}, - {"samtest", cmd_sam_test , "SAM User Encrypted RPC test (experimental!)"}, - {"enumaliases",cmd_sam_enum_aliases, "SAM Aliases Database Query (experimental!)"}, #if 0 - {"enumgroups", cmd_sam_enum_groups, "SAM Group Database Query (experimental!)"}, -#endif - {"samgroups", cmd_sam_query_groups, "SAM Group Database Query (experimental!)"}, - {"quit", cmd_quit, "logoff the server"}, - {"q", cmd_quit, "logoff the server"}, - {"exit", cmd_quit, "logoff the server"}, - {"bye", cmd_quit, "logoff the server"}, - {"help", cmd_help, "[command] give help on a command"}, - {"?", cmd_help, "[command] give help on a command"}, - {"!", NULL, "run a shell command on the local system"}, - {"", NULL, NULL} -}; - - -/**************************************************************************** -do a (presumably graceful) quit... -****************************************************************************/ -static void cmd_quit(struct client_info *info) -{ - rpcclient_stop(); - exit(0); -} - -/**************************************************************************** -help -****************************************************************************/ -static void cmd_help(struct client_info *info) -{ - int i=0,j; - fstring buf; - - if (next_token(NULL,buf,NULL, sizeof(buf))) - { - if ((i = process_tok(buf)) >= 0) - fprintf(out_hnd, "HELP %s:\n\t%s\n\n",commands[i].name,commands[i].description); - } - else - while (commands[i].description) - { - for (j=0; commands[i].description && (j<5); j++) { - fprintf(out_hnd, "%-15s",commands[i].name); - i++; - } - fprintf(out_hnd, "\n"); - } -} - -/******************************************************************* - lookup a command string in the list of commands, including - abbreviations - ******************************************************************/ -static int process_tok(fstring tok) -{ - int i = 0, matches = 0; - int cmd=0; - int tok_len = strlen(tok); - - while (commands[i].fn != NULL) - { - if (strequal(commands[i].name,tok)) - { - matches = 1; - cmd = i; - break; - } - else if (strnequal(commands[i].name, tok, tok_len)) - { - matches++; - cmd = i; - } - i++; - } - - if (matches == 0) - return(-1); - else if (matches == 1) - return(cmd); - else - return(-2); -} - -/**************************************************************************** -wait for keyboard activity, swallowing network packets -****************************************************************************/ -static void wait_keyboard(struct cli_state *cli) -{ - fd_set fds; - struct timeval timeout; - - while (1) - { - FD_ZERO(&fds); - FD_SET(cli->fd,&fds); - FD_SET(fileno(stdin),&fds); - - timeout.tv_sec = 20; - timeout.tv_usec = 0; - sys_select_intr(MAX(cli->fd,fileno(stdin))+1,&fds,&timeout); - - if (FD_ISSET(fileno(stdin),&fds)) - return; - - /* We deliberately use receive_smb instead of - client_receive_smb as we want to receive - session keepalives and then drop them here. - */ - if (FD_ISSET(cli->fd,&fds)) - receive_smb(cli->fd,cli->inbuf,0); - } -} - -/**************************************************************************** - process commands from the client -****************************************************************************/ -static void do_command(struct client_info *info, char *tok, char *line) -{ - int i; - - if ((i = process_tok(tok)) >= 0) - { - commands[i].fn(info); - } - else if (i == -2) - { - fprintf(out_hnd, "%s: command abbreviation ambiguous\n", CNV_LANG(tok)); - } - else - { - fprintf(out_hnd, "%s: command not found\n", CNV_LANG(tok)); - } -} - -/**************************************************************************** - process commands from the client -****************************************************************************/ -static BOOL process( struct client_info *info, char *cmd_str) -{ - pstring line; - char *cmd = cmd_str; - - if (cmd[0] != '\0') while (cmd[0] != '\0') - { - char *p; - fstring tok; - - if ((p = strchr(cmd, ';')) == 0) - { - strncpy(line, cmd, 999); - line[1000] = '\0'; - cmd += strlen(cmd); - } - else - { - if (p - cmd > 999) p = cmd + 999; - strncpy(line, cmd, p - cmd); - line[p - cmd] = '\0'; - cmd = p + 1; - } - - /* input language code to internal one */ - CNV_INPUT (line); - - /* get the first part of the command */ - { - char *ptr = line; - if (!next_token(&ptr,tok,NULL, sizeof(tok))) continue; - } - - do_command(info, tok, line); - } - else while (!feof(stdin)) - { - fstring tok; - - /* display a prompt */ - fprintf(out_hnd, "smb: %s> ", CNV_LANG(info->cur_dir)); - fflush(out_hnd); - -#ifdef CLIX - line[0] = wait_keyboard(smb_cli); - /* this might not be such a good idea... */ - if ( line[0] == EOF) - { - break; - } -#else - wait_keyboard(smb_cli); -#endif - - /* and get a response */ -#ifdef CLIX - fgets( &line[1],999, stdin); -#else - if (!fgets(line,1000,stdin)) - { - break; - } -#endif - - /* input language code to internal one */ - CNV_INPUT (line); - - /* special case - first char is ! */ - if (*line == '!') - { - system(line + 1); - continue; - } - - fprintf(out_hnd, "%s\n", line); - - /* get the first part of the command */ - { - char *ptr = line; - if (!next_token(&ptr,tok,NULL, sizeof(tok))) continue; - } - - do_command(info, tok, line); - } - - return(True); -} - -/**************************************************************************** -usage on the program -****************************************************************************/ -static void usage(char *pname) -{ - fprintf(out_hnd, "Usage: %s service [-d debuglevel] [-l log] ", - pname); - - fprintf(out_hnd, "\nVersion %s\n",VERSION); - fprintf(out_hnd, "\t-d debuglevel set the debuglevel\n"); - fprintf(out_hnd, "\t-l log basename. Basename for log/debug files\n"); - fprintf(out_hnd, "\t-n netbios name. Use this name as my netbios name\n"); - fprintf(out_hnd, "\t-N don't ask for a password\n"); - fprintf(out_hnd, "\t-m max protocol set the max protocol level\n"); - fprintf(out_hnd, "\t-I dest IP use this IP to connect to\n"); - fprintf(out_hnd, "\t-E write messages to stderr instead of stdout\n"); - fprintf(out_hnd, "\t-U username set the network username\n"); - fprintf(out_hnd, "\t-W workgroup set the workgroup name\n"); - fprintf(out_hnd, "\t-c command string execute semicolon separated commands\n"); - fprintf(out_hnd, "\t-t terminal code terminal i/o code {sjis|euc|jis7|jis8|junet|hex}\n"); - fprintf(out_hnd, "\n"); -} - -enum client_action -{ - CLIENT_NONE, - CLIENT_IPC, - CLIENT_SVC -}; - -/**************************************************************************** - main program -****************************************************************************/ - int main(int argc,char *argv[]) -{ - BOOL interactive = True; - int opt; - extern FILE *dbf; - extern char *optarg; - extern int optind; - static pstring servicesf = CONFIGFILE; - pstring term_code; - char *p; - BOOL got_pass = False; - char *cmd_str=""; - mode_t myumask = 0755; - enum client_action cli_action = CLIENT_NONE; - - struct client_info cli_info; - - pstring password; /* local copy only, if one is entered */ - - printf("Please use rpcclient from the SAMBA_TNG cvs tag.\n"); - printf("Please refer to http://samba.org/cvs.html for details.\n"); -/* -#ifndef DEBUG_PASSWORD - exit(-1); + add_lsa_commands(); + add_net_commands(); + add_evt_commands(); + add_sam_commands(); + add_svc_commands(); + add_reg_commands(); + add_ntl_commands(); + add_at_commands(); + add_spl_commands(); + add_dfs_commands(); #endif -*/ - - out_hnd = stdout; - fstrcpy(debugf, argv[0]); - - rpcclient_init(); - -#ifdef KANJI - pstrcpy(term_code, KANJI); -#else /* KANJI */ - *term_code = 0; -#endif /* KANJI */ - - DEBUGLEVEL = 2; - - cli_info.put_total_size = 0; - cli_info.put_total_time_ms = 0; - cli_info.get_total_size = 0; - cli_info.get_total_time_ms = 0; - - cli_info.dir_total = 0; - cli_info.newer_than = 0; - cli_info.archive_level = 0; - cli_info.print_mode = 1; - - cli_info.translation = False; - cli_info.recurse_dir = False; - cli_info.lowercase = False; - cli_info.prompt = True; - cli_info.abort_mget = True; - - cli_info.dest_ip.s_addr = 0; - cli_info.name_type = 0x20; - - pstrcpy(cli_info.cur_dir , "\\"); - pstrcpy(cli_info.file_sel, ""); - pstrcpy(cli_info.base_dir, ""); - pstrcpy(smb_cli->domain, ""); - pstrcpy(smb_cli->user_name, ""); - pstrcpy(cli_info.myhostname, ""); - pstrcpy(cli_info.dest_host, ""); - - pstrcpy(cli_info.svc_type, "A:"); - pstrcpy(cli_info.share, ""); - pstrcpy(cli_info.service, ""); - - ZERO_STRUCT(cli_info.dom.level3_sid); - ZERO_STRUCT(cli_info.dom.level5_sid); - fstrcpy(cli_info.dom.level3_dom, ""); - fstrcpy(cli_info.dom.level5_dom, ""); - - smb_cli->nt_pipe_fnum = 0xffff; - - TimeInit(); - charset_initialise(); - - myumask = umask(0); - umask(myumask); - - if (!get_myname(global_myname)) - { - fprintf(stderr, "Failed to get my hostname.\n"); - } - - if (getenv("USER")) - { - pstrcpy(smb_cli->user_name,getenv("USER")); - - /* modification to support userid%passwd syntax in the USER var - 25.Aug.97, jdblair@uab.edu */ - - if ((p=strchr(smb_cli->user_name,'%'))) - { - *p = 0; - pstrcpy(password,p+1); - got_pass = True; - memset(strchr(getenv("USER"),'%')+1,'X',strlen(password)); - } - strupper(smb_cli->user_name); - } - - password[0] = 0; - - /* modification to support PASSWD environmental var - 25.Aug.97, jdblair@uab.edu */ - if (getenv("PASSWD")) - { - pstrcpy(password,getenv("PASSWD")); - } - - if (*smb_cli->user_name == 0 && getenv("LOGNAME")) - { - pstrcpy(smb_cli->user_name,getenv("LOGNAME")); - strupper(smb_cli->user_name); - } - - if (argc < 2) - { - usage(argv[0]); - exit(1); - } - - if (*argv[1] != '-') - { - - pstrcpy(cli_info.service, argv[1]); - /* Convert any '/' characters in the service name to '\' characters */ - string_replace( cli_info.service, '/','\\'); - argc--; - argv++; - - fprintf(out_hnd, "service: %s\n", cli_info.service); - - if (count_chars(cli_info.service,'\\') < 3) - { - usage(argv[0]); - printf("\n%s: Not enough '\\' characters in service\n", cli_info.service); - exit(1); - } - - /* - if (count_chars(cli_info.service,'\\') > 3) - { - usage(pname); - printf("\n%s: Too many '\\' characters in service\n", cli_info.service); - exit(1); - } - */ - - if (argc > 1 && (*argv[1] != '-')) - { - got_pass = True; - pstrcpy(password,argv[1]); - memset(argv[1],'X',strlen(argv[1])); - argc--; - argv++; - } - - cli_action = CLIENT_SVC; - } - - while ((opt = getopt(argc, argv,"s:O:M:S:i:N:n:d:l:hI:EB:U:L:t:m:W:T:D:c:")) != EOF) - { - switch (opt) - { - 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"); - break; - } - - case 'O': - { - pstrcpy(user_socket_options,optarg); - break; - } - - case 'S': - { - pstrcpy(cli_info.dest_host,optarg); - strupper(cli_info.dest_host); - cli_action = CLIENT_IPC; - break; - } - - case 'i': - { - extern pstring global_scope; - pstrcpy(global_scope, optarg); - strupper(global_scope); - break; - } - - case 'U': - { - char *lp; - pstrcpy(smb_cli->user_name,optarg); - if ((lp=strchr(smb_cli->user_name,'%'))) - { - *lp = 0; - pstrcpy(password,lp+1); - got_pass = True; - memset(strchr(optarg,'%')+1,'X',strlen(password)); - } - break; - } - - case 'W': - { - pstrcpy(smb_cli->domain,optarg); - break; - } - - case 'E': - { - dbf = stderr; - break; - } - - case 'I': - { - cli_info.dest_ip = *interpret_addr2(optarg); - if (zero_ip(cli_info.dest_ip)) - { - exit(1); - } - break; - } - - case 'n': - { - fstrcpy(global_myname, optarg); - break; - } - - case 'N': - { - got_pass = True; - break; - } - - case 'd': - { - if (*optarg == 'A') - DEBUGLEVEL = 10000; - else - DEBUGLEVEL = atoi(optarg); - break; - } - - case 'l': - { - slprintf(debugf, sizeof(debugf)-1, - "%s.client", optarg); - interactive = False; - break; - } - - case 'c': - { - cmd_str = optarg; - got_pass = True; - break; - } - - case 'h': - { - usage(argv[0]); - exit(0); - break; - } - - case 's': - { - pstrcpy(servicesf, optarg); - break; - } - - case 't': - { - pstrcpy(term_code, optarg); - break; - } - - default: - { - usage(argv[0]); - exit(1); - break; - } - } - } - - setup_logging(debugf, interactive); - - if (cli_action == CLIENT_NONE) - { - usage(argv[0]); - exit(1); - } - - strupper(global_myname); - fstrcpy(cli_info.myhostname, global_myname); - - DEBUG(3,("%s client started (version %s)\n",timestring(False),VERSION)); - - if (!lp_load(servicesf,True, False, False)) - { - fprintf(stderr, "Can't load %s - run testparm to debug it\n", servicesf); - } - - codepage_initialise(lp_client_code_page()); - - if (*smb_cli->domain == 0) pstrcpy(smb_cli->domain,lp_workgroup()); - - load_interfaces(); - - if (cli_action == CLIENT_IPC) - { - pstrcpy(cli_info.share, "IPC$"); - pstrcpy(cli_info.svc_type, "IPC"); - } - - fstrcpy(cli_info.mach_acct, cli_info.myhostname); - strupper(cli_info.mach_acct); - fstrcat(cli_info.mach_acct, "$"); - - /* set the password cache info */ - if (got_pass) - { - if (password[0] == 0) - { - pwd_set_nullpwd(&(smb_cli->pwd)); - } - else - { - pwd_make_lm_nt_16(&(smb_cli->pwd), password); /* generate 16 byte hashes */ - } - } - else - { - pwd_read(&(smb_cli->pwd), "Enter Password:", True); - } - - /* paranoia: destroy the local copy of the password */ - memset((char *)password, '\0', sizeof(password)); - - /* establish connections. nothing to stop these being re-established. */ - rpcclient_connect(&cli_info); - - DEBUG(5,("rpcclient_connect: smb_cli->fd:%d\n", smb_cli->fd)); - if (smb_cli->fd <= 0) - { - fprintf(stderr, "warning: connection could not be established to %s<%02x>\n", - cli_info.dest_host, cli_info.name_type); - fprintf(stderr, "this version of smbclient may crash if you proceed\n"); - exit(-1); - } - - switch (cli_action) - { - case CLIENT_IPC: - { - process(&cli_info, cmd_str); - break; - } - - default: - { - fprintf(stderr, "unknown client action requested\n"); - break; - } - } - - rpcclient_stop(); - return(0); + return command_main(argc, argv); } diff --git a/source3/script/mkproto.awk b/source3/script/mkproto.awk index 7ae89b7467..6e74b0d85f 100644 --- a/source3/script/mkproto.awk +++ b/source3/script/mkproto.awk @@ -2,8 +2,12 @@ BEGIN { inheader=0; # use_ldap_define = 0; current_file=""; - print "#ifndef _PROTO_H_" - print "#define _PROTO_H_" + if (headername=="") { + headername="_PROTO_H_"; + } + + print "#ifndef",headername + print "#define",headername print "/* This file is automatically generated with \"make proto\". DO NOT EDIT */" print "" } diff --git a/source3/script/mkproto.sh b/source3/script/mkproto.sh new file mode 100755 index 0000000000..4dbe4c204e --- /dev/null +++ b/source3/script/mkproto.sh @@ -0,0 +1,41 @@ +#! /bin/sh + +LANG=C; export LANG +LC_ALL=C; export LC_ALL +LC_COLLATE=C; export LC_COLLATE + +if [ $# -lt 3 ] +then + echo "Usage: $0 awk [-h headerdefine] outputheader proto_obj" + exit 1 +fi + +awk="$1" +shift + +if [ x"$1" = x-h ] +then + headeropt="-v headername=$2" + shift; shift; +else + headeropt="" +fi + +header="$1" +shift +headertmp="$header.$$.tmp~" + +proto_src="`echo $@ | tr ' ' '\n' | sed -e 's/\.o/\.c/g' | sort | uniq | egrep -v 'ubiqx/|wrapped'`" + +echo creating $header + +${awk} $headeropt \ + -f script/mkproto.awk $proto_src > $headertmp + +if cmp -s $header $headertmp 2>/dev/null +then + echo "$header unchanged" + rm $headertmp +else + mv $headertmp $header +fi -- cgit