From 98052f6f186f27a6fde4786274132a6bb4d69e79 Mon Sep 17 00:00:00 2001
From: Pavel Reichl <preichl@redhat.com>
Date: Mon, 12 May 2014 15:00:26 +0000
Subject: [PATCH] SDAP: Make nesting_level = 0 to ignore nested groups
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Make ldap_group_nesting_level = 0 to ignore group nesting entirely.

Resolves:
https://fedorahosted.org/sssd/ticket/2294

Reviewed-by: Lukáš Slebodník <lslebodn@redhat.com>
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
(cherry picked from commit c30f1d05d6c75080fbe8ea9868f291e7a331ad44)

Line numbers are slightly adjusted by Howard Guo <hguo@suse.com> to fit into this older version of sssd.

diff -rupN sssd-1.11.5.1/src/providers/ldap/sdap_async_groups.c sssd-1.11.5.1-patched/src/providers/ldap/sdap_async_groups.c
--- sssd-1.11.5.1/src/providers/ldap/sdap_async_groups.c	2016-02-19 14:30:50.543055896 +0100
+++ sssd-1.11.5.1-patched/src/providers/ldap/sdap_async_groups.c	2016-02-19 14:40:32.811904140 +0100
@@ -34,16 +34,18 @@ static int sdap_find_entry_by_origDN(TAL
                                      struct sysdb_ctx *ctx,
                                      struct sss_domain_info *domain,
                                      const char *orig_dn,
-                                     char **localdn)
+                                     char **_localdn,
+                                     bool *_is_group)
 {
     TALLOC_CTX *tmpctx;
-    const char *no_attrs[] = { NULL };
+    const char *attrs[] = {SYSDB_OBJECTCLASS,  NULL};
     struct ldb_dn *base_dn;
     char *filter;
     struct ldb_message **msgs;
     size_t num_msgs;
     int ret;
     char *sanitized_dn;
+    const char *objectclass;
 
     tmpctx = talloc_new(NULL);
     if (!tmpctx) {
@@ -70,7 +72,7 @@ static int sdap_find_entry_by_origDN(TAL
 
     DEBUG(9, ("Searching cache for [%s].\n", sanitized_dn));
     ret = sysdb_search_entry(tmpctx, ctx,
-                             base_dn, LDB_SCOPE_SUBTREE, filter, no_attrs,
+                             base_dn, LDB_SCOPE_SUBTREE, filter, attrs,
                              &num_msgs, &msgs);
     if (ret) {
         goto done;
@@ -80,12 +82,25 @@ static int sdap_find_entry_by_origDN(TAL
         goto done;
     }
 
-    *localdn = talloc_strdup(memctx, ldb_dn_get_linearized(msgs[0]->dn));
-    if (!*localdn) {
+    *_localdn = talloc_strdup(memctx, ldb_dn_get_linearized(msgs[0]->dn));
+    if (!*_localdn) {
         ret = ENOENT;
         goto done;
     }
 
+    if (_is_group != NULL) {
+        objectclass = ldb_msg_find_attr_as_string(msgs[0], SYSDB_OBJECTCLASS,
+                                                  NULL);
+        if (objectclass == NULL) {
+            DEBUG(SSSDBG_OP_FAILURE, ("An antry without a %s?\n",
+                  SYSDB_OBJECTCLASS));
+            ret = EINVAL;
+            goto done;
+        }
+
+        *_is_group = strcmp(SYSDB_GROUP_CLASS, objectclass) == 0;
+    }
+
     ret = EOK;
 
 done:
@@ -234,7 +249,8 @@ static int sdap_fill_memberships(struct
             /* sync search entry with this as origDN */
             ret = sdap_find_entry_by_origDN(el->values, member_sysdb,
                                             member_dom, (char *)values[i].data,
-                                            (char **)&el->values[j].data);
+                                            (char **)&el->values[j].data,
+                                            NULL);
             if (ret == ENOENT) {
                 /* member may be outside of the configured search bases
                  * or out of scope of nesting limit */
@@ -1189,6 +1205,10 @@ sdap_process_group_members_2307bis(struc
     char *strdn;
     int ret;
     int i;
+    int nesting_level;
+    bool is_group;
+
+    nesting_level = dp_opt_get_int(state->opts->basic, SDAP_NESTING_LEVEL);
 
     for (i=0; i < memberel->num_values; i++) {
         member_dn = (char *)memberel->values[i].data;
@@ -1197,8 +1217,15 @@ sdap_process_group_members_2307bis(struc
                                         state->sysdb,
                                         state->dom,
                                         member_dn,
-                                        &strdn);
+                                        &strdn,
+                                        &is_group);
+
         if (ret == EOK) {
+            if (nesting_level == 0 && is_group) {
+                /* Ignore group members which are groups themselves. */
+                continue;
+            }
+
             /*
              * User already cached in sysdb. Remember the sysdb DN for later
              * use by sdap_save_groups()
