]> CyberLeo.Net >> Repos - FreeBSD/releng/9.2.git/blob - contrib/bind9/lib/dns/dlz.c
- Copy stable/9 to releng/9.2 as part of the 9.2-RELEASE cycle.
[FreeBSD/releng/9.2.git] / contrib / bind9 / lib / dns / dlz.c
1 /*
2  * Portions Copyright (C) 2005, 2007, 2009-2012  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
146         /*
147          * initialize the dlz_implementations list, this is guaranteed
148          * to only really happen once.
149          */
150         RUNTIME_CHECK(isc_once_do(&once, dlz_initialize) == ISC_R_SUCCESS);
151
152         /*
153          * Performs checks to make sure data is as we expect it to be.
154          */
155         REQUIRE(dbp != NULL && *dbp == NULL);
156         REQUIRE(dlzname != NULL);
157         REQUIRE(drivername != NULL);
158         REQUIRE(mctx != NULL);
159
160         /* write log message */
161         isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
162                       DNS_LOGMODULE_DLZ, ISC_LOG_INFO,
163                       "Loading '%s' using driver %s", dlzname, drivername);
164
165         /* lock the dlz_implementations list so we can search it. */
166         RWLOCK(&dlz_implock, isc_rwlocktype_read);
167
168         /* search for the driver implementation  */
169         impinfo = dlz_impfind(drivername);
170         if (impinfo == NULL) {
171                 RWUNLOCK(&dlz_implock, isc_rwlocktype_read);
172
173                 isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
174                               DNS_LOGMODULE_DLZ, ISC_LOG_ERROR,
175                               "unsupported DLZ database driver '%s'."
176                               "  %s not loaded.",
177                               drivername, dlzname);
178
179                 return (ISC_R_NOTFOUND);
180         }
181
182         /* Allocate memory to hold the DLZ database driver */
183         (*dbp) = isc_mem_get(mctx, sizeof(dns_dlzdb_t));
184         if ((*dbp) == NULL) {
185                 RWUNLOCK(&dlz_implock, isc_rwlocktype_read);
186                 return (ISC_R_NOMEMORY);
187         }
188
189         /* Make sure memory region is set to all 0's */
190         memset((*dbp), 0, sizeof(dns_dlzdb_t));
191
192         (*dbp)->implementation = impinfo;
193
194         /* Create a new database using implementation 'drivername'. */
195         result = ((impinfo->methods->create)(mctx, dlzname, argc, argv,
196                                              impinfo->driverarg,
197                                              &(*dbp)->dbdata));
198
199         /* mark the DLZ driver as valid */
200         if (result == ISC_R_SUCCESS) {
201                 RWUNLOCK(&dlz_implock, isc_rwlocktype_read);
202                 (*dbp)->magic = DNS_DLZ_MAGIC;
203                 isc_mem_attach(mctx, &(*dbp)->mctx);
204                 isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
205                               DNS_LOGMODULE_DLZ, ISC_LOG_DEBUG(2),
206                               "DLZ driver loaded successfully.");
207                 return (ISC_R_SUCCESS);
208         } else {
209                 isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
210                               DNS_LOGMODULE_DLZ, ISC_LOG_ERROR,
211                               "DLZ driver failed to load.");
212         }
213
214         /* impinfo->methods->create failed. */
215         RWUNLOCK(&dlz_implock, isc_rwlocktype_read);
216         isc_mem_put(mctx, (*dbp), sizeof(dns_dlzdb_t));
217         return (result);
218 }
219
220 void
221 dns_dlzdestroy(dns_dlzdb_t **dbp) {
222         isc_mem_t *mctx;
223         dns_dlzdestroy_t destroy;
224
225         /* Write debugging message to log */
226         isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
227                       DNS_LOGMODULE_DLZ, ISC_LOG_DEBUG(2),
228                       "Unloading DLZ driver.");
229
230         /*
231          * Perform checks to make sure data is as we expect it to be.
232          */
233         REQUIRE(dbp != NULL && DNS_DLZ_VALID(*dbp));
234
235 #ifdef BIND9
236         if ((*dbp)->ssutable != NULL) {
237                 dns_ssutable_detach(&(*dbp)->ssutable);
238         }
239 #endif
240
241         /* call the drivers destroy method */
242         if ((*dbp) != NULL) {
243                 mctx = (*dbp)->mctx;
244                 destroy = (*dbp)->implementation->methods->destroy;
245                 (*destroy)((*dbp)->implementation->driverarg,(*dbp)->dbdata);
246                 /* return memory */
247                 isc_mem_put(mctx, (*dbp), sizeof(dns_dlzdb_t));
248                 isc_mem_detach(&mctx);
249         }
250
251         *dbp = NULL;
252 }
253
254
255 isc_result_t
256 dns_dlzfindzone(dns_view_t *view, dns_name_t *name, unsigned int minlabels,
257                 dns_db_t **dbp)
258 {
259         dns_fixedname_t fname;
260         dns_name_t *zonename;
261         unsigned int namelabels;
262         unsigned int i;
263         isc_result_t result;
264         dns_dlzfindzone_t findzone;
265         dns_dlzdb_t *dlzdatabase;
266
267         /*
268          * Performs checks to make sure data is as we expect it to be.
269          */
270         REQUIRE(DNS_DLZ_VALID(view->dlzdatabase));
271         REQUIRE(name != NULL);
272         REQUIRE(dbp != NULL && *dbp == NULL);
273
274         /* setup a "fixed" dns name */
275         dns_fixedname_init(&fname);
276         zonename = dns_fixedname_name(&fname);
277
278         /* count the number of labels in the name */
279         namelabels = dns_name_countlabels(name);
280
281         /*
282          * loop through starting with the longest domain name and
283          * trying shorter names portions of the name until we find a
284          * match, have an error, or are below the 'minlabels'
285          * threshold.  minlabels is 0, if the standard database didn't
286          * have a zone name match.  Otherwise minlabels is the number
287          * of labels in that name.  We need to beat that for a
288          * "better" match for the DLZ database to be authoritative
289          * instead of the standard database.
290          */
291         for (i = namelabels; i > minlabels && i > 1; i--) {
292                 if (i == namelabels) {
293                         result = dns_name_copy(name, zonename, NULL);
294                         if (result != ISC_R_SUCCESS)
295                                 return (result);
296                 } else
297                         dns_name_split(name, i, NULL, zonename);
298
299                 /* ask SDLZ driver if the zone is supported */
300                 dlzdatabase = view->dlzdatabase;
301                 findzone = dlzdatabase->implementation->methods->findzone;
302                 result = (*findzone)(dlzdatabase->implementation->driverarg,
303                                      dlzdatabase->dbdata, dlzdatabase->mctx,
304                                      view->rdclass, zonename, dbp);
305                 if (result != ISC_R_NOTFOUND)
306                         return (result);
307         }
308         return (ISC_R_NOTFOUND);
309 }
310
311 /*%
312  * Registers a DLZ driver.  This basically just adds the dlz
313  * driver to the list of available drivers in the dlz_implementations list.
314  */
315 isc_result_t
316 dns_dlzregister(const char *drivername, const dns_dlzmethods_t *methods,
317                 void *driverarg, isc_mem_t *mctx,
318                 dns_dlzimplementation_t **dlzimp)
319 {
320
321         dns_dlzimplementation_t *dlz_imp;
322
323         /* Write debugging message to log */
324         isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
325                       DNS_LOGMODULE_DLZ, ISC_LOG_DEBUG(2),
326                       "Registering DLZ driver '%s'", drivername);
327
328         /*
329          * Performs checks to make sure data is as we expect it to be.
330          */
331         REQUIRE(drivername != NULL);
332         REQUIRE(methods != NULL);
333         REQUIRE(methods->create != NULL);
334         REQUIRE(methods->destroy != NULL);
335         REQUIRE(methods->findzone != NULL);
336         REQUIRE(mctx != NULL);
337         REQUIRE(dlzimp != NULL && *dlzimp == NULL);
338
339         /*
340          * initialize the dlz_implementations list, this is guaranteed
341          * to only really happen once.
342          */
343         RUNTIME_CHECK(isc_once_do(&once, dlz_initialize) == ISC_R_SUCCESS);
344
345         /* lock the dlz_implementations list so we can modify it. */
346         RWLOCK(&dlz_implock, isc_rwlocktype_write);
347
348         /*
349          * check that another already registered driver isn't using
350          * the same name
351          */
352         dlz_imp = dlz_impfind(drivername);
353         if (dlz_imp != NULL) {
354                 isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
355                               DNS_LOGMODULE_DLZ, ISC_LOG_DEBUG(2),
356                               "DLZ Driver '%s' already registered",
357                               drivername);
358                 RWUNLOCK(&dlz_implock, isc_rwlocktype_write);
359                 return (ISC_R_EXISTS);
360         }
361
362         /*
363          * Allocate memory for a dlz_implementation object.  Error if
364          * we cannot.
365          */
366         dlz_imp = isc_mem_get(mctx, sizeof(dns_dlzimplementation_t));
367         if (dlz_imp == NULL) {
368                 RWUNLOCK(&dlz_implock, isc_rwlocktype_write);
369                 return (ISC_R_NOMEMORY);
370         }
371
372         /* Make sure memory region is set to all 0's */
373         memset(dlz_imp, 0, sizeof(dns_dlzimplementation_t));
374
375         /* Store the data passed into this method */
376         dlz_imp->name = drivername;
377         dlz_imp->methods = methods;
378         dlz_imp->mctx = NULL;
379         dlz_imp->driverarg = driverarg;
380
381         /* attach the new dlz_implementation object to a memory context */
382         isc_mem_attach(mctx, &dlz_imp->mctx);
383
384         /*
385          * prepare the dlz_implementation object to be put in a list,
386          * and append it to the list
387          */
388         ISC_LINK_INIT(dlz_imp, link);
389         ISC_LIST_APPEND(dlz_implementations, dlz_imp, link);
390
391         /* Unlock the dlz_implementations list.  */
392         RWUNLOCK(&dlz_implock, isc_rwlocktype_write);
393
394         /* Pass back the dlz_implementation that we created. */
395         *dlzimp = dlz_imp;
396
397         return (ISC_R_SUCCESS);
398 }
399
400 /*%
401  * Helper function for dns_dlzstrtoargv().
402  * Pardon the gratuitous recursion.
403  */
404 static isc_result_t
405 dns_dlzstrtoargvsub(isc_mem_t *mctx, char *s, unsigned int *argcp,
406                     char ***argvp, unsigned int n)
407 {
408         isc_result_t result;
409
410  restart:
411         /* Discard leading whitespace. */
412         while (*s == ' ' || *s == '\t')
413                 s++;
414
415         if (*s == '\0') {
416                 /* We have reached the end of the string. */
417                 *argcp = n;
418                 *argvp = isc_mem_get(mctx, n * sizeof(char *));
419                 if (*argvp == NULL)
420                         return (ISC_R_NOMEMORY);
421         } else {
422                 char *p = s;
423                 while (*p != ' ' && *p != '\t' && *p != '\0' && *p != '{') {
424                         if (*p == '\n') {
425                                 *p = ' ';
426                                 goto restart;
427                         }
428                         p++;
429                 }
430
431                 /* do "grouping", items between { and } are one arg */
432                 if (*p == '{') {
433                         char *t = p;
434                         /*
435                          * shift all characters to left by 1 to get rid of '{'
436                          */
437                         while (*t != '\0') {
438                                 t++;
439                                 *(t-1) = *t;
440                         }
441                         while (*p != '\0' && *p != '}') {
442                                 p++;
443                         }
444                         /* get rid of '}' character */
445                         if (*p == '}') {
446                                 *p = '\0';
447                                 p++;
448                         }
449                         /* normal case, no "grouping" */
450                 } else if (*p != '\0')
451                         *p++ = '\0';
452
453                 result = dns_dlzstrtoargvsub(mctx, p, argcp, argvp, n + 1);
454                 if (result != ISC_R_SUCCESS)
455                         return (result);
456                 (*argvp)[n] = s;
457         }
458         return (ISC_R_SUCCESS);
459 }
460
461 /*%
462  * Tokenize the string "s" into whitespace-separated words,
463  * return the number of words in '*argcp' and an array
464  * of pointers to the words in '*argvp'.  The caller
465  * must free the array using isc_mem_put().  The string
466  * is modified in-place.
467  */
468 isc_result_t
469 dns_dlzstrtoargv(isc_mem_t *mctx, char *s,
470                  unsigned int *argcp, char ***argvp)
471 {
472         return(dns_dlzstrtoargvsub(mctx, s, argcp, argvp, 0));
473 }
474
475 /*%
476  * Unregisters a DLZ driver.  This basically just removes the dlz
477  * driver from the list of available drivers in the dlz_implementations list.
478  */
479 void
480 dns_dlzunregister(dns_dlzimplementation_t **dlzimp) {
481         dns_dlzimplementation_t *dlz_imp;
482         isc_mem_t *mctx;
483
484         /* Write debugging message to log */
485         isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
486                       DNS_LOGMODULE_DLZ, ISC_LOG_DEBUG(2),
487                       "Unregistering DLZ driver.");
488
489         /*
490          * Performs checks to make sure data is as we expect it to be.
491          */
492         REQUIRE(dlzimp != NULL && *dlzimp != NULL);
493
494         /*
495          * initialize the dlz_implementations list, this is guaranteed
496          * to only really happen once.
497          */
498         RUNTIME_CHECK(isc_once_do(&once, dlz_initialize) == ISC_R_SUCCESS);
499
500         dlz_imp = *dlzimp;
501
502         /* lock the dlz_implementations list so we can modify it. */
503         RWLOCK(&dlz_implock, isc_rwlocktype_write);
504
505         /* remove the dlz_implementation object from the list */
506         ISC_LIST_UNLINK(dlz_implementations, dlz_imp, link);
507         mctx = dlz_imp->mctx;
508
509         /*
510          * Return the memory back to the available memory pool and
511          * remove it from the memory context.
512          */
513         isc_mem_put(mctx, dlz_imp, sizeof(dns_dlzimplementation_t));
514         isc_mem_detach(&mctx);
515
516         /* Unlock the dlz_implementations list. */
517         RWUNLOCK(&dlz_implock, isc_rwlocktype_write);
518 }
519
520 #ifdef BIND9
521 /*
522  * Create a writeable DLZ zone. This can be called by DLZ drivers
523  * during configure() to create a zone that can be updated. The zone
524  * type is set to dns_zone_dlz, which is equivalent to a master zone
525  *
526  * This function uses a callback setup in dns_dlzconfigure() to call
527  * into the server zone code to setup the remaining pieces of server
528  * specific functionality on the zone
529  */
530 isc_result_t
531 dns_dlz_writeablezone(dns_view_t *view, const char *zone_name) {
532         dns_zone_t *zone = NULL;
533         dns_zone_t *dupzone = NULL;
534         isc_result_t result;
535         isc_buffer_t buffer;
536         dns_fixedname_t fixorigin;
537         dns_name_t *origin;
538         dns_dlzdb_t *dlzdatabase;
539
540         REQUIRE(DNS_DLZ_VALID(view->dlzdatabase));
541
542         dlzdatabase = view->dlzdatabase;
543
544         REQUIRE(dlzdatabase->configure_callback != NULL);
545
546         isc_buffer_init(&buffer, zone_name, strlen(zone_name));
547         isc_buffer_add(&buffer, strlen(zone_name));
548         dns_fixedname_init(&fixorigin);
549         result = dns_name_fromtext(dns_fixedname_name(&fixorigin),
550                                    &buffer, dns_rootname, 0, NULL);
551         if (result != ISC_R_SUCCESS)
552                 goto cleanup;
553         origin = dns_fixedname_name(&fixorigin);
554
555         /* See if the zone already exists */
556         result = dns_view_findzone(view, origin, &dupzone);
557         if (result == ISC_R_SUCCESS) {
558                 dns_zone_detach(&dupzone);
559                 result = ISC_R_EXISTS;
560                 goto cleanup;
561         }
562         INSIST(dupzone == NULL);
563
564         /* Create it */
565         result = dns_zone_create(&zone, view->mctx);
566         if (result != ISC_R_SUCCESS)
567                 goto cleanup;
568         result = dns_zone_setorigin(zone, origin);
569         if (result != ISC_R_SUCCESS)
570                 goto cleanup;
571         dns_zone_setview(zone, view);
572
573         dns_zone_setadded(zone, ISC_TRUE);
574
575         if (dlzdatabase->ssutable == NULL) {
576                 result = dns_ssutable_createdlz(dlzdatabase->mctx,
577                                                 &dlzdatabase->ssutable,
578                                                 view->dlzdatabase);
579                 if (result != ISC_R_SUCCESS)
580                         goto cleanup;
581         }
582         dns_zone_setssutable(zone, dlzdatabase->ssutable);
583
584         result = dlzdatabase->configure_callback(view, zone);
585         if (result != ISC_R_SUCCESS)
586                 goto cleanup;
587
588         /*
589          * Add the zone to its view in the new view list.
590          */
591         result = dns_view_addzone(view, zone);
592
593  cleanup:
594         if (zone != NULL)
595                 dns_zone_detach(&zone);
596
597         return (result);
598 }
599 #endif
600
601 /*%
602  * Configure a DLZ driver. This is optional, and if supplied gives
603  * the backend an opportunity to configure parameters related to DLZ.
604  */
605 isc_result_t
606 dns_dlzconfigure(dns_view_t *view, isc_result_t (*callback)(dns_view_t *,
607                  dns_zone_t *))
608 {
609         dns_dlzimplementation_t *impl;
610         dns_dlzdb_t *dlzdatabase;
611         isc_result_t result;
612
613         REQUIRE(view != NULL);
614         REQUIRE(DNS_DLZ_VALID(view->dlzdatabase));
615         REQUIRE(view->dlzdatabase->implementation != NULL);
616
617         dlzdatabase = view->dlzdatabase;
618         impl = dlzdatabase->implementation;
619
620         if (impl->methods->configure == NULL)
621                 return (ISC_R_SUCCESS);
622
623         dlzdatabase->configure_callback = callback;
624
625         result = impl->methods->configure(impl->driverarg,
626                                           dlzdatabase->dbdata, view);
627         return (result);
628 }
629
630 isc_boolean_t
631 dns_dlz_ssumatch(dns_dlzdb_t *dlzdatabase,
632                   dns_name_t *signer, dns_name_t *name, isc_netaddr_t *tcpaddr,
633                   dns_rdatatype_t type, const dst_key_t *key)
634 {
635         dns_dlzimplementation_t *impl;
636         isc_boolean_t r;
637
638         REQUIRE(dlzdatabase != NULL);
639         REQUIRE(dlzdatabase->implementation != NULL);
640         REQUIRE(dlzdatabase->implementation->methods != NULL);
641         impl = dlzdatabase->implementation;
642
643         if (impl->methods->ssumatch == NULL) {
644                 isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
645                               DNS_LOGMODULE_DLZ, ISC_LOG_INFO,
646                               "No ssumatch method for DLZ database");
647                 return (ISC_FALSE);
648         }
649
650         r = impl->methods->ssumatch(signer, name, tcpaddr, type, key,
651                                     impl->driverarg, dlzdatabase->dbdata);
652         return (r);
653 }