* Portions Copyright (C) Internet Systems Consortium, Inc. ("ISC")
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, you can obtain one at https://mozilla.org/MPL/2.0/.
* See the COPYRIGHT file distributed with this work for additional
* information regarding copyright ownership.
* Copyright (C) 2002 Stichting NLnet, Netherlands, stichting@nlnet.nl.
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the
* above copyright notice and this permission notice appear in all
* THE SOFTWARE IS PROVIDED "AS IS" AND STICHTING NLNET
* DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
* STICHTING NLNET BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
* OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE
* USE OR PERFORMANCE OF THIS SOFTWARE.
* The development of Dynamically Loadable Zones (DLZ) for Bind 9 was
* conceived and contributed by Rob Butler.
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the
* above copyright notice and this permission notice appear in all
* THE SOFTWARE IS PROVIDED "AS IS" AND ROB BUTLER
* DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
* ROB BUTLER BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
* OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE
* USE OR PERFORMANCE OF THIS SOFTWARE.
* The DLZ interface allows zones to be looked up using a driver instead of
* Bind's default in memory zone table.
#include <dns/clientinfo.h>
#define DNS_DLZ_MAGIC ISC_MAGIC('D','L','Z','D')
#define DNS_DLZ_VALID(dlz) ISC_MAGIC_VALID(dlz, DNS_DLZ_MAGIC)
(*dns_dlzallowzonexfr_t)(void *driverarg, void *dbdata, isc_mem_t *mctx,
dns_rdataclass_t rdclass, dns_name_t *name,
isc_sockaddr_t *clientaddr,
* Method prototype. Drivers implementing the DLZ interface MUST
* supply an allow zone transfer method. This method is called when
* the DNS server is performing a zone transfer query. The driver's
* method should return ISC_R_SUCCESS and a database pointer to the
* name server if the zone is supported by the database, and zone
* transfer is allowed. Otherwise it will return ISC_R_NOTFOUND if
* the zone is not supported by the database, or ISC_R_NOPERM if zone
* transfers are not allowed. If an error occurs it should return a
* result code indicating the type of error.
(*dns_dlzcreate_t)(isc_mem_t *mctx, const char *dlzname, unsigned int argc,
char *argv[], void *driverarg, void **dbdata);
* Method prototype. Drivers implementing the DLZ interface MUST
* supply a create method. This method is called when the DNS server
* is starting up and creating drivers for use later.
(*dns_dlzdestroy_t)(void *driverarg, void **dbdata);
* Method prototype. Drivers implementing the DLZ interface MUST
* supply a destroy method. This method is called when the DNS server
* is shutting down and no longer needs the driver.
(*dns_dlzfindzone_t)(void *driverarg, void *dbdata, isc_mem_t *mctx,
dns_rdataclass_t rdclass, dns_name_t *name,
dns_clientinfomethods_t *methods,
dns_clientinfo_t *clientinfo,
* Method prototype. Drivers implementing the DLZ interface MUST
* supply a find zone method. This method is called when the DNS
* server is performing a query. The find zone method will be called
* with the longest possible name first, and continue to be called
* with successively shorter domain names, until any of the following
* \li 1) a match is found, and the function returns (ISC_R_SUCCESS)
* \li 2) a problem occurs, and the functions returns anything other
* \li 3) we run out of domain name labels. I.E. we have tried the
* \li 4) the number of labels in the domain name is less than
* min_labels for dns_dlzfindzone
* The driver's find zone method should return ISC_R_SUCCESS and a
* database pointer to the name server if the zone is supported by the
* database. Otherwise it will return ISC_R_NOTFOUND, and a null
* pointer if the zone is not supported. If an error occurs it should
* return a result code indicating the type of error.
(*dns_dlzconfigure_t)(void *driverarg, void *dbdata,
dns_view_t *view, dns_dlzdb_t *dlzdb);
* Method prototype. Drivers implementing the DLZ interface may
* optionally supply a configure method. If supplied, this will be
* called immediately after the create method is called. The driver
* may call configuration functions during the configure call
typedef bool (*dns_dlzssumatch_t)(dns_name_t *signer,
void *driverarg, void *dbdata);
* Method prototype. Drivers implementing the DLZ interface may
* optionally supply a ssumatch method. If supplied, this will be
* called to authorize update requests
/*% the methods supplied by a DLZ driver */
typedef struct dns_dlzmethods {
dns_dlzdestroy_t destroy;
dns_dlzfindzone_t findzone;
dns_dlzallowzonexfr_t allowzonexfr;
dns_dlzconfigure_t configure;
dns_dlzssumatch_t ssumatch;
/*% information about a DLZ driver */
struct dns_dlzimplementation {
const dns_dlzmethods_t *methods;
ISC_LINK(dns_dlzimplementation_t) link;
typedef isc_result_t (*dlzconfigure_callback_t)(dns_view_t *, dns_dlzdb_t *,
/*% An instance of a DLZ driver */
dns_dlzimplementation_t *implementation;
dlzconfigure_callback_t configure_callback;
ISC_LINK(dns_dlzdb_t) link;
dns_ssutable_t *ssutable;
dns_dlzallowzonexfr(dns_view_t *view, dns_name_t *name,
isc_sockaddr_t *clientaddr, dns_db_t **dbp);
* This method is called when the DNS server is performing a zone
* transfer query. It will call the DLZ driver's allow zone transfer
dns_dlzcreate(isc_mem_t *mctx, const char *dlzname,
const char *drivername, unsigned int argc,
char *argv[], dns_dlzdb_t **dbp);
* This method is called when the DNS server is starting up and
* creating drivers for use later. It will search the DLZ driver list
* for 'drivername' and return a DLZ driver via dbp if a match is
* found. If the DLZ driver supplies a create method, this function
dns_dlzdestroy(dns_dlzdb_t **dbp);
* This method is called when the DNS server is shutting down and no
* longer needs the driver. If the DLZ driver supplies a destroy
* methods, this function will call it.
dns_dlzregister(const char *drivername, const dns_dlzmethods_t *methods,
void *driverarg, isc_mem_t *mctx,
dns_dlzimplementation_t **dlzimp);
* Register a dynamically loadable zones (DLZ) driver for the database
* type 'drivername', implemented by the functions in '*methods'.
* dlzimp must point to a NULL dlz_implementation_t pointer. That is,
* dlzimp != NULL && *dlzimp == NULL. It will be assigned a value that
* will later be used to identify the driver when deregistering it.
dns_dlzstrtoargv(isc_mem_t *mctx, char *s, unsigned int *argcp, char ***argvp);
* This method is called when the name server is starting up to parse
* the DLZ driver command line from named.conf. Basically it splits
* up a string into and argc / argv. The primary difference of this
* method is items between braces { } are considered only 1 word. for
* example the command line "this is { one grouped phrase } and this
* isn't" would be parsed into:
* \li argv{2]: " one grouped phrase "
* braces should NOT be nested, more than one grouping in the command
* line is allowed. Notice, argv[2] has an extra space at the
* beginning and end. Extra spaces are not stripped between a
* grouping. You can do so in your driver if needed, or be sure not
* to put extra spaces before / after the braces.
dns_dlzunregister(dns_dlzimplementation_t **dlzimp);
* Removes the dlz driver from the list of registered dlz drivers.
* There must be no active dlz drivers of this type when this function
typedef isc_result_t dns_dlz_writeablezone_t(dns_view_t *view,
dns_dlz_writeablezone_t dns_dlz_writeablezone;
* creates a writeable DLZ zone. Must be called from within the
* configure() method of a DLZ driver.
dns_dlzconfigure(dns_view_t *view, dns_dlzdb_t *dlzdb,
dlzconfigure_callback_t callback);
* call a DLZ drivers configure method, if supplied
dns_dlz_ssumatch(dns_dlzdb_t *dlzdatabase,
dns_name_t *signer, dns_name_t *name, isc_netaddr_t *tcpaddr,
dns_rdatatype_t type, const dst_key_t *key);
* call a DLZ drivers ssumatch method, if supplied. Otherwise return false