Replace cli_rpc_pipe_close by a talloc destructor on rpc_pipe_struct
[kai/samba.git] / source / utils / smbtree.c
index 5deb29a149b3a03b5b3f66feea464e9376d03695..c2b364d1e9ac80250dbb3d60ab97bbf36f361933 100644 (file)
    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.
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
 #include "includes.h"
 
-static BOOL use_bcast;
+static int use_bcast;
 
 /* How low can we go? */
 
@@ -33,7 +32,7 @@ static enum tree_level level = LEV_SHARE;
 
 struct name_list {
         struct name_list *prev, *next;
-        pstring name, comment;
+        char *name, *comment;
         uint32 server_type;
 };
 
@@ -58,44 +57,59 @@ static void add_name(const char *machine_name, uint32 server_type,
 
         ZERO_STRUCTP(new_name);
 
-        pstrcpy(new_name->name, machine_name);
-        pstrcpy(new_name->comment, comment);
+       new_name->name = SMB_STRDUP(machine_name);
+       new_name->comment = SMB_STRDUP(comment);
         new_name->server_type = server_type;
 
+       if (!new_name->name || !new_name->comment) {
+               SAFE_FREE(new_name->name);
+               SAFE_FREE(new_name->comment);
+               SAFE_FREE(new_name);
+               return;
+       }
+
         DLIST_ADD(*name_list, new_name);
 }
 
 /****************************************************************************
   display tree of smb workgroups, servers and shares
 ****************************************************************************/
