[SSSD] [PATCH 2/5] Hook to perform a mmap cache update from sssd_nss

Simo Sorce simo at redhat.com
Wed Dec 5 18:40:43 UTC 2012


This set of functions enumerate each user/group from all domains
and invalidate any mmap cache record that matches.
---
 src/providers/data_provider.h      |    6 ++
 src/responder/nss/nsssrv.c         |   15 +++++
 src/responder/nss/nsssrv_cmd.c     |  100 ++++++++++++++++++++++++++++++++++++
 src/responder/nss/nsssrv_private.h |    3 +
 4 files changed, 124 insertions(+), 0 deletions(-)

diff --git a/src/providers/data_provider.h b/src/providers/data_provider.h
index bb944509da9f1dc89216266cf62c57fb4127fd57..9c7340021268925860b48b3e62f0d0b4d4731ebb 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 e01bd1a4d49d80e0c43fa1bbe4521636c87015e6..8694edaf614f6a218621518416965ffb2e558873 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 db1efdd21f8b0f277c2465bfecdf51bba6395408..2397fb38d37e0fc4c00b2f2967e3d12afbffde2e 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)
 {
@@ -1746,6 +1796,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 f1d47c3bc4a62fb816b7b262083e36c05383673d..c58893110ec3617e7950d3bfb7ac1607dde69bb5 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_ */
-- 
1.7.1




More information about the sssd-devel mailing list