mirror of
https://github.com/samba-team/samba.git
synced 2024-12-24 21:34:56 +03:00
381e8299dc
and stuff will work....
(This used to be commit e652a14264
)
432 lines
8.2 KiB
C
432 lines
8.2 KiB
C
/*
|
|
Unix SMB/Netbios implementation.
|
|
Version 2.2
|
|
RPC pipe client
|
|
|
|
Copyright (C) Tim Potter 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.
|
|
*/
|
|
|
|
#include "includes.h"
|
|
|
|
extern int DEBUGLEVEL;
|
|
|
|
/* Connect info */
|
|
|
|
pstring password;
|
|
pstring username;
|
|
pstring workgroup;
|
|
pstring server;
|
|
|
|
/* Various pipe commands */
|
|
|
|
extern struct cmd_set lsarpc_commands[];
|
|
extern struct cmd_set samr_commands[];
|
|
extern struct cmd_set spoolss_commands[];
|
|
|
|
DOM_SID domain_sid;
|
|
|
|
/* Fetch the SID for this domain */
|
|
|
|
void fetch_domain_sid(void)
|
|
{
|
|
struct cli_state cli;
|
|
POLICY_HND pol;
|
|
uint32 result = 0, info_class = 5;
|
|
struct ntuser_creds creds;
|
|
fstring domain_name;
|
|
static BOOL got_domain_sid;
|
|
|
|
if (got_domain_sid) return;
|
|
|
|
ZERO_STRUCT(cli);
|
|
init_rpcclient_creds(&creds);
|
|
|
|
if (cli_lsa_initialise(&cli, server, &creds) == NULL) {
|
|
fprintf(stderr, "could not initialise lsa pipe\n");
|
|
goto error;
|
|
}
|
|
|
|
if ((result = cli_lsa_open_policy(&cli, True,
|
|
SEC_RIGHTS_MAXIMUM_ALLOWED,
|
|
&pol) != NT_STATUS_NOPROBLEMO)) {
|
|
goto error;
|
|
}
|
|
|
|
if ((result = cli_lsa_query_info_policy(&cli, &pol, info_class,
|
|
domain_name, &domain_sid))
|
|
!= NT_STATUS_NOPROBLEMO) {
|
|
goto error;
|
|
}
|
|
|
|
got_domain_sid = True;
|
|
|
|
cli_lsa_close(&cli, &pol);
|
|
cli_lsa_shutdown(&cli);
|
|
|
|
return;
|
|
|
|
error:
|
|
fprintf(stderr, "could not obtain sid for domain %s\n", workgroup);
|
|
|
|
if (result != NT_STATUS_NOPROBLEMO) {
|
|
fprintf(stderr, "error: %s\n", get_nt_error_msg(result));
|
|
}
|
|
|
|
exit(1);
|
|
}
|
|
|
|
/* Initialise client credentials for authenticated pipe access */
|
|
|
|
void init_rpcclient_creds(struct ntuser_creds *creds)
|
|
{
|
|
ZERO_STRUCTP(creds);
|
|
|
|
if (lp_encrypted_passwords()) {
|
|
pwd_make_lm_nt_16(&creds->pwd, password);
|
|
} else {
|
|
pwd_set_cleartext(&creds->pwd, password);
|
|
}
|
|
|
|
fstrcpy(creds->user_name, username);
|
|
fstrcpy(creds->domain, workgroup);
|
|
}
|
|
|
|
/* List to hold groups of commands */
|
|
|
|
static struct cmd_list {
|
|
struct cmd_list *prev, *next;
|
|
struct cmd_set *cmd_set;
|
|
} *cmd_list;
|
|
|
|
static uint32 cmd_help(int argc, char **argv)
|
|
{
|
|
struct cmd_list *temp_list;
|
|
|
|
for (temp_list = cmd_list; temp_list; temp_list = temp_list->next) {
|
|
struct cmd_set *temp_set = temp_list->cmd_set;
|
|
|
|
while(temp_set->name) {
|
|
printf("%s\t%s\n", temp_set->name,
|
|
temp_set->description);
|
|
temp_set++;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static uint32 cmd_debuglevel(int argc, char **argv)
|
|
{
|
|
if (argc > 2) {
|
|
printf("Usage: %s [debuglevel]\n", argv[0]);
|
|
return NT_STATUS_NOPROBLEMO;
|
|
}
|
|
|
|
if (argc == 2) {
|
|
DEBUGLEVEL = atoi(argv[1]);
|
|
}
|
|
|
|
printf("debuglevel is %d\n", DEBUGLEVEL);
|
|
|
|
return NT_STATUS_NOPROBLEMO;
|
|
}
|
|
|
|
static uint32 cmd_quit(int argc, char **argv)
|
|
{
|
|
exit(0);
|
|
}
|
|
|
|
/* Build in rpcclient commands */
|
|
|
|
static struct cmd_set rpcclient_commands[] = {
|
|
{ "help", cmd_help, "Print list of commands" },
|
|
{ "debuglevel", cmd_debuglevel, "Set debug level" },
|
|
{ "quit", cmd_quit, "Exit program" },
|
|
{ "?", cmd_help, "Print list of commands" },
|
|
|
|
{ NULL, NULL, NULL }
|
|
};
|
|
|
|
void add_command_set(struct cmd_set *cmd_set)
|
|
{
|
|
struct cmd_list *entry;
|
|
|
|
if (!(entry = (struct cmd_list *)malloc(sizeof(struct cmd_list)))) {
|
|
DEBUG(0, ("out of memory\n"));
|
|
return;
|
|
}
|
|
|
|
ZERO_STRUCTP(entry);
|
|
|
|
entry->cmd_set = cmd_set;
|
|
DLIST_ADD(cmd_list, entry);
|
|
}
|
|
|
|
static uint32 do_cmd(struct cmd_set *cmd_entry, char *cmd)
|
|
{
|
|
char *p = cmd, **argv = NULL;
|
|
uint32 result;
|
|
pstring buf;
|
|
int argc = 1, i;
|
|
|
|
next_token(&p, buf, " ", sizeof(buf));
|
|
|
|
/* Count number of arguments first time through the loop then
|
|
allocate memory and strdup them. */
|
|
|
|
again:
|
|
while(next_token(NULL, buf, " ", sizeof(buf))) {
|
|
if (argv) {
|
|
argv[argc] = strdup(buf);
|
|
}
|
|
|
|
argc++;
|
|
}
|
|
|
|
if (!argv) {
|
|
|
|
/* Create argument list */
|
|
|
|
argv = (char **)malloc(sizeof(char *) * argc);
|
|
|
|
if (!argv) {
|
|
fprintf(stderr, "out of memoryx\n");
|
|
return 0;
|
|
}
|
|
|
|
p = cmd;
|
|
next_token(&p, buf, " ", sizeof(buf));
|
|
argv[0] = strdup(buf);
|
|
argc = 1;
|
|
|
|
goto again;
|
|
}
|
|
|
|
/* Call the function */
|
|
|
|
result = cmd_entry->fn(argc, argv);
|
|
|
|
/* Cleanup */
|
|
|
|
for (i = 0; i < argc; i++) {
|
|
free(argv[i]);
|
|
}
|
|
|
|
free(argv);
|
|
|
|
return result;
|
|
}
|
|
|
|
/* Process a command entered at the prompt or as part of -c */
|
|
|
|
static uint32 process_cmd(char *cmd)
|
|
{
|
|
struct cmd_list *temp_list;
|
|
BOOL found = False;
|
|
pstring buf;
|
|
char *p = cmd;
|
|
uint32 result;
|
|
|
|
if (!next_token(&p, buf, " ", sizeof(buf))) {
|
|
return 0;
|
|
}
|
|
|
|
/* Search for matching commands */
|
|
|
|
for (temp_list = cmd_list; temp_list; temp_list = temp_list->next) {
|
|
struct cmd_set *temp_set = temp_list->cmd_set;
|
|
|
|
while(temp_set->name) {
|
|
if (strequal(buf, temp_set->name)) {
|
|
found = True;
|
|
result = do_cmd(temp_set, cmd);
|
|
goto done;
|
|
}
|
|
temp_set++;
|
|
}
|
|
}
|
|
|
|
done:
|
|
if (!found && buf[0]) {
|
|
printf("command not found: %s\n", buf);
|
|
return 0;
|
|
}
|
|
|
|
if (result != 0) {
|
|
printf("result was %s\n", get_nt_error_msg(result));
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
/* Print usage information */
|
|
|
|
static void usage(char *pname)
|
|
{
|
|
printf("Usage: %s server [options]\n", pname);
|
|
|
|
printf("\t-N don't ask for a password\n");
|
|
printf("\t-d debuglevel set the debuglevel\n");
|
|
printf("\t-h Print this help message.\n");
|
|
printf("\t-U username set the network username\n");
|
|
printf("\t-W workgroup set the workgroup name\n");
|
|
printf("\t-c command string execute semicolon separated cmds\n");
|
|
printf("\n");
|
|
}
|
|
|
|
/* Main function */
|
|
|
|
int main(int argc, char *argv[])
|
|
{
|
|
extern char *optarg;
|
|
extern int optind;
|
|
struct in_addr dest_ip;
|
|
extern pstring global_myname;
|
|
BOOL got_pass = False;
|
|
BOOL have_ip = False;
|
|
int opt;
|
|
pstring cmdstr = "", servicesf = CONFIGFILE;
|
|
extern FILE *dbf;
|
|
|
|
setlinebuf(stdout);
|
|
dbf = stderr;
|
|
|
|
setup_logging(argv[0], True);
|
|
|
|
#ifdef HAVE_LIBREADLINE
|
|
/* Allow conditional parsing of the ~/.inputrc file. */
|
|
rl_readline_name = "rpcclient";
|
|
#endif
|
|
|
|
DEBUGLEVEL = 2;
|
|
|
|
/* Load smb.conf file */
|
|
|
|
charset_initialise();
|
|
|
|
if (!lp_load(servicesf,True,False,False)) {
|
|
fprintf(stderr, "Can't load %s\n", servicesf);
|
|
}
|
|
|
|
codepage_initialise(lp_client_code_page());
|
|
load_interfaces();
|
|
|
|
TimeInit();
|
|
|
|
get_myname((*global_myname)?NULL:global_myname);
|
|
strupper(global_myname);
|
|
|
|
/* Parse options */
|
|
|
|
if (argc < 2) {
|
|
usage(argv[0]);
|
|
return 0;
|
|
}
|
|
|
|
pstrcpy(server, argv[1]);
|
|
|
|
argv++;
|
|
argc--;
|
|
|
|
while ((opt = getopt(argc, argv, "s:Nd:I:U:W:c:")) != EOF) {
|
|
switch (opt) {
|
|
case 's':
|
|
pstrcpy(servicesf, optarg);
|
|
break;
|
|
case 'N':
|
|
got_pass = True;
|
|
break;
|
|
case 'd':
|
|
DEBUGLEVEL = atoi(optarg);
|
|
break;
|
|
case 'I':
|
|
dest_ip = *interpret_addr2(optarg);
|
|
have_ip = True;
|
|
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;
|
|
}
|
|
case 'W':
|
|
pstrcpy(workgroup, optarg);
|
|
break;
|
|
case 'c':
|
|
pstrcpy(cmdstr, optarg);
|
|
got_pass = True;
|
|
break;
|
|
case 'h':
|
|
default:
|
|
usage(argv[0]);
|
|
exit(1);
|
|
}
|
|
}
|
|
|
|
/* Load command lists */
|
|
|
|
add_command_set(rpcclient_commands);
|
|
add_command_set(lsarpc_commands);
|
|
add_command_set(samr_commands);
|
|
add_command_set(spoolss_commands);
|
|
|
|
/* Do anything specified with -c */
|
|
|
|
if (cmdstr[0]) {
|
|
pstring cmd;
|
|
char *p = cmdstr;
|
|
uint32 result;
|
|
|
|
while(next_token(&p, cmd, ";", sizeof(pstring))) {
|
|
result = process_cmd(cmd);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
/* Loop around accepting commands */
|
|
|
|
while(1) {
|
|
pstring prompt, cmd;
|
|
uint32 result;
|
|
|
|
ZERO_STRUCT(cmd);
|
|
|
|
slprintf(prompt, sizeof(prompt) - 1, "rpcclient> ");
|
|
|
|
#if HAVE_READLINE
|
|
cmd = readline(prompt);
|
|
#else
|
|
printf("%s", prompt);
|
|
|
|
if (!fgets(cmd, sizeof(cmd) - 1, stdin)) {
|
|
break;
|
|
}
|
|
|
|
cmd[strlen(cmd) - 1] = '\0';
|
|
#endif
|
|
result = process_cmd(cmd);
|
|
}
|
|
|
|
return 0;
|
|
}
|