summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSumit Bose <sbose@redhat.com>2015-03-09 16:36:29 +0100
committerJakub Hrozek <jhrozek@redhat.com>2015-04-22 12:51:56 +0200
commitf476d37bf5a14944eb1c7706d793aa012556db5b (patch)
tree39b60abeea59eac09c2bd55ea2038012ee76a0bc
parent424f26892d1b2587a806694820babf5754b8db66 (diff)
downloadsssd-f476d37bf5a14944eb1c7706d793aa012556db5b.tar.gz
sssd-f476d37bf5a14944eb1c7706d793aa012556db5b.tar.xz
sssd-f476d37bf5a14944eb1c7706d793aa012556db5b.zip
LDAP/AD: do not resolve group members during tokenGroups request
During initgroups requests we try to avoid to resolve the complete member list of groups if possible, e.g. if there are no nested groups. The tokenGroups LDAP lookup return the complete list of memberships for a user hence it is not necessary lookup the other group member and un-roll nested groups. With this patch only the group entry is looked up and saved as incomplete group to the cache. This is achieved by adding a new boolean parameter no_members to groups_get_send() and sdap_get_groups_send(). The difference to config options like ldap_group_nesting_level = 0 or ignore_group_members is that if no_members is set to true groups which are missing in the cache are created a incomplete groups. As a result a request to lookup this group will trigger a new LDAP request to resolve the group completely. This way no information is ignored but the time needed to read all data is better distributed between different requests. https://fedorahosted.org/sssd/ticket/2601 Reviewed-by: Jakub Hrozek <jhrozek@redhat.com> (cherry picked from commit d81d8d3dc151ebc95cd0e3f3b14c1cdaa48980f1)
-rw-r--r--src/providers/ipa/ipa_subdomains_ext_groups.c2
-rw-r--r--src/providers/ldap/ldap_common.h3
-rw-r--r--src/providers/ldap/ldap_id.c14
-rw-r--r--src/providers/ldap/sdap_async.h3
-rw-r--r--src/providers/ldap/sdap_async_enum.c2
-rw-r--r--src/providers/ldap/sdap_async_groups.c36
-rw-r--r--src/providers/ldap/sdap_async_initgroups.c14
-rw-r--r--src/providers/ldap/sdap_async_initgroups_ad.c2
-rw-r--r--src/providers/ldap/sdap_async_private.h6
9 files changed, 64 insertions, 18 deletions
diff --git a/src/providers/ipa/ipa_subdomains_ext_groups.c b/src/providers/ipa/ipa_subdomains_ext_groups.c
index b9690bdb6..9cf1814c3 100644
--- a/src/providers/ipa/ipa_subdomains_ext_groups.c
+++ b/src/providers/ipa/ipa_subdomains_ext_groups.c
@@ -872,7 +872,7 @@ static void ipa_add_ad_memberships_get_next(struct tevent_req *req)
state->sdap_id_ctx->conn,
(const char *) val->data,
BE_FILTER_NAME, BE_ATTR_CORE,
- false);
+ false, false);
if (subreq == NULL) {
DEBUG(SSSDBG_OP_FAILURE, "groups_get_send failed.\n");
ret = ENOMEM;
diff --git a/src/providers/ldap/ldap_common.h b/src/providers/ldap/ldap_common.h
index 889d5b118..3685bc206 100644
--- a/src/providers/ldap/ldap_common.h
+++ b/src/providers/ldap/ldap_common.h
@@ -212,7 +212,8 @@ struct tevent_req *groups_get_send(TALLOC_CTX *memctx,
const char *name,
int filter_type,
int attrs_type,
- bool noexist_delete);
+ bool noexist_delete,
+ bool no_members);
int groups_get_recv(struct tevent_req *req, int *dp_error_out, int *sdap_ret);
struct tevent_req *ldap_netgroup_get_send(TALLOC_CTX *memctx,
diff --git a/src/providers/ldap/ldap_id.c b/src/providers/ldap/ldap_id.c
index 5ce462d77..001072244 100644
--- a/src/providers/ldap/ldap_id.c
+++ b/src/providers/ldap/ldap_id.c
@@ -528,6 +528,7 @@ struct groups_get_state {
int dp_error;
int sdap_ret;
bool noexist_delete;
+ bool no_members;
};
static int groups_get_retry(struct tevent_req *req);
@@ -544,7 +545,8 @@ struct tevent_req *groups_get_send(TALLOC_CTX *memctx,
const char *name,
int filter_type,
int attrs_type,
- bool noexist_delete)
+ bool noexist_delete,
+ bool no_members)
{
struct tevent_req *req;
struct groups_get_state *state;
@@ -567,6 +569,7 @@ struct tevent_req *groups_get_send(TALLOC_CTX *memctx,
state->conn = conn;
state->dp_error = DP_ERR_FATAL;
state->noexist_delete = noexist_delete;
+ state->no_members = no_members;
state->op = sdap_id_op_create(state, state->conn->conn_cache);
if (!state->op) {
@@ -713,7 +716,8 @@ struct tevent_req *groups_get_send(TALLOC_CTX *memctx,
/* TODO: handle attrs_type */
ret = build_attrs_from_map(state, ctx->opts->group_map, SDAP_OPTS_GROUP,
- state->domain->ignore_group_members ?
+ (state->domain->ignore_group_members
+ || state->no_members) ?
(const char **)member_filter : NULL,
&state->attrs, NULL);
@@ -845,7 +849,7 @@ static void groups_get_search(struct tevent_req *req)
state->attrs, state->filter,
dp_opt_get_int(state->ctx->opts->basic,
SDAP_SEARCH_TIMEOUT),
- false);
+ false, state->no_members);
if (!subreq) {
tevent_req_error(req, ENOMEM);
return;
@@ -1387,7 +1391,7 @@ sdap_handle_acct_req_send(TALLOC_CTX *mem_ctx,
ar->filter_value,
ar->filter_type,
ar->attr_type,
- noexist_delete);
+ noexist_delete, false);
break;
case BE_REQ_INITGROUPS: /* init groups for user */
@@ -1722,7 +1726,7 @@ static struct tevent_req *get_user_and_group_send(TALLOC_CTX *memctx,
subreq = groups_get_send(req, state->ev, state->id_ctx,
state->sdom, state->conn,
state->filter_val, state->filter_type,
- state->attrs_type, state->noexist_delete);
+ state->attrs_type, state->noexist_delete, false);
if (subreq == NULL) {
DEBUG(SSSDBG_OP_FAILURE, "users_get_send failed.\n");
ret = ENOMEM;
diff --git a/src/providers/ldap/sdap_async.h b/src/providers/ldap/sdap_async.h
index 1239f28c1..ef9b3bbad 100644
--- a/src/providers/ldap/sdap_async.h
+++ b/src/providers/ldap/sdap_async.h
@@ -96,7 +96,8 @@ struct tevent_req *sdap_get_groups_send(TALLOC_CTX *memctx,
const char **attrs,
const char *filter,
int timeout,
- bool enumeration);
+ bool enumeration,
+ bool no_members);
int sdap_get_groups_recv(struct tevent_req *req,
TALLOC_CTX *mem_ctx, char **timestamp);
diff --git a/src/providers/ldap/sdap_async_enum.c b/src/providers/ldap/sdap_async_enum.c
index 242b3172f..1cc09abdf 100644
--- a/src/providers/ldap/sdap_async_enum.c
+++ b/src/providers/ldap/sdap_async_enum.c
@@ -811,7 +811,7 @@ static struct tevent_req *enum_groups_send(TALLOC_CTX *memctx,
state->attrs, state->filter,
dp_opt_get_int(state->ctx->opts->basic,
SDAP_ENUM_SEARCH_TIMEOUT),
- true);
+ true, false);
if (!subreq) {
ret = ENOMEM;
goto fail;
diff --git a/src/providers/ldap/sdap_async_groups.c b/src/providers/ldap/sdap_async_groups.c
index c86b5c6b5..818f30b95 100644
--- a/src/providers/ldap/sdap_async_groups.c
+++ b/src/providers/ldap/sdap_async_groups.c
@@ -1750,6 +1750,7 @@ struct sdap_get_groups_state {
char *filter;
int timeout;
bool enumeration;
+ bool no_members;
char *higher_usn;
struct sysdb_attrs **groups;
@@ -1779,7 +1780,8 @@ struct tevent_req *sdap_get_groups_send(TALLOC_CTX *memctx,
const char **attrs,
const char *filter,
int timeout,
- bool enumeration)
+ bool enumeration,
+ bool no_members)
{
errno_t ret;
struct tevent_req *req;
@@ -1802,6 +1804,7 @@ struct tevent_req *sdap_get_groups_send(TALLOC_CTX *memctx,
state->count = 0;
state->timeout = timeout;
state->enumeration = enumeration;
+ state->no_members = no_members;
state->base_filter = filter;
state->base_iter = 0;
state->search_bases = sdom->group_search_bases;
@@ -1926,6 +1929,7 @@ static void sdap_get_groups_process(struct tevent_req *subreq)
bool next_base = false;
size_t count;
struct sysdb_attrs **groups;
+ char **groupnamelist;
ret = sdap_get_generic_recv(subreq, state,
&count, &groups);
@@ -1992,6 +1996,36 @@ static void sdap_get_groups_process(struct tevent_req *subreq)
return;
}
+ if (state->no_members) {
+ ret = sysdb_attrs_primary_name_list(state->sysdb, state,
+ state->groups, state->count,
+ state->opts->group_map[SDAP_AT_GROUP_NAME].name,
+ &groupnamelist);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE,
+ "sysdb_attrs_primary_name_list failed.\n");
+ tevent_req_error(req, ret);
+ return;
+ }
+
+ ret = sdap_add_incomplete_groups(state->sysdb, state->dom, state->opts,
+ groupnamelist, state->groups,
+ state->count);
+ if (ret == EOK) {
+ DEBUG(SSSDBG_TRACE_LIBS,
+ "Reading only group data without members successful.\n");
+ tevent_req_done(req);
+ } else {
+ DEBUG(SSSDBG_OP_FAILURE, "sdap_add_incomplete_groups failed.\n");
+ tevent_req_error(req, ret);
+ }
+ return;
+
+ ret = sdap_save_groups(state, state->sysdb, state->dom, state->opts,
+ state->groups, state->count, false,
+ NULL, true, NULL);
+ }
+
/* Check whether we need to do nested searches
* for RFC2307bis/FreeIPA/ActiveDirectory
* We don't need to do this for enumeration,
diff --git a/src/providers/ldap/sdap_async_initgroups.c b/src/providers/ldap/sdap_async_initgroups.c
index 6b3179d2d..bc6b5e45e 100644
--- a/src/providers/ldap/sdap_async_initgroups.c
+++ b/src/providers/ldap/sdap_async_initgroups.c
@@ -29,12 +29,12 @@
#include "providers/ldap/sdap_users.h"
/* ==Save-fake-group-list=====================================*/
-static errno_t sdap_add_incomplete_groups(struct sysdb_ctx *sysdb,
- struct sss_domain_info *domain,
- struct sdap_options *opts,
- char **groupnames,
- struct sysdb_attrs **ldap_groups,
- int ldap_groups_count)
+errno_t sdap_add_incomplete_groups(struct sysdb_ctx *sysdb,
+ struct sss_domain_info *domain,
+ struct sdap_options *opts,
+ char **groupnames,
+ struct sysdb_attrs **ldap_groups,
+ int ldap_groups_count)
{
TALLOC_CTX *tmp_ctx;
struct ldb_message *msg;
@@ -3152,7 +3152,7 @@ static void sdap_get_initgr_done(struct tevent_req *subreq)
subreq = groups_get_send(req, state->ev, state->id_ctx,
state->id_ctx->opts->sdom, state->conn,
- gid, BE_FILTER_IDNUM, BE_ATTR_ALL, NULL);
+ gid, BE_FILTER_IDNUM, BE_ATTR_ALL, false, false);
if (!subreq) {
ret = ENOMEM;
goto fail;
diff --git a/src/providers/ldap/sdap_async_initgroups_ad.c b/src/providers/ldap/sdap_async_initgroups_ad.c
index 1b8c8d981..9915f1863 100644
--- a/src/providers/ldap/sdap_async_initgroups_ad.c
+++ b/src/providers/ldap/sdap_async_initgroups_ad.c
@@ -630,7 +630,7 @@ static errno_t sdap_ad_resolve_sids_step(struct tevent_req *req)
subreq = groups_get_send(state, state->ev, state->id_ctx, sdap_domain,
state->conn, state->current_sid,
- BE_FILTER_SECID, BE_ATTR_CORE, false);
+ BE_FILTER_SECID, BE_ATTR_CORE, false, true);
if (subreq == NULL) {
return ENOMEM;
}
diff --git a/src/providers/ldap/sdap_async_private.h b/src/providers/ldap/sdap_async_private.h
index e689394c5..3995a2ac3 100644
--- a/src/providers/ldap/sdap_async_private.h
+++ b/src/providers/ldap/sdap_async_private.h
@@ -132,4 +132,10 @@ errno_t sdap_nested_group_recv(TALLOC_CTX *mem_ctx,
unsigned long *_num_groups,
struct sysdb_attrs ***_groups);
+errno_t sdap_add_incomplete_groups(struct sysdb_ctx *sysdb,
+ struct sss_domain_info *domain,
+ struct sdap_options *opts,
+ char **groupnames,
+ struct sysdb_attrs **ldap_groups,
+ int ldap_groups_count);
#endif /* _SDAP_ASYNC_PRIVATE_H_ */