From 1fc3e4a14eaec7bdaec5901f8bb213a718fc7bc1 Mon Sep 17 00:00:00 2001 From: Pavel Březina Date: Sep 16 2019 08:33:30 +0000 Subject: cache_req: add autofs map by name plugin We will use the current data provider call that downloads all map entries but we will replace it later when new call is available. Resolves: https://pagure.io/SSSD/sssd/issue/2607 Reviewed-by: Tomáš Halman --- diff --git a/Makefile.am b/Makefile.am index 8d2b0a0..80fc3a9 100644 --- a/Makefile.am +++ b/Makefile.am @@ -564,6 +564,7 @@ SSSD_CACHE_REQ_OBJ = \ src/responder/common/cache_req/plugins/cache_req_netgroup_by_name.c \ src/responder/common/cache_req/plugins/cache_req_host_by_name.c \ src/responder/common/cache_req/plugins/cache_req_autofs_map_entries.c \ + src/responder/common/cache_req/plugins/cache_req_autofs_map_by_name.c \ $(NULL) SSSD_RESPONDER_IFACE_OBJ = \ diff --git a/src/responder/common/cache_req/cache_req.c b/src/responder/common/cache_req/cache_req.c index 2ce9dec..75f396a 100644 --- a/src/responder/common/cache_req/cache_req.c +++ b/src/responder/common/cache_req/cache_req.c @@ -62,6 +62,7 @@ cache_req_get_plugin(enum cache_req_type type) &cache_req_host_by_name, &cache_req_autofs_map_entries, + &cache_req_autofs_map_by_name }; if (type >= CACHE_REQ_SENTINEL) { diff --git a/src/responder/common/cache_req/cache_req.h b/src/responder/common/cache_req/cache_req.h index 0c214a4..66a1344 100644 --- a/src/responder/common/cache_req/cache_req.h +++ b/src/responder/common/cache_req/cache_req.h @@ -55,6 +55,7 @@ enum cache_req_type { CACHE_REQ_HOST_BY_NAME, CACHE_REQ_AUTOFS_MAP_ENTRIES, + CACHE_REQ_AUTOFS_MAP_BY_NAME, CACHE_REQ_SENTINEL }; @@ -444,4 +445,16 @@ cache_req_autofs_map_entries_send(TALLOC_CTX *mem_ctx, #define cache_req_autofs_map_entries_recv(mem_ctx, req, _result) \ cache_req_single_domain_recv(mem_ctx, req, _result) +struct tevent_req * +cache_req_autofs_map_by_name_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct resp_ctx *rctx, + struct sss_nc_ctx *ncache, + int cache_refresh_percent, + const char *domain, + const char *name); + +#define cache_req_autofs_map_by_name_recv(mem_ctx, req, _result) \ + cache_req_single_domain_recv(mem_ctx, req, _result) + #endif /* _CACHE_REQ_H_ */ diff --git a/src/responder/common/cache_req/cache_req_data.c b/src/responder/common/cache_req/cache_req_data.c index e8174da..a764557 100644 --- a/src/responder/common/cache_req/cache_req_data.c +++ b/src/responder/common/cache_req/cache_req_data.c @@ -95,6 +95,7 @@ cache_req_data_create(TALLOC_CTX *mem_ctx, case CACHE_REQ_NETGROUP_BY_NAME: case CACHE_REQ_OBJECT_BY_NAME: case CACHE_REQ_AUTOFS_MAP_ENTRIES: + case CACHE_REQ_AUTOFS_MAP_BY_NAME: if (input->name.input == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Bug: name cannot be NULL!\n"); ret = ERR_INTERNAL; diff --git a/src/responder/common/cache_req/cache_req_plugin.h b/src/responder/common/cache_req/cache_req_plugin.h index 1b228d1..d9a5474 100644 --- a/src/responder/common/cache_req/cache_req_plugin.h +++ b/src/responder/common/cache_req/cache_req_plugin.h @@ -316,5 +316,6 @@ extern const struct cache_req_plugin cache_req_svc_by_port; extern const struct cache_req_plugin cache_req_netgroup_by_name; extern const struct cache_req_plugin cache_req_host_by_name; extern const struct cache_req_plugin cache_req_autofs_map_entries; +extern const struct cache_req_plugin cache_req_autofs_map_by_name; #endif /* _CACHE_REQ_PLUGIN_H_ */ diff --git a/src/responder/common/cache_req/plugins/cache_req_autofs_map_by_name.c b/src/responder/common/cache_req/plugins/cache_req_autofs_map_by_name.c new file mode 100644 index 0000000..5260443 --- /dev/null +++ b/src/responder/common/cache_req/plugins/cache_req_autofs_map_by_name.c @@ -0,0 +1,155 @@ +/* + Authors: + Pavel Březina + + Copyright (C) 2019 Red Hat + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include +#include + +#include "db/sysdb.h" +#include "db/sysdb_autofs.h" +#include "util/util.h" +#include "providers/data_provider.h" +#include "responder/common/cache_req/cache_req_plugin.h" + +static const char * +cache_req_autofs_map_by_name_create_debug_name(TALLOC_CTX *mem_ctx, + struct cache_req_data *data, + struct sss_domain_info *domain) +{ + return talloc_strdup(mem_ctx, data->name.name); +} + +static errno_t +cache_req_autofs_map_by_name_lookup(TALLOC_CTX *mem_ctx, + struct cache_req *cr, + struct cache_req_data *data, + struct sss_domain_info *domain, + struct ldb_result **_result) +{ + struct ldb_message *map; + struct ldb_result *result; + errno_t ret; + + ret = sysdb_get_map_byname(mem_ctx, domain, data->name.name, &map); + if (ret != EOK) { + return ret; + } + + result = cache_req_create_ldb_result_from_msg(mem_ctx, map); + if (result == NULL) { + talloc_free(map); + return ENOMEM; + } + + *_result = talloc_steal(mem_ctx, result); + return EOK; +} + +static struct tevent_req * +cache_req_autofs_map_by_name_dp_send(TALLOC_CTX *mem_ctx, + struct cache_req *cr, + struct cache_req_data *data, + struct sss_domain_info *domain, + struct ldb_result *result) +{ + struct be_conn *be_conn; + errno_t ret; + + ret = sss_dp_get_domain_conn(cr->rctx, domain->conn_name, &be_conn); + if (ret != EOK) { + DEBUG(SSSDBG_CRIT_FAILURE, + "BUG: The Data Provider connection for %s is not available!\n", + domain->name); + return NULL; + } + + return sbus_call_dp_dp_autofsHandler_send(mem_ctx, be_conn->conn, + be_conn->bus_name, SSS_BUS_PATH, + DP_FAST_REPLY, data->name.name); +} + +bool +cache_req_autofs_map_by_name_dp_recv(struct tevent_req *subreq, + struct cache_req *cr) +{ + const char *err_msg; + uint16_t err_maj; + uint32_t err_min; + errno_t ret; + bool bret; + + /* Use subreq as memory context so err_msg is freed with it. */ + ret = sbus_call_dp_dp_autofsHandler_recv(subreq, subreq, &err_maj, + &err_min, &err_msg); + bret = cache_req_common_process_dp_reply(cr, ret, err_maj, + err_min, err_msg); + + return bret; +} + +const struct cache_req_plugin cache_req_autofs_map_by_name = { + .name = "Get autofs map", + .attr_expiration = SYSDB_CACHE_EXPIRE, + .parse_name = true, + .ignore_default_domain = true, + .bypass_cache = false, + .only_one_result = false, + .search_all_domains = false, + .require_enumeration = false, + .allow_missing_fqn = true, + .allow_switch_to_upn = false, + .upn_equivalent = CACHE_REQ_SENTINEL, + .get_next_domain_flags = 0, + + .is_well_known_fn = NULL, + .prepare_domain_data_fn = NULL, + .create_debug_name_fn = cache_req_autofs_map_by_name_create_debug_name, + .global_ncache_add_fn = NULL, + .ncache_check_fn = NULL, + .ncache_add_fn = NULL, + .ncache_filter_fn = NULL, + .lookup_fn = cache_req_autofs_map_by_name_lookup, + .dp_send_fn = cache_req_autofs_map_by_name_dp_send, + .dp_recv_fn = cache_req_autofs_map_by_name_dp_recv, + .dp_get_domain_check_fn = NULL, + .dp_get_domain_send_fn = NULL, + .dp_get_domain_recv_fn = NULL, +}; + +struct tevent_req * +cache_req_autofs_map_by_name_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct resp_ctx *rctx, + struct sss_nc_ctx *ncache, + int cache_refresh_percent, + const char *domain, + const char *name) +{ + struct cache_req_data *data; + + data = cache_req_data_name(mem_ctx, CACHE_REQ_AUTOFS_MAP_BY_NAME, name); + if (data == NULL) { + return NULL; + } + + return cache_req_steal_data_and_send(mem_ctx, ev, rctx, ncache, + cache_refresh_percent, + CACHE_REQ_POSIX_DOM, domain, + data); +} diff --git a/src/tests/cwrap/Makefile.am b/src/tests/cwrap/Makefile.am index 4e6cbf4..2e50d8f 100644 --- a/src/tests/cwrap/Makefile.am +++ b/src/tests/cwrap/Makefile.am @@ -65,6 +65,7 @@ SSSD_CACHE_REQ_OBJ = \ ../../../src/responder/common/cache_req/plugins/cache_req_netgroup_by_name.c \ ../../../src/responder/common/cache_req/plugins/cache_req_host_by_name.c \ ../../../src/responder/common/cache_req/plugins/cache_req_autofs_map_entries.c \ + ../../../src/responder/common/cache_req/plugins/cache_req_autofs_map_by_name.c \ $(NULL) SSSD_RESPONDER_IFACE_OBJ = \