422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt/*
649482995baef0f0663216e0f97ae2f4adb1a4e3Tinderbox User * Copyright (C) 2011-2014, 2016, 2017 Internet Systems Consortium, Inc. ("ISC")
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt *
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 Hunt */
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
207845805eb591b77ffbd99735617cab7e2ed804Evan Hunt/* $Id$ */
cf786a52ce85fd069c764a7de3d036b63a741153Automatic Updater
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt#include <config.h>
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt#include <stdio.h>
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt#include <string.h>
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt#include <stdlib.h>
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt#include <dlfcn.h>
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt#include <dns/log.h>
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt#include <dns/result.h>
50f64cf0e58073f61bea3e1e4a9ad258bca80961Francis Dupont#include <dns/dlz_dlopen.h>
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt#include <isc/mem.h>
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt#include <isc/print.h>
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt#include <isc/result.h>
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt#include <isc/util.h>
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt#include <named/globals.h>
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt#include <dlz/dlz_dlopen_driver.h>
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt#ifdef ISC_DLZ_DLOPEN
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Huntstatic dns_sdlzimplementation_t *dlz_dlopen = NULL;
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunttypedef struct dlopen_data {
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt isc_mem_t *mctx;
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt char *dl_path;
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt char *dlzname;
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt void *dl_handle;
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt void *dbdata;
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt unsigned int flags;
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt isc_mutex_t lock;
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt int version;
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt isc_boolean_t in_configure;
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
50f64cf0e58073f61bea3e1e4a9ad258bca80961Francis Dupont dlz_dlopen_version_t *dlz_version;
50f64cf0e58073f61bea3e1e4a9ad258bca80961Francis Dupont dlz_dlopen_create_t *dlz_create;
50f64cf0e58073f61bea3e1e4a9ad258bca80961Francis Dupont dlz_dlopen_findzonedb_t *dlz_findzonedb;
50f64cf0e58073f61bea3e1e4a9ad258bca80961Francis Dupont dlz_dlopen_lookup_t *dlz_lookup;
50f64cf0e58073f61bea3e1e4a9ad258bca80961Francis Dupont dlz_dlopen_authority_t *dlz_authority;
50f64cf0e58073f61bea3e1e4a9ad258bca80961Francis Dupont dlz_dlopen_allnodes_t *dlz_allnodes;
50f64cf0e58073f61bea3e1e4a9ad258bca80961Francis Dupont dlz_dlopen_allowzonexfr_t *dlz_allowzonexfr;
50f64cf0e58073f61bea3e1e4a9ad258bca80961Francis Dupont dlz_dlopen_newversion_t *dlz_newversion;
50f64cf0e58073f61bea3e1e4a9ad258bca80961Francis Dupont dlz_dlopen_closeversion_t *dlz_closeversion;
50f64cf0e58073f61bea3e1e4a9ad258bca80961Francis Dupont dlz_dlopen_configure_t *dlz_configure;
50f64cf0e58073f61bea3e1e4a9ad258bca80961Francis Dupont dlz_dlopen_ssumatch_t *dlz_ssumatch;
50f64cf0e58073f61bea3e1e4a9ad258bca80961Francis Dupont dlz_dlopen_addrdataset_t *dlz_addrdataset;
50f64cf0e58073f61bea3e1e4a9ad258bca80961Francis Dupont dlz_dlopen_subrdataset_t *dlz_subrdataset;
50f64cf0e58073f61bea3e1e4a9ad258bca80961Francis Dupont dlz_dlopen_delrdataset_t *dlz_delrdataset;
50f64cf0e58073f61bea3e1e4a9ad258bca80961Francis Dupont dlz_dlopen_destroy_t *dlz_destroy;
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt} dlopen_data_t;
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt/* Modules can choose whether they are lock-safe or not. */
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt#define MAYBE_LOCK(cd) \
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt do { \
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt if ((cd->flags & DNS_SDLZFLAG_THREADSAFE) == 0 && \
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt cd->in_configure == ISC_FALSE) \
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt LOCK(&cd->lock); \
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt } while (0)
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt#define MAYBE_UNLOCK(cd) \
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt do { \
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt if ((cd->flags & DNS_SDLZFLAG_THREADSAFE) == 0 && \
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt cd->in_configure == ISC_FALSE) \
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt UNLOCK(&cd->lock); \
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt } while (0)
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt/*
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * Log a message at the given level.
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt */
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Huntstatic void dlopen_log(int level, const char *fmt, ...)
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt{
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt va_list ap;
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt va_start(ap, fmt);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt isc_log_vwrite(dns_lctx, DNS_LOGCATEGORY_DATABASE,
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt DNS_LOGMODULE_DLZ, ISC_LOG_DEBUG(level),
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt fmt, ap);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt va_end(ap);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt}
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt/*
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * SDLZ methods
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt */
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Huntstatic isc_result_t
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Huntdlopen_dlz_allnodes(const char *zone, void *driverarg, void *dbdata,
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt dns_sdlzallnodes_t *allnodes)
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt{
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt dlopen_data_t *cd = (dlopen_data_t *) dbdata;
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt isc_result_t result;
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt UNUSED(driverarg);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt if (cd->dlz_allnodes == NULL) {
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt return (ISC_R_NOPERM);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt }
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt MAYBE_LOCK(cd);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt result = cd->dlz_allnodes(zone, cd->dbdata, allnodes);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt MAYBE_UNLOCK(cd);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt return (result);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt}
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Huntstatic isc_result_t
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Huntdlopen_dlz_allowzonexfr(void *driverarg, void *dbdata, const char *name,
cf786a52ce85fd069c764a7de3d036b63a741153Automatic Updater const char *client)
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt{
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt dlopen_data_t *cd = (dlopen_data_t *) dbdata;
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt isc_result_t result;
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt UNUSED(driverarg);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt if (cd->dlz_allowzonexfr == NULL) {
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt return (ISC_R_NOPERM);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt }
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt MAYBE_LOCK(cd);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt result = cd->dlz_allowzonexfr(cd->dbdata, name, client);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt MAYBE_UNLOCK(cd);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt return (result);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt}
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Huntstatic isc_result_t
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Huntdlopen_dlz_authority(const char *zone, void *driverarg, void *dbdata,
793814f80703afdd69b59ade91e63efa81ae4178Evan Hunt dns_sdlzlookup_t *lookup)
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt{
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt dlopen_data_t *cd = (dlopen_data_t *) dbdata;
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt isc_result_t result;
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt UNUSED(driverarg);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt if (cd->dlz_authority == NULL) {
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt return (ISC_R_NOTIMPLEMENTED);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt }
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt MAYBE_LOCK(cd);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt result = cd->dlz_authority(zone, cd->dbdata, lookup);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt MAYBE_UNLOCK(cd);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt return (result);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt}
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Huntstatic isc_result_t
abff0f462a758383d012887d3a97da4dac0c5a94Evan Huntdlopen_dlz_findzonedb(void *driverarg, void *dbdata, const char *name,
abff0f462a758383d012887d3a97da4dac0c5a94Evan Hunt dns_clientinfomethods_t *methods,
abff0f462a758383d012887d3a97da4dac0c5a94Evan Hunt dns_clientinfo_t *clientinfo)
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt{
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt dlopen_data_t *cd = (dlopen_data_t *) dbdata;
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt isc_result_t result;
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt UNUSED(driverarg);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt MAYBE_LOCK(cd);
abff0f462a758383d012887d3a97da4dac0c5a94Evan Hunt result = cd->dlz_findzonedb(cd->dbdata, name, methods, clientinfo);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt MAYBE_UNLOCK(cd);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt return (result);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt}
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Huntstatic isc_result_t
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Huntdlopen_dlz_lookup(const char *zone, const char *name, void *driverarg,
793814f80703afdd69b59ade91e63efa81ae4178Evan Hunt void *dbdata, dns_sdlzlookup_t *lookup,
793814f80703afdd69b59ade91e63efa81ae4178Evan Hunt dns_clientinfomethods_t *methods,
793814f80703afdd69b59ade91e63efa81ae4178Evan Hunt dns_clientinfo_t *clientinfo)
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt{
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt dlopen_data_t *cd = (dlopen_data_t *) dbdata;
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt isc_result_t result;
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt UNUSED(driverarg);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt MAYBE_LOCK(cd);
793814f80703afdd69b59ade91e63efa81ae4178Evan Hunt result = cd->dlz_lookup(zone, name, cd->dbdata, lookup,
793814f80703afdd69b59ade91e63efa81ae4178Evan Hunt methods, clientinfo);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt MAYBE_UNLOCK(cd);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt return (result);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt}
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt/*
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * Load a symbol from the library
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt */
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Huntstatic void *
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Huntdl_load_symbol(dlopen_data_t *cd, const char *symbol, isc_boolean_t mandatory) {
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt void *ptr = dlsym(cd->dl_handle, symbol);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt if (ptr == NULL && mandatory) {
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt dlopen_log(ISC_LOG_ERROR,
cf786a52ce85fd069c764a7de3d036b63a741153Automatic Updater "dlz_dlopen: library '%s' is missing "
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt "required symbol '%s'", cd->dl_path, symbol);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt }
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt return (ptr);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt}
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt/*
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * Called at startup for each dlopen zone in named.conf
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt */
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Huntstatic isc_result_t
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Huntdlopen_dlz_create(const char *dlzname, unsigned int argc, char *argv[],
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt void *driverarg, void **dbdata)
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt{
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt dlopen_data_t *cd;
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt isc_mem_t *mctx = NULL;
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt isc_result_t result = ISC_R_FAILURE;
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt int dlopen_flags = 0;
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt UNUSED(driverarg);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt if (argc < 2) {
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt dlopen_log(ISC_LOG_ERROR,
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt "dlz_dlopen driver for '%s' needs a path to "
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt "the shared library", dlzname);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt return (ISC_R_FAILURE);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt }
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
41bbb34bc20f189af62e7047ce42822615417f15Evan Hunt result = isc_mem_create(0, 0, &mctx);
41bbb34bc20f189af62e7047ce42822615417f15Evan Hunt if (result != ISC_R_SUCCESS)
41bbb34bc20f189af62e7047ce42822615417f15Evan Hunt return (result);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt cd = isc_mem_get(mctx, sizeof(*cd));
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt if (cd == NULL) {
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt isc_mem_destroy(&mctx);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt return (ISC_R_NOMEMORY);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt }
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt memset(cd, 0, sizeof(*cd));
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt cd->mctx = mctx;
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt cd->dl_path = isc_mem_strdup(cd->mctx, argv[1]);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt if (cd->dl_path == NULL) {
c1d33c159bf81d6faf9948ac9a6f307ca52284afEvan Hunt result = ISC_R_NOMEMORY;
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt goto failed;
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt }
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt cd->dlzname = isc_mem_strdup(cd->mctx, dlzname);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt if (cd->dlzname == NULL) {
c1d33c159bf81d6faf9948ac9a6f307ca52284afEvan Hunt result = ISC_R_NOMEMORY;
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt goto failed;
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt }
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt /* Initialize the lock */
45b727f651aba2cbd2f9db51ccfb4b541520a5deMark Andrews result = isc_mutex_init(&cd->lock);
08df939613d7f20bdac132a93efc537bb457ccfaTinderbox User if (result != ISC_R_SUCCESS)
45b727f651aba2cbd2f9db51ccfb4b541520a5deMark Andrews goto failed;
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt /* Open the library */
0148654d85b2818f9317b428a67701f4585c8243Scott Mann dlopen_flags = RTLD_NOW|RTLD_GLOBAL;
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt#ifdef RTLD_DEEPBIND
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt /*
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 */
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt dlopen_flags |= RTLD_DEEPBIND;
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt#endif
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt cd->dl_handle = dlopen(cd->dl_path, dlopen_flags);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt if (cd->dl_handle == NULL) {
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt dlopen_log(ISC_LOG_ERROR,
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt "dlz_dlopen failed to open library '%s' - %s",
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt cd->dl_path, dlerror());
c1d33c159bf81d6faf9948ac9a6f307ca52284afEvan Hunt result = ISC_R_FAILURE;
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt goto failed;
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt }
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt /* Find the symbols */
50f64cf0e58073f61bea3e1e4a9ad258bca80961Francis Dupont cd->dlz_version = (dlz_dlopen_version_t *)
50f64cf0e58073f61bea3e1e4a9ad258bca80961Francis Dupont dl_load_symbol(cd, "dlz_version", ISC_TRUE);
50f64cf0e58073f61bea3e1e4a9ad258bca80961Francis Dupont cd->dlz_create = (dlz_dlopen_create_t *)
50f64cf0e58073f61bea3e1e4a9ad258bca80961Francis Dupont dl_load_symbol(cd, "dlz_create", ISC_TRUE);
50f64cf0e58073f61bea3e1e4a9ad258bca80961Francis Dupont cd->dlz_lookup = (dlz_dlopen_lookup_t *)
50f64cf0e58073f61bea3e1e4a9ad258bca80961Francis Dupont dl_load_symbol(cd, "dlz_lookup", ISC_TRUE);
50f64cf0e58073f61bea3e1e4a9ad258bca80961Francis Dupont cd->dlz_findzonedb = (dlz_dlopen_findzonedb_t *)
50f64cf0e58073f61bea3e1e4a9ad258bca80961Francis Dupont dl_load_symbol(cd, "dlz_findzonedb", ISC_TRUE);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt if (cd->dlz_create == NULL ||
abff0f462a758383d012887d3a97da4dac0c5a94Evan Hunt cd->dlz_version == NULL ||
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt cd->dlz_lookup == NULL ||
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt cd->dlz_findzonedb == NULL)
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt {
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt /* We're missing a required symbol */
c1d33c159bf81d6faf9948ac9a6f307ca52284afEvan Hunt result = ISC_R_FAILURE;
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt goto failed;
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt }
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
50f64cf0e58073f61bea3e1e4a9ad258bca80961Francis Dupont cd->dlz_allowzonexfr = (dlz_dlopen_allowzonexfr_t *)
50f64cf0e58073f61bea3e1e4a9ad258bca80961Francis Dupont dl_load_symbol(cd, "dlz_allowzonexfr", ISC_FALSE);
50f64cf0e58073f61bea3e1e4a9ad258bca80961Francis Dupont cd->dlz_allnodes = (dlz_dlopen_allnodes_t *)
50f64cf0e58073f61bea3e1e4a9ad258bca80961Francis Dupont dl_load_symbol(cd, "dlz_allnodes",
50f64cf0e58073f61bea3e1e4a9ad258bca80961Francis Dupont ISC_TF(cd->dlz_allowzonexfr != NULL));
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 dl_load_symbol(cd, "dlz_closeversion",
50f64cf0e58073f61bea3e1e4a9ad258bca80961Francis Dupont ISC_TF(cd->dlz_newversion != NULL));
50f64cf0e58073f61bea3e1e4a9ad258bca80961Francis Dupont cd->dlz_configure = (dlz_dlopen_configure_t *)
50f64cf0e58073f61bea3e1e4a9ad258bca80961Francis Dupont dl_load_symbol(cd, "dlz_configure", ISC_FALSE);
50f64cf0e58073f61bea3e1e4a9ad258bca80961Francis Dupont cd->dlz_ssumatch = (dlz_dlopen_ssumatch_t *)
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);
261543671b70b078a2d55bbf16ef78ae2074bbdcEvan Hunt cd->dlz_destroy = (dlz_dlopen_destroy_t *)
261543671b70b078a2d55bbf16ef78ae2074bbdcEvan Hunt dl_load_symbol(cd, "dlz_destroy", ISC_FALSE);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt /* Check the version of the API is the same */
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt cd->version = cd->dlz_version(&cd->flags);
cbd1fa092ea66bfa9990c5e515725646295396c5Evan Hunt if (cd->version < (DLZ_DLOPEN_VERSION - DLZ_DLOPEN_AGE) ||
cbd1fa092ea66bfa9990c5e515725646295396c5Evan Hunt cd->version > DLZ_DLOPEN_VERSION)
cbd1fa092ea66bfa9990c5e515725646295396c5Evan Hunt {
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt dlopen_log(ISC_LOG_ERROR,
cbd1fa092ea66bfa9990c5e515725646295396c5Evan Hunt "dlz_dlopen: %s: incorrect driver API version %d, "
cbd1fa092ea66bfa9990c5e515725646295396c5Evan Hunt "requires %d",
cbd1fa092ea66bfa9990c5e515725646295396c5Evan Hunt cd->dl_path, cd->version, DLZ_DLOPEN_VERSION);
d51456e4537729c2263303350abeff45379b1105Evan Hunt result = ISC_R_FAILURE;
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt goto failed;
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt }
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt /*
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 */
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt MAYBE_LOCK(cd);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt result = cd->dlz_create(dlzname, argc-1, argv+1,
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt &cd->dbdata,
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt "log", dlopen_log,
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt "putrr", dns_sdlz_putrr,
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt "putnamedrr", dns_sdlz_putnamedrr,
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt "writeable_zone", dns_dlz_writeablezone,
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt NULL);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt MAYBE_UNLOCK(cd);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt if (result != ISC_R_SUCCESS)
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt goto failed;
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt *dbdata = cd;
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt return (ISC_R_SUCCESS);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Huntfailed:
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt dlopen_log(ISC_LOG_ERROR, "dlz_dlopen of '%s' failed", dlzname);
45b727f651aba2cbd2f9db51ccfb4b541520a5deMark Andrews if (cd->dl_path != NULL)
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt isc_mem_free(mctx, cd->dl_path);
45b727f651aba2cbd2f9db51ccfb4b541520a5deMark Andrews if (cd->dlzname != NULL)
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt isc_mem_free(mctx, cd->dlzname);
45b727f651aba2cbd2f9db51ccfb4b541520a5deMark Andrews if (dlopen_flags != 0)
50f64cf0e58073f61bea3e1e4a9ad258bca80961Francis Dupont (void) isc_mutex_destroy(&cd->lock);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt#ifdef HAVE_DLCLOSE
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt if (cd->dl_handle)
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt dlclose(cd->dl_handle);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt#endif
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt isc_mem_put(mctx, cd, sizeof(*cd));
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt isc_mem_destroy(&mctx);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt return (result);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt}
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt/*
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * Called when bind is shutting down
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt */
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Huntstatic void
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Huntdlopen_dlz_destroy(void *driverarg, void *dbdata) {
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt dlopen_data_t *cd = (dlopen_data_t *) dbdata;
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt isc_mem_t *mctx;
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt UNUSED(driverarg);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt if (cd->dlz_destroy) {
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt MAYBE_LOCK(cd);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt cd->dlz_destroy(cd->dbdata);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt MAYBE_UNLOCK(cd);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt }
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt if (cd->dl_path)
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt isc_mem_free(cd->mctx, cd->dl_path);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt if (cd->dlzname)
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt isc_mem_free(cd->mctx, cd->dlzname);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt#ifdef HAVE_DLCLOSE
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt if (cd->dl_handle)
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt dlclose(cd->dl_handle);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt#endif
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
50f64cf0e58073f61bea3e1e4a9ad258bca80961Francis Dupont (void) isc_mutex_destroy(&cd->lock);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt mctx = cd->mctx;
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt isc_mem_put(mctx, cd, sizeof(*cd));
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt isc_mem_destroy(&mctx);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt}
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt/*
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * Called to start a transaction
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt */
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Huntstatic isc_result_t
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Huntdlopen_dlz_newversion(const char *zone, void *driverarg, void *dbdata,
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt void **versionp)
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt{
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt dlopen_data_t *cd = (dlopen_data_t *) dbdata;
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt isc_result_t result;
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt UNUSED(driverarg);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt if (cd->dlz_newversion == NULL)
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt return (ISC_R_NOTIMPLEMENTED);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt MAYBE_LOCK(cd);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt result = cd->dlz_newversion(zone, cd->dbdata, versionp);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt MAYBE_UNLOCK(cd);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt return (result);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt}
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt/*
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * Called to end a transaction
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt */
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Huntstatic void
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Huntdlopen_dlz_closeversion(const char *zone, isc_boolean_t commit,
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt void *driverarg, void *dbdata, void **versionp)
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt{
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt dlopen_data_t *cd = (dlopen_data_t *) dbdata;
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt UNUSED(driverarg);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt if (cd->dlz_newversion == NULL) {
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt *versionp = NULL;
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt return;
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt }
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt MAYBE_LOCK(cd);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt cd->dlz_closeversion(zone, commit, cd->dbdata, versionp);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt MAYBE_UNLOCK(cd);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt}
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt/*
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * Called on startup to configure any writeable zones
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt */
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Huntstatic isc_result_t
2b8bed6681d1541474f022586cbe728dfce36880Evan Huntdlopen_dlz_configure(dns_view_t *view, dns_dlzdb_t *dlzdb,
2b8bed6681d1541474f022586cbe728dfce36880Evan Hunt void *driverarg, void *dbdata)
2b8bed6681d1541474f022586cbe728dfce36880Evan Hunt{
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt dlopen_data_t *cd = (dlopen_data_t *) dbdata;
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt isc_result_t result;
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt UNUSED(driverarg);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt if (cd->dlz_configure == NULL)
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt return (ISC_R_SUCCESS);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt MAYBE_LOCK(cd);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt cd->in_configure = ISC_TRUE;
2b8bed6681d1541474f022586cbe728dfce36880Evan Hunt result = cd->dlz_configure(view, dlzdb, cd->dbdata);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt cd->in_configure = ISC_FALSE;
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt MAYBE_UNLOCK(cd);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt return (result);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt}
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt/*
2732d4922c2e72a399204320791acfd2fd3d6c7cMark Andrews * Check for authority to change a name.
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt */
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Huntstatic isc_boolean_t
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{
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt dlopen_data_t *cd = (dlopen_data_t *) dbdata;
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt isc_boolean_t ret;
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt UNUSED(driverarg);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt if (cd->dlz_ssumatch == NULL)
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt return (ISC_FALSE);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt MAYBE_LOCK(cd);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt ret = cd->dlz_ssumatch(signer, name, tcpaddr, type, key, keydatalen,
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt keydata, cd->dbdata);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt MAYBE_UNLOCK(cd);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt return (ret);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt}
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt/*
2732d4922c2e72a399204320791acfd2fd3d6c7cMark Andrews * Add an rdataset.
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt */
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Huntstatic isc_result_t
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Huntdlopen_dlz_addrdataset(const char *name, const char *rdatastr,
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt void *driverarg, void *dbdata, void *version)
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt{
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt dlopen_data_t *cd = (dlopen_data_t *) dbdata;
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt isc_result_t result;
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt UNUSED(driverarg);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt if (cd->dlz_addrdataset == NULL)
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt return (ISC_R_NOTIMPLEMENTED);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt MAYBE_LOCK(cd);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt result = cd->dlz_addrdataset(name, rdatastr, cd->dbdata, version);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt MAYBE_UNLOCK(cd);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt return (result);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt}
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt/*
2732d4922c2e72a399204320791acfd2fd3d6c7cMark Andrews * Subtract an rdataset.
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt */
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Huntstatic isc_result_t
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Huntdlopen_dlz_subrdataset(const char *name, const char *rdatastr,
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt void *driverarg, void *dbdata, void *version)
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt{
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt dlopen_data_t *cd = (dlopen_data_t *) dbdata;
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt isc_result_t result;
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt UNUSED(driverarg);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt if (cd->dlz_subrdataset == NULL)
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt return (ISC_R_NOTIMPLEMENTED);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt MAYBE_LOCK(cd);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt result = cd->dlz_subrdataset(name, rdatastr, cd->dbdata, version);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt MAYBE_UNLOCK(cd);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt return (result);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt}
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt/*
2732d4922c2e72a399204320791acfd2fd3d6c7cMark Andrews * Delete a rdataset.
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt */
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Huntstatic isc_result_t
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Huntdlopen_dlz_delrdataset(const char *name, const char *type,
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt void *driverarg, void *dbdata, void *version)
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt{
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt dlopen_data_t *cd = (dlopen_data_t *) dbdata;
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt isc_result_t result;
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt UNUSED(driverarg);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt if (cd->dlz_delrdataset == NULL)
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt return (ISC_R_NOTIMPLEMENTED);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt MAYBE_LOCK(cd);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt result = cd->dlz_delrdataset(name, type, cd->dbdata, version);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt MAYBE_UNLOCK(cd);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt return (result);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt}
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Huntstatic dns_sdlzmethods_t dlz_dlopen_methods = {
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt dlopen_dlz_create,
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt dlopen_dlz_destroy,
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt dlopen_dlz_findzonedb,
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt dlopen_dlz_lookup,
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt dlopen_dlz_authority,
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt dlopen_dlz_allnodes,
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt dlopen_dlz_allowzonexfr,
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt dlopen_dlz_newversion,
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt dlopen_dlz_closeversion,
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt dlopen_dlz_configure,
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt dlopen_dlz_ssumatch,
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt dlopen_dlz_addrdataset,
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt dlopen_dlz_subrdataset,
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt dlopen_dlz_delrdataset
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt};
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt#endif
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt/*
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * Register driver with BIND
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt */
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Huntisc_result_t
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Huntdlz_dlopen_init(isc_mem_t *mctx) {
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt#ifndef ISC_DLZ_DLOPEN
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt UNUSED(mctx);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt return (ISC_R_NOTIMPLEMENTED);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt#else
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt isc_result_t result;
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt dlopen_log(2, "Registering DLZ_dlopen driver");
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt result = dns_sdlzregister("dlopen", &dlz_dlopen_methods, NULL,
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt DNS_SDLZFLAG_RELATIVEOWNER |
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt DNS_SDLZFLAG_RELATIVERDATA |
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt DNS_SDLZFLAG_THREADSAFE,
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt mctx, &dlz_dlopen);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt if (result != ISC_R_SUCCESS) {
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt UNEXPECTED_ERROR(__FILE__, __LINE__,
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt "dns_sdlzregister() failed: %s",
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt isc_result_totext(result));
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt result = ISC_R_UNEXPECTED;
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt }
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt return (result);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt#endif
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt}
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt/*
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * Unregister the driver
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt */
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Huntvoid
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Huntdlz_dlopen_clear(void) {
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt#ifdef ISC_DLZ_DLOPEN
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt dlopen_log(2, "Unregistering DLZ_dlopen driver");
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt if (dlz_dlopen != NULL)
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt dns_sdlzunregister(&dlz_dlopen);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt#endif
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt}