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