From 48f27f74c9a9d5aebf8d2be941dfb282578ba9ba Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
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 <atikhono@redhat.com>
---
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