summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorSimo Sorce <simo@redhat.com>2012-12-05 17:40:43 +0000
committerJakub Hrozek <jhrozek@redhat.com>2012-12-06 11:46:04 +0100
commit88d0a8eff723aab806807f9833136ab174d45b46 (patch)
tree5aed57d47d3ad3f5424b3e2975ff6cef887939b4 /src
parentd239eeb424c8241aba73cdcfa727ec2b4774f770 (diff)
downloadsssd-88d0a8eff723aab806807f9833136ab174d45b46.tar.gz
sssd-88d0a8eff723aab806807f9833136ab174d45b46.tar.xz
sssd-88d0a8eff723aab806807f9833136ab174d45b46.zip
Hook to perform a mmap cache update from sssd_nss
This set of functions enumerate each user/group from all domains and invalidate any mmap cache record that matches.
Diffstat (limited to 'src')
-rw-r--r--src/providers/data_provider.h6
-rw-r--r--src/responder/nss/nsssrv.c15
-rw-r--r--src/responder/nss/nsssrv_cmd.c100
-rw-r--r--src/responder/nss/nsssrv_private.h3
4 files changed, 124 insertions, 0 deletions
diff --git a/src/providers/data_provider.h b/src/providers/data_provider.h
index d49fcd524..d82b4c94a 100644
--- a/src/providers/data_provider.h
+++ b/src/providers/data_provider.h
@@ -54,6 +54,12 @@
#define DP_METHOD_AUTOFSHANDLER "autofsHandler"
#define DP_METHOD_HOSTHANDLER "hostHandler"
#define DP_METHOD_GETDOMAINS "getDomains"
+
+/* this is a reverse method sent from providers to
+ * the nss responder to tell it to update the mmap
+ * cache */
+#define DP_REV_METHOD_UPDATE_CACHE "updateCache"
+
/**
* @defgroup pamHandler PAM DBUS request
* @ingroup sss_pam
diff --git a/src/responder/nss/nsssrv.c b/src/responder/nss/nsssrv.c
index 1156c45f4..94aada5ec 100644
--- a/src/responder/nss/nsssrv.c
+++ b/src/responder/nss/nsssrv.c
@@ -33,6 +33,7 @@
#include "popt.h"
#include "util/util.h"
#include "responder/nss/nsssrv.h"
+#include "responder/nss/nsssrv_private.h"
#include "responder/nss/nsssrv_mmap_cache.h"
#include "responder/common/negcache.h"
#include "db/sysdb.h"
@@ -280,7 +281,21 @@ done:
return ret;
}
+static int nss_update_memcache(DBusMessage *message,
+ struct sbus_connection *conn)
+{
+ struct resp_ctx *rctx = talloc_get_type(sbus_conn_get_private_data(conn),
+ struct resp_ctx);
+ struct nss_ctx *nctx = talloc_get_type(rctx->pvt_ctx, struct nss_ctx);
+
+ nss_update_pw_memcache(nctx);
+ nss_update_gr_memcache(nctx);
+
+ return EOK;
+}
+
static struct sbus_method nss_dp_methods[] = {
+ { DP_REV_METHOD_UPDATE_CACHE, nss_update_memcache },
{ NULL, NULL }
};
diff --git a/src/responder/nss/nsssrv_cmd.c b/src/responder/nss/nsssrv_cmd.c
index 74a79c415..a02edd1e6 100644
--- a/src/responder/nss/nsssrv_cmd.c
+++ b/src/responder/nss/nsssrv_cmd.c
@@ -107,6 +107,56 @@ struct setent_ctx {
* PASSWD db related functions
***************************************************************************/
+void nss_update_pw_memcache(struct nss_ctx *nctx)
+{
+ struct sss_domain_info *dom;
+ struct ldb_result *res;
+ uint64_t exp;
+ struct sized_string key;
+ const char *id;
+ time_t now;
+ int ret;
+ int i;
+
+ now = time(NULL);
+
+ for (dom = nctx->rctx->domains; dom != NULL; dom = dom->next) {
+ ret = sysdb_enumpwent(nctx, dom->sysdb, &res);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_CRIT_FAILURE,
+ ("Failed to enumerate users for domain [%s]\n", dom->name));
+ continue;
+ }
+
+ for (i = 0; i < res->count; i++) {
+ exp = ldb_msg_find_attr_as_uint64(res->msgs[i],
+ SYSDB_CACHE_EXPIRE, 0);
+ if (exp >= now) {
+ continue;
+ }
+
+ /* names require more manipulation (build up fqname conditionally),
+ * but uidNumber is unique and always resolvable too, so we use
+ * that to update the cache, as it points to the same entry */
+ id = ldb_msg_find_attr_as_string(res->msgs[i], SYSDB_UIDNUM, NULL);
+ if (!id) {
+ DEBUG(SSSDBG_CRIT_FAILURE,
+ ("Failed to find uidNumber in %s.\n",
+ ldb_dn_get_linearized(res->msgs[i]->dn)));
+ continue;
+ }
+ to_sized_string(&key, id);
+
+ ret = sss_mmap_cache_pw_invalidate(nctx->pwd_mc_ctx, &key);
+ if (ret != EOK && ret != ENOENT) {
+ DEBUG(SSSDBG_CRIT_FAILURE,
+ ("Internal failure in memory cache code: %d [%s]\n",
+ ret, strerror(ret)));
+ }
+ }
+ }
+}
+
static gid_t get_gid_override(struct ldb_message *msg,
struct sss_domain_info *dom)
{
@@ -1744,6 +1794,56 @@ done:
* GROUP db related functions
***************************************************************************/
+void nss_update_gr_memcache(struct nss_ctx *nctx)
+{
+ struct sss_domain_info *dom;
+ struct ldb_result *res;
+ uint64_t exp;
+ struct sized_string key;
+ const char *id;
+ time_t now;
+ int ret;
+ int i;
+
+ now = time(NULL);
+
+ for (dom = nctx->rctx->domains; dom != NULL; dom = dom->next) {
+ ret = sysdb_enumgrent(nctx, dom->sysdb, &res);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_CRIT_FAILURE,
+ ("Failed to enumerate users for domain [%s]\n", dom->name));
+ continue;
+ }
+
+ for (i = 0; i < res->count; i++) {
+ exp = ldb_msg_find_attr_as_uint64(res->msgs[i],
+ SYSDB_CACHE_EXPIRE, 0);
+ if (exp >= now) {
+ continue;
+ }
+
+ /* names require more manipulation (build up fqname conditionally),
+ * but uidNumber is unique and always resolvable too, so we use
+ * that to update the cache, as it points to the same entry */
+ id = ldb_msg_find_attr_as_string(res->msgs[i], SYSDB_GIDNUM, NULL);
+ if (!id) {
+ DEBUG(SSSDBG_CRIT_FAILURE,
+ ("Failed to find gidNumber in %s.\n",
+ ldb_dn_get_linearized(res->msgs[i]->dn)));
+ continue;
+ }
+ to_sized_string(&key, id);
+
+ ret = sss_mmap_cache_gr_invalidate(nctx->grp_mc_ctx, &key);
+ if (ret != EOK && ret != ENOENT) {
+ DEBUG(SSSDBG_CRIT_FAILURE,
+ ("Internal failure in memory cache code: %d [%s]\n",
+ ret, strerror(ret)));
+ }
+ }
+ }
+}
+
#define GID_ROFFSET 0
#define MNUM_ROFFSET sizeof(uint32_t)
#define STRS_ROFFSET 2*sizeof(uint32_t)
diff --git a/src/responder/nss/nsssrv_private.h b/src/responder/nss/nsssrv_private.h
index f1d47c3bc..c58893110 100644
--- a/src/responder/nss/nsssrv_private.h
+++ b/src/responder/nss/nsssrv_private.h
@@ -123,4 +123,7 @@ errno_t check_cache(struct nss_dom_ctx *dctx,
sss_dp_callback_t callback,
void *pvt);
+void nss_update_pw_memcache(struct nss_ctx *nctx);
+void nss_update_gr_memcache(struct nss_ctx *nctx);
+
#endif /* NSSSRV_PRIVATE_H_ */