649482995baef0f0663216e0f97ae2f4adb1a4e3Tinderbox User * Copyright (C) 2011-2014, 2016, 2017 Internet Systems Consortium, Inc. ("ISC")
0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark Andrews * This Source Code Form is subject to the terms of the Mozilla Public
0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark Andrews * License, v. 2.0. If a copy of the MPL was not distributed with this
0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark Andrews * file, You can obtain one at http://mozilla.org/MPL/2.0/.
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Huntstatic dns_sdlzimplementation_t *dlz_dlopen = NULL;
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt/* Modules can choose whether they are lock-safe or not. */
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt if ((cd->flags & DNS_SDLZFLAG_THREADSAFE) == 0 && \
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt if ((cd->flags & DNS_SDLZFLAG_THREADSAFE) == 0 && \
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * Log a message at the given level.
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Huntstatic void dlopen_log(int level, const char *fmt, ...)
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt isc_log_vwrite(dns_lctx, DNS_LOGCATEGORY_DATABASE,
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * SDLZ methods
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Huntdlopen_dlz_allnodes(const char *zone, void *driverarg, void *dbdata,
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt result = cd->dlz_allnodes(zone, cd->dbdata, allnodes);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Huntdlopen_dlz_allowzonexfr(void *driverarg, void *dbdata, const char *name,
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt result = cd->dlz_allowzonexfr(cd->dbdata, name, client);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Huntdlopen_dlz_authority(const char *zone, void *driverarg, void *dbdata,
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt result = cd->dlz_authority(zone, cd->dbdata, lookup);
abff0f462a758383d012887d3a97da4dac0c5a94Evan Huntdlopen_dlz_findzonedb(void *driverarg, void *dbdata, const char *name,
abff0f462a758383d012887d3a97da4dac0c5a94Evan Hunt result = cd->dlz_findzonedb(cd->dbdata, name, methods, clientinfo);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Huntdlopen_dlz_lookup(const char *zone, const char *name, void *driverarg,
793814f80703afdd69b59ade91e63efa81ae4178Evan Hunt result = cd->dlz_lookup(zone, name, cd->dbdata, lookup,
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * Load a symbol from the library
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Huntstatic void *
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Huntdl_load_symbol(dlopen_data_t *cd, const char *symbol, isc_boolean_t mandatory) {
cf786a52ce85fd069c764a7de3d036b63a741153Automatic Updater "dlz_dlopen: library '%s' is missing "
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * Called at startup for each dlopen zone in named.conf
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Huntdlopen_dlz_create(const char *dlzname, unsigned int argc, char *argv[],
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt "dlz_dlopen driver for '%s' needs a path to "
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt /* Initialize the lock */
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt /* Open the library */
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * If RTLD_DEEPBIND is available then use it. This can avoid
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * issues with a module using a different version of a system
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * library than one that bind9 uses. For example, bind9 may link
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * to MIT kerberos, but the module may use Heimdal. If we don't
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * use RTLD_DEEPBIND then we could end up with Heimdal functions
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * calling MIT functions, which leads to bizarre results (usually
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * a segfault).
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt cd->dl_handle = dlopen(cd->dl_path, dlopen_flags);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt "dlz_dlopen failed to open library '%s' - %s",
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt /* Find the symbols */
50f64cf0e58073f61bea3e1e4a9ad258bca80961Francis Dupont cd->dlz_findzonedb = (dlz_dlopen_findzonedb_t *)
50f64cf0e58073f61bea3e1e4a9ad258bca80961Francis Dupont dl_load_symbol(cd, "dlz_findzonedb", ISC_TRUE);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt /* We're missing a required symbol */
50f64cf0e58073f61bea3e1e4a9ad258bca80961Francis Dupont cd->dlz_allowzonexfr = (dlz_dlopen_allowzonexfr_t *)
50f64cf0e58073f61bea3e1e4a9ad258bca80961Francis Dupont dl_load_symbol(cd, "dlz_allowzonexfr", ISC_FALSE);
50f64cf0e58073f61bea3e1e4a9ad258bca80961Francis Dupont cd->dlz_authority = (dlz_dlopen_authority_t *)
50f64cf0e58073f61bea3e1e4a9ad258bca80961Francis Dupont dl_load_symbol(cd, "dlz_authority", ISC_FALSE);
50f64cf0e58073f61bea3e1e4a9ad258bca80961Francis Dupont cd->dlz_newversion = (dlz_dlopen_newversion_t *)
50f64cf0e58073f61bea3e1e4a9ad258bca80961Francis Dupont dl_load_symbol(cd, "dlz_newversion", ISC_FALSE);
50f64cf0e58073f61bea3e1e4a9ad258bca80961Francis Dupont cd->dlz_closeversion = (dlz_dlopen_closeversion_t *)
50f64cf0e58073f61bea3e1e4a9ad258bca80961Francis Dupont cd->dlz_configure = (dlz_dlopen_configure_t *)
50f64cf0e58073f61bea3e1e4a9ad258bca80961Francis Dupont dl_load_symbol(cd, "dlz_configure", ISC_FALSE);
50f64cf0e58073f61bea3e1e4a9ad258bca80961Francis Dupont dl_load_symbol(cd, "dlz_ssumatch", ISC_FALSE);
50f64cf0e58073f61bea3e1e4a9ad258bca80961Francis Dupont cd->dlz_addrdataset = (dlz_dlopen_addrdataset_t *)
50f64cf0e58073f61bea3e1e4a9ad258bca80961Francis Dupont dl_load_symbol(cd, "dlz_addrdataset", ISC_FALSE);
50f64cf0e58073f61bea3e1e4a9ad258bca80961Francis Dupont cd->dlz_subrdataset = (dlz_dlopen_subrdataset_t *)
50f64cf0e58073f61bea3e1e4a9ad258bca80961Francis Dupont dl_load_symbol(cd, "dlz_subrdataset", ISC_FALSE);
50f64cf0e58073f61bea3e1e4a9ad258bca80961Francis Dupont cd->dlz_delrdataset = (dlz_dlopen_delrdataset_t *)
50f64cf0e58073f61bea3e1e4a9ad258bca80961Francis Dupont dl_load_symbol(cd, "dlz_delrdataset", ISC_FALSE);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt /* Check the version of the API is the same */
cbd1fa092ea66bfa9990c5e515725646295396c5Evan Hunt if (cd->version < (DLZ_DLOPEN_VERSION - DLZ_DLOPEN_AGE) ||
cbd1fa092ea66bfa9990c5e515725646295396c5Evan Hunt "dlz_dlopen: %s: incorrect driver API version %d, "
cbd1fa092ea66bfa9990c5e515725646295396c5Evan Hunt "requires %d",
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * Call the library's create function. Note that this is an
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * extended version of dlz create, with the addition of
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * named function pointers for helper functions that the
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * driver will need. This avoids the need for the backend to
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * link the BIND9 libraries
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt dlopen_log(ISC_LOG_ERROR, "dlz_dlopen of '%s' failed", dlzname);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * Called when bind is shutting down
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Huntdlopen_dlz_destroy(void *driverarg, void *dbdata) {
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * Called to start a transaction
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Huntdlopen_dlz_newversion(const char *zone, void *driverarg, void *dbdata,
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt result = cd->dlz_newversion(zone, cd->dbdata, versionp);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * Called to end a transaction
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Huntdlopen_dlz_closeversion(const char *zone, isc_boolean_t commit,
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt cd->dlz_closeversion(zone, commit, cd->dbdata, versionp);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * Called on startup to configure any writeable zones
2b8bed6681d1541474f022586cbe728dfce36880Evan Huntdlopen_dlz_configure(dns_view_t *view, dns_dlzdb_t *dlzdb,
2b8bed6681d1541474f022586cbe728dfce36880Evan Hunt result = cd->dlz_configure(view, dlzdb, cd->dbdata);
2732d4922c2e72a399204320791acfd2fd3d6c7cMark Andrews * Check for authority to change a name.
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Huntdlopen_dlz_ssumatch(const char *signer, const char *name, const char *tcpaddr,
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt const char *type, const char *key, isc_uint32_t keydatalen,
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt unsigned char *keydata, void *driverarg, void *dbdata)
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt ret = cd->dlz_ssumatch(signer, name, tcpaddr, type, key, keydatalen,
2732d4922c2e72a399204320791acfd2fd3d6c7cMark Andrews * Add an rdataset.
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Huntdlopen_dlz_addrdataset(const char *name, const char *rdatastr,
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt result = cd->dlz_addrdataset(name, rdatastr, cd->dbdata, version);
2732d4922c2e72a399204320791acfd2fd3d6c7cMark Andrews * Subtract an rdataset.
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Huntdlopen_dlz_subrdataset(const char *name, const char *rdatastr,
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt result = cd->dlz_subrdataset(name, rdatastr, cd->dbdata, version);
2732d4922c2e72a399204320791acfd2fd3d6c7cMark Andrews * Delete a rdataset.
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Huntdlopen_dlz_delrdataset(const char *name, const char *type,
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt result = cd->dlz_delrdataset(name, type, cd->dbdata, version);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * Register driver with BIND
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt result = dns_sdlzregister("dlopen", &dlz_dlopen_methods, NULL,
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt "dns_sdlzregister() failed: %s",
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * Unregister the driver