]> git.pld-linux.org Git - packages/bind.git/blame - bind-sdb-ldap.patch
- release 2 (by relup.sh)
[packages/bind.git] / bind-sdb-ldap.patch
CommitLineData
f1f8128e 1diff -urN bind-9.2.3-orig/bin/named/Makefile.in bind-9.2.3/bin/named/Makefile.in
2--- bind-9.2.3-orig/bin/named/Makefile.in 2001-05-31 18:45:00.000000000 -0600
3+++ bind-9.2.3/bin/named/Makefile.in 2003-11-16 14:52:51.000000000 -0700
4@@ -26,10 +26,10 @@
5 #
6 # Add database drivers here.
7 #
8-DBDRIVER_OBJS =
9-DBDRIVER_SRCS =
10+DBDRIVER_OBJS = ldapdb.@O@
11+DBDRIVER_SRCS = ldapdb.c
12 DBDRIVER_INCLUDES =
13-DBDRIVER_LIBS =
14+DBDRIVER_LIBS = -lldap -llber -lresolv
15
16 CINCLUDES = -I${srcdir}/include -I${srcdir}/unix/include \
17 ${LWRES_INCLUDES} ${DNS_INCLUDES} \
18diff -urN bind-9.2.3-orig/bin/named/include/ldapdb.h bind-9.2.3/bin/named/include/ldapdb.h
19--- bind-9.2.3-orig/bin/named/include/ldapdb.h 1969-12-31 17:00:00.000000000 -0700
20+++ bind-9.2.3/bin/named/include/ldapdb.h 2003-11-16 14:52:51.000000000 -0700
21@@ -0,0 +1,6 @@
22+#include <isc/types.h>
23+
24+isc_result_t ldapdb_init(void);
25+
26+void ldapdb_clear(void);
27+
28diff -urN bind-9.2.3-orig/bin/named/ldapdb.c bind-9.2.3/bin/named/ldapdb.c
29--- bind-9.2.3-orig/bin/named/ldapdb.c 1969-12-31 17:00:00.000000000 -0700
30+++ bind-9.2.3/bin/named/ldapdb.c 2003-11-16 14:52:51.000000000 -0700
a37d2a21 31@@ -0,0 +1,667 @@
f1f8128e 32+/*
a37d2a21 33+ * ldapdb.c version 1.0-beta
f1f8128e 34+ *
a37d2a21 35+ * Copyright (C) 2002, 2004 Stig Venaas
f1f8128e 36+ *
37+ * Permission to use, copy, modify, and distribute this software for any
38+ * purpose with or without fee is hereby granted, provided that the above
39+ * copyright notice and this permission notice appear in all copies.
a37d2a21 40+ *
41+ * Contributors: Jeremy C. McDermond
42+ */
43+
44+/*
45+ * If you want to use TLS, uncomment the define below
f1f8128e 46+ */
a37d2a21 47+/* #define LDAPDB_TLS */
f1f8128e 48+
49+/*
50+ * If you are using an old LDAP API uncomment the define below. Only do this
51+ * if you know what you're doing or get compilation errors on ldap_memfree().
a37d2a21 52+ * This also forces LDAPv2.
f1f8128e 53+ */
a37d2a21 54+/* #define LDAPDB_RFC1823API */
55+
56+/* Using LDAPv3 by default, change this if you want v2 */
57+#ifndef LDAPDB_LDAP_VERSION
58+#define LDAPDB_LDAP_VERSION 3
59+#endif
f1f8128e 60+
61+#include <config.h>
62+
63+#include <string.h>
64+#include <stdio.h>
65+#include <stdlib.h>
66+#include <ctype.h>
67+
68+#include <isc/mem.h>
69+#include <isc/print.h>
70+#include <isc/result.h>
71+#include <isc/util.h>
72+#include <isc/thread.h>
73+
74+#include <dns/sdb.h>
75+
76+#include <named/globals.h>
77+#include <named/log.h>
78+
79+#include <ldap.h>
80+#include "ldapdb.h"
81+
82+/*
83+ * A simple database driver for LDAP
84+ */
85+
86+/* enough for name with 8 labels of max length */
87+#define MAXNAMELEN 519
88+
89+static dns_sdbimplementation_t *ldapdb = NULL;
90+
91+struct ldapdb_data {
92+ char *hostport;
93+ char *hostname;
94+ int portno;
95+ char *base;
96+ int defaultttl;
97+ char *filterall;
98+ int filteralllen;
99+ char *filterone;
100+ int filteronelen;
101+ char *filtername;
a37d2a21 102+ char *bindname;
103+ char *bindpw;
104+#ifdef LDAPDB_TLS
105+ int tls;
106+#endif
f1f8128e 107+};
108+
109+/* used by ldapdb_getconn */
110+
111+struct ldapdb_entry {
112+ void *index;
113+ size_t size;
114+ void *data;
115+ struct ldapdb_entry *next;
116+};
117+
118+static struct ldapdb_entry *ldapdb_find(struct ldapdb_entry *stack,
119+ const void *index, size_t size) {
120+ while (stack != NULL) {
121+ if (stack->size == size && !memcmp(stack->index, index, size))
122+ return stack;
123+ stack = stack->next;
124+ }
125+ return NULL;
126+}
127+
128+static void ldapdb_insert(struct ldapdb_entry **stack,
129+ struct ldapdb_entry *item) {
130+ item->next = *stack;
131+ *stack = item;
132+}
133+
134+static void ldapdb_lock(int what) {
135+ static isc_mutex_t lock;
136+
137+ switch (what) {
138+ case 0:
139+ isc_mutex_init(&lock);
140+ break;
141+ case 1:
142+ LOCK(&lock);
143+ break;
144+ case -1:
145+ UNLOCK(&lock);
146+ break;
147+ }
148+}
149+
150+/* data == NULL means cleanup */
151+static LDAP **
152+ldapdb_getconn(struct ldapdb_data *data)
153+{
154+ static struct ldapdb_entry *allthreadsdata = NULL;
155+ struct ldapdb_entry *threaddata, *conndata;
156+ unsigned long threadid;
157+
158+ if (data == NULL) {
159+ /* cleanup */
160+ /* lock out other threads */
161+ ldapdb_lock(1);
162+ while (allthreadsdata != NULL) {
163+ threaddata = allthreadsdata;
164+ free(threaddata->index);
165+ while (threaddata->data != NULL) {
166+ conndata = threaddata->data;
167+ free(conndata->index);
168+ if (conndata->data != NULL)
169+ ldap_unbind((LDAP *)conndata->data);
170+ threaddata->data = conndata->next;
171+ free(conndata);
172+ }
173+ allthreadsdata = threaddata->next;
174+ free(threaddata);
175+ }
176+ ldapdb_lock(-1);
177+ return (NULL);
178+ }
179+
180+ /* look for connection data for current thread */
181+ threadid = isc_thread_self();
182+ threaddata = ldapdb_find(allthreadsdata, &threadid, sizeof(threadid));
183+ if (threaddata == NULL) {
184+ /* no data for this thread, create empty connection list */
185+ threaddata = malloc(sizeof(*threaddata));
186+ if (threaddata == NULL)
187+ return (NULL);
188+ threaddata->index = malloc(sizeof(threadid));
189+ if (threaddata->index == NULL) {
190+ free(threaddata);
191+ return (NULL);
192+ }
193+ *(unsigned long *)threaddata->index = threadid;
194+ threaddata->size = sizeof(threadid);
195+ threaddata->data = NULL;
196+
197+ /* need to lock out other threads here */
198+ ldapdb_lock(1);
199+ ldapdb_insert(&allthreadsdata, threaddata);
200+ ldapdb_lock(-1);
201+ }
202+
203+ /* threaddata points at the connection list for current thread */
204+ /* look for existing connection to our server */
205+ conndata = ldapdb_find((struct ldapdb_entry *)threaddata->data,
206+ data->hostport, strlen(data->hostport));
207+ if (conndata == NULL) {
208+ /* no connection data structure for this server, create one */
209+ conndata = malloc(sizeof(*conndata));
210+ if (conndata == NULL)
211+ return (NULL);
a37d2a21 212+ conndata->index = data->hostport;
f1f8128e 213+ conndata->size = strlen(data->hostport);
214+ conndata->data = NULL;
215+ ldapdb_insert((struct ldapdb_entry **)&threaddata->data,
216+ conndata);
217+ }
218+
219+ return (LDAP **)&conndata->data;
220+}
221+
222+static void
223+ldapdb_bind(struct ldapdb_data *data, LDAP **ldp)
224+{
a37d2a21 225+#ifndef LDAPDB_RFC1823API
226+ const int ver = LDAPDB_LDAP_VERSION;
227+#endif
228+
f1f8128e 229+ if (*ldp != NULL)
230+ ldap_unbind(*ldp);
231+ *ldp = ldap_open(data->hostname, data->portno);
232+ if (*ldp == NULL)
233+ return;
a37d2a21 234+
235+#ifndef LDAPDB_RFC1823API
236+ ldap_set_option(*ldp, LDAP_OPT_PROTOCOL_VERSION, &ver);
237+#endif
238+
239+#ifdef LDAPDB_TLS
240+ if (data->tls) {
241+ ldap_start_tls_s(*ldp, NULL, NULL);
242+ }
243+#endif
244+
245+ if (ldap_simple_bind_s(*ldp, data->bindname, data->bindpw) != LDAP_SUCCESS) {
f1f8128e 246+ ldap_unbind(*ldp);
247+ *ldp = NULL;
248+ }
249+}
250+
251+static isc_result_t
252+ldapdb_search(const char *zone, const char *name, void *dbdata, void *retdata)
253+{
254+ struct ldapdb_data *data = dbdata;
255+ isc_result_t result = ISC_R_NOTFOUND;
256+ LDAP **ldp;
257+ LDAPMessage *res, *e;
a37d2a21 258+ char *fltr, *a, **vals = NULL, **names = NULL;
f1f8128e 259+ char type[64];
a37d2a21 260+#ifdef LDAPDB_RFC1823API
f1f8128e 261+ void *ptr;
262+#else
263+ BerElement *ptr;
264+#endif
265+ int i, j, errno, msgid;
266+
267+ ldp = ldapdb_getconn(data);
268+ if (ldp == NULL)
269+ return (ISC_R_FAILURE);
270+ if (*ldp == NULL) {
271+ ldapdb_bind(data, ldp);
272+ if (*ldp == NULL) {
273+ isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, ISC_LOG_ERROR,
274+ "LDAP sdb zone '%s': bind failed", zone);
275+ return (ISC_R_FAILURE);
276+ }
277+ }
278+
279+ if (name == NULL) {
280+ fltr = data->filterall;
281+ } else {
282+ if (strlen(name) > MAXNAMELEN) {
283+ isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, ISC_LOG_ERROR,
284+ "LDAP sdb zone '%s': name %s too long", zone, name);
285+ return (ISC_R_FAILURE);
286+ }
287+ sprintf(data->filtername, "%s))", name);
288+ fltr = data->filterone;
289+ }
290+
291+ msgid = ldap_search(*ldp, data->base, LDAP_SCOPE_SUBTREE, fltr, NULL, 0);
292+ if (msgid == -1) {
293+ ldapdb_bind(data, ldp);
294+ if (*ldp != NULL)
295+ msgid = ldap_search(*ldp, data->base, LDAP_SCOPE_SUBTREE, fltr, NULL, 0);
296+ }
297+
298+ if (*ldp == NULL || msgid == -1) {
299+ isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, ISC_LOG_ERROR,
300+ "LDAP sdb zone '%s': search failed, filter %s", zone, fltr);
301+ return (ISC_R_FAILURE);
302+ }
303+
304+ /* Get the records one by one as they arrive and return them to bind */
305+ while ((errno = ldap_result(*ldp, msgid, 0, NULL, &res)) != LDAP_RES_SEARCH_RESULT ) {
306+ LDAP *ld = *ldp;
307+ int ttl = data->defaultttl;
308+
309+ /* not supporting continuation references at present */
310+ if (errno != LDAP_RES_SEARCH_ENTRY) {
311+ isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, ISC_LOG_ERROR,
312+ "LDAP sdb zone '%s': ldap_result returned %d", zone, errno);
313+ ldap_msgfree(res);
314+ return (ISC_R_FAILURE);
315+ }
316+
317+ /* only one entry per result message */
318+ e = ldap_first_entry(ld, res);
319+ if (e == NULL) {
320+ ldap_msgfree(res);
321+ isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, ISC_LOG_ERROR,
322+ "LDAP sdb zone '%s': ldap_first_entry failed", zone);
323+ return (ISC_R_FAILURE);
324+ }
325+
326+ if (name == NULL) {
327+ names = ldap_get_values(ld, e, "relativeDomainName");
328+ if (names == NULL)
329+ continue;
330+ }
331+
332+ vals = ldap_get_values(ld, e, "dNSTTL");
333+ if (vals != NULL) {
334+ ttl = atoi(vals[0]);
335+ ldap_value_free(vals);
336+ }
337+
338+ for (a = ldap_first_attribute(ld, e, &ptr); a != NULL; a = ldap_next_attribute(ld, e, ptr)) {
339+ char *s;
340+
341+ for (s = a; *s; s++)
342+ *s = toupper(*s);
343+ s = strstr(a, "RECORD");
344+ if ((s == NULL) || (s == a) || (s - a >= (signed int)sizeof(type))) {
a37d2a21 345+#ifndef LDAPDB_RFC1823API
f1f8128e 346+ ldap_memfree(a);
347+#endif
348+ continue;
349+ }
350+
351+ strncpy(type, a, s - a);
352+ type[s - a] = '\0';
353+ vals = ldap_get_values(ld, e, a);
354+ if (vals != NULL) {
355+ for (i = 0; vals[i] != NULL; i++) {
356+ if (name != NULL) {
357+ result = dns_sdb_putrr(retdata, type, ttl, vals[i]);
358+ } else {
359+ for (j = 0; names[j] != NULL; j++) {
360+ result = dns_sdb_putnamedrr(retdata, names[j], type, ttl, vals[i]);
361+ if (result != ISC_R_SUCCESS)
362+ break;
363+ }
364+ }
365+; if (result != ISC_R_SUCCESS) {
366+ isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, ISC_LOG_ERROR,
367+ "LDAP sdb zone '%s': dns_sdb_put... failed for %s", zone, vals[i]);
368+ ldap_value_free(vals);
a37d2a21 369+#ifndef LDAPDB_RFC1823API
f1f8128e 370+ ldap_memfree(a);
371+ if (ptr != NULL)
372+ ber_free(ptr, 0);
373+#endif
374+ if (name == NULL)
375+ ldap_value_free(names);
376+ ldap_msgfree(res);
377+ return (ISC_R_FAILURE);
378+ }
379+ }
380+ ldap_value_free(vals);
381+ }
a37d2a21 382+#ifndef LDAPDB_RFC1823API
f1f8128e 383+ ldap_memfree(a);
384+#endif
385+ }
a37d2a21 386+#ifndef LDAPDB_RFC1823API
f1f8128e 387+ if (ptr != NULL)
388+ ber_free(ptr, 0);
389+#endif
390+ if (name == NULL)
391+ ldap_value_free(names);
392+
a37d2a21 393+ /* free this result */
f1f8128e 394+ ldap_msgfree(res);
395+ }
396+
a37d2a21 397+ /* free final result */
398+ ldap_msgfree(res);
f1f8128e 399+ return (result);
400+}
401+
402+
403+/* callback routines */
404+static isc_result_t
405+ldapdb_lookup(const char *zone, const char *name, void *dbdata,
406+ dns_sdblookup_t *lookup)
407+{
408+ return ldapdb_search(zone, name, dbdata, lookup);
409+}
410+
411+static isc_result_t
412+ldapdb_allnodes(const char *zone, void *dbdata,
413+ dns_sdballnodes_t *allnodes)
414+{
415+ return ldapdb_search(zone, NULL, dbdata, allnodes);
416+}
417+
418+static char *
419+unhex(char *in)
420+{
421+ static const char hexdigits[] = "0123456789abcdef";
422+ char *p, *s = in;
423+ int d1, d2;
424+
425+ while ((s = strchr(s, '%'))) {
426+ if (!(s[1] && s[2]))
427+ return NULL;
428+ if ((p = strchr(hexdigits, tolower(s[1]))) == NULL)
429+ return NULL;
430+ d1 = p - hexdigits;
431+ if ((p = strchr(hexdigits, tolower(s[2]))) == NULL)
432+ return NULL;
433+ d2 = p - hexdigits;
434+ *s++ = d1 << 4 | d2;
435+ memmove(s, s + 2, strlen(s) - 1);
436+ }
437+ return in;
438+}
439+
a37d2a21 440+/* returns 0 for ok, -1 for bad syntax, -2 for unknown critical extension */
441+static int
442+parseextensions(char *extensions, struct ldapdb_data *data)
443+{
444+ char *s, *next, *name, *value;
445+ int critical;
446+
447+ while (extensions != NULL) {
448+ s = strchr(extensions, ',');
449+ if (s != NULL) {
450+ *s++ = '\0';
451+ next = s;
452+ } else {
453+ next = NULL;
454+ }
455+
456+ if (*extensions != '\0') {
457+ s = strchr(extensions, '=');
458+ if (s != NULL) {
459+ *s++ = '\0';
460+ value = *s != '\0' ? s : NULL;
461+ } else {
462+ value = NULL;
463+ }
464+ name = extensions;
f1f8128e 465+
a37d2a21 466+ critical = *name == '!';
467+ if (critical) {
468+ name++;
469+ }
470+ if (*name == '\0') {
471+ return -1;
472+ }
473+
474+ if (!strcasecmp(name, "bindname")) {
475+ data->bindname = value;
476+ } else if (!strcasecmp(name, "x-bindpw")) {
477+ data->bindpw = value;
478+#ifdef LDAPDB_TLS
479+ } else if (!strcasecmp(name, "x-tls")) {
480+ data->tls = value == NULL || !strcasecmp(value, "true");
481+#endif
482+ } else if (critical) {
483+ return -2;
484+ }
485+ }
486+ extensions = next;
487+ }
488+ return 0;
489+}
f1f8128e 490+
491+static void
492+free_data(struct ldapdb_data *data)
493+{
494+ if (data->hostport != NULL)
495+ isc_mem_free(ns_g_mctx, data->hostport);
496+ if (data->hostname != NULL)
497+ isc_mem_free(ns_g_mctx, data->hostname);
498+ if (data->filterall != NULL)
499+ isc_mem_put(ns_g_mctx, data->filterall, data->filteralllen);
500+ if (data->filterone != NULL)
501+ isc_mem_put(ns_g_mctx, data->filterone, data->filteronelen);
502+ isc_mem_put(ns_g_mctx, data, sizeof(struct ldapdb_data));
503+}
504+
505+
506+static isc_result_t
507+ldapdb_create(const char *zone, int argc, char **argv,
508+ void *driverdata, void **dbdata)
509+{
510+ struct ldapdb_data *data;
a37d2a21 511+ char *s, *filter = NULL, *extensions = NULL;
f1f8128e 512+ int defaultttl;
513+
514+ UNUSED(driverdata);
515+
516+ /* we assume that only one thread will call create at a time */
517+ /* want to do this only once for all instances */
518+
519+ if ((argc < 2)
520+ || (argv[0] != strstr( argv[0], "ldap://"))
521+ || ((defaultttl = atoi(argv[1])) < 1))
522+ return (ISC_R_FAILURE);
523+ data = isc_mem_get(ns_g_mctx, sizeof(struct ldapdb_data));
524+ if (data == NULL)
525+ return (ISC_R_NOMEMORY);
526+
527+ memset(data, 0, sizeof(struct ldapdb_data));
528+ data->hostport = isc_mem_strdup(ns_g_mctx, argv[0] + strlen("ldap://"));
529+ if (data->hostport == NULL) {
530+ free_data(data);
531+ return (ISC_R_NOMEMORY);
532+ }
533+
534+ data->defaultttl = defaultttl;
535+
536+ s = strchr(data->hostport, '/');
537+ if (s != NULL) {
538+ *s++ = '\0';
539+ data->base = s;
540+ /* attrs, scope, filter etc? */
541+ s = strchr(s, '?');
542+ if (s != NULL) {
543+ *s++ = '\0';
544+ /* ignore attributes */
545+ s = strchr(s, '?');
546+ if (s != NULL) {
547+ *s++ = '\0';
548+ /* ignore scope */
549+ s = strchr(s, '?');
550+ if (s != NULL) {
551+ *s++ = '\0';
552+ /* filter */
553+ filter = s;
554+ s = strchr(s, '?');
555+ if (s != NULL) {
556+ *s++ = '\0';
a37d2a21 557+ /* extensions */
558+ extensions = s;
559+ s = strchr(s, '?');
560+ if (s != NULL) {
561+ *s++ = '\0';
562+ }
563+ if (*extensions == '\0') {
564+ extensions = NULL;
565+ }
f1f8128e 566+ }
567+ if (*filter == '\0') {
568+ filter = NULL;
569+ }
570+ }
571+ }
572+ }
573+ if (*data->base == '\0') {
574+ data->base = NULL;
575+ }
a37d2a21 576+ }
577+
578+ /* parse extensions */
579+ if (extensions != NULL) {
580+ int err;
f1f8128e 581+
a37d2a21 582+ err = parseextensions(extensions, data);
583+ if (err < 0) {
584+ /* err should be -1 or -2 */
f1f8128e 585+ free_data(data);
a37d2a21 586+ if (err == -1) {
587+ isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, ISC_LOG_ERROR,
588+ "LDAP sdb zone '%s': URL: extension syntax error", zone);
589+ } else if (err == -2) {
590+ isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, ISC_LOG_ERROR,
591+ "LDAP sdb zone '%s': URL: unknown critical extension", zone);
592+ }
f1f8128e 593+ return (ISC_R_FAILURE);
594+ }
595+ }
596+
a37d2a21 597+ if ((data->base != NULL && unhex(data->base) == NULL) ||
598+ (filter != NULL && unhex(filter) == NULL) ||
599+ (data->bindname != NULL && unhex(data->bindname) == NULL) ||
600+ (data->bindpw != NULL && unhex(data->bindpw) == NULL)) {
601+ free_data(data);
602+ isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, ISC_LOG_ERROR,
603+ "LDAP sdb zone '%s': URL: bad hex values", zone);
604+ return (ISC_R_FAILURE);
605+ }
606+
f1f8128e 607+ /* compute filterall and filterone once and for all */
608+ if (filter == NULL) {
609+ data->filteralllen = strlen(zone) + strlen("(zoneName=)") + 1;
610+ data->filteronelen = strlen(zone) + strlen("(&(zoneName=)(relativeDomainName=))") + MAXNAMELEN + 1;
611+ } else {
612+ data->filteralllen = strlen(filter) + strlen(zone) + strlen("(&(zoneName=))") + 1;
613+ data->filteronelen = strlen(filter) + strlen(zone) + strlen("(&(zoneName=)(relativeDomainName=))") + MAXNAMELEN + 1;
614+ }
615+
616+ data->filterall = isc_mem_get(ns_g_mctx, data->filteralllen);
617+ if (data->filterall == NULL) {
618+ free_data(data);
619+ return (ISC_R_NOMEMORY);
620+ }
621+ data->filterone = isc_mem_get(ns_g_mctx, data->filteronelen);
622+ if (data->filterone == NULL) {
623+ free_data(data);
624+ return (ISC_R_NOMEMORY);
625+ }
626+
627+ if (filter == NULL) {
628+ sprintf(data->filterall, "(zoneName=%s)", zone);
629+ sprintf(data->filterone, "(&(zoneName=%s)(relativeDomainName=", zone);
630+ } else {
631+ sprintf(data->filterall, "(&%s(zoneName=%s))", filter, zone);
632+ sprintf(data->filterone, "(&%s(zoneName=%s)(relativeDomainName=", filter, zone);
633+ }
634+ data->filtername = data->filterone + strlen(data->filterone);
635+
636+ /* support URLs with literal IPv6 addresses */
637+ data->hostname = isc_mem_strdup(ns_g_mctx, data->hostport + (*data->hostport == '[' ? 1 : 0));
638+ if (data->hostname == NULL) {
639+ free_data(data);
640+ return (ISC_R_NOMEMORY);
641+ }
642+
643+ if (*data->hostport == '[' &&
644+ (s = strchr(data->hostname, ']')) != NULL )
645+ *s++ = '\0';
646+ else
647+ s = data->hostname;
648+ s = strchr(s, ':');
649+ if (s != NULL) {
650+ *s++ = '\0';
651+ data->portno = atoi(s);
652+ } else
653+ data->portno = LDAP_PORT;
654+
655+ *dbdata = data;
656+ return (ISC_R_SUCCESS);
657+}
658+
659+static void
660+ldapdb_destroy(const char *zone, void *driverdata, void **dbdata) {
661+ struct ldapdb_data *data = *dbdata;
662+
663+ UNUSED(zone);
664+ UNUSED(driverdata);
665+
666+ free_data(data);
667+}
668+
669+static dns_sdbmethods_t ldapdb_methods = {
670+ ldapdb_lookup,
671+ NULL, /* authority */
672+ ldapdb_allnodes,
673+ ldapdb_create,
674+ ldapdb_destroy
675+};
676+
677+/* Wrapper around dns_sdb_register() */
678+isc_result_t
679+ldapdb_init(void) {
680+ unsigned int flags =
681+ DNS_SDBFLAG_RELATIVEOWNER |
682+ DNS_SDBFLAG_RELATIVERDATA |
683+ DNS_SDBFLAG_THREADSAFE;
684+
685+ ldapdb_lock(0);
686+ return (dns_sdb_register("ldap", &ldapdb_methods, NULL, flags,
687+ ns_g_mctx, &ldapdb));
688+}
689+
690+/* Wrapper around dns_sdb_unregister() */
691+void
692+ldapdb_clear(void) {
693+ if (ldapdb != NULL) {
694+ /* clean up thread data */
695+ ldapdb_getconn(NULL);
696+ dns_sdb_unregister(&ldapdb);
697+ }
698+}
699diff -urN bind-9.2.3-orig/bin/named/main.c bind-9.2.3/bin/named/main.c
700--- bind-9.2.3-orig/bin/named/main.c 2003-10-09 01:32:33.000000000 -0600
701+++ bind-9.2.3/bin/named/main.c 2003-11-16 14:52:51.000000000 -0700
702@@ -64,6 +64,7 @@
703 * Include header files for database drivers here.
704 */
705 /* #include "xxdb.h" */
706+#include <ldapdb.h>
707
708 static isc_boolean_t want_stats = ISC_FALSE;
709 static char program_name[ISC_DIR_NAMEMAX] = "named";
710@@ -544,6 +545,7 @@
711 * Add calls to register sdb drivers here.
712 */
713 /* xxdb_init(); */
714+ ldapdb_init();
715
716 ns_server_create(ns_g_mctx, &ns_g_server);
717 }
718@@ -558,6 +560,7 @@
719 * Add calls to unregister sdb drivers here.
720 */
721 /* xxdb_clear(); */
722+ ldapdb_clear();
723
724 isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_MAIN,
725 ISC_LOG_NOTICE, "exiting");
726diff -urN bind-9.2.3-orig/doc/INSTALL.sdb-ldap bind-9.2.3/doc/INSTALL.sdb-ldap
727--- bind-9.2.3-orig/doc/INSTALL.sdb-ldap 1969-12-31 17:00:00.000000000 -0700
728+++ bind-9.2.3/doc/INSTALL.sdb-ldap 2003-11-16 14:53:32.000000000 -0700
729@@ -0,0 +1,59 @@
730+This is the INSTALL file for 0.9. See
731+http://www.venaas.no/ldap/bind-sdb/ for updates or other information.
732+
733+BUILDING
734+
735+You need the source for BIND 9.1.0 or newer (for zone transfers you
736+will need at least 9.1.1rc3 due to a bug). Basically you need to follow
737+the instructions in doc/misc/sdb, if my instructions doesn't make sense,
738+please have a look at that as well.
739+
740+Copy ldapdb.c to bin/named and ldapdb.h to bin/named/include in the
741+source tree.
742+
743+Next alter bin/named/Makefile.in. Add ldapdb.@O@ to DBDRIVER_OBJS and
744+ldapdb.c to DBDRIVER_SRCS. You also need to add something like
745+-I/usr/local/include to DBDRIVER_INCLUDES and
746+-L/usr/local/lib -lldap -llber -lresolv to DBDRIVER_LIBS
747+depending on what LDAP library you have and where you installed it.
748+
749+Finally you need to edit bin/named/main.c. Below where it says
750+"#include "xxdb.h"", add the line "#include <ldapdb.h>". Below where
751+it says "xxdb_init();" add the line "ldapdb_init();", and finally
752+below where it says "xxdb_clear();", add "ldapdb_clear();".
753+
754+Now you should hopefully be able to build it. If you get an error
755+message about ldap_memfree() not being defined, you're probably
756+using an LDAP library with the interface defined in RFC 1823. To
757+build, uncomment the #define RFC1823API line near the top of ldapdb.c.
758+
759+
760+CONFIGURING
761+
762+Before you do any configuring of LDAP stuff, please try to configure
763+and start bind as usual to see if things work.
764+
765+To do anything useful, you need to store a zone in some LDAP server.
766+From this release on, you must use a schema called dNSZone. Note that
767+it relies on some attribute definitions in the Cosine schema, so that
768+must be included as well. The Cosine schema probably comes with your
769+LDAP server. You can find dNSZone and further details on how to store
770+the data in your LDAP server at
771+http://www.venaas.no/ldap/bind-sdb/
772+
773+For an example, have a look at my venaas.com zone. Try a subtree search
774+for objectClass=* at
775+ldap ldap://129.241.20.67/dc=venaas,dc=com,o=DNS,dc=venaas,dc=no
776+
777+To use it with BIND, I've added the following to named.conf:
778+zone "venaas.com" {
779+ type master;
780+ database "ldap ldap://129.241.20.67/dc=venaas,dc=com,o=DNS,dc=venaas,dc=no 172800";
781+};
782+
783+When doing lookups BIND will do a sub-tree search below the base in the
784+URL. The number 172800 is the TTL which will be used for all entries that
785+haven't got the dNSTTL attribute. It is also possible to add an filter to
786+the URL, say ldap://host/base???(o=internal)
787+
788+Stig Venaas <venaas@uninett.no> 2002-04-17
789diff -urN bind-9.2.3-orig/doc/README.sdb-ldap bind-9.2.3/doc/README.sdb-ldap
790--- bind-9.2.3-orig/doc/README.sdb-ldap 1969-12-31 17:00:00.000000000 -0700
791+++ bind-9.2.3/doc/README.sdb-ldap 2003-11-16 14:53:18.000000000 -0700
792@@ -0,0 +1,40 @@
793+This is an attempt at an LDAP back-end for BIND 9 using the new simplified
794+database interface "sdb". This is the nineth release (0.9) and seems to
795+be pretty stable. Note that since version 0.4 a new schema is used.
796+It is not backwards compatible with versions before 0.4.
797+
798+In 0.9 the code has been cleaned up a bit and should be slightly faster
799+than previous versions. It also fixes an error with zone transfers (AXFR)
800+and entries with multiple relativeDomainName values. The problem was
801+that it would only use the first value in the result. There's no need
802+to upgrade unless you use such entries.
803+
804+0.8 uses asynchronous LDAP search which should give better performance.
805+Thanks to Ashley Burston for providing patch. Another new feature is
806+allowing filters in URLs. The syntax is as in RFC 2255. Few people will
807+need this, but if you have say an internal and external version of the
808+same zone, you could stick say o=internal and o=external into different
809+entries, and specify for instance ldap://host/base???(o=internal)
810+Some error logging has also been added.
811+
812+0.7 allows space and other characters to be used in URLs by use of %-quoting.
813+For instance space can be written as %20. It also fixes a problem with some
814+servers and/or APIs that do not preserve attribute casing.
815+
816+0.6 fixes some memory leaks present in older versions unless compiled with
817+the RFC 1823 API.
818+
819+The big changes in 0.5 are thread support and improved connection handling.
820+Multiple threads can now access the back-end simultaneously, and rather than
821+having one connection per zone, there is now one connection per thread per
822+LDAP server. This should help people with multiple CPUs and people with a
823+huge number of zones. One final change is support for literal IPv6 addresses
824+in LDAP URLs. At least OpenLDAP 2 has IPv6 support, so if you use OpenLDAP 2
825+libraries and server, you got all you need.
826+
827+If you have bug reports, fixes, comments, questions or whatever, please
828+contact me. See also http://www.venaas.no/ldap/bind-sdb/ for information.
829+
830+See INSTALL for how to build, install and use.
831+
832+Stig Venaas <venaas@uninett.no> 2001-12-29
This page took 0.141862 seconds and 4 git commands to generate.