diff options
Diffstat (limited to 'source/rpcclient/rpcclient.c')
-rw-r--r-- | source/rpcclient/rpcclient.c | 252 |
1 files changed, 145 insertions, 107 deletions
diff --git a/source/rpcclient/rpcclient.c b/source/rpcclient/rpcclient.c index 880fdc599a8..3067d8f437d 100644 --- a/source/rpcclient/rpcclient.c +++ b/source/rpcclient/rpcclient.c @@ -1,5 +1,6 @@ /* - Unix SMB/CIFS implementation. + Unix SMB/Netbios implementation. + Version 2.2 RPC pipe client Copyright (C) Tim Potter 2000-2001 @@ -34,7 +35,7 @@ static struct cmd_list { /**************************************************************************** handle completion of commands for readline ****************************************************************************/ -static char **completion_fn(char *text, int start, int end) +static char **completion_fn(const char *text, int start, int end) { #define MAX_COMPLETIONS 100 char **matches; @@ -129,7 +130,7 @@ static void read_authfile ( /* break up the line into parameter & value. will need to eat a little whitespace possibly */ param = buf; - if (!(ptr = strchr_m(buf, '='))) + if (!(ptr = strchr(buf, '='))) continue; val = ptr+1; *ptr = '\0'; @@ -156,16 +157,23 @@ static char* next_command (char** cmdstr) { static pstring command; char *p; + BOOL next_cmd = False; if (!cmdstr || !(*cmdstr)) return NULL; - p = strchr_m(*cmdstr, ';'); - if (p) + printf("cmd = %s\n", *cmdstr); + + p = strchr(*cmdstr, ';'); + if (p) { + next_cmd = True; *p = '\0'; + } pstrcpy(command, *cmdstr); - *cmdstr = p; - + *cmdstr = p; + if (next_cmd) + p++; + return command; } @@ -186,7 +194,7 @@ static void get_username (char *username) /* Fetch the SID for this computer */ -static void fetch_machine_sid(struct cli_state *cli) +void fetch_machine_sid(struct cli_state *cli) { POLICY_HND pol; NTSTATUS result = NT_STATUS_OK; @@ -234,7 +242,7 @@ static void fetch_machine_sid(struct cli_state *cli) fprintf(stderr, "could not obtain sid for domain %s\n", cli->domain); if (!NT_STATUS_IS_OK(result)) { - fprintf(stderr, "error: %s\n", nt_errstr(result)); + fprintf(stderr, "error: %s\n", get_nt_error_msg(result)); } exit(1); @@ -566,124 +574,146 @@ static NTSTATUS process_cmd(struct cli_state *cli, char *cmd) } if (!NT_STATUS_IS_OK(result)) { - printf("result was %s\n", nt_errstr(result)); + printf("result was %s\n", get_nt_error_msg(result)); } return result; } +/* Print usage information */ +static void usage(void) +{ + printf("Usage: rpcclient [options] server\n"); + + printf("\t-A authfile file containing user credentials\n"); + printf("\t-c \"command string\" execute semicolon separated cmds\n"); + printf("\t-d debuglevel set the debuglevel\n"); + printf("\t-l logfile name of logfile to use as opposed to stdout\n"); + printf("\t-h Print this help message.\n"); + printf("\t-N don't ask for a password\n"); + printf("\t-s configfile specify an alternative config file\n"); + printf("\t-U username set the network username\n"); + printf("\t-W domain set the domain name for user account\n"); + printf("\n"); +} + /* Main function */ - int main(int argc, char *argv[]) +int main(int argc, char *argv[]) { + extern char *optarg; + extern int optind; extern pstring global_myname; - static int got_pass = 0; + BOOL got_pass = False; BOOL interactive = True; int opt; - static char *cmdstr = ""; - const char *server; + int olddebug; + pstring cmdstr = "", + servicesf = CONFIGFILE; + fstring password, + username, + domain, + server; struct cli_state *cli; - fstring password="", - username="", - domain=""; - static char *opt_authfile=NULL, - *opt_username=NULL, - *opt_domain=NULL, - *opt_configfile=NULL, - *opt_logfile=NULL, - *opt_ipaddr=NULL; - pstring logfile; - struct cmd_set **cmd_set; + pstring logfile; + struct cmd_set **cmd_set; struct in_addr server_ip; NTSTATUS nt_status; - - /* make sure the vars that get altered (4th field) are in - a fixed location or certain compilers complain */ - poptContext pc; - struct poptOption long_options[] = { - POPT_AUTOHELP - {"authfile", 'A', POPT_ARG_STRING, &opt_authfile, 'A', "File containing user credentials"}, - {"conf", 's', POPT_ARG_STRING, &opt_configfile, 's', "Specify an alternative config file"}, - {"nopass", 'N', POPT_ARG_NONE, &got_pass, 'N', "Don't ask for a password"}, - {"user", 'U', POPT_ARG_STRING, &opt_username, 'U', "Set the network username"}, - {"workgroup", 'W', POPT_ARG_STRING, &opt_domain, 'W', "Set the domain name for user account"}, - {"command", 'c', POPT_ARG_STRING, &cmdstr, 'c', "Execute semicolon separated cmds"}, - {"logfile", 'l', POPT_ARG_STRING, &opt_logfile, 'l', "Logfile to use instead of stdout"}, - {"dest-ip", 'I', POPT_ARG_STRING, &opt_ipaddr, 'I', "Specify destination IP address"}, - { NULL, 0, POPT_ARG_INCLUDE_TABLE, popt_common_debug }, - { NULL } - }; + extern BOOL AllowDebugChange; setlinebuf(stdout); - /* Parse options */ + DEBUGLEVEL = 1; + AllowDebugChange = False; - pc = poptGetContext("rpcclient", argc, (const char **) argv, - long_options, 0); + /* Parse options */ if (argc == 1) { - poptPrintHelp(pc, stderr, 0); + usage(); return 0; } - - while((opt = poptGetNextOpt(pc)) != -1) { - switch (opt) { - case 'A': - /* only get the username, password, and domain from the file */ - read_authfile (opt_authfile, username, password, domain); - if (strlen (password)) - got_pass = 1; - break; - - case 'l': - slprintf(logfile, sizeof(logfile) - 1, "%s.client", - opt_logfile); - lp_set_logfile(logfile); - interactive = False; - break; - - case 's': - pstrcpy(dyn_CONFIGFILE, opt_configfile); - break; - - case 'U': { - char *lp; - pstrcpy(username,opt_username); + /* + * M. Sweet: getopt() behaves slightly differently on various + * platforms. The following loop ensures that the System V, + * BSD, and Linux (glibc) implementations work similarly to + * allow the server name anywhere on the command-line. + */ - if ((lp=strchr_m(username,'%'))) { - *lp = 0; - pstrcpy(password,lp+1); - got_pass = 1; - memset(strchr_m(opt_username,'%') + 1, 'X', - strlen(password)); + pstrcpy(server, ""); + + while (argc > optind) { + while ((opt = getopt(argc, argv, "A:s:Nd:U:W:c:l:h")) != EOF) { + switch (opt) { + case 'A': + /* only get the username, password, and domain from the file */ + read_authfile (optarg, username, password, domain); + if (strlen (password)) + got_pass = True; + break; + + case 'c': + pstrcpy(cmdstr, optarg); + break; + + case 'd': + DEBUGLEVEL = atoi(optarg); + break; + + case 'l': + slprintf(logfile, sizeof(logfile) - 1, "%s.client", optarg); + lp_set_logfile(logfile); + interactive = False; + break; + + case 'N': + got_pass = True; + break; + + case 's': + pstrcpy(servicesf, optarg); + break; + + case 'U': { + char *lp; + pstrcpy(username,optarg); + if ((lp=strchr(username,'%'))) { + *lp = 0; + pstrcpy(password,lp+1); + got_pass = True; + memset(strchr(optarg,'%')+1,'X',strlen(password)); + } + break; } - break; - } - case 'I': - if ( (server_ip.s_addr=inet_addr(opt_ipaddr)) == INADDR_NONE ) { - fprintf(stderr, "%s not a valid IP address\n", - opt_ipaddr); + + case 'W': + pstrcpy(domain, optarg); + break; + + case 'h': + default: + usage(); return 1; } - case 'W': - pstrcpy(domain, opt_domain); - break; } - } - /* Get server as remaining unparsed argument. Print usage if more - than one unparsed argument is present. */ + if (argc > optind) { + if (strncmp("//", argv[optind], 2) == 0 || + strncmp("\\\\", argv[optind], 2) == 0) + { + argv[optind] += 2; + } - server = poptGetArg(pc); - - if (!server || poptGetArg(pc)) { - poptPrintHelp(pc, stderr, 0); - return 1; + pstrcpy(server, argv[optind]); + optind ++; + } } - poptFreeContext(pc); + if (!server[0]) { + usage(); + return 1; + } /* the following functions are part of the Samba debugging facilities. See lib/debug.c */ @@ -691,19 +721,27 @@ static NTSTATUS process_cmd(struct cli_state *cli, char *cmd) if (!interactive) reopen_logs(); + TimeInit(); + charset_initialise(); + /* Load smb.conf file */ + /* FIXME! How to get this DEBUGLEVEL to last over lp_load()? */ + olddebug = DEBUGLEVEL; + if (!lp_load(servicesf,True,False,False)) { + fprintf(stderr, "Can't load %s\n", servicesf); + } + DEBUGLEVEL = olddebug; - if (!lp_load(dyn_CONFIGFILE,True,False,False)) - fprintf(stderr, "Can't load %s\n", dyn_CONFIGFILE); + codepage_initialise(lp_client_code_page()); load_interfaces(); get_myname((*global_myname)?NULL:global_myname); strupper(global_myname); - + /* Resolve the IP address */ - if (!opt_ipaddr && !resolve_name(server, &server_ip, 0x20)) { + if (!resolve_name(server, &server_ip, 0x20)) { DEBUG(1,("Unable to resolve %s\n", server)); return 1; } @@ -712,14 +750,14 @@ static NTSTATUS process_cmd(struct cli_state *cli, char *cmd) * Get password * from stdin if necessary */ - + if (!got_pass) { char *pass = getpass("Password:"); if (pass) { fstrcpy(password, pass); - } } - + } + if (!strlen(username) && !got_pass) get_username(username); @@ -727,15 +765,15 @@ static NTSTATUS process_cmd(struct cli_state *cli, char *cmd) &server_ip, 0, "IPC$", "IPC", username, domain, - password, 0); + password, strlen(password)); if (!NT_STATUS_IS_OK(nt_status)) { - DEBUG(0,("Cannot connect to server. Error was %s\n", nt_errstr(nt_status))); + DEBUG(1,("Cannot connect to server. Error was %s\n", nt_errstr(nt_status))); return 1; } - + memset(password,'X',sizeof(password)); - + /* Load command lists */ cmd_set = rpcclient_command_list; @@ -756,7 +794,7 @@ static NTSTATUS process_cmd(struct cli_state *cli, char *cmd) while((cmd=next_command(&p)) != NULL) { process_cmd(cli, cmd); } - + cli_shutdown(cli); return 0; } @@ -777,7 +815,7 @@ static NTSTATUS process_cmd(struct cli_state *cli, char *cmd) if (line[0] != '\n') process_cmd(cli, line); } - + cli_shutdown(cli); return 0; } |