-static BOOL get_workgroups(struct user_auth_info *user_info)
+static bool get_workgroups(struct user_auth_info *user_info)
 {
         struct cli_state *cli;
-        struct in_addr server_ip;
-       pstring master_workgroup;
+        struct sockaddr_storage server_ss;
+       TALLOC_CTX *ctx = talloc_tos();
+       char *master_workgroup = NULL;
 
         /* Try to connect to a #1d name of our current workgroup.  If that
            doesn't work broadcast for a master browser and then jump off
            that workgroup. */
 
-       pstrcpy(master_workgroup, lp_workgroup());
+       master_workgroup = talloc_strdup(ctx, lp_workgroup());
+       if (!master_workgroup) {
+               return false;
+       }
 
-        if (!use_bcast && !find_master_ip(lp_workgroup(), &server_ip)) {
+        if (!use_bcast && !find_master_ip(lp_workgroup(), &server_ss)) {
                 DEBUG(4, ("Unable to find master browser for workgroup %s, falling back to broadcast\n", 
                          master_workgroup));
                                use_bcast = True;
                } else if(!use_bcast) {
-               if (!(cli = get_ipc_connect(inet_ntoa(server_ip), &server_ip, user_info)))
+                       char addr[INET6_ADDRSTRLEN];
+                       print_sockaddr(addr, sizeof(addr), &server_ss);
+                       if (!(cli = get_ipc_connect(addr, &server_ss, user_info)))
                                return False;
                }
-               
-               if (!(cli = get_ipc_connect_master_ip_bcast(master_workgroup, user_info))) {
+
+               if (!(cli = get_ipc_connect_master_ip_bcast(talloc_tos(),
+                                                       user_info,
+                                                       &master_workgroup))) {
                        DEBUG(4, ("Unable to find master browser by "
                                  "broadcast\n"));
                        return False;
         }
 
-        if (!cli_NetServerEnum(cli, master_workgroup, 
+        if (!cli_NetServerEnum(cli, master_workgroup,
                                SV_TYPE_DOMAIN_ENUM, add_name, &workgroups))
                 return False;
 
@@ -104,42 +118,44 @@ static BOOL get_workgroups(struct user_auth_info *user_info)
 
 /* Retrieve the list of servers for a given workgroup */
 
-static BOOL get_servers(char *workgroup, struct user_auth_info *user_info)
+static bool get_servers(char *workgroup, struct user_auth_info *user_info)
 {
         struct cli_state *cli;
-        struct in_addr server_ip;
+        struct sockaddr_storage server_ss;
+       char addr[INET6_ADDRSTRLEN];
 
         /* Open an IPC$ connection to the master browser for the workgroup */
 
-        if (!find_master_ip(workgroup, &server_ip)) {
+        if (!find_master_ip(workgroup, &server_ss)) {
                 DEBUG(4, ("Cannot find master browser for workgroup %s\n",
                           workgroup));
                 return False;
         }
 
-        if (!(cli = get_ipc_connect(inet_ntoa(server_ip), &server_ip, user_info)))
+       print_sockaddr(addr, sizeof(addr), &server_ss);
+        if (!(cli = get_ipc_connect(addr, &server_ss, user_info)))
                 return False;
 
-        if (!cli_NetServerEnum(cli, workgroup, SV_TYPE_ALL, add_name, 
+        if (!cli_NetServerEnum(cli, workgroup, SV_TYPE_ALL, add_name,
                                &servers))
                 return False;
 
         return True;
 }
 
-static BOOL get_rpc_shares(struct cli_state *cli, 
+static bool get_rpc_shares(struct cli_state *cli,
                           void (*fn)(const char *, uint32, const char *, void *),
                           void *state)
 {
        NTSTATUS status;
        struct rpc_pipe_client *pipe_hnd;
        TALLOC_CTX *mem_ctx;
-       uint32 enum_hnd;
+       WERROR werr;
+       struct srvsvc_NetShareInfoCtr info_ctr;
        struct srvsvc_NetShareCtr1 ctr1;
-       union srvsvc_NetShareCtr ctr;
-       uint32 numentries;
        int i;
-       uint32 info_level = 1;
+       uint32_t resume_handle = 0;
+       uint32_t total_entries = 0;
 
        mem_ctx = talloc_new(NULL);
        if (mem_ctx == NULL) {
@@ -147,7 +163,6 @@ static BOOL get_rpc_shares(struct cli_state *cli,
                return False;
        }
 
-       enum_hnd = 0;
        pipe_hnd = cli_rpc_pipe_open_noauth(cli, PI_SRVSVC, &status);
 
        if (pipe_hnd == NULL) {
@@ -157,33 +172,38 @@ static BOOL get_rpc_shares(struct cli_state *cli,
                return False;
        }
 
+       ZERO_STRUCT(info_ctr);
        ZERO_STRUCT(ctr1);
-       level = 1;
-       ctr.ctr1 = &ctr1;
 
-       status = rpccli_srvsvc_NetShareEnum(pipe_hnd, mem_ctx, NULL,
-                                           &info_level, &ctr,
-                                           0xffffffff, &numentries,
-                                           &enum_hnd);
+       info_ctr.level = 1;
+       info_ctr.ctr.ctr1 = &ctr1;
+
+       status = rpccli_srvsvc_NetShareEnumAll(pipe_hnd, mem_ctx,
+                                              pipe_hnd->desthost,
+                                              &info_ctr,
+                                              0xffffffff,
+                                              &total_entries,
+                                              &resume_handle,
+                                              &werr);
 
-       if (!NT_STATUS_IS_OK(status)) {
+       if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(werr)) {
                TALLOC_FREE(mem_ctx);
-               cli_rpc_pipe_close(pipe_hnd);
+               TALLOC_FREE(pipe_hnd);
                return False;
        }
 
-       for (i=0; i<numentries; i++) {
-               fn(ctr.ctr1->array[i].name, ctr.ctr1->array[i].type, 
-                  ctr.ctr1->array[i].comment, state);
+       for (i=0; i<total_entries; i++) {
+               struct srvsvc_NetShareInfo1 info = info_ctr.ctr.ctr1->array[i];
+               fn(info.name, info.type, info.comment, state);
        }
 
        TALLOC_FREE(mem_ctx);
-       cli_rpc_pipe_close(pipe_hnd);
+       TALLOC_FREE(pipe_hnd);
        return True;
 }
 
 
-static BOOL get_shares(char *server_name, struct user_auth_info *user_info)
+static bool get_shares(char *server_name, struct user_auth_info *user_info)
 {
         struct cli_state *cli;
 
@@ -192,14 +212,14 @@ static BOOL get_shares(char *server_name, struct user_auth_info *user_info)
 
        if (get_rpc_shares(cli, add_name, &shares))
                return True;
-       
+
         if (!cli_RNetShareEnum(cli, add_name, &shares))
                 return False;
 
         return True;
 }
 
-static BOOL print_tree(struct user_auth_info *user_info)
+static bool print_tree(struct user_auth_info *user_info)
 {
         struct name_list *wg, *sv, *sh;
 
@@ -250,6 +270,8 @@ static BOOL print_tree(struct user_auth_info *user_info)
 ****************************************************************************/
  int main(int argc,char *argv[])
 {
+       TALLOC_CTX *frame = talloc_stackframe();
+       struct user_auth_info local_auth_info;
        struct poptOption long_options[] = {
                POPT_AUTOHELP
                { "broadcast", 'b', POPT_ARG_VAL, &use_bcast, True, "Use broadcast instead of using the master browser" },
@@ -260,7 +282,7 @@ static BOOL print_tree(struct user_auth_info *user_info)
                POPT_TABLEEND
        };
        poptContext pc;
-       
+
        /* Initialise samba stuff */
        load_case_tables();
 
@@ -270,28 +292,34 @@ static BOOL print_tree(struct user_auth_info *user_info)
 
        setup_logging(argv[0],True);
 
-       pc = poptGetContext("smbtree", argc, (const char **)argv, long_options, 
+       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,True);
+       lp_load(get_dyn_CONFIGFILE(),True,False,False,True);
        load_interfaces();
 
        /* Parse command line args */
 
-       if (!cmdline_auth_info.got_pass) {
+       if (!get_cmdline_auth_info_got_pass()) {
                char *pass = getpass("Password: ");
                if (pass) {
-                       pstrcpy(cmdline_auth_info.password, pass);
+                       set_cmdline_auth_info_password(pass);
                }
-        cmdline_auth_info.got_pass = True;
        }
 
        /* Now do our stuff */
 
-        if (!print_tree(&cmdline_auth_info))
+       if (!get_cmdline_auth_info_copy(&local_auth_info)) {
+               return 1;
+       }
+
+        if (!print_tree(&local_auth_info)) {
+               TALLOC_FREE(frame);
                 return 1;
+       }
 
+       TALLOC_FREE(frame);
        return 0;
 }