Remove building with NOCRYPTO option
[minix.git] / external / bsd / bind / dist / contrib / dlz / modules / bdbhpt / dlz_bdbhpt_dynamic.c
blob9779c8502bee3ffdd8940140466e48436a669ec8
1 /* $NetBSD: dlz_bdbhpt_dynamic.c,v 1.1.1.5 2015/07/08 15:37:45 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) 2011 Internet Systems Consortium, Inc. ("ISC")
41 * Permission to use, copy, modify, and/or 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 ISC DISCLAIMS ALL WARRANTIES WITH
46 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
47 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
48 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
49 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
50 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
51 * PERFORMANCE OF THIS SOFTWARE.
55 * This is simply a merge of Andrew Tridgell's dlz_example.c and the
56 * original bdb_bdbhpt_driver.c
58 * This provides the externally loadable bdbhpt DLZ driver, without
59 * update support
63 #include <stdio.h>
64 #include <stdlib.h>
65 #include <string.h>
66 #include <stdarg.h>
67 #include <stdint.h>
69 #include <db.h>
71 #include "dlz_minimal.h"
73 /* should the bdb driver use threads. */
74 #ifdef ISC_PLATFORM_USETHREADS
75 #define bdbhpt_threads DB_THREAD
76 #else
77 #define bdbhpt_threads 0
78 #endif
80 /* bdbhpt database names */
81 #define dlz_data "dns_data"
82 #define dlz_zone "dns_zone"
83 #define dlz_xfr "dns_xfr"
84 #define dlz_client "dns_client"
86 #define dlz_bdbhpt_dynamic_version "0.1"
89 * This structure contains all our DB handles and helper functions we
90 * inherit from the dlz_dlopen driver
93 typedef struct bdbhpt_instance {
94 DB_ENV *dbenv; /* bdbhpt environment */
95 DB *data; /* dns_data database handle */
96 DB *zone; /* zone database handle */
97 DB *xfr; /* zone xfr database handle */
98 DB *client; /* client database handle */
100 /* Helper functions from the dlz_dlopen driver */
101 log_t *log;
102 dns_sdlz_putrr_t *putrr;
103 dns_sdlz_putnamedrr_t *putnamedrr;
104 dns_dlz_writeablezone_t *writeable_zone;
105 } bdbhpt_instance_t;
107 typedef struct bdbhpt_parsed_data {
108 char *host;
109 char *type;
110 int ttl;
111 char *data;
112 } bdbhpt_parsed_data_t;
114 static void
115 b9_add_helper(struct bdbhpt_instance *db, const char *helper_name, void *ptr);
118 * Reverses a string in place.
120 static char
121 *bdbhpt_strrev(char *str) {
122 char *p1, *p2;
124 if (! str || ! *str)
125 return str;
126 for (p1 = str, p2 = str + strlen(str) - 1; p2 > p1; ++p1, --p2) {
127 *p1 ^= *p2;
128 *p2 ^= *p1;
129 *p1 ^= *p2;
131 return str;
135 * Parses the DBT from the Berkeley DB into a parsed_data record
136 * The parsed_data record should be allocated before and passed into the
137 * bdbhpt_parse_data function. The char (type & data) fields should not
138 * be "free"d as that memory is part of the DBT data field. It will be
139 * "free"d when the DBT is freed.
142 static isc_result_t
143 bdbhpt_parse_data(log_t *log, char *in, bdbhpt_parsed_data_t *pd) {
145 char *endp, *ttlStr;
146 char *tmp = in;
147 char *lastchar = (char *) &tmp[strlen(tmp)];
150 * String should be formatted as:
151 * replication_id
152 * (a space)
153 * host_name
154 * (a space)
155 * ttl
156 * (a space)
157 * type
158 * (a space)
159 * remaining data
161 * examples:
163 * 9191 host 10 A 127.0.0.1
164 * server1_212 host 10 A 127.0.0.2
165 * {xxxx-xxxx-xxxx-xxxx-xxxx} host 10 MX 20 mail.example.com
169 * we don't need the replication id, so don't
170 * bother saving a pointer to it.
173 /* find space after replication id */
174 tmp = strchr(tmp, ' ');
175 /* verify we found a space */
176 if (tmp == NULL)
177 return ISC_R_FAILURE;
178 /* make sure it is safe to increment pointer */
179 if (++tmp > lastchar)
180 return ISC_R_FAILURE;
182 /* save pointer to host */
183 pd->host = tmp;
185 /* find space after host and change it to a '\0' */
186 tmp = strchr(tmp, ' ');
187 /* verify we found a space */
188 if (tmp == NULL)
189 return ISC_R_FAILURE;
190 /* change the space to a null (string terminator) */
191 tmp[0] = '\0';
192 /* make sure it is safe to increment pointer */
193 if (++tmp > lastchar)
194 return ISC_R_FAILURE;
196 /* save pointer to ttl string */
197 ttlStr = tmp;
199 /* find space after ttl and change it to a '\0' */
200 tmp = strchr(tmp, ' ');
201 /* verify we found a space */
202 if (tmp == NULL)
203 return ISC_R_FAILURE;
204 /* change the space to a null (string terminator) */
205 tmp[0] = '\0';
206 /* make sure it is safe to increment pointer */
207 if (++tmp > lastchar)
208 return ISC_R_FAILURE;
210 /* save pointer to dns type */
211 pd->type = tmp;
213 /* find space after type and change it to a '\0' */
214 tmp = strchr(tmp, ' ');
215 /* verify we found a space */
216 if (tmp == NULL)
217 return ISC_R_FAILURE;
218 /* change the space to a null (string terminator) */
219 tmp[0] = '\0';
220 /* make sure it is safe to increment pointer */
221 if (++tmp > lastchar)
222 return ISC_R_FAILURE;
224 /* save pointer to remainder of DNS data */
225 pd->data = tmp;
227 /* convert ttl string to integer */
228 pd->ttl = strtol(ttlStr, &endp, 10);
229 if (*endp != '\0' || pd->ttl < 0) {
230 log(ISC_LOG_ERROR,
231 "bdbhpt_dynamic: "
232 "ttl must be a positive number");
233 return ISC_R_FAILURE;
236 /* if we get this far everything should have worked. */
237 return ISC_R_SUCCESS;
241 * See if a zone transfer is allowed
243 isc_result_t
244 dlz_allowzonexfr(void *dbdata, const char *name, const char *client) {
245 isc_result_t result;
246 bdbhpt_instance_t *db = (bdbhpt_instance_t *) dbdata;
247 DBT key, data;
249 /* check to see if we are authoritative for the zone first. */
250 #if DLZ_DLOPEN_VERSION >= 3
251 result = dlz_findzonedb(dbdata, name, NULL, NULL);
252 #else
253 result = dlz_findzonedb(dbdata, name);
254 #endif
255 if (result != ISC_R_SUCCESS)
256 return (ISC_R_NOTFOUND);
258 memset(&key, 0, sizeof(DBT));
259 key.flags = DB_DBT_MALLOC;
260 key.data = strdup(name);
261 if (key.data == NULL) {
262 result = ISC_R_NOMEMORY;
263 goto xfr_cleanup;
265 key.size = strlen(key.data);
267 memset(&data, 0, sizeof(DBT));
268 data.flags = DB_DBT_MALLOC;
269 data.data = strdup(client);
270 if (data.data == NULL) {
271 result = ISC_R_NOMEMORY;
272 goto xfr_cleanup;
274 data.size = strlen(data.data);
276 switch(db->client->get(db->client, NULL, &key, &data, DB_GET_BOTH)) {
277 case DB_NOTFOUND:
278 result = ISC_R_NOTFOUND;
279 break;
280 case 0:
281 result = ISC_R_SUCCESS;
282 break;
283 default:
284 result = ISC_R_FAILURE;
287 xfr_cleanup:
288 /* free any memory duplicate string in the key field */
289 if (key.data != NULL)
290 free(key.data);
292 /* free any memory allocated to the data field. */
293 if (data.data != NULL)
294 free(data.data);
296 return result;
300 * Perform a zone transfer
302 * BDB does not allow a secondary index on a database that allows
303 * duplicates. We have a few options:
305 * 1) kill speed by having lookup method use a secondary db which
306 * is associated to the primary DB with the DNS data. Then have
307 * another secondary db for zone transfer which also points to
308 * the dns_data primary. NO - The point of this driver is
309 * lookup performance.
311 * 2) Blow up database size by storing DNS data twice. Once for
312 * the lookup (dns_data) database, and a second time for the zone
313 * transfer (dns_xfr) database. NO - That would probably require
314 * a larger cache to provide good performance. Also, that would
315 * make the DB larger on disk potentially slowing it as well.
317 * 3) Loop through the dns_xfr database with a cursor to get
318 * all the different hosts in a zone. Then use the zone & host
319 * together to lookup the data in the dns_data database. YES -
320 * This may slow down zone xfr's a little, but that's ok they
321 * don't happen as often and don't need to be as fast. We can
322 * also use this table when deleting a zone (The BDB driver
323 * is read only - the delete would be used during replication
324 * updates by a separate process).
326 isc_result_t
327 dlz_allnodes(const char *zone, void *dbdata, dns_sdlzallnodes_t *allnodes) {
328 isc_result_t result = ISC_R_NOTFOUND;
329 bdbhpt_instance_t *db = (bdbhpt_instance_t *) dbdata;
330 DBC *xfr_cursor = NULL;
331 DBC *dns_cursor = NULL;
332 DBT xfr_key, xfr_data, dns_key, dns_data;
333 int xfr_flags;
334 int dns_flags;
335 int bdbhptres;
336 bdbhpt_parsed_data_t pd;
337 char *tmp = NULL, *tmp_zone, *tmp_zone_host = NULL;
339 memset(&xfr_key, 0, sizeof(DBT));
340 memset(&xfr_data, 0, sizeof(DBT));
341 memset(&dns_key, 0, sizeof(DBT));
342 memset(&dns_data, 0, sizeof(DBT));
344 xfr_key.data = tmp_zone = strdup(zone);
345 if (xfr_key.data == NULL)
346 return (ISC_R_NOMEMORY);
348 xfr_key.size = strlen(xfr_key.data);
350 /* get a cursor to loop through dns_xfr table */
351 if (db->xfr->cursor(db->xfr, NULL, &xfr_cursor, 0) != 0) {
352 result = ISC_R_FAILURE;
353 goto allnodes_cleanup;
356 /* get a cursor to loop through dns_data table */
357 if (db->data->cursor(db->data, NULL, &dns_cursor, 0) != 0) {
358 result = ISC_R_FAILURE;
359 goto allnodes_cleanup;
362 xfr_flags = DB_SET;
364 /* loop through xfr table for specified zone. */
365 while ((bdbhptres = xfr_cursor->c_get(xfr_cursor, &xfr_key,
366 &xfr_data, xfr_flags)) == 0)
368 xfr_flags = DB_NEXT_DUP;
370 /* +1 to allow for space between zone and host names */
371 dns_key.size = xfr_data.size + xfr_key.size + 1;
373 /* +1 to allow for null term at end of string. */
374 dns_key.data = tmp_zone_host = malloc(dns_key.size + 1);
375 if (dns_key.data == NULL)
376 goto allnodes_cleanup;
379 * construct search key for dns_data.
380 * zone_name(a space)host_name
382 strcpy(dns_key.data, zone);
383 strcat(dns_key.data, " ");
384 strncat(dns_key.data, xfr_data.data, xfr_data.size);
386 dns_flags = DB_SET;
388 while ((bdbhptres = dns_cursor->c_get(dns_cursor,
389 &dns_key,
390 &dns_data,
391 dns_flags)) == 0)
393 dns_flags = DB_NEXT_DUP;
395 /* +1 to allow for null term at end of string. */
396 tmp = realloc(tmp, dns_data.size + 1);
397 if (tmp == NULL)
398 goto allnodes_cleanup;
400 /* copy data to tmp string, and append null term. */
401 strncpy(tmp, dns_data.data, dns_data.size);
402 tmp[dns_data.size] = '\0';
404 /* split string into dns data parts. */
405 if (bdbhpt_parse_data(db->log,
406 tmp, &pd) != ISC_R_SUCCESS)
407 goto allnodes_cleanup;
408 result = db->putnamedrr(allnodes, pd.host,
409 pd.type, pd.ttl, pd.data);
410 if (result != ISC_R_SUCCESS)
411 goto allnodes_cleanup;
413 } /* end inner while loop */
415 /* clean up memory */
416 if (tmp_zone_host != NULL) {
417 free(tmp_zone_host);
418 tmp_zone_host = NULL;
420 } /* end outer while loop */
422 allnodes_cleanup:
423 /* free any memory */
424 if (tmp != NULL)
425 free(tmp);
427 if (tmp_zone_host != NULL)
428 free(tmp_zone_host);
430 if (tmp_zone != NULL)
431 free(tmp_zone);
433 /* get rid of cursors */
434 if (xfr_cursor != NULL)
435 xfr_cursor->c_close(xfr_cursor);
437 if (dns_cursor != NULL)
438 dns_cursor->c_close(dns_cursor);
440 return result;
444 * Performs bdbhpt cleanup.
445 * Used by bdbhpt_create if there is an error starting up.
446 * Used by bdbhpt_destroy when the driver is shutting down.
448 static void
449 bdbhpt_cleanup(bdbhpt_instance_t *db) {
450 /* close databases */
451 if (db->data != NULL)
452 db->data->close(db->data, 0);
453 if (db->xfr != NULL)
454 db->xfr->close(db->xfr, 0);
455 if (db->zone != NULL)
456 db->zone->close(db->zone, 0);
457 if (db->client != NULL)
458 db->client->close(db->client, 0);
460 /* close environment */
461 if (db->dbenv != NULL)
462 db->dbenv->close(db->dbenv, 0);
466 * See if we handle a given zone
468 #if DLZ_DLOPEN_VERSION < 3
469 isc_result_t
470 dlz_findzonedb(void *dbdata, const char *name)
471 #else
472 isc_result_t
473 dlz_findzonedb(void *dbdata, const char *name,
474 dns_clientinfomethods_t *methods,
475 dns_clientinfo_t *clientinfo)
476 #endif
478 isc_result_t result;
479 bdbhpt_instance_t *db = (bdbhpt_instance_t *) dbdata;
480 DBT key, data;
482 memset(&key, 0, sizeof(DBT));
483 memset(&data, 0, sizeof(DBT));
484 data.flags = DB_DBT_MALLOC;
486 #if DLZ_DLOPEN_VERSION >= 3
487 UNUSED(methods);
488 UNUSED(clientinfo);
489 #endif
491 key.data = strdup(name);
493 if (key.data == NULL)
494 return (ISC_R_NOMEMORY);
497 * reverse string to take advantage of BDB locality of reference
498 * if we need futher lookups because the zone doesn't match the
499 * first time.
501 key.data = bdbhpt_strrev(key.data);
502 key.size = strlen(key.data);
504 switch(db->zone->get(db->zone, NULL, &key, &data, 0)) {
505 case DB_NOTFOUND:
506 result = ISC_R_NOTFOUND;
507 break;
508 case 0:
509 result = ISC_R_SUCCESS;
510 break;
511 default:
512 result = ISC_R_FAILURE;
515 /* free any memory duplicate string in the key field */
516 if (key.data != NULL)
517 free(key.data);
519 /* free any memory allocated to the data field. */
520 if (data.data != NULL)
521 free(data.data);
523 return result;
527 * Look up one record in the database.
530 #if DLZ_DLOPEN_VERSION == 1
531 isc_result_t dlz_lookup(const char *zone, const char *name,
532 void *dbdata, dns_sdlzlookup_t *lookup)
533 #else
534 isc_result_t dlz_lookup(const char *zone, const char *name, void *dbdata,
535 dns_sdlzlookup_t *lookup,
536 dns_clientinfomethods_t *methods,
537 dns_clientinfo_t *clientinfo)
538 #endif
540 isc_result_t result = ISC_R_NOTFOUND;
541 bdbhpt_instance_t *db = (bdbhpt_instance_t *) dbdata;
542 DBC *data_cursor = NULL;
543 DBT key, data;
544 int bdbhptres;
545 int flags;
547 bdbhpt_parsed_data_t pd;
548 char *tmp = NULL;
549 char *keyStr = NULL;
551 #if DLZ_DLOPEN_VERSION >= 2
552 UNUSED(methods);
553 UNUSED(clientinfo);
554 #endif
556 memset(&key, 0, sizeof(DBT));
557 memset(&data, 0, sizeof(DBT));
559 key.size = strlen(zone) + strlen(name) + 1;
561 /* allocate mem for key */
562 key.data = keyStr = malloc((key.size + 1) * sizeof(char));
564 if (keyStr == NULL)
565 return ISC_R_NOMEMORY;
567 strcpy(keyStr, zone);
568 strcat(keyStr, " ");
569 strcat(keyStr, name);
571 /* get a cursor to loop through data */
572 if (db->data->cursor(db->data, NULL, &data_cursor, 0) != 0) {
573 result = ISC_R_FAILURE;
574 goto lookup_cleanup;
577 result = ISC_R_NOTFOUND;
579 flags = DB_SET;
580 while ((bdbhptres = data_cursor->c_get(data_cursor, &key, &data,
581 flags)) == 0)
583 flags = DB_NEXT_DUP;
584 tmp = realloc(tmp, data.size + 1);
585 if (tmp == NULL)
586 goto lookup_cleanup;
588 strncpy(tmp, data.data, data.size);
589 tmp[data.size] = '\0';
591 if (bdbhpt_parse_data(db->log, tmp, &pd) != ISC_R_SUCCESS)
592 goto lookup_cleanup;
594 result = db->putrr(lookup, pd.type, pd.ttl, pd.data);
595 if (result != ISC_R_SUCCESS)
596 goto lookup_cleanup;
597 } /* end while loop */
599 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;
613 * Initialises, sets flags and then opens Berkeley databases.
615 static isc_result_t
616 bdbhpt_opendb(log_t *log, DB_ENV *db_env, DBTYPE db_type, DB **db,
617 const char *db_name, char *db_file, int flags)
619 int result;
621 /* Initialise the database. */
622 if ((result = db_create(db, db_env, 0)) != 0) {
623 log(ISC_LOG_ERROR,
624 "bdbhpt_dynamic: could not initialize %s database. "
625 "BerkeleyDB 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 log(ISC_LOG_ERROR,
633 "bdbhpt_dynamic: could not set flags for %s database. "
634 "BerkeleyDB error: %s",
635 db_name, db_strerror(result));
636 return ISC_R_FAILURE;
639 /* open the database. */
640 if ((result = (*db)->open(*db, NULL, db_file, db_name, db_type,
641 DB_RDONLY | bdbhpt_threads, 0)) != 0) {
642 log(ISC_LOG_ERROR,
643 "bdbhpt_dynamic: could not open %s database in %s. "
644 "BerkeleyDB error: %s",
645 db_name, db_file, db_strerror(result));
646 return ISC_R_FAILURE;
649 return ISC_R_SUCCESS;
654 * Called to initialize the driver
656 isc_result_t
657 dlz_create(const char *dlzname, unsigned int argc, char *argv[],
658 void **dbdata, ...)
660 isc_result_t result;
661 int bdbhptres;
662 int bdbFlags = 0;
663 bdbhpt_instance_t *db = NULL;
665 const char *helper_name;
666 va_list ap;
668 UNUSED(dlzname);
670 /* Allocate memory for our db structures and helper functions */
671 db = calloc(1, sizeof(struct bdbhpt_instance));
672 if (db == NULL)
673 return (ISC_R_NOMEMORY);
675 /* Fill in the helper functions */
676 va_start(ap, dbdata);
677 while ((helper_name = va_arg(ap, const char *)) != NULL)
678 b9_add_helper(db, helper_name, va_arg(ap, void*));
679 va_end(ap);
681 /* verify we have 4 arg's passed to the driver */
682 if (argc != 4) {
683 db->log(ISC_LOG_ERROR,
684 "bdbhpt_dynamic: please supply 3 command line args. "
685 "You supplied: %s", argc);
686 return (ISC_R_FAILURE);
689 switch((char) *argv[1]) {
691 * Transactional mode. Highest safety - lowest speed.
693 case 'T':
694 case 't':
695 bdbFlags = DB_INIT_MPOOL | DB_INIT_LOCK |
696 DB_INIT_LOG | DB_INIT_TXN;
697 db->log(ISC_LOG_INFO,
698 "bdbhpt_dynamic: using transactional mode.");
699 break;
702 * Concurrent mode. Lower safety (no rollback) -
703 * higher speed.
705 case 'C':
706 case 'c':
707 bdbFlags = DB_INIT_CDB | DB_INIT_MPOOL;
708 db->log(ISC_LOG_INFO,
709 "bdbhpt_dynamic: using concurrent mode.");
710 break;
713 * Private mode. No inter-process communication & no locking.
714 * Lowest saftey - highest speed.
716 case 'P':
717 case 'p':
718 bdbFlags = DB_PRIVATE | DB_INIT_MPOOL;
719 db->log(ISC_LOG_INFO,
720 "bdbhpt_dynamic: using private mode.");
721 break;
722 default:
723 db->log(ISC_LOG_ERROR,
724 "bdbhpt_dynamic: "
725 "operating mode must be set to P or C or T. "
726 "You specified '%s'", argv[1]);
727 return (ISC_R_FAILURE);
731 * create bdbhpt environment
732 * Basically bdbhpt allocates and assigns memory to db->dbenv
734 bdbhptres = db_env_create(&db->dbenv, 0);
735 if (bdbhptres != 0) {
736 db->log(ISC_LOG_ERROR,
737 "bdbhpt_dynamic: db environment could not be created. "
738 "BerkeleyDB error: %s", db_strerror(bdbhptres));
739 result = ISC_R_FAILURE;
740 goto init_cleanup;
743 /* open bdbhpt environment */
744 bdbhptres = db->dbenv->open(db->dbenv, argv[2],
745 bdbFlags | bdbhpt_threads | DB_CREATE, 0);
746 if (bdbhptres != 0) {
747 db->log(ISC_LOG_ERROR,
748 "bdbhpt_dynamic: "
749 "db environment at '%s' could not be opened. "
750 "BerkeleyDB error: %s",
751 argv[2], db_strerror(bdbhptres));
752 result = ISC_R_FAILURE;
753 goto init_cleanup;
756 /* open dlz_data database. */
757 result = bdbhpt_opendb(db->log, db->dbenv, DB_UNKNOWN, &db->data,
758 dlz_data, argv[3], DB_DUP | DB_DUPSORT);
759 if (result != ISC_R_SUCCESS)
760 goto init_cleanup;
762 /* open dlz_xfr database. */
763 result = bdbhpt_opendb(db->log, db->dbenv, DB_UNKNOWN, &db->xfr,
764 dlz_xfr, argv[3], DB_DUP | DB_DUPSORT);
765 if (result != ISC_R_SUCCESS)
766 goto init_cleanup;
768 /* open dlz_zone database. */
769 result = bdbhpt_opendb(db->log, db->dbenv, DB_UNKNOWN, &db->zone,
770 dlz_zone, argv[3], 0);
771 if (result != ISC_R_SUCCESS)
772 goto init_cleanup;
774 /* open dlz_client database. */
775 result = bdbhpt_opendb(db->log, db->dbenv, DB_UNKNOWN, &db->client,
776 dlz_client, argv[3], DB_DUP | DB_DUPSORT);
777 if (result != ISC_R_SUCCESS)
778 goto init_cleanup;
780 *dbdata = db;
782 db->log(ISC_LOG_INFO,
783 "bdbhpt_dynamic: version %s, started",
784 dlz_bdbhpt_dynamic_version);
785 return(ISC_R_SUCCESS);
787 init_cleanup:
788 bdbhpt_cleanup(db);
789 return result;
793 * Shut down the backend
795 void
796 dlz_destroy(void *dbdata) {
797 struct bdbhpt_instance *db = (struct bdbhpt_instance *)dbdata;
799 db->log(ISC_LOG_INFO,
800 "dlz_bdbhpt_dynamic (%s): shutting down",
801 dlz_bdbhpt_dynamic_version);
802 bdbhpt_cleanup((bdbhpt_instance_t *) dbdata);
803 free(db);
807 * Return the version of the API
810 dlz_version(unsigned int *flags) {
811 UNUSED(flags);
812 return (DLZ_DLOPEN_VERSION);
816 * Register a helper function from the bind9 dlz_dlopen driver
818 static void
819 b9_add_helper(struct bdbhpt_instance *db, const char *helper_name, void *ptr) {
820 if (strcmp(helper_name, "log") == 0)
821 db->log = (log_t *)ptr;
822 if (strcmp(helper_name, "putrr") == 0)
823 db->putrr = (dns_sdlz_putrr_t *)ptr;
824 if (strcmp(helper_name, "putnamedrr") == 0)
825 db->putnamedrr = (dns_sdlz_putnamedrr_t *)ptr;
826 if (strcmp(helper_name, "writeable_zone") == 0)
827 db->writeable_zone = (dns_dlz_writeablezone_t *)ptr;