+++ /dev/null
--/*
-- * Copyright (C) 2000, 2001 Internet Software Consortium.
-- *
-- * Permission to use, copy, modify, and distribute this software for any
-- * purpose with or without fee is hereby granted, provided that the above
-- * copyright notice and this permission notice appear in all copies.
-- *
-- * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
-- * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
-- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
-- * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
-- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
-- * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
-- * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
-- * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-- */
--
--/* $Id: dirdb.c,v 1.9 2001/01/09 21:46:22 bwelling Exp $ */
--
--/*
-- * A simple database driver that returns basic information about
-- * files and directories in the Unix file system as DNS data.
-- */
--
--#include <config.h>
--
--#include <stdio.h>
--#include <string.h>
--#include <unistd.h>
--#include <sys/stat.h>
--#include <sys/sysmacros.h>
--
--#include <isc/mem.h>
--#include <isc/print.h>
--#include <isc/result.h>
--#include <isc/util.h>
--
--#include <dns/sdb.h>
--
--#include <named/globals.h>
--
--#include "dirdb.h"
--
--static dns_sdbimplementation_t *dirdb = NULL;
--
--#define CHECK(op) \
-- do { result = (op); \
-- if (result != ISC_R_SUCCESS) return (result); \
-- } while (0)
--
--#define CHECKN(op) \
-- do { n = (op); \
-- if (n < 0) return (ISC_R_FAILURE); \
-- } while (0)
--
--
--/*
-- * This database operates on relative names.
-- *
-- * Any name will be interpreted as a pathname offset from the directory
-- * specified in the configuration file.
-- */
--static isc_result_t
--dirdb_lookup(const char *zone, const char *name, void *dbdata,
-- dns_sdblookup_t *lookup)
--{
-- char filename[255];
-- char filename2[255];
-- char buf[1024];
-- struct stat statbuf;
-- isc_result_t result;
-- int n;
--
-- UNUSED(zone);
-- UNUSED(dbdata);
--
-- if (strcmp(name, "@") == 0)
-- snprintf(filename, sizeof(filename), "%s", (char *)dbdata);
-- else
-- snprintf(filename, sizeof(filename), "%s/%s",
-- (char *)dbdata, name);
-- CHECKN(lstat(filename, &statbuf));
--
-- if (S_ISDIR(statbuf.st_mode))
-- CHECK(dns_sdb_putrr(lookup, "txt", 3600, "dir"));
-- else if (S_ISCHR(statbuf.st_mode) || S_ISBLK(statbuf.st_mode)) {
-- CHECKN(snprintf(buf, sizeof(buf),
-- "\"%sdev\" \"major %d\" \"minor %d\"",
-- S_ISCHR(statbuf.st_mode) ? "chr" : "blk",
-- major(statbuf.st_rdev),
-- minor(statbuf.st_rdev)));
-- CHECK(dns_sdb_putrr(lookup, "txt", 3600, buf));
-- } else if (S_ISFIFO(statbuf.st_mode))
-- CHECK(dns_sdb_putrr(lookup, "txt", 3600, "pipe"));
-- else if (S_ISSOCK(statbuf.st_mode))
-- CHECK(dns_sdb_putrr(lookup, "txt", 3600, "socket"));
-- else if (S_ISLNK(statbuf.st_mode)) {
-- CHECKN(readlink(filename, filename2, sizeof(filename2) - 1));
-- buf[n] = 0;
-- CHECKN(snprintf(buf, sizeof(buf), "\"symlink\" \"%s\"",
-- filename2));
-- CHECK(dns_sdb_putrr(lookup, "txt", 3600, buf));
-- } else if (!S_ISREG(statbuf.st_mode))
-- CHECK(dns_sdb_putrr(lookup, "txt", 3600, "unknown"));
-- else {
-- CHECKN(snprintf(buf, sizeof(buf), "\"file\" \"size = %u\"",
-- (unsigned int)statbuf.st_size));
-- CHECK(dns_sdb_putrr(lookup, "txt", 3600, buf));
-- }
--
-- return (ISC_R_SUCCESS);
--}
--
--/*
-- * lookup () does not return SOA or NS records, so authority() must be defined.
-- */
--static isc_result_t
--dirdb_authority(const char *zone, void *dbdata, dns_sdblookup_t *lookup) {
-- isc_result_t result;
--
-- UNUSED(zone);
-- UNUSED(dbdata);
--
-- result = dns_sdb_putsoa(lookup, "ns", "hostmaster", 0);
-- INSIST(result == ISC_R_SUCCESS);
-- result = dns_sdb_putrr(lookup, "ns", 86400, "ns1");
-- INSIST(result == ISC_R_SUCCESS);
-- result = dns_sdb_putrr(lookup, "ns", 86400, "ns2");
-- INSIST(result == ISC_R_SUCCESS);
-- return (ISC_R_SUCCESS);
--}
--
--/*
-- * Each database stores the top-level directory as the dbdata opaque
-- * object. The create() function allocates it. argv[0] holds the top
-- * level directory.
-- */
--static isc_result_t
--dirdb_create(const char *zone, int argc, char **argv,
-- void *driverdata, void **dbdata)
--{
-- UNUSED(zone);
-- UNUSED(driverdata);
--
-- if (argc < 1)
-- return (ISC_R_FAILURE);
-- *dbdata = isc_mem_strdup((isc_mem_t *)driverdata, argv[0]);
-- if (*dbdata == NULL)
-- return (ISC_R_NOMEMORY);
-- return (ISC_R_SUCCESS);
--}
--
--/*
-- * The destroy() function frees the memory allocated by create().
-- */
--static void
--dirdb_destroy(const char *zone, void *driverdata, void **dbdata) {
-- UNUSED(zone);
-- UNUSED(driverdata);
-- isc_mem_free((isc_mem_t *)driverdata, *dbdata);
--}
--
--/*
-- * This zone does not support zone transfer, so allnodes() is NULL.
-- */
--static dns_sdbmethods_t dirdb_methods = {
-- dirdb_lookup,
-- dirdb_authority,
-- NULL, /* allnodes */
-- dirdb_create,
-- dirdb_destroy
--};
--
--/*
-- * Wrapper around dns_sdb_register(). Note that the first ns_g_mctx is
-- * being passed as the "driverdata" parameter, so that will it will be
-- * passed to create() and destroy().
-- */
--isc_result_t
--dirdb_init(void) {
-- unsigned int flags;
-- flags = DNS_SDBFLAG_RELATIVEOWNER | DNS_SDBFLAG_RELATIVERDATA |
-- DNS_SDBFLAG_THREADSAFE;
-- return (dns_sdb_register("dir", &dirdb_methods, ns_g_mctx, flags,
-- ns_g_mctx, &dirdb));
--}
--
--/*
-- * Wrapper around dns_sdb_unregister().
-- */
--void
--dirdb_clear(void) {
-- if (dirdb != NULL)
-- dns_sdb_unregister(&dirdb);
--}
+++ /dev/null
--/*
-- * Copyright (C) 2000, 2001 Internet Software Consortium.
-- *
-- * Permission to use, copy, modify, and distribute this software for any
-- * purpose with or without fee is hereby granted, provided that the above
-- * copyright notice and this permission notice appear in all copies.
-- *
-- * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
-- * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
-- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
-- * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
-- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
-- * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
-- * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
-- * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-- */
--
--/* $Id: dirdb.h,v 1.2 2001/01/09 21:46:23 bwelling Exp $ */
--
--#include <isc/types.h>
--
--isc_result_t dirdb_init(void);
--
--void dirdb_clear(void);
--
+++ /dev/null
--This is the INSTALL file for 0.4. See
--http://www.venaas.no/ldap/bind-sdb/ for updates or other information.
--
--BUILDING
--
--You need the source for BIND 9.1.0 or newer (for zone transfers you
--will need at least 9.1.1rc3 due to a bug). Basically you need to follow
--the instructions in doc/misc/sdb, if my instructions doesn't make sense,
--please have a look at that as well.
--
--Copy ldapdb.c to bin/named and ldapdb.h to bin/named/include in the
--source tree.
--
--Next alter bin/named/Makefile.in. Add ldapdb.@O@ to DBDRIVER_OBJS and
--ldapdb.c to DBDRIVER_SRCS. You also need to add something like
---I/usr/local/include to DBDRIVER_INCLUDES and
---L/usr/local/lib -lldap -llber -lresolv to DBDRIVER_LIBS
--depending on what LDAP library you have and where you installed it.
--
--Finally you need to edit bin/named/main.c. Below where it says
--"#include "xxdb.h"", add the line "#include <ldapdb.h>". Below where
--it says "xxdb_init();" add the line "ldapdb_init();", and finally
--below where it says "xxdb_clear();", add "ldapdb_clear();".
--
--Now you should hopefully be able to build it.
--
--
--CONFIGURING
--
--Before you do any configuring of LDAP stuff, please try to configure
--and start bind as usual to see if things work.
--
--To do anything useful, you need to store a zone in some LDAP server.
--From this release on, you must use a schema called dNSZone. Note that
--it relies on some attribute definitions in the Cosine schema, so that
--must be included as well. The Cosine schema probably comes with your
--LDAP server. You can find dNSZone and further details on how to store
--the data in your LDAP server at
--http://www.venaas.no/ldap/bind-sdb/
--
--For an example, have a look at my venaas.com zone. Try a subtree search
--for objectClass=* at
--ldap ldap://129.241.20.67/dc=venaas,dc=com,o=DNS,dc=venaas,dc=no
--
--To use it with BIND, I've added the following to named.conf:
--zone "venaas.com" {
-- type master;
-- database "ldap ldap://129.241.20.67/dc=venaas,dc=com,o=DNS,dc=venaas,dc=no 172800";
--};
--
--When doing lookups BIND will do a sub-tree search below the base in the
--URL. The number 172800 is the TTL which will be used for all entries that
--haven't got the dNSTTL attribute.
--
--Stig Venaas <venaas@uninett.no> 2001-04-12
+++ /dev/null
--This is an attempt at an LDAP back-end for BIND 9 using the new simplified
--database interface "sdb". This is the fifth release (0.5) and is not ready
--for production use yet. Note that this version (and 0.4) uses a new schema
--and is not backwards compatible with versions before 0.4. The big changes in
--0.5 are thread support and improved connection handling. Multiple threads
--can now access the back-end simultaneously, and rather than having one
--connection per zone, there is now one connection per thread per LDAP server.
--This should help people with multiple CPUs and people with a huge number of
--zones. One final change is support for literal IPv6 addresses in LDAP URLs.
--At least OpenLDAP 2 has IPv6 support, so if you use OpenLDAP 2 libraries and
--server, you got all you need.
--
--If you have bug reports, fixes, comments, questions or whatever, please
--contact me. See also http://www.venaas.no/ldap/bind-sdb/ for information.
--
--See INSTALL for how to build, install and use.
--
--Stig Venaas <venaas@uninett.no> 2001-05-06
+++ /dev/null
--INSTALLATION
--
--To Compile zone2ldap from contrib/sdb directory:
--
-- gcc -g `../../isc-config.sh --cflags isc dns` -c zone2ldap.c
-- gcc -g -o zone2ldap zone2ldap.o `isc-config.sh --libs isc dns` -lldap -llber -lresolv
--
--USAGE:
--
--See zone2ldap.1
--
--BUGS:
--
--Jeff McNeil <jeff@snapcase.g-rock.net>
--
--
--
+++ /dev/null
--/*
-- * Copyright (C) 2001 Stig Venaas
-- *
-- * Permission to use, copy, modify, and distribute this software for any
-- * purpose with or without fee is hereby granted, provided that the above
-- * copyright notice and this permission notice appear in all copies.
-- */
--
--#include <config.h>
--
--#include <string.h>
--#include <stdio.h>
--#include <stdlib.h>
--#include <ctype.h>
--
--#include <isc/mem.h>
--#include <isc/print.h>
--#include <isc/result.h>
--#include <isc/util.h>
--#include <isc/thread.h>
--
--#include <dns/sdb.h>
--
--#include <named/globals.h>
--
--#include <ldap.h>
--#include "ldapdb.h"
--
--/*
-- * A simple database driver for LDAP. Not production quality yet
-- */
--
--static dns_sdbimplementation_t *ldapdb = NULL;
--
--struct ldapdb_data {
-- char *hostport;
-- char *hostname;
-- int portno;
-- char *base;
-- int defaultttl;
--};
--
--/* used by ldapdb_getconn */
--
--struct ldapdb_entry {
-- void *index;
-- size_t size;
-- void *data;
-- struct ldapdb_entry *next;
--};
--
--static struct ldapdb_entry *ldapdb_find(struct ldapdb_entry *stack,
-- const void *index, size_t size) {
-- while (stack != NULL) {
-- if (stack->size == size && !memcmp(stack->index, index, size))
-- return stack;
-- stack = stack->next;
-- }
-- return NULL;
--}
--
--static void ldapdb_insert(struct ldapdb_entry **stack,
-- struct ldapdb_entry *item) {
-- item->next = *stack;
-- *stack = item;
--}
--
--static void ldapdb_lock(int what) {
-- static isc_mutex_t lock;
--
-- switch (what) {
-- case 0:
-- isc_mutex_init(&lock);
-- break;
-- case 1:
-- LOCK(&lock);
-- break;
-- case -1:
-- UNLOCK(&lock);
-- break;
-- }
--}
--
--/* data == NULL means cleanup */
--static LDAP **
--ldapdb_getconn(struct ldapdb_data *data)
--{
-- static struct ldapdb_entry *allthreadsdata = NULL;
-- struct ldapdb_entry *threaddata, *conndata;
-- unsigned long threadid;
--
-- if (data == NULL) {
-- /* cleanup */
-- /* lock out other threads */
-- ldapdb_lock(1);
-- while (allthreadsdata != NULL) {
-- threaddata = allthreadsdata;
-- free(threaddata->index);
-- while (threaddata->data != NULL) {
-- conndata = threaddata->data;
-- free(conndata->index);
-- if (conndata->data != NULL)
-- ldap_unbind((LDAP *)conndata->data);
-- threaddata->data = conndata->next;
-- free(conndata);
-- }
-- allthreadsdata = threaddata->next;
-- free(threaddata);
-- }
-- ldapdb_lock(-1);
-- return (NULL);
-- }
--
-- /* look for connection data for current thread */
-- threadid = isc_thread_self();
-- threaddata = ldapdb_find(allthreadsdata, &threadid, sizeof(threadid));
-- if (threaddata == NULL) {
-- /* no data for this thread, create empty connection list */
-- threaddata = malloc(sizeof(*threaddata));
-- if (threaddata == NULL)
-- return (NULL);
-- threaddata->index = malloc(sizeof(threadid));
-- if (threaddata->index == NULL) {
-- free(threaddata);
-- return (NULL);
-- }
-- *(unsigned long *)threaddata->index = threadid;
-- threaddata->size = sizeof(threadid);
-- threaddata->data = NULL;
--
-- /* need to lock out other threads here */
-- ldapdb_lock(1);
-- ldapdb_insert(&allthreadsdata, threaddata);
-- ldapdb_lock(-1);
-- }
--
-- /* threaddata points at the connection list for current thread */
-- /* look for existing connection to our server */
-- conndata = ldapdb_find((struct ldapdb_entry *)threaddata->data,
-- data->hostport, strlen(data->hostport));
-- if (conndata == NULL) {
-- /* no connection data structure for this server, create one */
-- conndata = malloc(sizeof(*conndata));
-- if (conndata == NULL)
-- return (NULL);
-- (char *)conndata->index = data->hostport;
-- conndata->size = strlen(data->hostport);
-- conndata->data = NULL;
-- ldapdb_insert((struct ldapdb_entry **)&threaddata->data,
-- conndata);
-- }
--
-- return (LDAP **)&conndata->data;
--}
--
--/* callback routines */
--static isc_result_t
--ldapdb_create(const char *zone, int argc, char **argv,
-- void *driverdata, void **dbdata)
--{
-- struct ldapdb_data *data;
-- char *s;
-- int defaultttl;
--
-- UNUSED(zone);
-- UNUSED(driverdata);
--
-- /* we assume that only one thread will call create at a time */
-- /* want to do this only once for all instances */
--
-- if ((argc < 2)
-- || (argv[0] != strstr( argv[0], "ldap://"))
-- || ((defaultttl = atoi(argv[1])) < 1))
-- return (ISC_R_FAILURE);
-- data = isc_mem_get(ns_g_mctx, sizeof(struct ldapdb_data));
-- if (data == NULL)
-- return (ISC_R_NOMEMORY);
-- data->hostport = isc_mem_strdup(ns_g_mctx, argv[0] + strlen("ldap://"));
-- if (data->hostport == NULL) {
-- isc_mem_put(ns_g_mctx, data, sizeof(struct ldapdb_data));
-- return (ISC_R_NOMEMORY);
-- }
-- data->defaultttl = defaultttl;
-- s = strchr(data->hostport, '/');
-- if (s != NULL) {
-- *s++ = '\0';
-- data->base = *s != '\0' ? s : NULL;
-- }
--
-- /* support URLs with literal IPv6 addresses */
-- data->hostname = isc_mem_strdup(ns_g_mctx, data->hostport +
-- (*data->hostport == '[' ? 1 : 0));
-- if (data->hostname == NULL) {
-- isc_mem_free(ns_g_mctx, data->hostport);
-- isc_mem_put(ns_g_mctx, data, sizeof(struct ldapdb_data));
-- return (ISC_R_NOMEMORY);
-- }
--
-- if (*data->hostport == '[' &&
-- (s = strchr(data->hostname, ']')) != NULL )
-- *s++ = '\0';
-- else
-- s = data->hostname;
-- s = strchr(s, ':');
-- if (s != NULL) {
-- *s++ = '\0';
-- data->portno = atoi(s);
-- } else
-- data->portno = LDAP_PORT;
--
-- *dbdata = data;
-- return (ISC_R_SUCCESS);
--}
--
--static void
--ldapdb_destroy(const char *zone, void *driverdata, void **dbdata) {
-- struct ldapdb_data *data = *dbdata;
--
-- UNUSED(zone);
-- UNUSED(driverdata);
--
-- if (data->hostport != NULL)
-- isc_mem_free(ns_g_mctx, data->hostport);
-- if (data->hostname != NULL)
-- isc_mem_free(ns_g_mctx, data->hostname);
-- isc_mem_put(ns_g_mctx, data, sizeof(struct ldapdb_data));
--}
--
--static void
--ldapdb_bind(struct ldapdb_data *data, LDAP **ldp)
--{
-- if (*ldp != NULL)
-- ldap_unbind(*ldp);
-- *ldp = ldap_open(data->hostname, data->portno);
-- if (*ldp == NULL)
-- return;
-- if (ldap_simple_bind_s(*ldp, NULL, NULL) != LDAP_SUCCESS) {
-- ldap_unbind(*ldp);
-- *ldp = NULL;
-- }
--}
--
--static isc_result_t
--ldapdb_lookup(const char *zone, const char *name, void *dbdata,
-- dns_sdblookup_t *lookup)
--{
-- isc_result_t result = ISC_R_NOTFOUND;
-- struct ldapdb_data *data = dbdata;
-- LDAP **ldp;
-- LDAPMessage *res, *e;
-- char *fltr, *a, **vals;
-- char type[64];
-- BerElement *ptr;
-- int i;
--
-- ldp = ldapdb_getconn(data);
-- if (ldp == NULL)
-- return (ISC_R_FAILURE);
-- if (*ldp == NULL) {
-- ldapdb_bind(data, ldp);
-- if (*ldp == NULL)
-- return (ISC_R_FAILURE);
-- }
-- fltr = isc_mem_get(ns_g_mctx, strlen(zone) + strlen(name) +
-- strlen("(&(zoneName=)(relativeDomainName=))") + 1);
-- if (fltr == NULL)
-- return (ISC_R_NOMEMORY);
--
-- strcpy(fltr, "(&(zoneName=");
-- strcat(fltr, zone);
-- strcat(fltr, ")(relativeDomainName=");
-- strcat(fltr, name);
-- strcat(fltr, "))");
--
-- if (ldap_search_s(*ldp, data->base, LDAP_SCOPE_SUBTREE, fltr, NULL, 0,
-- &res) != LDAP_SUCCESS) {
-- ldapdb_bind(data, ldp);
-- if (*ldp != NULL)
-- ldap_search_s(*ldp, data->base, LDAP_SCOPE_SUBTREE,
-- fltr, NULL, 0, &res);
-- }
--
-- isc_mem_put(ns_g_mctx, fltr, strlen(fltr) + 1);
--
-- if (*ldp == NULL)
-- goto exit;
--
-- for (e = ldap_first_entry(*ldp, res); e != NULL;
-- e = ldap_next_entry(*ldp, e)) {
-- LDAP *ld = *ldp;
-- int ttl = data->defaultttl;
--
-- for (a = ldap_first_attribute(ld, e, &ptr); a != NULL;
-- a = ldap_next_attribute(ld, e, ptr)) {
-- if (!strcmp(a, "dNSTTL")) {
-- vals = ldap_get_values(ld, e, a);
-- ttl = atoi(vals[0]);
-- ldap_value_free(vals);
-- ldap_memfree(a);
-- break;
-- }
-- ldap_memfree(a);
-- }
-- for (a = ldap_first_attribute(ld, e, &ptr); a != NULL;
-- a = ldap_next_attribute(ld, e, ptr)) {
-- char *s;
--
-- for (s = a; *s; s++)
-- *s = toupper(*s);
-- s = strstr(a, "RECORD");
-- if ((s == NULL) || (s == a)
-- || (s - a >= (signed int)sizeof(type))) {
-- ldap_memfree(a);
-- continue;
-- }
-- strncpy(type, a, s - a);
-- type[s - a] = '\0';
-- vals = ldap_get_values(ld, e, a);
-- for (i=0; vals[i] != NULL; i++) {
-- result = dns_sdb_putrr(lookup, type, ttl,
-- vals[i]);
-- if (result != ISC_R_SUCCESS) {
-- ldap_value_free(vals);
-- ldap_memfree(a);
-- result = ISC_R_FAILURE;
-- goto exit;
-- }
-- }
-- ldap_value_free(vals);
-- ldap_memfree(a);
-- }
-- }
-- exit:
-- ldap_msgfree(res);
-- return (result);
--}
--
--static isc_result_t
--ldapdb_allnodes(const char *zone, void *dbdata,
-- dns_sdballnodes_t *allnodes) {
-- isc_result_t result = ISC_R_NOTFOUND;
-- struct ldapdb_data *data = dbdata;
-- LDAP **ldp;
-- LDAPMessage *res, *e;
-- char type[64];
-- char *fltr, *a, **vals;
-- BerElement *ptr;
-- int i;
--
-- ldp = ldapdb_getconn(data);
-- if (ldp == NULL)
-- return (ISC_R_FAILURE);
-- if (*ldp == NULL) {
-- ldapdb_bind(data, ldp);
-- if (*ldp == NULL)
-- return (ISC_R_FAILURE);
-- }
--
-- fltr = isc_mem_get(ns_g_mctx, strlen(zone) + strlen("(zoneName=)") + 1);
-- if (fltr == NULL)
-- return (ISC_R_NOMEMORY);
--
-- strcpy(fltr, "(zoneName=");
-- strcat(fltr, zone);
-- strcat(fltr, ")");
--
-- if (ldap_search_s(*ldp, data->base, LDAP_SCOPE_SUBTREE, fltr, NULL, 0,
-- &res) != LDAP_SUCCESS) {
-- ldapdb_bind(data, ldp);
-- if (*ldp != NULL)
-- ldap_search_s(*ldp, data->base, LDAP_SCOPE_SUBTREE,
-- fltr, NULL, 0, &res);
-- }
--
-- isc_mem_put(ns_g_mctx, fltr, strlen(fltr) + 1);
--
-- for (e = ldap_first_entry(*ldp, res); e != NULL;
-- e = ldap_next_entry(*ldp, e)) {
-- LDAP *ld = *ldp;
-- char *name = NULL;
-- int ttl = data->defaultttl;
--
-- for (a = ldap_first_attribute(ld, e, &ptr); a != NULL;
-- a = ldap_next_attribute(ld, e, ptr)) {
-- if (!strcmp(a, "dNSTTL")) {
-- vals = ldap_get_values(ld, e, a);
-- ttl = atoi(vals[0]);
-- ldap_value_free(vals);
-- } else if (!strcmp(a, "relativeDomainName")) {
-- vals = ldap_get_values(ld, e, a);
-- name = isc_mem_strdup(ns_g_mctx, vals[0]);
-- ldap_value_free(vals);
-- }
-- ldap_memfree(a);
-- }
--
-- if (name == NULL)
-- continue;
--
-- for (a = ldap_first_attribute(ld, e, &ptr); a != NULL;
-- a = ldap_next_attribute(ld, e, ptr)) {
-- char *s;
--
-- for (s = a; *s; s++)
-- *s = toupper(*s);
-- s = strstr(a, "RECORD");
-- if ((s == NULL) || (s == a)
-- || (s - a >= (signed int)sizeof(type))) {
-- ldap_memfree(a);
-- continue;
-- }
-- strncpy(type, a, s - a);
-- type[s - a] = '\0';
-- vals = ldap_get_values(ld, e, a);
-- for (i=0; vals[i] != NULL; i++) {
-- result = dns_sdb_putnamedrr(allnodes, name,
-- type, ttl, vals[i]);
-- if (result != ISC_R_SUCCESS) {
-- ldap_value_free(vals);
-- ldap_memfree(a);
-- isc_mem_free(ns_g_mctx, name);
-- result = ISC_R_FAILURE;
-- goto exit;
-- }
-- }
-- ldap_value_free(vals);
-- ldap_memfree(a);
-- }
-- isc_mem_free(ns_g_mctx, name);
-- }
--
-- exit:
-- ldap_msgfree(res);
-- return (result);
--}
--
--static dns_sdbmethods_t ldapdb_methods = {
-- ldapdb_lookup,
-- NULL, /* authority */
-- ldapdb_allnodes,
-- ldapdb_create,
-- ldapdb_destroy
--};
--
--/* Wrapper around dns_sdb_register() */
--isc_result_t
--ldapdb_init(void) {
-- unsigned int flags =
-- DNS_SDBFLAG_RELATIVEOWNER |
-- DNS_SDBFLAG_RELATIVERDATA |
-- DNS_SDBFLAG_THREADSAFE;
--
-- ldapdb_lock(0);
-- return (dns_sdb_register("ldap", &ldapdb_methods, NULL, flags,
-- ns_g_mctx, &ldapdb));
--}
--
--/* Wrapper around dns_sdb_unregister() */
--void
--ldapdb_clear(void) {
-- if (ldapdb != NULL) {
-- /* clean up thread data */
-- ldapdb_getconn(NULL);
-- dns_sdb_unregister(&ldapdb);
-- }
--}
+++ /dev/null
--#include <isc/types.h>
--
--isc_result_t ldapdb_init(void);
--
--void ldapdb_clear(void);
--
+++ /dev/null
--.TH zone2ldap 1 "8 March 2001"
--.SH NAME
--zone2ldap /- Load BIND 9 Zone files into LDAP Directory
--.SH SYNOPSIS
--zone2ldap [-D Bind DN] [-w Bind Password] [-b Base DN] [-z Zone] [-f Zone File ] [-h Ldap Host] [-cd] [-v]
--.SH DESCRIPTION
--zone2ldap will parse a complete BIND 9 format DNS zone file, and load
--the contents into an LDAP directory, for use with the LDAP sdb back-end.
--
--If the zone already exists, zone2ldap will exit succesfully. If the zone does not exists, or
--partially exists, zone2ldap will attempt to add all/missing zone data.
--
--.SS Options
--.TP
---b
--LDAP Base DN. LDAP systems require a "base dn", which is generally considered the LDAP Directory root.
--If the zone you are loading is different from the base, then you will need to tell zone2ldap what your LDAP
--base is.
--.TP
---v
--Print version information, and immediatly exit.
--.TP
---f
--Zone file. Bind 9.1 compatible zone file, from which zone information will be read.
--.TP
---d
--Dump debug information to standard out.
--.TP
---w
--LDAP Bind password, corresponding the the value of "-b".
--.TP
---h
--LDAP Directory host. This is the hostname of the LDAP system you wish to store zone information on.
--An LDAP server should be listening on port 389 of the target system. This may be ommited, and will default
--to "localhost".
--.TP
---c
--This will create the zone portion of the DN you are importing. For instance, if you are creating a domain.com zone,
--zone2ldap should first create "dc=domain,dc=com". This is useful if you are creating multiple domains.
--.TP
---z
--This is the name of the zone specified in the SOA record.
--.SH EXAMPLES
--Following are brief examples of how to import a zone file into your LDAP DIT.
--.SS Loading zone domain.com, with an LDAP Base DN of dc=domain,dc=com
--zone2ldap -D dc=root -w secret -h localhost -z domain.com -f domain.com.zone
--
--This will add Resource Records into an ALREADY EXISTING dc=domain,dc=com. The final SOA DN in this case, will be
--dc=@,dc=domain,dc=com
--
--.SS Loading customer.com, if your LDAP Base DN is dc=provider,dc=net.
--zone2ldap -D dc=root -w secret -h localhost -z customer.com -b dc=provider,dc=net -f customer.com.zone -c
--
--This will create dc=customer,dc=com under dc=provider,dc=net, and add all necessary Resource Records. The final
--root DN to the SOA will be dc=@,dc=customer,dc=com,dc=provider,dc=net.
--
--.SH "SEE ALSO"
--named(8) ldap(3)
--http://www.venaas.no/ldap/bind-sdb/
--.SH "BUGS"
--Send all bug reports to Jeff McNeil <jeff@snapcase.g-rock.net>
--.SH AUTHOR
--Jeff McNeil <jeff@snapcase.g-rock.net>
--
+++ /dev/null
--/*
-- * Copyright (C) 2001 Jeff McNeil <jeff@snapcase.g-rock.net>
-- *
-- * Permission to use, copy, modify, and distribute this software for any
-- * purpose with or without fee is hereby granted, provided that the above
-- * copyright notice and this permission notice appear in all copies.
-- *
-- * Change Log
-- *
-- * Tue May 1 19:19:54 EDT 2001 - Jeff McNeil
-- * Update to objectClass code, and add_to_rr_list function
-- * (I need to rename that) to support the dNSZone schema,
-- * ditched dNSDomain2 schema support. Version 0.3-ALPHA
-- */
--
--#include <errno.h>
--#include <string.h>
--#include <stdlib.h>
--#include <unistd.h>
--#include <getopt.h>
--
--#include <isc/buffer.h>
--#include <isc/mem.h>
--#include <isc/print.h>
--#include <isc/result.h>
--
--#include <dns/db.h>
--#include <dns/dbiterator.h>
--#include <dns/fixedname.h>
--#include <dns/name.h>
--#include <dns/rdata.h>
--#include <dns/rdataset.h>
--#include <dns/rdatasetiter.h>
--#include <dns/result.h>
--#include <dns/rdatatype.h>
--
--#include <ldap.h>
--
--#define DNS_OBJECT 6
--#define DNS_TOP 2
--
--#define VERSION "0.4-ALPHA"
--
--#define NO_SPEC 0
--#define WI_SPEC 1
--
--/* Global Zone Pointer */
--char *gbl_zone = NULL;
--
--typedef struct LDAP_INFO
--{
-- char *dn;
-- LDAPMod **attrs;
-- struct LDAP_INFO *next;
-- int attrcnt;
--}
--ldap_info;
--
--/* usage Info */
--void usage ();
--
--/* Add to the ldap dit */
--void add_ldap_values (ldap_info * ldinfo);
--
--/* Init an ldap connection */
--void init_ldap_conn ();
--
--/* Ldap error checking */
--void ldap_result_check (char *msg, char *dn, int err);
--
--/* Put a hostname into a char ** array */
--char **hostname_to_dn_list (char *hostname, char *zone, unsigned int flags);
--
--/* Find out how many items are in a char ** array */
--int get_attr_list_size (char **tmp);
--
--/* Get a DN */
--char *build_dn_from_dc_list (char **dc_list, unsigned int ttl, int flag);
--
--/* Add to RR list */
--void add_to_rr_list (char *dn, char *name, char *type, char *data,
-- unsigned int ttl, unsigned int flags);
--
--/* Error checking */
--void isc_result_check (isc_result_t res, char *errorstr);
--
--/* Generate LDIF Format files */
--void generate_ldap (dns_name_t * dnsname, dns_rdata_t * rdata,
-- unsigned int ttl);
--
--/* head pointer to the list */
--ldap_info *ldap_info_base = NULL;
--
--char *argzone, *ldapbase, *binddn, *bindpw = NULL;
--char *ldapsystem = "localhost";
--static char *objectClasses[] =
-- { "top", "dNSZone", NULL };
--static char *topObjectClasses[] = { "top", NULL };
--LDAP *conn;
--unsigned int debug = 0;
--
--#ifdef DEBUG
--debug = 1;
--#endif
--
--int
--main (int *argc, char **argv)
--{
-- isc_mem_t *isc_ctx = NULL;
-- isc_result_t result;
-- char *basedn;
-- ldap_info *tmp;
-- LDAPMod *base_attrs[2];
-- LDAPMod base;
-- isc_buffer_t buff;
-- char *zonefile;
-- char fullbasedn[1024];
-- char *ctmp;
-- dns_fixedname_t fixedzone, fixedname;
-- dns_rdataset_t rdataset;
-- char **dc_list;
-- dns_rdata_t rdata = DNS_RDATA_INIT;
-- dns_rdatasetiter_t *riter;
-- dns_name_t *zone, *name;
-- dns_db_t *db = NULL;
-- dns_dbiterator_t *dbit = NULL;
-- dns_dbnode_t *node;
-- extern char *optarg;
-- extern int optind, opterr, optopt;
-- int create_base = 0;
-- int topt;
--
-- if ((int) argc < 2)
-- {
-- usage ();
-- exit (-1);
-- }
--
-- while ((topt = getopt ((int) argc, argv, "D:w:b:z:f:h:?dcv")) != -1)
-- {
-- switch (topt)
-- {
-- case 'v':
-- printf("%s\n", VERSION);
-- exit(0);
-- case 'c':
-- create_base++;
-- break;
-- case 'd':
-- debug++;
-- break;
-- case 'D':
-- binddn = strdup (optarg);
-- break;
-- case 'w':
-- bindpw = strdup (optarg);
-- break;
-- case 'b':
-- ldapbase = strdup (optarg);
-- break;
-- case 'z':
-- argzone = strdup (optarg);
-- // We wipe argzone all to hell when we parse it for the DN */
-- gbl_zone = strdup(argzone);
-- break;
-- case 'f':
-- zonefile = strdup (optarg);
-- break;
-- case 'h':
-- ldapsystem = strdup (optarg);
-- break;
-- case '?':
-- default:
-- usage ();
-- exit (0);
-- }
-- }
--
-- if ((argzone == NULL) || (zonefile == NULL))
-- {
-- usage ();
-- exit (-1);
-- }
--
-- if (debug)
-- printf ("Initializing ISC Routines, parsing zone file\n");
--
-- result = isc_mem_create (0, 0, &isc_ctx);
-- isc_result_check (result, "isc_mem_create");
--
-- isc_buffer_init (&buff, argzone, strlen (argzone));
-- isc_buffer_add (&buff, strlen (argzone));
-- dns_fixedname_init (&fixedzone);
-- zone = dns_fixedname_name (&fixedzone);
-- result = dns_name_fromtext (zone, &buff, dns_rootname, ISC_FALSE, NULL);
-- isc_result_check (result, "dns_name_fromtext");
--
-- result =
-- dns_db_create (isc_ctx, "rbt", zone, dns_dbtype_zone, dns_rdataclass_in,
-- 0, NULL, &db);
-- isc_result_check (result, "dns_db_create");
--
-- result = dns_db_load (db, zonefile);
-- isc_result_check (result, "Check Zone Syntax: dns_db_load");
--
-- result = dns_db_createiterator (db, ISC_FALSE, &dbit);
-- isc_result_check (result, "dns_db_createiterator");
--
-- result = dns_dbiterator_first (dbit);
-- isc_result_check (result, "dns_dbiterator_first");
--
-- dns_fixedname_init (&fixedname);
-- name = dns_fixedname_name (&fixedname);
-- dns_rdataset_init (&rdataset);
-- dns_rdata_init (&rdata);
--
-- while (result == ISC_R_SUCCESS)
-- {
-- node = NULL;
-- result = dns_dbiterator_current (dbit, &node, name);
--
-- if (result == ISC_R_NOMORE)
-- break;
--
-- isc_result_check (result, "dns_dbiterator_current");
--
-- riter = NULL;
-- result = dns_db_allrdatasets (db, node, NULL, 0, &riter);
-- isc_result_check (result, "dns_db_allrdatasets");
--
-- result = dns_rdatasetiter_first (riter);
-- //isc_result_check(result, "dns_rdatasetiter_first");
--
-- while (result == ISC_R_SUCCESS)
-- {
-- dns_rdatasetiter_current (riter, &rdataset);
-- result = dns_rdataset_first (&rdataset);
-- isc_result_check (result, "dns_rdatasetiter_current");
--
-- while (result == ISC_R_SUCCESS)
-- {
-- dns_rdataset_current (&rdataset, &rdata);
-- generate_ldap (name, &rdata, rdataset.ttl);
-- dns_rdata_reset (&rdata);
-- result = dns_rdataset_next (&rdataset);
-- }
-- dns_rdataset_disassociate (&rdataset);
-- result = dns_rdatasetiter_next (riter);
--
-- }
-- dns_rdatasetiter_destroy (&riter);
-- result = dns_dbiterator_next (dbit);
--
-- }
--
-- /* Initialize the LDAP Connection */
-- if (debug)
-- printf ("Initializing LDAP Connection to %s as %s\n", ldapsystem, binddn);
--
-- init_ldap_conn ();
--
-- if (create_base)
-- {
-- if (debug)
-- printf ("Creating base zone DN %s\n", argzone);
--
-- dc_list = hostname_to_dn_list (argzone, argzone, DNS_TOP);
-- basedn = build_dn_from_dc_list (dc_list, 0, NO_SPEC);
--
-- for (ctmp = &basedn[strlen (basedn)]; ctmp >= &basedn[0]; ctmp--)
-- {
-- if ((*ctmp == ',') || (ctmp == &basedn[0]))
-- {
-- base.mod_op = LDAP_MOD_ADD;
-- base.mod_type = "objectClass";
-- base.mod_values = topObjectClasses;
-- base_attrs[0] = &base;
-- base_attrs[1] = NULL;
--
-- if (ldapbase)
-- {
-- if (ctmp != &basedn[0])
-- sprintf (fullbasedn, "%s,%s", ctmp + 1, ldapbase);
-- else
-- sprintf (fullbasedn, "%s,%s", ctmp, ldapbase);
--
-- }
-- else
-- {
-- if (ctmp != &basedn[0])
-- sprintf (fullbasedn, "%s", ctmp + 1);
-- else
-- sprintf (fullbasedn, "%s", ctmp);
-- }
-- result = ldap_add_s (conn, fullbasedn, base_attrs);
-- ldap_result_check ("intial ldap_add_s", fullbasedn, result);
-- }
--
-- }
-- }
-- else
-- {
-- if (debug)
-- printf ("Skipping zone base dn creation for %s\n", argzone);
-- }
--
-- for (tmp = ldap_info_base; tmp != NULL; tmp = tmp->next)
-- {
--
-- if (debug)
-- printf ("Adding DN: %s\n", tmp->dn);
--
-- add_ldap_values (tmp);
-- }
--
--if (debug)
-- printf("Operation Complete.\n");
--
-- return 0;
--}
--
--
--/* Check the status of an isc_result_t after any isc routines.
-- * I should probably rename this function, as not to cause any
-- * confusion with the isc* routines. Will exit on error. */
--void
--isc_result_check (isc_result_t res, char *errorstr)
--{
-- if (res != ISC_R_SUCCESS)
-- {
-- fprintf (stderr, " %s: %s\n", errorstr, isc_result_totext (res));
-- exit (-1);
-- }
--}
--
--
--/* Takes DNS information, in bind data structure format, and adds textual
-- * zone information to the LDAP run queue. */
--void
--generate_ldap (dns_name_t * dnsname, dns_rdata_t * rdata, unsigned int ttl)
--{
-- unsigned char name[DNS_NAME_MAXTEXT + 1];
-- unsigned int len;
-- unsigned char type[20];
-- unsigned char data[2048];
-- char **dc_list;
-- char *dn;
--
-- isc_buffer_t buff;
-- isc_result_t result;
--
-- isc_buffer_init (&buff, name, sizeof (name));
-- result = dns_name_totext (dnsname, ISC_TRUE, &buff);
-- isc_result_check (result, "dns_name_totext");
-- name[isc_buffer_usedlength (&buff)] = 0;
--
-- isc_buffer_init (&buff, type, sizeof (type));
-- result = dns_rdatatype_totext (rdata->type, &buff);
-- isc_result_check (result, "dns_rdatatype_totext");
-- type[isc_buffer_usedlength (&buff)] = 0;
--
-- isc_buffer_init (&buff, data, sizeof (data));
-- result = dns_rdata_totext (rdata, NULL, &buff);
-- isc_result_check (result, "dns_rdata_totext");
-- data[isc_buffer_usedlength (&buff)] = 0;
--
-- dc_list = hostname_to_dn_list (name, argzone, DNS_OBJECT);
-- len = (get_attr_list_size (dc_list) - 2);
-- dn = build_dn_from_dc_list (dc_list, ttl, WI_SPEC);
--
-- if (debug)
-- printf ("Adding %s (%s %s) to run queue list.\n", dn, type, data);
--
-- add_to_rr_list (dn, dc_list[len], type, data, ttl, DNS_OBJECT);
--}
--
--
--/* Locate an item in the Run queue linked list, by DN. Used by functions
-- * which add items to the run queue.
-- */
--ldap_info *
--locate_by_dn (char *dn)
--{
-- ldap_info *tmp;
-- for (tmp = ldap_info_base; tmp != (ldap_info *) NULL; tmp = tmp->next)
-- {
-- if (!strncmp (tmp->dn, dn, strlen (dn)))
-- return tmp;
-- }
-- return (ldap_info *) NULL;
--}
--
--
--
--/* Take textual zone data, and add to the LDAP Run queue. This works like so:
-- * If locate_by_dn does not return, alloc a new ldap_info structure, and then
-- * calloc a LDAPMod array, fill in the default "everyone needs this" information,
-- * including object classes and dc's. If it locate_by_dn does return, then we'll
-- * realloc for more LDAPMod structs, and appened the new data. If an LDAPMod exists
-- * for the parameter we're adding, then we'll realloc the mod_values array, and
-- * add the new value to the existing LDAPMod. Finnaly, it assures linkage exists
-- * within the Run queue linked ilst*/
--
--void
--add_to_rr_list (char *dn, char *name, char *type,
-- char *data, unsigned int ttl, unsigned int flags)
--{
-- int i;
-- int x;
-- ldap_info *tmp;
-- int attrlist;
-- char ldap_type_buffer[128];
-- char charttl[64];
--
--
-- if ((tmp = locate_by_dn (dn)) == NULL)
-- {
--
-- /* There wasn't one already there, so we need to allocate a new one,
-- * and stick it on the list */
--
-- tmp = (ldap_info *) malloc (sizeof (ldap_info));
-- if (tmp == (ldap_info *) NULL)
-- {
-- fprintf (stderr, "malloc: %s\n", strerror (errno));
-- ldap_unbind_s (conn);
-- exit (-1);
-- }
--
-- tmp->dn = strdup (dn);
-- tmp->attrs = (LDAPMod **) calloc (sizeof (LDAPMod *), flags);
-- if (tmp->attrs == (LDAPMod **) NULL)
-- {
-- fprintf (stderr, "calloc: %s\n", strerror (errno));
-- ldap_unbind_s (conn);
-- exit (-1);
-- }
--
-- for (i = 0; i < flags; i++)
-- {
-- tmp->attrs[i] = (LDAPMod *) malloc (sizeof (LDAPMod));
-- if (tmp->attrs[i] == (LDAPMod *) NULL)
-- {
-- fprintf (stderr, "malloc: %s\n", strerror (errno));
-- exit (-1);
-- }
-- }
-- tmp->attrs[0]->mod_op = LDAP_MOD_ADD;
-- tmp->attrs[0]->mod_type = "objectClass";
--
-- if (flags == DNS_OBJECT)
-- tmp->attrs[0]->mod_values = objectClasses;
-- else
-- {
-- tmp->attrs[0]->mod_values = topObjectClasses;
-- tmp->attrs[1] = NULL;
-- tmp->attrcnt = 2;
-- tmp->next = ldap_info_base;
-- ldap_info_base = tmp;
-- return;
-- }
--
-- tmp->attrs[1]->mod_op = LDAP_MOD_ADD;
-- tmp->attrs[1]->mod_type = "relativeDomainName";
-- tmp->attrs[1]->mod_values = (char **) calloc (sizeof (char *), 2);
--
-- if (tmp->attrs[1]->mod_values == (char **)NULL)
-- exit(-1);
--
-- tmp->attrs[1]->mod_values[0] = strdup (name);
-- tmp->attrs[1]->mod_values[2] = NULL;
--
-- sprintf (ldap_type_buffer, "%sRecord", type);
--
-- tmp->attrs[2]->mod_op = LDAP_MOD_ADD;
-- tmp->attrs[2]->mod_type = strdup (ldap_type_buffer);
-- tmp->attrs[2]->mod_values = (char **) calloc (sizeof (char *), 2);
--
-- if (tmp->attrs[2]->mod_values == (char **)NULL)
-- exit(-1);
--
-- tmp->attrs[2]->mod_values[0] = strdup (data);
-- tmp->attrs[2]->mod_values[1] = NULL;
--
-- tmp->attrs[3]->mod_op = LDAP_MOD_ADD;
-- tmp->attrs[3]->mod_type = "dNSTTL";
-- tmp->attrs[3]->mod_values = (char **) calloc (sizeof (char *), 2);
--
-- if (tmp->attrs[3]->mod_values == (char **)NULL)
-- exit(-1);
--
-- sprintf (charttl, "%d", ttl);
-- tmp->attrs[3]->mod_values[0] = strdup (charttl);
-- tmp->attrs[3]->mod_values[1] = NULL;
--
-- tmp->attrs[4]->mod_op = LDAP_MOD_ADD;
-- tmp->attrs[4]->mod_type = "zoneName";
-- tmp->attrs[4]->mod_values = (char **)calloc(sizeof(char *), 2);
-- tmp->attrs[4]->mod_values[0] = gbl_zone;
-- tmp->attrs[4]->mod_values[1] = NULL;
--
-- tmp->attrs[5] = NULL;
-- tmp->attrcnt = flags;
-- tmp->next = ldap_info_base;
-- ldap_info_base = tmp;
-- }
-- else
-- {
--
-- for (i = 0; tmp->attrs[i] != NULL; i++)
-- {
-- sprintf (ldap_type_buffer, "%sRecord", type);
-- if (!strncmp
-- (ldap_type_buffer, tmp->attrs[i]->mod_type,
-- strlen (tmp->attrs[i]->mod_type)))
-- {
-- attrlist = get_attr_list_size (tmp->attrs[i]->mod_values);
-- tmp->attrs[i]->mod_values =
-- (char **) realloc (tmp->attrs[i]->mod_values,
-- sizeof (char *) * (attrlist + 1));
--
-- if (tmp->attrs[i]->mod_values == (char **) NULL)
-- {
-- fprintf (stderr, "realloc: %s\n", strerror (errno));
-- ldap_unbind_s (conn);
-- exit (-1);
-- }
-- for (x = 0; tmp->attrs[i]->mod_values[x] != NULL; x++);
--
-- tmp->attrs[i]->mod_values[x] = strdup (data);
-- tmp->attrs[i]->mod_values[x + 1] = NULL;
-- return;
-- }
-- }
-- tmp->attrs =
-- (LDAPMod **) realloc (tmp->attrs,
-- sizeof (LDAPMod) * ++(tmp->attrcnt));
-- if (tmp->attrs == NULL)
-- {
-- fprintf (stderr, "realloc: %s\n", strerror (errno));
-- ldap_unbind_s (conn);
-- exit (-1);
-- }
--
-- for (x = 0; tmp->attrs[x] != NULL; x++);
-- tmp->attrs[x] = (LDAPMod *) malloc (sizeof (LDAPMod));
-- tmp->attrs[x]->mod_op = LDAP_MOD_ADD;
-- tmp->attrs[x]->mod_type = strdup (ldap_type_buffer);
-- tmp->attrs[x]->mod_values = (char **) calloc (sizeof (char *), 2);
-- tmp->attrs[x]->mod_values[0] = strdup (data);
-- tmp->attrs[x]->mod_values[1] = NULL;
-- tmp->attrs[x + 1] = NULL;
-- }
--}
--
--/* Size of a mod_values list, plus the terminating NULL field. */
--int
--get_attr_list_size (char **tmp)
--{
-- int i = 0;
-- char **ftmp = tmp;
-- while (*ftmp != NULL)
-- {
-- i++;
-- ftmp++;
-- }
-- return ++i;
--}
--
--
--/* take a hostname, and split it into a char ** of the dc parts,
-- * example, we have www.domain.com, this function will return:
-- * array[0] = com, array[1] = domain, array[2] = www. */
--
--char **
--hostname_to_dn_list (char *hostname, char *zone, unsigned int flags)
--{
-- char *tmp;
-- static char *dn_buffer[64];
-- int i = 0;
-- char *zname;
-- char *hnamebuff;
--
-- zname = strdup (hostname);
--
-- if (flags == DNS_OBJECT)
-- {
--
-- if (strlen (zname) != strlen (zone))
-- {
-- tmp = &zname[strlen (zname) - strlen (zone)];
-- *--tmp = '\0';
-- hnamebuff = strdup (zname);
-- zname = ++tmp;
-- }
-- else
-- hnamebuff = "@";
-- }
-- else
-- {
-- zname = zone;
-- hnamebuff = NULL;
-- }
--
-- for (tmp = strrchr (zname, '.'); tmp != (char *) 0;
-- tmp = strrchr (zname, '.'))
-- {
-- *tmp++ = '\0';
-- dn_buffer[i++] = tmp;
-- }
-- dn_buffer[i++] = zname;
-- dn_buffer[i++] = hnamebuff;
-- dn_buffer[i] = NULL;
--
-- return dn_buffer;
--}
--
--
--/* build an sdb compatible LDAP DN from a "dc_list" (char **).
-- * will append dNSTTL information to each RR Record, with the
-- * exception of "@"/SOA. */
--
--char *
--build_dn_from_dc_list (char **dc_list, unsigned int ttl, int flag)
--{
-- int size;
-- int x;
-- static char dn[1024];
-- char tmp[128];
--
-- bzero (tmp, sizeof (tmp));
-- bzero (dn, sizeof (dn));
-- size = get_attr_list_size (dc_list);
-- for (x = size - 2; x > 0; x--)
-- {
-- if (flag == WI_SPEC)
-- {
-- if (x == (size - 2) && (strncmp (dc_list[x], "@", 1) == 0) && (ttl))
-- sprintf (tmp, "relativeDomainName=%s + dNSTTL=%d,", dc_list[x], ttl);
-- else if (x == (size - 2))
-- sprintf(tmp, "relativeDomainName=%s,",dc_list[x]);
-- else
-- sprintf(tmp,"dc=%s,", dc_list[x]);
-- }
-- else
-- {
-- sprintf(tmp, "dc=%s,", dc_list[x]);
-- }
--
--
-- strncat (dn, tmp, sizeof (dn) - strlen (dn));
-- }
--
-- sprintf (tmp, "dc=%s", dc_list[0]);
-- strncat (dn, tmp, sizeof (dn) - strlen (dn));
--
-- fflush(NULL);
-- return dn;
--}
--
--
--/* Initialize LDAP Conn */
--void
--init_ldap_conn ()
--{
-- int result;
-- conn = ldap_open (ldapsystem, LDAP_PORT);
-- if (conn == NULL)
-- {
-- fprintf (stderr, "Error opening Ldap connection: %s\n",
-- strerror (errno));
-- exit (-1);
-- }
--
-- result = ldap_simple_bind_s (conn, binddn, bindpw);
-- ldap_result_check ("ldap_simple_bind_s", "LDAP Bind", result);
--}
--
--/* Like isc_result_check, only for LDAP */
--void
--ldap_result_check (char *msg, char *dn, int err)
--{
-- if ((err != LDAP_SUCCESS) && (err != LDAP_ALREADY_EXISTS))
-- {
-- fprintf(stderr, "Error while adding %s (%s):\n",
-- dn, msg);
-- ldap_perror (conn, dn);
-- ldap_unbind_s (conn);
-- exit (-1);
-- }
--}
--
--
--
--/* For running the ldap_info run queue. */
--void
--add_ldap_values (ldap_info * ldinfo)
--{
-- int result;
-- char dnbuffer[1024];
--
--
-- if (ldapbase != NULL)
-- sprintf (dnbuffer, "%s,%s", ldinfo->dn, ldapbase);
-- else
-- sprintf (dnbuffer, "%s", ldinfo->dn);
--
-- result = ldap_add_s (conn, dnbuffer, ldinfo->attrs);
-- ldap_result_check ("ldap_add_s", dnbuffer, result);
--}
--
--
--
--
--/* name says it all */
--void
--usage ()
--{
-- fprintf (stderr,
-- "zone2ldap -D [BIND DN] -w [BIND PASSWORD] -b [BASE DN] -z [ZONE] -f [ZONE FILE] -h [LDAP HOST]
-- [-c Create LDAP Base structure][-d Debug Output (lots !)] \n ");}
+++ /dev/null
--/*
-- * Copyright (C) 2000, 2001 Internet Software Consortium.
-- *
-- * Permission to use, copy, modify, and distribute this software for any
-- * purpose with or without fee is hereby granted, provided that the above
-- * copyright notice and this permission notice appear in all copies.
-- *
-- * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
-- * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
-- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
-- * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
-- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
-- * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
-- * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
-- * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-- */
--
--/* $Id: pgsqldb.c,v 1.12 2001/02/28 23:42:37 bwelling Exp $ */
--
--#include <config.h>
--
--#include <stdio.h>
--#include <string.h>
--#include <stdlib.h>
--
--#include <pgsql/libpq-fe.h>
--
--#include <isc/mem.h>
--#include <isc/print.h>
--#include <isc/result.h>
--#include <isc/util.h>
--
--#include <dns/sdb.h>
--#include <dns/result.h>
--
--#include <named/globals.h>
--
--#include "pgsqldb.h"
--
--/*
-- * A simple database driver that interfaces to a PostgreSQL database. This
-- * is not complete, and not designed for general use. It opens one
-- * connection to the database per zone, which is inefficient. It also may
-- * not handle quoting correctly.
-- *
-- * The table must contain the fields "name", "rdtype", and "rdata", and
-- * is expected to contain a properly constructed zone. The program "zonetodb"
-- * creates such a table.
-- */
--
--static dns_sdbimplementation_t *pgsqldb = NULL;
--
--struct dbinfo {
-- PGconn *conn;
-- char *database;
-- char *table;
-- char *host;
-- char *user;
-- char *passwd;
--};
--
--static void
--pgsqldb_destroy(const char *zone, void *driverdata, void **dbdata);
--
--/*
-- * Canonicalize a string before writing it to the database.
-- * "dest" must be an array of at least size 2*strlen(source) + 1.
-- */
--static void
--quotestring(const char *source, char *dest) {
-- while (*source != 0) {
-- if (*source == '\'')
-- *dest++ = '\'';
-- /* SQL doesn't treat \ as special, but PostgreSQL does */
-- else if (*source == '\\')
-- *dest++ = '\\';
-- *dest++ = *source++;
-- }
-- *dest++ = 0;
--}
--
--/*
-- * Connect to the database.
-- */
--static isc_result_t
--db_connect(struct dbinfo *dbi) {
-- dbi->conn = PQsetdbLogin(dbi->host, NULL, NULL, NULL, dbi->database,
-- dbi->user, dbi->passwd);
--
-- if (PQstatus(dbi->conn) == CONNECTION_OK)
-- return (ISC_R_SUCCESS);
-- else
-- return (ISC_R_FAILURE);
--}
--
--/*
-- * Check to see if the connection is still valid. If not, attempt to
-- * reconnect.
-- */
--static isc_result_t
--maybe_reconnect(struct dbinfo *dbi) {
-- if (PQstatus(dbi->conn) == CONNECTION_OK)
-- return (ISC_R_SUCCESS);
--
-- return (db_connect(dbi));
--}
--
--/*
-- * This database operates on absolute names.
-- *
-- * Queries are converted into SQL queries and issued synchronously. Errors
-- * are handled really badly.
-- */
--static isc_result_t
--pgsqldb_lookup(const char *zone, const char *name, void *dbdata,
-- dns_sdblookup_t *lookup)
--{
-- isc_result_t result;
-- struct dbinfo *dbi = dbdata;
-- PGresult *res;
-- char str[1500];
-- char *canonname;
-- int i;
--
-- UNUSED(zone);
--
-- canonname = isc_mem_get(ns_g_mctx, strlen(name) * 2 + 1);
-- if (canonname == NULL)
-- return (ISC_R_NOMEMORY);
-- quotestring(name, canonname);
-- snprintf(str, sizeof(str),
-- "SELECT TTL,RDTYPE,RDATA FROM \"%s\" WHERE "
-- "lower(NAME) = lower('%s')", dbi->table, canonname);
-- isc_mem_put(ns_g_mctx, canonname, strlen(name) * 2 + 1);
--
-- result = maybe_reconnect(dbi);
-- if (result != ISC_R_SUCCESS)
-- return (result);
--
-- res = PQexec(dbi->conn, str);
-- if (!res || PQresultStatus(res) != PGRES_TUPLES_OK) {
-- PQclear(res);
-- return (ISC_R_FAILURE);
-- }
-- if (PQntuples(res) == 0) {
-- PQclear(res);
-- return (ISC_R_NOTFOUND);
-- }
--
-- for (i = 0; i < PQntuples(res); i++) {
-- char *ttlstr = PQgetvalue(res, i, 0);
-- char *type = PQgetvalue(res, i, 1);
-- char *data = PQgetvalue(res, i, 2);
-- dns_ttl_t ttl;
-- char *endp;
-- ttl = strtol(ttlstr, &endp, 10);
-- if (*endp != '\0') {
-- PQclear(res);
-- return (DNS_R_BADTTL);
-- }
-- result = dns_sdb_putrr(lookup, type, ttl, data);
-- if (result != ISC_R_SUCCESS) {
-- PQclear(res);
-- return (ISC_R_FAILURE);
-- }
-- }
--
-- PQclear(res);
-- return (ISC_R_SUCCESS);
--}
--
--/*
-- * Issue an SQL query to return all nodes in the database and fill the
-- * allnodes structure.
-- */
--static isc_result_t
--pgsqldb_allnodes(const char *zone, void *dbdata, dns_sdballnodes_t *allnodes) {
-- struct dbinfo *dbi = dbdata;
-- PGresult *res;
-- isc_result_t result;
-- char str[1500];
-- int i;
--
-- UNUSED(zone);
--
-- snprintf(str, sizeof(str),
-- "SELECT TTL,NAME,RDTYPE,RDATA FROM \"%s\" ORDER BY NAME",
-- dbi->table);
--
-- result = maybe_reconnect(dbi);
-- if (result != ISC_R_SUCCESS)
-- return (result);
--
-- res = PQexec(dbi->conn, str);
-- if (!res || PQresultStatus(res) != PGRES_TUPLES_OK ) {
-- PQclear(res);
-- return (ISC_R_FAILURE);
-- }
-- if (PQntuples(res) == 0) {
-- PQclear(res);
-- return (ISC_R_NOTFOUND);
-- }
--
-- for (i = 0; i < PQntuples(res); i++) {
-- char *ttlstr = PQgetvalue(res, i, 0);
-- char *name = PQgetvalue(res, i, 1);
-- char *type = PQgetvalue(res, i, 2);
-- char *data = PQgetvalue(res, i, 3);
-- dns_ttl_t ttl;
-- char *endp;
-- ttl = strtol(ttlstr, &endp, 10);
-- if (*endp != '\0') {
-- PQclear(res);
-- return (DNS_R_BADTTL);
-- }
-- result = dns_sdb_putnamedrr(allnodes, name, type, ttl, data);
-- if (result != ISC_R_SUCCESS) {
-- PQclear(res);
-- return (ISC_R_FAILURE);
-- }
-- }
--
-- PQclear(res);
-- return (ISC_R_SUCCESS);
--}
--
--/*
-- * Create a connection to the database and save any necessary information
-- * in dbdata.
-- *
-- * argv[0] is the name of the database
-- * argv[1] is the name of the table
-- * argv[2] (if present) is the name of the host to connect to
-- * argv[3] (if present) is the name of the user to connect as
-- * argv[4] (if present) is the name of the password to connect with
-- */
--static isc_result_t
--pgsqldb_create(const char *zone, int argc, char **argv,
-- void *driverdata, void **dbdata)
--{
-- struct dbinfo *dbi;
-- isc_result_t result;
--
-- UNUSED(zone);
-- UNUSED(driverdata);
--
-- if (argc < 2)
-- return (ISC_R_FAILURE);
--
-- dbi = isc_mem_get(ns_g_mctx, sizeof(struct dbinfo));
-- if (dbi == NULL)
-- return (ISC_R_NOMEMORY);
-- dbi->conn = NULL;
-- dbi->database = NULL;
-- dbi->table = NULL;
-- dbi->host = NULL;
-- dbi->user = NULL;
-- dbi->passwd = NULL;
--
--#define STRDUP_OR_FAIL(target, source) \
-- do { \
-- target = isc_mem_strdup(ns_g_mctx, source); \
-- if (target == NULL) { \
-- result = ISC_R_NOMEMORY; \
-- goto cleanup; \
-- } \
-- } while (0);
--
-- STRDUP_OR_FAIL(dbi->database, argv[0]);
-- STRDUP_OR_FAIL(dbi->table, argv[1]);
-- if (argc > 2)
-- STRDUP_OR_FAIL(dbi->host, argv[2]);
-- if (argc > 3)
-- STRDUP_OR_FAIL(dbi->user, argv[3]);
-- if (argc > 4)
-- STRDUP_OR_FAIL(dbi->passwd, argv[4]);
--
-- result = db_connect(dbi);
-- if (result != ISC_R_SUCCESS)
-- goto cleanup;
--
-- *dbdata = dbi;
-- return (ISC_R_SUCCESS);
--
-- cleanup:
-- pgsqldb_destroy(zone, driverdata, (void **)&dbi);
-- return (result);
--}
--
--/*
-- * Close the connection to the database.
-- */
--static void
--pgsqldb_destroy(const char *zone, void *driverdata, void **dbdata) {
-- struct dbinfo *dbi = *dbdata;
--
-- UNUSED(zone);
-- UNUSED(driverdata);
--
-- if (dbi->conn != NULL)
-- PQfinish(dbi->conn);
-- if (dbi->database != NULL)
-- isc_mem_free(ns_g_mctx, dbi->database);
-- if (dbi->table != NULL)
-- isc_mem_free(ns_g_mctx, dbi->table);
-- if (dbi->host != NULL)
-- isc_mem_free(ns_g_mctx, dbi->host);
-- if (dbi->user != NULL)
-- isc_mem_free(ns_g_mctx, dbi->user);
-- if (dbi->passwd != NULL)
-- isc_mem_free(ns_g_mctx, dbi->passwd);
-- if (dbi->database != NULL)
-- isc_mem_free(ns_g_mctx, dbi->database);
-- isc_mem_put(ns_g_mctx, dbi, sizeof(struct dbinfo));
--}
--
--/*
-- * Since the SQL database corresponds to a zone, the authority data should
-- * be returned by the lookup() function. Therefore the authority() function
-- * is NULL.
-- */
--static dns_sdbmethods_t pgsqldb_methods = {
-- pgsqldb_lookup,
-- NULL, /* authority */
-- pgsqldb_allnodes,
-- pgsqldb_create,
-- pgsqldb_destroy
--};
--
--/*
-- * Wrapper around dns_sdb_register().
-- */
--isc_result_t
--pgsqldb_init(void) {
-- unsigned int flags;
-- flags = 0;
-- return (dns_sdb_register("pgsql", &pgsqldb_methods, NULL, flags,
-- ns_g_mctx, &pgsqldb));
--}
--
--/*
-- * Wrapper around dns_sdb_unregister().
-- */
--void
--pgsqldb_clear(void) {
-- if (pgsqldb != NULL)
-- dns_sdb_unregister(&pgsqldb);
--}
+++ /dev/null
--/*
-- * Copyright (C) 2000, 2001 Internet Software Consortium.
-- *
-- * Permission to use, copy, modify, and distribute this software for any
-- * purpose with or without fee is hereby granted, provided that the above
-- * copyright notice and this permission notice appear in all copies.
-- *
-- * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
-- * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
-- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
-- * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
-- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
-- * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
-- * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
-- * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-- */
--
--/* $Id: pgsqldb.h,v 1.2 2001/01/09 21:46:27 bwelling Exp $ */
--
--#include <isc/types.h>
--
--isc_result_t pgsqldb_init(void);
--
--void pgsqldb_clear(void);
--
+++ /dev/null
--# Copyright (C) 2000, 2001 Internet Software Consortium.
--#
--# Permission to use, copy, modify, and distribute this software for any
--# purpose with or without fee is hereby granted, provided that the above
--# copyright notice and this permission notice appear in all copies.
--#
--# THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
--# DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
--# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
--# INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
--# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
--# FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
--# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
--# WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
--
--# $Id: lookup.tcl,v 1.7 2001/01/09 21:46:24 bwelling Exp $
--
--#
--# Sample lookup procedure for tcldb
--#
--# This lookup procedure defines zones with identical SOA, NS, and MX
--# records at the apex and a single A record that varies from zone to
--# zone at the name "www".
--#
--# Something like this could be used by a web hosting company to serve
--# a number of domains without needing to create a separate master file
--# for each domain. Instead, all per-zone data (in this case, a single
--# IP address) specified in the named.conf file like this:
--#
--# zone "a.com." { type master; database "tcl 10.0.0.42"; };
--# zone "b.com." { type master; database "tcl 10.0.0.99"; };
--#
--# Since the tcldb driver doesn't support zone transfers, there should
--# be at least two identically configured master servers. In the
--# example below, they are assumed to be called ns1.isp.nil and
--# ns2.isp.nil.
--#
--
--proc lookup {zone name} {
-- global dbargs
-- switch -- $name {
-- @ { return [list \
-- {SOA 86400 "ns1.isp.nil. hostmaster.isp.nil. \
-- 1 3600 1800 1814400 3600"} \
-- {NS 86400 "ns1.isp.nil."} \
-- {NS 86400 "ns2.isp.nil."} \
-- {MX 86400 "10 mail.isp.nil."} ] }
-- www { return [list [list A 3600 $dbargs($zone)] ] }
-- }
-- return NXDOMAIN
--}
+++ /dev/null
--/*
-- * Copyright (C) 2000, 2001 Internet Software Consortium.
-- *
-- * Permission to use, copy, modify, and distribute this software for any
-- * purpose with or without fee is hereby granted, provided that the above
-- * copyright notice and this permission notice appear in all copies.
-- *
-- * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
-- * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
-- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
-- * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
-- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
-- * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
-- * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
-- * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-- */
--
--/* $Id: tcldb.c,v 1.7 2001/01/09 21:46:28 bwelling Exp $ */
--
--/*
-- * A simple database driver that calls a Tcl procedure to define
-- * the contents of the DNS namespace. The procedure is loaded
-- * from the file lookup.tcl; look at the comments there for
-- * more information.
-- */
--
--#include <config.h>
--
--#include <string.h>
--#include <stdlib.h>
--#include <unistd.h>
--#include <sys/stat.h>
--
--#include <isc/mem.h>
--#include <isc/print.h>
--#include <isc/result.h>
--#include <isc/util.h>
--
--#include <dns/log.h>
--#include <dns/sdb.h>
--
--#include <named/globals.h>
--
--#include <tcl.h>
--
--#include <tcldb.h>
--
--#define CHECK(op) \
-- do { result = (op); \
-- if (result != ISC_R_SUCCESS) return (result); \
-- } while (0)
--
--typedef struct tcldb_driver {
-- isc_mem_t *mctx;
-- Tcl_Interp *interp;
--} tcldb_driver_t;
--
--static tcldb_driver_t *the_driver = NULL;
--
--static dns_sdbimplementation_t *tcldb = NULL;
--
--static isc_result_t
--tcldb_driver_create(isc_mem_t *mctx, tcldb_driver_t **driverp) {
-- int tclres;
-- isc_result_t result = ISC_R_SUCCESS;
-- tcldb_driver_t *driver = isc_mem_get(mctx, sizeof(tcldb_driver_t));
-- if (driver == NULL)
-- return (ISC_R_NOMEMORY);
-- driver->mctx = mctx;
-- driver->interp = Tcl_CreateInterp();
--
-- tclres = Tcl_EvalFile(driver->interp, (char *) "lookup.tcl");
-- if (tclres != TCL_OK) {
-- isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
-- DNS_LOGMODULE_SDB, ISC_LOG_ERROR,
-- "initializing tcldb: "
-- "loading 'lookup.tcl' failed: %s",
-- driver->interp->result);
-- result = ISC_R_FAILURE;
-- goto cleanup;
-- }
-- *driverp = driver;
-- return (ISC_R_SUCCESS);
--
-- cleanup:
-- isc_mem_put(mctx, driver, sizeof(tcldb_driver_t));
-- return (result);
--
--}
--
--static void
--tcldb_driver_destroy(tcldb_driver_t **driverp) {
-- tcldb_driver_t *driver = *driverp;
-- Tcl_DeleteInterp(driver->interp);
-- isc_mem_put(driver->mctx, driver, sizeof(tcldb_driver_t));
--}
--
--/*
-- * Perform a lookup, by invoking the Tcl procedure "lookup".
-- */
--static isc_result_t
--tcldb_lookup(const char *zone, const char *name, void *dbdata,
-- dns_sdblookup_t *lookup)
--{
-- isc_result_t result = ISC_R_SUCCESS;
-- int tclres;
-- int rrc; /* RR count */
-- char **rrv; /* RR vector */
-- int i;
-- char *cmdv[3];
-- char *cmd;
--
-- tcldb_driver_t *driver = (tcldb_driver_t *) dbdata;
--
-- cmdv[0] = "lookup";
-- cmdv[1] = zone;
-- cmdv[2] = name;
-- cmd = Tcl_Merge(3, cmdv);
-- tclres = Tcl_Eval(driver->interp, cmd);
-- Tcl_Free(cmd);
--
-- if (tclres != TCL_OK) {
-- isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
-- DNS_LOGMODULE_SDB, ISC_LOG_ERROR,
-- "zone '%s': tcl lookup function failed: %s",
-- zone, driver->interp->result);
-- return (ISC_R_FAILURE);
-- }
--
-- if (strcmp(driver->interp->result, "NXDOMAIN") == 0) {
-- result = ISC_R_NOTFOUND;
-- goto fail;
-- }
--
-- tclres = Tcl_SplitList(driver->interp, driver->interp->result,
-- &rrc, &rrv);
-- if (tclres != TCL_OK)
-- goto malformed;
--
-- for (i = 0; i < rrc; i++) {
-- isc_result_t tmpres;
-- int fieldc; /* Field count */
-- char **fieldv; /* Field vector */
-- tclres = Tcl_SplitList(driver->interp, rrv[i],
-- &fieldc, &fieldv);
-- if (tclres != TCL_OK) {
-- tmpres = ISC_R_FAILURE;
-- goto failrr;
-- }
-- if (fieldc != 3)
-- goto malformed;
-- tmpres = dns_sdb_putrr(lookup, fieldv[0], atoi(fieldv[1]),
-- fieldv[2]);
-- Tcl_Free((char *) fieldv);
-- failrr:
-- if (tmpres != ISC_R_SUCCESS)
-- result = tmpres;
-- }
-- Tcl_Free((char *) rrv);
-- if (result == ISC_R_SUCCESS)
-- return (result);
--
-- malformed:
-- isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
-- DNS_LOGMODULE_SDB, ISC_LOG_ERROR,
-- "zone '%s': "
-- "malformed return value from tcl lookup function: %s",
-- zone, driver->interp->result);
-- result = ISC_R_FAILURE;
-- fail:
-- return (result);
--}
--
--/*
-- * Set up per-zone state. In our case, the database arguments of the
-- * zone are collected into a Tcl list and assigned to an element of
-- * the global array "dbargs".
-- */
--static isc_result_t
--tcldb_create(const char *zone, int argc, char **argv,
-- void *driverdata, void **dbdata)
--{
-- tcldb_driver_t *driver = (tcldb_driver_t *) driverdata;
--
-- char *list = Tcl_Merge(argc, argv);
--
-- Tcl_SetVar2(driver->interp, (char *) "dbargs", (char *) zone, list, 0);
--
-- Tcl_Free(list);
--
-- *dbdata = driverdata;
--
-- return (ISC_R_SUCCESS);
--}
--
--/*
-- * This driver does not support zone transfer, so allnodes() is NULL.
-- */
--static dns_sdbmethods_t tcldb_methods = {
-- tcldb_lookup,
-- NULL, /* authority */
-- NULL, /* allnodes */
-- tcldb_create,
-- NULL /* destroy */
--};
--
--/*
-- * Initialize the tcldb driver.
-- */
--isc_result_t
--tcldb_init(void) {
-- isc_result_t result;
-- int flags = DNS_SDBFLAG_RELATIVEOWNER | DNS_SDBFLAG_RELATIVERDATA;
--
-- result = tcldb_driver_create(ns_g_mctx, &the_driver);
-- if (result != ISC_R_SUCCESS)
-- return (result);
--
-- return (dns_sdb_register("tcl", &tcldb_methods, the_driver, flags,
-- ns_g_mctx, &tcldb));
--}
--
--/*
-- * Wrapper around dns_sdb_unregister().
-- */
--void
--tcldb_clear(void) {
-- if (tcldb != NULL)
-- dns_sdb_unregister(&tcldb);
-- if (the_driver != NULL)
-- tcldb_driver_destroy(&the_driver);
--}
+++ /dev/null
--/*
-- * Copyright (C) 2000, 2001 Internet Software Consortium.
-- *
-- * Permission to use, copy, modify, and distribute this software for any
-- * purpose with or without fee is hereby granted, provided that the above
-- * copyright notice and this permission notice appear in all copies.
-- *
-- * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
-- * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
-- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
-- * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
-- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
-- * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
-- * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
-- * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-- */
--
--/* $Id: timedb.c,v 1.7 2001/01/09 21:46:30 bwelling Exp $ */
--
--/*
-- * A simple database driver that enables the server to return the
-- * current time in a DNS record.
-- */
--
--#include <config.h>
--
--#include <string.h>
--#include <stdio.h>
--#include <time.h>
--
--#include <isc/print.h>
--#include <isc/result.h>
--#include <isc/util.h>
--
--#include <dns/sdb.h>
--
--#include <named/globals.h>
--
--#include "timedb.h"
--
--static dns_sdbimplementation_t *timedb = NULL;
--
--/*
-- * This database operates on relative names.
-- *
-- * "time" and "@" return the time in a TXT record.
-- * "clock" is a CNAME to "time"
-- * "current" is a DNAME to "@" (try time.current.time)
-- */
--static isc_result_t
--timedb_lookup(const char *zone, const char *name, void *dbdata,
-- dns_sdblookup_t *lookup)
--{
-- isc_result_t result;
--
-- UNUSED(zone);
-- UNUSED(dbdata);
--
-- if (strcmp(name, "@") == 0 || strcmp(name, "time") == 0) {
-- time_t now = time(NULL);
-- char buf[100];
-- int n;
--
-- /*
-- * Call ctime to create the string, put it in quotes, and
-- * remove the trailing newline.
-- */
-- n = snprintf(buf, sizeof(buf), "\"%s", ctime(&now));
-- if (n < 0)
-- return (ISC_R_FAILURE);
-- buf[n - 1] = '\"';
-- result = dns_sdb_putrr(lookup, "txt", 1, buf);
-- if (result != ISC_R_SUCCESS)
-- return (ISC_R_FAILURE);
-- } else if (strcmp(name, "clock") == 0) {
-- result = dns_sdb_putrr(lookup, "cname", 1, "time");
-- if (result != ISC_R_SUCCESS)
-- return (ISC_R_FAILURE);
-- } else if (strcmp(name, "current") == 0) {
-- result = dns_sdb_putrr(lookup, "dname", 1, "@");
-- if (result != ISC_R_SUCCESS)
-- return (ISC_R_FAILURE);
-- } else
-- return (ISC_R_NOTFOUND);
--
-- return (ISC_R_SUCCESS);
--}
--
--/*
-- * lookup() does not return SOA or NS records, so authority() must be defined.
-- */
--static isc_result_t
--timedb_authority(const char *zone, void *dbdata, dns_sdblookup_t *lookup) {
-- isc_result_t result;
--
-- UNUSED(zone);
-- UNUSED(dbdata);
--
-- result = dns_sdb_putsoa(lookup, "localhost.", "root.localhost.", 0);
-- if (result != ISC_R_SUCCESS)
-- return (ISC_R_FAILURE);
--
-- result = dns_sdb_putrr(lookup, "ns", 86400, "ns1.localdomain.");
-- if (result != ISC_R_SUCCESS)
-- return (ISC_R_FAILURE);
-- result = dns_sdb_putrr(lookup, "ns", 86400, "ns2.localdomain.");
-- if (result != ISC_R_SUCCESS)
-- return (ISC_R_FAILURE);
--
-- return (ISC_R_SUCCESS);
--}
--
--/*
-- * This zone does not support zone transfer, so allnodes() is NULL. There
-- * is no database specific data, so create() and destroy() are NULL.
-- */
--static dns_sdbmethods_t timedb_methods = {
-- timedb_lookup,
-- timedb_authority,
-- NULL, /* allnodes */
-- NULL, /* create */
-- NULL /* destroy */
--};
--
--/*
-- * Wrapper around dns_sdb_register().
-- */
--isc_result_t
--timedb_init(void) {
-- unsigned int flags;
-- flags = DNS_SDBFLAG_RELATIVEOWNER | DNS_SDBFLAG_RELATIVERDATA;
-- return (dns_sdb_register("time", &timedb_methods, NULL, flags,
-- ns_g_mctx, &timedb));
--}
--
--/*
-- * Wrapper around dns_sdb_unregister().
-- */
--void
--timedb_clear(void) {
-- if (timedb != NULL)
-- dns_sdb_unregister(&timedb);
--}
+++ /dev/null
--/*
-- * Copyright (C) 2000, 2001 Internet Software Consortium.
-- *
-- * Permission to use, copy, modify, and distribute this software for any
-- * purpose with or without fee is hereby granted, provided that the above
-- * copyright notice and this permission notice appear in all copies.
-- *
-- * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
-- * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
-- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
-- * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
-- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
-- * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
-- * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
-- * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-- */
--
--/* $Id: timedb.h,v 1.2 2001/01/09 21:46:31 bwelling Exp $ */
--
--#include <isc/types.h>
--
--isc_result_t timedb_init(void);
--
--void timedb_clear(void);
--