xref: /minix3/external/bsd/bind/dist/bin/named/unix/dlz_dlopen_driver.c (revision 00b67f09dd46474d133c95011a48590a8e8f94c7)
1*00b67f09SDavid van Moolenbroek /*	$NetBSD: dlz_dlopen_driver.c,v 1.6 2014/12/10 04:37:52 christos Exp $	*/
2*00b67f09SDavid van Moolenbroek 
3*00b67f09SDavid van Moolenbroek /*
4*00b67f09SDavid van Moolenbroek  * Copyright (C) 2011-2014  Internet Systems Consortium, Inc. ("ISC")
5*00b67f09SDavid van Moolenbroek  *
6*00b67f09SDavid van Moolenbroek  * Permission to use, copy, modify, and/or distribute this software for any
7*00b67f09SDavid van Moolenbroek  * purpose with or without fee is hereby granted, provided that the above
8*00b67f09SDavid van Moolenbroek  * copyright notice and this permission notice appear in all copies.
9*00b67f09SDavid van Moolenbroek  *
10*00b67f09SDavid van Moolenbroek  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
11*00b67f09SDavid van Moolenbroek  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
12*00b67f09SDavid van Moolenbroek  * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
13*00b67f09SDavid van Moolenbroek  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
14*00b67f09SDavid van Moolenbroek  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
15*00b67f09SDavid van Moolenbroek  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
16*00b67f09SDavid van Moolenbroek  * PERFORMANCE OF THIS SOFTWARE.
17*00b67f09SDavid van Moolenbroek  */
18*00b67f09SDavid van Moolenbroek 
19*00b67f09SDavid van Moolenbroek /* Id */
20*00b67f09SDavid van Moolenbroek 
21*00b67f09SDavid van Moolenbroek #include <config.h>
22*00b67f09SDavid van Moolenbroek 
23*00b67f09SDavid van Moolenbroek #include <stdio.h>
24*00b67f09SDavid van Moolenbroek #include <string.h>
25*00b67f09SDavid van Moolenbroek #include <stdlib.h>
26*00b67f09SDavid van Moolenbroek #include <dlfcn.h>
27*00b67f09SDavid van Moolenbroek 
28*00b67f09SDavid van Moolenbroek #include <dns/log.h>
29*00b67f09SDavid van Moolenbroek #include <dns/result.h>
30*00b67f09SDavid van Moolenbroek #include <dns/dlz_dlopen.h>
31*00b67f09SDavid van Moolenbroek 
32*00b67f09SDavid van Moolenbroek #include <isc/mem.h>
33*00b67f09SDavid van Moolenbroek #include <isc/print.h>
34*00b67f09SDavid van Moolenbroek #include <isc/result.h>
35*00b67f09SDavid van Moolenbroek #include <isc/util.h>
36*00b67f09SDavid van Moolenbroek 
37*00b67f09SDavid van Moolenbroek #include <named/globals.h>
38*00b67f09SDavid van Moolenbroek 
39*00b67f09SDavid van Moolenbroek #include <dlz/dlz_dlopen_driver.h>
40*00b67f09SDavid van Moolenbroek 
41*00b67f09SDavid van Moolenbroek #ifdef ISC_DLZ_DLOPEN
42*00b67f09SDavid van Moolenbroek static dns_sdlzimplementation_t *dlz_dlopen = NULL;
43*00b67f09SDavid van Moolenbroek 
44*00b67f09SDavid van Moolenbroek 
45*00b67f09SDavid van Moolenbroek typedef struct dlopen_data {
46*00b67f09SDavid van Moolenbroek 	isc_mem_t *mctx;
47*00b67f09SDavid van Moolenbroek 	char *dl_path;
48*00b67f09SDavid van Moolenbroek 	char *dlzname;
49*00b67f09SDavid van Moolenbroek 	void *dl_handle;
50*00b67f09SDavid van Moolenbroek 	void *dbdata;
51*00b67f09SDavid van Moolenbroek 	unsigned int flags;
52*00b67f09SDavid van Moolenbroek 	isc_mutex_t lock;
53*00b67f09SDavid van Moolenbroek 	int version;
54*00b67f09SDavid van Moolenbroek 	isc_boolean_t in_configure;
55*00b67f09SDavid van Moolenbroek 
56*00b67f09SDavid van Moolenbroek 	dlz_dlopen_version_t *dlz_version;
57*00b67f09SDavid van Moolenbroek 	dlz_dlopen_create_t *dlz_create;
58*00b67f09SDavid van Moolenbroek 	dlz_dlopen_findzonedb_t *dlz_findzonedb;
59*00b67f09SDavid van Moolenbroek 	dlz_dlopen_lookup_t *dlz_lookup;
60*00b67f09SDavid van Moolenbroek 	dlz_dlopen_authority_t *dlz_authority;
61*00b67f09SDavid van Moolenbroek 	dlz_dlopen_allnodes_t *dlz_allnodes;
62*00b67f09SDavid van Moolenbroek 	dlz_dlopen_allowzonexfr_t *dlz_allowzonexfr;
63*00b67f09SDavid van Moolenbroek 	dlz_dlopen_newversion_t *dlz_newversion;
64*00b67f09SDavid van Moolenbroek 	dlz_dlopen_closeversion_t *dlz_closeversion;
65*00b67f09SDavid van Moolenbroek 	dlz_dlopen_configure_t *dlz_configure;
66*00b67f09SDavid van Moolenbroek 	dlz_dlopen_ssumatch_t *dlz_ssumatch;
67*00b67f09SDavid van Moolenbroek 	dlz_dlopen_addrdataset_t *dlz_addrdataset;
68*00b67f09SDavid van Moolenbroek 	dlz_dlopen_subrdataset_t *dlz_subrdataset;
69*00b67f09SDavid van Moolenbroek 	dlz_dlopen_delrdataset_t *dlz_delrdataset;
70*00b67f09SDavid van Moolenbroek 	dlz_dlopen_destroy_t *dlz_destroy;
71*00b67f09SDavid van Moolenbroek } dlopen_data_t;
72*00b67f09SDavid van Moolenbroek 
73*00b67f09SDavid van Moolenbroek /* Modules can choose whether they are lock-safe or not. */
74*00b67f09SDavid van Moolenbroek #define MAYBE_LOCK(cd) \
75*00b67f09SDavid van Moolenbroek 	do { \
76*00b67f09SDavid van Moolenbroek 		if ((cd->flags & DNS_SDLZFLAG_THREADSAFE) == 0 && \
77*00b67f09SDavid van Moolenbroek 		    cd->in_configure == ISC_FALSE) \
78*00b67f09SDavid van Moolenbroek 			LOCK(&cd->lock); \
79*00b67f09SDavid van Moolenbroek 	} while (/*CONSTCOND*/0)
80*00b67f09SDavid van Moolenbroek 
81*00b67f09SDavid van Moolenbroek #define MAYBE_UNLOCK(cd) \
82*00b67f09SDavid van Moolenbroek 	do { \
83*00b67f09SDavid van Moolenbroek 		if ((cd->flags & DNS_SDLZFLAG_THREADSAFE) == 0 && \
84*00b67f09SDavid van Moolenbroek 		    cd->in_configure == ISC_FALSE) \
85*00b67f09SDavid van Moolenbroek 			UNLOCK(&cd->lock); \
86*00b67f09SDavid van Moolenbroek 	} while (0)
87*00b67f09SDavid van Moolenbroek 
88*00b67f09SDavid van Moolenbroek /*
89*00b67f09SDavid van Moolenbroek  * Log a message at the given level.
90*00b67f09SDavid van Moolenbroek  */
dlopen_log(int level,const char * fmt,...)91*00b67f09SDavid van Moolenbroek static void dlopen_log(int level, const char *fmt, ...)
92*00b67f09SDavid van Moolenbroek {
93*00b67f09SDavid van Moolenbroek 	va_list ap;
94*00b67f09SDavid van Moolenbroek 	va_start(ap, fmt);
95*00b67f09SDavid van Moolenbroek 	isc_log_vwrite(dns_lctx, DNS_LOGCATEGORY_DATABASE,
96*00b67f09SDavid van Moolenbroek 		       DNS_LOGMODULE_DLZ, ISC_LOG_DEBUG(level),
97*00b67f09SDavid van Moolenbroek 		       fmt, ap);
98*00b67f09SDavid van Moolenbroek 	va_end(ap);
99*00b67f09SDavid van Moolenbroek }
100*00b67f09SDavid van Moolenbroek 
101*00b67f09SDavid van Moolenbroek /*
102*00b67f09SDavid van Moolenbroek  * SDLZ methods
103*00b67f09SDavid van Moolenbroek  */
104*00b67f09SDavid van Moolenbroek 
105*00b67f09SDavid van Moolenbroek static isc_result_t
dlopen_dlz_allnodes(const char * zone,void * driverarg,void * dbdata,dns_sdlzallnodes_t * allnodes)106*00b67f09SDavid van Moolenbroek dlopen_dlz_allnodes(const char *zone, void *driverarg, void *dbdata,
107*00b67f09SDavid van Moolenbroek 		    dns_sdlzallnodes_t *allnodes)
108*00b67f09SDavid van Moolenbroek {
109*00b67f09SDavid van Moolenbroek 	dlopen_data_t *cd = (dlopen_data_t *) dbdata;
110*00b67f09SDavid van Moolenbroek 	isc_result_t result;
111*00b67f09SDavid van Moolenbroek 
112*00b67f09SDavid van Moolenbroek 
113*00b67f09SDavid van Moolenbroek 	UNUSED(driverarg);
114*00b67f09SDavid van Moolenbroek 
115*00b67f09SDavid van Moolenbroek 	if (cd->dlz_allnodes == NULL) {
116*00b67f09SDavid van Moolenbroek 		return (ISC_R_NOPERM);
117*00b67f09SDavid van Moolenbroek 	}
118*00b67f09SDavid van Moolenbroek 
119*00b67f09SDavid van Moolenbroek 	MAYBE_LOCK(cd);
120*00b67f09SDavid van Moolenbroek 	result = cd->dlz_allnodes(zone, cd->dbdata, allnodes);
121*00b67f09SDavid van Moolenbroek 	MAYBE_UNLOCK(cd);
122*00b67f09SDavid van Moolenbroek 	return (result);
123*00b67f09SDavid van Moolenbroek }
124*00b67f09SDavid van Moolenbroek 
125*00b67f09SDavid van Moolenbroek 
126*00b67f09SDavid van Moolenbroek static isc_result_t
dlopen_dlz_allowzonexfr(void * driverarg,void * dbdata,const char * name,const char * client)127*00b67f09SDavid van Moolenbroek dlopen_dlz_allowzonexfr(void *driverarg, void *dbdata, const char *name,
128*00b67f09SDavid van Moolenbroek 			const char *client)
129*00b67f09SDavid van Moolenbroek {
130*00b67f09SDavid van Moolenbroek 	dlopen_data_t *cd = (dlopen_data_t *) dbdata;
131*00b67f09SDavid van Moolenbroek 	isc_result_t result;
132*00b67f09SDavid van Moolenbroek 
133*00b67f09SDavid van Moolenbroek 	UNUSED(driverarg);
134*00b67f09SDavid van Moolenbroek 
135*00b67f09SDavid van Moolenbroek 
136*00b67f09SDavid van Moolenbroek 	if (cd->dlz_allowzonexfr == NULL) {
137*00b67f09SDavid van Moolenbroek 		return (ISC_R_NOPERM);
138*00b67f09SDavid van Moolenbroek 	}
139*00b67f09SDavid van Moolenbroek 
140*00b67f09SDavid van Moolenbroek 	MAYBE_LOCK(cd);
141*00b67f09SDavid van Moolenbroek 	result = cd->dlz_allowzonexfr(cd->dbdata, name, client);
142*00b67f09SDavid van Moolenbroek 	MAYBE_UNLOCK(cd);
143*00b67f09SDavid van Moolenbroek 	return (result);
144*00b67f09SDavid van Moolenbroek }
145*00b67f09SDavid van Moolenbroek 
146*00b67f09SDavid van Moolenbroek static isc_result_t
dlopen_dlz_authority(const char * zone,void * driverarg,void * dbdata,dns_sdlzlookup_t * lookup)147*00b67f09SDavid van Moolenbroek dlopen_dlz_authority(const char *zone, void *driverarg, void *dbdata,
148*00b67f09SDavid van Moolenbroek 		     dns_sdlzlookup_t *lookup)
149*00b67f09SDavid van Moolenbroek {
150*00b67f09SDavid van Moolenbroek 	dlopen_data_t *cd = (dlopen_data_t *) dbdata;
151*00b67f09SDavid van Moolenbroek 	isc_result_t result;
152*00b67f09SDavid van Moolenbroek 
153*00b67f09SDavid van Moolenbroek 	UNUSED(driverarg);
154*00b67f09SDavid van Moolenbroek 
155*00b67f09SDavid van Moolenbroek 	if (cd->dlz_authority == NULL) {
156*00b67f09SDavid van Moolenbroek 		return (ISC_R_NOTIMPLEMENTED);
157*00b67f09SDavid van Moolenbroek 	}
158*00b67f09SDavid van Moolenbroek 
159*00b67f09SDavid van Moolenbroek 	MAYBE_LOCK(cd);
160*00b67f09SDavid van Moolenbroek 	result = cd->dlz_authority(zone, cd->dbdata, lookup);
161*00b67f09SDavid van Moolenbroek 	MAYBE_UNLOCK(cd);
162*00b67f09SDavid van Moolenbroek 	return (result);
163*00b67f09SDavid van Moolenbroek }
164*00b67f09SDavid van Moolenbroek 
165*00b67f09SDavid van Moolenbroek static isc_result_t
dlopen_dlz_findzonedb(void * driverarg,void * dbdata,const char * name,dns_clientinfomethods_t * methods,dns_clientinfo_t * clientinfo)166*00b67f09SDavid van Moolenbroek dlopen_dlz_findzonedb(void *driverarg, void *dbdata, const char *name,
167*00b67f09SDavid van Moolenbroek 		      dns_clientinfomethods_t *methods,
168*00b67f09SDavid van Moolenbroek 		      dns_clientinfo_t *clientinfo)
169*00b67f09SDavid van Moolenbroek {
170*00b67f09SDavid van Moolenbroek 	dlopen_data_t *cd = (dlopen_data_t *) dbdata;
171*00b67f09SDavid van Moolenbroek 	isc_result_t result;
172*00b67f09SDavid van Moolenbroek 
173*00b67f09SDavid van Moolenbroek 	UNUSED(driverarg);
174*00b67f09SDavid van Moolenbroek 
175*00b67f09SDavid van Moolenbroek 	MAYBE_LOCK(cd);
176*00b67f09SDavid van Moolenbroek 	result = cd->dlz_findzonedb(cd->dbdata, name, methods, clientinfo);
177*00b67f09SDavid van Moolenbroek 	MAYBE_UNLOCK(cd);
178*00b67f09SDavid van Moolenbroek 	return (result);
179*00b67f09SDavid van Moolenbroek }
180*00b67f09SDavid van Moolenbroek 
181*00b67f09SDavid van Moolenbroek 
182*00b67f09SDavid van Moolenbroek static isc_result_t
dlopen_dlz_lookup(const char * zone,const char * name,void * driverarg,void * dbdata,dns_sdlzlookup_t * lookup,dns_clientinfomethods_t * methods,dns_clientinfo_t * clientinfo)183*00b67f09SDavid van Moolenbroek dlopen_dlz_lookup(const char *zone, const char *name, void *driverarg,
184*00b67f09SDavid van Moolenbroek 		  void *dbdata, dns_sdlzlookup_t *lookup,
185*00b67f09SDavid van Moolenbroek 		  dns_clientinfomethods_t *methods,
186*00b67f09SDavid van Moolenbroek 		  dns_clientinfo_t *clientinfo)
187*00b67f09SDavid van Moolenbroek {
188*00b67f09SDavid van Moolenbroek 	dlopen_data_t *cd = (dlopen_data_t *) dbdata;
189*00b67f09SDavid van Moolenbroek 	isc_result_t result;
190*00b67f09SDavid van Moolenbroek 
191*00b67f09SDavid van Moolenbroek 	UNUSED(driverarg);
192*00b67f09SDavid van Moolenbroek 
193*00b67f09SDavid van Moolenbroek 	MAYBE_LOCK(cd);
194*00b67f09SDavid van Moolenbroek 	result = cd->dlz_lookup(zone, name, cd->dbdata, lookup,
195*00b67f09SDavid van Moolenbroek 				methods, clientinfo);
196*00b67f09SDavid van Moolenbroek 	MAYBE_UNLOCK(cd);
197*00b67f09SDavid van Moolenbroek 	return (result);
198*00b67f09SDavid van Moolenbroek }
199*00b67f09SDavid van Moolenbroek 
200*00b67f09SDavid van Moolenbroek /*
201*00b67f09SDavid van Moolenbroek  * Load a symbol from the library
202*00b67f09SDavid van Moolenbroek  */
203*00b67f09SDavid van Moolenbroek static void *
dl_load_symbol(dlopen_data_t * cd,const char * symbol,isc_boolean_t mandatory)204*00b67f09SDavid van Moolenbroek dl_load_symbol(dlopen_data_t *cd, const char *symbol, isc_boolean_t mandatory) {
205*00b67f09SDavid van Moolenbroek 	void *ptr = dlsym(cd->dl_handle, symbol);
206*00b67f09SDavid van Moolenbroek 	if (ptr == NULL && mandatory) {
207*00b67f09SDavid van Moolenbroek 		dlopen_log(ISC_LOG_ERROR,
208*00b67f09SDavid van Moolenbroek 			   "dlz_dlopen: library '%s' is missing "
209*00b67f09SDavid van Moolenbroek 			   "required symbol '%s'", cd->dl_path, symbol);
210*00b67f09SDavid van Moolenbroek 	}
211*00b67f09SDavid van Moolenbroek 	return (ptr);
212*00b67f09SDavid van Moolenbroek }
213*00b67f09SDavid van Moolenbroek 
214*00b67f09SDavid van Moolenbroek /*
215*00b67f09SDavid van Moolenbroek  * Called at startup for each dlopen zone in named.conf
216*00b67f09SDavid van Moolenbroek  */
217*00b67f09SDavid van Moolenbroek static isc_result_t
dlopen_dlz_create(const char * dlzname,unsigned int argc,char * argv[],void * driverarg,void ** dbdata)218*00b67f09SDavid van Moolenbroek dlopen_dlz_create(const char *dlzname, unsigned int argc, char *argv[],
219*00b67f09SDavid van Moolenbroek 		  void *driverarg, void **dbdata)
220*00b67f09SDavid van Moolenbroek {
221*00b67f09SDavid van Moolenbroek 	dlopen_data_t *cd;
222*00b67f09SDavid van Moolenbroek 	isc_mem_t *mctx = NULL;
223*00b67f09SDavid van Moolenbroek 	isc_result_t result = ISC_R_FAILURE;
224*00b67f09SDavid van Moolenbroek 	int dlopen_flags = 0;
225*00b67f09SDavid van Moolenbroek 
226*00b67f09SDavid van Moolenbroek 	UNUSED(driverarg);
227*00b67f09SDavid van Moolenbroek 
228*00b67f09SDavid van Moolenbroek 	if (argc < 2) {
229*00b67f09SDavid van Moolenbroek 		dlopen_log(ISC_LOG_ERROR,
230*00b67f09SDavid van Moolenbroek 			   "dlz_dlopen driver for '%s' needs a path to "
231*00b67f09SDavid van Moolenbroek 			   "the shared library", dlzname);
232*00b67f09SDavid van Moolenbroek 		return (ISC_R_FAILURE);
233*00b67f09SDavid van Moolenbroek 	}
234*00b67f09SDavid van Moolenbroek 
235*00b67f09SDavid van Moolenbroek 	result = isc_mem_create(0, 0, &mctx);
236*00b67f09SDavid van Moolenbroek 	if (result != ISC_R_SUCCESS)
237*00b67f09SDavid van Moolenbroek 		return (result);
238*00b67f09SDavid van Moolenbroek 
239*00b67f09SDavid van Moolenbroek 	cd = isc_mem_get(mctx, sizeof(*cd));
240*00b67f09SDavid van Moolenbroek 	if (cd == NULL) {
241*00b67f09SDavid van Moolenbroek 		isc_mem_destroy(&mctx);
242*00b67f09SDavid van Moolenbroek 		return (ISC_R_NOMEMORY);
243*00b67f09SDavid van Moolenbroek 	}
244*00b67f09SDavid van Moolenbroek 	memset(cd, 0, sizeof(*cd));
245*00b67f09SDavid van Moolenbroek 
246*00b67f09SDavid van Moolenbroek 	cd->mctx = mctx;
247*00b67f09SDavid van Moolenbroek 
248*00b67f09SDavid van Moolenbroek 	cd->dl_path = isc_mem_strdup(cd->mctx, argv[1]);
249*00b67f09SDavid van Moolenbroek 	if (cd->dl_path == NULL) {
250*00b67f09SDavid van Moolenbroek 		result = ISC_R_NOMEMORY;
251*00b67f09SDavid van Moolenbroek 		goto failed;
252*00b67f09SDavid van Moolenbroek 	}
253*00b67f09SDavid van Moolenbroek 
254*00b67f09SDavid van Moolenbroek 	cd->dlzname = isc_mem_strdup(cd->mctx, dlzname);
255*00b67f09SDavid van Moolenbroek 	if (cd->dlzname == NULL) {
256*00b67f09SDavid van Moolenbroek 		result = ISC_R_NOMEMORY;
257*00b67f09SDavid van Moolenbroek 		goto failed;
258*00b67f09SDavid van Moolenbroek 	}
259*00b67f09SDavid van Moolenbroek 
260*00b67f09SDavid van Moolenbroek 	/* Initialize the lock */
261*00b67f09SDavid van Moolenbroek 	result = isc_mutex_init(&cd->lock);
262*00b67f09SDavid van Moolenbroek 	if (result != ISC_R_SUCCESS)
263*00b67f09SDavid van Moolenbroek 		goto failed;
264*00b67f09SDavid van Moolenbroek 
265*00b67f09SDavid van Moolenbroek 	/* Open the library */
266*00b67f09SDavid van Moolenbroek 	dlopen_flags = RTLD_NOW|RTLD_GLOBAL;
267*00b67f09SDavid van Moolenbroek 
268*00b67f09SDavid van Moolenbroek #ifdef RTLD_DEEPBIND
269*00b67f09SDavid van Moolenbroek 	/*
270*00b67f09SDavid van Moolenbroek 	 * If RTLD_DEEPBIND is available then use it. This can avoid
271*00b67f09SDavid van Moolenbroek 	 * issues with a module using a different version of a system
272*00b67f09SDavid van Moolenbroek 	 * library than one that bind9 uses. For example, bind9 may link
273*00b67f09SDavid van Moolenbroek 	 * to MIT kerberos, but the module may use Heimdal. If we don't
274*00b67f09SDavid van Moolenbroek 	 * use RTLD_DEEPBIND then we could end up with Heimdal functions
275*00b67f09SDavid van Moolenbroek 	 * calling MIT functions, which leads to bizarre results (usually
276*00b67f09SDavid van Moolenbroek 	 * a segfault).
277*00b67f09SDavid van Moolenbroek 	 */
278*00b67f09SDavid van Moolenbroek 	dlopen_flags |= RTLD_DEEPBIND;
279*00b67f09SDavid van Moolenbroek #endif
280*00b67f09SDavid van Moolenbroek 
281*00b67f09SDavid van Moolenbroek 	cd->dl_handle = dlopen(cd->dl_path, dlopen_flags);
282*00b67f09SDavid van Moolenbroek 	if (cd->dl_handle == NULL) {
283*00b67f09SDavid van Moolenbroek 		dlopen_log(ISC_LOG_ERROR,
284*00b67f09SDavid van Moolenbroek 			   "dlz_dlopen failed to open library '%s' - %s",
285*00b67f09SDavid van Moolenbroek 			   cd->dl_path, dlerror());
286*00b67f09SDavid van Moolenbroek 		result = ISC_R_FAILURE;
287*00b67f09SDavid van Moolenbroek 		goto failed;
288*00b67f09SDavid van Moolenbroek 	}
289*00b67f09SDavid van Moolenbroek 
290*00b67f09SDavid van Moolenbroek 	/* Find the symbols */
291*00b67f09SDavid van Moolenbroek 	cd->dlz_version = (dlz_dlopen_version_t *)
292*00b67f09SDavid van Moolenbroek 		dl_load_symbol(cd, "dlz_version", ISC_TRUE);
293*00b67f09SDavid van Moolenbroek 	cd->dlz_create = (dlz_dlopen_create_t *)
294*00b67f09SDavid van Moolenbroek 		dl_load_symbol(cd, "dlz_create", ISC_TRUE);
295*00b67f09SDavid van Moolenbroek 	cd->dlz_lookup = (dlz_dlopen_lookup_t *)
296*00b67f09SDavid van Moolenbroek 		dl_load_symbol(cd, "dlz_lookup", ISC_TRUE);
297*00b67f09SDavid van Moolenbroek 	cd->dlz_findzonedb = (dlz_dlopen_findzonedb_t *)
298*00b67f09SDavid van Moolenbroek 		dl_load_symbol(cd, "dlz_findzonedb", ISC_TRUE);
299*00b67f09SDavid van Moolenbroek 
300*00b67f09SDavid van Moolenbroek 	if (cd->dlz_create == NULL ||
301*00b67f09SDavid van Moolenbroek 	    cd->dlz_version == NULL ||
302*00b67f09SDavid van Moolenbroek 	    cd->dlz_lookup == NULL ||
303*00b67f09SDavid van Moolenbroek 	    cd->dlz_findzonedb == NULL)
304*00b67f09SDavid van Moolenbroek 	{
305*00b67f09SDavid van Moolenbroek 		/* We're missing a required symbol */
306*00b67f09SDavid van Moolenbroek 		result = ISC_R_FAILURE;
307*00b67f09SDavid van Moolenbroek 		goto failed;
308*00b67f09SDavid van Moolenbroek 	}
309*00b67f09SDavid van Moolenbroek 
310*00b67f09SDavid van Moolenbroek 	cd->dlz_allowzonexfr = (dlz_dlopen_allowzonexfr_t *)
311*00b67f09SDavid van Moolenbroek 		dl_load_symbol(cd, "dlz_allowzonexfr", ISC_FALSE);
312*00b67f09SDavid van Moolenbroek 	cd->dlz_allnodes = (dlz_dlopen_allnodes_t *)
313*00b67f09SDavid van Moolenbroek 		dl_load_symbol(cd, "dlz_allnodes",
314*00b67f09SDavid van Moolenbroek 			       ISC_TF(cd->dlz_allowzonexfr != NULL));
315*00b67f09SDavid van Moolenbroek 	cd->dlz_authority = (dlz_dlopen_authority_t *)
316*00b67f09SDavid van Moolenbroek 		dl_load_symbol(cd, "dlz_authority", ISC_FALSE);
317*00b67f09SDavid van Moolenbroek 	cd->dlz_newversion = (dlz_dlopen_newversion_t *)
318*00b67f09SDavid van Moolenbroek 		dl_load_symbol(cd, "dlz_newversion", ISC_FALSE);
319*00b67f09SDavid van Moolenbroek 	cd->dlz_closeversion = (dlz_dlopen_closeversion_t *)
320*00b67f09SDavid van Moolenbroek 		dl_load_symbol(cd, "dlz_closeversion",
321*00b67f09SDavid van Moolenbroek 			       ISC_TF(cd->dlz_newversion != NULL));
322*00b67f09SDavid van Moolenbroek 	cd->dlz_configure = (dlz_dlopen_configure_t *)
323*00b67f09SDavid van Moolenbroek 		dl_load_symbol(cd, "dlz_configure", ISC_FALSE);
324*00b67f09SDavid van Moolenbroek 	cd->dlz_ssumatch = (dlz_dlopen_ssumatch_t *)
325*00b67f09SDavid van Moolenbroek 		dl_load_symbol(cd, "dlz_ssumatch", ISC_FALSE);
326*00b67f09SDavid van Moolenbroek 	cd->dlz_addrdataset = (dlz_dlopen_addrdataset_t *)
327*00b67f09SDavid van Moolenbroek 		dl_load_symbol(cd, "dlz_addrdataset", ISC_FALSE);
328*00b67f09SDavid van Moolenbroek 	cd->dlz_subrdataset = (dlz_dlopen_subrdataset_t *)
329*00b67f09SDavid van Moolenbroek 		dl_load_symbol(cd, "dlz_subrdataset", ISC_FALSE);
330*00b67f09SDavid van Moolenbroek 	cd->dlz_delrdataset = (dlz_dlopen_delrdataset_t *)
331*00b67f09SDavid van Moolenbroek 		dl_load_symbol(cd, "dlz_delrdataset", ISC_FALSE);
332*00b67f09SDavid van Moolenbroek 	cd->dlz_destroy = (dlz_dlopen_destroy_t *)
333*00b67f09SDavid van Moolenbroek 		dl_load_symbol(cd, "dlz_destroy", ISC_FALSE);
334*00b67f09SDavid van Moolenbroek 
335*00b67f09SDavid van Moolenbroek 	/* Check the version of the API is the same */
336*00b67f09SDavid van Moolenbroek 	cd->version = cd->dlz_version(&cd->flags);
337*00b67f09SDavid van Moolenbroek 	if (cd->version < (DLZ_DLOPEN_VERSION - DLZ_DLOPEN_AGE) ||
338*00b67f09SDavid van Moolenbroek 	    cd->version > DLZ_DLOPEN_VERSION)
339*00b67f09SDavid van Moolenbroek 	{
340*00b67f09SDavid van Moolenbroek 		dlopen_log(ISC_LOG_ERROR,
341*00b67f09SDavid van Moolenbroek 			   "dlz_dlopen: %s: incorrect driver API version %d, "
342*00b67f09SDavid van Moolenbroek 			   "requires %d",
343*00b67f09SDavid van Moolenbroek 			   cd->dl_path, cd->version, DLZ_DLOPEN_VERSION);
344*00b67f09SDavid van Moolenbroek 		result = ISC_R_FAILURE;
345*00b67f09SDavid van Moolenbroek 		goto failed;
346*00b67f09SDavid van Moolenbroek 	}
347*00b67f09SDavid van Moolenbroek 
348*00b67f09SDavid van Moolenbroek 	/*
349*00b67f09SDavid van Moolenbroek 	 * Call the library's create function. Note that this is an
350*00b67f09SDavid van Moolenbroek 	 * extended version of dlz create, with the addition of
351*00b67f09SDavid van Moolenbroek 	 * named function pointers for helper functions that the
352*00b67f09SDavid van Moolenbroek 	 * driver will need. This avoids the need for the backend to
353*00b67f09SDavid van Moolenbroek 	 * link the BIND9 libraries
354*00b67f09SDavid van Moolenbroek 	 */
355*00b67f09SDavid van Moolenbroek 	MAYBE_LOCK(cd);
356*00b67f09SDavid van Moolenbroek 	result = cd->dlz_create(dlzname, argc-1, argv+1,
357*00b67f09SDavid van Moolenbroek 				&cd->dbdata,
358*00b67f09SDavid van Moolenbroek 				"log", dlopen_log,
359*00b67f09SDavid van Moolenbroek 				"putrr", dns_sdlz_putrr,
360*00b67f09SDavid van Moolenbroek 				"putnamedrr", dns_sdlz_putnamedrr,
361*00b67f09SDavid van Moolenbroek 				"writeable_zone", dns_dlz_writeablezone,
362*00b67f09SDavid van Moolenbroek 				NULL);
363*00b67f09SDavid van Moolenbroek 	MAYBE_UNLOCK(cd);
364*00b67f09SDavid van Moolenbroek 	if (result != ISC_R_SUCCESS)
365*00b67f09SDavid van Moolenbroek 		goto failed;
366*00b67f09SDavid van Moolenbroek 
367*00b67f09SDavid van Moolenbroek 	*dbdata = cd;
368*00b67f09SDavid van Moolenbroek 
369*00b67f09SDavid van Moolenbroek 	return (ISC_R_SUCCESS);
370*00b67f09SDavid van Moolenbroek 
371*00b67f09SDavid van Moolenbroek failed:
372*00b67f09SDavid van Moolenbroek 	dlopen_log(ISC_LOG_ERROR, "dlz_dlopen of '%s' failed", dlzname);
373*00b67f09SDavid van Moolenbroek 	if (cd->dl_path != NULL)
374*00b67f09SDavid van Moolenbroek 		isc_mem_free(mctx, cd->dl_path);
375*00b67f09SDavid van Moolenbroek 	if (cd->dlzname != NULL)
376*00b67f09SDavid van Moolenbroek 		isc_mem_free(mctx, cd->dlzname);
377*00b67f09SDavid van Moolenbroek 	if (dlopen_flags != 0)
378*00b67f09SDavid van Moolenbroek 		(void) isc_mutex_destroy(&cd->lock);
379*00b67f09SDavid van Moolenbroek #ifdef HAVE_DLCLOSE
380*00b67f09SDavid van Moolenbroek 	if (cd->dl_handle)
381*00b67f09SDavid van Moolenbroek 		dlclose(cd->dl_handle);
382*00b67f09SDavid van Moolenbroek #endif
383*00b67f09SDavid van Moolenbroek 	isc_mem_put(mctx, cd, sizeof(*cd));
384*00b67f09SDavid van Moolenbroek 	isc_mem_destroy(&mctx);
385*00b67f09SDavid van Moolenbroek 	return (result);
386*00b67f09SDavid van Moolenbroek }
387*00b67f09SDavid van Moolenbroek 
388*00b67f09SDavid van Moolenbroek /*
389*00b67f09SDavid van Moolenbroek  * Called when bind is shutting down
390*00b67f09SDavid van Moolenbroek  */
391*00b67f09SDavid van Moolenbroek static void
dlopen_dlz_destroy(void * driverarg,void * dbdata)392*00b67f09SDavid van Moolenbroek dlopen_dlz_destroy(void *driverarg, void *dbdata) {
393*00b67f09SDavid van Moolenbroek 	dlopen_data_t *cd = (dlopen_data_t *) dbdata;
394*00b67f09SDavid van Moolenbroek 	isc_mem_t *mctx;
395*00b67f09SDavid van Moolenbroek 
396*00b67f09SDavid van Moolenbroek 	UNUSED(driverarg);
397*00b67f09SDavid van Moolenbroek 
398*00b67f09SDavid van Moolenbroek 	if (cd->dlz_destroy) {
399*00b67f09SDavid van Moolenbroek 		MAYBE_LOCK(cd);
400*00b67f09SDavid van Moolenbroek 		cd->dlz_destroy(cd->dbdata);
401*00b67f09SDavid van Moolenbroek 		MAYBE_UNLOCK(cd);
402*00b67f09SDavid van Moolenbroek 	}
403*00b67f09SDavid van Moolenbroek 
404*00b67f09SDavid van Moolenbroek 	if (cd->dl_path)
405*00b67f09SDavid van Moolenbroek 		isc_mem_free(cd->mctx, cd->dl_path);
406*00b67f09SDavid van Moolenbroek 	if (cd->dlzname)
407*00b67f09SDavid van Moolenbroek 		isc_mem_free(cd->mctx, cd->dlzname);
408*00b67f09SDavid van Moolenbroek 
409*00b67f09SDavid van Moolenbroek #ifdef HAVE_DLCLOSE
410*00b67f09SDavid van Moolenbroek 	if (cd->dl_handle)
411*00b67f09SDavid van Moolenbroek 		dlclose(cd->dl_handle);
412*00b67f09SDavid van Moolenbroek #endif
413*00b67f09SDavid van Moolenbroek 
414*00b67f09SDavid van Moolenbroek 	(void) isc_mutex_destroy(&cd->lock);
415*00b67f09SDavid van Moolenbroek 
416*00b67f09SDavid van Moolenbroek 	mctx = cd->mctx;
417*00b67f09SDavid van Moolenbroek 	isc_mem_put(mctx, cd, sizeof(*cd));
418*00b67f09SDavid van Moolenbroek 	isc_mem_destroy(&mctx);
419*00b67f09SDavid van Moolenbroek }
420*00b67f09SDavid van Moolenbroek 
421*00b67f09SDavid van Moolenbroek /*
422*00b67f09SDavid van Moolenbroek  * Called to start a transaction
423*00b67f09SDavid van Moolenbroek  */
424*00b67f09SDavid van Moolenbroek static isc_result_t
dlopen_dlz_newversion(const char * zone,void * driverarg,void * dbdata,void ** versionp)425*00b67f09SDavid van Moolenbroek dlopen_dlz_newversion(const char *zone, void *driverarg, void *dbdata,
426*00b67f09SDavid van Moolenbroek 		      void **versionp)
427*00b67f09SDavid van Moolenbroek {
428*00b67f09SDavid van Moolenbroek 	dlopen_data_t *cd = (dlopen_data_t *) dbdata;
429*00b67f09SDavid van Moolenbroek 	isc_result_t result;
430*00b67f09SDavid van Moolenbroek 
431*00b67f09SDavid van Moolenbroek 	UNUSED(driverarg);
432*00b67f09SDavid van Moolenbroek 
433*00b67f09SDavid van Moolenbroek 	if (cd->dlz_newversion == NULL)
434*00b67f09SDavid van Moolenbroek 		return (ISC_R_NOTIMPLEMENTED);
435*00b67f09SDavid van Moolenbroek 
436*00b67f09SDavid van Moolenbroek 	MAYBE_LOCK(cd);
437*00b67f09SDavid van Moolenbroek 	result = cd->dlz_newversion(zone, cd->dbdata, versionp);
438*00b67f09SDavid van Moolenbroek 	MAYBE_UNLOCK(cd);
439*00b67f09SDavid van Moolenbroek 	return (result);
440*00b67f09SDavid van Moolenbroek }
441*00b67f09SDavid van Moolenbroek 
442*00b67f09SDavid van Moolenbroek /*
443*00b67f09SDavid van Moolenbroek  * Called to end a transaction
444*00b67f09SDavid van Moolenbroek  */
445*00b67f09SDavid van Moolenbroek static void
dlopen_dlz_closeversion(const char * zone,isc_boolean_t commit,void * driverarg,void * dbdata,void ** versionp)446*00b67f09SDavid van Moolenbroek dlopen_dlz_closeversion(const char *zone, isc_boolean_t commit,
447*00b67f09SDavid van Moolenbroek 			void *driverarg, void *dbdata, void **versionp)
448*00b67f09SDavid van Moolenbroek {
449*00b67f09SDavid van Moolenbroek 	dlopen_data_t *cd = (dlopen_data_t *) dbdata;
450*00b67f09SDavid van Moolenbroek 
451*00b67f09SDavid van Moolenbroek 	UNUSED(driverarg);
452*00b67f09SDavid van Moolenbroek 
453*00b67f09SDavid van Moolenbroek 	if (cd->dlz_newversion == NULL) {
454*00b67f09SDavid van Moolenbroek 		*versionp = NULL;
455*00b67f09SDavid van Moolenbroek 		return;
456*00b67f09SDavid van Moolenbroek 	}
457*00b67f09SDavid van Moolenbroek 
458*00b67f09SDavid van Moolenbroek 	MAYBE_LOCK(cd);
459*00b67f09SDavid van Moolenbroek 	cd->dlz_closeversion(zone, commit, cd->dbdata, versionp);
460*00b67f09SDavid van Moolenbroek 	MAYBE_UNLOCK(cd);
461*00b67f09SDavid van Moolenbroek }
462*00b67f09SDavid van Moolenbroek 
463*00b67f09SDavid van Moolenbroek /*
464*00b67f09SDavid van Moolenbroek  * Called on startup to configure any writeable zones
465*00b67f09SDavid van Moolenbroek  */
466*00b67f09SDavid van Moolenbroek static isc_result_t
dlopen_dlz_configure(dns_view_t * view,dns_dlzdb_t * dlzdb,void * driverarg,void * dbdata)467*00b67f09SDavid van Moolenbroek dlopen_dlz_configure(dns_view_t *view, dns_dlzdb_t *dlzdb,
468*00b67f09SDavid van Moolenbroek 		     void *driverarg, void *dbdata)
469*00b67f09SDavid van Moolenbroek {
470*00b67f09SDavid van Moolenbroek 	dlopen_data_t *cd = (dlopen_data_t *) dbdata;
471*00b67f09SDavid van Moolenbroek 	isc_result_t result;
472*00b67f09SDavid van Moolenbroek 
473*00b67f09SDavid van Moolenbroek 	UNUSED(driverarg);
474*00b67f09SDavid van Moolenbroek 
475*00b67f09SDavid van Moolenbroek 	if (cd->dlz_configure == NULL)
476*00b67f09SDavid van Moolenbroek 		return (ISC_R_SUCCESS);
477*00b67f09SDavid van Moolenbroek 
478*00b67f09SDavid van Moolenbroek 	MAYBE_LOCK(cd);
479*00b67f09SDavid van Moolenbroek 	cd->in_configure = ISC_TRUE;
480*00b67f09SDavid van Moolenbroek 	result = cd->dlz_configure(view, dlzdb, cd->dbdata);
481*00b67f09SDavid van Moolenbroek 	cd->in_configure = ISC_FALSE;
482*00b67f09SDavid van Moolenbroek 	MAYBE_UNLOCK(cd);
483*00b67f09SDavid van Moolenbroek 
484*00b67f09SDavid van Moolenbroek 	return (result);
485*00b67f09SDavid van Moolenbroek }
486*00b67f09SDavid van Moolenbroek 
487*00b67f09SDavid van Moolenbroek 
488*00b67f09SDavid van Moolenbroek /*
489*00b67f09SDavid van Moolenbroek  * Check for authority to change a name
490*00b67f09SDavid van Moolenbroek  */
491*00b67f09SDavid van Moolenbroek static isc_boolean_t
dlopen_dlz_ssumatch(const char * signer,const char * name,const char * tcpaddr,const char * type,const char * key,isc_uint32_t keydatalen,unsigned char * keydata,void * driverarg,void * dbdata)492*00b67f09SDavid van Moolenbroek dlopen_dlz_ssumatch(const char *signer, const char *name, const char *tcpaddr,
493*00b67f09SDavid van Moolenbroek 		    const char *type, const char *key, isc_uint32_t keydatalen,
494*00b67f09SDavid van Moolenbroek 		    unsigned char *keydata, void *driverarg, void *dbdata)
495*00b67f09SDavid van Moolenbroek {
496*00b67f09SDavid van Moolenbroek 	dlopen_data_t *cd = (dlopen_data_t *) dbdata;
497*00b67f09SDavid van Moolenbroek 	isc_boolean_t ret;
498*00b67f09SDavid van Moolenbroek 
499*00b67f09SDavid van Moolenbroek 	UNUSED(driverarg);
500*00b67f09SDavid van Moolenbroek 
501*00b67f09SDavid van Moolenbroek 	if (cd->dlz_ssumatch == NULL)
502*00b67f09SDavid van Moolenbroek 		return (ISC_FALSE);
503*00b67f09SDavid van Moolenbroek 
504*00b67f09SDavid van Moolenbroek 	MAYBE_LOCK(cd);
505*00b67f09SDavid van Moolenbroek 	ret = cd->dlz_ssumatch(signer, name, tcpaddr, type, key, keydatalen,
506*00b67f09SDavid van Moolenbroek 			       keydata, cd->dbdata);
507*00b67f09SDavid van Moolenbroek 	MAYBE_UNLOCK(cd);
508*00b67f09SDavid van Moolenbroek 
509*00b67f09SDavid van Moolenbroek 	return (ret);
510*00b67f09SDavid van Moolenbroek }
511*00b67f09SDavid van Moolenbroek 
512*00b67f09SDavid van Moolenbroek 
513*00b67f09SDavid van Moolenbroek /*
514*00b67f09SDavid van Moolenbroek  * Add an rdataset
515*00b67f09SDavid van Moolenbroek  */
516*00b67f09SDavid van Moolenbroek static isc_result_t
dlopen_dlz_addrdataset(const char * name,const char * rdatastr,void * driverarg,void * dbdata,void * version)517*00b67f09SDavid van Moolenbroek dlopen_dlz_addrdataset(const char *name, const char *rdatastr,
518*00b67f09SDavid van Moolenbroek 		       void *driverarg, void *dbdata, void *version)
519*00b67f09SDavid van Moolenbroek {
520*00b67f09SDavid van Moolenbroek 	dlopen_data_t *cd = (dlopen_data_t *) dbdata;
521*00b67f09SDavid van Moolenbroek 	isc_result_t result;
522*00b67f09SDavid van Moolenbroek 
523*00b67f09SDavid van Moolenbroek 	UNUSED(driverarg);
524*00b67f09SDavid van Moolenbroek 
525*00b67f09SDavid van Moolenbroek 	if (cd->dlz_addrdataset == NULL)
526*00b67f09SDavid van Moolenbroek 		return (ISC_R_NOTIMPLEMENTED);
527*00b67f09SDavid van Moolenbroek 
528*00b67f09SDavid van Moolenbroek 	MAYBE_LOCK(cd);
529*00b67f09SDavid van Moolenbroek 	result = cd->dlz_addrdataset(name, rdatastr, cd->dbdata, version);
530*00b67f09SDavid van Moolenbroek 	MAYBE_UNLOCK(cd);
531*00b67f09SDavid van Moolenbroek 
532*00b67f09SDavid van Moolenbroek 	return (result);
533*00b67f09SDavid van Moolenbroek }
534*00b67f09SDavid van Moolenbroek 
535*00b67f09SDavid van Moolenbroek /*
536*00b67f09SDavid van Moolenbroek  * Subtract an rdataset
537*00b67f09SDavid van Moolenbroek  */
538*00b67f09SDavid van Moolenbroek static isc_result_t
dlopen_dlz_subrdataset(const char * name,const char * rdatastr,void * driverarg,void * dbdata,void * version)539*00b67f09SDavid van Moolenbroek dlopen_dlz_subrdataset(const char *name, const char *rdatastr,
540*00b67f09SDavid van Moolenbroek 		       void *driverarg, void *dbdata, void *version)
541*00b67f09SDavid van Moolenbroek {
542*00b67f09SDavid van Moolenbroek 	dlopen_data_t *cd = (dlopen_data_t *) dbdata;
543*00b67f09SDavid van Moolenbroek 	isc_result_t result;
544*00b67f09SDavid van Moolenbroek 
545*00b67f09SDavid van Moolenbroek 	UNUSED(driverarg);
546*00b67f09SDavid van Moolenbroek 
547*00b67f09SDavid van Moolenbroek 	if (cd->dlz_subrdataset == NULL)
548*00b67f09SDavid van Moolenbroek 		return (ISC_R_NOTIMPLEMENTED);
549*00b67f09SDavid van Moolenbroek 
550*00b67f09SDavid van Moolenbroek 	MAYBE_LOCK(cd);
551*00b67f09SDavid van Moolenbroek 	result = cd->dlz_subrdataset(name, rdatastr, cd->dbdata, version);
552*00b67f09SDavid van Moolenbroek 	MAYBE_UNLOCK(cd);
553*00b67f09SDavid van Moolenbroek 
554*00b67f09SDavid van Moolenbroek 	return (result);
555*00b67f09SDavid van Moolenbroek }
556*00b67f09SDavid van Moolenbroek 
557*00b67f09SDavid van Moolenbroek /*
558*00b67f09SDavid van Moolenbroek   delete a rdataset
559*00b67f09SDavid van Moolenbroek  */
560*00b67f09SDavid van Moolenbroek static isc_result_t
dlopen_dlz_delrdataset(const char * name,const char * type,void * driverarg,void * dbdata,void * version)561*00b67f09SDavid van Moolenbroek dlopen_dlz_delrdataset(const char *name, const char *type,
562*00b67f09SDavid van Moolenbroek 		       void *driverarg, void *dbdata, void *version)
563*00b67f09SDavid van Moolenbroek {
564*00b67f09SDavid van Moolenbroek 	dlopen_data_t *cd = (dlopen_data_t *) dbdata;
565*00b67f09SDavid van Moolenbroek 	isc_result_t result;
566*00b67f09SDavid van Moolenbroek 
567*00b67f09SDavid van Moolenbroek 	UNUSED(driverarg);
568*00b67f09SDavid van Moolenbroek 
569*00b67f09SDavid van Moolenbroek 	if (cd->dlz_delrdataset == NULL)
570*00b67f09SDavid van Moolenbroek 		return (ISC_R_NOTIMPLEMENTED);
571*00b67f09SDavid van Moolenbroek 
572*00b67f09SDavid van Moolenbroek 	MAYBE_LOCK(cd);
573*00b67f09SDavid van Moolenbroek 	result = cd->dlz_delrdataset(name, type, cd->dbdata, version);
574*00b67f09SDavid van Moolenbroek 	MAYBE_UNLOCK(cd);
575*00b67f09SDavid van Moolenbroek 
576*00b67f09SDavid van Moolenbroek 	return (result);
577*00b67f09SDavid van Moolenbroek }
578*00b67f09SDavid van Moolenbroek 
579*00b67f09SDavid van Moolenbroek 
580*00b67f09SDavid van Moolenbroek static dns_sdlzmethods_t dlz_dlopen_methods = {
581*00b67f09SDavid van Moolenbroek 	dlopen_dlz_create,
582*00b67f09SDavid van Moolenbroek 	dlopen_dlz_destroy,
583*00b67f09SDavid van Moolenbroek 	dlopen_dlz_findzonedb,
584*00b67f09SDavid van Moolenbroek 	dlopen_dlz_lookup,
585*00b67f09SDavid van Moolenbroek 	dlopen_dlz_authority,
586*00b67f09SDavid van Moolenbroek 	dlopen_dlz_allnodes,
587*00b67f09SDavid van Moolenbroek 	dlopen_dlz_allowzonexfr,
588*00b67f09SDavid van Moolenbroek 	dlopen_dlz_newversion,
589*00b67f09SDavid van Moolenbroek 	dlopen_dlz_closeversion,
590*00b67f09SDavid van Moolenbroek 	dlopen_dlz_configure,
591*00b67f09SDavid van Moolenbroek 	dlopen_dlz_ssumatch,
592*00b67f09SDavid van Moolenbroek 	dlopen_dlz_addrdataset,
593*00b67f09SDavid van Moolenbroek 	dlopen_dlz_subrdataset,
594*00b67f09SDavid van Moolenbroek 	dlopen_dlz_delrdataset
595*00b67f09SDavid van Moolenbroek };
596*00b67f09SDavid van Moolenbroek #endif
597*00b67f09SDavid van Moolenbroek 
598*00b67f09SDavid van Moolenbroek /*
599*00b67f09SDavid van Moolenbroek  * Register driver with BIND
600*00b67f09SDavid van Moolenbroek  */
601*00b67f09SDavid van Moolenbroek isc_result_t
dlz_dlopen_init(isc_mem_t * mctx)602*00b67f09SDavid van Moolenbroek dlz_dlopen_init(isc_mem_t *mctx) {
603*00b67f09SDavid van Moolenbroek #ifndef ISC_DLZ_DLOPEN
604*00b67f09SDavid van Moolenbroek 	UNUSED(mctx);
605*00b67f09SDavid van Moolenbroek 	return (ISC_R_NOTIMPLEMENTED);
606*00b67f09SDavid van Moolenbroek #else
607*00b67f09SDavid van Moolenbroek 	isc_result_t result;
608*00b67f09SDavid van Moolenbroek 
609*00b67f09SDavid van Moolenbroek 	dlopen_log(2, "Registering DLZ_dlopen driver");
610*00b67f09SDavid van Moolenbroek 
611*00b67f09SDavid van Moolenbroek 	result = dns_sdlzregister("dlopen", &dlz_dlopen_methods, NULL,
612*00b67f09SDavid van Moolenbroek 				  DNS_SDLZFLAG_RELATIVEOWNER |
613*00b67f09SDavid van Moolenbroek 				  DNS_SDLZFLAG_RELATIVERDATA |
614*00b67f09SDavid van Moolenbroek 				  DNS_SDLZFLAG_THREADSAFE,
615*00b67f09SDavid van Moolenbroek 				  mctx, &dlz_dlopen);
616*00b67f09SDavid van Moolenbroek 
617*00b67f09SDavid van Moolenbroek 	if (result != ISC_R_SUCCESS) {
618*00b67f09SDavid van Moolenbroek 		UNEXPECTED_ERROR(__FILE__, __LINE__,
619*00b67f09SDavid van Moolenbroek 				 "dns_sdlzregister() failed: %s",
620*00b67f09SDavid van Moolenbroek 				 isc_result_totext(result));
621*00b67f09SDavid van Moolenbroek 		result = ISC_R_UNEXPECTED;
622*00b67f09SDavid van Moolenbroek 	}
623*00b67f09SDavid van Moolenbroek 
624*00b67f09SDavid van Moolenbroek 	return (result);
625*00b67f09SDavid van Moolenbroek #endif
626*00b67f09SDavid van Moolenbroek }
627*00b67f09SDavid van Moolenbroek 
628*00b67f09SDavid van Moolenbroek 
629*00b67f09SDavid van Moolenbroek /*
630*00b67f09SDavid van Moolenbroek  * Unregister the driver
631*00b67f09SDavid van Moolenbroek  */
632*00b67f09SDavid van Moolenbroek void
dlz_dlopen_clear(void)633*00b67f09SDavid van Moolenbroek dlz_dlopen_clear(void) {
634*00b67f09SDavid van Moolenbroek #ifdef ISC_DLZ_DLOPEN
635*00b67f09SDavid van Moolenbroek 	dlopen_log(2, "Unregistering DLZ_dlopen driver");
636*00b67f09SDavid van Moolenbroek 	if (dlz_dlopen != NULL)
637*00b67f09SDavid van Moolenbroek 		dns_sdlzunregister(&dlz_dlopen);
638*00b67f09SDavid van Moolenbroek #endif
639*00b67f09SDavid van Moolenbroek }
640