03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews/*
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * Copyright (C) 2002 Stichting NLnet, Netherlands, stichting@nlnet.nl.
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews *
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * Permission to use, copy, modify, and distribute this software for any
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * purpose with or without fee is hereby granted, provided that the
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * above copyright notice and this permission notice appear in all
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * copies.
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews *
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * THE SOFTWARE IS PROVIDED "AS IS" AND STICHTING NLNET
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * STICHTING NLNET BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * USE OR PERFORMANCE OF THIS SOFTWARE.
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews *
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * The development of Dynamically Loadable Zones (DLZ) for Bind 9 was
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * conceived and contributed by Rob Butler.
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews *
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * Permission to use, copy, modify, and distribute this software for any
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * purpose with or without fee is hereby granted, provided that the
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * above copyright notice and this permission notice appear in all
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * copies.
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews *
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * THE SOFTWARE IS PROVIDED "AS IS" AND ROB BUTLER
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * ROB BUTLER BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * USE OR PERFORMANCE OF THIS SOFTWARE.
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews/*
02d54949f0f1db4729e14c3322b207f58d2578a4Mark Andrews * Copyright (C) 1999-2001, 2016 Internet Systems Consortium, Inc. ("ISC")
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews *
02d54949f0f1db4729e14c3322b207f58d2578a4Mark Andrews * This Source Code Form is subject to the terms of the Mozilla Public
02d54949f0f1db4729e14c3322b207f58d2578a4Mark Andrews * License, v. 2.0. If a copy of the MPL was not distributed with this
02d54949f0f1db4729e14c3322b207f58d2578a4Mark Andrews * file, You can obtain one at http://mozilla.org/MPL/2.0/.
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews#ifdef DLZ_BDB
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews#include <config.h>
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews#include <stdio.h>
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews#include <string.h>
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews#include <stdlib.h>
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews#include <dns/log.h>
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews#include <dns/sdlz.h>
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews#include <dns/result.h>
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews#include <isc/mem.h>
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews#include <isc/print.h>
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews#include <isc/result.h>
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews#include <isc/util.h>
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews#include <named/globals.h>
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews#include <dlz/dlz_bdbhpt_driver.h>
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews#include <db.h>
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrewsstatic dns_sdlzimplementation_t *dlz_bdbhpt = NULL;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews/* should the bdb driver use threads. */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews#ifdef ISC_PLATFORM_USETHREADS
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews#define bdbhpt_threads DB_THREAD
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews#else
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews#define bdbhpt_threads 0
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews#endif
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews/* bdbhpt database names */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews#define dlz_data "dns_data"
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews#define dlz_zone "dns_zone"
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews#define dlz_xfr "dns_xfr"
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews#define dlz_client "dns_client"
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /* This structure contains all the Berkeley DB handles
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * for this instance of the bdbhpt driver.
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrewstypedef struct bdbhpt_instance {
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews DB_ENV *dbenv; /*%< bdbhpt environment */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews DB *data; /*%< dns_data database handle */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews DB *zone; /*%< zone database handle */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews DB *xfr; /*%< zone xfr database handle */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews DB *client; /*%< client database handle */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews isc_mem_t *mctx; /*%< memory context */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews} bdbhpt_instance_t;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrewstypedef struct bdbhpt_parsed_data {
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews char *host;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews char *type;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews int ttl;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews char *data;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews} bdbhpt_parsed_data_t;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews/* forward reference */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrewsstatic isc_result_t
abff0f462a758383d012887d3a97da4dac0c5a94Evan Huntbdbhpt_findzone(void *driverarg, void *dbdata, const char *name,
abff0f462a758383d012887d3a97da4dac0c5a94Evan Hunt dns_clientinfomethods_t *methods, dns_clientinfo_t *clientinfo);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews/*%
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * Reverses a string in place.
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrewsstatic char *bdbhpt_strrev(char *str)
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews{
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews char *p1, *p2;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if (! str || ! *str)
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews return str;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews for (p1 = str, p2 = str + strlen(str) - 1; p2 > p1; ++p1, --p2)
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews {
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews *p1 ^= *p2;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews *p2 ^= *p1;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews *p1 ^= *p2;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews }
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews return str;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews}
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews/*%
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * Parses the DBT from the Berkeley DB into a parsed_data record
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * The parsed_data record should be allocated before and passed into the
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * bdbhpt_parse_data function. The char (type & data) fields should not
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * be "free"d as that memory is part of the DBT data field. It will be
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * "free"d when the DBT is freed.
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrewsstatic isc_result_t
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrewsbdbhpt_parse_data(char *in, bdbhpt_parsed_data_t *pd) {
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews char *endp, *ttlStr;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews char *tmp = in;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews char *lastchar = (char *) &tmp[strlen(tmp)];
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /*%
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * String should be formated as:
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * replication_id
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * (a space)
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * host_name
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * (a space)
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * ttl
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * (a space)
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * type
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * (a space)
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * remaining data
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews *
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * examples:
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews *
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * 9191 host 10 A 127.0.0.1
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * server1_212 host 10 A 127.0.0.2
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * {xxxx-xxxx-xxxx-xxxx-xxxx} host 10 MX 20 mail.example.com
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /*
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * we don't need the replication id, so don't
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * bother saving a pointer to it.
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /* find space after replication id */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews tmp = strchr(tmp, ' ');
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /* verify we found a space */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if (tmp == NULL)
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews return ISC_R_FAILURE;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /* make sure it is safe to increment pointer */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if (++tmp > lastchar)
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews return ISC_R_FAILURE;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /* save pointer to host */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews pd->host = tmp;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /* find space after host and change it to a '\0' */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews tmp = strchr(tmp, ' ');
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /* verify we found a space */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if (tmp == NULL)
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews return ISC_R_FAILURE;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /* change the space to a null (string terminator) */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews tmp[0] = '\0';
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /* make sure it is safe to increment pointer */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if (++tmp > lastchar)
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews return ISC_R_FAILURE;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /* save pointer to ttl string */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews ttlStr = tmp;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /* find space after ttl and change it to a '\0' */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews tmp = strchr(tmp, ' ');
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /* verify we found a space */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if (tmp == NULL)
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews return ISC_R_FAILURE;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /* change the space to a null (string terminator) */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews tmp[0] = '\0';
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /* make sure it is safe to increment pointer */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if (++tmp > lastchar)
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews return ISC_R_FAILURE;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /* save pointer to dns type */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews pd->type = tmp;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /* find space after type and change it to a '\0' */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews tmp = strchr(tmp, ' ');
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /* verify we found a space */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if (tmp == NULL)
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews return ISC_R_FAILURE;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /* change the space to a null (string terminator) */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews tmp[0] = '\0';
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /* make sure it is safe to increment pointer */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if (++tmp > lastchar)
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews return ISC_R_FAILURE;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /* save pointer to remainder of DNS data */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews pd->data = tmp;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /* convert ttl string to integer */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews pd->ttl = strtol(ttlStr, &endp, 10);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if (*endp != '\0' || pd->ttl < 0) {
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews DNS_LOGMODULE_DLZ, ISC_LOG_ERROR,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews "bdbhpt driver ttl must be a postive number");
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews return ISC_R_FAILURE;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews }
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /* if we get this far everything should have worked. */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews return ISC_R_SUCCESS;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews}
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews/*
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * DLZ methods
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrewsstatic isc_result_t
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrewsbdbhpt_allowzonexfr(void *driverarg, void *dbdata, const char *name,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews const char *client)
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews{
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews isc_result_t result;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews bdbhpt_instance_t *db = (bdbhpt_instance_t *) dbdata;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews DBT key, data;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /* check to see if we are authoritative for the zone first. */
abff0f462a758383d012887d3a97da4dac0c5a94Evan Hunt result = bdbhpt_findzone(driverarg, dbdata, name, NULL, NULL);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if (result != ISC_R_SUCCESS)
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews return (ISC_R_NOTFOUND);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews memset(&key, 0, sizeof(DBT));
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews key.flags = DB_DBT_MALLOC;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews key.data = strdup(name);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if (key.data == NULL) {
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews result = ISC_R_NOMEMORY;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews goto xfr_cleanup;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews }
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews key.size = strlen(key.data);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews memset(&data, 0, sizeof(DBT));
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews data.flags = DB_DBT_MALLOC;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews data.data = strdup(client);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if (data.data == NULL) {
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews result = ISC_R_NOMEMORY;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews goto xfr_cleanup;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews }
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews data.size = strlen(data.data);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews switch(db->client->get(db->client, NULL, &key, &data, DB_GET_BOTH)) {
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews case DB_NOTFOUND:
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews result = ISC_R_NOTFOUND;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews break;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews case 0:
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews result = ISC_R_SUCCESS;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews break;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews default:
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews result = ISC_R_FAILURE;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews }
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews xfr_cleanup:
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /* free any memory duplicate string in the key field */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if (key.data != NULL)
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews free(key.data);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /* free any memory allocated to the data field. */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if (data.data != NULL)
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews free(data.data);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews return result;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews}
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews/*%
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * BDB does not allow a secondary index on a database that allows
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * duplicates. We have a few options:
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews *
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * 1) kill speed by having lookup method use a secondary db which
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * is associated to the primary DB with the DNS data. Then have
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * another secondary db for zone transfer which also points to
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * the dns_data primary. NO - The point of this driver is
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * lookup performance.
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews *
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * 2) Blow up database size by storing DNS data twice. Once for
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * the lookup (dns_data) database, and a second time for the zone
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * transfer (dns_xfr) database. NO - That would probably require
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * a larger cache to provide good performance. Also, that would
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * make the DB larger on disk potentially slowing it as well.
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews *
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * 3) Loop through the dns_xfr database with a cursor to get
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * all the different hosts in a zone. Then use the zone & host
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * together to lookup the data in the dns_data database. YES -
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * This may slow down zone xfr's a little, but that's ok they
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * don't happen as often and don't need to be as fast. We can
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * also use this table when deleting a zone (The BDB driver
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * is read only - the delete would be used during replication
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * updates by a separate process).
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrewsstatic isc_result_t
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrewsbdbhpt_allnodes(const char *zone, void *driverarg, void *dbdata,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews dns_sdlzallnodes_t *allnodes)
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews{
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews isc_result_t result = ISC_R_NOTFOUND;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews bdbhpt_instance_t *db = (bdbhpt_instance_t *) dbdata;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews DBC *xfr_cursor = NULL;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews DBC *dns_cursor = NULL;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews DBT xfr_key, xfr_data, dns_key, dns_data;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews int xfr_flags;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews int dns_flags;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews int bdbhptres;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews bdbhpt_parsed_data_t pd;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews char *tmp = NULL, *tmp_zone, *tmp_zone_host = NULL;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews UNUSED(driverarg);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews memset(&xfr_key, 0, sizeof(DBT));
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews memset(&xfr_data, 0, sizeof(DBT));
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews memset(&dns_key, 0, sizeof(DBT));
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews memset(&dns_data, 0, sizeof(DBT));
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews xfr_key.data = tmp_zone = strdup(zone);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if (xfr_key.data == NULL)
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews return (ISC_R_NOMEMORY);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews xfr_key.size = strlen(xfr_key.data);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /* get a cursor to loop through dns_xfr table */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if (db->xfr->cursor(db->xfr, NULL, &xfr_cursor, 0) != 0) {
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews result = ISC_R_FAILURE;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews goto allnodes_cleanup;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews }
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /* get a cursor to loop through dns_data table */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if (db->data->cursor(db->data, NULL, &dns_cursor, 0) != 0) {
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews result = ISC_R_FAILURE;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews goto allnodes_cleanup;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews }
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews xfr_flags = DB_SET;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /* loop through xfr table for specified zone. */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews while ((bdbhptres = xfr_cursor->c_get(xfr_cursor, &xfr_key, &xfr_data,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews xfr_flags)) == 0) {
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews xfr_flags = DB_NEXT_DUP;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /* +1 to allow for space between zone and host names */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews dns_key.size = xfr_data.size + xfr_key.size + 1;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /* +1 to allow for null term at end of string. */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews dns_key.data = tmp_zone_host = malloc(dns_key.size + 1);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if (dns_key.data == NULL)
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews goto allnodes_cleanup;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /*
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * construct search key for dns_data.
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * zone_name(a space)host_name
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews strcpy(dns_key.data, zone);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews strcat(dns_key.data, " ");
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews strncat(dns_key.data, xfr_data.data, xfr_data.size);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews dns_flags = DB_SET;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews while ((bdbhptres = dns_cursor->c_get(dns_cursor, &dns_key,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews &dns_data,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews dns_flags)) == 0) {
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews dns_flags = DB_NEXT_DUP;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /* +1 to allow for null term at end of string. */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews tmp = realloc(tmp, dns_data.size + 1);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if (tmp == NULL)
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews goto allnodes_cleanup;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /* copy data to tmp string, and append null term. */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews strncpy(tmp, dns_data.data, dns_data.size);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews tmp[dns_data.size] = '\0';
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /* split string into dns data parts. */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if (bdbhpt_parse_data(tmp, &pd) != ISC_R_SUCCESS)
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews goto allnodes_cleanup;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews result = dns_sdlz_putnamedrr(allnodes, pd.host,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews pd.type, pd.ttl, pd.data);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if (result != ISC_R_SUCCESS)
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews goto allnodes_cleanup;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews } /* end inner while loop */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /* clean up memory */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if (tmp_zone_host != NULL) {
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews free(tmp_zone_host);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews tmp_zone_host = NULL;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews }
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews } /* end outer while loop */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews allnodes_cleanup:
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /* free any memory */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if (tmp != NULL)
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews free(tmp);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if (tmp_zone_host != NULL)
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews free(tmp_zone_host);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if (tmp_zone != NULL)
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews free(tmp_zone);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /* get rid of cursors */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if (xfr_cursor != NULL)
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews xfr_cursor->c_close(xfr_cursor);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if (dns_cursor != NULL)
bb9298e0088e8a636ea59f5b435f7c5b536c8017Mark Andrews dns_cursor->c_close(dns_cursor);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews return result;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews}
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews/*%
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * Performs bdbhpt cleanup.
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * Used by bdbhpt_create if there is an error starting up.
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * Used by bdbhpt_destroy when the driver is shutting down.
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrewsstatic void
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrewsbdbhpt_cleanup(bdbhpt_instance_t *db) {
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews isc_mem_t *mctx;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /* close databases */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if (db->data != NULL)
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews db->data->close(db->data, 0);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if (db->xfr != NULL)
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews db->xfr->close(db->xfr, 0);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if (db->zone != NULL)
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews db->zone->close(db->zone, 0);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if (db->client != NULL)
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews db->client->close(db->client, 0);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /* close environment */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if (db->dbenv != NULL)
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews db->dbenv->close(db->dbenv, 0);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /* cleanup memory */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if (db->mctx != NULL) {
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /* save mctx for later */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews mctx = db->mctx;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /* return, and detach the memory */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews isc_mem_put(mctx, db, sizeof(bdbhpt_instance_t));
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews isc_mem_detach(&mctx);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews }
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews}
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrewsstatic isc_result_t
abff0f462a758383d012887d3a97da4dac0c5a94Evan Huntbdbhpt_findzone(void *driverarg, void *dbdata, const char *name,
abff0f462a758383d012887d3a97da4dac0c5a94Evan Hunt dns_clientinfomethods_t *methods, dns_clientinfo_t *clientinfo)
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews{
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews isc_result_t result;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews bdbhpt_instance_t *db = (bdbhpt_instance_t *) dbdata;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews DBT key, data;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews UNUSED(driverarg);
abff0f462a758383d012887d3a97da4dac0c5a94Evan Hunt UNUSED(methods);
abff0f462a758383d012887d3a97da4dac0c5a94Evan Hunt UNUSED(clientinfo);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews memset(&key, 0, sizeof(DBT));
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews memset(&data, 0, sizeof(DBT));
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews data.flags = DB_DBT_MALLOC;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews key.data = strdup(name);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if (key.data == NULL)
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews return (ISC_R_NOMEMORY);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /*
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * reverse string to take advantage of BDB locality of reference
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * if we need futher lookups because the zone doesn't match the
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * first time.
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews key.data = bdbhpt_strrev(key.data);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews key.size = strlen(key.data);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews switch(db->zone->get(db->zone, NULL, &key, &data, 0)) {
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews case DB_NOTFOUND:
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews result = ISC_R_NOTFOUND;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews break;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews case 0:
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews result = ISC_R_SUCCESS;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews break;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews default:
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews result = ISC_R_FAILURE;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews }
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /* free any memory duplicate string in the key field */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if (key.data != NULL)
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews free(key.data);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /* free any memory allocated to the data field. */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if (data.data != NULL)
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews free(data.data);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews return result;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews}
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrewsstatic isc_result_t
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrewsbdbhpt_lookup(const char *zone, const char *name, void *driverarg,
793814f80703afdd69b59ade91e63efa81ae4178Evan Hunt void *dbdata, dns_sdlzlookup_t *lookup,
793814f80703afdd69b59ade91e63efa81ae4178Evan Hunt dns_clientinfomethods_t *methods, dns_clientinfo_t *clientinfo)
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews{
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews isc_result_t result = ISC_R_NOTFOUND;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews bdbhpt_instance_t *db = (bdbhpt_instance_t *) dbdata;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews DBC *data_cursor = NULL;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews DBT key, data;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews int bdbhptres;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews int flags;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews bdbhpt_parsed_data_t pd;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews char *tmp = NULL;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews char *keyStr = NULL;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews UNUSED(driverarg);
793814f80703afdd69b59ade91e63efa81ae4178Evan Hunt UNUSED(methods);
793814f80703afdd69b59ade91e63efa81ae4178Evan Hunt UNUSED(clientinfo);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews memset(&key, 0, sizeof(DBT));
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews memset(&data, 0, sizeof(DBT));
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews key.size = strlen(zone) + strlen(name) + 1;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /* allocate mem for key */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews key.data = keyStr = malloc((key.size + 1) * sizeof(char));
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if (keyStr == NULL)
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews return ISC_R_NOMEMORY;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews strcpy(keyStr, zone);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews strcat(keyStr, " ");
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews strcat(keyStr, name);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /* get a cursor to loop through data */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if (db->data->cursor(db->data, NULL, &data_cursor, 0) != 0) {
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews result = ISC_R_FAILURE;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews goto lookup_cleanup;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews }
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews result = ISC_R_NOTFOUND;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews flags = DB_SET;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews while ((bdbhptres = data_cursor->c_get(data_cursor, &key, &data,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews flags)) == 0) {
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews flags = DB_NEXT_DUP;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews tmp = realloc(tmp, data.size + 1);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if (tmp == NULL)
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews goto lookup_cleanup;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews strncpy(tmp, data.data, data.size);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews tmp[data.size] = '\0';
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if (bdbhpt_parse_data(tmp, &pd) != ISC_R_SUCCESS)
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews goto lookup_cleanup;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews result = dns_sdlz_putrr(lookup, pd.type, pd.ttl, pd.data);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if (result != ISC_R_SUCCESS)
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews goto lookup_cleanup;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews } /* end while loop */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews lookup_cleanup:
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /* get rid of cursor */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if (data_cursor != NULL)
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews data_cursor->c_close(data_cursor);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if (keyStr != NULL)
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews free(keyStr);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if (tmp != NULL)
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews free(tmp);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews return result;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews}
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews/*% Initializes, sets flags and then opens Berkeley databases. */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrewsstatic isc_result_t
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrewsbdbhpt_opendb(DB_ENV *db_env, DBTYPE db_type, DB **db, const char *db_name,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews char *db_file, int flags) {
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews int result;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /* Initialize the database. */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if ((result = db_create(db, db_env, 0)) != 0) {
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews DNS_LOGMODULE_DLZ, ISC_LOG_ERROR,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews "bdbhpt could not initialize %s database. "
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews "bdbhpt error: %s",
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews db_name, db_strerror(result));
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews return ISC_R_FAILURE;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews }
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /* set database flags. */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if ((result = (*db)->set_flags(*db, flags)) != 0) {
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews DNS_LOGMODULE_DLZ, ISC_LOG_ERROR,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews "bdbhpt could not set flags for %s database. "
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews "bdbhpt error: %s",
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews db_name, db_strerror(result));
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews return ISC_R_FAILURE;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews }
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /* open the database. */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if ((result = (*db)->open(*db, NULL, db_file, db_name, db_type,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews DB_RDONLY | bdbhpt_threads, 0)) != 0) {
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews DNS_LOGMODULE_DLZ, ISC_LOG_ERROR,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews "bdbhpt could not open %s database in %s. "
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews "bdbhpt error: %s",
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews db_name, db_file, db_strerror(result));
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews return ISC_R_FAILURE;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews }
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews return ISC_R_SUCCESS;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews}
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrewsstatic isc_result_t
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrewsbdbhpt_create(const char *dlzname, unsigned int argc, char *argv[],
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews void *driverarg, void **dbdata)
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews{
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews isc_result_t result;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews int bdbhptres;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews int bdbFlags = 0;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews bdbhpt_instance_t *db = NULL;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews UNUSED(dlzname);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews UNUSED(driverarg);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /* verify we have 4 arg's passed to the driver */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if (argc != 4) {
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews DNS_LOGMODULE_DLZ, ISC_LOG_ERROR,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews "bdbhpt driver requires at least "
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews "3 command line args.");
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews return (ISC_R_FAILURE);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews }
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews switch((char) *argv[1]) {
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /*
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * Transactional mode. Highest safety - lowest speed.
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews case 'T':
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews case 't':
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews bdbFlags = DB_INIT_MPOOL | DB_INIT_LOCK |
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews DB_INIT_LOG | DB_INIT_TXN;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews DNS_LOGMODULE_DLZ, ISC_LOG_DEBUG(1),
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews "bdbhpt driver using transactional mode.");
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews break;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /*
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * Concurrent mode. Lower safety (no rollback) -
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * higher speed.
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews case 'C':
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews case 'c':
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews bdbFlags = DB_INIT_CDB | DB_INIT_MPOOL;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews DNS_LOGMODULE_DLZ, ISC_LOG_DEBUG(1),
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews "bdbhpt driver using concurrent mode.");
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews break;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /*
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * Private mode. No inter-process communication & no locking.
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * Lowest saftey - highest speed.
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews case 'P':
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews case 'p':
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews bdbFlags = DB_PRIVATE | DB_INIT_MPOOL;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews DNS_LOGMODULE_DLZ, ISC_LOG_DEBUG(1),
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews "bdbhpt driver using private mode.");
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews break;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews default:
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews DNS_LOGMODULE_DLZ, ISC_LOG_ERROR,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews "bdbhpt driver requires the operating mode "
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews "be set to P or C or T. You specified '%s'",
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews argv[1]);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews return (ISC_R_FAILURE);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews }
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /* allocate and zero memory for driver structure */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews db = isc_mem_get(ns_g_mctx, sizeof(bdbhpt_instance_t));
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if (db == NULL) {
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews DNS_LOGMODULE_DLZ, ISC_LOG_ERROR,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews "Could not allocate memory for "
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews "database instance object.");
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews return (ISC_R_NOMEMORY);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews }
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews memset(db, 0, sizeof(bdbhpt_instance_t));
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /* attach to the memory context */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews isc_mem_attach(ns_g_mctx, &db->mctx);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /*
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * create bdbhpt environment
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * Basically bdbhpt allocates and assigns memory to db->dbenv
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews bdbhptres = db_env_create(&db->dbenv, 0);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if (bdbhptres != 0) {
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews DNS_LOGMODULE_DLZ, ISC_LOG_ERROR,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews "bdbhpt environment could not be created. "
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews "bdbhpt error: %s",
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews db_strerror(bdbhptres));
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews result = ISC_R_FAILURE;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews goto init_cleanup;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews }
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /* open bdbhpt environment */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews bdbhptres = db->dbenv->open(db->dbenv, argv[2],
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews bdbFlags | bdbhpt_threads | DB_CREATE, 0);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if (bdbhptres != 0) {
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews DNS_LOGMODULE_DLZ, ISC_LOG_ERROR,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews "bdbhpt environment at '%s' could not be opened."
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews " bdbhpt error: %s",
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews argv[2], db_strerror(bdbhptres));
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews result = ISC_R_FAILURE;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews goto init_cleanup;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews }
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /* open dlz_data database. */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews result = bdbhpt_opendb(db->dbenv, DB_UNKNOWN, &db->data,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews dlz_data, argv[3], DB_DUP | DB_DUPSORT);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if (result != ISC_R_SUCCESS)
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews goto init_cleanup;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /* open dlz_xfr database. */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews result = bdbhpt_opendb(db->dbenv, DB_UNKNOWN, &db->xfr,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews dlz_xfr, argv[3], DB_DUP | DB_DUPSORT);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if (result != ISC_R_SUCCESS)
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews goto init_cleanup;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /* open dlz_zone database. */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews result = bdbhpt_opendb(db->dbenv, DB_UNKNOWN, &db->zone,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews dlz_zone, argv[3], 0);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if (result != ISC_R_SUCCESS)
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews goto init_cleanup;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /* open dlz_client database. */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews result = bdbhpt_opendb(db->dbenv, DB_UNKNOWN, &db->client,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews dlz_client, argv[3], DB_DUP | DB_DUPSORT);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if (result != ISC_R_SUCCESS)
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews goto init_cleanup;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews *dbdata = db;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews return(ISC_R_SUCCESS);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews init_cleanup:
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews bdbhpt_cleanup(db);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews return result;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews}
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrewsstatic void
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrewsbdbhpt_destroy(void *driverarg, void *dbdata)
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews{
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews UNUSED(driverarg);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews bdbhpt_cleanup((bdbhpt_instance_t *) dbdata);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews}
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews/*
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * bdbhpt_authority not needed as authority data is returned by lookup
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrewsstatic dns_sdlzmethods_t dlz_bdbhpt_methods = {
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews bdbhpt_create,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews bdbhpt_destroy,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews bdbhpt_findzone,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews bdbhpt_lookup,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews NULL,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews bdbhpt_allnodes,
71bd858d8ed62672e7c23999dc7c02fd16a55089Evan Hunt bdbhpt_allowzonexfr,
71bd858d8ed62672e7c23999dc7c02fd16a55089Evan Hunt NULL,
71bd858d8ed62672e7c23999dc7c02fd16a55089Evan Hunt NULL,
71bd858d8ed62672e7c23999dc7c02fd16a55089Evan Hunt NULL,
71bd858d8ed62672e7c23999dc7c02fd16a55089Evan Hunt NULL,
71bd858d8ed62672e7c23999dc7c02fd16a55089Evan Hunt NULL,
71bd858d8ed62672e7c23999dc7c02fd16a55089Evan Hunt NULL,
71bd858d8ed62672e7c23999dc7c02fd16a55089Evan Hunt NULL,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews};
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews/*%
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * Wrapper around dns_sdlzregister().
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrewsisc_result_t
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrewsdlz_bdbhpt_init(void) {
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews isc_result_t result;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /*
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * Write debugging message to log
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews DNS_LOGMODULE_DLZ, ISC_LOG_DEBUG(2),
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews "Registering DLZ bdbhpt driver.");
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews result = dns_sdlzregister("bdbhpt", &dlz_bdbhpt_methods, NULL,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews DNS_SDLZFLAG_RELATIVEOWNER |
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews DNS_SDLZFLAG_RELATIVERDATA |
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews DNS_SDLZFLAG_THREADSAFE,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews ns_g_mctx, &dlz_bdbhpt);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if (result != ISC_R_SUCCESS) {
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews UNEXPECTED_ERROR(__FILE__, __LINE__,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews "dns_sdlzregister() failed: %s",
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews isc_result_totext(result));
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews result = ISC_R_UNEXPECTED;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews }
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews return result;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews}
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews/*%
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * Wrapper around dns_sdlzunregister().
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrewsvoid
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrewsdlz_bdbhpt_clear(void) {
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /*
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * Write debugging message to log
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews DNS_LOGMODULE_DLZ, ISC_LOG_DEBUG(2),
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews "Unregistering DLZ bdbhpt driver.");
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if (dlz_bdbhpt != NULL)
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews dns_sdlzunregister(&dlz_bdbhpt);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews}
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews#endif