Sync usage with man page.
[netbsd-mini2440.git] / external / bsd / bind / dist / contrib / dlz / drivers / dlz_bdbhpt_driver.c
blob09338c36bb5a7c096ac1ef42a0eed0cc737adcf3
1 /* $NetBSD$ */
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);
120 * Reverses a string in place.
123 static char *bdbhpt_strrev(char *str)
125 char *p1, *p2;
127 if (! str || ! *str)
128 return str;
129 for (p1 = str, p2 = str + strlen(str) - 1; p2 > p1; ++p1, --p2)
131 *p1 ^= *p2;
132 *p2 ^= *p1;
133 *p1 ^= *p2;
135 return str;
139 * Parses the DBT from the Berkeley DB into a parsed_data record
140 * The parsed_data record should be allocated before and passed into the
141 * bdbhpt_parse_data function. The char (type & data) fields should not
142 * be "free"d as that memory is part of the DBT data field. It will be
143 * "free"d when the DBT is freed.
146 static isc_result_t
147 bdbhpt_parse_data(char *in, bdbhpt_parsed_data_t *pd) {
149 char *endp, *ttlStr;
150 char *tmp = in;
151 char *lastchar = (char *) &tmp[strlen(tmp)];
154 * String should be formated as:
155 * replication_id
156 * (a space)
157 * host_name
158 * (a space)
159 * ttl
160 * (a space)
161 * type
162 * (a space)
163 * remaining data
165 * examples:
167 * 9191 host 10 A 127.0.0.1
168 * server1_212 host 10 A 127.0.0.2
169 * {xxxx-xxxx-xxxx-xxxx-xxxx} host 10 MX 20 mail.example.com
173 * we don't need the replication id, so don't
174 * bother saving a pointer to it.
177 /* find space after replication id */
178 tmp = strchr(tmp, ' ');
179 /* verify we found a space */
180 if (tmp == NULL)
181 return ISC_R_FAILURE;
182 /* make sure it is safe to increment pointer */
183 if (++tmp > lastchar)
184 return ISC_R_FAILURE;
186 /* save pointer to host */
187 pd->host = tmp;
189 /* find space after host and change it to a '\0' */
190 tmp = strchr(tmp, ' ');
191 /* verify we found a space */
192 if (tmp == NULL)
193 return ISC_R_FAILURE;
194 /* change the space to a null (string terminator) */
195 tmp[0] = '\0';
196 /* make sure it is safe to increment pointer */
197 if (++tmp > lastchar)
198 return ISC_R_FAILURE;
200 /* save pointer to ttl string */
201 ttlStr = tmp;
203 /* find space after ttl and change it to a '\0' */
204 tmp = strchr(tmp, ' ');
205 /* verify we found a space */
206 if (tmp == NULL)
207 return ISC_R_FAILURE;
208 /* change the space to a null (string terminator) */
209 tmp[0] = '\0';
210 /* make sure it is safe to increment pointer */
211 if (++tmp > lastchar)
212 return ISC_R_FAILURE;
214 /* save pointer to dns type */
215 pd->type = tmp;
217 /* find space after type and change it to a '\0' */
218 tmp = strchr(tmp, ' ');
219 /* verify we found a space */
220 if (tmp == NULL)
221 return ISC_R_FAILURE;
222 /* change the space to a null (string terminator) */
223 tmp[0] = '\0';
224 /* make sure it is safe to increment pointer */
225 if (++tmp > lastchar)
226 return ISC_R_FAILURE;
228 /* save pointer to remainder of DNS data */
229 pd->data = tmp;
231 /* convert ttl string to integer */
232 pd->ttl = strtol(ttlStr, &endp, 10);
233 if (*endp != '\0' || pd->ttl < 0) {
234 isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
235 DNS_LOGMODULE_DLZ, ISC_LOG_ERROR,
236 "bdbhpt driver ttl must be a postive number");
237 return ISC_R_FAILURE;
240 /* if we get this far everything should have worked. */
241 return ISC_R_SUCCESS;
245 * DLZ methods
248 static isc_result_t
249 bdbhpt_allowzonexfr(void *driverarg, void *dbdata, const char *name,
250 const char *client)
252 isc_result_t result;
253 bdbhpt_instance_t *db = (bdbhpt_instance_t *) dbdata;
254 DBT key, data;
256 /* check to see if we are authoritative for the zone first. */
257 result = bdbhpt_findzone(driverarg, dbdata, name);
258 if (result != ISC_R_SUCCESS)
259 return (ISC_R_NOTFOUND);
261 memset(&key, 0, sizeof(DBT));
262 key.flags = DB_DBT_MALLOC;
263 key.data = strdup(name);
264 if (key.data == NULL) {
265 result = ISC_R_NOMEMORY;
266 goto xfr_cleanup;
268 key.size = strlen(key.data);
270 memset(&data, 0, sizeof(DBT));
271 data.flags = DB_DBT_MALLOC;
272 data.data = strdup(client);
273 if (data.data == NULL) {
274 result = ISC_R_NOMEMORY;
275 goto xfr_cleanup;
277 data.size = strlen(data.data);
279 switch(db->client->get(db->client, NULL, &key, &data, DB_GET_BOTH)) {
280 case DB_NOTFOUND:
281 result = ISC_R_NOTFOUND;
282 break;
283 case 0:
284 result = ISC_R_SUCCESS;
285 break;
286 default:
287 result = ISC_R_FAILURE;
290 xfr_cleanup:
292 /* free any memory duplicate string in the key field */
293 if (key.data != NULL)
294 free(key.data);
296 /* free any memory allocated to the data field. */
297 if (data.data != NULL)
298 free(data.data);
300 return result;
305 * BDB does not allow a secondary index on a database that allows
306 * duplicates. We have a few options:
308 * 1) kill speed by having lookup method use a secondary db which
309 * is associated to the primary DB with the DNS data. Then have
310 * another secondary db for zone transfer which also points to
311 * the dns_data primary. NO - The point of this driver is
312 * lookup performance.
314 * 2) Blow up database size by storing DNS data twice. Once for
315 * the lookup (dns_data) database, and a second time for the zone
316 * transfer (dns_xfr) database. NO - That would probably require
317 * a larger cache to provide good performance. Also, that would
318 * make the DB larger on disk potentially slowing it as well.
320 * 3) Loop through the dns_xfr database with a cursor to get
321 * all the different hosts in a zone. Then use the zone & host
322 * together to lookup the data in the dns_data database. YES -
323 * This may slow down zone xfr's a little, but that's ok they
324 * don't happen as often and don't need to be as fast. We can
325 * also use this table when deleting a zone (The BDB driver
326 * is read only - the delete would be used during replication
327 * updates by a separate process).
330 static isc_result_t
331 bdbhpt_allnodes(const char *zone, void *driverarg, void *dbdata,
332 dns_sdlzallnodes_t *allnodes)
335 isc_result_t result = ISC_R_NOTFOUND;
336 bdbhpt_instance_t *db = (bdbhpt_instance_t *) dbdata;
337 DBC *xfr_cursor = NULL;
338 DBC *dns_cursor = NULL;
339 DBT xfr_key, xfr_data, dns_key, dns_data;
340 int xfr_flags;
341 int dns_flags;
342 int bdbhptres;
343 bdbhpt_parsed_data_t pd;
344 char *tmp = NULL, *tmp_zone, *tmp_zone_host = NULL;
346 UNUSED(driverarg);
348 memset(&xfr_key, 0, sizeof(DBT));
349 memset(&xfr_data, 0, sizeof(DBT));
350 memset(&dns_key, 0, sizeof(DBT));
351 memset(&dns_data, 0, sizeof(DBT));
353 xfr_key.data = tmp_zone = strdup(zone);
354 if (xfr_key.data == NULL)
355 return (ISC_R_NOMEMORY);
357 xfr_key.size = strlen(xfr_key.data);
359 /* get a cursor to loop through dns_xfr table */
360 if (db->xfr->cursor(db->xfr, NULL, &xfr_cursor, 0) != 0) {
361 result = ISC_R_FAILURE;
362 goto allnodes_cleanup;
365 /* get a cursor to loop through dns_data table */
366 if (db->data->cursor(db->data, NULL, &dns_cursor, 0) != 0) {
367 result = ISC_R_FAILURE;
368 goto allnodes_cleanup;
371 xfr_flags = DB_SET;
373 /* loop through xfr table for specified zone. */
374 while ((bdbhptres = xfr_cursor->c_get(xfr_cursor, &xfr_key, &xfr_data,
375 xfr_flags)) == 0) {
377 xfr_flags = DB_NEXT_DUP;
379 /* +1 to allow for space between zone and host names */
380 dns_key.size = xfr_data.size + xfr_key.size + 1;
382 /* +1 to allow for null term at end of string. */
383 dns_key.data = tmp_zone_host = malloc(dns_key.size + 1);
384 if (dns_key.data == NULL)
385 goto allnodes_cleanup;
388 * construct search key for dns_data.
389 * zone_name(a space)host_name
391 strcpy(dns_key.data, zone);
392 strcat(dns_key.data, " ");
393 strncat(dns_key.data, xfr_data.data, xfr_data.size);
395 dns_flags = DB_SET;
397 while ((bdbhptres = dns_cursor->c_get(dns_cursor, &dns_key,
398 &dns_data,
399 dns_flags)) == 0) {
401 dns_flags = DB_NEXT_DUP;
403 /* +1 to allow for null term at end of string. */
404 tmp = realloc(tmp, dns_data.size + 1);
405 if (tmp == NULL)
406 goto allnodes_cleanup;
408 /* copy data to tmp string, and append null term. */
409 strncpy(tmp, dns_data.data, dns_data.size);
410 tmp[dns_data.size] = '\0';
412 /* split string into dns data parts. */
413 if (bdbhpt_parse_data(tmp, &pd) != ISC_R_SUCCESS)
414 goto allnodes_cleanup;
416 result = dns_sdlz_putnamedrr(allnodes, pd.host,
417 pd.type, pd.ttl, pd.data);
418 if (result != ISC_R_SUCCESS)
419 goto allnodes_cleanup;
421 } /* end inner while loop */
423 /* clean up memory */
424 if (tmp_zone_host != NULL) {
425 free(tmp_zone_host);
426 tmp_zone_host = NULL;
428 } /* end outer while loop */
430 allnodes_cleanup:
432 /* free any memory */
433 if (tmp != NULL)
434 free(tmp);
436 if (tmp_zone_host != NULL)
437 free(tmp_zone_host);
439 if (tmp_zone != NULL)
440 free(tmp_zone);
442 /* get rid of cursors */
443 if (xfr_cursor != NULL)
444 xfr_cursor->c_close(xfr_cursor);
446 if (dns_cursor != NULL)
447 dns_cursor->c_close(xfr_cursor);
449 return result;
453 * Performs bdbhpt cleanup.
454 * Used by bdbhpt_create if there is an error starting up.
455 * Used by bdbhpt_destroy when the driver is shutting down.
458 static void
459 bdbhpt_cleanup(bdbhpt_instance_t *db) {
461 isc_mem_t *mctx;
463 /* close databases */
464 if (db->data != NULL)
465 db->data->close(db->data, 0);
466 if (db->xfr != NULL)
467 db->xfr->close(db->xfr, 0);
468 if (db->zone != NULL)
469 db->zone->close(db->zone, 0);
470 if (db->client != NULL)
471 db->client->close(db->client, 0);
473 /* close environment */
474 if (db->dbenv != NULL)
475 db->dbenv->close(db->dbenv, 0);
477 /* cleanup memory */
478 if (db->mctx != NULL) {
479 /* save mctx for later */
480 mctx = db->mctx;
481 /* return, and detach the memory */
482 isc_mem_put(mctx, db, sizeof(bdbhpt_instance_t));
483 isc_mem_detach(&mctx);
487 static isc_result_t
488 bdbhpt_findzone(void *driverarg, void *dbdata, const char *name)
491 isc_result_t result;
492 bdbhpt_instance_t *db = (bdbhpt_instance_t *) dbdata;
493 DBT key, data;
495 UNUSED(driverarg);
497 memset(&key, 0, sizeof(DBT));
498 memset(&data, 0, sizeof(DBT));
499 data.flags = DB_DBT_MALLOC;
501 key.data = strdup(name);
503 if (key.data == NULL)
504 return (ISC_R_NOMEMORY);
507 * reverse string to take advantage of BDB locality of reference
508 * if we need futher lookups because the zone doesn't match the
509 * first time.
511 key.data = bdbhpt_strrev(key.data);
512 key.size = strlen(key.data);
514 switch(db->zone->get(db->zone, NULL, &key, &data, 0)) {
515 case DB_NOTFOUND:
516 result = ISC_R_NOTFOUND;
517 break;
518 case 0:
519 result = ISC_R_SUCCESS;
520 break;
521 default:
522 result = ISC_R_FAILURE;
525 /* free any memory duplicate string in the key field */
526 if (key.data != NULL)
527 free(key.data);
529 /* free any memory allocated to the data field. */
530 if (data.data != NULL)
531 free(data.data);
533 return result;
536 static isc_result_t
537 bdbhpt_lookup(const char *zone, const char *name, void *driverarg,
538 void *dbdata, dns_sdlzlookup_t *lookup)
541 isc_result_t result = ISC_R_NOTFOUND;
542 bdbhpt_instance_t *db = (bdbhpt_instance_t *) dbdata;
543 DBC *data_cursor = NULL;
544 DBT key, data;
545 int bdbhptres;
546 int flags;
548 bdbhpt_parsed_data_t pd;
549 char *tmp = NULL;
550 char *keyStr = NULL;
552 UNUSED(driverarg);
554 memset(&key, 0, sizeof(DBT));
555 memset(&data, 0, sizeof(DBT));
557 key.size = strlen(zone) + strlen(name) + 1;
559 /* allocate mem for key */
560 key.data = keyStr = malloc((key.size + 1) * sizeof(char));
562 if (keyStr == NULL)
563 return ISC_R_NOMEMORY;
565 strcpy(keyStr, zone);
566 strcat(keyStr, " ");
567 strcat(keyStr, name);
569 /* get a cursor to loop through data */
570 if (db->data->cursor(db->data, NULL, &data_cursor, 0) != 0) {
571 result = ISC_R_FAILURE;
572 goto lookup_cleanup;
575 result = ISC_R_NOTFOUND;
577 flags = DB_SET;
578 while ((bdbhptres = data_cursor->c_get(data_cursor, &key, &data,
579 flags)) == 0) {
581 flags = DB_NEXT_DUP;
582 tmp = realloc(tmp, data.size + 1);
583 if (tmp == NULL)
584 goto lookup_cleanup;
586 strncpy(tmp, data.data, data.size);
587 tmp[data.size] = '\0';
589 if (bdbhpt_parse_data(tmp, &pd) != ISC_R_SUCCESS)
590 goto lookup_cleanup;
592 result = dns_sdlz_putrr(lookup, pd.type, pd.ttl, pd.data);
594 if (result != ISC_R_SUCCESS)
595 goto lookup_cleanup;
596 } /* end while loop */
598 lookup_cleanup:
600 /* get rid of cursor */
601 if (data_cursor != NULL)
602 data_cursor->c_close(data_cursor);
604 if (keyStr != NULL)
605 free(keyStr);
606 if (tmp != NULL)
607 free(tmp);
609 return result;
612 /*% Initializes, sets flags and then opens Berkeley databases. */
614 static isc_result_t
615 bdbhpt_opendb(DB_ENV *db_env, DBTYPE db_type, DB **db, const char *db_name,
616 char *db_file, int flags) {
618 int result;
620 /* Initialize the database. */
621 if ((result = db_create(db, db_env, 0)) != 0) {
622 isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
623 DNS_LOGMODULE_DLZ, ISC_LOG_ERROR,
624 "bdbhpt could not initialize %s database. "
625 "bdbhpt error: %s",
626 db_name, db_strerror(result));
627 return ISC_R_FAILURE;
630 /* set database flags. */
631 if ((result = (*db)->set_flags(*db, flags)) != 0) {
632 isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
633 DNS_LOGMODULE_DLZ, ISC_LOG_ERROR,
634 "bdbhpt could not set flags for %s database. "
635 "bdbhpt error: %s",
636 db_name, db_strerror(result));
637 return ISC_R_FAILURE;
640 /* open the database. */
641 if ((result = (*db)->open(*db, NULL, db_file, db_name, db_type,
642 DB_RDONLY | bdbhpt_threads, 0)) != 0) {
643 isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
644 DNS_LOGMODULE_DLZ, ISC_LOG_ERROR,
645 "bdbhpt could not open %s database in %s. "
646 "bdbhpt error: %s",
647 db_name, db_file, db_strerror(result));
648 return ISC_R_FAILURE;
651 return ISC_R_SUCCESS;
654 static isc_result_t
655 bdbhpt_create(const char *dlzname, unsigned int argc, char *argv[],
656 void *driverarg, void **dbdata)
658 isc_result_t result;
659 int bdbhptres;
660 int bdbFlags = 0;
661 bdbhpt_instance_t *db = NULL;
663 UNUSED(dlzname);
664 UNUSED(driverarg);
666 /* verify we have 4 arg's passed to the driver */
667 if (argc != 4) {
668 isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
669 DNS_LOGMODULE_DLZ, ISC_LOG_ERROR,
670 "bdbhpt driver requires at least "
671 "3 command line args.");
672 return (ISC_R_FAILURE);
675 switch((char) *argv[1]) {
677 * Transactional mode. Highest safety - lowest speed.
679 case 'T':
680 case 't':
681 bdbFlags = DB_INIT_MPOOL | DB_INIT_LOCK |
682 DB_INIT_LOG | DB_INIT_TXN;
683 isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
684 DNS_LOGMODULE_DLZ, ISC_LOG_DEBUG(1),
685 "bdbhpt driver using transactional mode.");
686 break;
688 * Concurrent mode. Lower safety (no rollback) -
689 * higher speed.
691 case 'C':
692 case 'c':
693 bdbFlags = DB_INIT_CDB | DB_INIT_MPOOL;
694 isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
695 DNS_LOGMODULE_DLZ, ISC_LOG_DEBUG(1),
696 "bdbhpt driver using concurrent mode.");
697 break;
699 * Private mode. No inter-process communication & no locking.
700 * Lowest saftey - highest speed.
702 case 'P':
703 case 'p':
704 bdbFlags = DB_PRIVATE | DB_INIT_MPOOL;
705 isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
706 DNS_LOGMODULE_DLZ, ISC_LOG_DEBUG(1),
707 "bdbhpt driver using private mode.");
708 break;
709 default:
710 isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
711 DNS_LOGMODULE_DLZ, ISC_LOG_ERROR,
712 "bdbhpt driver requires the operating mode "
713 "be set to P or C or T. You specified '%s'",
714 argv[1]);
715 return (ISC_R_FAILURE);
718 /* allocate and zero memory for driver structure */
719 db = isc_mem_get(ns_g_mctx, sizeof(bdbhpt_instance_t));
720 if (db == NULL) {
721 isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
722 DNS_LOGMODULE_DLZ, ISC_LOG_ERROR,
723 "Could not allocate memory for "
724 "database instance object.");
725 return (ISC_R_NOMEMORY);
727 memset(db, 0, sizeof(bdbhpt_instance_t));
729 /* attach to the memory context */
730 isc_mem_attach(ns_g_mctx, &db->mctx);
733 * create bdbhpt environment
734 * Basically bdbhpt allocates and assigns memory to db->dbenv
736 bdbhptres = db_env_create(&db->dbenv, 0);
737 if (bdbhptres != 0) {
738 isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
739 DNS_LOGMODULE_DLZ, ISC_LOG_ERROR,
740 "bdbhpt environment could not be created. "
741 "bdbhpt error: %s",
742 db_strerror(bdbhptres));
743 result = ISC_R_FAILURE;
744 goto init_cleanup;
747 /* open bdbhpt environment */
748 bdbhptres = db->dbenv->open(db->dbenv, argv[2],
749 bdbFlags | bdbhpt_threads | DB_CREATE, 0);
750 if (bdbhptres != 0) {
751 isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
752 DNS_LOGMODULE_DLZ, ISC_LOG_ERROR,
753 "bdbhpt environment at '%s' could not be opened."
754 " bdbhpt error: %s",
755 argv[2], db_strerror(bdbhptres));
756 result = ISC_R_FAILURE;
757 goto init_cleanup;
760 /* open dlz_data database. */
761 result = bdbhpt_opendb(db->dbenv, DB_UNKNOWN, &db->data,
762 dlz_data, argv[3], DB_DUP | DB_DUPSORT);
763 if (result != ISC_R_SUCCESS)
764 goto init_cleanup;
766 /* open dlz_xfr database. */
767 result = bdbhpt_opendb(db->dbenv, DB_UNKNOWN, &db->xfr,
768 dlz_xfr, argv[3], DB_DUP | DB_DUPSORT);
769 if (result != ISC_R_SUCCESS)
770 goto init_cleanup;
772 /* open dlz_zone database. */
773 result = bdbhpt_opendb(db->dbenv, DB_UNKNOWN, &db->zone,
774 dlz_zone, argv[3], 0);
775 if (result != ISC_R_SUCCESS)
776 goto init_cleanup;
778 /* open dlz_client database. */
779 result = bdbhpt_opendb(db->dbenv, DB_UNKNOWN, &db->client,
780 dlz_client, argv[3], DB_DUP | DB_DUPSORT);
781 if (result != ISC_R_SUCCESS)
782 goto init_cleanup;
784 *dbdata = db;
786 return(ISC_R_SUCCESS);
788 init_cleanup:
790 bdbhpt_cleanup(db);
791 return result;
794 static void
795 bdbhpt_destroy(void *driverarg, void *dbdata)
797 UNUSED(driverarg);
799 bdbhpt_cleanup((bdbhpt_instance_t *) dbdata);
803 * bdbhpt_authority not needed as authority data is returned by lookup
805 static dns_sdlzmethods_t dlz_bdbhpt_methods = {
806 bdbhpt_create,
807 bdbhpt_destroy,
808 bdbhpt_findzone,
809 bdbhpt_lookup,
810 NULL,
811 bdbhpt_allnodes,
812 bdbhpt_allowzonexfr
816 * Wrapper around dns_sdlzregister().
818 isc_result_t
819 dlz_bdbhpt_init(void) {
820 isc_result_t result;
823 * Write debugging message to log
825 isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
826 DNS_LOGMODULE_DLZ, ISC_LOG_DEBUG(2),
827 "Registering DLZ bdbhpt driver.");
829 result = dns_sdlzregister("bdbhpt", &dlz_bdbhpt_methods, NULL,
830 DNS_SDLZFLAG_RELATIVEOWNER |
831 DNS_SDLZFLAG_RELATIVERDATA |
832 DNS_SDLZFLAG_THREADSAFE,
833 ns_g_mctx, &dlz_bdbhpt);
834 if (result != ISC_R_SUCCESS) {
835 UNEXPECTED_ERROR(__FILE__, __LINE__,
836 "dns_sdlzregister() failed: %s",
837 isc_result_totext(result));
838 result = ISC_R_UNEXPECTED;
842 return result;
846 * Wrapper around dns_sdlzunregister().
848 void
849 dlz_bdbhpt_clear(void) {
852 * Write debugging message to log
854 isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
855 DNS_LOGMODULE_DLZ, ISC_LOG_DEBUG(2),
856 "Unregistering DLZ bdbhpt driver.");
858 if (dlz_bdbhpt != NULL)
859 dns_sdlzunregister(&dlz_bdbhpt);
862 #endif