Remove building with NOCRYPTO option
[minix.git] / external / bsd / bind / dist / contrib / dlz / drivers / dlz_bdbhpt_driver.c
blob855b04d29a533fb5239b0c4f53fd8dc5c655c7ed
1 /* $NetBSD: dlz_bdbhpt_driver.c,v 1.5 2014/12/10 04:37:55 christos Exp $ */
3 /*
4 * Copyright (C) 2002 Stichting NLnet, Netherlands, stichting@nlnet.nl.
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the
8 * above copyright notice and this permission notice appear in all
9 * copies.
11 * THE SOFTWARE IS PROVIDED "AS IS" AND STICHTING NLNET
12 * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
13 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
14 * STICHTING NLNET BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR
15 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
16 * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
17 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE
18 * USE OR PERFORMANCE OF THIS SOFTWARE.
20 * The development of Dynamically Loadable Zones (DLZ) for Bind 9 was
21 * conceived and contributed by Rob Butler.
23 * Permission to use, copy, modify, and distribute this software for any
24 * purpose with or without fee is hereby granted, provided that the
25 * above copyright notice and this permission notice appear in all
26 * copies.
28 * THE SOFTWARE IS PROVIDED "AS IS" AND ROB BUTLER
29 * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
30 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
31 * ROB BUTLER BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR
32 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
33 * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
34 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE
35 * USE OR PERFORMANCE OF THIS SOFTWARE.
39 * Copyright (C) 1999-2001 Internet Software Consortium.
41 * Permission to use, copy, modify, and distribute this software for any
42 * purpose with or without fee is hereby granted, provided that the above
43 * copyright notice and this permission notice appear in all copies.
45 * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
46 * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
47 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
48 * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
49 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
50 * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
51 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
52 * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
55 #ifdef DLZ_BDB
57 #include <config.h>
58 #include <stdio.h>
59 #include <string.h>
60 #include <stdlib.h>
62 #include <dns/log.h>
63 #include <dns/sdlz.h>
64 #include <dns/result.h>
66 #include <isc/mem.h>
67 #include <isc/print.h>
68 #include <isc/result.h>
69 #include <isc/util.h>
71 #include <named/globals.h>
73 #include <dlz/dlz_bdbhpt_driver.h>
75 #include <db.h>
77 static dns_sdlzimplementation_t *dlz_bdbhpt = NULL;
79 /* should the bdb driver use threads. */
80 #ifdef ISC_PLATFORM_USETHREADS
81 #define bdbhpt_threads DB_THREAD
82 #else
83 #define bdbhpt_threads 0
84 #endif
86 /* bdbhpt database names */
87 #define dlz_data "dns_data"
88 #define dlz_zone "dns_zone"
89 #define dlz_xfr "dns_xfr"
90 #define dlz_client "dns_client"
92 /* This structure contains all the Berkeley DB handles
93 * for this instance of the bdbhpt driver.
96 typedef struct bdbhpt_instance {
97 DB_ENV *dbenv; /*%< bdbhpt environment */
98 DB *data; /*%< dns_data database handle */
99 DB *zone; /*%< zone database handle */
100 DB *xfr; /*%< zone xfr database handle */
101 DB *client; /*%< client database handle */
102 isc_mem_t *mctx; /*%< memory context */
104 } bdbhpt_instance_t;
106 typedef struct bdbhpt_parsed_data {
107 char *host;
108 char *type;
109 int ttl;
110 char *data;
111 } bdbhpt_parsed_data_t;
114 /* forward reference */
116 static isc_result_t
117 bdbhpt_findzone(void *driverarg, void *dbdata, const char *name,
118 dns_clientinfomethods_t *methods, dns_clientinfo_t *clientinfo);
121 * Reverses a string in place.
124 static char *bdbhpt_strrev(char *str)
126 char *p1, *p2;
128 if (! str || ! *str)
129 return str;
130 for (p1 = str, p2 = str + strlen(str) - 1; p2 > p1; ++p1, --p2)
132 *p1 ^= *p2;
133 *p2 ^= *p1;
134 *p1 ^= *p2;
136 return str;
140 * Parses the DBT from the Berkeley DB into a parsed_data record
141 * The parsed_data record should be allocated before and passed into the
142 * bdbhpt_parse_data function. The char (type & data) fields should not
143 * be "free"d as that memory is part of the DBT data field. It will be
144 * "free"d when the DBT is freed.
147 static isc_result_t
148 bdbhpt_parse_data(char *in, bdbhpt_parsed_data_t *pd) {
150 char *endp, *ttlStr;
151 char *tmp = in;
152 char *lastchar = (char *) &tmp[strlen(tmp)];
155 * String should be formated as:
156 * replication_id
157 * (a space)
158 * host_name
159 * (a space)
160 * ttl
161 * (a space)
162 * type
163 * (a space)
164 * remaining data
166 * examples:
168 * 9191 host 10 A 127.0.0.1
169 * server1_212 host 10 A 127.0.0.2
170 * {xxxx-xxxx-xxxx-xxxx-xxxx} host 10 MX 20 mail.example.com
174 * we don't need the replication id, so don't
175 * bother saving a pointer to it.
178 /* find space after replication id */
179 tmp = strchr(tmp, ' ');
180 /* verify we found a space */
181 if (tmp == NULL)
182 return ISC_R_FAILURE;
183 /* make sure it is safe to increment pointer */
184 if (++tmp > lastchar)
185 return ISC_R_FAILURE;
187 /* save pointer to host */
188 pd->host = tmp;
190 /* find space after host and change it to a '\0' */
191 tmp = strchr(tmp, ' ');
192 /* verify we found a space */
193 if (tmp == NULL)
194 return ISC_R_FAILURE;
195 /* change the space to a null (string terminator) */
196 tmp[0] = '\0';
197 /* make sure it is safe to increment pointer */
198 if (++tmp > lastchar)
199 return ISC_R_FAILURE;
201 /* save pointer to ttl string */
202 ttlStr = tmp;
204 /* find space after ttl and change it to a '\0' */
205 tmp = strchr(tmp, ' ');
206 /* verify we found a space */
207 if (tmp == NULL)
208 return ISC_R_FAILURE;
209 /* change the space to a null (string terminator) */
210 tmp[0] = '\0';
211 /* make sure it is safe to increment pointer */
212 if (++tmp > lastchar)
213 return ISC_R_FAILURE;
215 /* save pointer to dns type */
216 pd->type = tmp;
218 /* find space after type and change it to a '\0' */
219 tmp = strchr(tmp, ' ');
220 /* verify we found a space */
221 if (tmp == NULL)
222 return ISC_R_FAILURE;
223 /* change the space to a null (string terminator) */
224 tmp[0] = '\0';
225 /* make sure it is safe to increment pointer */
226 if (++tmp > lastchar)
227 return ISC_R_FAILURE;
229 /* save pointer to remainder of DNS data */
230 pd->data = tmp;
232 /* convert ttl string to integer */
233 pd->ttl = strtol(ttlStr, &endp, 10);
234 if (*endp != '\0' || pd->ttl < 0) {
235 isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
236 DNS_LOGMODULE_DLZ, ISC_LOG_ERROR,
237 "bdbhpt driver ttl must be a postive number");
238 return ISC_R_FAILURE;
241 /* if we get this far everything should have worked. */
242 return ISC_R_SUCCESS;
246 * DLZ methods
249 static isc_result_t
250 bdbhpt_allowzonexfr(void *driverarg, void *dbdata, const char *name,
251 const char *client)
253 isc_result_t result;
254 bdbhpt_instance_t *db = (bdbhpt_instance_t *) dbdata;
255 DBT key, data;
257 /* check to see if we are authoritative for the zone first. */
258 result = bdbhpt_findzone(driverarg, dbdata, name, NULL, NULL);
259 if (result != ISC_R_SUCCESS)
260 return (ISC_R_NOTFOUND);
262 memset(&key, 0, sizeof(DBT));
263 key.flags = DB_DBT_MALLOC;
264 key.data = strdup(name);
265 if (key.data == NULL) {
266 result = ISC_R_NOMEMORY;
267 goto xfr_cleanup;
269 key.size = strlen(key.data);
271 memset(&data, 0, sizeof(DBT));
272 data.flags = DB_DBT_MALLOC;
273 data.data = strdup(client);
274 if (data.data == NULL) {
275 result = ISC_R_NOMEMORY;
276 goto xfr_cleanup;
278 data.size = strlen(data.data);
280 switch(db->client->get(db->client, NULL, &key, &data, DB_GET_BOTH)) {
281 case DB_NOTFOUND:
282 result = ISC_R_NOTFOUND;
283 break;
284 case 0:
285 result = ISC_R_SUCCESS;
286 break;
287 default:
288 result = ISC_R_FAILURE;
291 xfr_cleanup:
293 /* free any memory duplicate string in the key field */
294 if (key.data != NULL)
295 free(key.data);
297 /* free any memory allocated to the data field. */
298 if (data.data != NULL)
299 free(data.data);
301 return result;
306 * BDB does not allow a secondary index on a database that allows
307 * duplicates. We have a few options:
309 * 1) kill speed by having lookup method use a secondary db which
310 * is associated to the primary DB with the DNS data. Then have
311 * another secondary db for zone transfer which also points to
312 * the dns_data primary. NO - The point of this driver is
313 * lookup performance.
315 * 2) Blow up database size by storing DNS data twice. Once for
316 * the lookup (dns_data) database, and a second time for the zone
317 * transfer (dns_xfr) database. NO - That would probably require
318 * a larger cache to provide good performance. Also, that would
319 * make the DB larger on disk potentially slowing it as well.
321 * 3) Loop through the dns_xfr database with a cursor to get
322 * all the different hosts in a zone. Then use the zone & host
323 * together to lookup the data in the dns_data database. YES -
324 * This may slow down zone xfr's a little, but that's ok they
325 * don't happen as often and don't need to be as fast. We can
326 * also use this table when deleting a zone (The BDB driver
327 * is read only - the delete would be used during replication
328 * updates by a separate process).
331 static isc_result_t
332 bdbhpt_allnodes(const char *zone, void *driverarg, void *dbdata,
333 dns_sdlzallnodes_t *allnodes)
336 isc_result_t result = ISC_R_NOTFOUND;
337 bdbhpt_instance_t *db = (bdbhpt_instance_t *) dbdata;
338 DBC *xfr_cursor = NULL;
339 DBC *dns_cursor = NULL;
340 DBT xfr_key, xfr_data, dns_key, dns_data;
341 int xfr_flags;
342 int dns_flags;
343 int bdbhptres;
344 bdbhpt_parsed_data_t pd;
345 char *tmp = NULL, *tmp_zone, *tmp_zone_host = NULL;
347 UNUSED(driverarg);
349 memset(&xfr_key, 0, sizeof(DBT));
350 memset(&xfr_data, 0, sizeof(DBT));
351 memset(&dns_key, 0, sizeof(DBT));
352 memset(&dns_data, 0, sizeof(DBT));
354 xfr_key.data = tmp_zone = strdup(zone);
355 if (xfr_key.data == NULL)
356 return (ISC_R_NOMEMORY);
358 xfr_key.size = strlen(xfr_key.data);
360 /* get a cursor to loop through dns_xfr table */
361 if (db->xfr->cursor(db->xfr, NULL, &xfr_cursor, 0) != 0) {
362 result = ISC_R_FAILURE;
363 goto allnodes_cleanup;
366 /* get a cursor to loop through dns_data table */
367 if (db->data->cursor(db->data, NULL, &dns_cursor, 0) != 0) {
368 result = ISC_R_FAILURE;
369 goto allnodes_cleanup;
372 xfr_flags = DB_SET;
374 /* loop through xfr table for specified zone. */
375 while ((bdbhptres = xfr_cursor->c_get(xfr_cursor, &xfr_key, &xfr_data,
376 xfr_flags)) == 0) {
378 xfr_flags = DB_NEXT_DUP;
380 /* +1 to allow for space between zone and host names */
381 dns_key.size = xfr_data.size + xfr_key.size + 1;
383 /* +1 to allow for null term at end of string. */
384 dns_key.data = tmp_zone_host = malloc(dns_key.size + 1);
385 if (dns_key.data == NULL)
386 goto allnodes_cleanup;
389 * construct search key for dns_data.
390 * zone_name(a space)host_name
392 strcpy(dns_key.data, zone);
393 strcat(dns_key.data, " ");
394 strncat(dns_key.data, xfr_data.data, xfr_data.size);
396 dns_flags = DB_SET;
398 while ((bdbhptres = dns_cursor->c_get(dns_cursor, &dns_key,
399 &dns_data,
400 dns_flags)) == 0) {
402 dns_flags = DB_NEXT_DUP;
404 /* +1 to allow for null term at end of string. */
405 tmp = realloc(tmp, dns_data.size + 1);
406 if (tmp == NULL)
407 goto allnodes_cleanup;
409 /* copy data to tmp string, and append null term. */
410 strncpy(tmp, dns_data.data, dns_data.size);
411 tmp[dns_data.size] = '\0';
413 /* split string into dns data parts. */
414 if (bdbhpt_parse_data(tmp, &pd) != ISC_R_SUCCESS)
415 goto allnodes_cleanup;
417 result = dns_sdlz_putnamedrr(allnodes, pd.host,
418 pd.type, pd.ttl, pd.data);
419 if (result != ISC_R_SUCCESS)
420 goto allnodes_cleanup;
422 } /* end inner while loop */
424 /* clean up memory */
425 if (tmp_zone_host != NULL) {
426 free(tmp_zone_host);
427 tmp_zone_host = NULL;
429 } /* end outer while loop */
431 allnodes_cleanup:
433 /* free any memory */
434 if (tmp != NULL)
435 free(tmp);
437 if (tmp_zone_host != NULL)
438 free(tmp_zone_host);
440 if (tmp_zone != NULL)
441 free(tmp_zone);
443 /* get rid of cursors */
444 if (xfr_cursor != NULL)
445 xfr_cursor->c_close(xfr_cursor);
447 if (dns_cursor != NULL)
448 dns_cursor->c_close(dns_cursor);
450 return result;
454 * Performs bdbhpt cleanup.
455 * Used by bdbhpt_create if there is an error starting up.
456 * Used by bdbhpt_destroy when the driver is shutting down.
459 static void
460 bdbhpt_cleanup(bdbhpt_instance_t *db) {
462 isc_mem_t *mctx;
464 /* close databases */
465 if (db->data != NULL)
466 db->data->close(db->data, 0);
467 if (db->xfr != NULL)
468 db->xfr->close(db->xfr, 0);
469 if (db->zone != NULL)
470 db->zone->close(db->zone, 0);
471 if (db->client != NULL)
472 db->client->close(db->client, 0);
474 /* close environment */
475 if (db->dbenv != NULL)
476 db->dbenv->close(db->dbenv, 0);
478 /* cleanup memory */
479 if (db->mctx != NULL) {
480 /* save mctx for later */
481 mctx = db->mctx;
482 /* return, and detach the memory */
483 isc_mem_put(mctx, db, sizeof(bdbhpt_instance_t));
484 isc_mem_detach(&mctx);
488 static isc_result_t
489 bdbhpt_findzone(void *driverarg, void *dbdata, const char *name,
490 dns_clientinfomethods_t *methods, dns_clientinfo_t *clientinfo)
493 isc_result_t result;
494 bdbhpt_instance_t *db = (bdbhpt_instance_t *) dbdata;
495 DBT key, data;
497 UNUSED(driverarg);
498 UNUSED(methods);
499 UNUSED(clientinfo);
501 memset(&key, 0, sizeof(DBT));
502 memset(&data, 0, sizeof(DBT));
503 data.flags = DB_DBT_MALLOC;
505 key.data = strdup(name);
507 if (key.data == NULL)
508 return (ISC_R_NOMEMORY);
511 * reverse string to take advantage of BDB locality of reference
512 * if we need futher lookups because the zone doesn't match the
513 * first time.
515 key.data = bdbhpt_strrev(key.data);
516 key.size = strlen(key.data);
518 switch(db->zone->get(db->zone, NULL, &key, &data, 0)) {
519 case DB_NOTFOUND:
520 result = ISC_R_NOTFOUND;
521 break;
522 case 0:
523 result = ISC_R_SUCCESS;
524 break;
525 default:
526 result = ISC_R_FAILURE;
529 /* free any memory duplicate string in the key field */
530 if (key.data != NULL)
531 free(key.data);
533 /* free any memory allocated to the data field. */
534 if (data.data != NULL)
535 free(data.data);
537 return result;
540 static isc_result_t
541 bdbhpt_lookup(const char *zone, const char *name, void *driverarg,
542 void *dbdata, dns_sdlzlookup_t *lookup,
543 dns_clientinfomethods_t *methods, dns_clientinfo_t *clientinfo)
546 isc_result_t result = ISC_R_NOTFOUND;
547 bdbhpt_instance_t *db = (bdbhpt_instance_t *) dbdata;
548 DBC *data_cursor = NULL;
549 DBT key, data;
550 int bdbhptres;
551 int flags;
553 bdbhpt_parsed_data_t pd;
554 char *tmp = NULL;
555 char *keyStr = NULL;
557 UNUSED(driverarg);
558 UNUSED(methods);
559 UNUSED(clientinfo);
561 memset(&key, 0, sizeof(DBT));
562 memset(&data, 0, sizeof(DBT));
564 key.size = strlen(zone) + strlen(name) + 1;
566 /* allocate mem for key */
567 key.data = keyStr = malloc((key.size + 1) * sizeof(char));
569 if (keyStr == NULL)
570 return ISC_R_NOMEMORY;
572 strcpy(keyStr, zone);
573 strcat(keyStr, " ");
574 strcat(keyStr, name);
576 /* get a cursor to loop through data */
577 if (db->data->cursor(db->data, NULL, &data_cursor, 0) != 0) {
578 result = ISC_R_FAILURE;
579 goto lookup_cleanup;
582 result = ISC_R_NOTFOUND;
584 flags = DB_SET;
585 while ((bdbhptres = data_cursor->c_get(data_cursor, &key, &data,
586 flags)) == 0) {
588 flags = DB_NEXT_DUP;
589 tmp = realloc(tmp, data.size + 1);
590 if (tmp == NULL)
591 goto lookup_cleanup;
593 strncpy(tmp, data.data, data.size);
594 tmp[data.size] = '\0';
596 if (bdbhpt_parse_data(tmp, &pd) != ISC_R_SUCCESS)
597 goto lookup_cleanup;
599 result = dns_sdlz_putrr(lookup, pd.type, pd.ttl, pd.data);
601 if (result != ISC_R_SUCCESS)
602 goto lookup_cleanup;
603 } /* end while loop */
605 lookup_cleanup:
607 /* get rid of cursor */
608 if (data_cursor != NULL)
609 data_cursor->c_close(data_cursor);
611 if (keyStr != NULL)
612 free(keyStr);
613 if (tmp != NULL)
614 free(tmp);
616 return result;
619 /*% Initializes, sets flags and then opens Berkeley databases. */
621 static isc_result_t
622 bdbhpt_opendb(DB_ENV *db_env, DBTYPE db_type, DB **db, const char *db_name,
623 char *db_file, int flags) {
625 int result;
627 /* Initialize the database. */
628 if ((result = db_create(db, db_env, 0)) != 0) {
629 isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
630 DNS_LOGMODULE_DLZ, ISC_LOG_ERROR,
631 "bdbhpt could not initialize %s database. "
632 "bdbhpt error: %s",
633 db_name, db_strerror(result));
634 return ISC_R_FAILURE;
637 /* set database flags. */
638 if ((result = (*db)->set_flags(*db, flags)) != 0) {
639 isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
640 DNS_LOGMODULE_DLZ, ISC_LOG_ERROR,
641 "bdbhpt could not set flags for %s database. "
642 "bdbhpt error: %s",
643 db_name, db_strerror(result));
644 return ISC_R_FAILURE;
647 /* open the database. */
648 if ((result = (*db)->open(*db, NULL, db_file, db_name, db_type,
649 DB_RDONLY | bdbhpt_threads, 0)) != 0) {
650 isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
651 DNS_LOGMODULE_DLZ, ISC_LOG_ERROR,
652 "bdbhpt could not open %s database in %s. "
653 "bdbhpt error: %s",
654 db_name, db_file, db_strerror(result));
655 return ISC_R_FAILURE;
658 return ISC_R_SUCCESS;
661 static isc_result_t
662 bdbhpt_create(const char *dlzname, unsigned int argc, char *argv[],
663 void *driverarg, void **dbdata)
665 isc_result_t result;
666 int bdbhptres;
667 int bdbFlags = 0;
668 bdbhpt_instance_t *db = NULL;
670 UNUSED(dlzname);
671 UNUSED(driverarg);
673 /* verify we have 4 arg's passed to the driver */
674 if (argc != 4) {
675 isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
676 DNS_LOGMODULE_DLZ, ISC_LOG_ERROR,
677 "bdbhpt driver requires at least "
678 "3 command line args.");
679 return (ISC_R_FAILURE);
682 switch((char) *argv[1]) {
684 * Transactional mode. Highest safety - lowest speed.
686 case 'T':
687 case 't':
688 bdbFlags = DB_INIT_MPOOL | DB_INIT_LOCK |
689 DB_INIT_LOG | DB_INIT_TXN;
690 isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
691 DNS_LOGMODULE_DLZ, ISC_LOG_DEBUG(1),
692 "bdbhpt driver using transactional mode.");
693 break;
695 * Concurrent mode. Lower safety (no rollback) -
696 * higher speed.
698 case 'C':
699 case 'c':
700 bdbFlags = DB_INIT_CDB | DB_INIT_MPOOL;
701 isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
702 DNS_LOGMODULE_DLZ, ISC_LOG_DEBUG(1),
703 "bdbhpt driver using concurrent mode.");
704 break;
706 * Private mode. No inter-process communication & no locking.
707 * Lowest saftey - highest speed.
709 case 'P':
710 case 'p':
711 bdbFlags = DB_PRIVATE | DB_INIT_MPOOL;
712 isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
713 DNS_LOGMODULE_DLZ, ISC_LOG_DEBUG(1),
714 "bdbhpt driver using private mode.");
715 break;
716 default:
717 isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
718 DNS_LOGMODULE_DLZ, ISC_LOG_ERROR,
719 "bdbhpt driver requires the operating mode "
720 "be set to P or C or T. You specified '%s'",
721 argv[1]);
722 return (ISC_R_FAILURE);
725 /* allocate and zero memory for driver structure */
726 db = isc_mem_get(ns_g_mctx, sizeof(bdbhpt_instance_t));
727 if (db == NULL) {
728 isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
729 DNS_LOGMODULE_DLZ, ISC_LOG_ERROR,
730 "Could not allocate memory for "
731 "database instance object.");
732 return (ISC_R_NOMEMORY);
734 memset(db, 0, sizeof(bdbhpt_instance_t));
736 /* attach to the memory context */
737 isc_mem_attach(ns_g_mctx, &db->mctx);
740 * create bdbhpt environment
741 * Basically bdbhpt allocates and assigns memory to db->dbenv
743 bdbhptres = db_env_create(&db->dbenv, 0);
744 if (bdbhptres != 0) {
745 isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
746 DNS_LOGMODULE_DLZ, ISC_LOG_ERROR,
747 "bdbhpt environment could not be created. "
748 "bdbhpt error: %s",
749 db_strerror(bdbhptres));
750 result = ISC_R_FAILURE;
751 goto init_cleanup;
754 /* open bdbhpt environment */
755 bdbhptres = db->dbenv->open(db->dbenv, argv[2],
756 bdbFlags | bdbhpt_threads | DB_CREATE, 0);
757 if (bdbhptres != 0) {
758 isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
759 DNS_LOGMODULE_DLZ, ISC_LOG_ERROR,
760 "bdbhpt environment at '%s' could not be opened."
761 " bdbhpt error: %s",
762 argv[2], db_strerror(bdbhptres));
763 result = ISC_R_FAILURE;
764 goto init_cleanup;
767 /* open dlz_data database. */
768 result = bdbhpt_opendb(db->dbenv, DB_UNKNOWN, &db->data,
769 dlz_data, argv[3], DB_DUP | DB_DUPSORT);
770 if (result != ISC_R_SUCCESS)
771 goto init_cleanup;
773 /* open dlz_xfr database. */
774 result = bdbhpt_opendb(db->dbenv, DB_UNKNOWN, &db->xfr,
775 dlz_xfr, argv[3], DB_DUP | DB_DUPSORT);
776 if (result != ISC_R_SUCCESS)
777 goto init_cleanup;
779 /* open dlz_zone database. */
780 result = bdbhpt_opendb(db->dbenv, DB_UNKNOWN, &db->zone,
781 dlz_zone, argv[3], 0);
782 if (result != ISC_R_SUCCESS)
783 goto init_cleanup;
785 /* open dlz_client database. */
786 result = bdbhpt_opendb(db->dbenv, DB_UNKNOWN, &db->client,
787 dlz_client, argv[3], DB_DUP | DB_DUPSORT);
788 if (result != ISC_R_SUCCESS)
789 goto init_cleanup;
791 *dbdata = db;
793 return(ISC_R_SUCCESS);
795 init_cleanup:
797 bdbhpt_cleanup(db);
798 return result;
801 static void
802 bdbhpt_destroy(void *driverarg, void *dbdata)
804 UNUSED(driverarg);
806 bdbhpt_cleanup((bdbhpt_instance_t *) dbdata);
810 * bdbhpt_authority not needed as authority data is returned by lookup
812 static dns_sdlzmethods_t dlz_bdbhpt_methods = {
813 bdbhpt_create,
814 bdbhpt_destroy,
815 bdbhpt_findzone,
816 bdbhpt_lookup,
817 NULL,
818 bdbhpt_allnodes,
819 bdbhpt_allowzonexfr,
820 NULL,
821 NULL,
822 NULL,
823 NULL,
824 NULL,
825 NULL,
826 NULL,
830 * Wrapper around dns_sdlzregister().
832 isc_result_t
833 dlz_bdbhpt_init(void) {
834 isc_result_t result;
837 * Write debugging message to log
839 isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
840 DNS_LOGMODULE_DLZ, ISC_LOG_DEBUG(2),
841 "Registering DLZ bdbhpt driver.");
843 result = dns_sdlzregister("bdbhpt", &dlz_bdbhpt_methods, NULL,
844 DNS_SDLZFLAG_RELATIVEOWNER |
845 DNS_SDLZFLAG_RELATIVERDATA |
846 DNS_SDLZFLAG_THREADSAFE,
847 ns_g_mctx, &dlz_bdbhpt);
848 if (result != ISC_R_SUCCESS) {
849 UNEXPECTED_ERROR(__FILE__, __LINE__,
850 "dns_sdlzregister() failed: %s",
851 isc_result_totext(result));
852 result = ISC_R_UNEXPECTED;
856 return result;
860 * Wrapper around dns_sdlzunregister().
862 void
863 dlz_bdbhpt_clear(void) {
866 * Write debugging message to log
868 isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
869 DNS_LOGMODULE_DLZ, ISC_LOG_DEBUG(2),
870 "Unregistering DLZ bdbhpt driver.");
872 if (dlz_bdbhpt != NULL)
873 dns_sdlzunregister(&dlz_bdbhpt);
876 #endif