summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJakub Hrozek <jhrozek@redhat.com>2012-05-21 22:44:05 +0200
committerJakub Hrozek <jhrozek@redhat.com>2012-10-20 14:48:09 +0200
commit5bbef2f85038ad093fbaa16527863139d3c9f849 (patch)
tree9a38a19462681a763ff3d29b52a2739fdcecd67d
parentcbc4fc991de6889c80e56dda6b80c8b7cd597e8a (diff)
downloadsssd-5bbef2f85038ad093fbaa16527863139d3c9f849.tar.gz
sssd-5bbef2f85038ad093fbaa16527863139d3c9f849.tar.xz
sssd-5bbef2f85038ad093fbaa16527863139d3c9f849.zip
autofs: use the new interface. FIXME - inspect the usage of autofs_cmd_done vs. autofs_setent_notify
-rw-r--r--src/responder/autofs/autofssrv_cmd.c395
1 files changed, 166 insertions, 229 deletions
diff --git a/src/responder/autofs/autofssrv_cmd.c b/src/responder/autofs/autofssrv_cmd.c
index 3af4a8468..d38eb8786 100644
--- a/src/responder/autofs/autofssrv_cmd.c
+++ b/src/responder/autofs/autofssrv_cmd.c
@@ -342,6 +342,13 @@ set_autofs_map_lifetime(uint32_t lifetime,
}
}
+#define set_map_entry(map, isready, isfound, lookup_ctx) do { \
+ map->ready = isready; \
+ map->found = isfound; \
+ set_autofs_map_lifetime(lookup_ctx->actx->neg_timeout, \
+ lookup_ctx, map); \
+} while(0)
+
static struct tevent_req *
setautomntent_send(TALLOC_CTX *mem_ctx,
const char *rawname,
@@ -531,282 +538,212 @@ fail:
return req;
}
-static errno_t
-lookup_automntmap_update_cache(struct setautomntent_lookup_ctx *lookup_ctx);
+const char *
+get_autofs_map_name(void *pvt)
+{
+ struct setautomntent_lookup_ctx *lookup_ctx = talloc_get_type(pvt,
+ struct setautomntent_lookup_ctx);
+ return lookup_ctx->mapname;
+}
-static errno_t
-lookup_automntmap_step(struct setautomntent_lookup_ctx *lookup_ctx)
+errno_t
+autofs_map_in_ncache(void *pvt)
{
- errno_t ret;
- struct sss_domain_info *dom = lookup_ctx->dctx->domain;
- struct autofs_dom_ctx *dctx = lookup_ctx->dctx;
- struct sysdb_ctx *sysdb;
struct autofs_map_ctx *map;
+ struct setautomntent_lookup_ctx *lookup_ctx = talloc_get_type(pvt,
+ struct setautomntent_lookup_ctx);
+ errno_t ret;
- /* Check each domain for this map name */
- while (dom) {
- /* if it is a domainless search, skip domains that require fully
- * qualified names instead */
- while (dom && dctx->cmd_ctx->check_next && dom->fqnames) {
- dom = dom->next;
- }
-
- /* No domains left to search */
- if (!dom) break;
-
- if (dom != dctx->domain) {
- /* make sure we reset the check_provider flag when we check
- * a new domain */
- dctx->check_provider =
- NEED_CHECK_PROVIDER(dom->provider);
- }
-
- /* make sure to update the dctx if we changed domain */
- dctx->domain = dom;
-
- DEBUG(SSSDBG_TRACE_FUNC, ("Requesting info for [%s@%s]\n",
- lookup_ctx->mapname, dom->name));
- sysdb = dom->sysdb;
- if (sysdb == NULL) {
- DEBUG(SSSDBG_FATAL_FAILURE,
- ("Fatal: Sysdb CTX not found for this domain!\n"));
- return EIO;
- }
-
- /* Look into the cache */
- talloc_free(dctx->map);
- ret = sysdb_get_map_byname(dctx, sysdb, lookup_ctx->mapname,
- &dctx->map);
- if (ret != EOK && ret != ENOENT) {
- DEBUG(SSSDBG_OP_FAILURE, ("Could not check cache\n"));
- return ret;
- } else if (ret == ENOENT) {
- DEBUG(SSSDBG_MINOR_FAILURE,
- ("No automount map [%s] in cache for domain [%s]\n",
- lookup_ctx->mapname, dom->name));
- if (!dctx->check_provider) {
- if (dctx->cmd_ctx->check_next) {
- DEBUG(SSSDBG_TRACE_INTERNAL, ("Moving on to next domain\n"));
- dom = dom->next;
- continue;
- }
- else break;
- }
- }
+ ret = get_autofs_map(lookup_ctx->actx, lookup_ctx->mapname, &map);
+ if (ret == ENOENT) {
+ /* The map hasn't been looked up yet. This shouldn't happen
+ * at this point.
+ */
+ DEBUG(SSSDBG_CRIT_FAILURE, ("Autofs map entry was lost!\n"));
+ return EIO;
+ } else if (ret != EOK) {
+ DEBUG(SSSDBG_CRIT_FAILURE, ("Failed to retrieve autofs map entry\n"));
+ return ret;
+ }
- ret = get_autofs_map(lookup_ctx->actx, lookup_ctx->mapname, &map);
- if (ret != EOK) {
- /* Something really bad happened! */
- DEBUG(SSSDBG_CRIT_FAILURE, ("Autofs map entry was lost!\n"));
- return ret;
- }
+ /* Got the map. Was it found or not? */
+ if (map->ready && !map->found) {
+ DEBUG(SSSDBG_TRACE_INTERNAL, ("Setting negative cache for %s\n",
+ lookup_ctx->mapname));
+ return EEXIST;
+ }
- if (dctx->map == NULL && !dctx->check_provider) {
- DEBUG(SSSDBG_MINOR_FAILURE,
- ("Autofs map not found, setting negative cache\n"));
- map->ready = true;
- map->found = false;
- set_autofs_map_lifetime(lookup_ctx->actx->neg_timeout, lookup_ctx, map);
- return ENOENT;
- }
+ return ENOENT;
+}
- if (dctx->check_provider) {
- ret = lookup_automntmap_update_cache(lookup_ctx);
- if (ret == EAGAIN) {
- DEBUG(SSSDBG_TRACE_INTERNAL,
- ("Looking up automount maps from the DP\n"));
- return EAGAIN;
- } else if (ret != EOK) {
- DEBUG(SSSDBG_OP_FAILURE,
- ("Error looking up automount maps [%d]: %s\n",
- ret, strerror(ret)));
- return ret;
- }
- }
+errno_t
+autofs_map_set_ncache(void *pvt)
+{
+ struct autofs_map_ctx *map;
+ struct setautomntent_lookup_ctx *lookup_ctx = talloc_get_type(pvt,
+ struct setautomntent_lookup_ctx);
+ errno_t ret;
- /* OK, the map is in cache and valid.
- * Let's get all members and return it
+ ret = get_autofs_map(lookup_ctx->actx, lookup_ctx->mapname, &map);
+ if (ret == ENOENT) {
+ /* The map hasn't been looked up yet. This shouldn't happen
+ * at this point.
*/
- ret = sysdb_autofs_entries_by_map(map, sysdb, map->mapname,
- &map->entry_count,
- &map->entries);
- if (ret != EOK && ret != ENOENT) {
- DEBUG(SSSDBG_OP_FAILURE,
- ("Error looking automount map entries [%d]: %s\n",
- ret, strerror(ret)));
- map->ready = true;
- map->found = false;
- set_autofs_map_lifetime(lookup_ctx->actx->neg_timeout, lookup_ctx, map);
- return EIO;
- }
+ DEBUG(SSSDBG_CRIT_FAILURE, ("Autofs map entry was lost!\n"));
+ return EIO;
+ } else if (ret != EOK) {
+ DEBUG(SSSDBG_CRIT_FAILURE, ("Failed to retrieve autofs map entry\n"));
+ return ret;
+ }
- map->map = talloc_steal(map, dctx->map);
+ DEBUG(SSSDBG_MINOR_FAILURE,
+ ("Autofs map not found, setting negative cache\n"));
+ set_map_entry(map, true, false, lookup_ctx);
+ return EOK;
+}
- DEBUG(SSSDBG_TRACE_FUNC,
- ("setautomntent done for map %s\n", lookup_ctx->mapname));
- map->ready = true;
- map->found = true;
- set_autofs_map_lifetime(dom->autofsmap_timeout, lookup_ctx, map);
- return EOK;
- }
+errno_t
+autofs_map_check_sysdb(TALLOC_CTX *mem_ctx,
+ struct sysdb_ctx *sysdb,
+ void *pvt,
+ struct ldb_result **res)
+{
+ errno_t ret;
+ struct ldb_message *msg;
+ struct setautomntent_lookup_ctx *lookup_ctx = talloc_get_type(pvt,
+ struct setautomntent_lookup_ctx);
- map = talloc_zero(lookup_ctx->actx, struct autofs_map_ctx);
- if (!map) {
- return ENOMEM;
+ ret = sysdb_get_map_byname(lookup_ctx, sysdb, lookup_ctx->mapname, &msg);
+ if (ret != EOK) {
+ return ret;
}
- map->ready = true;
- map->found = false;
- map->map_table = lookup_ctx->actx->maps;
-
- map->mapname = talloc_strdup(map, lookup_ctx->mapname);
- if (!map->mapname) {
- talloc_free(map);
+ *res = talloc_zero(mem_ctx, struct ldb_result);
+ if (!*res) {
+ talloc_free(msg);
return ENOMEM;
}
- ret = set_autofs_map(lookup_ctx->actx, map);
- if (ret != EOK) {
- talloc_free(map);
+ (*res)->msgs = talloc_zero_array(*res, struct ldb_message *, 2);
+ if (!(*res)->msgs) {
+ talloc_free(msg);
+ talloc_free(*res);
return ENOMEM;
}
+ (*res)->msgs[0] = talloc_move(*res, &msg);
+ (*res)->count = 1;
- set_autofs_map_lifetime(lookup_ctx->actx->neg_timeout, lookup_ctx, map);
-
- /* If we've gotten here, then no domain contained this map */
- return ENOENT;
+ return EOK;
}
-static void lookup_automntmap_cache_updated(uint16_t err_maj, uint32_t err_min,
- const char *err_msg, void *ptr);
-static void autofs_dp_send_map_req_done(struct tevent_req *req);
+struct tevent_req *
+autofs_map_lookup(void *pvt)
+{
+ struct setautomntent_lookup_ctx *lookup_ctx = talloc_get_type(pvt,
+ struct setautomntent_lookup_ctx);
-static errno_t
-lookup_automntmap_update_cache(struct setautomntent_lookup_ctx *lookup_ctx)
+ return sss_dp_get_autofs_send(lookup_ctx->cctx, lookup_ctx->rctx,
+ lookup_ctx->dctx->domain, true,
+ SSS_DP_AUTOFS, lookup_ctx->mapname);
+}
+
+errno_t
+autofs_map_updated(TALLOC_CTX *mem_ctx, struct tevent_req *req,
+ dbus_uint16_t *dp_err, dbus_uint32_t *dp_ret,
+ char **err_msg)
{
- errno_t ret;
- uint64_t cache_expire = 0;
- struct autofs_dom_ctx *dctx = lookup_ctx->dctx;
- struct tevent_req *req = NULL;
- struct dp_callback_ctx *cb_ctx = NULL;
-
- if (dctx->map != NULL) {
- cache_expire = ldb_msg_find_attr_as_uint64(dctx->map,
- SYSDB_CACHE_EXPIRE, 0);
-
- /* if we have any reply let's check cache validity */
- ret = sss_cmd_check_cache(dctx->map, 0, cache_expire);
- if (ret == EOK) {
- DEBUG(SSSDBG_TRACE_FUNC, ("Cached entry is valid, returning..\n"));
- return EOK;
- } else if (ret != EAGAIN && ret != ENOENT) {
- DEBUG(SSSDBG_CRIT_FAILURE, ("Error checking cache: %d\n", ret));
- goto error;
- }
- }
+ return sss_dp_get_autofs_recv(mem_ctx, req, dp_err, dp_ret, err_msg);
+}
- /* dont loop forever :-) */
- dctx->check_provider = false;
+static void setautomntent_done(struct tevent_req *subreq);
- /* keep around current data in case backend is offline */
- /* FIXME - do this by default */
-#if 0
- if (dctx->res->count) {
- dctx->res = talloc_steal(dctx, dctx->res);
- }
-#endif
+static errno_t
+lookup_automntmap_step(struct setautomntent_lookup_ctx *lookup_ctx)
+{
+ struct tevent_req *req;
+ static struct getent_ops setautomntent_ops = {
+ .check_ncache = autofs_map_in_ncache,
+ .set_ncache = autofs_map_set_ncache,
+ .check_sysdb = autofs_map_check_sysdb,
+ .update_cache = autofs_map_lookup,
+ .cache_updated = autofs_map_updated,
+ .get_ent_name = get_autofs_map_name
+ };
- req = sss_dp_get_autofs_send(lookup_ctx->cctx, lookup_ctx->rctx,
- lookup_ctx->dctx->domain, true,
- SSS_DP_AUTOFS, lookup_ctx->mapname);
+ req = getent_send(lookup_ctx, lookup_ctx->rctx->ev, lookup_ctx->cctx,
+ lookup_ctx->dctx->cmd_ctx->check_next, 0,
+ &setautomntent_ops, "autofs", lookup_ctx);
if (!req) {
- DEBUG(SSSDBG_CRIT_FAILURE,
- ("Out of memory sending data provider request\n"));
- ret = ENOMEM;
- goto error;
- }
-
- cb_ctx = talloc_zero(lookup_ctx->dctx, struct dp_callback_ctx);
- if(!cb_ctx) {
- talloc_zfree(req);
- ret = ENOMEM;
- goto error;
+ return ENOMEM;
}
- cb_ctx->callback = lookup_automntmap_cache_updated;
- cb_ctx->ptr = lookup_ctx;
- cb_ctx->cctx = lookup_ctx->dctx->cmd_ctx->cctx;
- cb_ctx->mem_ctx = lookup_ctx->dctx;
+ /* FIXME - what if the client disconnects at this point? */
+ tevent_req_set_callback(req, setautomntent_done, lookup_ctx);
- tevent_req_set_callback(req, autofs_dp_send_map_req_done, cb_ctx);
-
- return EAGAIN;
-
-error:
- ret = autofs_cmd_send_error(lookup_ctx->dctx->cmd_ctx, ret);
- if (ret != EOK) {
- DEBUG(SSSDBG_CRIT_FAILURE, ("Fatal error, killing connection!\n"));
- talloc_free(lookup_ctx->cctx);
- return ret;
- }
- autofs_cmd_done(lookup_ctx->dctx->cmd_ctx, ret);
return EOK;
}
-static void autofs_dp_send_map_req_done(struct tevent_req *req)
+static void setautomntent_done(struct tevent_req *req)
{
- struct dp_callback_ctx *cb_ctx =
- tevent_req_callback_data(req, struct dp_callback_ctx);
- struct setautomntent_lookup_ctx *lookup_ctx =
- talloc_get_type(cb_ctx->ptr, struct setautomntent_lookup_ctx);
-
errno_t ret;
- dbus_uint16_t err_maj;
- dbus_uint32_t err_min;
- char *err_msg;
+ struct setautomntent_lookup_ctx *lookup_ctx = tevent_req_data(req,
+ struct setautomntent_lookup_ctx);
+ struct autofs_map_ctx *map;
+ struct ldb_result *rcv_map;
+ struct sysdb_ctx *sysdb;
- ret = sss_dp_get_autofs_recv(cb_ctx->mem_ctx, req,
- &err_maj, &err_min,
- &err_msg);
+ ret = getent_recv(lookup_ctx, req, &sysdb, &rcv_map);
talloc_free(req);
- if (ret != EOK) {
- DEBUG(SSSDBG_CRIT_FAILURE, ("Fatal error, killing connection!\n"));
- talloc_free(lookup_ctx->cctx);
+ if (ret != EOK && ret != ENOENT) {
+ DEBUG(SSSDBG_OP_FAILURE, ("getent failed\n"));
+ autofs_cmd_done(lookup_ctx->dctx->cmd_ctx, ret);
return;
}
+ /* Either we succeeded or no domains were eligible */
- cb_ctx->callback(err_maj, err_min, err_msg, cb_ctx->ptr);
-}
+ ret = get_autofs_map(lookup_ctx->actx, lookup_ctx->mapname, &map);
+ if (ret != EOK) {
+ /* Something really bad happened! */
+ DEBUG(SSSDBG_CRIT_FAILURE, ("Autofs map entry was lost!\n"));
+ goto done;
+ }
-static void lookup_automntmap_cache_updated(uint16_t err_maj, uint32_t err_min,
- const char *err_msg, void *ptr)
-{
- struct setautomntent_lookup_ctx *lookup_ctx =
- talloc_get_type(ptr, struct setautomntent_lookup_ctx);
- struct autofs_dom_ctx *dctx = lookup_ctx->dctx;
- errno_t ret;
+ if (ret == ENOENT) {
+ /* Make sure the map is in negative cache */
+ set_map_entry(map, true, false, lookup_ctx);
+ goto done;
+ }
- if (err_maj) {
+ if (rcv_map->count != 1) {
DEBUG(SSSDBG_CRIT_FAILURE,
- ("Unable to get information from Data Provider\n"
- "Error: %u, %u, %s\n"
- "Will try to return what we have in cache\n",
- (unsigned int)err_maj, (unsigned int)err_min, err_msg));
- /* Loop to the next domain if possible */
- if (dctx->domain->next && dctx->cmd_ctx->check_next) {
- dctx->domain = dctx->domain->next;
- dctx->check_provider = NEED_CHECK_PROVIDER(dctx->domain->provider);
- }
+ ("Cache containes %d duplicate entries\n",
+ rcv_map->count));
+ ret = EIO;
+ goto done;
}
- /* ok the backend returned, search to see if we have updated results */
- ret = lookup_automntmap_step(lookup_ctx);
- if (ret != EOK) {
- if (ret == EAGAIN) {
- return;
- }
+ /* OK, the map is in cache and valid.
+ * Let's get all members and return it
+ */
+ ret = sysdb_autofs_entries_by_map(map, sysdb, map->mapname,
+ &map->entry_count, &map->entries);
+ if (ret != EOK && ret != ENOENT) {
+ DEBUG(SSSDBG_OP_FAILURE,
+ ("Error looking automount map entries [%d]: %s\n",
+ ret, strerror(ret)));
+ set_map_entry(map, true, false, lookup_ctx);
+ ret = EIO;
+ goto done;
}
- /* We have results to return */
+ map->map = talloc_steal(map, rcv_map->msgs[0]);
+
+ DEBUG(SSSDBG_TRACE_FUNC,
+ ("setautomntent done for map %s\n", lookup_ctx->mapname));
+ set_map_entry(map, true, true, lookup_ctx);
+
+ ret = EOK;
+done:
+ /* FIXME - what about autofs_cmd_done() ? */
autofs_setent_notify(lookup_ctx->map, ret);
}