diff options
author | Stephen Gallagher <sgallagh@redhat.com> | 2012-05-08 08:47:33 -0400 |
---|---|---|
committer | Stephen Gallagher <sgallagh@redhat.com> | 2012-05-10 11:34:46 -0400 |
commit | ae8d047122c7ba8123f72b2eac68944868ac37d4 (patch) | |
tree | 6a7be7127f9daf8732cc6fe7158c5da91c0cf3dd /src/providers/ldap/sdap_async_groups.c | |
parent | ca4b7b92738f3dd463914e3de5757cd98d37a983 (diff) | |
download | sssd-ae8d047122c7ba8123f72b2eac68944868ac37d4.tar.gz sssd-ae8d047122c7ba8123f72b2eac68944868ac37d4.tar.bz2 sssd-ae8d047122c7ba8123f72b2eac68944868ac37d4.zip |
LDAP: Handle very large Active Directory groups
Active Directory 2008R2 allows only 1500 group members to be
retrieved in a single lookup. However, when we hit such a
situation, we can take advantage of the ASQ lookups, which are not
similarly limited.
With this patch, we will add any members found by ASQ that were
not found by the initial lookup so we will end with a complete
group listing.
https://fedorahosted.org/sssd/ticket/783
Diffstat (limited to 'src/providers/ldap/sdap_async_groups.c')
-rw-r--r-- | src/providers/ldap/sdap_async_groups.c | 54 |
1 files changed, 37 insertions, 17 deletions
diff --git a/src/providers/ldap/sdap_async_groups.c b/src/providers/ldap/sdap_async_groups.c index fb6a85e2..36152503 100644 --- a/src/providers/ldap/sdap_async_groups.c +++ b/src/providers/ldap/sdap_async_groups.c @@ -2977,19 +2977,47 @@ sdap_nested_group_process_deref_result(struct tevent_req *req) errno_t ret; struct sdap_deref_ctx *dctx = state->derefctx; const char *tmp_name; + size_t i; while (dctx->result_index < dctx->num_results) { - if (dctx->deref_result[dctx->result_index]->map == \ - state->opts->user_map) { + /* Add to appropriate hash table */ + ret = sysdb_attrs_get_string( + dctx->deref_result[dctx->result_index]->attrs, + SYSDB_ORIG_DN, &orig_dn); + if (ret != EOK) { + DEBUG(2, ("The entry has no originalDN\n")); + return ret; + } - /* Add to appropriate hash table */ - ret = sysdb_attrs_get_string( - dctx->deref_result[dctx->result_index]->attrs, - SYSDB_ORIG_DN, &orig_dn); - if (ret != EOK) { - DEBUG(2, ("The entry has no originalDN\n")); - return ret; + /* Ensure that all members returned from the deref request are included + * in the member processing. Sometimes we will get more results back from + * deref/asq than we got from the initial lookup, as is the case with + * Active Directory and its range retrieval mechanism. + */ + for (i = 0; i < state->members->num_values; i++) { + /* FIXME: This is inefficient for very large sets of groups */ + if (strcasecmp((const char *)state->members->values[i].data, + orig_dn) == 0) break; + } + if (i >= state->members->num_values) { + state->members->values = talloc_realloc(state, + state->members->values, + struct ldb_val, + state->members->num_values + 1); + if (!state->members->values) { + return ENOMEM; } + state->members->values[state->members->num_values].data = + (uint8_t *)talloc_strdup(state->members->values, orig_dn); + if (!state->members->values[state->members->num_values].data) { + return ENOMEM; + } + state->members->values[state->members->num_values].length = strlen(orig_dn); + state->members->num_values++; + } + + if (dctx->deref_result[dctx->result_index]->map == \ + state->opts->user_map) { /* check if the user is in search base */ if (!sss_ldap_dn_in_search_bases(state, orig_dn, @@ -3024,14 +3052,6 @@ sdap_nested_group_process_deref_result(struct tevent_req *req) return EIO; } - ret = sysdb_attrs_get_string( - dctx->deref_result[dctx->result_index]->attrs, - SYSDB_ORIG_DN, &orig_dn); - if (ret != EOK) { - DEBUG(2, ("The entry has no originalDN\n")); - return ret; - } - /* check if the group is in search base */ if (!sss_ldap_dn_in_search_bases(state, orig_dn, state->opts->group_search_bases, |