utils/smbtree.c

説明を見る。
00001 /* 
00002    Unix SMB/CIFS implementation.
00003    Network neighbourhood browser.
00004    
00005    Copyright (C) Tim Potter      2000
00006    Copyright (C) Jelmer Vernooij 2003
00007    
00008    This program is free software; you can redistribute it and/or modify
00009    it under the terms of the GNU General Public License as published by
00010    the Free Software Foundation; either version 2 of the License, or
00011    (at your option) any later version.
00012    
00013    This program is distributed in the hope that it will be useful,
00014    but WITHOUT ANY WARRANTY; without even the implied warranty of
00015    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016    GNU General Public License for more details.
00017    
00018    You should have received a copy of the GNU General Public License
00019    along with this program; if not, write to the Free Software
00020    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00021 */
00022 
00023 #include "includes.h"
00024 
00025 static BOOL use_bcast;
00026 
00027 /* How low can we go? */
00028 
00029 enum tree_level {LEV_WORKGROUP, LEV_SERVER, LEV_SHARE};
00030 static enum tree_level level = LEV_SHARE;
00031 
00032 /* Holds a list of workgroups or servers */
00033 
00034 struct name_list {
00035         struct name_list *prev, *next;
00036         pstring name, comment;
00037         uint32 server_type;
00038 };
00039 
00040 static struct name_list *workgroups, *servers, *shares;
00041 
00042 static void free_name_list(struct name_list *list)
00043 {
00044         while(list)
00045                 DLIST_REMOVE(list, list);
00046 }
00047 
00048 static void add_name(const char *machine_name, uint32 server_type,
00049                      const char *comment, void *state)
00050 {
00051         struct name_list **name_list = (struct name_list **)state;
00052         struct name_list *new_name;
00053 
00054         new_name = SMB_MALLOC_P(struct name_list);
00055 
00056         if (!new_name)
00057                 return;
00058 
00059         ZERO_STRUCTP(new_name);
00060 
00061         pstrcpy(new_name->name, machine_name);
00062         pstrcpy(new_name->comment, comment);
00063         new_name->server_type = server_type;
00064 
00065         DLIST_ADD(*name_list, new_name);
00066 }
00067 
00068 /****************************************************************************
00069   display tree of smb workgroups, servers and shares
00070 ****************************************************************************/
00071 static BOOL get_workgroups(struct user_auth_info *user_info)
00072 {
00073         struct cli_state *cli;
00074         struct in_addr server_ip;
00075         pstring master_workgroup;
00076 
00077         /* Try to connect to a #1d name of our current workgroup.  If that
00078            doesn't work broadcast for a master browser and then jump off
00079            that workgroup. */
00080 
00081         pstrcpy(master_workgroup, lp_workgroup());
00082 
00083         if (!use_bcast && !find_master_ip(lp_workgroup(), &server_ip)) {
00084                 DEBUG(4, ("Unable to find master browser for workgroup %s, falling back to broadcast\n", 
00085                           master_workgroup));
00086                                 use_bcast = True;
00087                 } else if(!use_bcast) {
00088                 if (!(cli = get_ipc_connect(inet_ntoa(server_ip), &server_ip, user_info)))
00089                                 return False;
00090                 }
00091                 
00092                 if (!(cli = get_ipc_connect_master_ip_bcast(master_workgroup, user_info))) {
00093                         DEBUG(4, ("Unable to find master browser by "
00094                                   "broadcast\n"));
00095                         return False;
00096         }
00097 
00098         if (!cli_NetServerEnum(cli, master_workgroup, 
00099                                SV_TYPE_DOMAIN_ENUM, add_name, &workgroups))
00100                 return False;
00101 
00102         return True;
00103 }
00104 
00105 /* Retrieve the list of servers for a given workgroup */
00106 
00107 static BOOL get_servers(char *workgroup, struct user_auth_info *user_info)
00108 {
00109         struct cli_state *cli;
00110         struct in_addr server_ip;
00111 
00112         /* Open an IPC$ connection to the master browser for the workgroup */
00113 
00114         if (!find_master_ip(workgroup, &server_ip)) {
00115                 DEBUG(4, ("Cannot find master browser for workgroup %s\n",
00116                           workgroup));
00117                 return False;
00118         }
00119 
00120         if (!(cli = get_ipc_connect(inet_ntoa(server_ip), &server_ip, user_info)))
00121                 return False;
00122 
00123         if (!cli_NetServerEnum(cli, workgroup, SV_TYPE_ALL, add_name, 
00124                                &servers))
00125                 return False;
00126 
00127         return True;
00128 }
00129 
00130 static BOOL get_rpc_shares(struct cli_state *cli, 
00131                            void (*fn)(const char *, uint32, const char *, void *),
00132                            void *state)
00133 {
00134         NTSTATUS status;
00135         struct rpc_pipe_client *pipe_hnd;
00136         TALLOC_CTX *mem_ctx;
00137         ENUM_HND enum_hnd;
00138         WERROR werr;
00139         SRV_SHARE_INFO_CTR ctr;
00140         int i;
00141 
00142         mem_ctx = talloc_new(NULL);
00143         if (mem_ctx == NULL) {
00144                 DEBUG(0, ("talloc_new failed\n"));
00145                 return False;
00146         }
00147 
00148         init_enum_hnd(&enum_hnd, 0);
00149 
00150         pipe_hnd = cli_rpc_pipe_open_noauth(cli, PI_SRVSVC, &status);
00151 
00152         if (pipe_hnd == NULL) {
00153                 DEBUG(10, ("Could not connect to srvsvc pipe: %s\n",
00154                            nt_errstr(status)));
00155                 TALLOC_FREE(mem_ctx);
00156                 return False;
00157         }
00158 
00159         werr = rpccli_srvsvc_net_share_enum(pipe_hnd, mem_ctx, 1, &ctr,
00160                                             0xffffffff, &enum_hnd);
00161 
00162         if (!W_ERROR_IS_OK(werr)) {
00163                 TALLOC_FREE(mem_ctx);
00164                 cli_rpc_pipe_close(pipe_hnd);
00165                 return False;
00166         }
00167 
00168         for (i=0; i<ctr.num_entries; i++) {
00169                 SRV_SHARE_INFO_1 *info = &ctr.share.info1[i];
00170                 char *name, *comment;
00171                 name = rpcstr_pull_unistr2_talloc(
00172                         mem_ctx, &info->info_1_str.uni_netname);
00173                 comment = rpcstr_pull_unistr2_talloc(
00174                         mem_ctx, &info->info_1_str.uni_remark);
00175                 fn(name, info->info_1.type, comment, state);
00176         }
00177 
00178         TALLOC_FREE(mem_ctx);
00179         cli_rpc_pipe_close(pipe_hnd);
00180         return True;
00181 }
00182 
00183 
00184 static BOOL get_shares(char *server_name, struct user_auth_info *user_info)
00185 {
00186         struct cli_state *cli;
00187 
00188         if (!(cli = get_ipc_connect(server_name, NULL, user_info)))
00189                 return False;
00190 
00191         if (get_rpc_shares(cli, add_name, &shares))
00192                 return True;
00193         
00194         if (!cli_RNetShareEnum(cli, add_name, &shares))
00195                 return False;
00196 
00197         return True;
00198 }
00199 
00200 static BOOL print_tree(struct user_auth_info *user_info)
00201 {
00202         struct name_list *wg, *sv, *sh;
00203 
00204         /* List workgroups */
00205 
00206         if (!get_workgroups(user_info))
00207                 return False;
00208 
00209         for (wg = workgroups; wg; wg = wg->next) {
00210 
00211                 printf("%s\n", wg->name);
00212 
00213                 /* List servers */
00214 
00215                 free_name_list(servers);
00216                 servers = NULL;
00217 
00218                 if (level == LEV_WORKGROUP || 
00219                     !get_servers(wg->name, user_info))
00220                         continue;
00221 
00222                 for (sv = servers; sv; sv = sv->next) {
00223 
00224                         printf("\t\\\\%-15s\t\t%s\n", 
00225                                sv->name, sv->comment);
00226 
00227                         /* List shares */
00228 
00229                         free_name_list(shares);
00230                         shares = NULL;
00231 
00232                         if (level == LEV_SERVER ||
00233                             !get_shares(sv->name, user_info))
00234                                 continue;
00235 
00236                         for (sh = shares; sh; sh = sh->next) {
00237                                 printf("\t\t\\\\%s\\%-15s\t%s\n", 
00238                                        sv->name, sh->name, sh->comment);
00239                         }
00240                 }
00241         }
00242 
00243         return True;
00244 }
00245 
00246 /****************************************************************************
00247   main program
00248 ****************************************************************************/
00249  int main(int argc,char *argv[])
00250 {
00251         struct poptOption long_options[] = {
00252                 POPT_AUTOHELP
00253                 { "broadcast", 'b', POPT_ARG_VAL, &use_bcast, True, "Use broadcast instead of using the master browser" },
00254                 { "domains", 'D', POPT_ARG_VAL, &level, LEV_WORKGROUP, "List only domains (workgroups) of tree" },
00255                 { "servers", 'S', POPT_ARG_VAL, &level, LEV_SERVER, "List domains(workgroups) and servers of tree" },
00256                 POPT_COMMON_SAMBA
00257                 POPT_COMMON_CREDENTIALS
00258                 POPT_TABLEEND
00259         };
00260         poptContext pc;
00261         
00262         /* Initialise samba stuff */
00263         load_case_tables();
00264 
00265         setlinebuf(stdout);
00266 
00267         dbf = x_stderr;
00268 
00269         setup_logging(argv[0],True);
00270 
00271         pc = poptGetContext("smbtree", argc, (const char **)argv, long_options, 
00272                                                 POPT_CONTEXT_KEEP_FIRST);
00273         while(poptGetNextOpt(pc) != -1);
00274         poptFreeContext(pc);
00275 
00276         lp_load(dyn_CONFIGFILE,True,False,False,True);
00277         load_interfaces();
00278 
00279         /* Parse command line args */
00280 
00281         if (!cmdline_auth_info.got_pass) {
00282                 char *pass = getpass("Password: ");
00283                 if (pass) {
00284                         pstrcpy(cmdline_auth_info.password, pass);
00285                 }
00286         cmdline_auth_info.got_pass = True;
00287         }
00288 
00289         /* Now do our stuff */
00290 
00291         if (!print_tree(&cmdline_auth_info))
00292                 return 1;
00293 
00294         return 0;
00295 }

Sambaに対してSat Aug 29 21:23:30 2009に生成されました。  doxygen 1.4.7