s3: Fix bug 8966, Fix net rpc share allowedusers to work with 2008r2
authorJeremy Allison <jra@samba.org>
Mon, 1 Oct 2012 04:16:18 +0000 (06:16 +0200)
committerVolker Lendecke <vl@samba.org>
Mon, 1 Oct 2012 05:59:34 +0000 (07:59 +0200)
The RAP NetShareEnum command was removed in 2008r2, so use the RPC
equivalent instead.

Autobuild-User(master): Volker Lendecke <vl@samba.org>
Autobuild-Date(master): Mon Oct  1 07:59:34 CEST 2012 on sn-devel-104

source3/utils/net_rpc.c

index ae5db99dd386ed13718dff72636767082568665d..60000242e05f025d79b2b14e97c7d130c2652c45 100644 (file)
@@ -4917,28 +4917,6 @@ static void show_userlist(struct rpc_pipe_client *pipe_hnd,
        return;
 }
 
-struct share_list {
-       int num_shares;
-       char **shares;
-};
-
-static void collect_share(const char *name, uint32 m,
-                         const char *comment, void *state)
-{
-       struct share_list *share_list = (struct share_list *)state;
-
-       if (m != STYPE_DISKTREE)
-               return;
-
-       share_list->num_shares += 1;
-       share_list->shares = SMB_REALLOC_ARRAY(share_list->shares, char *, share_list->num_shares);
-       if (!share_list->shares) {
-               share_list->num_shares = 0;
-               return;
-       }
-       share_list->shares[share_list->num_shares-1] = SMB_STRDUP(name);
-}
-
 /**
  * List shares on a remote RPC server, including the security descriptors.
  *
@@ -4964,16 +4942,21 @@ static NTSTATUS rpc_share_allowedusers_internals(struct net_context *c,
                                                int argc,
                                                const char **argv)
 {
-       int ret;
        bool r;
-       uint32 i;
        FILE *f;
+       NTSTATUS nt_status = NT_STATUS_OK;
+       uint32_t total_entries = 0;
+       uint32_t resume_handle = 0;
+       uint32_t preferred_len = 0xffffffff;
+       uint32_t i;
+       struct dcerpc_binding_handle *b = NULL;
+       struct srvsvc_NetShareInfoCtr info_ctr;
+       struct srvsvc_NetShareCtr1 ctr1;
+       WERROR result;
 
        struct user_token *tokens = NULL;
        int num_tokens = 0;
 
-       struct share_list share_list;
-
        if (argc == 0) {
                f = stdin;
        } else {
@@ -4998,22 +4981,47 @@ static NTSTATUS rpc_share_allowedusers_internals(struct net_context *c,
        for (i=0; i<num_tokens; i++)
                collect_alias_memberships(&tokens[i].token);
 
-       share_list.num_shares = 0;
-       share_list.shares = NULL;
+       ZERO_STRUCT(info_ctr);
+       ZERO_STRUCT(ctr1);
+
+       info_ctr.level = 1;
+       info_ctr.ctr.ctr1 = &ctr1;
+
+       b = pipe_hnd->binding_handle;
+
+       /* Issue the NetShareEnum RPC call and retrieve the response */
+       nt_status = dcerpc_srvsvc_NetShareEnumAll(b,
+                                       talloc_tos(),
+                                       pipe_hnd->desthost,
+                                       &info_ctr,
+                                       preferred_len,
+                                       &total_entries,
+                                       &resume_handle,
+                                       &result);
+
+       /* Was it successful? */
+       if (!NT_STATUS_IS_OK(nt_status)) {
+               /*  Nope.  Go clean up. */
+               goto done;
+       }
 
-       ret = cli_RNetShareEnum(cli, collect_share, &share_list);
+       if (!W_ERROR_IS_OK(result)) {
+               /*  Nope.  Go clean up. */
+               nt_status = werror_to_ntstatus(result);
+               goto done;
+       }
 
-       if (ret == -1) {
-               DEBUG(0, ("Error returning browse list: %s\n",
-                         cli_errstr(cli)));
+       if (total_entries == 0) {
                goto done;
        }
 
-       for (i = 0; i < share_list.num_shares; i++) {
-               char *netname = share_list.shares[i];
+        /* For each returned entry... */
+       for (i = 0; i < info_ctr.ctr.ctr1->count; i++) {
+               const char *netname = info_ctr.ctr.ctr1->array[i].name;
 
-               if (netname[strlen(netname)-1] == '$')
+               if (info_ctr.ctr.ctr1->array[i].type != STYPE_DISKTREE) {
                        continue;
+               }
 
                d_printf("%s\n", netname);
 
@@ -5025,9 +5033,8 @@ static NTSTATUS rpc_share_allowedusers_internals(struct net_context *c,
                free_user_token(&tokens[i].token);
        }
        SAFE_FREE(tokens);
-       SAFE_FREE(share_list.shares);
 
-       return NT_STATUS_OK;
+       return nt_status;
 }
 
 static int rpc_share_allowedusers(struct net_context *c, int argc,