From 7a92ae1598735ff69e36c72a7be60292ccad41d3 Mon Sep 17 00:00:00 2001 From: Jakub Hrozek Date: Mon, 21 Jan 2013 13:23:30 +0100 Subject: TOOLS: invalidate parent groups in memory cache, too https://fedorahosted.org/sssd/ticket/1775 In addition to invalidating the group being added to when adding a member group/user, we also need to invalidate all its parent groups, otherwise this getgrnam("parent") wouldn't report the members newly added to its child groups. --- src/tools/sss_groupmod.c | 4 +-- src/tools/sss_usermod.c | 4 +-- src/tools/tools_mc_util.c | 68 ++++++++++++++++++++++++++++++++++++++++++++--- src/tools/tools_util.h | 3 ++- 4 files changed, 71 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/tools/sss_groupmod.c b/src/tools/sss_groupmod.c index 8463857a..29113d3d 100644 --- a/src/tools/sss_groupmod.c +++ b/src/tools/sss_groupmod.c @@ -221,14 +221,14 @@ int main(int argc, const char **argv) /* Nothing we can do about it */ } - ret = sss_mc_refresh_grouplist(tctx->octx->addgroups); + ret = sss_mc_refresh_grouplist(tctx, tctx->octx->addgroups); if (ret != EOK) { ERROR("NSS request failed (%1$d). Entry might remain in memory " "cache.\n", ret); /* Nothing we can do about it */ } - ret = sss_mc_refresh_grouplist(tctx->octx->rmgroups); + ret = sss_mc_refresh_grouplist(tctx, tctx->octx->rmgroups); if (ret != EOK) { ERROR("NSS request failed (%1$d). Entry might remain in memory " "cache.\n", ret); diff --git a/src/tools/sss_usermod.c b/src/tools/sss_usermod.c index 23630435..fa2c27b0 100644 --- a/src/tools/sss_usermod.c +++ b/src/tools/sss_usermod.c @@ -243,14 +243,14 @@ int main(int argc, const char **argv) /* Nothing we can do about it */ } - ret = sss_mc_refresh_grouplist(tctx->octx->addgroups); + ret = sss_mc_refresh_grouplist(tctx, tctx->octx->addgroups); if (ret != EOK) { ERROR("NSS request failed (%1$d). Entry might remain in memory " "cache.\n", ret); /* Nothing we can do about it */ } - ret = sss_mc_refresh_grouplist(tctx->octx->rmgroups); + ret = sss_mc_refresh_grouplist(tctx, tctx->octx->rmgroups); if (ret != EOK) { ERROR("NSS request failed (%1$d). Entry might remain in memory " "cache.\n", ret); diff --git a/src/tools/tools_mc_util.c b/src/tools/tools_mc_util.c index 45b145d2..d623c48c 100644 --- a/src/tools/tools_mc_util.c +++ b/src/tools/tools_mc_util.c @@ -22,6 +22,7 @@ #include #include +#include "db/sysdb.h" #include "util/util.h" #include "tools/tools_util.h" #include "util/mmap_cache.h" @@ -241,7 +242,67 @@ errno_t sss_mc_refresh_group(const char *groupname) return sss_mc_refresh_ent(groupname, SSS_TOOLS_GROUP); } -errno_t sss_mc_refresh_grouplist(char **groupnames) +errno_t sss_mc_refresh_nested_group(struct tools_ctx *tctx, + const char *name) +{ + errno_t ret; + struct ldb_message *msg; + struct ldb_message_element *el; + const char *attrs[] = { SYSDB_MEMBEROF, + SYSDB_NAME, + NULL }; + size_t i; + char *parent_name; + + ret = sss_mc_refresh_group(name); + if (ret != EOK) { + DEBUG(SSSDBG_MINOR_FAILURE, + ("Cannot refresh group %s from memory cache\n", name)); + /* try to carry on */ + } + + ret = sysdb_search_group_by_name(tctx, tctx->sysdb, tctx->local, + name, attrs, &msg); + if (ret) { + DEBUG(SSSDBG_OP_FAILURE, + ("Search failed: %s (%d)\n", strerror(ret), ret)); + return ret; + } + + el = ldb_msg_find_element(msg, SYSDB_MEMBEROF); + if (!el || el->num_values == 0) { + DEBUG(SSSDBG_TRACE_INTERNAL, ("Group %s has no parents\n", name)); + talloc_free(msg); + return EOK; + } + + /* This group is nested. We need to invalidate all its parents, too */ + for (i=0; i < el->num_values; i++) { + ret = sysdb_group_dn_name(tctx->sysdb, tctx, + (const char *) el->values[i].data, + &parent_name); + if (ret != EOK) { + DEBUG(SSSDBG_MINOR_FAILURE, ("Malformed DN [%s]? Skipping\n", + (const char *) el->values[i].data)); + talloc_free(parent_name); + continue; + } + + ret = sss_mc_refresh_group(parent_name); + talloc_free(parent_name); + if (ret != EOK) { + DEBUG(SSSDBG_MINOR_FAILURE, + ("Cannot refresh group %s from memory cache\n", name)); + /* try to carry on */ + } + } + + talloc_free(msg); + return EOK; +} + +errno_t sss_mc_refresh_grouplist(struct tools_ctx *tctx, + char **groupnames) { int i; errno_t ret; @@ -250,10 +311,11 @@ errno_t sss_mc_refresh_grouplist(char **groupnames) if (!groupnames) return EOK; for (i = 0; groupnames[i]; i++) { - ret = sss_mc_refresh_group(groupnames[i]); + ret = sss_mc_refresh_nested_group(tctx, groupnames[i]); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, - ("Cannot refresh group %s from memory cache\n")); + ("Cannot refresh group %s from memory cache\n", + groupnames[i])); failed = true; continue; } diff --git a/src/tools/tools_util.h b/src/tools/tools_util.h index 3554a182..47bf3876 100644 --- a/src/tools/tools_util.h +++ b/src/tools/tools_util.h @@ -111,7 +111,8 @@ errno_t sss_memcache_clear_all(void); errno_t sss_mc_refresh_user(const char *username); errno_t sss_mc_refresh_group(const char *groupname); -errno_t sss_mc_refresh_grouplist(char **groupnames); +errno_t sss_mc_refresh_grouplist(struct tools_ctx *tctx, + char **groupnames); /* from files.c */ int remove_tree(const char *root); -- cgit