From 231d1118727b989a4af9911a45a465912fe659d6 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() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 Reviewed-by: Pavel Březina --- 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 693f687be..6001c49cb 100644 --- a/src/db/sysdb.c +++ b/src/db/sysdb.c @@ -2139,3 +2139,25 @@ void ldb_debug_messages(void *context, enum ldb_debug_level level, fmt, ap); } } + +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 a00efa55f..37a2c4124 100644 --- a/src/db/sysdb.h +++ b/src/db/sysdb.h @@ -1532,4 +1532,11 @@ errno_t sysdb_cert_derb64_to_ldap_filter(TALLOC_CTX *mem_ctx, void ldb_debug_messages(void *context, enum ldb_debug_level level, const char *fmt, va_list ap); +/* 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 135b392f7..f6e00eb10 100644 --- a/src/responder/nss/nss_protocol_grent.c +++ b/src/responder/nss/nss_protocol_grent.c @@ -361,6 +361,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; @@ -418,10 +419,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) { @@ -435,7 +437,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