From fa2756c944b0316b2fef33646d15d13670dcfb49 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Sun, 22 Apr 2007 15:25:54 +0000 Subject: r22461: Use ranged LDAP queries in lookup_usergroups_member() and start to optinmize lookup_groupmem(). In the later, at least try to avoid those massive LDAP dn_lookups by looking in the cache before. Guenther (This used to be commit eb1566869c5493f2a1d1ff9fcaaa45c143ad12a0) --- source3/nsswitch/winbindd_ads.c | 174 +++++++++++++++++----------------------- 1 file changed, 75 insertions(+), 99 deletions(-) (limited to 'source3') diff --git a/source3/nsswitch/winbindd_ads.c b/source3/nsswitch/winbindd_ads.c index 8391a985fc..f189123d7d 100644 --- a/source3/nsswitch/winbindd_ads.c +++ b/source3/nsswitch/winbindd_ads.c @@ -609,13 +609,15 @@ static NTSTATUS lookup_usergroups_memberof(struct winbindd_domain *domain, { ADS_STATUS rc; NTSTATUS status = NT_STATUS_UNSUCCESSFUL; - int count; LDAPMessage *res = NULL; ADS_STRUCT *ads; const char *attrs[] = {"memberOf", NULL}; size_t num_groups = 0; DOM_SID *group_sids = NULL; int i; + char **strings; + size_t num_strings = 0; + DEBUG(3,("ads: lookup_usergroups_memberof\n")); @@ -626,22 +628,16 @@ static NTSTATUS lookup_usergroups_memberof(struct winbindd_domain *domain, goto done; } - rc = ads_search_retry_extended_dn(ads, &res, user_dn, attrs, - ADS_EXTENDED_DN_HEX_STRING); - - if (!ADS_ERR_OK(rc) || !res) { + rc = ads_search_retry_extended_dn_ranged(ads, mem_ctx, user_dn, attrs, + ADS_EXTENDED_DN_HEX_STRING, + &strings, &num_strings); + + if (!ADS_ERR_OK(rc)) { DEBUG(1,("lookup_usergroups_memberof ads_search member=%s: %s\n", user_dn, ads_errstr(rc))); return ads_ntstatus(rc); } - count = ads_count_replies(ads, res); - - if (count == 0) { - status = NT_STATUS_NO_SUCH_USER; - goto done; - } - *user_sids = NULL; num_groups = 0; @@ -651,16 +647,32 @@ static NTSTATUS lookup_usergroups_memberof(struct winbindd_domain *domain, goto done; } - count = ads_pull_sids_from_extendeddn(ads, mem_ctx, res, "memberOf", - ADS_EXTENDED_DN_HEX_STRING, - &group_sids); - if (count == 0) { + group_sids = TALLOC_ZERO_ARRAY(mem_ctx, DOM_SID, num_strings + 1); + if (!group_sids) { + TALLOC_FREE(strings); + status = NT_STATUS_NO_MEMORY; + goto done; + } + + for (i=0; iname, sid_string_static(group_sid))); @@ -886,77 +893,19 @@ static NTSTATUS lookup_groupmem(struct winbindd_domain *domain, members = NULL; num_members = 0; - if ((attrs = TALLOC_ARRAY(mem_ctx, const char *, 3)) == NULL) { - status = NT_STATUS_NO_MEMORY; - goto done; - } - - attrs[1] = talloc_strdup(mem_ctx, "usnChanged"); - attrs[2] = NULL; - - do { - if (num_members == 0) - attrs[0] = talloc_strdup(mem_ctx, "member"); - - DEBUG(10, ("Searching for attrs[0] = %s, attrs[1] = %s\n", attrs[0], attrs[1])); - - rc = ads_search_retry(ads, &res, ldap_exp, attrs); - - if (!ADS_ERR_OK(rc) || !res) { - DEBUG(1,("ads: lookup_groupmem ads_search: %s\n", - ads_errstr(rc))); - status = ads_ntstatus(rc); - goto done; - } + args.control = ADS_EXTENDED_DN_OID; + args.val = ADS_EXTENDED_DN_HEX_STRING; + args.critical = True; - count = ads_count_replies(ads, res); - if (count == 0) - break; + rc = ads_ranged_search(ads, mem_ctx, LDAP_SCOPE_SUBTREE, ads->config.bind_path, + ldap_exp, &args, "member", &members, &num_members); - if (num_members == 0) { - if (!ads_pull_uint32(ads, res, "usnChanged", &first_usn)) { - DEBUG(1, ("ads: lookup_groupmem could not pull usnChanged!\n")); - goto done; - } - } - - if (!ads_pull_uint32(ads, res, "usnChanged", ¤t_usn)) { - DEBUG(1, ("ads: lookup_groupmem could not pull usnChanged!\n")); - goto done; - } - - if (first_usn != current_usn) { - DEBUG(5, ("ads: lookup_groupmem USN on this record changed" - " - restarting search\n")); - if (num_retries < 5) { - num_retries++; - num_members = 0; - ads_msgfree(ads, res); - res = NULL; - continue; - } else { - DEBUG(5, ("ads: lookup_groupmem USN on this record changed" - " - restarted search too many times, aborting!\n")); - status = NT_STATUS_UNSUCCESSFUL; - goto done; - } - } - - members = ads_pull_strings_range(ads, mem_ctx, res, - "member", - members, - &attrs[0], - &num_members, - &more_values); - - ads_msgfree(ads, res); - res = NULL; - - if ((members == NULL) || (num_members == 0)) - break; - - } while (more_values); - + if (!ADS_ERR_OK(rc)) { + DEBUG(0,("ads_ranged_search failed with: %s\n", ads_errstr(rc))); + status = NT_STATUS_UNSUCCESSFUL; + goto done; + } + /* now we need to turn a list of members into rids, names and name types the problem is that the members are in the form of distinguised names */ @@ -975,19 +924,46 @@ static NTSTATUS lookup_groupmem(struct winbindd_domain *domain, for (i=0;i