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