diff -urN bind-9.2.3-orig/bin/named/Makefile.in bind-9.2.3/bin/named/Makefile.in --- bind-9.2.3-orig/bin/named/Makefile.in 2001-05-31 18:45:00.000000000 -0600 +++ bind-9.2.3/bin/named/Makefile.in 2003-11-16 14:52:51.000000000 -0700 @@ -26,10 +26,10 @@ # # Add database drivers here. # -DBDRIVER_OBJS = -DBDRIVER_SRCS = +DBDRIVER_OBJS = ldapdb.@O@ +DBDRIVER_SRCS = ldapdb.c DBDRIVER_INCLUDES = -DBDRIVER_LIBS = +DBDRIVER_LIBS = -lldap -llber -lresolv CINCLUDES = -I${srcdir}/include -I${srcdir}/unix/include \ ${LWRES_INCLUDES} ${DNS_INCLUDES} \ diff -urN bind-9.2.3-orig/bin/named/include/ldapdb.h bind-9.2.3/bin/named/include/ldapdb.h --- bind-9.2.3-orig/bin/named/include/ldapdb.h 1969-12-31 17:00:00.000000000 -0700 +++ bind-9.2.3/bin/named/include/ldapdb.h 2003-11-16 14:52:51.000000000 -0700 @@ -0,0 +1,6 @@ +#include + +isc_result_t ldapdb_init(void); + +void ldapdb_clear(void); + diff -urN bind-9.2.3-orig/bin/named/ldapdb.c bind-9.2.3/bin/named/ldapdb.c --- bind-9.2.3-orig/bin/named/ldapdb.c 1969-12-31 17:00:00.000000000 -0700 +++ bind-9.2.3/bin/named/ldapdb.c 2003-11-16 14:52:51.000000000 -0700 @@ -0,0 +1,667 @@ +/* + * ldapdb.c version 1.0-beta + * + * Copyright (C) 2002, 2004 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. + * + * Contributors: Jeremy C. McDermond + */ + +/* + * If you want to use TLS, uncomment the define below + */ +/* #define LDAPDB_TLS */ + +/* + * If you are using an old LDAP API uncomment the define below. Only do this + * if you know what you're doing or get compilation errors on ldap_memfree(). + * This also forces LDAPv2. + */ +/* #define LDAPDB_RFC1823API */ + +/* Using LDAPv3 by default, change this if you want v2 */ +#ifndef LDAPDB_LDAP_VERSION +#define LDAPDB_LDAP_VERSION 3 +#endif + +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include +#include "ldapdb.h" + +/* + * A simple database driver for LDAP + */ + +/* enough for name with 8 labels of max length */ +#define MAXNAMELEN 519 + +static dns_sdbimplementation_t *ldapdb = NULL; + +struct ldapdb_data { + char *hostport; + char *hostname; + int portno; + char *base; + int defaultttl; + char *filterall; + int filteralllen; + char *filterone; + int filteronelen; + char *filtername; + char *bindname; + char *bindpw; +#ifdef LDAPDB_TLS + int tls; +#endif +}; + +/* 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); + conndata->index = data->hostport; + conndata->size = strlen(data->hostport); + conndata->data = NULL; + ldapdb_insert((struct ldapdb_entry **)&threaddata->data, + conndata); + } + + return (LDAP **)&conndata->data; +} + +static void +ldapdb_bind(struct ldapdb_data *data, LDAP **ldp) +{ +#ifndef LDAPDB_RFC1823API + const int ver = LDAPDB_LDAP_VERSION; +#endif + + if (*ldp != NULL) + ldap_unbind(*ldp); + *ldp = ldap_open(data->hostname, data->portno); + if (*ldp == NULL) + return; + +#ifndef LDAPDB_RFC1823API + ldap_set_option(*ldp, LDAP_OPT_PROTOCOL_VERSION, &ver); +#endif + +#ifdef LDAPDB_TLS + if (data->tls) { + ldap_start_tls_s(*ldp, NULL, NULL); + } +#endif + + if (ldap_simple_bind_s(*ldp, data->bindname, data->bindpw) != LDAP_SUCCESS) { + ldap_unbind(*ldp); + *ldp = NULL; + } +} + +static isc_result_t +ldapdb_search(const char *zone, const char *name, void *dbdata, void *retdata) +{ + struct ldapdb_data *data = dbdata; + isc_result_t result = ISC_R_NOTFOUND; + LDAP **ldp; + LDAPMessage *res, *e; + char *fltr, *a, **vals = NULL, **names = NULL; + char type[64]; +#ifdef LDAPDB_RFC1823API + void *ptr; +#else + BerElement *ptr; +#endif + int i, j, errno, msgid; + + ldp = ldapdb_getconn(data); + if (ldp == NULL) + return (ISC_R_FAILURE); + if (*ldp == NULL) { + ldapdb_bind(data, ldp); + if (*ldp == NULL) { + isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, ISC_LOG_ERROR, + "LDAP sdb zone '%s': bind failed", zone); + return (ISC_R_FAILURE); + } + } + + if (name == NULL) { + fltr = data->filterall; + } else { + if (strlen(name) > MAXNAMELEN) { + isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, ISC_LOG_ERROR, + "LDAP sdb zone '%s': name %s too long", zone, name); + return (ISC_R_FAILURE); + } + sprintf(data->filtername, "%s))", name); + fltr = data->filterone; + } + + msgid = ldap_search(*ldp, data->base, LDAP_SCOPE_SUBTREE, fltr, NULL, 0); + if (msgid == -1) { + ldapdb_bind(data, ldp); + if (*ldp != NULL) + msgid = ldap_search(*ldp, data->base, LDAP_SCOPE_SUBTREE, fltr, NULL, 0); + } + + if (*ldp == NULL || msgid == -1) { + isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, ISC_LOG_ERROR, + "LDAP sdb zone '%s': search failed, filter %s", zone, fltr); + return (ISC_R_FAILURE); + } + + /* Get the records one by one as they arrive and return them to bind */ + while ((errno = ldap_result(*ldp, msgid, 0, NULL, &res)) != LDAP_RES_SEARCH_RESULT ) { + LDAP *ld = *ldp; + int ttl = data->defaultttl; + + /* not supporting continuation references at present */ + if (errno != LDAP_RES_SEARCH_ENTRY) { + isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, ISC_LOG_ERROR, + "LDAP sdb zone '%s': ldap_result returned %d", zone, errno); + ldap_msgfree(res); + return (ISC_R_FAILURE); + } + + /* only one entry per result message */ + e = ldap_first_entry(ld, res); + if (e == NULL) { + ldap_msgfree(res); + isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, ISC_LOG_ERROR, + "LDAP sdb zone '%s': ldap_first_entry failed", zone); + return (ISC_R_FAILURE); + } + + if (name == NULL) { + names = ldap_get_values(ld, e, "relativeDomainName"); + if (names == NULL) + continue; + } + + vals = ldap_get_values(ld, e, "dNSTTL"); + if (vals != NULL) { + ttl = atoi(vals[0]); + ldap_value_free(vals); + } + + 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))) { +#ifndef LDAPDB_RFC1823API + ldap_memfree(a); +#endif + continue; + } + + strncpy(type, a, s - a); + type[s - a] = '\0'; + vals = ldap_get_values(ld, e, a); + if (vals != NULL) { + for (i = 0; vals[i] != NULL; i++) { + if (name != NULL) { + result = dns_sdb_putrr(retdata, type, ttl, vals[i]); + } else { + for (j = 0; names[j] != NULL; j++) { + result = dns_sdb_putnamedrr(retdata, names[j], type, ttl, vals[i]); + if (result != ISC_R_SUCCESS) + break; + } + } +; if (result != ISC_R_SUCCESS) { + isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, ISC_LOG_ERROR, + "LDAP sdb zone '%s': dns_sdb_put... failed for %s", zone, vals[i]); + ldap_value_free(vals); +#ifndef LDAPDB_RFC1823API + ldap_memfree(a); + if (ptr != NULL) + ber_free(ptr, 0); +#endif + if (name == NULL) + ldap_value_free(names); + ldap_msgfree(res); + return (ISC_R_FAILURE); + } + } + ldap_value_free(vals); + } +#ifndef LDAPDB_RFC1823API + ldap_memfree(a); +#endif + } +#ifndef LDAPDB_RFC1823API + if (ptr != NULL) + ber_free(ptr, 0); +#endif + if (name == NULL) + ldap_value_free(names); + + /* free this result */ + ldap_msgfree(res); + } + + /* free final result */ + ldap_msgfree(res); + return (result); +} + + +/* callback routines */ +static isc_result_t +ldapdb_lookup(const char *zone, const char *name, void *dbdata, + dns_sdblookup_t *lookup) +{ + return ldapdb_search(zone, name, dbdata, lookup); +} + +static isc_result_t +ldapdb_allnodes(const char *zone, void *dbdata, + dns_sdballnodes_t *allnodes) +{ + return ldapdb_search(zone, NULL, dbdata, allnodes); +} + +static char * +unhex(char *in) +{ + static const char hexdigits[] = "0123456789abcdef"; + char *p, *s = in; + int d1, d2; + + while ((s = strchr(s, '%'))) { + if (!(s[1] && s[2])) + return NULL; + if ((p = strchr(hexdigits, tolower(s[1]))) == NULL) + return NULL; + d1 = p - hexdigits; + if ((p = strchr(hexdigits, tolower(s[2]))) == NULL) + return NULL; + d2 = p - hexdigits; + *s++ = d1 << 4 | d2; + memmove(s, s + 2, strlen(s) - 1); + } + return in; +} + +/* returns 0 for ok, -1 for bad syntax, -2 for unknown critical extension */ +static int +parseextensions(char *extensions, struct ldapdb_data *data) +{ + char *s, *next, *name, *value; + int critical; + + while (extensions != NULL) { + s = strchr(extensions, ','); + if (s != NULL) { + *s++ = '\0'; + next = s; + } else { + next = NULL; + } + + if (*extensions != '\0') { + s = strchr(extensions, '='); + if (s != NULL) { + *s++ = '\0'; + value = *s != '\0' ? s : NULL; + } else { + value = NULL; + } + name = extensions; + + critical = *name == '!'; + if (critical) { + name++; + } + if (*name == '\0') { + return -1; + } + + if (!strcasecmp(name, "bindname")) { + data->bindname = value; + } else if (!strcasecmp(name, "x-bindpw")) { + data->bindpw = value; +#ifdef LDAPDB_TLS + } else if (!strcasecmp(name, "x-tls")) { + data->tls = value == NULL || !strcasecmp(value, "true"); +#endif + } else if (critical) { + return -2; + } + } + extensions = next; + } + return 0; +} + +static void +free_data(struct ldapdb_data *data) +{ + if (data->hostport != NULL) + isc_mem_free(ns_g_mctx, data->hostport); + if (data->hostname != NULL) + isc_mem_free(ns_g_mctx, data->hostname); + if (data->filterall != NULL) + isc_mem_put(ns_g_mctx, data->filterall, data->filteralllen); + if (data->filterone != NULL) + isc_mem_put(ns_g_mctx, data->filterone, data->filteronelen); + isc_mem_put(ns_g_mctx, data, sizeof(struct ldapdb_data)); +} + + +static isc_result_t +ldapdb_create(const char *zone, int argc, char **argv, + void *driverdata, void **dbdata) +{ + struct ldapdb_data *data; + char *s, *filter = NULL, *extensions = NULL; + int defaultttl; + + 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); + + memset(data, 0, sizeof(struct ldapdb_data)); + data->hostport = isc_mem_strdup(ns_g_mctx, argv[0] + strlen("ldap://")); + if (data->hostport == NULL) { + free_data(data); + return (ISC_R_NOMEMORY); + } + + data->defaultttl = defaultttl; + + s = strchr(data->hostport, '/'); + if (s != NULL) { + *s++ = '\0'; + data->base = s; + /* attrs, scope, filter etc? */ + s = strchr(s, '?'); + if (s != NULL) { + *s++ = '\0'; + /* ignore attributes */ + s = strchr(s, '?'); + if (s != NULL) { + *s++ = '\0'; + /* ignore scope */ + s = strchr(s, '?'); + if (s != NULL) { + *s++ = '\0'; + /* filter */ + filter = s; + s = strchr(s, '?'); + if (s != NULL) { + *s++ = '\0'; + /* extensions */ + extensions = s; + s = strchr(s, '?'); + if (s != NULL) { + *s++ = '\0'; + } + if (*extensions == '\0') { + extensions = NULL; + } + } + if (*filter == '\0') { + filter = NULL; + } + } + } + } + if (*data->base == '\0') { + data->base = NULL; + } + } + + /* parse extensions */ + if (extensions != NULL) { + int err; + + err = parseextensions(extensions, data); + if (err < 0) { + /* err should be -1 or -2 */ + free_data(data); + if (err == -1) { + isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, ISC_LOG_ERROR, + "LDAP sdb zone '%s': URL: extension syntax error", zone); + } else if (err == -2) { + isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, ISC_LOG_ERROR, + "LDAP sdb zone '%s': URL: unknown critical extension", zone); + } + return (ISC_R_FAILURE); + } + } + + if ((data->base != NULL && unhex(data->base) == NULL) || + (filter != NULL && unhex(filter) == NULL) || + (data->bindname != NULL && unhex(data->bindname) == NULL) || + (data->bindpw != NULL && unhex(data->bindpw) == NULL)) { + free_data(data); + isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, ISC_LOG_ERROR, + "LDAP sdb zone '%s': URL: bad hex values", zone); + return (ISC_R_FAILURE); + } + + /* compute filterall and filterone once and for all */ + if (filter == NULL) { + data->filteralllen = strlen(zone) + strlen("(zoneName=)") + 1; + data->filteronelen = strlen(zone) + strlen("(&(zoneName=)(relativeDomainName=))") + MAXNAMELEN + 1; + } else { + data->filteralllen = strlen(filter) + strlen(zone) + strlen("(&(zoneName=))") + 1; + data->filteronelen = strlen(filter) + strlen(zone) + strlen("(&(zoneName=)(relativeDomainName=))") + MAXNAMELEN + 1; + } + + data->filterall = isc_mem_get(ns_g_mctx, data->filteralllen); + if (data->filterall == NULL) { + free_data(data); + return (ISC_R_NOMEMORY); + } + data->filterone = isc_mem_get(ns_g_mctx, data->filteronelen); + if (data->filterone == NULL) { + free_data(data); + return (ISC_R_NOMEMORY); + } + + if (filter == NULL) { + sprintf(data->filterall, "(zoneName=%s)", zone); + sprintf(data->filterone, "(&(zoneName=%s)(relativeDomainName=", zone); + } else { + sprintf(data->filterall, "(&%s(zoneName=%s))", filter, zone); + sprintf(data->filterone, "(&%s(zoneName=%s)(relativeDomainName=", filter, zone); + } + data->filtername = data->filterone + strlen(data->filterone); + + /* support URLs with literal IPv6 addresses */ + data->hostname = isc_mem_strdup(ns_g_mctx, data->hostport + (*data->hostport == '[' ? 1 : 0)); + if (data->hostname == NULL) { + free_data(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); + + free_data(data); +} + +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); + } +} diff -urN bind-9.2.3-orig/bin/named/main.c bind-9.2.3/bin/named/main.c --- bind-9.2.3-orig/bin/named/main.c 2003-10-09 01:32:33.000000000 -0600 +++ bind-9.2.3/bin/named/main.c 2003-11-16 14:52:51.000000000 -0700 @@ -64,6 +64,7 @@ * Include header files for database drivers here. */ /* #include "xxdb.h" */ +#include static isc_boolean_t want_stats = ISC_FALSE; static char program_name[ISC_DIR_NAMEMAX] = "named"; @@ -544,6 +545,7 @@ * Add calls to register sdb drivers here. */ /* xxdb_init(); */ + ldapdb_init(); ns_server_create(ns_g_mctx, &ns_g_server); } @@ -558,6 +560,7 @@ * Add calls to unregister sdb drivers here. */ /* xxdb_clear(); */ + ldapdb_clear(); isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_MAIN, ISC_LOG_NOTICE, "exiting"); diff -urN bind-9.2.3-orig/doc/INSTALL.sdb-ldap bind-9.2.3/doc/INSTALL.sdb-ldap --- bind-9.2.3-orig/doc/INSTALL.sdb-ldap 1969-12-31 17:00:00.000000000 -0700 +++ bind-9.2.3/doc/INSTALL.sdb-ldap 2003-11-16 14:53:32.000000000 -0700 @@ -0,0 +1,59 @@ +This is the INSTALL file for 0.9. 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 ". 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. If you get an error +message about ldap_memfree() not being defined, you're probably +using an LDAP library with the interface defined in RFC 1823. To +build, uncomment the #define RFC1823API line near the top of ldapdb.c. + + +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. It is also possible to add an filter to +the URL, say ldap://host/base???(o=internal) + +Stig Venaas 2002-04-17 diff -urN bind-9.2.3-orig/doc/README.sdb-ldap bind-9.2.3/doc/README.sdb-ldap --- bind-9.2.3-orig/doc/README.sdb-ldap 1969-12-31 17:00:00.000000000 -0700 +++ bind-9.2.3/doc/README.sdb-ldap 2003-11-16 14:53:18.000000000 -0700 @@ -0,0 +1,40 @@ +This is an attempt at an LDAP back-end for BIND 9 using the new simplified +database interface "sdb". This is the nineth release (0.9) and seems to +be pretty stable. Note that since version 0.4 a new schema is used. +It is not backwards compatible with versions before 0.4. + +In 0.9 the code has been cleaned up a bit and should be slightly faster +than previous versions. It also fixes an error with zone transfers (AXFR) +and entries with multiple relativeDomainName values. The problem was +that it would only use the first value in the result. There's no need +to upgrade unless you use such entries. + +0.8 uses asynchronous LDAP search which should give better performance. +Thanks to Ashley Burston for providing patch. Another new feature is +allowing filters in URLs. The syntax is as in RFC 2255. Few people will +need this, but if you have say an internal and external version of the +same zone, you could stick say o=internal and o=external into different +entries, and specify for instance ldap://host/base???(o=internal) +Some error logging has also been added. + +0.7 allows space and other characters to be used in URLs by use of %-quoting. +For instance space can be written as %20. It also fixes a problem with some +servers and/or APIs that do not preserve attribute casing. + +0.6 fixes some memory leaks present in older versions unless compiled with +the RFC 1823 API. + +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 2001-12-29