a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt/*
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt * Driver API implementation and main entry point for BIND.
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt *
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt * BIND calls dyndb_version() before loading, dyndb_init() during startup
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt * and dyndb_destroy() during shutdown.
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt *
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt * It is completely up to implementation what to do.
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt *
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt * dyndb <name> <driver> {} sections in named.conf are independent so
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt * driver init() and destroy() functions are called independently for
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt * each section even if they reference the same driver/library. It is
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt * up to driver implementation to detect and catch this situation if
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt * it is undesirable.
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt *
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt * Copyright (C) 2009-2015 Red Hat ; see COPYRIGHT for license
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt */
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt#include <config.h>
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt#include <isc/commandline.h>
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt#include <isc/hash.h>
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt#include <isc/mem.h>
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt#include <isc/lib.h>
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt#include <isc/util.h>
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt#include <dns/db.h>
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt#include <dns/dyndb.h>
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt#include <dns/lib.h>
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt#include <dns/types.h>
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt#include "db.h"
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt#include "log.h"
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt#include "instance.h"
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt#include "util.h"
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Huntdns_dyndb_destroy_t dyndb_destroy;
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Huntdns_dyndb_register_t dyndb_init;
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Huntdns_dyndb_version_t dyndb_version;
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt/*
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt * Driver init is called for each dyndb section in named.conf
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt * once during startup and then again on every reload.
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt *
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt * @code
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt * dyndb example-name "sample.so" { param1 param2 };
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt * @endcode
e939674d53a127ddeeaf4b41fd72933f0b493308Mark Andrews *
ab598428c8bc10d75bb1ef5dff15f8848869cb1bMark Andrews * @param[in] name User-defined string from dyndb "name" {}; definition
ab598428c8bc10d75bb1ef5dff15f8848869cb1bMark Andrews * in named.conf.
ab598428c8bc10d75bb1ef5dff15f8848869cb1bMark Andrews * The example above will have name = "example-name".
ab598428c8bc10d75bb1ef5dff15f8848869cb1bMark Andrews * @param[in] parameters User-defined parameters from dyndb section as one
ab598428c8bc10d75bb1ef5dff15f8848869cb1bMark Andrews * string. The example above will have
ab598428c8bc10d75bb1ef5dff15f8848869cb1bMark Andrews * params = "param1 param2";
f503aa345b451f94875a5bab637223bcbbd93b6dEvan Hunt * @param[in] file The name of the file from which the parameters
f503aa345b451f94875a5bab637223bcbbd93b6dEvan Hunt * were read.
f503aa345b451f94875a5bab637223bcbbd93b6dEvan Hunt * @param[in] line The line number from which the parameters were read.
ab598428c8bc10d75bb1ef5dff15f8848869cb1bMark Andrews * @param[out] instp Pointer to instance-specific data
ab598428c8bc10d75bb1ef5dff15f8848869cb1bMark Andrews * (for one dyndb section).
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt */
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Huntisc_result_t
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Huntdyndb_init(isc_mem_t *mctx, const char *name, const char *parameters,
f503aa345b451f94875a5bab637223bcbbd93b6dEvan Hunt const char *file, unsigned long line,
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt const dns_dyndbctx_t *dctx, void **instp)
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt{
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt isc_result_t result;
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt unsigned int argc;
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt char **argv = NULL;
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt char *s = NULL;
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt sample_instance_t *sample_inst = NULL;
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt REQUIRE(name != NULL);
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt REQUIRE(dctx != NULL);
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt /*
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt * Depending on how dlopen() was called, we may not have
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt * access to named's global namespace, in which case we need
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt * to initialize libisc/libdns
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt */
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt if (dctx->refvar != &isc_bind9) {
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt isc_lib_register();
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt isc_log_setcontext(dctx->lctx);
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt dns_log_setcontext(dctx->lctx);
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt }
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt
93c211afc97e7a072c12ef346581065e4065ff15Evan Hunt isc_hash_set_initializer(dctx->hashinit);
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt s = isc_mem_strdup(mctx, parameters);
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt if (s == NULL) {
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt result = ISC_R_NOMEMORY;
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt goto cleanup;
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt }
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt result = isc_commandline_strtoargv(mctx, s, &argc, &argv, 0);
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt if (result != ISC_R_SUCCESS)
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt goto cleanup;
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt
f503aa345b451f94875a5bab637223bcbbd93b6dEvan Hunt log_write(ISC_LOG_DEBUG(9),
f503aa345b451f94875a5bab637223bcbbd93b6dEvan Hunt "loading params for dyndb '%s' from %s:%lu",
f503aa345b451f94875a5bab637223bcbbd93b6dEvan Hunt name, file, line);
f503aa345b451f94875a5bab637223bcbbd93b6dEvan Hunt
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt /* Finally, create the instance. */
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt CHECK(new_sample_instance(mctx, name, argc, argv, dctx, &sample_inst));
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt /*
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt * This is an example so we create and load zones
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt * right now. This step can be arbitrarily postponed.
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt */
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt CHECK(load_sample_instance_zones(sample_inst));
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt *instp = sample_inst;
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt cleanup:
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt if (s != NULL)
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt isc_mem_free(mctx, s);
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt if (argv != NULL)
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt isc_mem_put(mctx, argv, argc * sizeof(*argv));
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt return (result);
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt}
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt/*
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt * Driver destroy is called for every instance on every reload and then once
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt * during shutdown.
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt *
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt * @param[out] instp Pointer to instance-specific data (for one dyndb section).
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt */
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Huntvoid
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Huntdyndb_destroy(void **instp) {
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt destroy_sample_instance((sample_instance_t **)instp);
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt}
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt/*
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt * Driver version is called when loading the driver to ensure there
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt * is no API mismatch betwen the driver and the caller.
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt */
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Huntint
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Huntdyndb_version(unsigned int *flags) {
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt UNUSED(flags);
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt return (DNS_DYNDB_VERSION);
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt}