The branch, v4-18-test has been updated via 0f1dbe552dc winbind: Fix "wbinfo -u" on a Samba AD DC with >1000 users via 97c9f812fa9 winbind: Test wbinfo -u with more than 1000 users from 128a80758fd s3:locking: fix debug level for NT_STATUS_NOT_FOUND messanges in get_static_share_mode_data
https://git.samba.org/?p=samba.git;a=shortlog;h=v4-18-test - Log ----------------------------------------------------------------- commit 0f1dbe552dc061e1863222b6b9471c1c7a412a83 Author: Volker Lendecke <v...@samba.org> Date: Wed Apr 26 17:19:29 2023 +0200 winbind: Fix "wbinfo -u" on a Samba AD DC with >1000 users BUG: https://bugzilla.samba.org/show_bug.cgi?id=15366 Signed-off-by: Volker Lendecke <v...@samba.org> Reviewed-by: Andrew Bartlett <abart...@samba.org> Autobuild-User(master): Andrew Bartlett <abart...@samba.org> Autobuild-Date(master): Tue May 9 02:58:45 UTC 2023 on atb-devel-224 (cherry picked from commit 6206e15b4de0ba67d713124c2be353dabf3878c8) Autobuild-User(v4-18-test): Jule Anger <jan...@samba.org> Autobuild-Date(v4-18-test): Fri May 12 15:58:34 UTC 2023 on atb-devel-224 commit 97c9f812fa9f246fbedebcb28fcf875ec6679709 Author: Volker Lendecke <v...@samba.org> Date: Thu Apr 27 12:25:24 2023 +0200 winbind: Test wbinfo -u with more than 1000 users winbind asks dcerpc_samr_LookupRids in one batch, where samr.idl has NTSTATUS samr_LookupRids( [in,ref] policy_handle *domain_handle, [in,range(0,1000)] uint32 num_rids, [in,size_is(1000),length_is(num_rids)] uint32 rids[], [out,ref] lsa_Strings *names, [out,ref] samr_Ids *types ); limiting num_rids to 1000 entries. Test this. BUG: https://bugzilla.samba.org/show_bug.cgi?id=15366 Signed-off-by: Volker Lendecke <v...@samba.org> Reviewed-by: Andrew Bartlett <abart...@samba.org> (cherry picked from commit f633389f36e79d3e772777ad7ca13012e3616273) ----------------------------------------------------------------------- Summary of changes: source3/script/tests/test_wbinfo_u_large_ad.sh | 28 +++++++ source3/winbindd/winbindd_samr.c | 102 +++++++++++++++---------- source4/selftest/tests.py | 5 ++ 3 files changed, 95 insertions(+), 40 deletions(-) create mode 100755 source3/script/tests/test_wbinfo_u_large_ad.sh Changeset truncated at 500 lines: diff --git a/source3/script/tests/test_wbinfo_u_large_ad.sh b/source3/script/tests/test_wbinfo_u_large_ad.sh new file mode 100755 index 00000000000..ab5f0ca1f6a --- /dev/null +++ b/source3/script/tests/test_wbinfo_u_large_ad.sh @@ -0,0 +1,28 @@ +#!/bin/sh + +LDBMODIFY="$VALGRIND ${LDBMODIFY:-$BINDIR/ldbmodify} $CONFIGURATION" +LDBSEARCH="$VALGRIND ${LDBSEARCH:-$BINDIR/ldbsearch} $CONFIGURATION" +WBINFO="$VALGRIND ${WBINFO:-$BINDIR/wbinfo} $CONFIGURATION" + +NUM_USERS=1234 + +BASE_DN=$($LDBSEARCH -H ldap://$DC_SERVER -b "" --scope=base defaultNamingContext | awk '/^defaultNamingContext/ {print $2}') + +incdir=$(dirname $0)/../../../testprogs/blackbox +. $incdir/subunit.sh + +seq -w 1 "$NUM_USERS" | + xargs -INUM echo -e "dn:cn=large_ad_NUM,cn=users,$BASE_DN\nchangetype:add\nobjectclass:user\nsamaccountname:large_ad_NUM\n" | + $LDBMODIFY -H ldap://$DC_SERVER -U "$DOMAIN\Administrator%$DC_PASSWORD" + +testit_grep_count \ + "Make sure $NUM_USERS $DOMAIN users are returned" \ + "$DOMAIN/large_ad_" \ + "$NUM_USERS" \ + ${WBINFO} -u || failed=$(expr $failed + 1) + +seq -w 1 "$NUM_USERS" | + xargs -INUM echo -e "dn:cn=large_ad_NUM,cn=users,$BASE_DN\nchangetype:delete\n" | + $LDBMODIFY -H ldap://$DC_SERVER -U "$DOMAIN\Administrator%$DC_PASSWORD" + +testok $0 $failed diff --git a/source3/winbindd/winbindd_samr.c b/source3/winbindd/winbindd_samr.c index ebf9c24b9e4..92dd1851abd 100644 --- a/source3/winbindd/winbindd_samr.c +++ b/source3/winbindd/winbindd_samr.c @@ -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: diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py index 823ada7a5dc..f8f7aae700d 100755 --- a/source4/selftest/tests.py +++ b/source4/selftest/tests.py @@ -852,6 +852,11 @@ for env in ["nt4_dc", "nt4_member", "ad_dc", "ad_member", "chgdcpass", "rodc"]: planpythontestsuite(env + ":local", "samba.tests.ntlm_auth") +plantestsuite( + "samba.wbinfo_u_large_ad.(ad_dc:local)", + "ad_dc:local", + [os.path.join(samba3srcdir, "script/tests/test_wbinfo_u_large_ad.sh")]) + for env in ["ktest"]: planpythontestsuite(env + ":local", "samba.tests.ntlm_auth_krb5") -- Samba Shared Repository