winbind: Fix "wbinfo -u" on a Samba AD DC with >1000 users
authorVolker Lendecke <vl@samba.org>
Wed, 26 Apr 2023 15:19:29 +0000 (17:19 +0200)
committerAndrew Bartlett <abartlet@samba.org>
Tue, 9 May 2023 02:58:45 +0000 (02:58 +0000)
BUG: https://bugzilla.samba.org/show_bug.cgi?id=15366

Signed-off-by: Volker Lendecke <vl@samba.org>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
Autobuild-User(master): Andrew Bartlett <abartlet@samba.org>
Autobuild-Date(master): Tue May  9 02:58:45 UTC 2023 on atb-devel-224

selftest/knownfail.d/wbinfo_u_large_ad [deleted file]
source3/winbindd/winbindd_samr.c

diff --git a/selftest/knownfail.d/wbinfo_u_large_ad b/selftest/knownfail.d/wbinfo_u_large_ad
deleted file mode 100644 (file)
index a7814a9..0000000
+++ /dev/null
@@ -1 +0,0 @@
-^samba.wbinfo_u_large_ad.\(ad_dc:local\).*
\ No newline at end of file
index ebf9c24b9e4d7315b9c1a05c4d0b30f9426bc9d4..92dd1851abd2dec7c959e8239dc5750e3da22d29 100644 (file)
@@ -914,8 +914,6 @@ static NTSTATUS sam_rids_to_names(struct winbindd_domain *domain,
        struct rpc_pipe_client *samr_pipe = NULL;
        struct dcerpc_binding_handle *h = NULL;
        struct policy_handle dom_pol = { .handle_type = 0, };
-       struct lsa_Strings lsa_names = { .count = 0, };
-       struct samr_Ids samr_types = { .count = 0, };
        enum lsa_SidType *types = NULL;
        char **names = NULL;
        const char *domain_name = NULL;
@@ -997,49 +995,73 @@ again:
        }
        h = samr_pipe->binding_handle;
 
-       status = dcerpc_samr_LookupRids(
-               h,
-               tmp_ctx,
-               &dom_pol,
-               num_rids,
-               rids,
-               &lsa_names,
-               &samr_types,
-               &result);
-
-       if (!retry && reset_connection_on_error(domain, samr_pipe, status)) {
-               retry = true;
-               goto again;
-       }
+       /*
+        * Magic number 1000 comes from samr.idl
+        */
 
-       if (!NT_STATUS_IS_OK(status)) {
-               DBG_DEBUG("dcerpc_samr_LookupRids failed: %s\n",
-                         nt_errstr(status));
-               goto fail;
-       }
-       if (!NT_STATUS_IS_OK(result) &&
-           !NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED)) {
-               DBG_DEBUG("dcerpc_samr_LookupRids resulted in %s\n",
-                         nt_errstr(result));
-               status = result;
-               goto fail;
-       }
+       for (i = 0; i < num_rids; i += 1000) {
+               uint32_t num_lookup_rids = MIN(num_rids - i, 1000);
+               struct lsa_Strings lsa_names = {
+                       .count = 0,
+               };
+               struct samr_Ids samr_types = {
+                       .count = 0,
+               };
+               uint32_t j;
+
+               status = dcerpc_samr_LookupRids(h,
+                                               tmp_ctx,
+                                               &dom_pol,
+                                               num_lookup_rids,
+                                               &rids[i],
+                                               &lsa_names,
+                                               &samr_types,
+                                               &result);
+
+               if (!retry &&
+                   reset_connection_on_error(domain, samr_pipe, status)) {
+                       retry = true;
+                       goto again;
+               }
 
-       for (i=0; i<num_rids; i++) {
-               types[i] = samr_types.ids[i];
-               names[i] = talloc_move(
-                       names,
-                       discard_const_p(char *, &lsa_names.names[i].string));
+               if (!NT_STATUS_IS_OK(status)) {
+                       DBG_DEBUG("dcerpc_samr_LookupRids failed: %s\n",
+                                 nt_errstr(status));
+                       goto fail;
+               }
+               if (!NT_STATUS_IS_OK(result) &&
+                   !NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED)) {
+                       DBG_DEBUG("dcerpc_samr_LookupRids resulted in %s\n",
+                                 nt_errstr(result));
+                       status = result;
+                       goto fail;
+               }
 
-               if (names[i] != NULL) {
-                       char *normalized = NULL;
-                       NTSTATUS nstatus = normalize_name_map(
-                               names, domain_name, names[i], &normalized);
-                       if (NT_STATUS_IS_OK(nstatus) ||
-                           NT_STATUS_EQUAL(nstatus, NT_STATUS_FILE_RENAMED)) {
-                               names[i] = normalized;
+               for (j = 0; j < num_lookup_rids; j++) {
+                       uint32_t dst = i + j;
+
+                       types[dst] = samr_types.ids[j];
+                       names[dst] = talloc_move(
+                               names,
+                               discard_const_p(char *,
+                                               &lsa_names.names[j].string));
+                       if (names[dst] != NULL) {
+                               char *normalized = NULL;
+                               NTSTATUS nstatus =
+                                       normalize_name_map(names,
+                                                          domain_name,
+                                                          names[dst],
+                                                          &normalized);
+                               if (NT_STATUS_IS_OK(nstatus) ||
+                                   NT_STATUS_EQUAL(nstatus,
+                                                   NT_STATUS_FILE_RENAMED)) {
+                                       names[dst] = normalized;
+                               }
                        }
                }
+
+               TALLOC_FREE(samr_types.ids);
+               TALLOC_FREE(lsa_names.names);
        }
 
 done: