From da9bc9b157a5ddc9a70147bf8df94e2bebb05c07 Mon Sep 17 00:00:00 2001 From: Petr Spacek Date: Mon, 15 Aug 2016 19:18:11 +0200 Subject: [PATCH] BIND 9.11: Port to new dyndb API. This is first step which allows the plugin to run. It requires configuration in format dyndb { {option1 value} {option2 value} }; This will be improved in another patch. --- README | 28 +++--- configure.ac | 2 +- src/Makefile.am | 2 - src/ldap_driver.c | 135 ++++++++++++++++++++--------- src/ldap_driver.h | 8 +- src/ldap_helper.c | 98 ++++++++++----------- src/ldap_helper.h | 6 +- src/settings.c | 6 +- src/settings.h | 2 +- src/syncrepl.c | 28 +++--- src/syncrepl.h | 2 +- src/types.h | 2 +- src/zone_manager.c | 205 -------------------------------------------- src/zone_manager.h | 29 ------- src/zone_register.c | 11 +-- 15 files changed, 180 insertions(+), 384 deletions(-) delete mode 100644 src/zone_manager.c delete mode 100644 src/zone_manager.h diff --git a/README b/README index 2fd09b5..e90fc26 100644 --- a/README +++ b/README @@ -2,15 +2,9 @@ =============== The dynamic LDAP back-end is a plug-in for BIND that provides an LDAP -database back-end capabilities. For now, it requires that BIND is patched -to support dynamic loading of database back-ends. You can get a patch -for your version here: +database back-end capabilities. It requires dyndb interface which is present +in BIND versions >= 9.11.0rc1. - https://github.com/pspacek/bind-dynamic_db - -Hopefully, the patch will once be included in the official BIND release. - -BIND >= 9.9.0 is required. 2. Features =========== @@ -309,19 +303,17 @@ Attributes: 5. Configuration ================ -To configure dynamic loading of back-end, you must put a "dynamic-db" +To configure dynamic loading of back-end, you must put a "dyndb" clause into your named.conf. The clause must then be followed by a -string denoting the name. The name is not that much important, it is -passed to the plug-in and might be used for example, for logging -purposes. Following after that is a set of options enclosed between -curly brackets. +string denoting the name of the instance and path to dyndb library. -The most important option here is "library". It names a shared object -file that will be opened and loaded. The "arg" option specifies a string -that is passed directly to the plugin. You can specify multiple "arg" -options. The LDAP back-end follows the convention that the first word of -this string is the name of the setting and the rest is the value. +The name is not that much important, it is passed to the plug-in +and is used for logging purposes and for naming working directories. +Library path must point to a shared object file that will be opened and loaded. + +Name and library path have to be followed by set of options enclosed between +curly brackets. 5.1 Configuration options ------------------------- diff --git a/configure.ac b/configure.ac index 9b26058..0311560 100644 --- a/configure.ac +++ b/configure.ac @@ -3,7 +3,7 @@ AC_INIT([bind-dyndb-ldap], [10.1], [freeipa-devel@redhat.com]) AM_INIT_AUTOMAKE([-Wall foreign dist-bzip2]) -AC_CONFIG_SRCDIR([src/zone_manager.h]) +AC_CONFIG_SRCDIR([src/ldap_driver.c]) AC_CONFIG_HEADERS([config.h]) AC_CONFIG_MACRO_DIR([m4]) diff --git a/src/Makefile.am b/src/Makefile.am index c5de9ce..e1e3968 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -26,7 +26,6 @@ HDRS = \ types.h \ util.h \ zone.h \ - zone_manager.h \ zone_register.h ldap_la_SOURCES = \ @@ -53,7 +52,6 @@ ldap_la_SOURCES = \ syncrepl.c \ str.c \ zone.c \ - zone_manager.c \ zone_register.c ldap_la_CFLAGS = -Wall -Wextra @WERROR@ -std=gnu99 -O2 diff --git a/src/ldap_driver.c b/src/ldap_driver.c index 5d67cda..7cf877b 100644 --- a/src/ldap_driver.c +++ b/src/ldap_driver.c @@ -9,13 +9,17 @@ #endif #include +#include +#include +#include #include +#include #include #include #include #include -#include +#include #include #include #include @@ -29,12 +33,12 @@ #include /* For memcpy */ +#include "bindcfg.h" #include "ldap_driver.h" #include "ldap_helper.h" #include "ldap_convert.h" #include "log.h" #include "util.h" -#include "zone_manager.h" #include "zone_register.h" #ifdef HAVE_VISIBILITY @@ -918,18 +922,17 @@ ldapdb_associate(isc_mem_t *mctx, dns_name_t *name, dns_dbtype_t type, void *driverarg, dns_db_t **dbp) { isc_result_t result; - ldap_instance_t *ldap_inst = NULL; + ldap_instance_t *ldap_inst = driverarg; zone_register_t *zr = NULL; - UNUSED(driverarg); /* Currently we don't need any data */ - REQUIRE(ISCAPI_MCTX_VALID(mctx)); - REQUIRE(argc == LDAP_DB_ARGC); REQUIRE(type == LDAP_DB_TYPE); REQUIRE(rdclass == LDAP_DB_RDATACLASS); + REQUIRE(argc == 0); + UNUSED(argv); + REQUIRE(driverarg != NULL); REQUIRE(dbp != NULL && *dbp == NULL); - CHECK(manager_get_ldap_instance(argv[0], &ldap_inst)); zr = ldap_instance_getzr(ldap_inst); if (zr == NULL) CLEANUP_WITH(ISC_R_NOTFOUND); @@ -942,19 +945,16 @@ ldapdb_associate(isc_mem_t *mctx, dns_name_t *name, dns_dbtype_t type, isc_result_t ldapdb_create(isc_mem_t *mctx, dns_name_t *name, dns_dbtype_t type, - dns_rdataclass_t rdclass, unsigned int argc, char *argv[], - void *driverarg, dns_db_t **dbp) + dns_rdataclass_t rdclass, void *driverarg, dns_db_t **dbp) { ldapdb_t *ldapdb = NULL; isc_result_t result; isc_boolean_t lock_ready = ISC_FALSE; - UNUSED(driverarg); /* Currently we don't need any data */ - /* Database instance name. */ - REQUIRE(argc == LDAP_DB_ARGC); REQUIRE(type == LDAP_DB_TYPE); REQUIRE(rdclass == LDAP_DB_RDATACLASS); + REQUIRE(driverarg != NULL); REQUIRE(dbp != NULL && *dbp == NULL); CHECKED_MEM_GET_PTR(mctx, ldapdb); @@ -976,7 +976,7 @@ ldapdb_create(isc_mem_t *mctx, dns_name_t *name, dns_dbtype_t type, CHECK(dns_name_dupwithoffsets(name, mctx, &ldapdb->common.origin)); CHECK(isc_refcount_init(&ldapdb->refs, 1)); - CHECK(manager_get_ldap_instance(argv[0], &ldapdb->ldap_inst)); + ldapdb->ldap_inst = driverarg; CHECK(dns_db_create(mctx, "rbt", name, dns_dbtype_zone, dns_rdataclass_in, 0, NULL, &ldapdb->rbtdb)); @@ -1000,50 +1000,105 @@ ldapdb_create(isc_mem_t *mctx, dns_name_t *name, dns_dbtype_t type, return result; } -static dns_dbimplementation_t *ldapdb_imp; -const char *ldapdb_impname = "dynamic-ldap"; +static void +library_init(void) +{ + log_info("bind-dyndb-ldap version " VERSION + " compiled at " __TIME__ " " __DATE__ + ", compiler " __VERSION__); + cfg_init_types(); +} + +/* + * Driver version is called when loading the driver to ensure there + * is no API mismatch betwen the driver and the caller. + */ +VISIBLE int +dyndb_version(unsigned int *flags) { + UNUSED(flags); + return (DNS_DYNDB_VERSION); +} +/* + * Driver init is called for each dyndb section in named.conf + * once during startup and then again on every reload. + * + * @code + * dyndb example-name "sample.so" { param1 param2 }; + * @endcode + * + * @param[in] name User-defined string from dyndb "name" {}; definition + * in named.conf. + * The example above will have name = "example-name". + * @param[in] parameters User-defined parameters from dyndb section as one + * string. The example above will have + * params = "param1 param2"; + * @param[out] instp Pointer to instance-specific data + * (for one dyndb section). + */ VISIBLE isc_result_t -dynamic_driver_init(isc_mem_t *mctx, const char *name, const char * const *argv, - dns_dyndb_arguments_t *dyndb_args) +dyndb_init(isc_mem_t *mctx, const char *name, const char *parameters, + const char *file, unsigned long line, const dns_dyndbctx_t *dctx, + void **instp) { - dns_dbimplementation_t *ldapdb_imp_new = NULL; + unsigned int argc; + char **argv = NULL; + char *tmps = NULL; + ldap_instance_t *inst = NULL; isc_result_t result; + static isc_once_t library_init_once = ISC_ONCE_INIT; REQUIRE(name != NULL); - REQUIRE(argv != NULL); - REQUIRE(dyndb_args != NULL); + REQUIRE(parameters != NULL); + REQUIRE(dctx != NULL); + REQUIRE(instp != NULL && *instp == NULL); - log_debug(2, "registering dynamic ldap driver for %s.", name); + RUNTIME_CHECK(isc_once_do(&library_init_once, library_init) + == ISC_R_SUCCESS); /* - * We need to discover what rdataset methods does - * dns_rdatalist_tordataset use. We then make a copy for ourselves - * with the exception that we modify the disassociate method to free - * the rdlist we allocate for it in clone_rdatalist_to_rdataset(). + * Depending on how dlopen() was called, we may not have + * access to named's global namespace, in which case we need + * to initialize libisc/libdns */ + if (dctx->refvar != &isc_bind9) { + isc_lib_register(); + isc_log_setcontext(dctx->lctx); + dns_log_setcontext(dctx->lctx); + } - /* Register new DNS DB implementation. */ - result = dns_db_register(ldapdb_impname, &ldapdb_associate, NULL, mctx, - &ldapdb_imp_new); - if (result != ISC_R_SUCCESS && result != ISC_R_EXISTS) - return result; - else if (result == ISC_R_SUCCESS) - ldapdb_imp = ldapdb_imp_new; + isc_hash_set_initializer(dctx->hashinit); + + log_debug(2, "registering dynamic ldap driver for %s.", name); + + tmps = isc_mem_strdup(mctx, parameters); + if (tmps == NULL) { + result = ISC_R_NOMEMORY; + goto cleanup; + } + CHECK(isc_commandline_strtoargv(mctx, tmps, &argc, &argv, 0)); /* Finally, create the instance. */ - result = manager_create_db_instance(mctx, name, argv, dyndb_args); + CHECK(new_ldap_instance(mctx, name, argc, argv, dctx, &inst)); + *instp = inst; + +cleanup: + if (tmps != NULL) + isc_mem_free(mctx, tmps); + if (argv != NULL) + isc_mem_put(mctx, argv, argc * sizeof(*argv)); return result; } +/* + * Driver destroy is called for every instance on every reload and then once + * during shutdown. + * + * @param[out] instp Pointer to instance-specific data (for one dyndb section). + */ VISIBLE void -dynamic_driver_destroy(void) -{ - /* Only unregister the implementation if it was registered by us. */ - if (ldapdb_imp != NULL) - dns_db_unregister(&ldapdb_imp); - - destroy_manager(); +dyndb_destroy(void **instp) { + destroy_ldap_instance((ldap_instance_t **)instp); } diff --git a/src/ldap_driver.h b/src/ldap_driver.h index 73c4827..62d50f6 100644 --- a/src/ldap_driver.h +++ b/src/ldap_driver.h @@ -19,9 +19,13 @@ typedef struct ldapdb ldapdb_t; isc_result_t ldapdb_create(isc_mem_t *mctx, dns_name_t *name, dns_dbtype_t type, - dns_rdataclass_t rdclass, unsigned int argc, char *argv[], - void *driverarg, dns_db_t **dbp) ATTR_NONNULL(1,2,6,8); + dns_rdataclass_t rdclass, void *driverarg, dns_db_t **dbp) + ATTR_NONNULL(1,2,5,6); +isc_result_t +ldapdb_associate(isc_mem_t *mctx, dns_name_t *name, dns_dbtype_t type, + dns_rdataclass_t rdclass, unsigned int argc, char *argv[], + void *driverarg, dns_db_t **dbp) ATTR_NONNULL(1,2,7,8); dns_db_t * ldapdb_get_rbtdb(dns_db_t *db) ATTR_NONNULLS; diff --git a/src/ldap_helper.c b/src/ldap_helper.c index ad6e417..58b1d7b 100644 --- a/src/ldap_helper.c +++ b/src/ldap_helper.c @@ -4,7 +4,7 @@ #include "config.h" -#include +#include #include #include #include @@ -77,7 +77,6 @@ #include "syncrepl.h" #include "util.h" #include "zone.h" -#include "zone_manager.h" #include "zone_register.h" #include "rbt_helper.h" #include "fwd_register.h" @@ -133,7 +132,8 @@ struct ldap_instance { isc_mem_t *mctx; /* These are needed for zone creation. */ - const char * db_name; + char * db_name; + dns_dbimplementation_t *db_imp; dns_view_t *view; dns_zonemgr_t *zmgr; @@ -184,12 +184,6 @@ struct ldap_connection { unsigned int tries; }; -/* - * Constants. - */ - -extern const char *ldapdb_impname; - /* Supported authentication types. */ const ldap_auth_pair_t supported_ldap_auth[] = { { AUTH_NONE, "none" }, @@ -505,13 +499,12 @@ validate_local_instance_settings(ldap_instance_t *inst, settings_set_t *set) { #define PRINT_BUFF_SIZE 255 isc_result_t -new_ldap_instance(isc_mem_t *mctx, const char *db_name, - const char * const *argv, dns_dyndb_arguments_t *dyndb_args, - isc_task_t *task, ldap_instance_t **ldap_instp) +new_ldap_instance(isc_mem_t *mctx, const char *db_name, unsigned int argc, + char **argv, const dns_dyndbctx_t *dctx, + ldap_instance_t **ldap_instp) { isc_result_t result; ldap_instance_t *ldap_inst; - dns_view_t *view = NULL; dns_forwarders_t *named_conf_forwarders = NULL; isc_buffer_t *forwarders_list = NULL; const char *forward_policy = NULL; @@ -526,30 +519,29 @@ new_ldap_instance(isc_mem_t *mctx, const char *db_name, ZERO_PTR(ldap_inst); CHECK(isc_refcount_init(&ldap_inst->errors, 0)); isc_mem_attach(mctx, &ldap_inst->mctx); + CHECKED_MEM_STRDUP(mctx, db_name, ldap_inst->db_name); + dns_view_attach(dctx->view, &ldap_inst->view); + dns_zonemgr_attach(dctx->zmgr, &ldap_inst->zmgr); + isc_task_attach(dctx->task, &ldap_inst->task); - ldap_inst->db_name = db_name; - view = dns_dyndb_get_view(dyndb_args); - dns_view_attach(view, &ldap_inst->view); - ldap_inst->zmgr = dns_dyndb_get_zonemgr(dyndb_args); - ldap_inst->task = task; ldap_inst->watcher = 0; CHECK(sync_ctx_init(ldap_inst->mctx, ldap_inst, &ldap_inst->sctx)); isc_string_printf_truncate(settings_name, PRINT_BUFF_SIZE, SETTING_SET_NAME_LOCAL " for database %s", - db_name); + ldap_inst->db_name); CHECK(settings_set_create(mctx, settings_local_default, sizeof(settings_local_default), settings_name, &settings_default_set, &ldap_inst->local_settings)); isc_string_printf_truncate(settings_name, PRINT_BUFF_SIZE, SETTING_SET_NAME_GLOBAL " for database %s", - db_name); + ldap_inst->db_name); CHECK(settings_set_create(mctx, settings_global_default, sizeof(settings_global_default), settings_name, ldap_inst->local_settings, &ldap_inst->global_settings)); - CHECK(settings_set_fill(ldap_inst->local_settings, argv)); + CHECK(settings_set_fill(ldap_inst->local_settings, argc, argv)); /* copy global forwarders setting for configuration roll back in * configure_zone_forwarders() */ @@ -573,7 +565,7 @@ new_ldap_instance(isc_mem_t *mctx, const char *db_name, * * Warn-only semantics is implemented in BIND RT#41441, * this code can be removed when we rebase to BIND 9.11. */ - CHECK(sync_task_add(ldap_inst->sctx, task)); + CHECK(sync_task_add(ldap_inst->sctx, ldap_inst->task)); gfwdevent = (ldap_globalfwd_handleez_t *)isc_event_allocate( ldap_inst->mctx, ldap_inst, LDAPDB_EVENT_GLOBALFWD_HANDLEEZ, @@ -586,7 +578,7 @@ new_ldap_instance(isc_mem_t *mctx, const char *db_name, gfwdevent->warn_only = (named_conf_forwarders->fwdpolicy == dns_fwdpolicy_first); - isc_task_send(task, (isc_event_t **)&gfwdevent); + isc_task_send(ldap_inst->task, (isc_event_t **)&gfwdevent); } else if (result == ISC_R_NOTFOUND) { /* global forwarders are not configured */ @@ -639,6 +631,10 @@ new_ldap_instance(isc_mem_t *mctx, const char *db_name, CHECK(ldap_pool_create(mctx, connections, &ldap_inst->pool)); CHECK(ldap_pool_connect(ldap_inst->pool, ldap_inst)); + /* Register new DNS DB implementation. */ + CHECK(dns_db_register(ldap_inst->db_name, &ldapdb_associate, ldap_inst, + mctx, &ldap_inst->db_imp)); + /* Start the watcher thread */ result = isc_thread_create(ldap_syncrepl_watcher, ldap_inst, &ldap_inst->watcher); @@ -663,7 +659,6 @@ void destroy_ldap_instance(ldap_instance_t **ldap_instp) { ldap_instance_t *ldap_inst; - const char *db_name; REQUIRE(ldap_instp != NULL); @@ -671,8 +666,6 @@ destroy_ldap_instance(ldap_instance_t **ldap_instp) if (ldap_inst == NULL) return; - db_name = ldap_inst->db_name; /* points to DB instance: outside ldap_inst */ - if (ldap_inst->watcher != 0) { ldap_inst->exiting = ISC_TRUE; /* @@ -695,7 +688,14 @@ destroy_ldap_instance(ldap_instance_t **ldap_instp) mldap_destroy(&ldap_inst->mldapdb); ldap_pool_destroy(&ldap_inst->pool); - dns_view_detach(&ldap_inst->view); + if (ldap_inst->db_imp != NULL) + dns_db_unregister(&ldap_inst->db_imp); + if (ldap_inst->view != NULL) + dns_view_detach(&ldap_inst->view); + if (ldap_inst->zmgr != NULL) + dns_zonemgr_detach(&ldap_inst->zmgr); + if (ldap_inst->task != NULL) + isc_task_detach(&ldap_inst->task); DESTROYLOCK(&ldap_inst->kinit_lock); @@ -709,10 +709,13 @@ destroy_ldap_instance(ldap_instance_t **ldap_instp) ldap_instance_untaint_start(ldap_inst)); isc_refcount_destroy(&ldap_inst->errors); + if (ldap_inst->db_name != NULL) { + log_debug(1, "LDAP instance '%s' destroyed", ldap_inst->db_name); + isc_mem_free(ldap_inst->mctx, ldap_inst->db_name); + } MEM_PUT_AND_DETACH(ldap_inst); *ldap_instp = NULL; - log_debug(1, "LDAP instance '%s' destroyed", db_name); } static isc_result_t ATTR_NONNULLS ATTR_CHECKRESULT @@ -916,7 +919,7 @@ create_zone(ldap_instance_t * const inst, const char * const dn, isc_result_t result; dns_zone_t *raw = NULL; dns_zone_t *secure = NULL; - const char *ldap_argv[2]; + const char *ldap_argv[1] = { inst->db_name }; const char *rbt_argv[1] = { "rbt" }; sync_state_t sync_state; isc_task_t *task = NULL; @@ -926,9 +929,6 @@ create_zone(ldap_instance_t * const inst, const char * const dn, REQUIRE(name != NULL); REQUIRE(rawp != NULL && *rawp == NULL); - ldap_argv[0] = ldapdb_impname; - ldap_argv[1] = inst->db_name; - result = zone_unload_ifempty(inst->view, name); if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) goto cleanup; @@ -938,7 +938,8 @@ create_zone(ldap_instance_t * const inst, const char * const dn, dns_zone_setclass(raw, dns_rdataclass_in); dns_zone_settype(raw, dns_zone_master); /* dns_zone_setview(raw, view); */ - CHECK(dns_zone_setdbtype(raw, 2, ldap_argv)); + CHECK(dns_zone_setdbtype(raw, sizeof(ldap_argv)/sizeof(ldap_argv[0]), + ldap_argv)); CHECK(configure_paths(inst->mctx, inst, raw, ISC_FALSE)); if (want_secure == ISC_FALSE) { @@ -3654,7 +3655,7 @@ update_zone(isc_task_t *task, isc_event_t *event) { ldap_syncreplevent_t *pevent = (ldap_syncreplevent_t *)event; isc_result_t result ; - ldap_instance_t *inst = NULL; + ldap_instance_t *inst = pevent->inst; isc_mem_t *mctx; dns_name_t prevname; ldap_entry_t *entry = pevent->entry; @@ -3662,7 +3663,6 @@ update_zone(isc_task_t *task, isc_event_t *event) mctx = pevent->mctx; dns_name_init(&prevname, NULL); - CHECK(manager_get_ldap_instance(pevent->dbname, &inst)); INSIST(task == inst->task); /* For task-exclusive mode */ if (SYNCREPL_DEL(pevent->chgtype)) { @@ -3673,6 +3673,9 @@ update_zone(isc_task_t *task, isc_event_t *event) task)); else if (entry->class & LDAP_ENTRYCLASS_FORWARD) CHECK(ldap_parse_fwd_zoneentry(entry, inst)); + else + FATAL_ERROR(__FILE__, __LINE__, + "update_zone: unexpected entry class"); } cleanup: @@ -3687,7 +3690,6 @@ update_zone(isc_task_t *task, isc_event_t *event) "Zones can be outdated, run `rndc reload`", ldap_entry_logname(entry)); - isc_mem_free(mctx, pevent->dbname); if (pevent->prevdn != NULL) isc_mem_free(mctx, pevent->prevdn); ldap_entry_destroy(&entry); @@ -3701,13 +3703,12 @@ update_config(isc_task_t * task, isc_event_t *event) { ldap_syncreplevent_t *pevent = (ldap_syncreplevent_t *)event; isc_result_t result; - ldap_instance_t *inst = NULL; + ldap_instance_t *inst = pevent->inst; ldap_entry_t *entry = pevent->entry; isc_mem_t *mctx; mctx = pevent->mctx; - CHECK(manager_get_ldap_instance(pevent->dbname, &inst)); INSIST(task == inst->task); /* For task-exclusive mode */ CHECK(ldap_parse_configentry(entry, inst)); @@ -3722,7 +3723,6 @@ update_config(isc_task_t * task, isc_event_t *event) ldap_entry_logname(entry)); ldap_entry_destroy(&entry); - isc_mem_free(mctx, pevent->dbname); isc_mem_detach(&mctx); isc_event_free(&event); isc_task_detach(&task); @@ -3733,13 +3733,12 @@ update_serverconfig(isc_task_t * task, isc_event_t *event) { ldap_syncreplevent_t *pevent = (ldap_syncreplevent_t *)event; isc_result_t result; - ldap_instance_t *inst = NULL; + ldap_instance_t *inst = pevent->inst; ldap_entry_t *entry = pevent->entry; isc_mem_t *mctx; mctx = pevent->mctx; - CHECK(manager_get_ldap_instance(pevent->dbname, &inst)); INSIST(task == inst->task); /* For task-exclusive mode */ CHECK(ldap_parse_serverconfigentry(entry, inst)); @@ -3754,7 +3753,6 @@ update_serverconfig(isc_task_t * task, isc_event_t *event) ldap_entry_logname(entry)); ldap_entry_destroy(&entry); - isc_mem_free(mctx, pevent->dbname); isc_mem_detach(&mctx); isc_event_free(&event); isc_task_detach(&task); @@ -3774,7 +3772,7 @@ update_record(isc_task_t *task, isc_event_t *event) /* syncrepl event */ ldap_syncreplevent_t *pevent = (ldap_syncreplevent_t *)event; isc_result_t result; - ldap_instance_t *inst = NULL; + ldap_instance_t *inst = pevent->inst; isc_mem_t *mctx; settings_set_t *zone_settings = NULL; dns_zone_t *raw = NULL; @@ -3811,7 +3809,6 @@ update_record(isc_task_t *task, isc_event_t *event) dns_name_init(&prevname, NULL); dns_name_init(&prevorigin, NULL); - CHECK(manager_get_ldap_instance(pevent->dbname, &inst)); CHECK(zr_get_zone_ptr(inst->zone_register, &entry->zone_name, &raw, &secure)); zone_found = ISC_TRUE; @@ -3984,7 +3981,6 @@ update_record(isc_task_t *task, isc_event_t *event) if (secure != NULL) dns_zone_detach(&secure); ldapdb_rdatalist_destroy(mctx, &rdatalist); - isc_mem_free(mctx, pevent->dbname); if (pevent->prevdn != NULL) isc_mem_free(mctx, pevent->prevdn); ldap_entry_destroy(&entry); @@ -4055,7 +4051,6 @@ syncrepl_update(ldap_instance_t *inst, ldap_entry_t **entryp, int chgtype) dns_name_t *zone_name = NULL; dns_zone_t *zone_ptr = NULL; char *dn = NULL; - char *dbname = NULL; isc_mem_t *mctx = NULL; isc_taskaction_t action = NULL; isc_task_t *task = NULL; @@ -4071,8 +4066,6 @@ syncrepl_update(ldap_instance_t *inst, ldap_entry_t **entryp, int chgtype) isc_mem_attach(inst->mctx, &mctx); - CHECKED_MEM_STRDUP(mctx, inst->db_name, dbname); - if (entry->class & LDAP_ENTRYCLASS_MASTER) zone_name = &entry->fqdn; else @@ -4129,7 +4122,7 @@ syncrepl_update(ldap_instance_t *inst, ldap_entry_t **entryp, int chgtype) } pevent->mctx = mctx; - pevent->dbname = dbname; + pevent->inst = inst; pevent->prevdn = NULL; pevent->chgtype = chgtype; pevent->entry = entry; @@ -4148,9 +4141,6 @@ syncrepl_update(ldap_instance_t *inst, ldap_entry_t **entryp, int chgtype) if (pevent != NULL) { /* Event was not sent */ sync_concurr_limit_signal(inst->sctx); - - if (dbname != NULL) - isc_mem_free(mctx, dbname); if (mctx != NULL) isc_mem_detach(&mctx); ldap_entry_destroy(entryp); @@ -4394,7 +4384,7 @@ int ldap_sync_intermediate ( sync_state_get(inst->sctx, &state); if (state == sync_datainit) { - result = sync_barrier_wait(inst->sctx, inst->db_name); + result = sync_barrier_wait(inst->sctx, inst); if (result != ISC_R_SUCCESS) { log_error_r("%s: sync_barrier_wait() failed for " "instance '%s'", __func__, inst->db_name); @@ -4447,7 +4437,7 @@ int ATTR_NONNULLS ATTR_CHECKRESULT ldap_sync_search_result ( INSIST(state == sync_configinit || state == sync_finished); if (state == sync_configinit) { - result = sync_barrier_wait(inst->sctx, inst->db_name); + result = sync_barrier_wait(inst->sctx, inst); if (result != ISC_R_SUCCESS) { log_error_r("%s: sync_barrier_wait() failed for " "instance '%s'", __func__, inst->db_name); diff --git a/src/ldap_helper.h b/src/ldap_helper.h index a491bae..773091c 100644 --- a/src/ldap_helper.h +++ b/src/ldap_helper.h @@ -40,9 +40,9 @@ void free_rdatalist(isc_mem_t *mctx, dns_rdatalist_t *rdlist) ATTR_NONNULLS; */ isc_result_t -new_ldap_instance(isc_mem_t *mctx, const char *db_name, - const char * const *argv, dns_dyndb_arguments_t *dyndb_args, - isc_task_t *task, ldap_instance_t **ldap_instp) ATTR_NONNULLS; +new_ldap_instance(isc_mem_t *mctx, const char *db_name, unsigned int argc, + char **argv, const dns_dyndbctx_t *dctx, + ldap_instance_t **ldap_instp) ATTR_NONNULLS; void destroy_ldap_instance(ldap_instance_t **ldap_inst) ATTR_NONNULLS; isc_result_t diff --git a/src/settings.c b/src/settings.c index 3692dae..bdcfd67 100644 --- a/src/settings.c +++ b/src/settings.c @@ -579,14 +579,14 @@ settings_set_free(settings_set_t **set) { * @endcode */ isc_result_t -settings_set_fill(settings_set_t *set, const char *const *argv) +settings_set_fill(settings_set_t *set, unsigned int argc, char **argv) { isc_result_t result; - int i; + unsigned int i; const char *name; char *value; - for (i = 0; argv[i] != NULL; i++) { + for (i = 0; i < argc; i++) { char buff[SETTING_LINE_MAXLENGTH] = ""; CHECK(isc_string_copy(buff, SETTING_LINE_MAXLENGTH, argv[i])); value = buff; diff --git a/src/settings.h b/src/settings.h index 9bc4176..b77fcf8 100644 --- a/src/settings.h +++ b/src/settings.h @@ -82,7 +82,7 @@ void settings_set_free(settings_set_t **set) ATTR_NONNULLS; isc_result_t -settings_set_fill(settings_set_t *set, const char *const *argv) +settings_set_fill(settings_set_t *set, unsigned int argc, char **argv) ATTR_NONNULLS ATTR_CHECKRESULT; isc_boolean_t diff --git a/src/syncrepl.c b/src/syncrepl.c index 0079644..6ed8051 100644 --- a/src/syncrepl.c +++ b/src/syncrepl.c @@ -15,7 +15,6 @@ #include "util.h" #include "semaphore.h" #include "syncrepl.h" -#include "zone_manager.h" #define LDAPDB_EVENT_SYNCREPL_BARRIER (LDAPDB_EVENTCLASS + 2) #define LDAPDB_EVENT_SYNCREPL_FINISH (LDAPDB_EVENTCLASS + 3) @@ -109,7 +108,7 @@ struct sync_ctx { */ struct sync_barrierev { ISC_EVENT_COMMON(sync_barrierev_t); - const char *dbname; + ldap_instance_t *inst; sync_ctx_t *sctx; }; @@ -122,7 +121,6 @@ struct sync_barrierev { void finish(isc_task_t *task, isc_event_t *event) { isc_result_t result = ISC_R_SUCCESS; - ldap_instance_t *inst = NULL; sync_barrierev_t *bev = NULL; sync_state_t new_state; @@ -130,7 +128,6 @@ finish(isc_task_t *task, isc_event_t *event) { REQUIRE(event != NULL); bev = (sync_barrierev_t *)event; - CHECK(manager_get_ldap_instance(bev->dbname, &inst)); log_debug(1, "sync_barrier_wait(): finish reached"); LOCK(&bev->sctx->mutex); switch (bev->sctx->state) { @@ -152,9 +149,8 @@ finish(isc_task_t *task, isc_event_t *event) { BROADCAST(&bev->sctx->cond); UNLOCK(&bev->sctx->mutex); if (new_state == sync_finished) - activate_zones(task, inst); + activate_zones(task, bev->inst); -cleanup: if (result != ISC_R_SUCCESS) log_error_r("syncrepl finish() failed"); isc_event_free(&event); @@ -162,12 +158,12 @@ finish(isc_task_t *task, isc_event_t *event) { } static isc_result_t ATTR_NONNULLS ATTR_CHECKRESULT -sync_finishev_create(sync_ctx_t *sctx, const char *inst_name, +sync_finishev_create(sync_ctx_t *sctx, ldap_instance_t *inst, sync_barrierev_t **evp) { sync_barrierev_t *ev = NULL; REQUIRE(sctx != NULL); - REQUIRE(inst_name != NULL); + REQUIRE(inst != NULL); REQUIRE(evp != NULL && *evp == NULL); ev = (sync_barrierev_t *)isc_event_allocate(sctx->mctx, @@ -177,7 +173,7 @@ sync_finishev_create(sync_ctx_t *sctx, const char *inst_name, if (ev == NULL) return ISC_R_NOMEMORY; - ev->dbname = inst_name; + ev->inst = inst; ev->sctx = sctx; *evp = ev; @@ -203,7 +199,6 @@ sync_finishev_create(sync_ctx_t *sctx, const char *inst_name, void barrier_decrement(isc_task_t *task, isc_event_t *event) { isc_result_t result = ISC_R_SUCCESS; - ldap_instance_t *inst = NULL; sync_barrierev_t *bev = NULL; sync_barrierev_t *fev = NULL; isc_event_t *ev = NULL; @@ -214,13 +209,12 @@ barrier_decrement(isc_task_t *task, isc_event_t *event) { REQUIRE(event != NULL); bev = (sync_barrierev_t *)event; - CHECK(manager_get_ldap_instance(bev->dbname, &inst)); isc_refcount_decrement(&bev->sctx->task_cnt, &cnt); if (cnt == 0) { log_debug(1, "sync_barrier_wait(): barrier reached"); LOCK(&bev->sctx->mutex); locked = ISC_TRUE; - CHECK(sync_finishev_create(bev->sctx, bev->dbname, &fev)); + CHECK(sync_finishev_create(bev->sctx, bev->inst, &fev)); ev = (isc_event_t *)fev; isc_task_send(ldap_instance_gettask(bev->sctx->inst), &ev); } @@ -235,12 +229,12 @@ barrier_decrement(isc_task_t *task, isc_event_t *event) { } static isc_result_t ATTR_NONNULLS ATTR_CHECKRESULT -sync_barrierev_create(sync_ctx_t *sctx, const char *inst_name, +sync_barrierev_create(sync_ctx_t *sctx, ldap_instance_t *inst, sync_barrierev_t **evp) { sync_barrierev_t *ev = NULL; REQUIRE(sctx != NULL); - REQUIRE(inst_name != NULL); + REQUIRE(inst != NULL); REQUIRE(evp != NULL && *evp == NULL); ev = (sync_barrierev_t *)isc_event_allocate(sctx->mctx, @@ -250,7 +244,7 @@ sync_barrierev_create(sync_ctx_t *sctx, const char *inst_name, if (ev == NULL) return ISC_R_NOMEMORY; - ev->dbname = inst_name; + ev->inst = inst; ev->sctx = sctx; *evp = ev; @@ -488,7 +482,7 @@ sync_task_add(sync_ctx_t *sctx, isc_task_t *task) { * enqueued before sync_barrier_wait() call. */ isc_result_t -sync_barrier_wait(sync_ctx_t *sctx, const char *inst_name) { +sync_barrier_wait(sync_ctx_t *sctx, ldap_instance_t *inst) { isc_result_t result; isc_event_t *ev = NULL; sync_barrierev_t *bev = NULL; @@ -524,7 +518,7 @@ sync_barrier_wait(sync_ctx_t *sctx, const char *inst_name) { taskel != NULL; taskel = next_taskel) { bev = NULL; - CHECK(sync_barrierev_create(sctx, inst_name, &bev)); + CHECK(sync_barrierev_create(sctx, inst, &bev)); next_taskel = NEXT(taskel, link); UNLINK(sctx->tasks, taskel, link); ev = (isc_event_t *)bev; diff --git a/src/syncrepl.h b/src/syncrepl.h index ba3070a..14684ea 100644 --- a/src/syncrepl.h +++ b/src/syncrepl.h @@ -49,7 +49,7 @@ isc_result_t sync_task_add(sync_ctx_t *sctx, isc_task_t *task) ATTR_NONNULLS ATTR_CHECKRESULT; isc_result_t -sync_barrier_wait(sync_ctx_t *sctx, const char *inst_name) ATTR_NONNULLS ATTR_CHECKRESULT; +sync_barrier_wait(sync_ctx_t *sctx, ldap_instance_t *inst) ATTR_NONNULLS ATTR_CHECKRESULT; isc_result_t sync_concurr_limit_wait(sync_ctx_t *sctx) ATTR_NONNULLS ATTR_CHECKRESULT; diff --git a/src/types.h b/src/types.h index 57d5579..25ef3b9 100644 --- a/src/types.h +++ b/src/types.h @@ -43,7 +43,7 @@ typedef struct ldap_syncreplevent ldap_syncreplevent_t; struct ldap_syncreplevent { ISC_EVENT_COMMON(ldap_syncreplevent_t); isc_mem_t *mctx; - char *dbname; + ldap_instance_t *inst; char *prevdn; int chgtype; ldap_entry_t *entry; diff --git a/src/zone_manager.c b/src/zone_manager.c deleted file mode 100644 index 85e19fb..0000000 --- a/src/zone_manager.c +++ /dev/null @@ -1,205 +0,0 @@ -/* - * Copyright (C) 2009-2014 bind-dyndb-ldap authors; see COPYING for license - */ - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include - -#include "config.h" - -#include "bindcfg.h" -#include "ldap_convert.h" -#include "ldap_helper.h" -#include "log.h" -#include "settings.h" -#include "util.h" -#include "zone_manager.h" - -struct db_instance { - isc_mem_t *mctx; - char *name; - ldap_instance_t *ldap_inst; - isc_timer_t *timer; - LINK(db_instance_t) link; -}; - -static isc_once_t initialize_once = ISC_ONCE_INIT; -static isc_mutex_t instance_list_lock; -static LIST(db_instance_t) instance_list; - -static void initialize_manager(void); -static void destroy_db_instance(db_instance_t **db_instp) ATTR_NONNULLS; -static isc_result_t find_db_instance(const char *name, db_instance_t **instance) ATTR_NONNULLS ATTR_CHECKRESULT; - - -static void -initialize_manager(void) -{ - INIT_LIST(instance_list); - isc_mutex_init(&instance_list_lock); - log_info("bind-dyndb-ldap version " VERSION - " compiled at " __TIME__ " " __DATE__ - ", compiler " __VERSION__); - cfg_init_types(); -} - -void -destroy_manager(void) -{ - db_instance_t *db_inst; - db_instance_t *next; - - RUNTIME_CHECK(isc_once_do(&initialize_once, initialize_manager) - == ISC_R_SUCCESS); - - LOCK(&instance_list_lock); - db_inst = HEAD(instance_list); - while (db_inst != NULL) { - next = NEXT(db_inst, link); - UNLINK(instance_list, db_inst, link); - destroy_db_instance(&db_inst); - db_inst = next; - } - UNLOCK(&instance_list_lock); -} - -static void ATTR_NONNULLS -destroy_db_instance(db_instance_t **db_instp) -{ - db_instance_t *db_inst; - - REQUIRE(db_instp != NULL && *db_instp != NULL); - - db_inst = *db_instp; - - if (db_inst->timer != NULL) - isc_timer_detach(&db_inst->timer); - if (db_inst->ldap_inst != NULL) - destroy_ldap_instance(&db_inst->ldap_inst); - if (db_inst->name != NULL) - isc_mem_free(db_inst->mctx, db_inst->name); - - MEM_PUT_AND_DETACH(db_inst); - - *db_instp = NULL; -} - -isc_result_t -manager_create_db_instance(isc_mem_t *mctx, const char *name, - const char * const *argv, - dns_dyndb_arguments_t *dyndb_args) -{ - isc_result_t result; - db_instance_t *db_inst = NULL; - isc_task_t *task; - settings_set_t *local_settings = NULL; - - REQUIRE(name != NULL); - REQUIRE(dyndb_args != NULL); - - RUNTIME_CHECK(isc_once_do(&initialize_once, initialize_manager) - == ISC_R_SUCCESS); - - result = find_db_instance(name, &db_inst); - if (result == ISC_R_SUCCESS) { - db_inst = NULL; - log_error("LDAP instance '%s' already exists", name); - CLEANUP_WITH(ISC_R_EXISTS); - } - - CHECKED_MEM_GET_PTR(mctx, db_inst); - ZERO_PTR(db_inst); - - isc_mem_attach(mctx, &db_inst->mctx); - CHECKED_MEM_STRDUP(mctx, name, db_inst->name); - task = dns_dyndb_get_task(dyndb_args); - CHECK(new_ldap_instance(mctx, db_inst->name, argv, dyndb_args, task, - &db_inst->ldap_inst)); - - local_settings = ldap_instance_getsettings_local(db_inst->ldap_inst); - CHECK(setting_get_bool("verbose_checks", local_settings, &verbose_checks)); - - /* instance must be in list while calling refresh_zones_from_ldap() */ - LOCK(&instance_list_lock); - APPEND(instance_list, db_inst, link); - UNLOCK(&instance_list_lock); - - return ISC_R_SUCCESS; - -cleanup: - if (db_inst != NULL) - destroy_db_instance(&db_inst); - - return result; -} - -isc_result_t -manager_get_ldap_instance(const char *name, ldap_instance_t **ldap_inst) -{ - isc_result_t result; - db_instance_t *db_inst; - - REQUIRE(name != NULL); - REQUIRE(ldap_inst != NULL); - - RUNTIME_CHECK(isc_once_do(&initialize_once, initialize_manager) - == ISC_R_SUCCESS); - db_inst = NULL; - CHECK(find_db_instance(name, &db_inst)); - - *ldap_inst = db_inst->ldap_inst; - -cleanup: - return result; -} - -static isc_result_t ATTR_NONNULLS ATTR_CHECKRESULT -find_db_instance(const char *name, db_instance_t **instance) -{ - db_instance_t *iterator; - - REQUIRE(name != NULL); - REQUIRE(instance != NULL && *instance == NULL); - - LOCK(&instance_list_lock); - iterator = HEAD(instance_list); - while (iterator != NULL) { - if (strcmp(name, iterator->name) == 0) - break; - iterator = NEXT(iterator, link); - } - UNLOCK(&instance_list_lock); - - if (iterator != NULL) { - *instance = iterator; - return ISC_R_SUCCESS; - } - - return ISC_R_NOTFOUND; -} - -isc_result_t -manager_get_db_timer(const char *name, isc_timer_t **timer) { - isc_result_t result; - db_instance_t *db_inst = NULL; - - REQUIRE(name != NULL); - - result = find_db_instance(name, &db_inst); - if (result == ISC_R_SUCCESS) - *timer = db_inst->timer; - - return result; -} diff --git a/src/zone_manager.h b/src/zone_manager.h deleted file mode 100644 index 1e06365..0000000 --- a/src/zone_manager.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (C) 2009-2014 bind-dyndb-ldap authors; see COPYING for license - */ - -#ifndef _LD_ZONE_MANAGER_H_ -#define _LD_ZONE_MANAGER_H_ - -#include - -#include "types.h" - -typedef struct db_instance db_instance_t; - -void destroy_manager(void); - -isc_result_t -manager_create_db_instance(isc_mem_t *mctx, const char *name, - const char * const *argv, - dns_dyndb_arguments_t *dyndb_args) ATTR_NONNULLS ATTR_CHECKRESULT; - -isc_result_t -manager_get_ldap_instance(const char *name, - ldap_instance_t **ldap_inst) ATTR_NONNULLS ATTR_CHECKRESULT; - -isc_result_t -manager_get_db_timer(const char *name, - isc_timer_t **timer) ATTR_NONNULLS ATTR_CHECKRESULT; - -#endif /* !_LD_ZONE_MANAGER_H_ */ diff --git a/src/zone_register.c b/src/zone_register.c index bde4a7c..d8525e9 100644 --- a/src/zone_register.c +++ b/src/zone_register.c @@ -260,15 +260,15 @@ zr_get_zone_path(isc_mem_t *mctx, settings_set_t *settings, static isc_result_t ATTR_NONNULL(1,2,4,5,6,8) create_zone_info(isc_mem_t * const mctx, dns_zone_t * const raw, dns_zone_t * const secure, const char * const dn, - settings_set_t *global_settings, const char *db_name, + settings_set_t *global_settings, ldap_instance_t *inst, dns_db_t * const ldapdb, zone_info_t **zinfop) { isc_result_t result; zone_info_t *zinfo; char settings_name[PRINT_BUFF_SIZE]; ld_string_t *zone_dir = NULL; - char *argv[1]; + REQUIRE(inst != NULL); REQUIRE(raw != NULL); REQUIRE(dn != NULL); REQUIRE(zinfop != NULL && *zinfop == NULL); @@ -294,11 +294,9 @@ create_zone_info(isc_mem_t * const mctx, dns_zone_t * const raw, CHECK(fs_dirs_create(str_buf(zone_dir))); if (ldapdb == NULL) { /* create new empty database */ - DE_CONST(db_name, argv[0]); CHECK(ldapdb_create(mctx, dns_zone_getorigin(raw), LDAP_DB_TYPE, LDAP_DB_RDATACLASS, - sizeof(argv)/sizeof(argv[0]), - argv, NULL, &zinfo->ldapdb)); + inst, &zinfo->ldapdb)); } else { /* re-use existing database */ dns_db_attach(ldapdb, &zinfo->ldapdb); } @@ -396,8 +394,7 @@ zr_add_zone(zone_register_t * const zr, dns_db_t * const ldapdb, } CHECK(create_zone_info(zr->mctx, raw, secure, dn, zr->global_settings, - ldap_instance_getdbname(zr->ldap_inst), ldapdb, - &new_zinfo)); + zr->ldap_inst, ldapdb, &new_zinfo)); CHECK(dns_rbt_addname(zr->rbt, name, new_zinfo)); cleanup: