From 48f27f74c9a9d5aebf8d2be941dfb282578ba9ba Mon Sep 17 00:00:00 2001 From: Sumit Bose Date: Fri, 12 Mar 2021 14:38:54 +0100 Subject: [PATCH] negcache: use right domain in nss_protocol_fill_initgr() When checking if a group returned by an initgroups request is filtered in the negative cache the domain of the user was used. This does not work reliable if the user can be a member of groups from multiple domains. With this patch th domain the group belongs to is determined and used while checking the negative cache. Resolves: https://github.com/SSSD/sssd/issues/5534 (cherry picked from commit 231d1118727b989a4af9911a45a465912fe659d6 with changes) Reviewed-by: Alexey Tikhonov --- src/db/sysdb.c | 22 ++++++++++++++++++++++ src/db/sysdb.h | 7 +++++++ src/responder/nss/nss_protocol_grent.c | 8 +++++--- 3 files changed, 34 insertions(+), 3 deletions(-) diff --git a/src/db/sysdb.c b/src/db/sysdb.c index 279bd5839..f9929c7ba 100644 --- a/src/db/sysdb.c +++ b/src/db/sysdb.c @@ -1978,3 +1978,25 @@ done: talloc_free(tmp_ctx); return differs; } + +struct sss_domain_info *find_domain_by_msg(struct sss_domain_info *dom, + struct ldb_message *msg) +{ + const char *name; + struct sss_domain_info *obj_dom = NULL; + + name = ldb_msg_find_attr_as_string(msg, SYSDB_NAME, NULL); + if (name == NULL) { + DEBUG(SSSDBG_OP_FAILURE, + "Object does not have a name attribute.\n"); + return dom; + } + + obj_dom = find_domain_by_object_name(get_domains_head(dom), name); + if (obj_dom == NULL) { + DEBUG(SSSDBG_OP_FAILURE, "No domain found for [%s].\n", name); + return dom; + } + + return obj_dom; +} diff --git a/src/db/sysdb.h b/src/db/sysdb.h index 679763bad..d47099eff 100644 --- a/src/db/sysdb.h +++ b/src/db/sysdb.h @@ -1505,4 +1505,11 @@ errno_t sysdb_handle_original_uuid(const char *orig_name, struct sysdb_attrs *dest_attrs, const char *dest_name); +/* Try to detect the object domain from the object's SYSDB_NAME attribute and + * return the matching sss_domain_info. This should work reliable with user + * and group objects since fully-qualified names are used here. If the proper + * domain cannot be detected the given domain is returned. */ +struct sss_domain_info *find_domain_by_msg(struct sss_domain_info *dom, + struct ldb_message *msg); + #endif /* __SYS_DB_H__ */ diff --git a/src/responder/nss/nss_protocol_grent.c b/src/responder/nss/nss_protocol_grent.c index 4c7ea9aed..e4494826a 100644 --- a/src/responder/nss/nss_protocol_grent.c +++ b/src/responder/nss/nss_protocol_grent.c @@ -343,6 +343,7 @@ nss_protocol_fill_initgr(struct nss_ctx *nss_ctx, struct cache_req_result *result) { struct sss_domain_info *domain; + struct sss_domain_info *grp_dom; struct ldb_message *user; struct ldb_message *msg; struct ldb_message *primary_group_msg; @@ -400,10 +401,11 @@ nss_protocol_fill_initgr(struct nss_ctx *nss_ctx, num_results = 0; for (i = 1; i < result->count; i++) { msg = result->msgs[i]; - gid = sss_view_ldb_msg_find_attr_as_uint64(domain, msg, SYSDB_GIDNUM, + grp_dom = find_domain_by_msg(domain, msg); + gid = sss_view_ldb_msg_find_attr_as_uint64(grp_dom, msg, SYSDB_GIDNUM, 0); posix = ldb_msg_find_attr_as_string(msg, SYSDB_POSIX, NULL); - grp_name = sss_view_ldb_msg_find_attr_as_string(domain, msg, SYSDB_NAME, + grp_name = sss_view_ldb_msg_find_attr_as_string(grp_dom, msg, SYSDB_NAME, NULL); if (gid == 0) { @@ -417,7 +419,7 @@ nss_protocol_fill_initgr(struct nss_ctx *nss_ctx, } } - if (is_group_filtered(nss_ctx->rctx->ncache, domain, grp_name, gid)) { + if (is_group_filtered(nss_ctx->rctx->ncache, grp_dom, grp_name, gid)) { continue; } -- 2.26.3