/*
- Unix SMB/Netbios implementation.
- Version 2.2
+ Unix SMB/CIFS implementation.
RPC pipe client
Copyright (C) Tim Potter 2000-2001
/* Fetch the SID for this computer */
-void fetch_machine_sid(struct cli_state *cli)
+static void fetch_machine_sid(struct cli_state *cli)
{
POLICY_HND pol;
NTSTATUS result = NT_STATUS_OK;
if (!(mem_ctx=talloc_init()))
{
- DEBUG(0,("fetch_domain_sid: talloc_init returned NULL!\n"));
+ DEBUG(0,("fetch_machine_sid: talloc_init returned NULL!\n"));
goto error;
}
fprintf(stderr, "could not obtain sid for domain %s\n", cli->domain);
if (!NT_STATUS_IS_OK(result)) {
- fprintf(stderr, "error: %s\n", get_nt_error_msg(result));
+ fprintf(stderr, "error: %s\n", nt_errstr(result));
}
exit(1);
}
+/* List the available commands on a given pipe */
+
+static NTSTATUS cmd_listcommands(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ int argc, char **argv)
+{
+ struct cmd_list *tmp;
+ struct cmd_set *tmp_set;
+ int i;
+
+ /* Usage */
+
+ if (argc != 2) {
+ printf("Usage: %s <pipe>\n", argv[0]);
+ return NT_STATUS_OK;
+ }
+
+ /* Help on one command */
+
+ for (tmp = cmd_list; tmp; tmp = tmp->next)
+ {
+ tmp_set = tmp->cmd_set;
+
+ if (!StrCaseCmp(argv[1], tmp_set->name))
+ {
+ printf("Available commands on the %s pipe:\n\n", tmp_set->name);
+
+ i = 0;
+ tmp_set++;
+ while(tmp_set->name) {
+ printf("%20s", tmp_set->name);
+ tmp_set++;
+ i++;
+ if (i%4 == 0)
+ printf("\n");
+ }
+
+ /* drop out of the loop */
+ break;
+ }
+ }
+ printf("\n\n");
+
+ return NT_STATUS_OK;
+}
/* Display help on commands */
while(tmp_set->name) {
printf("%15s\t\t%s\n", tmp_set->name,
- tmp_set->description);
+ tmp_set->description ? tmp_set->description:
+ "");
tmp_set++;
}
{ "help", cmd_help, NULL, "Get help on commands", "[command]" },
{ "?", cmd_help, NULL, "Get help on commands", "[command]" },
{ "debuglevel", cmd_debuglevel, NULL, "Set debug level", "level" },
+ { "list", cmd_listcommands, NULL, "List available commands on <pipe>", "pipe" },
{ "exit", cmd_quit, NULL, "Exit program", "" },
{ "quit", cmd_quit, NULL, "Exit program", "" },
}
if (!NT_STATUS_IS_OK(result)) {
- printf("result was %s\n", get_nt_error_msg(result));
+ printf("result was %s\n", nt_errstr(result));
}
return result;
}
-/* Print usage information */
-static void usage(void)
-{
- printf("Usage: rpcclient server [options]\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[])
{
- extern char *optarg;
- extern int optind;
extern pstring global_myname;
- BOOL got_pass = False;
+ static int got_pass = 0;
BOOL interactive = True;
int opt;
int olddebug;
- pstring cmdstr = "";
+ static char *cmdstr = "";
+ const char *server;
struct cli_state *cli;
fstring password="",
username="",
- domain="",
- server="";
- struct cmd_set **cmd_set;
- struct in_addr server_ip;
- NTSTATUS nt_status;
+ 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;
+ struct in_addr server_ip;
+ NTSTATUS nt_status;
+ extern BOOL AllowDebugChange;
+
+ /* 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 }
+ };
setlinebuf(stdout);
DEBUGLEVEL = 1;
+ AllowDebugChange = False;
+
+ /* Parse options */
+
+ pc = poptGetContext("rpcclient", argc, (const char **) argv,
+ long_options, 0);
- while ((opt = getopt(argc, argv, "A:s:Nd:U:W:c:l:h")) != EOF) {
+ if (argc == 1) {
+ poptPrintHelp(pc, stderr, 0);
+ return 0;
+ }
+
+ while((opt = poptGetNextOpt(pc)) != -1) {
switch (opt) {
case 'A':
/* only get the username, password, and domain from the file */
- read_authfile (optarg, username, password, domain);
+ read_authfile (opt_authfile, username, password, domain);
if (strlen (password))
- got_pass = True;
+ got_pass = 1;
break;
-
- case 'c':
- pstrcpy(cmdstr, optarg);
- break;
-
- case 'd':
- DEBUGLEVEL = atoi(optarg);
- break;
-
+
case 'l':
- slprintf(logfile, sizeof(logfile) - 1, "%s.client", optarg);
+ slprintf(logfile, sizeof(logfile) - 1, "%s.client",
+ opt_logfile);
lp_set_logfile(logfile);
interactive = False;
break;
-
- case 'N':
- got_pass = True;
- break;
case 's':
- pstrcpy(dyn_CONFIGFILE, optarg);
+ pstrcpy(dyn_CONFIGFILE, opt_configfile);
break;
-
+
case 'U': {
char *lp;
- pstrcpy(username,optarg);
+
+ pstrcpy(username,opt_username);
+
if ((lp=strchr_m(username,'%'))) {
*lp = 0;
pstrcpy(password,lp+1);
- got_pass = True;
- memset(strchr_m(optarg,'%')+1,'X',strlen(password));
+ got_pass = 1;
+ memset(strchr_m(opt_username,'%') + 1, 'X',
+ strlen(password));
}
break;
}
-
+ case 'I':
+ if (!inet_aton(opt_ipaddr, &server_ip)) {
+ fprintf(stderr, "%s not a valid IP address\n",
+ opt_ipaddr);
+ return 1;
+ }
case 'W':
- pstrcpy(domain, optarg);
+ pstrcpy(domain, opt_domain);
break;
-
- case 'h':
- default:
- usage();
- exit(1);
}
}
- argv += optind;
- argc -= optind;
+ /* Get server as remaining unparsed argument. Print usage if more
+ than one unparsed argument is present. */
- /* Parse options */
- if (argc == 0) {
- usage();
- return 0;
- }
+ server = poptGetArg(pc);
- if (strncmp("//", argv[0], 2) == 0 || strncmp("\\\\", argv[0], 2) == 0)
- argv[0] += 2;
+ if (!server || poptGetArg(pc)) {
+ poptPrintHelp(pc, stderr, 0);
+ return 1;
+ }
- pstrcpy(server, argv[0]);
+ poptFreeContext(pc);
/* the following functions are part of the Samba debugging
facilities. See lib/debug.c */
get_myname((*global_myname)?NULL:global_myname);
strupper(global_myname);
-
- /* resolve the IP address */
- if (!resolve_name(server, &server_ip, 0x20)) {
- DEBUG(1,("Unable to resolve server name\n"));
+ /* Resolve the IP address */
+
+ if (!opt_ipaddr && !resolve_name(server, &server_ip, 0x20)) {
+ DEBUG(1,("Unable to resolve %s\n", server));
return 1;
}
&server_ip, 0,
"IPC$", "IPC",
username, domain,
- password, strlen(password));
+ password, 0);
if (!NT_STATUS_IS_OK(nt_status)) {
- DEBUG(1,("Cannot connect to server. Error was %s\n", get_nt_error_msg(nt_status)));
+ DEBUG(0,("Cannot connect to server. Error was %s\n", nt_errstr(nt_status)));
return 1;
}