From 868bf88fdf1adde15f6c3423d199d62290861c37 Mon Sep 17 00:00:00 2001
From: "Paul B. Henson" <henson@acm.org>
Date: Tue, 13 Nov 2012 03:31:43 -0800
Subject: [PATCH] Add ignore_group_members option.

https://fedorahosted.org/sssd/ticket/1376

diff --git a/src/confdb/confdb.c b/src/confdb/confdb.c
index d70dc36..2a12f80 100644
--- a/src/confdb/confdb.c
+++ b/src/confdb/confdb.c
@@ -894,6 +894,15 @@ static int confdb_get_domain_internal(struct confdb_ctx *cdb,
         goto done;
     }
 
+    ret = get_entry_as_bool(res->msgs[0], &domain->ignore_group_members,
+                            CONFDB_DOMAIN_IGNORE_GROUP_MEMBERS, 0);
+    if(ret != EOK) {
+        DEBUG(SSSDBG_FATAL_FAILURE,
+              ("Invalid value for %s\n",
+               CONFDB_DOMAIN_IGNORE_GROUP_MEMBERS));
+        goto done;
+    }
+
     ret = get_entry_as_uint32(res->msgs[0], &domain->id_min,
                               CONFDB_DOMAIN_MINID,
                               confdb_get_min_id(domain));
diff --git a/src/confdb/confdb.h b/src/confdb/confdb.h
index 88e80c1..eb16d01 100644
--- a/src/confdb/confdb.h
+++ b/src/confdb/confdb.h
@@ -162,6 +162,7 @@
 #define CONFDB_DOMAIN_CASE_SENSITIVE "case_sensitive"
 #define CONFDB_DOMAIN_SUBDOMAIN_HOMEDIR "subdomain_homedir"
 #define CONFDB_DOMAIN_DEFAULT_SUBDOMAIN_HOMEDIR "/home/%d/%u"
+#define CONFDB_DOMAIN_IGNORE_GROUP_MEMBERS "ignore_group_members"
 
 #define CONFDB_DOMAIN_USER_CACHE_TIMEOUT "entry_cache_user_timeout"
 #define CONFDB_DOMAIN_GROUP_CACHE_TIMEOUT "entry_cache_group_timeout"
@@ -200,6 +201,7 @@ struct sss_domain_info {
     int timeout;
     bool enumerate;
     bool fqnames;
+    bool ignore_group_members;
     uint32_t id_min;
     uint32_t id_max;
 
diff --git a/src/config/SSSDConfig/__init__.py.in b/src/config/SSSDConfig/__init__.py.in
index 458bd4c..9235ebd 100644
--- a/src/config/SSSDConfig/__init__.py.in
+++ b/src/config/SSSDConfig/__init__.py.in
@@ -111,6 +111,7 @@ option_strings = {
     'cache_credentials' : _('Cache credentials for offline login'),
     'store_legacy_passwords' : _('Store password hashes'),
     'use_fully_qualified_names' : _('Display users/groups in fully-qualified form'),
+    'ignore_group_members' : _('Don\'t include group members in group lookups'),
     'entry_cache_timeout' : _('Entry cache timeout length (seconds)'),
     'lookup_family_order' : _('Restrict or prefer a specific address family when performing DNS lookups'),
     'account_cache_expiration' : _('How long to keep cached entries after last successful login (days)'),
diff --git a/src/config/SSSDConfigTest.py b/src/config/SSSDConfigTest.py
index 8a9adb8..4f85629 100755
--- a/src/config/SSSDConfigTest.py
+++ b/src/config/SSSDConfigTest.py
@@ -493,6 +493,7 @@ class SSSDConfigTestSSSDDomain(unittest.TestCase):
             'cache_credentials',
             'store_legacy_passwords',
             'use_fully_qualified_names',
+            'ignore_group_members',
             'filter_users',
             'filter_groups',
             'entry_cache_timeout',
@@ -833,6 +834,7 @@ class SSSDConfigTestSSSDDomain(unittest.TestCase):
             'cache_credentials',
             'store_legacy_passwords',
             'use_fully_qualified_names',
+            'ignore_group_members',
             'filter_users',
             'filter_groups',
             'entry_cache_timeout',
diff --git a/src/config/etc/sssd.api.conf b/src/config/etc/sssd.api.conf
index 48fe7eb..3ed9d58 100644
--- a/src/config/etc/sssd.api.conf
+++ b/src/config/etc/sssd.api.conf
@@ -97,6 +97,7 @@ force_timeout = int, None, false
 cache_credentials = bool, None, false
 store_legacy_passwords = bool, None, false
 use_fully_qualified_names = bool, None, false
+ignore_group_members = bool, None, false
 entry_cache_timeout = int, None, false
 lookup_family_order = str, None, false
 account_cache_expiration = int, None, false
diff --git a/src/man/sssd.conf.5.xml b/src/man/sssd.conf.5.xml
index 39ef2bb..a7e9f2b 100644
--- a/src/man/sssd.conf.5.xml
+++ b/src/man/sssd.conf.5.xml
@@ -1218,6 +1218,23 @@ override_homedir = /home/%u
                     </listitem>
                 </varlistentry>
                 <varlistentry>
+                    <term>ignore_group_members (bool)</term>
+                    <listitem>
+                        <para>
+                            Do not return group members for group lookups.
+                        </para>
+                        <para>
+                            If set to TRUE, the group membership attribute
+                            is not requested from the ldap server, and
+                            group members are not returned when processing
+                            group lookup calls.
+                        </para>
+                        <para>
+                            Default: FALSE
+                        </para>
+                    </listitem>
+                </varlistentry>
+                <varlistentry>
                     <term>auth_provider (string)</term>
                     <listitem>
                         <para>
diff --git a/src/providers/ldap/ldap_id.c b/src/providers/ldap/ldap_id.c
index d8dc3b2..d4f9d2d 100644
--- a/src/providers/ldap/ldap_id.c
+++ b/src/providers/ldap/ldap_id.c
@@ -379,6 +379,7 @@ struct tevent_req *groups_get_send(TALLOC_CTX *memctx,
     enum idmap_error_code err;
     char *sid;
     bool use_id_mapping = dp_opt_get_bool(ctx->opts->basic, SDAP_ID_MAPPING);
+    const char *member_filter[2];
 
     req = tevent_req_create(memctx, &state, struct groups_get_state);
     if (!req) return NULL;
@@ -477,9 +478,15 @@ struct tevent_req *groups_get_send(TALLOC_CTX *memctx,
         goto fail;
     }
 
+    member_filter[0] = (const char *)ctx->opts->group_map[SDAP_AT_GROUP_MEMBER].name;
+    member_filter[1] = NULL;
+
     /* TODO: handle attrs_type */
     ret = build_attrs_from_map(state, ctx->opts->group_map, SDAP_OPTS_GROUP,
-                               NULL, &state->attrs, NULL);
+                               state->domain->ignore_group_members ?
+                                   (const char **)member_filter : NULL,
+                               &state->attrs, NULL);
+
     if (ret != EOK) goto fail;
 
     ret = groups_get_retry(req);
diff --git a/src/providers/ldap/sdap_async_groups.c b/src/providers/ldap/sdap_async_groups.c
index 42802f5..f52bbb6 100644
--- a/src/providers/ldap/sdap_async_groups.c
+++ b/src/providers/ldap/sdap_async_groups.c
@@ -1799,8 +1799,12 @@ static void sdap_get_groups_done(struct tevent_req *subreq)
     if (state->check_count == 0) {
         DEBUG(9, ("All groups processed\n"));
 
+        /* If ignore_group_members is set for the domain, don't update
+         * group memberships in the cache.
+         */
         ret = sdap_save_groups(state, state->sysdb, state->dom, state->opts,
-                               state->groups, state->count, true, NULL,
+                               state->groups, state->count,
+                               !state->dom->ignore_group_members, NULL,
                                &state->higher_usn);
         if (ret) {
             DEBUG(2, ("Failed to store groups.\n"));
diff --git a/src/responder/nss/nsssrv_cmd.c b/src/responder/nss/nsssrv_cmd.c
index 93cd2dd..7df5532 100644
--- a/src/responder/nss/nsssrv_cmd.c
+++ b/src/responder/nss/nsssrv_cmd.c
@@ -2190,24 +2190,27 @@ static int fill_grent(struct sss_packet *packet,
                                             pwfield.str, pwfield.len);
 
         memnum = 0;
-        el = ldb_msg_find_element(msg, SYSDB_MEMBERUID);
-        if (el) {
-            ret = fill_members(packet, dom, nctx, el, &rzero, &rsize, &memnum);
-            if (ret != EOK) {
-                num = 0;
-                goto done;
+        if (!dom->ignore_group_members) {
+            el = ldb_msg_find_element(msg, SYSDB_MEMBERUID);
+            if (el) {
+                ret = fill_members(packet, dom, nctx, el, &rzero, &rsize,
+                                   &memnum);
+                if (ret != EOK) {
+                    num = 0;
+                    goto done;
+                }
+                sss_packet_get_body(packet, &body, &blen);
             }
-            sss_packet_get_body(packet, &body, &blen);
-        }
-
-        el = ldb_msg_find_element(msg, SYSDB_GHOST);
-        if (el) {
-            ret = fill_members(packet, dom, nctx, el, &rzero, &rsize, &memnum);
-            if (ret != EOK) {
-                num = 0;
-                goto done;
+            el = ldb_msg_find_element(msg, SYSDB_GHOST);
+            if (el) {
+                ret = fill_members(packet, dom, nctx, el, &rzero, &rsize,
+                                   &memnum);
+                if (ret != EOK) {
+                    num = 0;
+                    goto done;
+                }
+                sss_packet_get_body(packet, &body, &blen);
             }
-            sss_packet_get_body(packet, &body, &blen);
         }
         if (memnum) {
             /* set num of members */
-- 
2.6.6

