Blame SOURCES/0197-LDAP-AD-do-not-resolve-group-members-during-tokenGro.patch

e543c9
From b8d9eca0d9469c1209161b31a0109d8e4ea2868c Mon Sep 17 00:00:00 2001
e543c9
From: Sumit Bose <sbose@redhat.com>
e543c9
Date: Mon, 9 Mar 2015 16:36:29 +0100
e543c9
Subject: [PATCH] LDAP/AD: do not resolve group members during tokenGroups
e543c9
 request
e543c9
e543c9
During initgroups requests we try to avoid to resolve the complete
e543c9
member list of groups if possible, e.g. if there are no nested groups.
e543c9
The tokenGroups LDAP lookup return the complete list of memberships for
e543c9
a user hence it is not necessary lookup the other group member and
e543c9
un-roll nested groups. With this patch only the group entry is looked up
e543c9
and saved as incomplete group to the cache.
e543c9
e543c9
This is achieved by adding a new boolean parameter no_members to
e543c9
groups_get_send() and sdap_get_groups_send(). The difference to config
e543c9
options like ldap_group_nesting_level = 0 or ignore_group_members is
e543c9
that if no_members is set to true groups which are missing in the cache
e543c9
are created a incomplete groups. As a result a request to lookup this
e543c9
group will trigger a new LDAP request to resolve the group completely.
e543c9
This way no information is ignored but the time needed to read all data
e543c9
is better distributed between different requests.
e543c9
e543c9
https://fedorahosted.org/sssd/ticket/2601
e543c9
e543c9
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
e543c9
(cherry picked from commit d81d8d3dc151ebc95cd0e3f3b14c1cdaa48980f1)
e543c9
---
e543c9
 src/providers/ipa/ipa_subdomains_ext_groups.c |  2 +-
e543c9
 src/providers/ldap/ldap_common.h              |  3 ++-
e543c9
 src/providers/ldap/ldap_id.c                  | 14 +++++++----
e543c9
 src/providers/ldap/sdap_async.h               |  3 ++-
e543c9
 src/providers/ldap/sdap_async_enum.c          |  2 +-
e543c9
 src/providers/ldap/sdap_async_groups.c        | 36 ++++++++++++++++++++++++++-
e543c9
 src/providers/ldap/sdap_async_initgroups.c    | 14 +++++------
e543c9
 src/providers/ldap/sdap_async_initgroups_ad.c |  2 +-
e543c9
 src/providers/ldap/sdap_async_private.h       |  6 +++++
e543c9
 9 files changed, 64 insertions(+), 18 deletions(-)
e543c9
e543c9
diff --git a/src/providers/ipa/ipa_subdomains_ext_groups.c b/src/providers/ipa/ipa_subdomains_ext_groups.c
e543c9
index ad278b248ec2a2a157fed0a455dbe97049e83f9d..976a71cfe3ab42425e3884c5f6d9e096fe61bb34 100644
e543c9
--- a/src/providers/ipa/ipa_subdomains_ext_groups.c
e543c9
+++ b/src/providers/ipa/ipa_subdomains_ext_groups.c
e543c9
@@ -872,7 +872,7 @@ static void ipa_add_ad_memberships_get_next(struct tevent_req *req)
e543c9
                                  state->sdap_id_ctx->conn,
e543c9
                                  (const char *) val->data,
e543c9
                                  BE_FILTER_NAME, BE_ATTR_CORE,
e543c9
-                                 false);
e543c9
+                                 false, false);
e543c9
     if (subreq == NULL) {
e543c9
         DEBUG(SSSDBG_OP_FAILURE, "groups_get_send failed.\n");
e543c9
         ret = ENOMEM;
e543c9
diff --git a/src/providers/ldap/ldap_common.h b/src/providers/ldap/ldap_common.h
e543c9
index bf69489a79e903a98878edb53d372d2242df2b0f..57ad1b8458988d7e108f019c20f67bcde32539d4 100644
e543c9
--- a/src/providers/ldap/ldap_common.h
e543c9
+++ b/src/providers/ldap/ldap_common.h
e543c9
@@ -212,7 +212,8 @@ struct tevent_req *groups_get_send(TALLOC_CTX *memctx,
e543c9
                                    const char *name,
e543c9
                                    int filter_type,
e543c9
                                    int attrs_type,
e543c9
-                                   bool noexist_delete);
e543c9
+                                   bool noexist_delete,
e543c9
+                                   bool no_members);
e543c9
 int groups_get_recv(struct tevent_req *req, int *dp_error_out, int *sdap_ret);
e543c9
 
