422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt/*
7c38d4781fd4c5b146503b0dad7f0a2d58bfd00bTinderbox User * Copyright (C) 2011-2017 Internet Systems Consortium, Inc. ("ISC")
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt *
0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark Andrews * This Source Code Form is subject to the terms of the Mozilla Public
0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark Andrews * License, v. 2.0. If a copy of the MPL was not distributed with this
0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark Andrews * file, You can obtain one at http://mozilla.org/MPL/2.0/.
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt */
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt/*
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * This provides a very simple example of an external loadable DLZ
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * driver, with update support.
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt */
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt#include <config.h>
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt#include <stdio.h>
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt#include <stdlib.h>
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt#include <stdarg.h>
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt#include <isc/log.h>
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt#include <isc/result.h>
e7d8a617835d93425b30c4fe1d35660ccd62e1d3Mark Andrews#include <isc/string.h>
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt#include <isc/types.h>
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt#include <isc/util.h>
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt#include <dns/types.h>
50f64cf0e58073f61bea3e1e4a9ad258bca80961Francis Dupont#include <dns/dlz_dlopen.h>
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt#include "driver.h"
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt#ifdef WIN32
653cad790b4dc6c1330f634150a8941b75ed761eMark Andrews#define STRTOK_R(a, b, c) strtok_s(a, b, c)
653cad790b4dc6c1330f634150a8941b75ed761eMark Andrews#elif defined(_REENTRANT)
653cad790b4dc6c1330f634150a8941b75ed761eMark Andrews#define STRTOK_R(a, b, c) strtok_r(a, b, c)
653cad790b4dc6c1330f634150a8941b75ed761eMark Andrews#else
653cad790b4dc6c1330f634150a8941b75ed761eMark Andrews#define STRTOK_R(a, b, c) strtok(a, b)
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt#endif
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
e7d8a617835d93425b30c4fe1d35660ccd62e1d3Mark Andrews#define CHECK(x) \
e7d8a617835d93425b30c4fe1d35660ccd62e1d3Mark Andrews do { \
e7d8a617835d93425b30c4fe1d35660ccd62e1d3Mark Andrews result = (x); \
e7d8a617835d93425b30c4fe1d35660ccd62e1d3Mark Andrews if (result != ISC_R_SUCCESS) \
e7d8a617835d93425b30c4fe1d35660ccd62e1d3Mark Andrews goto failure; \
e7d8a617835d93425b30c4fe1d35660ccd62e1d3Mark Andrews } while (0)
e7d8a617835d93425b30c4fe1d35660ccd62e1d3Mark Andrews
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt/* For this simple example, use fixed sized strings */
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Huntstruct record {
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt char name[100];
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt char type[10];
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt char data[200];
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt dns_ttl_t ttl;
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt};
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt#define MAX_RECORDS 100
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
50f64cf0e58073f61bea3e1e4a9ad258bca80961Francis Duponttypedef void log_t(int level, const char *fmt, ...);
50f64cf0e58073f61bea3e1e4a9ad258bca80961Francis Dupont
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Huntstruct dlz_example_data {
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt char *zone_name;
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt /* An example driver doesn't need good memory management :-) */
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt struct record current[MAX_RECORDS];
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt struct record adds[MAX_RECORDS];
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt struct record deletes[MAX_RECORDS];
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt isc_boolean_t transaction_started;
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt /* Helper functions from the dlz_dlopen driver */
50f64cf0e58073f61bea3e1e4a9ad258bca80961Francis Dupont log_t *log;
50f64cf0e58073f61bea3e1e4a9ad258bca80961Francis Dupont dns_sdlz_putrr_t *putrr;
50f64cf0e58073f61bea3e1e4a9ad258bca80961Francis Dupont dns_sdlz_putnamedrr_t *putnamedrr;
50f64cf0e58073f61bea3e1e4a9ad258bca80961Francis Dupont dns_dlz_writeablezone_t *writeable_zone;
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt};
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Huntstatic isc_boolean_t
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Huntsingle_valued(const char *type) {
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt const char *single[] = { "soa", "cname", NULL };
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt int i;
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt for (i = 0; single[i]; i++) {
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt if (strcasecmp(single[i], type) == 0) {
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt return (ISC_TRUE);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt }
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt }
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt return (ISC_FALSE);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt}
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt/*
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * Add a record to a list
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt */
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Huntstatic isc_result_t
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Huntadd_name(struct dlz_example_data *state, struct record *list,
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt const char *name, const char *type, dns_ttl_t ttl, const char *data)
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt{
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt int i;
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt isc_boolean_t single = single_valued(type);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt int first_empty = -1;
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt for (i = 0; i < MAX_RECORDS; i++) {
50f64cf0e58073f61bea3e1e4a9ad258bca80961Francis Dupont if (first_empty == -1 && strlen(list[i].name) == 0U) {
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt first_empty = i;
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt }
cf786a52ce85fd069c764a7de3d036b63a741153Automatic Updater if (strcasecmp(list[i].name, name) != 0)
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt continue;
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt if (strcasecmp(list[i].type, type) != 0)
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt continue;
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt if (!single && strcasecmp(list[i].data, data) != 0)
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt continue;
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt break;
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt }
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt if (i == MAX_RECORDS && first_empty != -1) {
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt i = first_empty;
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt }
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt if (i == MAX_RECORDS) {
611dc8876869036ab5e981e53ae7a446145d9354Mark Andrews if (state->log != NULL)
611dc8876869036ab5e981e53ae7a446145d9354Mark Andrews state->log(ISC_LOG_ERROR,
611dc8876869036ab5e981e53ae7a446145d9354Mark Andrews "dlz_example: out of record space");
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt return (ISC_R_FAILURE);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt }
e7d8a617835d93425b30c4fe1d35660ccd62e1d3Mark Andrews
e7d8a617835d93425b30c4fe1d35660ccd62e1d3Mark Andrews if (strlen(name) >= sizeof(list[i].name) ||
e7d8a617835d93425b30c4fe1d35660ccd62e1d3Mark Andrews strlen(type) >= sizeof(list[i].type) ||
e7d8a617835d93425b30c4fe1d35660ccd62e1d3Mark Andrews strlen(data) >= sizeof(list[i].data))
e7d8a617835d93425b30c4fe1d35660ccd62e1d3Mark Andrews return (ISC_R_NOSPACE);
e7d8a617835d93425b30c4fe1d35660ccd62e1d3Mark Andrews
e7d8a617835d93425b30c4fe1d35660ccd62e1d3Mark Andrews strncpy(list[i].name, name, sizeof(list[i].name));
56510cd031b3faf7d10f86f4c059442a2dd4be45Evan Hunt list[i].name[sizeof(list[i].name) - 1] = '\0';
56510cd031b3faf7d10f86f4c059442a2dd4be45Evan Hunt
e7d8a617835d93425b30c4fe1d35660ccd62e1d3Mark Andrews strncpy(list[i].type, type, sizeof(list[i].type));
56510cd031b3faf7d10f86f4c059442a2dd4be45Evan Hunt list[i].type[sizeof(list[i].type) - 1] = '\0';
56510cd031b3faf7d10f86f4c059442a2dd4be45Evan Hunt
47c5b8af920a93763c97d9a93ea1fd766961a5b3Evan Hunt strncpy(list[i].data, data, sizeof(list[i].data));
56510cd031b3faf7d10f86f4c059442a2dd4be45Evan Hunt list[i].data[sizeof(list[i].data) - 1] = '\0';
56510cd031b3faf7d10f86f4c059442a2dd4be45Evan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt list[i].ttl = ttl;
e7d8a617835d93425b30c4fe1d35660ccd62e1d3Mark Andrews
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt return (ISC_R_SUCCESS);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt}
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt/*
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * Delete a record from a list
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt */
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Huntstatic isc_result_t
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Huntdel_name(struct dlz_example_data *state, struct record *list,
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt const char *name, const char *type, dns_ttl_t ttl,
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt const char *data)
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt{
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt int i;
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt UNUSED(state);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt for (i = 0; i < MAX_RECORDS; i++) {
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt if (strcasecmp(name, list[i].name) == 0 &&
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt strcasecmp(type, list[i].type) == 0 &&
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt strcasecmp(data, list[i].data) == 0 &&
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt ttl == list[i].ttl) {
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt break;
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt }
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt }
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt if (i == MAX_RECORDS) {
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt return (ISC_R_NOTFOUND);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt }
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt memset(&list[i], 0, sizeof(struct record));
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt return (ISC_R_SUCCESS);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt}
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
793814f80703afdd69b59ade91e63efa81ae4178Evan Huntstatic isc_result_t
793814f80703afdd69b59ade91e63efa81ae4178Evan Huntfmt_address(isc_sockaddr_t *addr, char *buffer, size_t size) {
793814f80703afdd69b59ade91e63efa81ae4178Evan Hunt char addr_buf[100];
793814f80703afdd69b59ade91e63efa81ae4178Evan Hunt const char *ret;
793814f80703afdd69b59ade91e63efa81ae4178Evan Hunt isc_uint16_t port = 0;
793814f80703afdd69b59ade91e63efa81ae4178Evan Hunt
793814f80703afdd69b59ade91e63efa81ae4178Evan Hunt switch (addr->type.sa.sa_family) {
793814f80703afdd69b59ade91e63efa81ae4178Evan Hunt case AF_INET:
793814f80703afdd69b59ade91e63efa81ae4178Evan Hunt port = ntohs(addr->type.sin.sin_port);
793814f80703afdd69b59ade91e63efa81ae4178Evan Hunt ret = inet_ntop(AF_INET, &addr->type.sin.sin_addr, addr_buf,
793814f80703afdd69b59ade91e63efa81ae4178Evan Hunt sizeof(addr_buf));
793814f80703afdd69b59ade91e63efa81ae4178Evan Hunt break;
793814f80703afdd69b59ade91e63efa81ae4178Evan Hunt case AF_INET6:
793814f80703afdd69b59ade91e63efa81ae4178Evan Hunt port = ntohs(addr->type.sin6.sin6_port);
793814f80703afdd69b59ade91e63efa81ae4178Evan Hunt ret = inet_ntop(AF_INET6, &addr->type.sin6.sin6_addr, addr_buf,
793814f80703afdd69b59ade91e63efa81ae4178Evan Hunt sizeof(addr_buf));
25500a1d9f34b31eee5db25527fe409da88931a2Mark Andrews break;
793814f80703afdd69b59ade91e63efa81ae4178Evan Hunt default:
793814f80703afdd69b59ade91e63efa81ae4178Evan Hunt return (ISC_R_FAILURE);
793814f80703afdd69b59ade91e63efa81ae4178Evan Hunt }
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
793814f80703afdd69b59ade91e63efa81ae4178Evan Hunt if (ret == NULL)
793814f80703afdd69b59ade91e63efa81ae4178Evan Hunt return (ISC_R_FAILURE);
793814f80703afdd69b59ade91e63efa81ae4178Evan Hunt
793814f80703afdd69b59ade91e63efa81ae4178Evan Hunt snprintf(buffer, size, "%s#%u", addr_buf, port);
793814f80703afdd69b59ade91e63efa81ae4178Evan Hunt return (ISC_R_SUCCESS);
793814f80703afdd69b59ade91e63efa81ae4178Evan Hunt}
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt/*
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * Return the version of the API
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt */
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Huntint
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Huntdlz_version(unsigned int *flags) {
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt UNUSED(flags);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt return (DLZ_DLOPEN_VERSION);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt}
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt/*
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * Remember a helper function from the bind9 dlz_dlopen driver
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt */
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Huntstatic void
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Huntb9_add_helper(struct dlz_example_data *state,
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt const char *helper_name, void *ptr)
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt{
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt if (strcmp(helper_name, "log") == 0)
50f64cf0e58073f61bea3e1e4a9ad258bca80961Francis Dupont state->log = (log_t *)ptr;
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt if (strcmp(helper_name, "putrr") == 0)
50f64cf0e58073f61bea3e1e4a9ad258bca80961Francis Dupont state->putrr = (dns_sdlz_putrr_t *)ptr;
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt if (strcmp(helper_name, "putnamedrr") == 0)
50f64cf0e58073f61bea3e1e4a9ad258bca80961Francis Dupont state->putnamedrr = (dns_sdlz_putnamedrr_t *)ptr;
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt if (strcmp(helper_name, "writeable_zone") == 0)
50f64cf0e58073f61bea3e1e4a9ad258bca80961Francis Dupont state->writeable_zone = (dns_dlz_writeablezone_t *)ptr;
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt}
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt/*
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * Called to initialize the driver
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt */
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Huntisc_result_t
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Huntdlz_create(const char *dlzname, unsigned int argc, char *argv[],
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt void **dbdata, ...)
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt{
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt struct dlz_example_data *state;
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt const char *helper_name;
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt va_list ap;
21a7fde6ba34c62f4859a4c19de4f49ec1bab474Evan Hunt char soa_data[1024];
2b8bed6681d1541474f022586cbe728dfce36880Evan Hunt const char *extra;
e7d8a617835d93425b30c4fe1d35660ccd62e1d3Mark Andrews isc_result_t result;
e7d8a617835d93425b30c4fe1d35660ccd62e1d3Mark Andrews int n;
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt UNUSED(dlzname);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt state = calloc(1, sizeof(struct dlz_example_data));
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt if (state == NULL)
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt return (ISC_R_NOMEMORY);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt /* Fill in the helper functions */
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt va_start(ap, dbdata);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt while ((helper_name = va_arg(ap, const char *)) != NULL) {
611dc8876869036ab5e981e53ae7a446145d9354Mark Andrews b9_add_helper(state, helper_name, va_arg(ap, void *));
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt }
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt va_end(ap);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
aefb3e308ba01ad47a3d3aaadf77a5edd4261cb9Evan Hunt if (argc < 2 || argv[1][0] == '\0') {
611dc8876869036ab5e981e53ae7a446145d9354Mark Andrews if (state->log != NULL)
611dc8876869036ab5e981e53ae7a446145d9354Mark Andrews state->log(ISC_LOG_ERROR,
611dc8876869036ab5e981e53ae7a446145d9354Mark Andrews "dlz_example: please specify a zone name");
411d2914ade28174f3789d4a8e43636fc68eb310Mark Andrews dlz_destroy(state);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt return (ISC_R_FAILURE);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt }
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
aefb3e308ba01ad47a3d3aaadf77a5edd4261cb9Evan Hunt /* Ensure zone name is absolute */
a3b6dcd4181891c47ac78f3535fffe85bd90d13bEvan Hunt state->zone_name = malloc(strlen(argv[1]) + 2);
611dc8876869036ab5e981e53ae7a446145d9354Mark Andrews if (state->zone_name == NULL) {
611dc8876869036ab5e981e53ae7a446145d9354Mark Andrews free(state);
611dc8876869036ab5e981e53ae7a446145d9354Mark Andrews return (ISC_R_NOMEMORY);
611dc8876869036ab5e981e53ae7a446145d9354Mark Andrews }
a3b6dcd4181891c47ac78f3535fffe85bd90d13bEvan Hunt if (argv[1][strlen(argv[1]) - 1] == '.')
a3b6dcd4181891c47ac78f3535fffe85bd90d13bEvan Hunt strcpy(state->zone_name, argv[1]);
a3b6dcd4181891c47ac78f3535fffe85bd90d13bEvan Hunt else
a3b6dcd4181891c47ac78f3535fffe85bd90d13bEvan Hunt sprintf(state->zone_name, "%s.", argv[1]);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
2b8bed6681d1541474f022586cbe728dfce36880Evan Hunt if (strcmp(state->zone_name, ".") == 0)
2b8bed6681d1541474f022586cbe728dfce36880Evan Hunt extra = ".root";
2b8bed6681d1541474f022586cbe728dfce36880Evan Hunt else
2b8bed6681d1541474f022586cbe728dfce36880Evan Hunt extra = ".";
2b8bed6681d1541474f022586cbe728dfce36880Evan Hunt
2b8bed6681d1541474f022586cbe728dfce36880Evan Hunt n = sprintf(soa_data, "%s hostmaster%s%s 123 900 600 86400 3600",
2b8bed6681d1541474f022586cbe728dfce36880Evan Hunt state->zone_name, extra, state->zone_name);
2b8bed6681d1541474f022586cbe728dfce36880Evan Hunt
e7d8a617835d93425b30c4fe1d35660ccd62e1d3Mark Andrews if (n < 0)
e7d8a617835d93425b30c4fe1d35660ccd62e1d3Mark Andrews CHECK(ISC_R_FAILURE);
e7d8a617835d93425b30c4fe1d35660ccd62e1d3Mark Andrews if ((unsigned)n >= sizeof(soa_data))
e7d8a617835d93425b30c4fe1d35660ccd62e1d3Mark Andrews CHECK(ISC_R_NOSPACE);
e7d8a617835d93425b30c4fe1d35660ccd62e1d3Mark Andrews
2b8bed6681d1541474f022586cbe728dfce36880Evan Hunt add_name(state, &state->current[0], state->zone_name,
2b8bed6681d1541474f022586cbe728dfce36880Evan Hunt "soa", 3600, soa_data);
2b8bed6681d1541474f022586cbe728dfce36880Evan Hunt add_name(state, &state->current[0], state->zone_name,
2b8bed6681d1541474f022586cbe728dfce36880Evan Hunt "ns", 3600, state->zone_name);
2b8bed6681d1541474f022586cbe728dfce36880Evan Hunt add_name(state, &state->current[0], state->zone_name,
2b8bed6681d1541474f022586cbe728dfce36880Evan Hunt "a", 1800, "10.53.0.1");
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
611dc8876869036ab5e981e53ae7a446145d9354Mark Andrews if (state->log != NULL)
611dc8876869036ab5e981e53ae7a446145d9354Mark Andrews state->log(ISC_LOG_INFO, "dlz_example: started for zone %s",
611dc8876869036ab5e981e53ae7a446145d9354Mark Andrews state->zone_name);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt *dbdata = state;
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt return (ISC_R_SUCCESS);
e7d8a617835d93425b30c4fe1d35660ccd62e1d3Mark Andrews
e7d8a617835d93425b30c4fe1d35660ccd62e1d3Mark Andrews failure:
e7d8a617835d93425b30c4fe1d35660ccd62e1d3Mark Andrews free(state);
e7d8a617835d93425b30c4fe1d35660ccd62e1d3Mark Andrews return (result);
e7d8a617835d93425b30c4fe1d35660ccd62e1d3Mark Andrews
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt}
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt/*
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * Shut down the backend
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt */
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Huntvoid
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Huntdlz_destroy(void *dbdata) {
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt struct dlz_example_data *state = (struct dlz_example_data *)dbdata;
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
611dc8876869036ab5e981e53ae7a446145d9354Mark Andrews if (state->log != NULL)
611dc8876869036ab5e981e53ae7a446145d9354Mark Andrews state->log(ISC_LOG_INFO,
611dc8876869036ab5e981e53ae7a446145d9354Mark Andrews "dlz_example: shutting down zone %s",
611dc8876869036ab5e981e53ae7a446145d9354Mark Andrews state->zone_name);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt free(state->zone_name);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt free(state);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt}
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt/*
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * See if we handle a given zone
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt */
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Huntisc_result_t
abff0f462a758383d012887d3a97da4dac0c5a94Evan Huntdlz_findzonedb(void *dbdata, const char *name,
abff0f462a758383d012887d3a97da4dac0c5a94Evan Hunt dns_clientinfomethods_t *methods,
abff0f462a758383d012887d3a97da4dac0c5a94Evan Hunt dns_clientinfo_t *clientinfo)
abff0f462a758383d012887d3a97da4dac0c5a94Evan Hunt{
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt struct dlz_example_data *state = (struct dlz_example_data *)dbdata;
abff0f462a758383d012887d3a97da4dac0c5a94Evan Hunt isc_sockaddr_t *src;
abff0f462a758383d012887d3a97da4dac0c5a94Evan Hunt char addrbuf[100];
aefb3e308ba01ad47a3d3aaadf77a5edd4261cb9Evan Hunt char absolute[1024];
abff0f462a758383d012887d3a97da4dac0c5a94Evan Hunt
a3b6dcd4181891c47ac78f3535fffe85bd90d13bEvan Hunt strcpy(addrbuf, "unknown");
abff0f462a758383d012887d3a97da4dac0c5a94Evan Hunt if (methods != NULL &&
abff0f462a758383d012887d3a97da4dac0c5a94Evan Hunt methods->sourceip != NULL &&
b3d116c299722ed7b27550744fff789a61ad3d2bEvan Hunt methods->version - methods->age <= DNS_CLIENTINFOMETHODS_VERSION &&
b3d116c299722ed7b27550744fff789a61ad3d2bEvan Hunt DNS_CLIENTINFOMETHODS_VERSION <= methods->version)
abff0f462a758383d012887d3a97da4dac0c5a94Evan Hunt {
abff0f462a758383d012887d3a97da4dac0c5a94Evan Hunt methods->sourceip(clientinfo, &src);
abff0f462a758383d012887d3a97da4dac0c5a94Evan Hunt fmt_address(src, addrbuf, sizeof(addrbuf));
abff0f462a758383d012887d3a97da4dac0c5a94Evan Hunt }
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
177be355d4ccf0ce6308e3e6c0f5404eaf13e9a0Evan Hunt state->log(ISC_LOG_INFO,
abff0f462a758383d012887d3a97da4dac0c5a94Evan Hunt "dlz_example: dlz_findzonedb called with name '%s' "
aefb3e308ba01ad47a3d3aaadf77a5edd4261cb9Evan Hunt "in zone DB '%s' from %s",
aefb3e308ba01ad47a3d3aaadf77a5edd4261cb9Evan Hunt name, state->zone_name, addrbuf);
177be355d4ccf0ce6308e3e6c0f5404eaf13e9a0Evan Hunt
177be355d4ccf0ce6308e3e6c0f5404eaf13e9a0Evan Hunt /*
177be355d4ccf0ce6308e3e6c0f5404eaf13e9a0Evan Hunt * Returning ISC_R_NOTFOUND will cause the query logic to
177be355d4ccf0ce6308e3e6c0f5404eaf13e9a0Evan Hunt * check the database for parent names, looking for zone cuts.
177be355d4ccf0ce6308e3e6c0f5404eaf13e9a0Evan Hunt *
177be355d4ccf0ce6308e3e6c0f5404eaf13e9a0Evan Hunt * Returning ISC_R_NOMORE prevents the query logic from doing
177be355d4ccf0ce6308e3e6c0f5404eaf13e9a0Evan Hunt * this; it will move onto the next database after a single query.
177be355d4ccf0ce6308e3e6c0f5404eaf13e9a0Evan Hunt */
177be355d4ccf0ce6308e3e6c0f5404eaf13e9a0Evan Hunt if (strcasecmp(name, "test.example.com") == 0)
177be355d4ccf0ce6308e3e6c0f5404eaf13e9a0Evan Hunt return (ISC_R_NOMORE);
177be355d4ccf0ce6308e3e6c0f5404eaf13e9a0Evan Hunt
abff0f462a758383d012887d3a97da4dac0c5a94Evan Hunt /*
abff0f462a758383d012887d3a97da4dac0c5a94Evan Hunt * For example.net, only return ISC_R_NOMORE when queried
abff0f462a758383d012887d3a97da4dac0c5a94Evan Hunt * from 10.53.0.1.
abff0f462a758383d012887d3a97da4dac0c5a94Evan Hunt */
abff0f462a758383d012887d3a97da4dac0c5a94Evan Hunt if (strcasecmp(name, "test.example.net") == 0 &&
abff0f462a758383d012887d3a97da4dac0c5a94Evan Hunt strncmp(addrbuf, "10.53.0.1", 9) == 0)
abff0f462a758383d012887d3a97da4dac0c5a94Evan Hunt return (ISC_R_NOMORE);
abff0f462a758383d012887d3a97da4dac0c5a94Evan Hunt
21a7fde6ba34c62f4859a4c19de4f49ec1bab474Evan Hunt /*
21a7fde6ba34c62f4859a4c19de4f49ec1bab474Evan Hunt * For bigcname.domain, return success so it appears to be
21a7fde6ba34c62f4859a4c19de4f49ec1bab474Evan Hunt * the zone origin; this regression tests a bug in which
21a7fde6ba34c62f4859a4c19de4f49ec1bab474Evan Hunt * zone origin nodes could fail to return SERVFAIL to the client.
21a7fde6ba34c62f4859a4c19de4f49ec1bab474Evan Hunt */
21a7fde6ba34c62f4859a4c19de4f49ec1bab474Evan Hunt if (strcasecmp(name, "bigcname.domain") == 0)
21a7fde6ba34c62f4859a4c19de4f49ec1bab474Evan Hunt return (ISC_R_SUCCESS);
21a7fde6ba34c62f4859a4c19de4f49ec1bab474Evan Hunt
21a7fde6ba34c62f4859a4c19de4f49ec1bab474Evan Hunt /*
21a7fde6ba34c62f4859a4c19de4f49ec1bab474Evan Hunt * Return success if we have an exact match between the
21a7fde6ba34c62f4859a4c19de4f49ec1bab474Evan Hunt * zone name and the qname
21a7fde6ba34c62f4859a4c19de4f49ec1bab474Evan Hunt */
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt if (strcasecmp(state->zone_name, name) == 0)
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt return (ISC_R_SUCCESS);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
aefb3e308ba01ad47a3d3aaadf77a5edd4261cb9Evan Hunt snprintf(absolute, sizeof(absolute), "%s.", name);
aefb3e308ba01ad47a3d3aaadf77a5edd4261cb9Evan Hunt if (strcasecmp(state->zone_name, absolute) == 0)
aefb3e308ba01ad47a3d3aaadf77a5edd4261cb9Evan Hunt return (ISC_R_SUCCESS);
aefb3e308ba01ad47a3d3aaadf77a5edd4261cb9Evan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt return (ISC_R_NOTFOUND);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt}
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt/*
abff0f462a758383d012887d3a97da4dac0c5a94Evan Hunt * Look up one record in the sample database.
abff0f462a758383d012887d3a97da4dac0c5a94Evan Hunt *
cbd1fa092ea66bfa9990c5e515725646295396c5Evan Hunt * If the queryname is "source-addr", send back a TXT record containing
abff0f462a758383d012887d3a97da4dac0c5a94Evan Hunt * the address of the client, to test the use of 'methods' and 'clientinfo'
cbd1fa092ea66bfa9990c5e515725646295396c5Evan Hunt *
cbd1fa092ea66bfa9990c5e515725646295396c5Evan Hunt * If the queryname is "too-long", send back a TXT record that's too long
cbd1fa092ea66bfa9990c5e515725646295396c5Evan Hunt * to process; this should result in a SERVFAIL when queried.
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt */
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Huntisc_result_t
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Huntdlz_lookup(const char *zone, const char *name, void *dbdata,
793814f80703afdd69b59ade91e63efa81ae4178Evan Hunt dns_sdlzlookup_t *lookup, dns_clientinfomethods_t *methods,
793814f80703afdd69b59ade91e63efa81ae4178Evan Hunt dns_clientinfo_t *clientinfo)
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt{
793814f80703afdd69b59ade91e63efa81ae4178Evan Hunt isc_result_t result;
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt struct dlz_example_data *state = (struct dlz_example_data *)dbdata;
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt isc_boolean_t found = ISC_FALSE;
aefb3e308ba01ad47a3d3aaadf77a5edd4261cb9Evan Hunt void *dbversion = NULL;
793814f80703afdd69b59ade91e63efa81ae4178Evan Hunt isc_sockaddr_t *src;
47c5b8af920a93763c97d9a93ea1fd766961a5b3Evan Hunt char full_name[256];
cbd1fa092ea66bfa9990c5e515725646295396c5Evan Hunt char buf[512];
8d8f9f7f86a33a155dd74b9b2c1317afca555d54Evan Hunt static char last[256] = { 0 };
8d8f9f7f86a33a155dd74b9b2c1317afca555d54Evan Hunt static int count = 0;
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt int i;
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt UNUSED(zone);
cf786a52ce85fd069c764a7de3d036b63a741153Automatic Updater
611dc8876869036ab5e981e53ae7a446145d9354Mark Andrews if (state->putrr == NULL)
611dc8876869036ab5e981e53ae7a446145d9354Mark Andrews return (ISC_R_NOTIMPLEMENTED);
611dc8876869036ab5e981e53ae7a446145d9354Mark Andrews
47c5b8af920a93763c97d9a93ea1fd766961a5b3Evan Hunt if (strcmp(name, "@") == 0) {
47c5b8af920a93763c97d9a93ea1fd766961a5b3Evan Hunt strncpy(full_name, state->zone_name, 255);
47c5b8af920a93763c97d9a93ea1fd766961a5b3Evan Hunt full_name[255] = '\0';
8d8f9f7f86a33a155dd74b9b2c1317afca555d54Evan Hunt } else if (strcmp(state->zone_name, ".") == 0)
8d8f9f7f86a33a155dd74b9b2c1317afca555d54Evan Hunt snprintf(full_name, 255, "%s.", name);
8d8f9f7f86a33a155dd74b9b2c1317afca555d54Evan Hunt else
47c5b8af920a93763c97d9a93ea1fd766961a5b3Evan Hunt snprintf(full_name, 255, "%s.%s", name, state->zone_name);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
8d8f9f7f86a33a155dd74b9b2c1317afca555d54Evan Hunt /*
8d8f9f7f86a33a155dd74b9b2c1317afca555d54Evan Hunt * For test purposes, log all calls to dlz_lookup()
8d8f9f7f86a33a155dd74b9b2c1317afca555d54Evan Hunt */
8d8f9f7f86a33a155dd74b9b2c1317afca555d54Evan Hunt if (strncasecmp(full_name, last, 255) == 0)
8d8f9f7f86a33a155dd74b9b2c1317afca555d54Evan Hunt count++;
8d8f9f7f86a33a155dd74b9b2c1317afca555d54Evan Hunt else {
8d8f9f7f86a33a155dd74b9b2c1317afca555d54Evan Hunt count = 1;
8d8f9f7f86a33a155dd74b9b2c1317afca555d54Evan Hunt strncpy(last, full_name, 255);
8d8f9f7f86a33a155dd74b9b2c1317afca555d54Evan Hunt }
8d8f9f7f86a33a155dd74b9b2c1317afca555d54Evan Hunt state->log(ISC_LOG_INFO, "lookup #%d for %s", count, full_name);
8d8f9f7f86a33a155dd74b9b2c1317afca555d54Evan Hunt
aefb3e308ba01ad47a3d3aaadf77a5edd4261cb9Evan Hunt /*
aefb3e308ba01ad47a3d3aaadf77a5edd4261cb9Evan Hunt * If we need to know the database version (as set in
aefb3e308ba01ad47a3d3aaadf77a5edd4261cb9Evan Hunt * the 'newversion' dlz function) we can pick it up from the
aefb3e308ba01ad47a3d3aaadf77a5edd4261cb9Evan Hunt * clientinfo.
aefb3e308ba01ad47a3d3aaadf77a5edd4261cb9Evan Hunt *
aefb3e308ba01ad47a3d3aaadf77a5edd4261cb9Evan Hunt * This allows a lookup to query the correct version of the DNS
aefb3e308ba01ad47a3d3aaadf77a5edd4261cb9Evan Hunt * data, if the DLZ can differentiate between versions.
aefb3e308ba01ad47a3d3aaadf77a5edd4261cb9Evan Hunt *
aefb3e308ba01ad47a3d3aaadf77a5edd4261cb9Evan Hunt * For example, if a new database transaction is created by
aefb3e308ba01ad47a3d3aaadf77a5edd4261cb9Evan Hunt * 'newversion', the lookup should query within the same
aefb3e308ba01ad47a3d3aaadf77a5edd4261cb9Evan Hunt * transaction scope if it can.
aefb3e308ba01ad47a3d3aaadf77a5edd4261cb9Evan Hunt *
aefb3e308ba01ad47a3d3aaadf77a5edd4261cb9Evan Hunt * If the DLZ only operates on 'live' data, then version
aefb3e308ba01ad47a3d3aaadf77a5edd4261cb9Evan Hunt * wouldn't necessarily be needed.
aefb3e308ba01ad47a3d3aaadf77a5edd4261cb9Evan Hunt */
aefb3e308ba01ad47a3d3aaadf77a5edd4261cb9Evan Hunt if (clientinfo != NULL &&
aefb3e308ba01ad47a3d3aaadf77a5edd4261cb9Evan Hunt clientinfo->version >= DNS_CLIENTINFO_VERSION) {
aefb3e308ba01ad47a3d3aaadf77a5edd4261cb9Evan Hunt dbversion = clientinfo->dbversion;
aefb3e308ba01ad47a3d3aaadf77a5edd4261cb9Evan Hunt if (dbversion != NULL && *(isc_boolean_t *)dbversion)
aefb3e308ba01ad47a3d3aaadf77a5edd4261cb9Evan Hunt state->log(ISC_LOG_INFO,
aefb3e308ba01ad47a3d3aaadf77a5edd4261cb9Evan Hunt "dlz_example: lookup against live "
8d8f9f7f86a33a155dd74b9b2c1317afca555d54Evan Hunt "transaction");
aefb3e308ba01ad47a3d3aaadf77a5edd4261cb9Evan Hunt }
aefb3e308ba01ad47a3d3aaadf77a5edd4261cb9Evan Hunt
793814f80703afdd69b59ade91e63efa81ae4178Evan Hunt if (strcmp(name, "source-addr") == 0) {
a3b6dcd4181891c47ac78f3535fffe85bd90d13bEvan Hunt strcpy(buf, "unknown");
793814f80703afdd69b59ade91e63efa81ae4178Evan Hunt if (methods != NULL &&
abff0f462a758383d012887d3a97da4dac0c5a94Evan Hunt methods->sourceip != NULL &&
b3d116c299722ed7b27550744fff789a61ad3d2bEvan Hunt (methods->version - methods->age <=
b3d116c299722ed7b27550744fff789a61ad3d2bEvan Hunt DNS_CLIENTINFOMETHODS_VERSION) &&
b3d116c299722ed7b27550744fff789a61ad3d2bEvan Hunt DNS_CLIENTINFOMETHODS_VERSION <= methods->version)
793814f80703afdd69b59ade91e63efa81ae4178Evan Hunt {
793814f80703afdd69b59ade91e63efa81ae4178Evan Hunt methods->sourceip(clientinfo, &src);
793814f80703afdd69b59ade91e63efa81ae4178Evan Hunt fmt_address(src, buf, sizeof(buf));
793814f80703afdd69b59ade91e63efa81ae4178Evan Hunt }
793814f80703afdd69b59ade91e63efa81ae4178Evan Hunt
aefb3e308ba01ad47a3d3aaadf77a5edd4261cb9Evan Hunt state->log(ISC_LOG_INFO,
8d8f9f7f86a33a155dd74b9b2c1317afca555d54Evan Hunt "dlz_example: lookup connection from %s", buf);
793814f80703afdd69b59ade91e63efa81ae4178Evan Hunt
793814f80703afdd69b59ade91e63efa81ae4178Evan Hunt found = ISC_TRUE;
793814f80703afdd69b59ade91e63efa81ae4178Evan Hunt result = state->putrr(lookup, "TXT", 0, buf);
cbd1fa092ea66bfa9990c5e515725646295396c5Evan Hunt if (result != ISC_R_SUCCESS)
cbd1fa092ea66bfa9990c5e515725646295396c5Evan Hunt return (result);
cbd1fa092ea66bfa9990c5e515725646295396c5Evan Hunt }
cbd1fa092ea66bfa9990c5e515725646295396c5Evan Hunt
21a7fde6ba34c62f4859a4c19de4f49ec1bab474Evan Hunt if (strcmp(name, "too-long") == 0 ||
21a7fde6ba34c62f4859a4c19de4f49ec1bab474Evan Hunt strcmp(zone, "bigcname.domain") == 0)
21a7fde6ba34c62f4859a4c19de4f49ec1bab474Evan Hunt {
cbd1fa092ea66bfa9990c5e515725646295396c5Evan Hunt for (i = 0; i < 511; i++)
cbd1fa092ea66bfa9990c5e515725646295396c5Evan Hunt buf[i] = 'x';
cbd1fa092ea66bfa9990c5e515725646295396c5Evan Hunt buf[i] = '\0';
cbd1fa092ea66bfa9990c5e515725646295396c5Evan Hunt found = ISC_TRUE;
cbd1fa092ea66bfa9990c5e515725646295396c5Evan Hunt result = state->putrr(lookup, "TXT", 0, buf);
793814f80703afdd69b59ade91e63efa81ae4178Evan Hunt if (result != ISC_R_SUCCESS)
793814f80703afdd69b59ade91e63efa81ae4178Evan Hunt return (result);
793814f80703afdd69b59ade91e63efa81ae4178Evan Hunt }
793814f80703afdd69b59ade91e63efa81ae4178Evan Hunt
8d8f9f7f86a33a155dd74b9b2c1317afca555d54Evan Hunt /* Tests for DLZ redirection zones */
8d8f9f7f86a33a155dd74b9b2c1317afca555d54Evan Hunt if (strcmp(name, "*") == 0 && strcmp(zone, ".") == 0) {
8d8f9f7f86a33a155dd74b9b2c1317afca555d54Evan Hunt result = state->putrr(lookup, "A", 0, "100.100.100.2");
8d8f9f7f86a33a155dd74b9b2c1317afca555d54Evan Hunt found = ISC_TRUE;
8d8f9f7f86a33a155dd74b9b2c1317afca555d54Evan Hunt if (result != ISC_R_SUCCESS)
8d8f9f7f86a33a155dd74b9b2c1317afca555d54Evan Hunt return (result);
8d8f9f7f86a33a155dd74b9b2c1317afca555d54Evan Hunt }
8d8f9f7f86a33a155dd74b9b2c1317afca555d54Evan Hunt
8d8f9f7f86a33a155dd74b9b2c1317afca555d54Evan Hunt if (strcmp(name, "long.name.is.not.there") == 0 &&
8d8f9f7f86a33a155dd74b9b2c1317afca555d54Evan Hunt strcmp(zone, ".") == 0)
8d8f9f7f86a33a155dd74b9b2c1317afca555d54Evan Hunt {
8d8f9f7f86a33a155dd74b9b2c1317afca555d54Evan Hunt result = state->putrr(lookup, "A", 0, "100.100.100.3");
8d8f9f7f86a33a155dd74b9b2c1317afca555d54Evan Hunt found = ISC_TRUE;
8d8f9f7f86a33a155dd74b9b2c1317afca555d54Evan Hunt if (result != ISC_R_SUCCESS)
8d8f9f7f86a33a155dd74b9b2c1317afca555d54Evan Hunt return (result);
8d8f9f7f86a33a155dd74b9b2c1317afca555d54Evan Hunt }
8d8f9f7f86a33a155dd74b9b2c1317afca555d54Evan Hunt
8d8f9f7f86a33a155dd74b9b2c1317afca555d54Evan Hunt /* Answer from current records */
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt for (i = 0; i < MAX_RECORDS; i++) {
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt if (strcasecmp(state->current[i].name, full_name) == 0) {
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt found = ISC_TRUE;
cf786a52ce85fd069c764a7de3d036b63a741153Automatic Updater result = state->putrr(lookup, state->current[i].type,
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt state->current[i].ttl,
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt state->current[i].data);
793814f80703afdd69b59ade91e63efa81ae4178Evan Hunt if (result != ISC_R_SUCCESS)
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt return (result);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt }
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt }
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt if (!found)
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt return (ISC_R_NOTFOUND);
793814f80703afdd69b59ade91e63efa81ae4178Evan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt return (ISC_R_SUCCESS);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt}
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt/*
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * See if a zone transfer is allowed
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt */
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Huntisc_result_t
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Huntdlz_allowzonexfr(void *dbdata, const char *name, const char *client) {
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt UNUSED(client);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt /* Just say yes for all our zones */
abff0f462a758383d012887d3a97da4dac0c5a94Evan Hunt return (dlz_findzonedb(dbdata, name, NULL, NULL));
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt}
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt/*
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * Perform a zone transfer
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt */
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Huntisc_result_t
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Huntdlz_allnodes(const char *zone, void *dbdata, dns_sdlzallnodes_t *allnodes) {
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt struct dlz_example_data *state = (struct dlz_example_data *)dbdata;
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt int i;
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt UNUSED(zone);
15c7a1bf207173deb2bff1d610d5f784b6629875Tinderbox User
611dc8876869036ab5e981e53ae7a446145d9354Mark Andrews if (state->putnamedrr == NULL)
611dc8876869036ab5e981e53ae7a446145d9354Mark Andrews return (ISC_R_NOTIMPLEMENTED);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt for (i = 0; i < MAX_RECORDS; i++) {
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt isc_result_t result;
50f64cf0e58073f61bea3e1e4a9ad258bca80961Francis Dupont if (strlen(state->current[i].name) == 0U) {
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt continue;
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt }
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt result = state->putnamedrr(allnodes, state->current[i].name,
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt state->current[i].type,
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt state->current[i].ttl,
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt state->current[i].data);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt if (result != ISC_R_SUCCESS)
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt return (result);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt }
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt return (ISC_R_SUCCESS);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt}
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt/*
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * Start a transaction
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt */
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Huntisc_result_t
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Huntdlz_newversion(const char *zone, void *dbdata, void **versionp) {
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt struct dlz_example_data *state = (struct dlz_example_data *)dbdata;
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt if (state->transaction_started) {
611dc8876869036ab5e981e53ae7a446145d9354Mark Andrews if (state->log != NULL)
611dc8876869036ab5e981e53ae7a446145d9354Mark Andrews state->log(ISC_LOG_INFO,
611dc8876869036ab5e981e53ae7a446145d9354Mark Andrews "dlz_example: transaction already "
611dc8876869036ab5e981e53ae7a446145d9354Mark Andrews "started for zone %s", zone);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt return (ISC_R_FAILURE);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt }
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt state->transaction_started = ISC_TRUE;
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt *versionp = (void *) &state->transaction_started;
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt return (ISC_R_SUCCESS);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt}
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt/*
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * End a transaction
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt */
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Huntvoid
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Huntdlz_closeversion(const char *zone, isc_boolean_t commit,
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt void *dbdata, void **versionp)
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt{
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt struct dlz_example_data *state = (struct dlz_example_data *)dbdata;
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt if (!state->transaction_started) {
611dc8876869036ab5e981e53ae7a446145d9354Mark Andrews if (state->log != NULL)
611dc8876869036ab5e981e53ae7a446145d9354Mark Andrews state->log(ISC_LOG_INFO, "dlz_example: transaction not "
611dc8876869036ab5e981e53ae7a446145d9354Mark Andrews "started for zone %s", zone);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt *versionp = NULL;
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt return;
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt }
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt state->transaction_started = ISC_FALSE;
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt *versionp = NULL;
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt if (commit) {
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt int i;
611dc8876869036ab5e981e53ae7a446145d9354Mark Andrews if (state->log != NULL)
611dc8876869036ab5e981e53ae7a446145d9354Mark Andrews state->log(ISC_LOG_INFO, "dlz_example: committing "
611dc8876869036ab5e981e53ae7a446145d9354Mark Andrews "transaction on zone %s", zone);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt for (i = 0; i < MAX_RECORDS; i++) {
e7d8a617835d93425b30c4fe1d35660ccd62e1d3Mark Andrews if (strlen(state->deletes[i].name) > 0U) {
e7d8a617835d93425b30c4fe1d35660ccd62e1d3Mark Andrews (void)del_name(state, &state->current[0],
e7d8a617835d93425b30c4fe1d35660ccd62e1d3Mark Andrews state->deletes[i].name,
e7d8a617835d93425b30c4fe1d35660ccd62e1d3Mark Andrews state->deletes[i].type,
e7d8a617835d93425b30c4fe1d35660ccd62e1d3Mark Andrews state->deletes[i].ttl,
e7d8a617835d93425b30c4fe1d35660ccd62e1d3Mark Andrews state->deletes[i].data);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt }
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt }
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt for (i = 0; i < MAX_RECORDS; i++) {
e7d8a617835d93425b30c4fe1d35660ccd62e1d3Mark Andrews if (strlen(state->adds[i].name) > 0U) {
e7d8a617835d93425b30c4fe1d35660ccd62e1d3Mark Andrews (void)add_name(state, &state->current[0],
e7d8a617835d93425b30c4fe1d35660ccd62e1d3Mark Andrews state->adds[i].name,
e7d8a617835d93425b30c4fe1d35660ccd62e1d3Mark Andrews state->adds[i].type,
e7d8a617835d93425b30c4fe1d35660ccd62e1d3Mark Andrews state->adds[i].ttl,
e7d8a617835d93425b30c4fe1d35660ccd62e1d3Mark Andrews state->adds[i].data);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt }
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt }
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt } else {
611dc8876869036ab5e981e53ae7a446145d9354Mark Andrews if (state->log != NULL)
611dc8876869036ab5e981e53ae7a446145d9354Mark Andrews state->log(ISC_LOG_INFO, "dlz_example: cancelling "
611dc8876869036ab5e981e53ae7a446145d9354Mark Andrews "transaction on zone %s", zone);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt }
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt memset(state->adds, 0, sizeof(state->adds));
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt memset(state->deletes, 0, sizeof(state->deletes));
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt}
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt/*
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * Configure a writeable zone
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt */
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Huntisc_result_t
2b8bed6681d1541474f022586cbe728dfce36880Evan Huntdlz_configure(dns_view_t *view, dns_dlzdb_t *dlzdb, void *dbdata) {
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt struct dlz_example_data *state = (struct dlz_example_data *)dbdata;
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt isc_result_t result;
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
611dc8876869036ab5e981e53ae7a446145d9354Mark Andrews if (state->log != NULL)
611dc8876869036ab5e981e53ae7a446145d9354Mark Andrews state->log(ISC_LOG_INFO, "dlz_example: starting configure");
611dc8876869036ab5e981e53ae7a446145d9354Mark Andrews
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt if (state->writeable_zone == NULL) {
611dc8876869036ab5e981e53ae7a446145d9354Mark Andrews if (state->log != NULL)
611dc8876869036ab5e981e53ae7a446145d9354Mark Andrews state->log(ISC_LOG_INFO, "dlz_example: no "
611dc8876869036ab5e981e53ae7a446145d9354Mark Andrews "writeable_zone method available");
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt return (ISC_R_FAILURE);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt }
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
2b8bed6681d1541474f022586cbe728dfce36880Evan Hunt result = state->writeable_zone(view, dlzdb, state->zone_name);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt if (result != ISC_R_SUCCESS) {
611dc8876869036ab5e981e53ae7a446145d9354Mark Andrews if (state->log != NULL)
611dc8876869036ab5e981e53ae7a446145d9354Mark Andrews state->log(ISC_LOG_ERROR, "dlz_example: failed to "
611dc8876869036ab5e981e53ae7a446145d9354Mark Andrews "configure zone %s", state->zone_name);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt return (result);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt }
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
611dc8876869036ab5e981e53ae7a446145d9354Mark Andrews if (state->log != NULL)
611dc8876869036ab5e981e53ae7a446145d9354Mark Andrews state->log(ISC_LOG_INFO, "dlz_example: configured writeable "
611dc8876869036ab5e981e53ae7a446145d9354Mark Andrews "zone %s", state->zone_name);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt return (ISC_R_SUCCESS);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt}
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt/*
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * Authorize a zone update
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt */
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Huntisc_boolean_t
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Huntdlz_ssumatch(const char *signer, const char *name, const char *tcpaddr,
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt const char *type, const char *key, isc_uint32_t keydatalen,
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt unsigned char *keydata, void *dbdata)
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt{
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt struct dlz_example_data *state = (struct dlz_example_data *)dbdata;
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt UNUSED(tcpaddr);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt UNUSED(type);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt UNUSED(key);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt UNUSED(keydatalen);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt UNUSED(keydata);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt if (strncmp(name, "deny.", 5) == 0) {
611dc8876869036ab5e981e53ae7a446145d9354Mark Andrews if (state->log != NULL)
611dc8876869036ab5e981e53ae7a446145d9354Mark Andrews state->log(ISC_LOG_INFO, "dlz_example: denying update "
611dc8876869036ab5e981e53ae7a446145d9354Mark Andrews "of name=%s by %s", name, signer);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt return (ISC_FALSE);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt }
611dc8876869036ab5e981e53ae7a446145d9354Mark Andrews if (state->log != NULL)
611dc8876869036ab5e981e53ae7a446145d9354Mark Andrews state->log(ISC_LOG_INFO, "dlz_example: allowing update of "
611dc8876869036ab5e981e53ae7a446145d9354Mark Andrews "name=%s by %s", name, signer);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt return (ISC_TRUE);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt}
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Huntstatic isc_result_t
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Huntmodrdataset(struct dlz_example_data *state, const char *name,
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt const char *rdatastr, struct record *list)
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt{
411d2914ade28174f3789d4a8e43636fc68eb310Mark Andrews char *full_name, *dclass, *type, *data, *ttlstr, *buf;
aefb3e308ba01ad47a3d3aaadf77a5edd4261cb9Evan Hunt char absolute[1024];
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt isc_result_t result;
653cad790b4dc6c1330f634150a8941b75ed761eMark Andrews#if defined(WIN32) || defined(_REENTRANT)
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt char *saveptr = NULL;
653cad790b4dc6c1330f634150a8941b75ed761eMark Andrews#endif
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
411d2914ade28174f3789d4a8e43636fc68eb310Mark Andrews buf = strdup(rdatastr);
411d2914ade28174f3789d4a8e43636fc68eb310Mark Andrews if (buf == NULL)
411d2914ade28174f3789d4a8e43636fc68eb310Mark Andrews return (ISC_R_FAILURE);
411d2914ade28174f3789d4a8e43636fc68eb310Mark Andrews
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt /*
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * The format is:
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * FULLNAME\tTTL\tDCLASS\tTYPE\tDATA
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt *
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * The DATA field is space separated, and is in the data format
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * for the type used by dig
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt */
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
653cad790b4dc6c1330f634150a8941b75ed761eMark Andrews full_name = STRTOK_R(buf, "\t", &saveptr);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt if (full_name == NULL)
411d2914ade28174f3789d4a8e43636fc68eb310Mark Andrews goto error;
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
653cad790b4dc6c1330f634150a8941b75ed761eMark Andrews ttlstr = STRTOK_R(NULL, "\t", &saveptr);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt if (ttlstr == NULL)
411d2914ade28174f3789d4a8e43636fc68eb310Mark Andrews goto error;
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
653cad790b4dc6c1330f634150a8941b75ed761eMark Andrews dclass = STRTOK_R(NULL, "\t", &saveptr);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt if (dclass == NULL)
411d2914ade28174f3789d4a8e43636fc68eb310Mark Andrews goto error;
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
653cad790b4dc6c1330f634150a8941b75ed761eMark Andrews type = STRTOK_R(NULL, "\t", &saveptr);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt if (type == NULL)
411d2914ade28174f3789d4a8e43636fc68eb310Mark Andrews goto error;
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
653cad790b4dc6c1330f634150a8941b75ed761eMark Andrews data = STRTOK_R(NULL, "\t", &saveptr);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt if (data == NULL)
411d2914ade28174f3789d4a8e43636fc68eb310Mark Andrews goto error;
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
aefb3e308ba01ad47a3d3aaadf77a5edd4261cb9Evan Hunt if (name[strlen(name) - 1] != '.') {
aefb3e308ba01ad47a3d3aaadf77a5edd4261cb9Evan Hunt snprintf(absolute, sizeof(absolute), "%s.", name);
aefb3e308ba01ad47a3d3aaadf77a5edd4261cb9Evan Hunt name = absolute;
aefb3e308ba01ad47a3d3aaadf77a5edd4261cb9Evan Hunt }
aefb3e308ba01ad47a3d3aaadf77a5edd4261cb9Evan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt result = add_name(state, list, name, type,
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt strtoul(ttlstr, NULL, 10), data);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt free(buf);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt return (result);
411d2914ade28174f3789d4a8e43636fc68eb310Mark Andrews
411d2914ade28174f3789d4a8e43636fc68eb310Mark Andrews error:
411d2914ade28174f3789d4a8e43636fc68eb310Mark Andrews free(buf);
411d2914ade28174f3789d4a8e43636fc68eb310Mark Andrews return (ISC_R_FAILURE);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt}
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Huntisc_result_t
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Huntdlz_addrdataset(const char *name, const char *rdatastr,
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt void *dbdata, void *version)
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt{
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt struct dlz_example_data *state = (struct dlz_example_data *)dbdata;
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt if (version != (void *) &state->transaction_started)
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt return (ISC_R_FAILURE);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
611dc8876869036ab5e981e53ae7a446145d9354Mark Andrews if (state->log != NULL)
611dc8876869036ab5e981e53ae7a446145d9354Mark Andrews state->log(ISC_LOG_INFO, "dlz_example: adding rdataset %s '%s'",
611dc8876869036ab5e981e53ae7a446145d9354Mark Andrews name, rdatastr);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt return (modrdataset(state, name, rdatastr, &state->adds[0]));
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt}
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Huntisc_result_t
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Huntdlz_subrdataset(const char *name, const char *rdatastr,
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt void *dbdata, void *version)
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt{
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt struct dlz_example_data *state = (struct dlz_example_data *)dbdata;
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt if (version != (void *) &state->transaction_started)
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt return (ISC_R_FAILURE);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
611dc8876869036ab5e981e53ae7a446145d9354Mark Andrews if (state->log != NULL)
611dc8876869036ab5e981e53ae7a446145d9354Mark Andrews state->log(ISC_LOG_INFO, "dlz_example: subtracting rdataset "
611dc8876869036ab5e981e53ae7a446145d9354Mark Andrews "%s '%s'", name, rdatastr);
cf786a52ce85fd069c764a7de3d036b63a741153Automatic Updater
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt return (modrdataset(state, name, rdatastr, &state->deletes[0]));
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt}
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Huntisc_result_t
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Huntdlz_delrdataset(const char *name, const char *type,
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt void *dbdata, void *version)
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt{
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt struct dlz_example_data *state = (struct dlz_example_data *)dbdata;
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt if (version != (void *) &state->transaction_started)
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt return (ISC_R_FAILURE);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt
611dc8876869036ab5e981e53ae7a446145d9354Mark Andrews if (state->log != NULL)
611dc8876869036ab5e981e53ae7a446145d9354Mark Andrews state->log(ISC_LOG_INFO, "dlz_example: deleting rdataset %s "
611dc8876869036ab5e981e53ae7a446145d9354Mark Andrews "of type %s", name, type);
cf786a52ce85fd069c764a7de3d036b63a741153Automatic Updater
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt return (ISC_R_SUCCESS);
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt}