summaryrefslogtreecommitdiffstats
path: root/src/providers/ldap/sdap_async_groups.c
diff options
context:
space:
mode:
authorStephen Gallagher <sgallagh@redhat.com>2012-05-08 08:47:33 -0400
committerStephen Gallagher <sgallagh@redhat.com>2012-05-10 11:34:46 -0400
commitae8d047122c7ba8123f72b2eac68944868ac37d4 (patch)
tree6a7be7127f9daf8732cc6fe7158c5da91c0cf3dd /src/providers/ldap/sdap_async_groups.c
parentca4b7b92738f3dd463914e3de5757cd98d37a983 (diff)
downloadsssd-ae8d047122c7ba8123f72b2eac68944868ac37d4.tar.gz
sssd-ae8d047122c7ba8123f72b2eac68944868ac37d4.tar.xz
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.c54
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 fb6a85e22..361525037 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,