e543c9
 struct tevent_req *ldap_netgroup_get_send(TALLOC_CTX *memctx,
e543c9
diff --git a/src/providers/ldap/ldap_id.c b/src/providers/ldap/ldap_id.c
e543c9
index 6de5b72a8b66cd95b16d25a2c37dc21a57695de3..55bb3c9fbd6f623e7795d7399c9e5ac4d5192e85 100644
e543c9
--- a/src/providers/ldap/ldap_id.c
e543c9
+++ b/src/providers/ldap/ldap_id.c
e543c9
@@ -528,6 +528,7 @@ struct groups_get_state {
e543c9
     int dp_error;
e543c9
     int sdap_ret;
e543c9
     bool noexist_delete;
e543c9
+    bool no_members;
e543c9
 };
e543c9
 
e543c9
 static int groups_get_retry(struct tevent_req *req);
e543c9
@@ -544,7 +545,8 @@ struct tevent_req *groups_get_send(TALLOC_CTX *memctx,
e543c9
                                    const char *name,
e543c9
                                    int filter_type,
e543c9
                                    int attrs_type,
e543c9
-                                   bool noexist_delete)
e543c9
+                                   bool noexist_delete,
e543c9
+                                   bool no_members)
e543c9
 {
e543c9
     struct tevent_req *req;
e543c9
     struct groups_get_state *state;
e543c9
@@ -567,6 +569,7 @@ struct tevent_req *groups_get_send(TALLOC_CTX *memctx,
e543c9
     state->conn = conn;
e543c9
     state->dp_error = DP_ERR_FATAL;
e543c9
     state->noexist_delete = noexist_delete;
e543c9
+    state->no_members = no_members;
e543c9
 
e543c9
     state->op = sdap_id_op_create(state, state->conn->conn_cache);
e543c9
     if (!state->op) {
e543c9
@@ -713,7 +716,8 @@ struct tevent_req *groups_get_send(TALLOC_CTX *memctx,
e543c9
 
e543c9
     /* TODO: handle attrs_type */
e543c9
     ret = build_attrs_from_map(state, ctx->opts->group_map, SDAP_OPTS_GROUP,
e543c9
-                               state->domain->ignore_group_members ?
e543c9
+                               (state->domain->ignore_group_members
e543c9
+                                    || state->no_members) ?
e543c9
                                    (const char **)member_filter : NULL,
e543c9
                                &state->attrs, NULL);
e543c9
 
e543c9
@@ -845,7 +849,7 @@ static void groups_get_search(struct tevent_req *req)
e543c9
                                   state->attrs, state->filter,
e543c9
                                   dp_opt_get_int(state->ctx->opts->basic,
e543c9
                                                  SDAP_SEARCH_TIMEOUT),
e543c9
-                                  false);
e543c9
+                                  false, state->no_members);
e543c9
     if (!subreq) {
e543c9
         tevent_req_error(req, ENOMEM);
e543c9
         return;
e543c9
@@ -1383,7 +1387,7 @@ sdap_handle_acct_req_send(TALLOC_CTX *mem_ctx,
e543c9
                                  ar->filter_value,
e543c9
                                  ar->filter_type,
e543c9
                                  ar->attr_type,
e543c9
-                                 noexist_delete);
e543c9
+                                 noexist_delete, false);
e543c9
         break;
e543c9
 
e543c9
     case BE_REQ_INITGROUPS: /* init groups for user */
e543c9
@@ -1718,7 +1722,7 @@ static struct tevent_req *get_user_and_group_send(TALLOC_CTX *memctx,
e543c9
     subreq = groups_get_send(req, state->ev, state->id_ctx,
e543c9
                              state->sdom, state->conn,
e543c9
                              state->filter_val, state->filter_type,
e543c9
-                             state->attrs_type, state->noexist_delete);
e543c9
+                             state->attrs_type, state->noexist_delete, false);
e543c9
     if (subreq == NULL) {
e543c9
         DEBUG(SSSDBG_OP_FAILURE, "users_get_send failed.\n");
e543c9
         ret = ENOMEM;
e543c9
diff --git a/src/providers/ldap/sdap_async.h b/src/providers/ldap/sdap_async.h
e543c9
index 1239f28c173373aac23c5796d694c7bd5ca24c96..ef9b3bbadba830bcf730b6fa70867c17d51380af 100644
e543c9
--- a/src/providers/ldap/sdap_async.h
e543c9
+++ b/src/providers/ldap/sdap_async.h
e543c9
@@ -96,7 +96,8 @@ struct tevent_req *sdap_get_groups_send(TALLOC_CTX *memctx,
e543c9
                                        const char **attrs,
e543c9
                                        const char *filter,
e543c9
                                        int timeout,
e543c9
-                                       bool enumeration);
e543c9
+                                       bool enumeration,
e543c9
+                                       bool no_members);
e543c9
 int sdap_get_groups_recv(struct tevent_req *req,
e543c9
                          TALLOC_CTX *mem_ctx, char **timestamp);
e543c9
 
e543c9
diff --git a/src/providers/ldap/sdap_async_enum.c b/src/providers/ldap/sdap_async_enum.c
e543c9
index 242b3172f367b0b35738bd2e86ea927a4409d2d6..1cc09abdf1aa14e3d1690ea1abe32604ae4ff1cd 100644
e543c9
--- a/src/providers/ldap/sdap_async_enum.c
e543c9
+++ b/src/providers/ldap/sdap_async_enum.c
e543c9
@@ -811,7 +811,7 @@ static struct tevent_req *enum_groups_send(TALLOC_CTX *memctx,
e543c9
                                   state->attrs, state->filter,
e543c9
                                   dp_opt_get_int(state->ctx->opts->basic,
e543c9
                                                  SDAP_ENUM_SEARCH_TIMEOUT),
e543c9
-                                  true);
e543c9
+                                  true, false);
e543c9
     if (!subreq) {
e543c9
         ret = ENOMEM;
e543c9
         goto fail;
e543c9
diff --git a/src/providers/ldap/sdap_async_groups.c b/src/providers/ldap/sdap_async_groups.c
e543c9
index c86b5c6b59a4de7e945b95cafae9149f681e2e18..818f30b95d4a4707c32d16b9866b008d89141e4d 100644
e543c9
--- a/src/providers/ldap/sdap_async_groups.c
e543c9
+++ b/src/providers/ldap/sdap_async_groups.c
e543c9
@@ -1750,6 +1750,7 @@ struct sdap_get_groups_state {
e543c9
     char *filter;
e543c9
     int timeout;
e543c9
     bool enumeration;
e543c9
+    bool no_members;
e543c9
 
e543c9
     char *higher_usn;
e543c9
     struct sysdb_attrs **groups;
e543c9
@@ -1779,7 +1780,8 @@ struct tevent_req *sdap_get_groups_send(TALLOC_CTX *memctx,
e543c9
                                        const char **attrs,
e543c9
                                        const char *filter,
e543c9
                                        int timeout,
e543c9
-                                       bool enumeration)
e543c9
+                                       bool enumeration,
e543c9
+                                       bool no_members)
e543c9
 {
e543c9
     errno_t ret;
e543c9
     struct tevent_req *req;
e543c9
@@ -1802,6 +1804,7 @@ struct tevent_req *sdap_get_groups_send(TALLOC_CTX *memctx,
e543c9
     state->count = 0;
e543c9
     state->timeout = timeout;
e543c9
     state->enumeration = enumeration;
e543c9
+    state->no_members = no_members;
e543c9
     state->base_filter = filter;
e543c9
     state->base_iter = 0;
e543c9
     state->search_bases = sdom->group_search_bases;
e543c9
@@ -1926,6 +1929,7 @@ static void sdap_get_groups_process(struct tevent_req *subreq)
e543c9
     bool next_base = false;
e543c9
     size_t count;
e543c9
     struct sysdb_attrs **groups;
e543c9
+    char **groupnamelist;
e543c9
 
e543c9
     ret = sdap_get_generic_recv(subreq, state,
e543c9
                                 &count, &groups);
e543c9
@@ -1992,6 +1996,36 @@ static void sdap_get_groups_process(struct tevent_req *subreq)
e543c9
         return;
e543c9
     }
e543c9
 
e543c9
+    if (state->no_members) {
e543c9
+        ret = sysdb_attrs_primary_name_list(state->sysdb, state,
e543c9
+                                state->groups, state->count,
e543c9
+                                state->opts->group_map[SDAP_AT_GROUP_NAME].name,
e543c9
+                                &groupnamelist);
e543c9
+        if (ret != EOK) {
e543c9
+            DEBUG(SSSDBG_OP_FAILURE,
e543c9
+                  "sysdb_attrs_primary_name_list failed.\n");
e543c9
+            tevent_req_error(req, ret);
e543c9
+            return;
e543c9
+        }
e543c9
+
e543c9
+        ret = sdap_add_incomplete_groups(state->sysdb, state->dom, state->opts,
e543c9
+                                         groupnamelist, state->groups,
e543c9
+                                         state->count);
e543c9
+        if (ret == EOK) {
e543c9
+            DEBUG(SSSDBG_TRACE_LIBS,
e543c9
+                  "Reading only group data without members successful.\n");
e543c9
+            tevent_req_done(req);
e543c9
+        } else {
e543c9
+            DEBUG(SSSDBG_OP_FAILURE, "sdap_add_incomplete_groups failed.\n");
e543c9
+            tevent_req_error(req, ret);
e543c9
+        }
e543c9
+        return;
e543c9
+
e543c9
+        ret = sdap_save_groups(state, state->sysdb, state->dom, state->opts,
e543c9
+                               state->groups, state->count, false,
e543c9
+                               NULL, true, NULL);
e543c9
+    }
e543c9
+
e543c9
     /* Check whether we need to do nested searches
e543c9
      * for RFC2307bis/FreeIPA/ActiveDirectory
e543c9
      * We don't need to do this for enumeration,
e543c9
diff --git a/src/providers/ldap/sdap_async_initgroups.c b/src/providers/ldap/sdap_async_initgroups.c
e543c9
index 48c16b71637f83399d9a523f64f6d812b91681ef..2fd235f2868b877c0e5d5d9f7b1b76d269eee8ee 100644
e543c9
--- a/src/providers/ldap/sdap_async_initgroups.c
e543c9
+++ b/src/providers/ldap/sdap_async_initgroups.c
e543c9
@@ -29,12 +29,12 @@
e543c9
 #include "providers/ldap/sdap_users.h"
e543c9
 
e543c9
 /* ==Save-fake-group-list=====================================*/
e543c9
-static errno_t sdap_add_incomplete_groups(struct sysdb_ctx *sysdb,
e543c9
-                                          struct sss_domain_info *domain,
e543c9
-                                          struct sdap_options *opts,
e543c9
-                                          char **groupnames,
e543c9
-                                          struct sysdb_attrs **ldap_groups,
e543c9
-                                          int ldap_groups_count)
e543c9
+errno_t sdap_add_incomplete_groups(struct sysdb_ctx *sysdb,
e543c9
+                                   struct sss_domain_info *domain,
e543c9
+                                   struct sdap_options *opts,
e543c9
+                                   char **groupnames,
e543c9
+                                   struct sysdb_attrs **ldap_groups,
e543c9
+                                   int ldap_groups_count)
e543c9
 {
e543c9
     TALLOC_CTX *tmp_ctx;
e543c9
     struct ldb_message *msg;
e543c9
@@ -3152,7 +3152,7 @@ static void sdap_get_initgr_done(struct tevent_req *subreq)
e543c9
 
e543c9
     subreq = groups_get_send(req, state->ev, state->id_ctx,
e543c9
                              state->id_ctx->opts->sdom, state->conn,
e543c9
-                             gid, BE_FILTER_IDNUM, BE_ATTR_ALL, NULL);
e543c9
+                             gid, BE_FILTER_IDNUM, BE_ATTR_ALL, false, false);
e543c9
     if (!subreq) {
e543c9
         ret = ENOMEM;
e543c9
         goto fail;
e543c9
diff --git a/src/providers/ldap/sdap_async_initgroups_ad.c b/src/providers/ldap/sdap_async_initgroups_ad.c
e543c9
index 1b8c8d981ea14ac0fca0903f16296c8a6701c5dd..9915f1863f172d5d3f59afe03abbbfb87fdf3409 100644
e543c9
--- a/src/providers/ldap/sdap_async_initgroups_ad.c
e543c9
+++ b/src/providers/ldap/sdap_async_initgroups_ad.c
e543c9
@@ -630,7 +630,7 @@ static errno_t sdap_ad_resolve_sids_step(struct tevent_req *req)
e543c9
 
e543c9
     subreq = groups_get_send(state, state->ev, state->id_ctx, sdap_domain,
e543c9
                              state->conn, state->current_sid,
e543c9
-                             BE_FILTER_SECID, BE_ATTR_CORE, false);
e543c9
+                             BE_FILTER_SECID, BE_ATTR_CORE, false, true);
e543c9
     if (subreq == NULL) {
e543c9
         return ENOMEM;
e543c9
     }
e543c9
diff --git a/src/providers/ldap/sdap_async_private.h b/src/providers/ldap/sdap_async_private.h
e543c9
index e689394c5db8a3385c333e6b98372c6f6d34366c..3995a2ac357c52f546696284d71d2127d0302409 100644
e543c9
--- a/src/providers/ldap/sdap_async_private.h
e543c9
+++ b/src/providers/ldap/sdap_async_private.h
e543c9
@@ -132,4 +132,10 @@ errno_t sdap_nested_group_recv(TALLOC_CTX *mem_ctx,
e543c9
                                unsigned long *_num_groups,
e543c9
                                struct sysdb_attrs ***_groups);
e543c9
 
e543c9
+errno_t sdap_add_incomplete_groups(struct sysdb_ctx *sysdb,
e543c9
+                                   struct sss_domain_info *domain,
e543c9
+                                   struct sdap_options *opts,
e543c9
+                                   char **groupnames,
e543c9
+                                   struct sysdb_attrs **ldap_groups,
e543c9
+                                   int ldap_groups_count);
e543c9
 #endif /* _SDAP_ASYNC_PRIVATE_H_ */
e543c9
-- 
e543c9
2.1.0
e543c9