From b0043a95f86b240d0beb551ef4e9ff9a4be99995 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
Date: Wed, 7 Aug 2019 13:59:04 +0200
Subject: [PATCH 78/90] autofs: convert code to cache_req
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This will simplify the code a lot so it can be further extended.
At this point the conversion is done 1:1, we will do additional
changes in next patches.
Resolves:
https://pagure.io/SSSD/sssd/issue/2607
Reviewed-by: Tomáš Halman <thalman@redhat.com>
---
src/responder/autofs/autofs_private.h | 72 +-
src/responder/autofs/autofssrv.c | 7 +-
src/responder/autofs/autofssrv_cmd.c | 1651 ++++++++-----------------
3 files changed, 549 insertions(+), 1181 deletions(-)
diff --git a/src/responder/autofs/autofs_private.h b/src/responder/autofs/autofs_private.h
index 6a39b17ad..3be25d4d9 100644
--- a/src/responder/autofs/autofs_private.h
+++ b/src/responder/autofs/autofs_private.h
@@ -21,7 +21,9 @@
#ifndef _AUTOFSSRV_PRIVATE_H_
#define _AUTOFSSRV_PRIVATE_H_
+#include "responder/common/responder.h"
#include "responder/common/responder_sbus.h"
+#include "responder/common/cache_req/cache_req.h"
#define SSS_AUTOFS_PROTO_VERSION 0x001
@@ -33,75 +35,33 @@ struct autofs_ctx {
hash_table_t *maps;
};
-struct autofs_state_ctx {
- char *automntmap_name;
-};
-
struct autofs_cmd_ctx {
- struct cli_ctx *cctx;
- char *mapname;
- char *key;
- uint32_t cursor;
+ struct autofs_ctx *autofs_ctx;
+ struct cli_ctx *cli_ctx;
+
+ const char *mapname;
+ const char *keyname;
uint32_t max_entries;
- bool check_next;
+ uint32_t cursor;
};
-struct autofs_dom_ctx {
- struct autofs_cmd_ctx *cmd_ctx;
- struct sss_domain_info *domain;
- bool check_provider;
-
- /* cache results */
- struct ldb_message *map;
-
- size_t entry_count;
- struct ldb_message **entries;
-
- struct autofs_map_ctx *map_ctx;
-};
+struct autofs_enum_ctx {
+ /* Results. First result is the map objects, next results are map entries. */
+ struct cache_req_result *result;
-struct autofs_map_ctx {
- /* state of the map entry */
- bool ready;
+ /* True if the map was found. */
bool found;
- /* requests */
- struct setent_req_list *reqs;
-
- hash_table_t *map_table;
- char *mapname;
+ /* False if the result is being created. */
+ bool ready;
- /* map entry */
- struct ldb_message *map;
- size_t entry_count;
- struct ldb_message **entries;
+ /* Requests that awaits the data. */
+ struct setent_req_list *notify_list;
};
struct sss_cmd_table *get_autofs_cmds(void);
int autofs_connection_setup(struct cli_ctx *cctx);
-void autofs_map_hash_delete_cb(hash_entry_t *item,
- hash_destroy_enum deltype, void *pvt);
-
errno_t autofs_orphan_maps(struct autofs_ctx *actx);
-enum sss_dp_autofs_type {
- SSS_DP_AUTOFS
-};
-
-struct tevent_req *
-sss_dp_get_autofs_send(TALLOC_CTX *mem_ctx,
- struct resp_ctx *rctx,
- struct sss_domain_info *dom,
- bool fast_reply,
- enum sss_dp_autofs_type type,
- const char *name);
-
-errno_t
-sss_dp_get_autofs_recv(TALLOC_CTX *mem_ctx,
- struct tevent_req *req,
- dbus_uint16_t *dp_err,
- dbus_uint32_t *dp_ret,
- char **err_msg);
-
#endif /* _AUTOFSSRV_PRIVATE_H_ */
diff --git a/src/responder/autofs/autofssrv.c b/src/responder/autofs/autofssrv.c
index 7d236f4d9..309ed76b1 100644
--- a/src/responder/autofs/autofssrv.c
+++ b/src/responder/autofs/autofssrv.c
@@ -28,6 +28,7 @@
#include "responder/common/responder.h"
#include "providers/data_provider.h"
#include "responder/autofs/autofs_private.h"
+#include "util/sss_ptr_hash.h"
static int autofs_clean_hash_table(struct sbus_request *dbus_req, void *data);
@@ -105,7 +106,6 @@ autofs_process_init(TALLOC_CTX *mem_ctx,
struct autofs_ctx *autofs_ctx;
struct be_conn *iter;
int ret;
- int hret;
int max_retries;
autofs_cmds = get_autofs_cmds();
@@ -158,9 +158,8 @@ autofs_process_init(TALLOC_CTX *mem_ctx,
}
/* Create the lookup table for setautomntent results */
- hret = sss_hash_create_ex(autofs_ctx, 10, &autofs_ctx->maps, 0, 0, 0, 0,
- autofs_map_hash_delete_cb, NULL);
- if (hret != HASH_SUCCESS) {
+ autofs_ctx->maps = sss_ptr_hash_create(autofs_ctx, NULL, NULL);
+ if (autofs_ctx->maps == NULL) {
DEBUG(SSSDBG_CRIT_FAILURE,
"Unable to initialize automount maps hash table\n");
ret = EIO;
diff --git a/src/responder/autofs/autofssrv_cmd.c b/src/responder/autofs/autofssrv_cmd.c
index 9ea2ab71b..670b6d50d 100644
--- a/src/responder/autofs/autofssrv_cmd.c
+++ b/src/responder/autofs/autofssrv_cmd.c
@@ -25,20 +25,22 @@
#include "util/util.h"
#include "responder/common/responder.h"
#include "responder/common/responder_packet.h"
+#include "responder/common/cache_req/cache_req.h"
#include "responder/autofs/autofs_private.h"
#include "db/sysdb.h"
#include "db/sysdb_autofs.h"
#include "confdb/confdb.h"
+#include "util/sss_ptr_hash.h"
static int autofs_cmd_send_error(struct autofs_cmd_ctx *cmdctx, int err)
{
- return sss_cmd_send_error(cmdctx->cctx, err);
+ return sss_cmd_send_error(cmdctx->cli_ctx, err);
}
static int
autofs_cmd_send_empty(struct autofs_cmd_ctx *cmdctx)
{
- return sss_cmd_send_empty(cmdctx->cctx);
+ return sss_cmd_send_empty(cmdctx->cli_ctx);
}
static int
@@ -54,7 +56,7 @@ autofs_cmd_done(struct autofs_cmd_ctx *cmdctx, int ret)
if (ret) {
return EFAULT;
}
- sss_cmd_done(cmdctx->cctx, cmdctx);
+ sss_cmd_done(cmdctx->cli_ctx, cmdctx);
break;
case EAGAIN:
@@ -70,7 +72,7 @@ autofs_cmd_done(struct autofs_cmd_ctx *cmdctx, int ret)
if (ret) {
return EFAULT;
}
- sss_cmd_done(cmdctx->cctx, cmdctx);
+ sss_cmd_done(cmdctx->cli_ctx, cmdctx);
break;
}
@@ -78,1058 +80,524 @@ autofs_cmd_done(struct autofs_cmd_ctx *cmdctx, int ret)
}
static errno_t
-autofs_setent_add_ref(TALLOC_CTX *memctx,
- struct autofs_map_ctx *map_ctx,
- struct tevent_req *req)
+autofs_fill_entry(struct ldb_message *entry, struct sss_packet *packet, size_t *rp)
{
- return setent_add_ref(memctx, &map_ctx->reqs, req);
-}
-
-static void
-autofs_setent_notify(struct autofs_map_ctx *map_ctx, errno_t ret)
-{
- setent_notify(&map_ctx->reqs, ret);
-}
-
-errno_t
-autofs_orphan_maps(struct autofs_ctx *actx)
-{
- int hret;
- unsigned long mcount;
- unsigned long i;
- hash_key_t *maps;
+ errno_t ret;
+ const char *key;
+ size_t keylen;
+ const char *value;
+ size_t valuelen;
+ uint8_t *body;
+ size_t blen;
+ size_t len;
- if (!actx || !actx->maps) {
+ key = ldb_msg_find_attr_as_string(entry, SYSDB_AUTOFS_ENTRY_KEY, NULL);
+ value = ldb_msg_find_attr_as_string(entry, SYSDB_AUTOFS_ENTRY_VALUE, NULL);
+ if (!key || !value) {
+ DEBUG(SSSDBG_MINOR_FAILURE, "Incomplete entry\n");
return EINVAL;
}
- hret = hash_keys(actx->maps, &mcount, &maps);
- if (hret != HASH_SUCCESS) {
- return EIO;
- }
-
- for (i = 0; i < mcount; i++) {
- hret = hash_delete(actx->maps, &maps[i]);
- if (hret != HASH_SUCCESS) {
- DEBUG(SSSDBG_MINOR_FAILURE, "Could not delete key from hash\n");
- continue;
- }
- }
-
- return EOK;
-}
+ keylen = 1 + strlen(key);
+ valuelen = 1 + strlen(value);
+ len = sizeof(uint32_t) + sizeof(uint32_t) + keylen + sizeof(uint32_t) + valuelen;
-static errno_t
-get_autofs_map(struct autofs_ctx *actx,
- char *mapname,
- struct autofs_map_ctx **map)
-{
- hash_key_t key;
- hash_value_t value;
- int hret;
-
- key.type = HASH_KEY_STRING;
- key.str = mapname;
-
- hret = hash_lookup(actx->maps, &key, &value);
- if (hret == HASH_SUCCESS) {
- *map = talloc_get_type(value.ptr, struct autofs_map_ctx);
- return EOK;
- } else if (hret == HASH_ERROR_KEY_NOT_FOUND) {
- return ENOENT;
+ ret = sss_packet_grow(packet, len);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, "Cannot grow packet\n");
+ return ret;
}
- DEBUG(SSSDBG_CRIT_FAILURE,
- "Unexpected error reading from autofs map hash [%d][%s]\n",
- hret, hash_error_string(hret));
- return EIO;
-}
-
-static int autofs_map_hash_remove (TALLOC_CTX *ctx);
+ sss_packet_get_body(packet, &body, &blen);
-void
-autofs_map_hash_delete_cb(hash_entry_t *item,
- hash_destroy_enum deltype, void *pvt)
-{
- struct autofs_map_ctx *map;
+ SAFEALIGN_SET_UINT32(&body[*rp], len, rp);
+ SAFEALIGN_SET_UINT32(&body[*rp], keylen, rp);
- if (deltype != HASH_ENTRY_DESTROY) {
- return;
+ if (keylen == 1) {
+ body[*rp] = '\0';
+ } else {
+ memcpy(&body[*rp], key, keylen);
}
+ *rp += keylen;
- map = talloc_get_type(item->value.ptr, struct autofs_map_ctx);
- if (!map) {
- DEBUG(SSSDBG_OP_FAILURE, "Invalid autofs map\n");
- return;
+ SAFEALIGN_SET_UINT32(&body[*rp], valuelen, rp);
+ if (valuelen == 1) {
+ body[*rp] = '\0';
+ } else {
+ memcpy(&body[*rp], value, valuelen);
}
+ *rp += valuelen;
- /* So that the destructor wouldn't attempt to remove the map from hash
- * table */
- map->map_table = NULL;
+ return EOK;
}
-static errno_t
-set_autofs_map(struct autofs_ctx *actx,
- struct autofs_map_ctx *map)
+errno_t
+autofs_orphan_maps(struct autofs_ctx *autofs_ctx)
{
- hash_key_t key;
- hash_value_t value;
- int hret;
-
- if (map->mapname == NULL) {
- DEBUG(SSSDBG_CRIT_FAILURE, "Missing autofs map name.\n");
- return EINVAL;
- }
-
- /* Add this entry to the hash table */
- key.type = HASH_KEY_STRING;
- key.str = map->mapname;
- value.type = HASH_VALUE_PTR;
- value.ptr = map;
- hret = hash_enter(actx->maps, &key, &value);
- if (hret != EOK) {
- DEBUG(SSSDBG_CRIT_FAILURE,
- "Unable to add hash table entry for [%s]\n", key.str);
- DEBUG(SSSDBG_MINOR_FAILURE,
- "Hash error [%d][%s]\n", hret, hash_error_string(hret));
- return EIO;
- }
- talloc_steal(actx->maps, map);
- talloc_set_destructor((TALLOC_CTX *) map, autofs_map_hash_remove);
+ sss_ptr_hash_delete_all(autofs_ctx->maps, true);
return EOK;
}
-static int
-autofs_map_hash_remove(TALLOC_CTX *ctx)
+static void
+autofs_enumctx_lifetime_timeout(struct tevent_context *ev,
+ struct tevent_timer *te,
+ struct timeval current_time,
+ void *pvt)
{
- int hret;
- hash_key_t key;
- struct autofs_map_ctx *map =
- talloc_get_type(ctx, struct autofs_map_ctx);
-
- if (map->map_table == NULL) {
- DEBUG(SSSDBG_TRACE_LIBS, "autofs map [%s] was already removed\n",
- map->mapname);
- return 0;
- }
+ struct autofs_enum_ctx *enum_ctx;
- key.type = HASH_KEY_STRING;
- key.str = map->mapname;
+ enum_ctx = talloc_get_type(pvt, struct autofs_enum_ctx);
- /* Remove the autofs map result object from the lookup table */
- hret = hash_delete(map->map_table, &key);
- if (hret != HASH_SUCCESS) {
- DEBUG(SSSDBG_CRIT_FAILURE,
- "Could not remove key from table! [%d][%s]\n",
- hret, hash_error_string(hret));
- return -1;
- }
- return 0;
+ /* Free the context. It will be automatically removed from the hash table. */
+ talloc_free(enum_ctx);
}
-static struct tevent_req *
-setautomntent_send(TALLOC_CTX *mem_ctx,
- const char *rawname,
- struct autofs_cmd_ctx *cmdctx);
-static errno_t setautomntent_recv(struct tevent_req *req);
-static void sss_autofs_cmd_setautomntent_done(struct tevent_req *req);
-
-/* FIXME - file a ticket to have per-responder private
- * data instead of growing the cli_ctx structure */
-static int
-sss_autofs_cmd_setautomntent(struct cli_ctx *client)
+static void
+autofs_set_enumctx_lifetime(struct autofs_ctx *autofs_ctx,
+ struct autofs_enum_ctx *enum_ctx,
+ uint32_t lifetime)
{
- struct autofs_cmd_ctx *cmdctx;
- struct cli_protocol *pctx;
- uint8_t *body;
- size_t blen;
- errno_t ret = EOK;
- const char *rawname;
- struct tevent_req *req;
-
- DEBUG(SSSDBG_TRACE_INTERNAL, "sss_autofs_cmd_setautomntent\n");
-
- cmdctx = talloc_zero(client, struct autofs_cmd_ctx);
- if (!cmdctx) {
- return ENOMEM;
- }
- cmdctx->cctx = client;
-
- pctx = talloc_get_type(cmdctx->cctx->protocol_ctx, struct cli_protocol);
-
- sss_packet_get_body(pctx->creq->in, &body, &blen);
-
- /* if not terminated fail */
- if (body[blen -1] != '\0') {
- ret = EINVAL;
- goto done;
- }
-
- /* If the body isn't valid UTF-8, fail */
- if (!sss_utf8_check(body, blen -1)) {
- ret = EINVAL;
- goto done;
- }
-
- rawname = (const char *)body;
- DEBUG(SSSDBG_TRACE_FUNC,
- "Got request for automount map named %s\n", rawname);
+ struct timeval tv;
+ struct tevent_timer *te;
- req = setautomntent_send(cmdctx, rawname, cmdctx);
- if (!req) {
+ tv = tevent_timeval_current_ofs(lifetime, 0);
+ te = tevent_add_timer(autofs_ctx->rctx->ev, enum_ctx, tv,
+ autofs_enumctx_lifetime_timeout, enum_ctx);
+ if (te == NULL) {
DEBUG(SSSDBG_CRIT_FAILURE,
- "Fatal error calling setautomntent_send\n");
- ret = EIO;
- goto done;
+ "Could not set up life timer for autofs maps. "
+ "Entries may become stale.\n");
}
- tevent_req_set_callback(req, sss_autofs_cmd_setautomntent_done, cmdctx);
-
- ret = EOK;
-done:
- return autofs_cmd_done(cmdctx, ret);
}
-static void sss_autofs_cmd_setautomntent_done(struct tevent_req *req)
+static struct autofs_enum_ctx *
+autofs_create_enumeration_context(TALLOC_CTX *mem_ctx,
+ struct autofs_ctx *autofs_ctx,
+ const char *mapname)
{
- struct autofs_cmd_ctx *cmdctx =
- tevent_req_callback_data(req, struct autofs_cmd_ctx);
- struct cli_protocol *pctx;
+ struct autofs_enum_ctx *enum_ctx;
errno_t ret;
- errno_t reqret;
- uint8_t *body;
- size_t blen;
- DEBUG(SSSDBG_TRACE_INTERNAL, "setautomntent done\n");
-
- reqret = setautomntent_recv(req);
- talloc_zfree(req);
- if (reqret != EOK && reqret != ENOENT) {
- DEBUG(SSSDBG_CRIT_FAILURE, "setautomntent_recv failed\n");
- autofs_cmd_done(cmdctx, reqret);
- return;
+ enum_ctx = talloc_zero(mem_ctx, struct autofs_enum_ctx);
+ if (enum_ctx == NULL) {
+ return NULL;
}
- pctx = talloc_get_type(cmdctx->cctx->protocol_ctx, struct cli_protocol);
+ enum_ctx->ready = false;
- /* Either we succeeded or no domains were eligible */
- ret = sss_packet_new(pctx->creq, 0,
- sss_packet_get_cmd(pctx->creq->in),
- &pctx->creq->out);
- if (ret == EOK) {
- if (reqret == ENOENT) {
- DEBUG(SSSDBG_TRACE_FUNC, "setautomntent did not find requested map\n");
- /* Notify the caller that this entry wasn't found */
- ret = sss_cmd_empty_packet(pctx->creq->out);
- if (ret != EOK) {
- DEBUG(SSSDBG_TRACE_INTERNAL,
- "sss_cmd_empty_packet() failed: %s [%d]\n",
- sss_strerror(ret), ret);
- }
- } else {
- DEBUG(SSSDBG_TRACE_FUNC, "setautomntent found data\n");
- ret = sss_packet_grow(pctx->creq->out, 2*sizeof(uint32_t));
- if (ret != EOK) {
- DEBUG(SSSDBG_CRIT_FAILURE, "Couldn't grow the packet\n");
- talloc_free(cmdctx);
- return;
- }
-
- sss_packet_get_body(pctx->creq->out, &body, &blen);
-
- /* Got some results */
- SAFEALIGN_SETMEM_UINT32(body, 1, NULL);
-
- /* Reserved padding */
- SAFEALIGN_SETMEM_UINT32(body + sizeof(uint32_t), 0, NULL);
- }
-
- sss_cmd_done(cmdctx->cctx, NULL);
- return;
+ ret = sss_ptr_hash_add(autofs_ctx->maps, mapname,
+ enum_ctx, struct autofs_enum_ctx);
+ if (ret != EOK) {
+ talloc_free(enum_ctx);
+ return NULL;
}
- DEBUG(SSSDBG_CRIT_FAILURE, "Error creating packet\n");
- return;
+ return enum_ctx;
}
-struct setautomntent_state {
- struct autofs_cmd_ctx *cmdctx;
- struct autofs_dom_ctx *dctx;
-
- char *mapname;
- struct autofs_map_ctx *map;
+struct autofs_setent_state {
+ struct autofs_ctx *autofs_ctx;
+ struct autofs_enum_ctx *enum_ctx;
};
-struct setautomntent_lookup_ctx {
- struct autofs_ctx *actx;
- struct autofs_dom_ctx *dctx;
- struct resp_ctx *rctx;
- struct cli_ctx *cctx;
-
- bool returned_to_mainloop;
-
- char *mapname;
- struct autofs_map_ctx *map;
-};
-
-static errno_t
-lookup_automntmap_step(struct setautomntent_lookup_ctx *lookup_ctx);
-
-static void
-autofs_map_result_timeout(struct tevent_context *ev,
- struct tevent_timer *te,
- struct timeval current_time,
- void *pvt)
-{
- struct autofs_map_ctx *map =
- talloc_get_type(pvt, struct autofs_map_ctx);
-
- /* Free the autofs map result context
- * The destructor for the autofs map will remove itself
- * from the hash table
- */
- talloc_free(map);
-}
-
-static void
-set_autofs_map_lifetime(uint32_t lifetime,
- struct setautomntent_lookup_ctx *lookup_ctx,
- struct autofs_map_ctx *map)
-{
- struct timeval tv;
- struct tevent_timer *te;
-
- tv = tevent_timeval_current_ofs(lifetime, 0);
- te = tevent_add_timer(lookup_ctx->rctx->ev,
- map, tv,
- autofs_map_result_timeout,
- map);
- if (!te) {
- DEBUG(SSSDBG_CRIT_FAILURE,
- "Could not set up life timer for autofs maps. "
- "Entries may become stale.\n");
- }
-}
-
-static errno_t
-setautomntent_get_autofs_map(struct autofs_ctx *actx,
- char *mapname,
- struct autofs_map_ctx **map);
+static void autofs_setent_done(struct tevent_req *subreq);
static struct tevent_req *
-setautomntent_send(TALLOC_CTX *mem_ctx,
- const char *rawname,
- struct autofs_cmd_ctx *cmdctx)
+autofs_setent_send(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ struct autofs_ctx *autofs_ctx,
+ const char *mapname)
{
- char *domname;
- errno_t ret;
+ struct autofs_setent_state *state;
+ struct tevent_req *subreq;
struct tevent_req *req;
- struct setautomntent_state *state;
- struct cli_ctx *client = cmdctx->cctx;
- struct autofs_dom_ctx *dctx;
- struct autofs_ctx *actx;
- struct autofs_state_ctx *state_ctx;
- struct setautomntent_lookup_ctx *lookup_ctx;
-
- actx = talloc_get_type(client->rctx->pvt_ctx, struct autofs_ctx);
- state_ctx = talloc_get_type(client->state_ctx, struct autofs_state_ctx);
-
- req = tevent_req_create(mem_ctx, &state, struct setautomntent_state);
- if (!req) {
- DEBUG(SSSDBG_FATAL_FAILURE,
- "Could not create tevent request for setautomntent\n");
- return NULL;
- }
- state->cmdctx = cmdctx;
-
- dctx = talloc_zero(state, struct autofs_dom_ctx);
- if (!dctx) {
- DEBUG(SSSDBG_FATAL_FAILURE, "Out of memory\n");
- ret = ENOMEM;
- goto fail;
- }
- dctx->cmd_ctx = state->cmdctx;
- state->dctx = dctx;
+ errno_t ret;
- ret = sss_parse_name_for_domains(state, client->rctx->domains,
- NULL, rawname,
- &domname, &state->mapname);
- if (ret != EOK) {
- DEBUG(SSSDBG_FATAL_FAILURE,
- "Invalid name received [%s]\n", rawname);
- goto fail;
+ req = tevent_req_create(mem_ctx, &state, struct autofs_setent_state);
+ if (req == NULL) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create tevent request!\n");
+ return NULL;
}
- DEBUG(SSSDBG_TRACE_FUNC,
- "Requesting info for automount map [%s] from [%s]\n",
- state->mapname, domname?domname:"<ALL>");
-
- if (domname) {
- dctx->domain = responder_get_domain(client->rctx, domname);
- if (!dctx->domain) {
- ret = EINVAL;
- goto fail;
- }
+ state->autofs_ctx = autofs_ctx;
- state_ctx->automntmap_name = talloc_strdup(client, rawname);
- if (!state_ctx->automntmap_name) {
- ret = ENOMEM;
- goto fail;
- }
- } else {
- /* this is a multidomain search */
- dctx->domain = client->rctx->domains;
- cmdctx->check_next = true;
-
- state_ctx->automntmap_name = talloc_strdup(client, state->mapname);
- if (!state_ctx->automntmap_name) {
- ret = ENOMEM;
- goto fail;
- }
- }
-
- dctx->check_provider = NEED_CHECK_PROVIDER(dctx->domain->provider);
- /* Is the result context already available?
- * Check for existing lookups for this map
- */
- ret = setautomntent_get_autofs_map(actx, state->mapname, &state->map);
- if (ret == EOK) {
- /* Another process already requested this map
- * Check whether it's ready for processing.
- */
- if (state->map->ready) {
- if (state->map->found) {
- DEBUG(SSSDBG_TRACE_LIBS,
- "Map %s is ready to be processed\n", state->mapname);
- tevent_req_done(req);
- tevent_req_post(req, actx->rctx->ev);
- return req;
- } else {
- DEBUG(SSSDBG_TRACE_LIBS,
- "Map %s was marked as nonexistent\n", state->mapname);
- tevent_req_error(req, ENOENT);
- tevent_req_post(req, actx->rctx->ev);
- return req;
- }
+ /* Lookup current results if available. */
+ state->enum_ctx = sss_ptr_hash_lookup(autofs_ctx->maps, mapname,
+ struct autofs_enum_ctx);
+ if (state->enum_ctx != NULL) {
+ if (state->enum_ctx->ready) {
+ ret = EOK;
+ goto done;
}
- /* Result object is still being constructed
- * Register for notification when it's ready
- */
- DEBUG(SSSDBG_TRACE_LIBS,
- "Map %s is being looked up, registering for notification\n",
- state->mapname);
- ret = autofs_setent_add_ref(state, state->map, req);
+ /* Map is still being created. We will watch the request. */
+ ret = setent_add_ref(state, &state->enum_ctx->notify_list, req);
if (ret != EOK) {
- goto fail;
- }
- /* Will return control below */
- } else if (ret == ENOENT) {
- DEBUG(SSSDBG_TRACE_LIBS,
- "Map %s needs to be looked up\n", state->mapname);
-
- state->map = talloc_zero(actx, struct autofs_map_ctx);
- if (!state->map) {
- ret = ENOMEM;
- goto fail;
- }
- dctx->map_ctx = state->map;
-
- state->map->mapname = talloc_strdup(state->map, state->mapname);
- if (!state->map->mapname) {
- talloc_free(state->map);
- ret = ENOMEM;
- goto fail;
+ DEBUG(SSSDBG_CRIT_FAILURE, "Unable to watch enumeration request "
+ "[%d]: %s\n", ret, sss_strerror(ret));
+ goto done;
}
- state->map->map_table = actx->maps;
- ret = autofs_setent_add_ref(state, state->map, req);
- if (ret != EOK) {
- talloc_free(state->map);
- goto fail;
- }
+ ret = EAGAIN;
+ goto done;
+ }
- ret = set_autofs_map(actx, state->map);
- if (ret != EOK) {
- talloc_free(state->map);
- goto fail;
- }
+ /* Map does not yet exist. Create the enumeration object and fetch data. */
+ state->enum_ctx = autofs_create_enumeration_context(state, autofs_ctx, mapname);
+ if (state->enum_ctx == NULL) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create enumeration context!\n");
+ ret = ENOMEM;
+ goto done;
+ }
- /* Perform lookup */
- lookup_ctx = talloc_zero(state->map, struct setautomntent_lookup_ctx);
- if (!lookup_ctx) {
- talloc_free(state->map);
- ret = ENOMEM;
- goto fail;
- }
+ subreq = cache_req_autofs_map_entries_send(mem_ctx, ev, autofs_ctx->rctx,
+ autofs_ctx->rctx->ncache,
+ 0, NULL, mapname);
+ if (subreq == NULL) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create subrequest!\n");
+ ret = ENOMEM;
+ goto done;
+ }
- /* Steal the dom_ctx onto the lookup_ctx so it doesn't go out of scope if
- * this request is canceled while other requests are in-progress.
- */
- lookup_ctx->dctx = talloc_steal(lookup_ctx, state->dctx);
- lookup_ctx->actx = actx;
- lookup_ctx->map = state->map;
- lookup_ctx->rctx = client->rctx;
- lookup_ctx->mapname =
- talloc_strdup(lookup_ctx, state->mapname);
- if (!lookup_ctx->mapname) {
- talloc_free(state->map);
- ret = ENOMEM;
- goto fail;
- }
+ tevent_req_set_callback(subreq, autofs_setent_done, req);
- ret = lookup_automntmap_step(lookup_ctx);
- if (ret == EAGAIN) {
- DEBUG(SSSDBG_TRACE_INTERNAL, "lookup_automntmap_step "
- "is refreshing the cache, re-entering the mainloop\n");
- return req;
- } else if (ret != EOK) {
- DEBUG(SSSDBG_CRIT_FAILURE, "Could not get data from cache\n");
- talloc_free(state->map);
- ret = ENOMEM;
- goto fail;
- }
+ ret = EAGAIN;
+done:
+ if (ret == EOK) {
tevent_req_done(req);
- tevent_req_post(req, cmdctx->cctx->ev);
- return req;
- } else {
- DEBUG(SSSDBG_CRIT_FAILURE,
- "Unexpected error from get_autofs_map [%d]: %s\n",
- ret, strerror(ret));
- goto fail;
+ tevent_req_post(req, ev);
+ } else if (ret != EAGAIN) {
+ tevent_req_error(req, ret);
+ tevent_req_post(req, ev);
}
return req;
-
-fail:
- tevent_req_error(req, ret);
- tevent_req_post(req, actx->rctx->ev);
- return req;
}
-static errno_t
-setautomntent_get_autofs_map(struct autofs_ctx *actx,
- char *mapname,
- struct autofs_map_ctx **map)
+static void autofs_setent_done(struct tevent_req *subreq)
{
+ struct autofs_setent_state *state;
+ struct cache_req_result *result;
+ struct tevent_req *req;
errno_t ret;
- if (strcmp(mapname, "auto.master") == 0) {
- /* Iterate over the hash and remove all maps */
- ret = autofs_orphan_maps(actx);
- if (ret != EOK) {
- DEBUG(SSSDBG_MINOR_FAILURE, "Could not remove existing maps from hash\n");
- }
- return ENOENT;
- }
+ req = tevent_req_callback_data(subreq, struct tevent_req);
+ state = tevent_req_data(req, struct autofs_setent_state);
- return get_autofs_map(actx, mapname, map);
-}
+ ret = cache_req_autofs_map_entries_recv(state, subreq, &result);
+ talloc_zfree(subreq);
-static errno_t
-lookup_automntmap_update_cache(struct setautomntent_lookup_ctx *lookup_ctx);
-
-static errno_t
-lookup_automntmap_step(struct setautomntent_lookup_ctx *lookup_ctx)
-{
- 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;
-
- /* Check each domain for this map name */
- while (dom) {
- 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);
- }
+ switch (ret) {
+ case EOK:
+ state->enum_ctx->found = true;
+ state->enum_ctx->result = talloc_steal(state->enum_ctx, result);
+ autofs_set_enumctx_lifetime(state->autofs_ctx, state->enum_ctx,
+ state->enum_ctx->result->domain->autofsmap_timeout);
+ break;
+ case ENOENT:
+ state->enum_ctx->found = false;
+ state->enum_ctx->result = NULL;
+ autofs_set_enumctx_lifetime(state->autofs_ctx, state->enum_ctx,
+ state->autofs_ctx->neg_timeout);
+ break;
+ default:
+ DEBUG(SSSDBG_OP_FAILURE, "Unable to get map data [%d]: %s\n",
+ ret, sss_strerror(ret));
- /* make sure to update the dctx if we changed domain */
- dctx->domain = dom;
+ setent_notify(&state->enum_ctx->notify_list, ret);
+ talloc_zfree(state->enum_ctx);
+ tevent_req_error(req, ret);
+ return;
+ }
- 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;
- }
+ state->enum_ctx->ready = true;
- /* Look into the cache */
- talloc_free(dctx->map);
- ret = sysdb_get_map_byname(dctx, dom, 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 = get_next_domain(dom, 0);
- continue;
- }
- else break;
- }
- }
+ /* Make the enumeration context disappear with maps table. */
+ talloc_steal(state->autofs_ctx->maps, state->enum_ctx);
- 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;
- }
+ setent_notify_done(&state->enum_ctx->notify_list);
+ tevent_req_done(req);
+ return;
+}
- 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;
- }
+static errno_t
+autofs_setent_recv(struct tevent_req *req,
+ struct autofs_enum_ctx **_enum_ctx)
+{
+ struct autofs_setent_state *state;
+ state = tevent_req_data(req, struct autofs_setent_state);
- 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;
- }
- }
+ TEVENT_REQ_RETURN_ON_ERROR(req);
- /* OK, the map is in cache and valid.
- * Let's get all members and return it
- */
- ret = sysdb_autofs_entries_by_map(map, dom, 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;
- }
+ *_enum_ctx = state->enum_ctx;
- map->map = talloc_steal(map, dctx->map);
+ 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;
- }
+static errno_t
+autofs_read_setautomntent_input(struct cli_ctx *cli_ctx,
+ const char **_mapname)
+{
+ struct cli_protocol *pctx;
+ uint8_t *body;
+ size_t blen;
- map = talloc_zero(lookup_ctx->actx, struct autofs_map_ctx);
- if (!map) {
- return ENOMEM;
- }
+ pctx = talloc_get_type(cli_ctx->protocol_ctx, struct cli_protocol);
- map->ready = true;
- map->found = false;
- map->map_table = lookup_ctx->actx->maps;
+ sss_packet_get_body(pctx->creq->in, &body, &blen);
- map->mapname = talloc_strdup(map, lookup_ctx->mapname);
- if (!map->mapname) {
- talloc_free(map);
- return ENOMEM;
+ /* if not terminated fail */
+ if (body[blen - 1] != '\0') {
+ return EINVAL;
}
- ret = set_autofs_map(lookup_ctx->actx, map);
- if (ret != EOK) {
- talloc_free(map);
- return ENOMEM;
+ /* If the body isn't valid UTF-8, fail */
+ if (!sss_utf8_check(body, blen - 1)) {
+ return EINVAL;
}
- set_autofs_map_lifetime(lookup_ctx->actx->neg_timeout, lookup_ctx, map);
+ *_mapname = (const char *)body;
- /* 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);
-
static errno_t
-lookup_automntmap_update_cache(struct setautomntent_lookup_ctx *lookup_ctx)
+autofs_write_setautomntent_output(struct cli_ctx *cli_ctx,
+ struct autofs_enum_ctx *enum_ctx)
{
+ struct cli_protocol *pctx;
+ uint8_t *body;
+ size_t blen;
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) {
- if (strcmp(lookup_ctx->mapname, "auto.master") != 0) {
- 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;
- }
- }
+ pctx = talloc_get_type(cli_ctx->protocol_ctx, struct cli_protocol);
- /* dont loop forever :-) */
- dctx->check_provider = false;
-
- /* 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
-
- req = sss_dp_get_autofs_send(lookup_ctx->cctx, lookup_ctx->rctx,
- lookup_ctx->dctx->domain, true,
- SSS_DP_AUTOFS, lookup_ctx->mapname);
- if (!req) {
- DEBUG(SSSDBG_CRIT_FAILURE,
- "Out of memory sending data provider request\n");
- ret = ENOMEM;
- goto error;
+ ret = sss_packet_new(pctx->creq, 0, sss_packet_get_cmd(pctx->creq->in),
+ &pctx->creq->out);
+ if (ret != EOK) {
+ return ret;
}
- cb_ctx = talloc_zero(lookup_ctx->dctx, struct dp_callback_ctx);
- if(!cb_ctx) {
- talloc_zfree(req);
- ret = ENOMEM;
- goto error;
+ if (!enum_ctx->found) {
+ DEBUG(SSSDBG_TRACE_FUNC, "Map was not found\n");
+ return sss_cmd_empty_packet(pctx->creq->out);
}
- 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;
-
- tevent_req_set_callback(req, autofs_dp_send_map_req_done, cb_ctx);
- return EAGAIN;
+ DEBUG(SSSDBG_TRACE_FUNC, "Map found\n");
-error:
- ret = autofs_cmd_send_error(lookup_ctx->dctx->cmd_ctx, ret);
+ ret = sss_packet_grow(pctx->creq->out, 2 * sizeof(uint32_t));
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)
-{
- 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;
-
- ret = sss_dp_get_autofs_recv(cb_ctx->mem_ctx, req,
- &err_maj, &err_min,
- &err_msg);
- talloc_free(req);
- if (ret != EOK) {
- DEBUG(SSSDBG_CRIT_FAILURE, "Fatal error, killing connection!\n");
- talloc_free(lookup_ctx->cctx);
- return;
- }
-
- cb_ctx->callback(err_maj, err_min, err_msg, cb_ctx->ptr);
-}
-
-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 (err_maj) {
- 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);
-
- /* Try to fall back to cache */
- ret = lookup_automntmap_step(lookup_ctx);
- if (ret == EOK) {
- /* We have cached results to return */
- autofs_setent_notify(lookup_ctx->map, ret);
- return;
- }
- /* Otherwise try the next domain */
- if (dctx->cmd_ctx->check_next
- && (dctx->domain = get_next_domain(dctx->domain, 0))) {
- dctx->check_provider = NEED_CHECK_PROVIDER(dctx->domain->provider);
- }
- }
+ sss_packet_get_body(pctx->creq->out, &body, &blen);
- ret = lookup_automntmap_step(lookup_ctx);
- if (ret != EOK) {
- if (ret == EAGAIN) {
- return;
- }
- }
+ /* Got some results */
+ SAFEALIGN_SETMEM_UINT32(body, 1, NULL);
- /* We have results to return */
- autofs_setent_notify(lookup_ctx->map, ret);
-}
+ /* Reserved padding */
+ SAFEALIGN_SETMEM_UINT32(body + sizeof(uint32_t), 0, NULL);
-static errno_t
-setautomntent_recv(struct tevent_req *req)
-{
- TEVENT_REQ_RETURN_ON_ERROR(req);
return EOK;
}
-static errno_t
-getautomntent_process(struct autofs_cmd_ctx *cmdctx,
- struct autofs_map_ctx *map,
- uint32_t cursor, uint32_t max_entries);
static void
-getautomntent_implicit_done(struct tevent_req *req);
-static errno_t
-fill_autofs_entry(struct ldb_message *entry, struct sss_packet *packet, size_t *rp);
-
+sss_autofs_cmd_setautomntent_done(struct tevent_req *req);
static int
-sss_autofs_cmd_getautomntent(struct cli_ctx *client)
+sss_autofs_cmd_setautomntent(struct cli_ctx *cli_ctx)
{
- struct autofs_cmd_ctx *cmdctx;
- struct autofs_map_ctx *map;
- struct autofs_ctx *actx;
- struct cli_protocol *pctx;
- uint8_t *body;
- size_t blen;
- errno_t ret;
- uint32_t namelen;
- size_t c = 0;
+ struct autofs_cmd_ctx *cmd_ctx;
+ struct autofs_ctx *autofs_ctx;
struct tevent_req *req;
+ errno_t ret;
- DEBUG(SSSDBG_TRACE_INTERNAL, "sss_autofs_cmd_getautomntent\n");
+ autofs_ctx = talloc_get_type(cli_ctx->rctx->pvt_ctx, struct autofs_ctx);
- cmdctx = talloc_zero(client, struct autofs_cmd_ctx);
- if (!cmdctx) {
+ cmd_ctx = talloc_zero(cli_ctx, struct autofs_cmd_ctx);
+ if (cmd_ctx == NULL) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create command context.\n");
return ENOMEM;
}
- cmdctx->cctx = client;
- actx = talloc_get_type(client->rctx->pvt_ctx, struct autofs_ctx);
- if (!actx) {
- DEBUG(SSSDBG_CRIT_FAILURE, "Missing autofs context\n");
- return EIO;
- }
+ cmd_ctx->cli_ctx = cli_ctx;
+ cmd_ctx->autofs_ctx = autofs_ctx;
- pctx = talloc_get_type(cmdctx->cctx->protocol_ctx, struct cli_protocol);
-
- /* get autofs map name and index to query */
- sss_packet_get_body(pctx->creq->in, &body, &blen);
-
- SAFEALIGN_COPY_UINT32_CHECK(&namelen, body+c, blen, &c);
-
- if (namelen == 0 || namelen > blen - c) {
- ret = EINVAL;
+ ret = autofs_read_setautomntent_input(cli_ctx, &cmd_ctx->mapname);
+ if (ret != EOK) {
goto done;
}
- cmdctx->mapname = (char *) body+c;
+ DEBUG(SSSDBG_TRACE_FUNC, "Creating enumeration context for %s\n",
+ cmd_ctx->mapname);
- /* if not null-terminated fail */
- if (cmdctx->mapname[namelen] != '\0') {
- ret = EINVAL;
+ req = autofs_setent_send(cli_ctx, cli_ctx->ev, autofs_ctx,
+ cmd_ctx->mapname);
+ if (req == NULL) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create tevent request\n");
+ ret = ENOMEM;
goto done;
}
- /* If the name isn't valid UTF-8, fail */
- if (!sss_utf8_check((const uint8_t *) cmdctx->mapname, namelen -1)) {
- ret = EINVAL;
- goto done;
- }
+ tevent_req_set_callback(req, sss_autofs_cmd_setautomntent_done, cmd_ctx);
- SAFEALIGN_COPY_UINT32_CHECK(&cmdctx->cursor, body+c+namelen+1, blen, &c);
- SAFEALIGN_COPY_UINT32_CHECK(&cmdctx->max_entries, body+c+namelen+1, blen, &c);
+ ret = EOK;
- DEBUG(SSSDBG_TRACE_FUNC,
- "Requested data of map %s cursor %d max entries %d\n",
- cmdctx->mapname, cmdctx->cursor, cmdctx->max_entries);
+done:
+ return autofs_cmd_done(cmd_ctx, ret);
+}
- ret = get_autofs_map(actx, cmdctx->mapname, &map);
- if (ret == ENOENT) {
- DEBUG(SSSDBG_TRACE_FUNC, "Performing implicit setautomntent\n");
- req = setautomntent_send(cmdctx, cmdctx->mapname, cmdctx);
- if (req == NULL) {
- DEBUG(SSSDBG_CRIT_FAILURE, "setautomntent_send failed\n");
- ret = EIO;
- goto done;
- }
+static void
+sss_autofs_cmd_setautomntent_done(struct tevent_req *req)
+{
+ struct autofs_enum_ctx *enum_ctx;
+ struct autofs_cmd_ctx *cmd_ctx;
+ errno_t ret;
- tevent_req_set_callback(req, getautomntent_implicit_done, cmdctx);
- ret = EOK;
- goto done;
- } else if (ret != EOK) {
- DEBUG(SSSDBG_OP_FAILURE,
- "An unexpected error occurred: [%d][%s]\n",
- ret, strerror(ret));
- goto done;
- }
+ cmd_ctx = tevent_req_callback_data(req, struct autofs_cmd_ctx);
- if (map->ready == false) {
- DEBUG(SSSDBG_TRACE_FUNC, "Performing implicit setautomntent\n");
- req = setautomntent_send(cmdctx, cmdctx->mapname, cmdctx);
- if (req == NULL) {
- DEBUG(SSSDBG_CRIT_FAILURE, "setautomntent_send failed\n");
- ret = EIO;
- goto done;
- }
+ ret = autofs_setent_recv(req, &enum_ctx);
+ talloc_zfree(req);
+ if (ret != EOK) {
+ autofs_cmd_done(cmd_ctx, ret);
+ return;
+ }
- tevent_req_set_callback(req, getautomntent_implicit_done, cmdctx);
- ret = EOK;
- goto done;
- } else if (map->found == false) {
- DEBUG(SSSDBG_TRACE_FUNC, "negative cache hit\n");
- ret = ENOENT;
- goto done;
+ ret = autofs_write_setautomntent_output(cmd_ctx->cli_ctx, enum_ctx);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create reply packet "
+ "[%d]: %s\n", ret, sss_strerror(ret));
+ autofs_cmd_done(cmd_ctx, ret);
+ return;
}
- DEBUG(SSSDBG_TRACE_INTERNAL,
- "returning entries for [%s]\n", map->mapname);
+ sss_cmd_done(cmd_ctx->cli_ctx, NULL);
+}
- ret = getautomntent_process(cmdctx, map, cmdctx->cursor, cmdctx->max_entries);
+static int
+sss_autofs_cmd_endautomntent(struct cli_ctx *client)
+{
+ struct cli_protocol *pctx;
+ errno_t ret;
-done:
- return autofs_cmd_done(cmdctx, ret);
+ DEBUG(SSSDBG_TRACE_FUNC, "endautomntent called\n");
+
+ pctx = talloc_get_type(client->protocol_ctx, struct cli_protocol);
+
+ /* create response packet */
+ ret = sss_packet_new(pctx->creq, 0,
+ sss_packet_get_cmd(pctx->creq->in),
+ &pctx->creq->out);
+
+ if (ret != EOK) {
+ return ret;
+ }
+
+ sss_cmd_done(client, NULL);
+ return EOK;
}
-static void
-getautomntent_implicit_done(struct tevent_req *req)
+static errno_t
+autofs_read_getautomntent_input(struct cli_ctx *cli_ctx,
+ const char **_mapname,
+ uint32_t *_cursor,
+ uint32_t *_max_entries)
{
- errno_t ret;
- struct autofs_map_ctx *map;
- struct autofs_cmd_ctx *cmdctx =
- tevent_req_callback_data(req, struct autofs_cmd_ctx);
- struct autofs_ctx *actx =
- talloc_get_type(cmdctx->cctx->rctx->pvt_ctx, struct autofs_ctx);
+ struct cli_protocol *pctx;
+ const char *mapname;
+ uint32_t namelen;
+ uint8_t *body;
+ size_t blen;
+ size_t c = 0;
- ret = setautomntent_recv(req);
- talloc_zfree(req);
- if (ret != EOK) {
- if (ret != ENOENT) {
- DEBUG(SSSDBG_CRIT_FAILURE, "setautomntent_recv failed\n");
- } else {
- DEBUG(SSSDBG_MINOR_FAILURE, "No such map\n");
- }
- goto done;
+ pctx = talloc_get_type(cli_ctx->protocol_ctx, struct cli_protocol);
+
+ sss_packet_get_body(pctx->creq->in, &body, &blen);
+
+ SAFEALIGN_COPY_UINT32_CHECK(&namelen, body+c, blen, &c);
+ if (namelen == 0 || namelen > blen - c) {
+ return EINVAL;
}
- ret = get_autofs_map(actx, cmdctx->mapname, &map);
- if (ret != EOK) {
- DEBUG(SSSDBG_CRIT_FAILURE,
- "Cannot get map after setautomntent succeeded?\n");
- goto done;
+ mapname = (const char *)body + c;
+
+ /* if not null-terminated fail */
+ if (mapname[namelen] != '\0') {
+ return EINVAL;
}
- if (map->ready == false) {
- DEBUG(SSSDBG_CRIT_FAILURE,
- "Map not ready after setautomntent succeeded\n");
- goto done;
+ /* If the name isn't valid UTF-8, fail */
+ if (!sss_utf8_check((const uint8_t *)mapname, namelen - 1)) {
+ return EINVAL;
}
- ret = getautomntent_process(cmdctx, map,
- cmdctx->cursor, cmdctx->max_entries);
-done:
- autofs_cmd_done(cmdctx, ret);
- return;
+ SAFEALIGN_COPY_UINT32_CHECK(_cursor, body + c + namelen + 1, blen, &c);
+ SAFEALIGN_COPY_UINT32_CHECK(_max_entries, body + c + namelen + 1, blen, &c);
+ *_mapname = mapname;
+
+ return EOK;
}
static errno_t
-getautomntent_process(struct autofs_cmd_ctx *cmdctx,
- struct autofs_map_ctx *map,
- uint32_t cursor, uint32_t max_entries)
+autofs_write_getautomntent_output(struct cli_ctx *cli_ctx,
+ struct autofs_enum_ctx *enum_ctx,
+ uint32_t cursor,
+ uint32_t max_entries)
{
struct cli_protocol *pctx;
- errno_t ret;
+ struct ldb_message **entries;
struct ldb_message *entry;
- size_t rp;
- uint32_t i, stop, left, nentries;
+ size_t count;
+ size_t num_entries;
uint8_t *body;
size_t blen;
+ size_t rp;
+ uint32_t i;
+ uint32_t stop;
+ uint32_t left;
+ errno_t ret;
- pctx = talloc_get_type(cmdctx->cctx->protocol_ctx, struct cli_protocol);
+ pctx = talloc_get_type(cli_ctx->protocol_ctx, struct cli_protocol);
- /* create response packet */
- ret = sss_packet_new(pctx->creq, 0,
- sss_packet_get_cmd(pctx->creq->in),
+ count = enum_ctx->found ? enum_ctx->result->count - 1 : 0;
+ entries = count > 0 ? enum_ctx->result->msgs + 1 : NULL;
+
+ ret = sss_packet_new(pctx->creq, 0, sss_packet_get_cmd(pctx->creq->in),
&pctx->creq->out);
if (ret != EOK) {
return ret;
}
- if (!map->map || !map->entries || !map->entries[0] ||
- cursor >= map->entry_count) {
- DEBUG(SSSDBG_MINOR_FAILURE, "No entries found\n");
- ret = sss_cmd_empty_packet(pctx->creq->out);
- if (ret != EOK) {
- return autofs_cmd_done(cmdctx, ret);
- }
- goto done;
+ if (!enum_ctx->found || count == 0 || cursor >= count) {
+ DEBUG(SSSDBG_TRACE_FUNC, "No entries was not found\n");
+ return sss_cmd_empty_packet(pctx->creq->out);
}
/* allocate memory for number of entries in the packet */
ret = sss_packet_grow(pctx->creq->out, sizeof(uint32_t));
if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE, "Cannot grow packet\n");
- goto done;
+ return ret;
}
- rp = sizeof(uint32_t); /* We'll write the number of entries here */
-
- left = map->entry_count - cursor;
+ rp = sizeof(uint32_t); /* We will first write the elements. */
+ left = count - cursor;
stop = max_entries < left ? max_entries : left;
- nentries = 0;
- for (i=0; i < stop; i++) {
- entry = map->entries[cursor];
+ num_entries = 0;
+ for (i = 0; i < stop; i++) {
+ entry = entries[cursor];
cursor++;
- ret = fill_autofs_entry(entry, pctx->creq->out, &rp);
+ ret = autofs_fill_entry(entry, pctx->creq->out, &rp);
if (ret != EOK) {
DEBUG(SSSDBG_MINOR_FAILURE,
"Cannot fill entry %d/%d, skipping\n", i, stop);
continue;
}
- nentries++;
+ num_entries++;
}
/* packet grows in fill_autofs_entry, body pointer may change,
@@ -1137,311 +605,212 @@ getautomntent_process(struct autofs_cmd_ctx *cmdctx,
sss_packet_get_body(pctx->creq->out, &body, &blen);
rp = 0;
- SAFEALIGN_SET_UINT32(&body[rp], nentries, &rp);
-
- ret = EOK;
-done:
- sss_packet_set_error(pctx->creq->out, ret);
- sss_cmd_done(cmdctx->cctx, cmdctx);
+ SAFEALIGN_SET_UINT32(&body[rp], num_entries, &rp);
return EOK;
}
-static errno_t
-fill_autofs_entry(struct ldb_message *entry, struct sss_packet *packet, size_t *rp)
+static void
+sss_autofs_cmd_getautomntent_done(struct tevent_req *req);
+
+static int
+sss_autofs_cmd_getautomntent(struct cli_ctx *cli_ctx)
{
+ struct autofs_cmd_ctx *cmd_ctx;
+ struct autofs_ctx *autofs_ctx;
+ struct tevent_req *req;
errno_t ret;
- const char *key;
- size_t keylen;
- const char *value;
- size_t valuelen;
- uint8_t *body;
- size_t blen;
- size_t len;
- key = ldb_msg_find_attr_as_string(entry, SYSDB_AUTOFS_ENTRY_KEY, NULL);
- value = ldb_msg_find_attr_as_string(entry, SYSDB_AUTOFS_ENTRY_VALUE, NULL);
- if (!key || !value) {
- DEBUG(SSSDBG_MINOR_FAILURE, "Incomplete entry\n");
- return EINVAL;
+ autofs_ctx = talloc_get_type(cli_ctx->rctx->pvt_ctx, struct autofs_ctx);
+
+ cmd_ctx = talloc_zero(cli_ctx, struct autofs_cmd_ctx);
+ if (cmd_ctx == NULL) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create command context.\n");
+ return ENOMEM;
}
- keylen = 1 + strlen(key);
- valuelen = 1 + strlen(value);
- len = sizeof(uint32_t) + sizeof(uint32_t) + keylen + sizeof(uint32_t) + valuelen;
+ cmd_ctx->cli_ctx = cli_ctx;
+ cmd_ctx->autofs_ctx = autofs_ctx;
- ret = sss_packet_grow(packet, len);
+ ret = autofs_read_getautomntent_input(cli_ctx, &cmd_ctx->mapname,
+ &cmd_ctx->cursor,
+ &cmd_ctx->max_entries);
if (ret != EOK) {
- DEBUG(SSSDBG_OP_FAILURE, "Cannot grow packet\n");
- return ret;
+ goto done;
}
- sss_packet_get_body(packet, &body, &blen);
-
- SAFEALIGN_SET_UINT32(&body[*rp], len, rp);
- SAFEALIGN_SET_UINT32(&body[*rp], keylen, rp);
+ DEBUG(SSSDBG_TRACE_FUNC, "Obtaining enumeration context for %s\n",
+ cmd_ctx->mapname);
- if (keylen == 1) {
- body[*rp] = '\0';
- } else {
- memcpy(&body[*rp], key, keylen);
+ req = autofs_setent_send(cli_ctx, cli_ctx->ev, autofs_ctx, cmd_ctx->mapname);
+ if (req == NULL) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create tevent request\n");
+ ret = ENOMEM;
+ goto done;
}
- *rp += keylen;
- SAFEALIGN_SET_UINT32(&body[*rp], valuelen, rp);
- if (valuelen == 1) {
- body[*rp] = '\0';
- } else {
- memcpy(&body[*rp], value, valuelen);
- }
- *rp += valuelen;
+ tevent_req_set_callback(req, sss_autofs_cmd_getautomntent_done, cmd_ctx);
- return EOK;
+ ret = EOK;
+
+done:
+ return autofs_cmd_done(cmd_ctx, ret);
}
-static errno_t
-getautomntbyname_process(struct autofs_cmd_ctx *cmdctx,
- struct autofs_map_ctx *map,
- const char *key);
static void
-getautomntbyname_implicit_done(struct tevent_req *req);
-
-static int
-sss_autofs_cmd_getautomntbyname(struct cli_ctx *client)
+sss_autofs_cmd_getautomntent_done(struct tevent_req *req)
{
+ struct autofs_enum_ctx *enum_ctx;
+ struct autofs_cmd_ctx *cmd_ctx;
errno_t ret;
- struct autofs_cmd_ctx *cmdctx;
- struct autofs_map_ctx *map;
- struct autofs_ctx *actx;
- struct cli_protocol *pctx;
- uint8_t *body;
- size_t blen;
- uint32_t namelen;
- uint32_t keylen;
- size_t c = 0;
- struct tevent_req *req;
- DEBUG(SSSDBG_TRACE_INTERNAL, "sss_autofs_cmd_getautomntbyname\n");
+ cmd_ctx = tevent_req_callback_data(req, struct autofs_cmd_ctx);
- cmdctx = talloc_zero(client, struct autofs_cmd_ctx);
- if (!cmdctx) {
- return ENOMEM;
+ ret = autofs_setent_recv(req, &enum_ctx);
+ talloc_zfree(req);
+ if (ret != EOK) {
+ autofs_cmd_done(cmd_ctx, ret);
+ return;
}
- cmdctx->cctx = client;
- actx = talloc_get_type(client->rctx->pvt_ctx, struct autofs_ctx);
- if (!actx) {
- DEBUG(SSSDBG_CRIT_FAILURE, "Missing autofs context\n");
- return EIO;
+ ret = autofs_write_getautomntent_output(cmd_ctx->cli_ctx, enum_ctx,
+ cmd_ctx->cursor,
+ cmd_ctx->max_entries);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create reply packet "
+ "[%d]: %s\n", ret, sss_strerror(ret));
+ autofs_cmd_done(cmd_ctx, ret);
+ return;
}
- pctx = talloc_get_type(cmdctx->cctx->protocol_ctx, struct cli_protocol);
+ sss_cmd_done(cmd_ctx->cli_ctx, NULL);
+}
- /* get autofs map name and index to query */
- sss_packet_get_body(pctx->creq->in, &body, &blen);
+static errno_t
+autofs_read_getautomntbyname_input(struct cli_ctx *cli_ctx,
+ const char **_mapname,
+ const char **_keyname)
+{
+ struct cli_protocol *pctx;
+ const char *mapname;
+ const char *keyname;
+ uint32_t namelen;
+ uint32_t keylen;
+ uint8_t *body;
+ size_t blen;
+ size_t c = 0;
- /* FIXME - split out a function to get string from <len><str>\0 */
- SAFEALIGN_COPY_UINT32_CHECK(&namelen, body+c, blen, &c);
+ pctx = talloc_get_type(cli_ctx->protocol_ctx, struct cli_protocol);
+
+ sss_packet_get_body(pctx->creq->in, &body, &blen);
+ /* Get map name. */
+ SAFEALIGN_COPY_UINT32_CHECK(&namelen, body + c, blen, &c);
if (namelen == 0 || namelen > blen - c) {
- ret = EINVAL;
- goto done;
+ return EINVAL;
}
- cmdctx->mapname = (char *) body+c;
+ mapname = (const char *) body + c;
/* if not null-terminated fail */
- if (cmdctx->mapname[namelen] != '\0') {
- ret = EINVAL;
- goto done;
+ if (mapname[namelen] != '\0') {
+ return EINVAL;
}
/* If the name isn't valid UTF-8, fail */
- if (!sss_utf8_check((const uint8_t *) cmdctx->mapname, namelen -1)) {
- ret = EINVAL;
- goto done;
+ if (!sss_utf8_check((const uint8_t *)mapname, namelen - 1)) {
+ return EINVAL;
}
c += namelen + 1;
- /* FIXME - split out a function to get string from <len><str>\0 */
- SAFEALIGN_COPY_UINT32_CHECK(&keylen, body+c, blen, &c);
-
+ /* Get key name. */
+ SAFEALIGN_COPY_UINT32_CHECK(&keylen, body + c, blen, &c);
if (keylen == 0 || keylen > blen - c) {
- ret = EINVAL;
- goto done;
+ return EINVAL;
}
- cmdctx->key = (char *) body+c;
+ keyname = (const char *) body + c;
/* if not null-terminated fail */
- if (cmdctx->key[keylen] != '\0') {
- ret = EINVAL;
- goto done;
+ if (keyname[keylen] != '\0') {
+ return EINVAL;
}
/* If the key isn't valid UTF-8, fail */
- if (!sss_utf8_check((const uint8_t *) cmdctx->key, keylen -1)) {
- ret = EINVAL;
- goto done;
- }
-
- DEBUG(SSSDBG_TRACE_FUNC,
- "Requested data of map %s key %s\n", cmdctx->mapname, cmdctx->key);
-
- ret = get_autofs_map(actx, cmdctx->mapname, &map);
- if (ret == ENOENT) {
- DEBUG(SSSDBG_TRACE_FUNC, "Performing implicit setautomntent\n");
- req = setautomntent_send(cmdctx, cmdctx->mapname, cmdctx);
- if (req == NULL) {
- DEBUG(SSSDBG_CRIT_FAILURE, "setautomntent_send failed\n");
- ret = EIO;
- goto done;
- }
-
- tevent_req_set_callback(req, getautomntbyname_implicit_done, cmdctx);
- ret = EOK;
- goto done;
- } else if (ret != EOK) {
- DEBUG(SSSDBG_OP_FAILURE,
- "An unexpected error occurred: [%d][%s]\n",
- ret, strerror(ret));
- goto done;
- }
-
- if (map->ready == false) {
- DEBUG(SSSDBG_TRACE_FUNC, "Performing implicit setautomntent\n");
- req = setautomntent_send(cmdctx, cmdctx->mapname, cmdctx);
- if (req == NULL) {
- DEBUG(SSSDBG_CRIT_FAILURE, "setautomntent_send failed\n");
- ret = EIO;
- goto done;
- }
-
- tevent_req_set_callback(req, getautomntbyname_implicit_done, cmdctx);
- ret = EOK;
- goto done;
- } else if (map->found == false) {
- DEBUG(SSSDBG_TRACE_FUNC, "negative cache hit\n");
- ret = ENOENT;
- goto done;
- }
-
- DEBUG(SSSDBG_TRACE_INTERNAL,
- "Looking up value for [%s] in [%s]\n", cmdctx->key, map->mapname);
-
- ret = getautomntbyname_process(cmdctx, map, cmdctx->key);
-
-done:
- return autofs_cmd_done(cmdctx, ret);
-}
-
-static void
-getautomntbyname_implicit_done(struct tevent_req *req)
-{
- errno_t ret;
- struct autofs_map_ctx *map;
- struct autofs_cmd_ctx *cmdctx =
- tevent_req_callback_data(req, struct autofs_cmd_ctx);
- struct autofs_ctx *actx =
- talloc_get_type(cmdctx->cctx->rctx->pvt_ctx, struct autofs_ctx);
-
- ret = setautomntent_recv(req);
- talloc_zfree(req);
- if (ret != EOK) {
- if (ret != ENOENT) {
- DEBUG(SSSDBG_CRIT_FAILURE, "setautomntent_recv failed\n");
- } else {
- DEBUG(SSSDBG_MINOR_FAILURE, "No such map\n");
- }
- goto done;
- }
-
- ret = get_autofs_map(actx, cmdctx->mapname, &map);
- if (ret != EOK) {
- DEBUG(SSSDBG_CRIT_FAILURE,
- "Cannot get map after setautomntent succeeded?\n");
- goto done;
+ if (!sss_utf8_check((const uint8_t *)keyname, keylen - 1)) {
+ return EINVAL;
}
- if (map->ready == false) {
- DEBUG(SSSDBG_CRIT_FAILURE,
- "Map not ready after setautomntent succeeded\n");
- goto done;
- }
+ *_mapname = mapname;
+ *_keyname = keyname;
- ret = getautomntbyname_process(cmdctx, map, cmdctx->key);
-done:
- autofs_cmd_done(cmdctx, ret);
- return;
+ return EOK;
}
static errno_t
-getautomntbyname_process(struct autofs_cmd_ctx *cmdctx,
- struct autofs_map_ctx *map,
- const char *key)
+autofs_write_getautomntbyname_output(struct cli_ctx *cli_ctx,
+ struct autofs_enum_ctx *enum_ctx,
+ const char *keyname)
{
struct cli_protocol *pctx;
- errno_t ret;
- size_t i;
- const char *k;
+ struct ldb_message **entries;
+ struct ldb_message *entry = NULL;
+ const char *entry_key;
const char *value;
- size_t valuelen;
+ size_t value_len;
size_t len;
+ size_t count;
uint8_t *body;
- size_t blen, rp;
+ size_t blen;
+ size_t rp;
+ size_t i;
+ errno_t ret;
- pctx = talloc_get_type(cmdctx->cctx->protocol_ctx, struct cli_protocol);
+ pctx = talloc_get_type(cli_ctx->protocol_ctx, struct cli_protocol);
- /* create response packet */
- ret = sss_packet_new(pctx->creq, 0,
- sss_packet_get_cmd(pctx->creq->in),
+ count = enum_ctx->found ? enum_ctx->result->count - 1 : 0;
+ entries = count > 0 ? enum_ctx->result->msgs + 1 : NULL;
+
+ ret = sss_packet_new(pctx->creq, 0, sss_packet_get_cmd(pctx->creq->in),
&pctx->creq->out);
if (ret != EOK) {
return ret;
}
- if (!map->map || !map->entries || !map->entries[0]) {
- DEBUG(SSSDBG_MINOR_FAILURE, "No entries found\n");
- ret = sss_cmd_empty_packet(pctx->creq->out);
- if (ret != EOK) {
- return autofs_cmd_done(cmdctx, ret);
- }
- goto done;
- }
-
- for (i=0; i < map->entry_count; i++) {
- k = ldb_msg_find_attr_as_string(map->entries[i],
- SYSDB_AUTOFS_ENTRY_KEY, NULL);
- if (!k) {
+ for (i = 0; i < count; i++) {
+ entry_key = ldb_msg_find_attr_as_string(entries[i],
+ SYSDB_AUTOFS_ENTRY_KEY,
+ NULL);
+ if (entry_key == NULL) {
DEBUG(SSSDBG_MINOR_FAILURE, "Skipping incomplete entry\n");
continue;
}
- if (strcmp(k, key) == 0) {
- DEBUG(SSSDBG_TRACE_INTERNAL, "Found key [%s]\n", key);
+ if (strcmp(entry_key, keyname) == 0) {
+ DEBUG(SSSDBG_TRACE_INTERNAL, "Found key [%s]\n", keyname);
+ entry = entries[i];
break;
}
}
- if (i >= map->entry_count) {
- DEBUG(SSSDBG_MINOR_FAILURE, "No key named [%s] found\n", key);
- ret = sss_cmd_empty_packet(pctx->creq->out);
- if (ret != EOK) {
- return autofs_cmd_done(cmdctx, ret);
- }
- goto done;
+ if (!enum_ctx->found || count == 0 || entry == NULL) {
+ DEBUG(SSSDBG_TRACE_FUNC, "Key [%s] was not found\n", keyname);
+ return sss_cmd_empty_packet(pctx->creq->out);
}
- value = ldb_msg_find_attr_as_string(map->entries[i],
- SYSDB_AUTOFS_ENTRY_VALUE, NULL);
+ value = ldb_msg_find_attr_as_string(entry, SYSDB_AUTOFS_ENTRY_VALUE, NULL);
+ if (value == NULL) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "No entry value found in [%s]\n", keyname);
+ return EINVAL;
+ }
- valuelen = 1 + strlen(value);
- len = sizeof(uint32_t) + sizeof(uint32_t) + valuelen;
+ value_len = 1 + strlen(value);
+ len = sizeof(uint32_t) + sizeof(uint32_t) + value_len;
ret = sss_packet_grow(pctx->creq->out, len);
if (ret != EOK) {
- goto done;
+ return ret;
}
sss_packet_get_body(pctx->creq->out, &body, &blen);
@@ -1449,43 +818,88 @@ getautomntbyname_process(struct autofs_cmd_ctx *cmdctx,
rp = 0;
SAFEALIGN_SET_UINT32(&body[rp], len, &rp);
- SAFEALIGN_SET_UINT32(&body[rp], valuelen, &rp);
- if (valuelen == 1) {
+ SAFEALIGN_SET_UINT32(&body[rp], value_len, &rp);
+ if (value_len == 1) {
body[rp] = '\0';
} else {
- memcpy(&body[rp], value, valuelen);
+ memcpy(&body[rp], value, value_len);
}
- rp += valuelen;
-
- ret = EOK;
-done:
- sss_packet_set_error(pctx->creq->out, ret);
- sss_cmd_done(cmdctx->cctx, cmdctx);
return EOK;
}
+static void
+sss_autofs_cmd_getautomntbyname_done(struct tevent_req *req);
+
static int
-sss_autofs_cmd_endautomntent(struct cli_ctx *client)
+sss_autofs_cmd_getautomntbyname(struct cli_ctx *cli_ctx)
{
- struct cli_protocol *pctx;
+ struct autofs_cmd_ctx *cmd_ctx;
+ struct autofs_ctx *autofs_ctx;
+ struct tevent_req *req;
errno_t ret;
- DEBUG(SSSDBG_TRACE_FUNC, "endautomntent called\n");
+ autofs_ctx = talloc_get_type(cli_ctx->rctx->pvt_ctx, struct autofs_ctx);
- pctx = talloc_get_type(client->protocol_ctx, struct cli_protocol);
+ cmd_ctx = talloc_zero(cli_ctx, struct autofs_cmd_ctx);
+ if (cmd_ctx == NULL) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create command context.\n");
+ return ENOMEM;
+ }
- /* create response packet */
- ret = sss_packet_new(pctx->creq, 0,
- sss_packet_get_cmd(pctx->creq->in),
- &pctx->creq->out);
+ cmd_ctx->cli_ctx = cli_ctx;
+ cmd_ctx->autofs_ctx = autofs_ctx;
+ ret = autofs_read_getautomntbyname_input(cli_ctx, &cmd_ctx->mapname,
+ &cmd_ctx->keyname);
if (ret != EOK) {
- return ret;
+ goto done;
}
- sss_cmd_done(client, NULL);
- return EOK;
+ DEBUG(SSSDBG_TRACE_FUNC, "Obtaining enumeration context for %s\n",
+ cmd_ctx->mapname);
+
+ req = autofs_setent_send(cli_ctx, cli_ctx->ev, autofs_ctx, cmd_ctx->mapname);
+ if (req == NULL) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create tevent request\n");
+ ret = ENOMEM;
+ goto done;
+ }
+
+ tevent_req_set_callback(req, sss_autofs_cmd_getautomntbyname_done, cmd_ctx);
+
+ ret = EOK;
+
+done:
+ return autofs_cmd_done(cmd_ctx, ret);
+}
+
+static void
+sss_autofs_cmd_getautomntbyname_done(struct tevent_req *req)
+{
+ struct autofs_enum_ctx *enum_ctx;
+ struct autofs_cmd_ctx *cmd_ctx;
+ errno_t ret;
+
+ cmd_ctx = tevent_req_callback_data(req, struct autofs_cmd_ctx);
+
+ ret = autofs_setent_recv(req, &enum_ctx);
+ talloc_zfree(req);
+ if (ret != EOK) {
+ autofs_cmd_done(cmd_ctx, ret);
+ return;
+ }
+
+ ret = autofs_write_getautomntbyname_output(cmd_ctx->cli_ctx, enum_ctx,
+ cmd_ctx->keyname);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create reply packet "
+ "[%d]: %s\n", ret, sss_strerror(ret));
+ autofs_cmd_done(cmd_ctx, ret);
+ return;
+ }
+
+ sss_cmd_done(cmd_ctx->cli_ctx, NULL);
}
struct cli_protocol_version *register_cli_protocol_version(void)
@@ -1518,10 +932,5 @@ int autofs_connection_setup(struct cli_ctx *cctx)
ret = sss_connection_setup(cctx);
if (ret != EOK) return ret;
- cctx->state_ctx = talloc_zero(cctx, struct autofs_state_ctx);
- if (!cctx->state_ctx) {
- return ENOMEM;
- }
-
return EOK;
}
--
2.20.1