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 83static ISC_LIST(dns_dlzimplementation_t) dlz_implementations; 84static isc_rwlock_t dlz_implock; 85static isc_once_t once = ISC_ONCE_INIT; 86 87static void 88dlz_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 */ 96static inline dns_dlzimplementation_t * 97dlz_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 112isc_result_t 113dns_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 139isc_result_t 140dns_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 220void 221dns_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 255isc_result_t 256dns_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 */ 315isc_result_t 316dns_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 */ 404static isc_result_t 405dns_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 */ 468isc_result_t 469dns_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 */ 479void 480dns_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 */ 530isc_result_t 531dns_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 */ 605isc_result_t 606dns_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 630isc_boolean_t 631dns_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} 654