r16349: Another fix to make winbind more robust in large domains:
authorGünther Deschner <gd@samba.org>
Mon, 19 Jun 2006 16:00:32 +0000 (16:00 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 16:17:37 +0000 (11:17 -0500)
We may only feed rpc_useraliases with chunks of 1024 entries.  This is
important as the token generation otherwise fails when a user is member
of more then 1024 groups.

Volker, please check.

Guenther
(This used to be commit d8fd94648f965eb043f957b154ce63b245a90328)

source3/nsswitch/winbindd_rpc.c

index de4dbc9a79bed6915b9a31ffc4d46d6ea148a1e1..322d284e0cb86c10643ec176407917422437bd62 100644 (file)
@@ -473,9 +473,14 @@ NTSTATUS msrpc_lookup_useraliases(struct winbindd_domain *domain,
 {
        NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
        POLICY_HND dom_pol;
-       DOM_SID2 *sid2;
+       DOM_SID2 *query_sids;
+       uint32 num_query_sids = 0;
        int i;
        struct rpc_pipe_client *cli;
+       uint32 *alias_rids_query, num_aliases_query;
+       int rangesize = MAX_SAM_ENTRIES_W2K;
+       uint32 total_sids = 0;
+       int num_queries = 1;
 
        *num_aliases = 0;
        *alias_rids = NULL;
@@ -486,19 +491,55 @@ NTSTATUS msrpc_lookup_useraliases(struct winbindd_domain *domain,
        if (!NT_STATUS_IS_OK(result))
                return result;
 
-       sid2 = TALLOC_ARRAY(mem_ctx, DOM_SID2, num_sids);
+       do {
+               /* prepare query */
 
-       if (sid2 == NULL)
-               return NT_STATUS_NO_MEMORY;
+               num_query_sids = MIN(num_sids - total_sids, rangesize);
 
-       for (i=0; i<num_sids; i++) {
-               sid_copy(&sid2[i].sid, &sids[i]);
-               sid2[i].num_auths = sid2[i].sid.num_auths;
-       }
+               DEBUG(10,("rpc: lookup_useraliases: entering query %d for %d sids\n", 
+                       num_queries, num_query_sids));  
+
+
+               query_sids = TALLOC_ARRAY(mem_ctx, DOM_SID2, num_query_sids);
+               if (query_sids == NULL) {
+                       return NT_STATUS_NO_MEMORY;
+               }
+
+               for (i=0; i<num_query_sids; i++) {
+                       sid_copy(&query_sids[i].sid, &sids[total_sids++]);
+                       query_sids[i].num_auths = query_sids[i].sid.num_auths;
+               }
+
+               /* do request */
+
+               result = rpccli_samr_query_useraliases(cli, mem_ctx, &dom_pol,
+                                                      num_query_sids, query_sids,
+                                                      &num_aliases_query, 
+                                                      &alias_rids_query);
+
+               if (!NT_STATUS_IS_OK(result)) {
+                       *num_aliases = 0;
+                       *alias_rids = NULL;
+                       TALLOC_FREE(query_sids);
+                       goto done;
+               }
+
+               /* process output */
+
+               for (i=0; i<num_aliases_query; i++) {
+                       add_rid_to_array_unique(mem_ctx, alias_rids_query[i], 
+                                               alias_rids, num_aliases);
+               }
+
+               TALLOC_FREE(query_sids);
+
+               num_queries++;
+
+       } while (total_sids < num_sids);
 
-       result = rpccli_samr_query_useraliases(cli, mem_ctx, &dom_pol,
-                                              num_sids, sid2,
-                                              num_aliases, alias_rids);
+ done:
+       DEBUG(10,("rpc: lookup_useraliases: got %d aliases in %d queries "
+               "(rangesize: %d)\n", *num_aliases, num_queries, rangesize));
 
        return result;
 }