diff options
author | Michal Zidek <mzidek@redhat.com> | 2012-08-06 19:42:08 +0200 |
---|---|---|
committer | Jakub Hrozek <jhrozek@redhat.com> | 2012-08-10 15:26:34 +0200 |
commit | fb5abb2a7abf63974d8db444c66f50a2dd74901f (patch) | |
tree | 425befccd8f17da69aa0048627aead2948a5d5d7 | |
parent | 8791b277ed173be2a258116a9203ba1862c30f65 (diff) | |
download | sssd-fb5abb2a7abf63974d8db444c66f50a2dd74901f.tar.gz sssd-fb5abb2a7abf63974d8db444c66f50a2dd74901f.tar.bz2 sssd-fb5abb2a7abf63974d8db444c66f50a2dd74901f.zip |
When ldap_group_nesting_level was reached, the LDAP provider tried to link group members with groups outside nesting limit.
https://fedorahosted.org/sssd/ticket/1194
-rw-r--r-- | src/providers/ldap/sdap_async_initgroups.c | 46 |
1 files changed, 45 insertions, 1 deletions
diff --git a/src/providers/ldap/sdap_async_initgroups.c b/src/providers/ldap/sdap_async_initgroups.c index 8a837bcc..2cda9c2e 100644 --- a/src/providers/ldap/sdap_async_initgroups.c +++ b/src/providers/ldap/sdap_async_initgroups.c @@ -1781,7 +1781,14 @@ save_rfc2307bis_group_memberships(struct sdap_initgr_rfc2307bis_state *state) TALLOC_CTX *tmp_ctx; struct rfc2307bis_group_memberships_state *membership_state; struct membership_diff *iter; + struct membership_diff *iter_start; + struct membership_diff *iter_tmp; bool in_transaction = false; + int num_added; + int i; + int grp_count; + int grp_count_old = 0; + char **add = NULL; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) return ENOMEM; @@ -1813,10 +1820,47 @@ save_rfc2307bis_group_memberships(struct sdap_initgr_rfc2307bis_state *state) } in_transaction = true; + iter_tmp = membership_state->memberships; + iter_start = membership_state->memberships; + DLIST_FOR_EACH(iter, membership_state->memberships) { + /* Create a copy of iter->add array but do not include groups outside + * nesting limit. This array must be NULL terminated. + */ + for (grp_count = 0; iter->add[grp_count]; grp_count++); + if (grp_count > grp_count_old) { + add = talloc_realloc(tmp_ctx, add, char*, grp_count + 1); + if (add == NULL) { + ret = ENOMEM; + goto done; + } + } + + num_added = 0; + for (i = 0; i < grp_count; i++) { + DLIST_FOR_EACH(iter_tmp, iter_start) { + if (!strcmp(iter_tmp->name,iter->add[i])) { + add[num_added] = iter->add[i]; + num_added++; + break; + } + } + } + + /* Swap old and new group counter. */ + grp_count ^= grp_count_old; + grp_count_old ^= grp_count; + grp_count ^= grp_count_old; + + if (num_added == 0) { + /* Nothing to add. Skip. */ + continue; + } else { + add[num_added] = NULL; + } ret = sysdb_update_members(state->sysdb, iter->name, SYSDB_MEMBER_GROUP, - (const char *const *) iter->add, + (const char *const *) add, (const char *const *) iter->del); if (ret != EOK) { DEBUG(3, ("Failed to update memberships\n")); |