From ac712654f07be9e9c05156c89af54eac483d75d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pavel=20B=C5=99ezina?= Date: Mon, 2 Sep 2019 13:05:14 +0200 Subject: [PATCH 88/90] autofs: always refresh auto.master MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reviewed-by: Tomáš Halman --- src/responder/autofs/autofs_private.h | 10 ++++- src/responder/autofs/autofssrv.c | 25 ++++++++---- src/responder/autofs/autofssrv_cmd.c | 56 ++++++++++++++++++++++----- 3 files changed, 74 insertions(+), 17 deletions(-) diff --git a/src/responder/autofs/autofs_private.h b/src/responder/autofs/autofs_private.h index 3be25d4d9..175a7768f 100644 --- a/src/responder/autofs/autofs_private.h +++ b/src/responder/autofs/autofs_private.h @@ -21,6 +21,8 @@ #ifndef _AUTOFSSRV_PRIVATE_H_ #define _AUTOFSSRV_PRIVATE_H_ +#include + #include "responder/common/responder.h" #include "responder/common/responder_sbus.h" #include "responder/common/cache_req/cache_req.h" @@ -55,6 +57,12 @@ struct autofs_enum_ctx { /* False if the result is being created. */ bool ready; + /* Enumeration context key. */ + const char *key; + + /* Hash table that contains this enumeration context. */ + hash_table_t *table; + /* Requests that awaits the data. */ struct setent_req_list *notify_list; }; @@ -62,6 +70,6 @@ struct autofs_enum_ctx { struct sss_cmd_table *get_autofs_cmds(void); int autofs_connection_setup(struct cli_ctx *cctx); -errno_t autofs_orphan_maps(struct autofs_ctx *actx); +void autofs_orphan_maps(struct autofs_ctx *actx); #endif /* _AUTOFSSRV_PRIVATE_H_ */ diff --git a/src/responder/autofs/autofssrv.c b/src/responder/autofs/autofssrv.c index 309ed76b1..922da5fd4 100644 --- a/src/responder/autofs/autofssrv.c +++ b/src/responder/autofs/autofssrv.c @@ -85,17 +85,26 @@ static int autofs_clean_hash_table(struct sbus_request *dbus_req, void *data) struct resp_ctx *rctx = talloc_get_type(data, struct resp_ctx); struct autofs_ctx *actx = talloc_get_type(rctx->pvt_ctx, struct autofs_ctx); - errno_t ret; - ret = autofs_orphan_maps(actx); - if (ret != EOK) { - DEBUG(SSSDBG_OP_FAILURE, "Could not invalidate maps\n"); - return ret; - } + autofs_orphan_maps(actx); return sbus_request_return_and_finish(dbus_req, DBUS_TYPE_INVALID); } +static void +autofs_maps_delete_cb(hash_entry_t *item, + hash_destroy_enum deltype, + void *pvt) +{ + struct autofs_ctx *autofs_ctx; + struct autofs_enum_ctx *enum_ctx; + + autofs_ctx = talloc_get_type(pvt, struct autofs_ctx); + + enum_ctx = sss_ptr_get_value(&item->value, struct autofs_enum_ctx); + talloc_unlink(autofs_ctx->maps, enum_ctx); +} + static int autofs_process_init(TALLOC_CTX *mem_ctx, struct tevent_context *ev, @@ -158,7 +167,9 @@ autofs_process_init(TALLOC_CTX *mem_ctx, } /* Create the lookup table for setautomntent results */ - autofs_ctx->maps = sss_ptr_hash_create(autofs_ctx, NULL, NULL); + autofs_ctx->maps = sss_ptr_hash_create(autofs_ctx, + autofs_maps_delete_cb, + autofs_ctx); if (autofs_ctx->maps == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to initialize automount maps hash table\n"); diff --git a/src/responder/autofs/autofssrv_cmd.c b/src/responder/autofs/autofssrv_cmd.c index d413f8570..71938399e 100644 --- a/src/responder/autofs/autofssrv_cmd.c +++ b/src/responder/autofs/autofssrv_cmd.c @@ -131,12 +131,12 @@ autofs_fill_entry(struct ldb_message *entry, struct sss_packet *packet, size_t * return EOK; } -errno_t +void autofs_orphan_maps(struct autofs_ctx *autofs_ctx) { - sss_ptr_hash_delete_all(autofs_ctx->maps, true); - - return EOK; + /* It will automatically decrease the refcount of enum_ctx through + * delete callback. */ + sss_ptr_hash_delete_all(autofs_ctx->maps, false); } static void @@ -149,8 +149,8 @@ autofs_enumctx_lifetime_timeout(struct tevent_context *ev, enum_ctx = talloc_get_type(pvt, struct autofs_enum_ctx); - /* Free the context. It will be automatically removed from the hash table. */ - talloc_free(enum_ctx); + /* Remove it from the table. It will automatically decrease the refcount. */ + sss_ptr_hash_delete(enum_ctx->table, enum_ctx->key, false); } static void @@ -185,6 +185,13 @@ autofs_create_enumeration_context(TALLOC_CTX *mem_ctx, } enum_ctx->ready = false; + enum_ctx->table = autofs_ctx->maps; + + enum_ctx->key = talloc_strdup(enum_ctx, mapname); + if (enum_ctx->key == NULL) { + talloc_free(enum_ctx); + return NULL; + } ret = sss_ptr_hash_add(autofs_ctx->maps, mapname, enum_ctx, struct autofs_enum_ctx); @@ -196,6 +203,34 @@ autofs_create_enumeration_context(TALLOC_CTX *mem_ctx, return enum_ctx; } +static void +autofs_orphan_master_map(struct autofs_ctx *autofs_ctx, + const char *mapname) +{ + struct sss_domain_info *dom; + errno_t ret; + + if (strcmp(mapname, "auto.master") != 0) { + return; + } + + DEBUG(SSSDBG_TRACE_FUNC, "Invalidating master map\n"); + + /* Remove and invalidate all maps. */ + autofs_orphan_maps(autofs_ctx); + + DEBUG(SSSDBG_TRACE_FUNC, "Invalidating autofs maps\n"); + for (dom = autofs_ctx->rctx->domains; + dom != NULL; + dom = get_next_domain(dom, SSS_GND_DESCEND)) { + ret = sysdb_invalidate_autofs_maps(dom); + if (ret != EOK) { + DEBUG(SSSDBG_MINOR_FAILURE, "Unable to invalidate maps in " + "%s [%d]: %s\n", dom->name, ret, sss_strerror(ret)); + } + } +} + struct autofs_setent_state { struct autofs_ctx *autofs_ctx; struct autofs_enum_ctx *enum_ctx; @@ -323,7 +358,8 @@ static void autofs_setent_done(struct tevent_req *subreq) } static errno_t -autofs_setent_recv(struct tevent_req *req, +autofs_setent_recv(TALLOC_CTX *mem_ctx, + struct tevent_req *req, struct autofs_enum_ctx **_enum_ctx) { struct autofs_setent_state *state; @@ -331,7 +367,7 @@ autofs_setent_recv(struct tevent_req *req, TEVENT_REQ_RETURN_ON_ERROR(req); - *_enum_ctx = state->enum_ctx; + *_enum_ctx = talloc_reference(mem_ctx, state->enum_ctx); return EOK; } @@ -430,6 +466,8 @@ sss_autofs_cmd_setautomntent(struct cli_ctx *cli_ctx) goto done; } + autofs_orphan_master_map(autofs_ctx, cmd_ctx->mapname); + DEBUG(SSSDBG_TRACE_FUNC, "Obtaining autofs map %s\n", cmd_ctx->mapname); @@ -668,7 +706,7 @@ sss_autofs_cmd_getautomntent_done(struct tevent_req *req) cmd_ctx = tevent_req_callback_data(req, struct autofs_cmd_ctx); - ret = autofs_setent_recv(req, &enum_ctx); + ret = autofs_setent_recv(cmd_ctx, req, &enum_ctx); talloc_zfree(req); if (ret != EOK) { autofs_cmd_done(cmd_ctx, ret); -- 2.20.1