62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt/*
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt * Copyright (C) 2002 Stichting NLnet, Netherlands, stichting@nlnet.nl.
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt *
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt * Permission to use, copy, modify, and distribute this software for any
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt * purpose with or without fee is hereby granted, provided that the
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt * above copyright notice and this permission notice appear in all
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt * copies.
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt *
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt * THE SOFTWARE IS PROVIDED "AS IS" AND STICHTING NLNET
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt * STICHTING NLNET BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt * USE OR PERFORMANCE OF THIS SOFTWARE.
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt *
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt * The development of Dynamically Loadable Zones (DLZ) for Bind 9 was
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt * conceived and contributed by Rob Butler.
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt *
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt * Permission to use, copy, modify, and distribute this software for any
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt * purpose with or without fee is hereby granted, provided that the
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt * above copyright notice and this permission notice appear in all
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt * copies.
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt *
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt * THE SOFTWARE IS PROVIDED "AS IS" AND ROB BUTLER
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt * ROB BUTLER BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt * USE OR PERFORMANCE OF THIS SOFTWARE.
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt */
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt/*
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt * Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt *
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt * Permission to use, copy, modify, and/or distribute this software for any
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt * purpose with or without fee is hereby granted, provided that the above
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt * copyright notice and this permission notice appear in all copies.
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt *
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt * PERFORMANCE OF THIS SOFTWARE.
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt */
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt/*
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt * This is simply a merge of Andrew Tridgell's dlz_example.c and the
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt * original bdb_bdbhpt_driver.c
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt *
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt * This provides the externally loadable bdbhpt DLZ driver, without
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt * update support
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt *
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt */
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt#include <stdio.h>
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt#include <stdlib.h>
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt#include <string.h>
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt#include <stdarg.h>
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt#include <stdint.h>
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt#include <db.h>
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt#include "dlz_minimal.h"
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt/* should the bdb driver use threads. */
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt#ifdef ISC_PLATFORM_USETHREADS
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt#define bdbhpt_threads DB_THREAD
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt#else
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt#define bdbhpt_threads 0
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt#endif
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt/* bdbhpt database names */
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt#define dlz_data "dns_data"
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt#define dlz_zone "dns_zone"
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt#define dlz_xfr "dns_xfr"
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt#define dlz_client "dns_client"
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt#define dlz_bdbhpt_dynamic_version "0.1"
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt/*
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt * This structure contains all our DB handles and helper functions we
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt * inherit from the dlz_dlopen driver
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt *
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt */
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunttypedef struct bdbhpt_instance {
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt DB_ENV *dbenv; /* bdbhpt environment */
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt DB *data; /* dns_data database handle */
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt DB *zone; /* zone database handle */
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt DB *xfr; /* zone xfr database handle */
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt DB *client; /* client database handle */
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt /* Helper functions from the dlz_dlopen driver */
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt log_t *log;
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt dns_sdlz_putrr_t *putrr;
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt dns_sdlz_putnamedrr_t *putnamedrr;
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt dns_dlz_writeablezone_t *writeable_zone;
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt} bdbhpt_instance_t;
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunttypedef struct bdbhpt_parsed_data {
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt char *host;
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt char *type;
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt int ttl;
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt char *data;
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt} bdbhpt_parsed_data_t;
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt
72c86c105a7cf315036d7131a4ef408bc6227639Evan Huntstatic void
72c86c105a7cf315036d7131a4ef408bc6227639Evan Huntb9_add_helper(struct bdbhpt_instance *db, const char *helper_name, void *ptr);
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt/*%
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt * Reverses a string in place.
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt */
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Huntstatic char
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt*bdbhpt_strrev(char *str) {
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt char *p1, *p2;
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt if (! str || ! *str)
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt return str;
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt for (p1 = str, p2 = str + strlen(str) - 1; p2 > p1; ++p1, --p2) {
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt *p1 ^= *p2;
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt *p2 ^= *p1;
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt *p1 ^= *p2;
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt }
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt return str;
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt}
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt/*%
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt * Parses the DBT from the Berkeley DB into a parsed_data record
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt * The parsed_data record should be allocated before and passed into the
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt * bdbhpt_parse_data function. The char (type & data) fields should not
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt * be "free"d as that memory is part of the DBT data field. It will be
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt * "free"d when the DBT is freed.
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt */
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Huntstatic isc_result_t
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Huntbdbhpt_parse_data(log_t *log, char *in, bdbhpt_parsed_data_t *pd) {
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt char *endp, *ttlStr;
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt char *tmp = in;
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt char *lastchar = (char *) &tmp[strlen(tmp)];
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt /*%
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt * String should be formatted as:
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt * replication_id
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt * (a space)
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt * host_name
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt * (a space)
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt * ttl
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt * (a space)
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt * type
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt * (a space)
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt * remaining data
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt *
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt * examples:
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt *
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt * 9191 host 10 A 127.0.0.1
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt * server1_212 host 10 A 127.0.0.2
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt * {xxxx-xxxx-xxxx-xxxx-xxxx} host 10 MX 20 mail.example.com
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt */
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt /*
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt * we don't need the replication id, so don't
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt * bother saving a pointer to it.
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt */
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt /* find space after replication id */
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt tmp = strchr(tmp, ' ');
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt /* verify we found a space */
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt if (tmp == NULL)
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt return ISC_R_FAILURE;
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt /* make sure it is safe to increment pointer */
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt if (++tmp > lastchar)
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt return ISC_R_FAILURE;
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt /* save pointer to host */
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt pd->host = tmp;
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt /* find space after host and change it to a '\0' */
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt tmp = strchr(tmp, ' ');
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt /* verify we found a space */
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt if (tmp == NULL)
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt return ISC_R_FAILURE;
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt /* change the space to a null (string terminator) */
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt tmp[0] = '\0';
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt /* make sure it is safe to increment pointer */
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt if (++tmp > lastchar)
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt return ISC_R_FAILURE;
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt /* save pointer to ttl string */
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt ttlStr = tmp;
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt /* find space after ttl and change it to a '\0' */
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt tmp = strchr(tmp, ' ');
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt /* verify we found a space */
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt if (tmp == NULL)
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt return ISC_R_FAILURE;
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt /* change the space to a null (string terminator) */
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt tmp[0] = '\0';
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt /* make sure it is safe to increment pointer */
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt if (++tmp > lastchar)
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt return ISC_R_FAILURE;
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt /* save pointer to dns type */
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt pd->type = tmp;
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt /* find space after type and change it to a '\0' */
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt tmp = strchr(tmp, ' ');
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt /* verify we found a space */
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt if (tmp == NULL)
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt return ISC_R_FAILURE;
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt /* change the space to a null (string terminator) */
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt tmp[0] = '\0';
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt /* make sure it is safe to increment pointer */
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt if (++tmp > lastchar)
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt return ISC_R_FAILURE;
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt /* save pointer to remainder of DNS data */
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt pd->data = tmp;
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt /* convert ttl string to integer */
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt pd->ttl = strtol(ttlStr, &endp, 10);
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt if (*endp != '\0' || pd->ttl < 0) {
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt log(ISC_LOG_ERROR,
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt "bdbhpt_dynamic: "
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt "ttl must be a positive number");
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt return ISC_R_FAILURE;
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt }
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt /* if we get this far everything should have worked. */
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt return ISC_R_SUCCESS;
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt}
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt/*
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt * See if a zone transfer is allowed
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt */
72c86c105a7cf315036d7131a4ef408bc6227639Evan Huntisc_result_t
72c86c105a7cf315036d7131a4ef408bc6227639Evan Huntdlz_allowzonexfr(void *dbdata, const char *name, const char *client) {
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt isc_result_t result;
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt bdbhpt_instance_t *db = (bdbhpt_instance_t *) dbdata;
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt DBT key, data;
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt /* check to see if we are authoritative for the zone first. */
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt#if DLZ_DLOPEN_VERSION >= 3
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt result = dlz_findzonedb(dbdata, name, NULL, NULL);
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt#else
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt result = dlz_findzonedb(dbdata, name);
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt#endif
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt if (result != ISC_R_SUCCESS)
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt return (ISC_R_NOTFOUND);
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt memset(&key, 0, sizeof(DBT));
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt key.flags = DB_DBT_MALLOC;
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt key.data = strdup(name);
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt if (key.data == NULL) {
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt result = ISC_R_NOMEMORY;
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt goto xfr_cleanup;
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt }
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt key.size = strlen(key.data);
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt memset(&data, 0, sizeof(DBT));
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt data.flags = DB_DBT_MALLOC;
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt data.data = strdup(client);
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt if (data.data == NULL) {
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt result = ISC_R_NOMEMORY;
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt goto xfr_cleanup;
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt }
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt data.size = strlen(data.data);
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt switch(db->client->get(db->client, NULL, &key, &data, DB_GET_BOTH)) {
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt case DB_NOTFOUND:
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt result = ISC_R_NOTFOUND;
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt break;
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt case 0:
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt result = ISC_R_SUCCESS;
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt break;
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt default:
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt result = ISC_R_FAILURE;
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt }
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt xfr_cleanup:
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt /* free any memory duplicate string in the key field */
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt if (key.data != NULL)
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt free(key.data);
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt /* free any memory allocated to the data field. */
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt if (data.data != NULL)
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt free(data.data);
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt return result;
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt}
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt/*%
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt * Perform a zone transfer
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt *
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt * BDB does not allow a secondary index on a database that allows
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt * duplicates. We have a few options:
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt *
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt * 1) kill speed by having lookup method use a secondary db which
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt * is associated to the primary DB with the DNS data. Then have
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt * another secondary db for zone transfer which also points to
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt * the dns_data primary. NO - The point of this driver is
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt * lookup performance.
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt *
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt * 2) Blow up database size by storing DNS data twice. Once for
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt * the lookup (dns_data) database, and a second time for the zone
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt * transfer (dns_xfr) database. NO - That would probably require
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt * a larger cache to provide good performance. Also, that would
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt * make the DB larger on disk potentially slowing it as well.
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt *
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt * 3) Loop through the dns_xfr database with a cursor to get
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt * all the different hosts in a zone. Then use the zone & host
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt * together to lookup the data in the dns_data database. YES -
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt * This may slow down zone xfr's a little, but that's ok they
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt * don't happen as often and don't need to be as fast. We can
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt * also use this table when deleting a zone (The BDB driver
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt * is read only - the delete would be used during replication
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt * updates by a separate process).
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt */
72c86c105a7cf315036d7131a4ef408bc6227639Evan Huntisc_result_t
72c86c105a7cf315036d7131a4ef408bc6227639Evan Huntdlz_allnodes(const char *zone, void *dbdata, dns_sdlzallnodes_t *allnodes) {
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt isc_result_t result = ISC_R_NOTFOUND;
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt bdbhpt_instance_t *db = (bdbhpt_instance_t *) dbdata;
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt DBC *xfr_cursor = NULL;
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt DBC *dns_cursor = NULL;
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt DBT xfr_key, xfr_data, dns_key, dns_data;
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt int xfr_flags;
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt int dns_flags;
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt int bdbhptres;
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt bdbhpt_parsed_data_t pd;
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt char *tmp = NULL, *tmp_zone, *tmp_zone_host = NULL;
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt memset(&xfr_key, 0, sizeof(DBT));
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt memset(&xfr_data, 0, sizeof(DBT));
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt memset(&dns_key, 0, sizeof(DBT));
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt memset(&dns_data, 0, sizeof(DBT));
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt xfr_key.data = tmp_zone = strdup(zone);
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt if (xfr_key.data == NULL)
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt return (ISC_R_NOMEMORY);
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt xfr_key.size = strlen(xfr_key.data);
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt /* get a cursor to loop through dns_xfr table */
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt if (db->xfr->cursor(db->xfr, NULL, &xfr_cursor, 0) != 0) {
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt result = ISC_R_FAILURE;
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt goto allnodes_cleanup;
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt }
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt /* get a cursor to loop through dns_data table */
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt if (db->data->cursor(db->data, NULL, &dns_cursor, 0) != 0) {
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt result = ISC_R_FAILURE;
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt goto allnodes_cleanup;
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt }
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt xfr_flags = DB_SET;
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt /* loop through xfr table for specified zone. */
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt while ((bdbhptres = xfr_cursor->c_get(xfr_cursor, &xfr_key,
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt &xfr_data, xfr_flags)) == 0)
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt {
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt xfr_flags = DB_NEXT_DUP;
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt /* +1 to allow for space between zone and host names */
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt dns_key.size = xfr_data.size + xfr_key.size + 1;
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt /* +1 to allow for null term at end of string. */
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt dns_key.data = tmp_zone_host = malloc(dns_key.size + 1);
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt if (dns_key.data == NULL)
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt goto allnodes_cleanup;
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt /*
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt * construct search key for dns_data.
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt * zone_name(a space)host_name
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt */
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt strcpy(dns_key.data, zone);
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt strcat(dns_key.data, " ");
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt strncat(dns_key.data, xfr_data.data, xfr_data.size);
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt dns_flags = DB_SET;
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt while ((bdbhptres = dns_cursor->c_get(dns_cursor,
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt &dns_key,
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt &dns_data,
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt dns_flags)) == 0)
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt {
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt dns_flags = DB_NEXT_DUP;
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt /* +1 to allow for null term at end of string. */
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt tmp = realloc(tmp, dns_data.size + 1);
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt if (tmp == NULL)
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt goto allnodes_cleanup;
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt /* copy data to tmp string, and append null term. */
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt strncpy(tmp, dns_data.data, dns_data.size);
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt tmp[dns_data.size] = '\0';
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt /* split string into dns data parts. */
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt if (bdbhpt_parse_data(db->log,
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt tmp, &pd) != ISC_R_SUCCESS)
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt goto allnodes_cleanup;
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt result = db->putnamedrr(allnodes, pd.host,
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt pd.type, pd.ttl, pd.data);
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt if (result != ISC_R_SUCCESS)
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt goto allnodes_cleanup;
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt } /* end inner while loop */
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt /* clean up memory */
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt if (tmp_zone_host != NULL) {
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt free(tmp_zone_host);
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt tmp_zone_host = NULL;
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt }
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt } /* end outer while loop */
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt allnodes_cleanup:
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt /* free any memory */
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt if (tmp != NULL)
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt free(tmp);
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt if (tmp_zone_host != NULL)
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt free(tmp_zone_host);
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt if (tmp_zone != NULL)
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt free(tmp_zone);
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt /* get rid of cursors */
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt if (xfr_cursor != NULL)
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt xfr_cursor->c_close(xfr_cursor);
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt if (dns_cursor != NULL)
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt dns_cursor->c_close(dns_cursor);
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt return result;
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt}
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt/*%
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt * Performs bdbhpt cleanup.
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt * Used by bdbhpt_create if there is an error starting up.
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt * Used by bdbhpt_destroy when the driver is shutting down.
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt */
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Huntstatic void
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Huntbdbhpt_cleanup(bdbhpt_instance_t *db) {
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt /* close databases */
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt if (db->data != NULL)
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt db->data->close(db->data, 0);
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt if (db->xfr != NULL)
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt db->xfr->close(db->xfr, 0);
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt if (db->zone != NULL)
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt db->zone->close(db->zone, 0);
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt if (db->client != NULL)
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt db->client->close(db->client, 0);
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt /* close environment */
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt if (db->dbenv != NULL)
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt db->dbenv->close(db->dbenv, 0);
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt}
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt/*
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt * See if we handle a given zone
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt */
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt#if DLZ_DLOPEN_VERSION < 3
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Huntisc_result_t
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Huntdlz_findzonedb(void *dbdata, const char *name)
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt#else
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Huntisc_result_t
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Huntdlz_findzonedb(void *dbdata, const char *name,
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt dns_clientinfomethods_t *methods,
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt dns_clientinfo_t *clientinfo)
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt#endif
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt{
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt isc_result_t result;
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt bdbhpt_instance_t *db = (bdbhpt_instance_t *) dbdata;
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt DBT key, data;
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt memset(&key, 0, sizeof(DBT));
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt memset(&data, 0, sizeof(DBT));
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt data.flags = DB_DBT_MALLOC;
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt#if DLZ_DLOPEN_VERSION >= 3
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt UNUSED(methods);
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt UNUSED(clientinfo);
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt#endif
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt key.data = strdup(name);
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt if (key.data == NULL)
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt return (ISC_R_NOMEMORY);
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt /*
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt * reverse string to take advantage of BDB locality of reference
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt * if we need futher lookups because the zone doesn't match the
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt * first time.
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt */
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt key.data = bdbhpt_strrev(key.data);
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt key.size = strlen(key.data);
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt switch(db->zone->get(db->zone, NULL, &key, &data, 0)) {
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt case DB_NOTFOUND:
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt result = ISC_R_NOTFOUND;
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt break;
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt case 0:
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt result = ISC_R_SUCCESS;
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt break;
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt default:
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt result = ISC_R_FAILURE;
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt }
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt /* free any memory duplicate string in the key field */
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt if (key.data != NULL)
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt free(key.data);
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt /* free any memory allocated to the data field. */
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt if (data.data != NULL)
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt free(data.data);
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt return result;
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt}
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt/*
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt * Look up one record in the database.
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt *
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt */
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt#if DLZ_DLOPEN_VERSION == 1
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Huntisc_result_t dlz_lookup(const char *zone, const char *name,
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt void *dbdata, dns_sdlzlookup_t *lookup)
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt#else
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Huntisc_result_t dlz_lookup(const char *zone, const char *name, void *dbdata,
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt dns_sdlzlookup_t *lookup,
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt dns_clientinfomethods_t *methods,
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt dns_clientinfo_t *clientinfo)
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt#endif
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt{
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt isc_result_t result = ISC_R_NOTFOUND;
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt bdbhpt_instance_t *db = (bdbhpt_instance_t *) dbdata;
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt DBC *data_cursor = NULL;
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt DBT key, data;
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt int bdbhptres;
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt int flags;
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt bdbhpt_parsed_data_t pd;
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt char *tmp = NULL;
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt char *keyStr = NULL;
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt#if DLZ_DLOPEN_VERSION >= 2
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt UNUSED(methods);
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt UNUSED(clientinfo);
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt#endif
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt memset(&key, 0, sizeof(DBT));
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt memset(&data, 0, sizeof(DBT));
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt key.size = strlen(zone) + strlen(name) + 1;
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt /* allocate mem for key */
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt key.data = keyStr = malloc((key.size + 1) * sizeof(char));
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt if (keyStr == NULL)
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt return ISC_R_NOMEMORY;
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt strcpy(keyStr, zone);
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt strcat(keyStr, " ");
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt strcat(keyStr, name);
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt /* get a cursor to loop through data */
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt if (db->data->cursor(db->data, NULL, &data_cursor, 0) != 0) {
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt result = ISC_R_FAILURE;
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt goto lookup_cleanup;
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt }
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt result = ISC_R_NOTFOUND;
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt flags = DB_SET;
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt while ((bdbhptres = data_cursor->c_get(data_cursor, &key, &data,
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt flags)) == 0)
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt {
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt flags = DB_NEXT_DUP;
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt tmp = realloc(tmp, data.size + 1);
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt if (tmp == NULL)
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt goto lookup_cleanup;
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt strncpy(tmp, data.data, data.size);
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt tmp[data.size] = '\0';
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt if (bdbhpt_parse_data(db->log, tmp, &pd) != ISC_R_SUCCESS)
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt goto lookup_cleanup;
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt result = db->putrr(lookup, pd.type, pd.ttl, pd.data);
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt if (result != ISC_R_SUCCESS)
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt goto lookup_cleanup;
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt } /* end while loop */
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt lookup_cleanup:
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt /* get rid of cursor */
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt if (data_cursor != NULL)
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt data_cursor->c_close(data_cursor);
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt if (keyStr != NULL)
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt free(keyStr);
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt if (tmp != NULL)
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt free(tmp);
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt return result;
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt}
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt/*%
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt * Initialises, sets flags and then opens Berkeley databases.
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt */
72c86c105a7cf315036d7131a4ef408bc6227639Evan Huntstatic isc_result_t
72c86c105a7cf315036d7131a4ef408bc6227639Evan Huntbdbhpt_opendb(log_t *log, DB_ENV *db_env, DBTYPE db_type, DB **db,
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt const char *db_name, char *db_file, int flags)
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt{
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt int result;
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt /* Initialise the database. */
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt if ((result = db_create(db, db_env, 0)) != 0) {
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt log(ISC_LOG_ERROR,
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt "bdbhpt_dynamic: could not initialize %s database. "
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt "BerkeleyDB error: %s",
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt db_name, db_strerror(result));
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt return ISC_R_FAILURE;
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt }
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt /* set database flags. */
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt if ((result = (*db)->set_flags(*db, flags)) != 0) {
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt log(ISC_LOG_ERROR,
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt "bdbhpt_dynamic: could not set flags for %s database. "
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt "BerkeleyDB error: %s",
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt db_name, db_strerror(result));
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt return ISC_R_FAILURE;
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt }
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt /* open the database. */
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt if ((result = (*db)->open(*db, NULL, db_file, db_name, db_type,
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt DB_RDONLY | bdbhpt_threads, 0)) != 0) {
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt log(ISC_LOG_ERROR,
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt "bdbhpt_dynamic: could not open %s database in %s. "
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt "BerkeleyDB error: %s",
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt db_name, db_file, db_strerror(result));
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt return ISC_R_FAILURE;
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt }
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt return ISC_R_SUCCESS;
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt}
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt/*
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt * Called to initialize the driver
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt */
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Huntisc_result_t
72c86c105a7cf315036d7131a4ef408bc6227639Evan Huntdlz_create(const char *dlzname, unsigned int argc, char *argv[],
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt void **dbdata, ...)
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt{
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt isc_result_t result;
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt int bdbhptres;
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt int bdbFlags = 0;
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt bdbhpt_instance_t *db = NULL;
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt const char *helper_name;
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt va_list ap;
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt UNUSED(dlzname);
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt /* Allocate memory for our db structures and helper functions */
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt db = calloc(1, sizeof(struct bdbhpt_instance));
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt if (db == NULL)
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt return (ISC_R_NOMEMORY);
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt /* Fill in the helper functions */
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt va_start(ap, dbdata);
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt while ((helper_name = va_arg(ap, const char *)) != NULL)
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt b9_add_helper(db, helper_name, va_arg(ap, void*));
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt va_end(ap);
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt /* verify we have 4 arg's passed to the driver */
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt if (argc != 4) {
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt db->log(ISC_LOG_ERROR,
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt "bdbhpt_dynamic: please supply 3 command line args. "
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt "You supplied: %s", argc);
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt return (ISC_R_FAILURE);
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt }
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt switch((char) *argv[1]) {
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt /*
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt * Transactional mode. Highest safety - lowest speed.
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt */
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt case 'T':
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt case 't':
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt bdbFlags = DB_INIT_MPOOL | DB_INIT_LOCK |
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt DB_INIT_LOG | DB_INIT_TXN;
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt db->log(ISC_LOG_INFO,
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt "bdbhpt_dynamic: using transactional mode.");
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt break;
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt /*
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt * Concurrent mode. Lower safety (no rollback) -
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt * higher speed.
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt */
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt case 'C':
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt case 'c':
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt bdbFlags = DB_INIT_CDB | DB_INIT_MPOOL;
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt db->log(ISC_LOG_INFO,
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt "bdbhpt_dynamic: using concurrent mode.");
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt break;
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt /*
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt * Private mode. No inter-process communication & no locking.
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt * Lowest saftey - highest speed.
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt */
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt case 'P':
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt case 'p':
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt bdbFlags = DB_PRIVATE | DB_INIT_MPOOL;
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt db->log(ISC_LOG_INFO,
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt "bdbhpt_dynamic: using private mode.");
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt break;
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt default:
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt db->log(ISC_LOG_ERROR,
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt "bdbhpt_dynamic: "
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt "operating mode must be set to P or C or T. "
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt "You specified '%s'", argv[1]);
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt return (ISC_R_FAILURE);
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt }
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt /*
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt * create bdbhpt environment
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt * Basically bdbhpt allocates and assigns memory to db->dbenv
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt */
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt bdbhptres = db_env_create(&db->dbenv, 0);
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt if (bdbhptres != 0) {
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt db->log(ISC_LOG_ERROR,
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt "bdbhpt_dynamic: db environment could not be created. "
ff7cc592b7b733ef095e67ad78db15e28dc52367Evan Hunt "BerkeleyDB error: %s", db_strerror(bdbhptres));
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt result = ISC_R_FAILURE;
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt goto init_cleanup;
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt }
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt /* open bdbhpt environment */
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt bdbhptres = db->dbenv->open(db->dbenv, argv[2],
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt bdbFlags | bdbhpt_threads | DB_CREATE, 0);
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt if (bdbhptres != 0) {
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt db->log(ISC_LOG_ERROR,
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt "bdbhpt_dynamic: "
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt "db environment at '%s' could not be opened. "
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt "BerkeleyDB error: %s",
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt argv[2], db_strerror(bdbhptres));
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt result = ISC_R_FAILURE;
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt goto init_cleanup;
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt }
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt /* open dlz_data database. */
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt result = bdbhpt_opendb(db->log, db->dbenv, DB_UNKNOWN, &db->data,
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt dlz_data, argv[3], DB_DUP | DB_DUPSORT);
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt if (result != ISC_R_SUCCESS)
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt goto init_cleanup;
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt /* open dlz_xfr database. */
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt result = bdbhpt_opendb(db->log, db->dbenv, DB_UNKNOWN, &db->xfr,
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt dlz_xfr, argv[3], DB_DUP | DB_DUPSORT);
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt if (result != ISC_R_SUCCESS)
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt goto init_cleanup;
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt /* open dlz_zone database. */
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt result = bdbhpt_opendb(db->log, db->dbenv, DB_UNKNOWN, &db->zone,
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt dlz_zone, argv[3], 0);
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt if (result != ISC_R_SUCCESS)
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt goto init_cleanup;
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt /* open dlz_client database. */
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt result = bdbhpt_opendb(db->log, db->dbenv, DB_UNKNOWN, &db->client,
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt dlz_client, argv[3], DB_DUP | DB_DUPSORT);
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt if (result != ISC_R_SUCCESS)
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt goto init_cleanup;
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt *dbdata = db;
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt db->log(ISC_LOG_INFO,
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt "bdbhpt_dynamic: version %s, started",
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt dlz_bdbhpt_dynamic_version);
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt return(ISC_R_SUCCESS);
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt init_cleanup:
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt bdbhpt_cleanup(db);
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt return result;
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt}
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt/*
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt * Shut down the backend
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt */
72c86c105a7cf315036d7131a4ef408bc6227639Evan Huntvoid
72c86c105a7cf315036d7131a4ef408bc6227639Evan Huntdlz_destroy(void *dbdata) {
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt struct bdbhpt_instance *db = (struct bdbhpt_instance *)dbdata;
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt db->log(ISC_LOG_INFO,
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt "dlz_bdbhpt_dynamic (%s): shutting down",
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt dlz_bdbhpt_dynamic_version);
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt bdbhpt_cleanup((bdbhpt_instance_t *) dbdata);
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt free(db);
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt}
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt/*
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt * Return the version of the API
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt */
72c86c105a7cf315036d7131a4ef408bc6227639Evan Huntint
72c86c105a7cf315036d7131a4ef408bc6227639Evan Huntdlz_version(unsigned int *flags) {
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt UNUSED(flags);
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt return (DLZ_DLOPEN_VERSION);
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt}
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt/*
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt * Register a helper function from the bind9 dlz_dlopen driver
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt */
72c86c105a7cf315036d7131a4ef408bc6227639Evan Huntstatic void
72c86c105a7cf315036d7131a4ef408bc6227639Evan Huntb9_add_helper(struct bdbhpt_instance *db, const char *helper_name, void *ptr) {
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt if (strcmp(helper_name, "log") == 0)
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt db->log = (log_t *)ptr;
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt if (strcmp(helper_name, "putrr") == 0)
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt db->putrr = (dns_sdlz_putrr_t *)ptr;
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt if (strcmp(helper_name, "putnamedrr") == 0)
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt db->putnamedrr = (dns_sdlz_putnamedrr_t *)ptr;
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt if (strcmp(helper_name, "writeable_zone") == 0)
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt db->writeable_zone = (dns_dlz_writeablezone_t *)ptr;
62d63e5f02a5e7fcda59cf361149e3d7c78477beEvan Hunt}
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt