summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichal Zidek <mzidek@redhat.com>2012-08-06 19:42:08 +0200
committerJakub Hrozek <jhrozek@redhat.com>2012-08-10 15:26:34 +0200
commitfb5abb2a7abf63974d8db444c66f50a2dd74901f (patch)
tree425befccd8f17da69aa0048627aead2948a5d5d7
parent8791b277ed173be2a258116a9203ba1862c30f65 (diff)
downloadsssd-fb5abb2a7abf63974d8db444c66f50a2dd74901f.tar.gz
sssd-fb5abb2a7abf63974d8db444c66f50a2dd74901f.tar.xz
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.c46
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 8a837bcc5..2cda9c2eb 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"));