]> CyberLeo.Net >> Repos - FreeBSD/releng/9.3.git/blob - contrib/bind9/lib/dns/dlz.c
Copy stable/9 to releng/9.3 as part of the 9.3-RELEASE cycle.
[FreeBSD/releng/9.3.git] / contrib / bind9 / lib / dns / dlz.c
1 /*
2  * Portions Copyright (C) 2005, 2007, 2009-2013  Internet Systems Consortium, Inc. ("ISC")
3  * Portions Copyright (C) 1999-2001  Internet Software Consortium.
4  *
5  * Permission to use, copy, modify, and/or distribute this software for any
6  * purpose with or without fee is hereby granted, provided that the above
7  * copyright notice and this permission notice appear in all copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
10  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
11  * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
12  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
13  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
14  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15  * PERFORMANCE OF THIS SOFTWARE.
16  */
17
18 /*
19  * Copyright (C) 2002 Stichting NLnet, Netherlands, stichting@nlnet.nl.
20  *
21  * Permission to use, copy, modify, and distribute this software for any
22  * purpose with or without fee is hereby granted, provided that the
23  * above copyright notice and this permission notice appear in all
24  * copies.
25  *
26  * THE SOFTWARE IS PROVIDED "AS IS" AND STICHTING NLNET
27  * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
28  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
29  * STICHTING NLNET BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR
30  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
31  * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
32  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE
33  * USE OR PERFORMANCE OF THIS SOFTWARE.
34  *
35  * The development of Dynamically Loadable Zones (DLZ) for Bind 9 was
36  * conceived and contributed by Rob Butler.
37  *
38  * Permission to use, copy, modify, and distribute this software for any
39  * purpose with or without fee is hereby granted, provided that the
40  * above copyright notice and this permission notice appear in all
41  * copies.
42  *
43  * THE SOFTWARE IS PROVIDED "AS IS" AND ROB BUTLER
44  * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
45  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
46  * ROB BUTLER BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR
47  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
48  * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
49  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE
50  * USE OR PERFORMANCE OF THIS SOFTWARE.
51  */
52
53 /* $Id$ */
54
55 /*! \file */
56
57 /***
58  *** Imports
59  ***/
60
61 #include <config.h>
62
63 #include <dns/fixedname.h>
64 #include <dns/log.h>
65 #include <dns/master.h>
66 #include <dns/dlz.h>
67 #include <dns/ssu.h>
68 #include <dns/zone.h>
69
70
71 #include <isc/buffer.h>
72 #include <isc/magic.h>
73 #include <isc/mem.h>
74 #include <isc/once.h>
75 #include <isc/rwlock.h>
76 #include <isc/string.h>
77 #include <isc/util.h>
78
79 /***
80  *** Supported DLZ DB Implementations Registry
81  ***/
82
83 static ISC_LIST(dns_dlzimplementation_t) dlz_implementations;
84 static isc_rwlock_t dlz_implock;
85 static isc_once_t once = ISC_ONCE_INIT;
86
87 static void
88 dlz_initialize(void) {
89         RUNTIME_CHECK(isc_rwlock_init(&dlz_implock, 0, 0) == ISC_R_SUCCESS);
90         ISC_LIST_INIT(dlz_implementations);
91 }
92
93 /*%
94  * Searches the dlz_implementations list for a driver matching name.
95  */
96 static inline dns_dlzimplementation_t *
97 dlz_impfind(const char *name) {
98         dns_dlzimplementation_t *imp;
99
100         for (imp = ISC_LIST_HEAD(dlz_implementations);
101              imp != NULL;
102              imp = ISC_LIST_NEXT(imp, link))
103                 if (strcasecmp(name, imp->name) == 0)
104                         return (imp);
105         return (NULL);
106 }
107
108 /***
109  *** Basic DLZ Methods
110  ***/
111
112 isc_result_t
113 dns_dlzallowzonexfr(dns_view_t *view, dns_name_t *name,
114                     isc_sockaddr_t *clientaddr, dns_db_t **dbp)
115 {
116         isc_result_t result;
117         dns_dlzallowzonexfr_t allowzonexfr;
118         dns_dlzdb_t *dlzdatabase;
119
120         /*
121          * Performs checks to make sure data is as we expect it to be.
122          */
123         REQUIRE(DNS_DLZ_VALID(view->dlzdatabase));
124         REQUIRE(name != NULL);
125         REQUIRE(dbp != NULL && *dbp == NULL);
126
127         /* ask driver if the zone is supported */
128         dlzdatabase = view->dlzdatabase;
129         allowzonexfr = dlzdatabase->implementation->methods->allowzonexfr;
130         result = (*allowzonexfr)(dlzdatabase->implementation->driverarg,
131                                  dlzdatabase->dbdata, dlzdatabase->mctx,
132                                  view->rdclass, name, clientaddr, dbp);
133
134         if (result == ISC_R_NOTIMPLEMENTED)
135                 return (ISC_R_NOTFOUND);
136         return (result);
137 }
138
139 isc_result_t
140 dns_dlzcreate(isc_mem_t *mctx, const char *dlzname, const char *drivername,
141               unsigned int argc, char *argv[], dns_dlzdb_t **dbp)
142 {
143         dns_dlzimplementation_t *impinfo;
144         isc_result_t result;
145         dns_dlzdb_t *db = NULL;
146
147         /*
148          * initialize the dlz_implementations list, this is guaranteed
149          * to only really happen once.
150          */
151         RUNTIME_CHECK(isc_once_do(&once, dlz_initialize) == ISC_R_SUCCESS);
152
153         /*
154          * Performs checks to make sure data is as we expect it to be.
155          */
156         REQUIRE(dbp != NULL && *dbp == NULL);
157         REQUIRE(dlzname != NULL);
158         REQUIRE(drivername != NULL);
159         REQUIRE(mctx != NULL);
160
161         /* write log message */
162         isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
163                       DNS_LOGMODULE_DLZ, ISC_LOG_INFO,
164                       "Loading '%s' using driver %s", dlzname, drivername);
165
166         /* lock the dlz_implementations list so we can search it. */
167         RWLOCK(&dlz_implock, isc_rwlocktype_read);
168
169         /* search for the driver implementation  */
170         impinfo = dlz_impfind(drivername);
171         if (impinfo == NULL) {
172                 RWUNLOCK(&dlz_implock, isc_rwlocktype_read);
173
174                 isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
175                               DNS_LOGMODULE_DLZ, ISC_LOG_ERROR,
176                               "unsupported DLZ database driver '%s'."
177                               "  %s not loaded.",
178                               drivername, dlzname);
179
180                 return (ISC_R_NOTFOUND);
181         }
182
183         /* Allocate memory to hold the DLZ database driver */
184         db = isc_mem_get(mctx, sizeof(dns_dlzdb_t));
185         if (db == NULL) {
186                 RWUNLOCK(&dlz_implock, isc_rwlocktype_read);
187                 return (ISC_R_NOMEMORY);
188         }
189
190         /* Make sure memory region is set to all 0's */
191         memset(db, 0, sizeof(dns_dlzdb_t));
192
193         db->implementation = impinfo;
194
195         /* Create a new database using implementation 'drivername'. */
196         result = ((impinfo->methods->create)(mctx, dlzname, argc, argv,
197                                              impinfo->driverarg,
198                                              &db->dbdata));
199
200         /* mark the DLZ driver as valid */
201         if (result == ISC_R_SUCCESS) {
202                 RWUNLOCK(&dlz_implock, isc_rwlocktype_read);
203                 db->magic = DNS_DLZ_MAGIC;
204                 isc_mem_attach(mctx, &db->mctx);
205                 isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
206                               DNS_LOGMODULE_DLZ, ISC_LOG_DEBUG(2),
207                               "DLZ driver loaded successfully.");
208                 *dbp = db;
209                 return (ISC_R_SUCCESS);
210         } else {
211                 isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
212                               DNS_LOGMODULE_DLZ, ISC_LOG_ERROR,
213                               "DLZ driver failed to load.");
214         }
215
216         /* impinfo->methods->create failed. */
217         RWUNLOCK(&dlz_implock, isc_rwlocktype_read);
218         isc_mem_put(mctx, db, sizeof(dns_dlzdb_t));
219         return (result);
220 }
221
222 void
223 dns_dlzdestroy(dns_dlzdb_t **dbp) {
224         isc_mem_t *mctx;
225         dns_dlzdestroy_t destroy;
226
227         /* Write debugging message to log */
228         isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
229                       DNS_LOGMODULE_DLZ, ISC_LOG_DEBUG(2),
230                       "Unloading DLZ driver.");
231
232         /*
233          * Perform checks to make sure data is as we expect it to be.
234          */
235         REQUIRE(dbp != NULL && DNS_DLZ_VALID(*dbp));
236
237 #ifdef BIND9
238         if ((*dbp)->ssutable != NULL) {
239                 dns_ssutable_detach(&(*dbp)->ssutable);
240         }
241 #endif
242
243         /* call the drivers destroy method */
244         if ((*dbp) != NULL) {
245                 mctx = (*dbp)->mctx;
246                 destroy = (*dbp)->implementation->methods->destroy;
247                 (*destroy)((*dbp)->implementation->driverarg,(*dbp)->dbdata);
248                 /* return memory */
249                 isc_mem_put(mctx, (*dbp), sizeof(dns_dlzdb_t));
250                 isc_mem_detach(&mctx);
251         }
252
253         *dbp = NULL;
254 }
255
256
257 isc_result_t
258 dns_dlzfindzone(dns_view_t *view, dns_name_t *name, unsigned int minlabels,
259                 dns_db_t **dbp)
260 {
261         dns_fixedname_t fname;
262         dns_name_t *zonename;
263         unsigned int namelabels;
264         unsigned int i;
265         isc_result_t result;
266         dns_dlzfindzone_t findzone;
267         dns_dlzdb_t *dlzdatabase;
268
269         /*
270          * Performs checks to make sure data is as we expect it to be.
271          */
272         REQUIRE(DNS_DLZ_VALID(view->dlzdatabase));
273         REQUIRE(name != NULL);
274         REQUIRE(dbp != NULL && *dbp == NULL);
275
276         /* setup a "fixed" dns name */
277         dns_fixedname_init(&fname);
278         zonename = dns_fixedname_name(&fname);
279
280         /* count the number of labels in the name */
281         namelabels = dns_name_countlabels(name);
282
283         /*
284          * loop through starting with the longest domain name and
285          * trying shorter names portions of the name until we find a
286          * match, have an error, or are below the 'minlabels'
287          * threshold.  minlabels is 0, if the standard database didn't
288          * have a zone name match.  Otherwise minlabels is the number
289          * of labels in that name.  We need to beat that for a
290          * "better" match for the DLZ database to be authoritative
291          * instead of the standard database.
292          */
293         for (i = namelabels; i > minlabels && i > 1; i--) {
294                 if (i == namelabels) {
295                         result = dns_name_copy(name, zonename, NULL);
296                         if (result != ISC_R_SUCCESS)
297                                 return (result);
298                 } else
299                         dns_name_split(name, i, NULL, zonename);
300
301                 /* ask SDLZ driver if the zone is supported */
302                 dlzdatabase = view->dlzdatabase;
303                 findzone = dlzdatabase->implementation->methods->findzone;
304                 result = (*findzone)(dlzdatabase->implementation->driverarg,
305                                      dlzdatabase->dbdata, dlzdatabase->mctx,
306                                      view->rdclass, zonename, dbp);
307                 if (result != ISC_R_NOTFOUND)
308                         return (result);
309         }
310         return (ISC_R_NOTFOUND);
311 }
312
313 /*%
314  * Registers a DLZ driver.  This basically just adds the dlz
315  * driver to the list of available drivers in the dlz_implementations list.
316  */
317 isc_result_t
318 dns_dlzregister(const char *drivername, const dns_dlzmethods_t *methods,
319                 void *driverarg, isc_mem_t *mctx,
320                 dns_dlzimplementation_t **dlzimp)
321 {
322
323         dns_dlzimplementation_t *dlz_imp;
324
325         /* Write debugging message to log */
326         isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
327                       DNS_LOGMODULE_DLZ, ISC_LOG_DEBUG(2),
328                       "Registering DLZ driver '%s'", drivername);
329
330         /*
331          * Performs checks to make sure data is as we expect it to be.
332          */
333         REQUIRE(drivername != NULL);
334         REQUIRE(methods != NULL);
335         REQUIRE(methods->create != NULL);
336         REQUIRE(methods->destroy != NULL);
337         REQUIRE(methods->findzone != NULL);
338         REQUIRE(mctx != NULL);
339         REQUIRE(dlzimp != NULL && *dlzimp == NULL);
340
341         /*
342          * initialize the dlz_implementations list, this is guaranteed
343          * to only really happen once.
344          */
345         RUNTIME_CHECK(isc_once_do(&once, dlz_initialize) == ISC_R_SUCCESS);
346
347         /* lock the dlz_implementations list so we can modify it. */
348         RWLOCK(&dlz_implock, isc_rwlocktype_write);
349
350         /*
351          * check that another already registered driver isn't using
352          * the same name
353          */
354         dlz_imp = dlz_impfind(drivername);
355         if (dlz_imp != NULL) {
356                 isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
357                               DNS_LOGMODULE_DLZ, ISC_LOG_DEBUG(2),
358                               "DLZ Driver '%s' already registered",
359                               drivername);
360                 RWUNLOCK(&dlz_implock, isc_rwlocktype_write);
361                 return (ISC_R_EXISTS);
362         }
363
364         /*
365          * Allocate memory for a dlz_implementation object.  Error if
366          * we cannot.
367          */
368         dlz_imp = isc_mem_get(mctx, sizeof(dns_dlzimplementation_t));
369         if (dlz_imp == NULL) {
370                 RWUNLOCK(&dlz_implock, isc_rwlocktype_write);
371                 return (ISC_R_NOMEMORY);
372         }
373
374         /* Make sure memory region is set to all 0's */
375         memset(dlz_imp, 0, sizeof(dns_dlzimplementation_t));
376
377         /* Store the data passed into this method */
378         dlz_imp->name = drivername;
379         dlz_imp->methods = methods;
380         dlz_imp->mctx = NULL;
381         dlz_imp->driverarg = driverarg;
382
383         /* attach the new dlz_implementation object to a memory context */
384         isc_mem_attach(mctx, &dlz_imp->mctx);
385
386         /*
387          * prepare the dlz_implementation object to be put in a list,
388          * and append it to the list
389          */
390         ISC_LINK_INIT(dlz_imp, link);
391         ISC_LIST_APPEND(dlz_implementations, dlz_imp, link);
392
393         /* Unlock the dlz_implementations list.  */
394         RWUNLOCK(&dlz_implock, isc_rwlocktype_write);
395
396         /* Pass back the dlz_implementation that we created. */
397         *dlzimp = dlz_imp;
398
399         return (ISC_R_SUCCESS);
400 }
401
402 /*%
403  * Helper function for dns_dlzstrtoargv().
404  * Pardon the gratuitous recursion.
405  */
406 static isc_result_t
407 dns_dlzstrtoargvsub(isc_mem_t *mctx, char *s, unsigned int *argcp,
408                     char ***argvp, unsigned int n)
409 {
410         isc_result_t result;
411
412  restart:
413         /* Discard leading whitespace. */
414         while (*s == ' ' || *s == '\t')
415                 s++;
416
417         if (*s == '\0') {
418                 /* We have reached the end of the string. */
419                 *argcp = n;
420                 *argvp = isc_mem_get(mctx, n * sizeof(char *));
421                 if (*argvp == NULL)
422                         return (ISC_R_NOMEMORY);
423         } else {
424                 char *p = s;
425                 while (*p != ' ' && *p != '\t' && *p != '\0' && *p != '{') {
426                         if (*p == '\n') {
427                                 *p = ' ';
428                                 goto restart;
429                         }
430                         p++;
431                 }
432
433                 /* do "grouping", items between { and } are one arg */
434                 if (*p == '{') {
435                         char *t = p;
436                         /*
437                          * shift all characters to left by 1 to get rid of '{'
438                          */
439                         while (*t != '\0') {
440                                 t++;
441                                 *(t-1) = *t;
442                         }
443                         while (*p != '\0' && *p != '}') {
444                                 p++;
445                         }
446                         /* get rid of '}' character */
447                         if (*p == '}') {
448                                 *p = '\0';
449                                 p++;
450                         }
451                         /* normal case, no "grouping" */
452                 } else if (*p != '\0')
453                         *p++ = '\0';
454
455                 result = dns_dlzstrtoargvsub(mctx, p, argcp, argvp, n + 1);
456                 if (result != ISC_R_SUCCESS)
457                         return (result);
458                 (*argvp)[n] = s;
459         }
460         return (ISC_R_SUCCESS);
461 }
462
463 /*%
464  * Tokenize the string "s" into whitespace-separated words,
465  * return the number of words in '*argcp' and an array
466  * of pointers to the words in '*argvp'.  The caller
467  * must free the array using isc_mem_put().  The string
468  * is modified in-place.
469  */
470 isc_result_t
471 dns_dlzstrtoargv(isc_mem_t *mctx, char *s,
472                  unsigned int *argcp, char ***argvp)
473 {
474         return(dns_dlzstrtoargvsub(mctx, s, argcp, argvp, 0));
475 }
476
477 /*%
478  * Unregisters a DLZ driver.  This basically just removes the dlz
479  * driver from the list of available drivers in the dlz_implementations list.
480  */
481 void
482 dns_dlzunregister(dns_dlzimplementation_t **dlzimp) {
483         dns_dlzimplementation_t *dlz_imp;
484         isc_mem_t *mctx;
485
486         /* Write debugging message to log */
487         isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
488                       DNS_LOGMODULE_DLZ, ISC_LOG_DEBUG(2),
489                       "Unregistering DLZ driver.");
490
491         /*
492          * Performs checks to make sure data is as we expect it to be.
493          */
494         REQUIRE(dlzimp != NULL && *dlzimp != NULL);
495
496         /*
497          * initialize the dlz_implementations list, this is guaranteed
498          * to only really happen once.
499          */
500         RUNTIME_CHECK(isc_once_do(&once, dlz_initialize) == ISC_R_SUCCESS);
501
502         dlz_imp = *dlzimp;
503
504         /* lock the dlz_implementations list so we can modify it. */
505         RWLOCK(&dlz_implock, isc_rwlocktype_write);
506
507         /* remove the dlz_implementation object from the list */
508         ISC_LIST_UNLINK(dlz_implementations, dlz_imp, link);
509         mctx = dlz_imp->mctx;
510
511         /*
512          * Return the memory back to the available memory pool and
513          * remove it from the memory context.
514          */
515         isc_mem_put(mctx, dlz_imp, sizeof(dns_dlzimplementation_t));
516         isc_mem_detach(&mctx);
517
518         /* Unlock the dlz_implementations list. */
519         RWUNLOCK(&dlz_implock, isc_rwlocktype_write);
520 }
521
522 #ifdef BIND9
523 /*
524  * Create a writeable DLZ zone. This can be called by DLZ drivers
525  * during configure() to create a zone that can be updated. The zone
526  * type is set to dns_zone_dlz, which is equivalent to a master zone
527  *
528  * This function uses a callback setup in dns_dlzconfigure() to call
529  * into the server zone code to setup the remaining pieces of server
530  * specific functionality on the zone
531  */
532 isc_result_t
533 dns_dlz_writeablezone(dns_view_t *view, const char *zone_name) {
534         dns_zone_t *zone = NULL;
535         dns_zone_t *dupzone = NULL;
536         isc_result_t result;
537         isc_buffer_t buffer;
538         dns_fixedname_t fixorigin;
539         dns_name_t *origin;
540         dns_dlzdb_t *dlzdatabase;
541
542         REQUIRE(DNS_DLZ_VALID(view->dlzdatabase));
543
544         dlzdatabase = view->dlzdatabase;
545
546         REQUIRE(dlzdatabase->configure_callback != NULL);
547
548         isc_buffer_constinit(&buffer, zone_name, strlen(zone_name));
549         isc_buffer_add(&buffer, strlen(zone_name));
550         dns_fixedname_init(&fixorigin);
551         result = dns_name_fromtext(dns_fixedname_name(&fixorigin),
552                                    &buffer, dns_rootname, 0, NULL);
553         if (result != ISC_R_SUCCESS)
554                 goto cleanup;
555         origin = dns_fixedname_name(&fixorigin);
556
557         /* See if the zone already exists */
558         result = dns_view_findzone(view, origin, &dupzone);
559         if (result == ISC_R_SUCCESS) {
560                 dns_zone_detach(&dupzone);
561                 result = ISC_R_EXISTS;
562                 goto cleanup;
563         }
564         INSIST(dupzone == NULL);
565
566         /* Create it */
567         result = dns_zone_create(&zone, view->mctx);
568         if (result != ISC_R_SUCCESS)
569                 goto cleanup;
570         result = dns_zone_setorigin(zone, origin);
571         if (result != ISC_R_SUCCESS)
572                 goto cleanup;
573         dns_zone_setview(zone, view);
574
575         dns_zone_setadded(zone, ISC_TRUE);
576
577         if (dlzdatabase->ssutable == NULL) {
578                 result = dns_ssutable_createdlz(dlzdatabase->mctx,
579                                                 &dlzdatabase->ssutable,
580                                                 view->dlzdatabase);
581                 if (result != ISC_R_SUCCESS)
582                         goto cleanup;
583         }
584         dns_zone_setssutable(zone, dlzdatabase->ssutable);
585
586         result = dlzdatabase->configure_callback(view, zone);
587         if (result != ISC_R_SUCCESS)
588                 goto cleanup;
589
590         /*
591          * Add the zone to its view in the new view list.
592          */
593         result = dns_view_addzone(view, zone);
594
595  cleanup:
596         if (zone != NULL)
597                 dns_zone_detach(&zone);
598
599         return (result);
600 }
601 #endif
602
603 /*%
604  * Configure a DLZ driver. This is optional, and if supplied gives
605  * the backend an opportunity to configure parameters related to DLZ.
606  */
607 isc_result_t
608 dns_dlzconfigure(dns_view_t *view, isc_result_t (*callback)(dns_view_t *,
609                  dns_zone_t *))
610 {
611         dns_dlzimplementation_t *impl;
612         dns_dlzdb_t *dlzdatabase;
613         isc_result_t result;
614
615         REQUIRE(view != NULL);
616         REQUIRE(DNS_DLZ_VALID(view->dlzdatabase));
617         REQUIRE(view->dlzdatabase->implementation != NULL);
618
619         dlzdatabase = view->dlzdatabase;
620         impl = dlzdatabase->implementation;
621
622         if (impl->methods->configure == NULL)
623                 return (ISC_R_SUCCESS);
624
625         dlzdatabase->configure_callback = callback;
626
627         result = impl->methods->configure(impl->driverarg,
628                                           dlzdatabase->dbdata, view);
629         return (result);
630 }
631
632 isc_boolean_t
633 dns_dlz_ssumatch(dns_dlzdb_t *dlzdatabase,
634                   dns_name_t *signer, dns_name_t *name, isc_netaddr_t *tcpaddr,
635                   dns_rdatatype_t type, const dst_key_t *key)
636 {
637         dns_dlzimplementation_t *impl;
638         isc_boolean_t r;
639
640         REQUIRE(dlzdatabase != NULL);
641         REQUIRE(dlzdatabase->implementation != NULL);
642         REQUIRE(dlzdatabase->implementation->methods != NULL);
643         impl = dlzdatabase->implementation;
644
645         if (impl->methods->ssumatch == NULL) {
646                 isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
647                               DNS_LOGMODULE_DLZ, ISC_LOG_INFO,
648                               "No ssumatch method for DLZ database");
649                 return (ISC_FALSE);
650         }
651
652         r = impl->methods->ssumatch(signer, name, tcpaddr, type, key,
653                                     impl->driverarg, dlzdatabase->dbdata);
654         return (r);
655 }