diff options
Diffstat (limited to 'source3/utils/smbtree.c')
-rw-r--r-- | source3/utils/smbtree.c | 148 |
1 files changed, 109 insertions, 39 deletions
diff --git a/source3/utils/smbtree.c b/source3/utils/smbtree.c index d245c324dd..940120d644 100644 --- a/source3/utils/smbtree.c +++ b/source3/utils/smbtree.c @@ -3,7 +3,6 @@ Network neighbourhood browser. Copyright (C) Tim Potter 2000 - Copyright (C) Jelmer Vernooij 2003 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 @@ -24,11 +23,34 @@ static BOOL use_bcast; +struct user_auth_info { + pstring username; + pstring password; + pstring workgroup; +}; + /* How low can we go? */ enum tree_level {LEV_WORKGROUP, LEV_SERVER, LEV_SHARE}; static enum tree_level level = LEV_SHARE; +static void usage(void) +{ + printf( +"Usage: smbtree [options]\n\ +\n\ +\t-d debuglevel set debug output level\n\ +\t-U username user to autheticate as\n\ +\t-W workgroup workgroup of user to authenticate as\n\ +\t-D list only domains (workgroups) of tree\n\ +\t-S list domains and servers of tree\n\ +\t-b use bcast instead of using the master browser\n\ +\n\ +The username can be of the form username%%password or\n\ +workgroup\\username%%password.\n\n\ +"); +} + /* Holds a list of workgroups or servers */ struct name_list { @@ -90,12 +112,10 @@ static struct cli_state *get_ipc_connect(char *server, struct in_addr *server_ip /* Return the IP address and workgroup of a master browser on the network. */ -static struct cli_state *get_ipc_connect_master_ip_bcast(pstring workgroup, struct user_auth_info *user_info) +static BOOL find_master_ip_bcast(pstring workgroup, struct in_addr *server_ip) { struct in_addr *ip_list; - struct cli_state *cli; int i, count; - struct in_addr server_ip; /* Go looking for workgroups by broadcasting on the local network */ @@ -109,7 +129,7 @@ static struct cli_state *get_ipc_connect_master_ip_bcast(pstring workgroup, stru if (!name_status_find("*", 0, 0x1d, ip_list[i], name)) continue; - if (!find_master_ip(name, &server_ip)) + if (!find_master_ip(name, server_ip)) continue; pstrcpy(workgroup, name); @@ -117,13 +137,10 @@ static struct cli_state *get_ipc_connect_master_ip_bcast(pstring workgroup, stru DEBUG(4, ("found master browser %s, %s\n", name, inet_ntoa(ip_list[i]))); - if (!(cli = get_ipc_connect(inet_ntoa(server_ip), &server_ip, user_info))) - continue; - - return cli; + return True; } - return NULL; + return False; } /**************************************************************************** @@ -141,21 +158,19 @@ static BOOL get_workgroups(struct user_auth_info *user_info) pstrcpy(master_workgroup, lp_workgroup()); - if (!use_bcast && !find_master_ip(lp_workgroup(), &server_ip)) { - DEBUG(4, ("Unable to find master browser for workgroup %s, falling back to broadcast\n", + if (use_bcast || !find_master_ip(lp_workgroup(), &server_ip)) { + DEBUG(4, ("Unable to find master browser for workgroup %s\n", master_workgroup)); - use_bcast = True; - } else if(!use_bcast) { - if (!(cli = get_ipc_connect(inet_ntoa(server_ip), &server_ip, user_info))) - return False; - } - - if (!(cli = get_ipc_connect_master_ip_bcast(master_workgroup, user_info))) { + if (!find_master_ip_bcast(master_workgroup, &server_ip)) { DEBUG(4, ("Unable to find master browser by " "broadcast\n")); return False; + } } + if (!(cli = get_ipc_connect(inet_ntoa(server_ip), &server_ip, user_info))) + return False; + if (!cli_NetServerEnum(cli, master_workgroup, SV_TYPE_DOMAIN_ENUM, add_name, &workgroups)) return False; @@ -252,17 +267,13 @@ static BOOL print_tree(struct user_auth_info *user_info) ****************************************************************************/ int main(int argc,char *argv[]) { - struct poptOption long_options[] = { - POPT_AUTOHELP - { "broadcast", 'b', POPT_ARG_VAL, &use_bcast, True, "Use broadcast instead of using the master browser" }, - { "domains", 'D', POPT_ARG_VAL, &level, LEV_WORKGROUP, "List only domains (workgroups) of tree" }, - { "servers", 'S', POPT_ARG_VAL, &level, LEV_SERVER, "List domains(workgroups) and servers of tree" }, - POPT_COMMON_SAMBA - POPT_COMMON_CREDENTIALS - POPT_TABLEEND - }; - poptContext pc; - + extern char *optarg; + extern int optind; + int opt; + char *p; + struct user_auth_info user_info; + BOOL got_pass = False; + /* Initialise samba stuff */ setlinebuf(stdout); @@ -271,27 +282,86 @@ static BOOL print_tree(struct user_auth_info *user_info) setup_logging(argv[0],True); - pc = poptGetContext("smbtree", argc, (const char **)argv, long_options, - POPT_CONTEXT_KEEP_FIRST); - while(poptGetNextOpt(pc) != -1); - poptFreeContext(pc); - lp_load(dyn_CONFIGFILE,True,False,False); load_interfaces(); + if (getenv("USER")) { + pstrcpy(user_info.username, getenv("USER")); + + if ((p=strchr(user_info.username, '%'))) { + *p = 0; + pstrcpy(user_info.password, p+1); + got_pass = True; + memset(strchr(getenv("USER"), '%') + 1, 'X', + strlen(user_info.password)); + } + } + + pstrcpy(user_info.workgroup, lp_workgroup()); + /* Parse command line args */ - if (!cmdline_auth_info.got_pass) { + while ((opt = getopt(argc, argv, "U:hd:W:DSb")) != EOF) { + switch (opt) { + case 'U': + pstrcpy(user_info.username,optarg); + p = strchr(user_info.username,'%'); + if (p) { + *p = 0; + pstrcpy(user_info.password, p+1); + got_pass = 1; + } + break; + + case 'b': + use_bcast = True; + break; + + case 'h': + usage(); + exit(1); + + case 'd': + DEBUGLEVEL = atoi(optarg); + break; + + case 'W': + pstrcpy(user_info.workgroup, optarg); + break; + + case 'D': + level = LEV_WORKGROUP; + break; + + case 'S': + level = LEV_SERVER; + break; + + default: + printf("Unknown option %c (%d)\n", (char)opt, opt); + exit(1); + } + } + + argc -= optind; + argv += optind; + + if (argc > 0) { + usage(); + exit(1); + } + + if (!got_pass) { char *pass = getpass("Password: "); if (pass) { - pstrcpy(cmdline_auth_info.password, pass); + pstrcpy(user_info.password, pass); } - cmdline_auth_info.got_pass = True; + got_pass = True; } /* Now do our stuff */ - if (!print_tree(&cmdline_auth_info)) + if (!print_tree(&user_info)) return 1; return 0; |