298 lines
14 KiB
Diff
298 lines
14 KiB
Diff
From b8d9eca0d9469c1209161b31a0109d8e4ea2868c Mon Sep 17 00:00:00 2001
|
|
From: Sumit Bose <sbose@redhat.com>
|
|
Date: Mon, 9 Mar 2015 16:36:29 +0100
|
|
Subject: [PATCH 32/99] 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)
|
|
---
|
|
src/providers/ipa/ipa_subdomains_ext_groups.c | 2 +-
|
|
src/providers/ldap/ldap_common.h | 3 ++-
|
|
src/providers/ldap/ldap_id.c | 14 +++++++----
|
|
src/providers/ldap/sdap_async.h | 3 ++-
|
|
src/providers/ldap/sdap_async_enum.c | 2 +-
|
|
src/providers/ldap/sdap_async_groups.c | 36 ++++++++++++++++++++++++++-
|
|
src/providers/ldap/sdap_async_initgroups.c | 14 +++++------
|
|
src/providers/ldap/sdap_async_initgroups_ad.c | 2 +-
|
|
src/providers/ldap/sdap_async_private.h | 6 +++++
|
|
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 ad278b248ec2a2a157fed0a455dbe97049e83f9d..976a71cfe3ab42425e3884c5f6d9e096fe61bb34 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 bf69489a79e903a98878edb53d372d2242df2b0f..57ad1b8458988d7e108f019c20f67bcde32539d4 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 6de5b72a8b66cd95b16d25a2c37dc21a57695de3..55bb3c9fbd6f623e7795d7399c9e5ac4d5192e85 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;
|
|
@@ -1383,7 +1387,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 */
|
|
@@ -1718,7 +1722,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 1239f28c173373aac23c5796d694c7bd5ca24c96..ef9b3bbadba830bcf730b6fa70867c17d51380af 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 242b3172f367b0b35738bd2e86ea927a4409d2d6..1cc09abdf1aa14e3d1690ea1abe32604ae4ff1cd 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 c86b5c6b59a4de7e945b95cafae9149f681e2e18..818f30b95d4a4707c32d16b9866b008d89141e4d 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 48c16b71637f83399d9a523f64f6d812b91681ef..2fd235f2868b877c0e5d5d9f7b1b76d269eee8ee 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 1b8c8d981ea14ac0fca0903f16296c8a6701c5dd..9915f1863f172d5d3f59afe03abbbfb87fdf3409 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 e689394c5db8a3385c333e6b98372c6f6d34366c..3995a2ac357c52f546696284d71d2127d0302409 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_ */
|
|
--
|
|
2.4.0
|
|
|