]> git.pld-linux.org Git - packages/bind.git/blob - bind-sdb-ldap.patch
Up to 9.18.25
[packages/bind.git] / bind-sdb-ldap.patch
1 diff -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} \
18 diff -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 +
28 diff -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
31 @@ -0,0 +1,667 @@
32 +/*
33 + * ldapdb.c version 1.0-beta
34 + *
35 + * Copyright (C) 2002, 2004 Stig Venaas
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.
40 + *
41 + * Contributors: Jeremy C. McDermond
42 + */
43 +
44 +/*
45 + * If you want to use TLS, uncomment the define below
46 + */
47 +/* #define LDAPDB_TLS */
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().
52 + * This also forces LDAPv2.
53 + */
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
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;
102 +       char *bindname;
103 +       char *bindpw;
104 +#ifdef LDAPDB_TLS
105 +       int tls;
106 +#endif
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);
212 +               conndata->index = data->hostport;
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 +{
225 +#ifndef LDAPDB_RFC1823API
226 +       const int ver = LDAPDB_LDAP_VERSION;
227 +#endif
228 +
229 +       if (*ldp != NULL)
230 +               ldap_unbind(*ldp);
231 +       *ldp = ldap_open(data->hostname, data->portno);
232 +       if (*ldp == NULL)
233 +               return;
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) {
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;
258 +       char *fltr, *a, **vals = NULL, **names = NULL;
259 +       char type[64];
260 +#ifdef LDAPDB_RFC1823API
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))) {
345 +#ifndef LDAPDB_RFC1823API
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);
369 +#ifndef LDAPDB_RFC1823API
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 +                       }
382 +#ifndef LDAPDB_RFC1823API
383 +                       ldap_memfree(a);
384 +#endif
385 +               }
386 +#ifndef LDAPDB_RFC1823API
387 +               if (ptr != NULL)
388 +                       ber_free(ptr, 0);
389 +#endif
390 +               if (name == NULL)
391 +                       ldap_value_free(names);
392 +
393 +               /* free this result */
394 +               ldap_msgfree(res);
395 +       }
396 +
397 +       /* free final result */
398 +       ldap_msgfree(res);
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 +
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;
465 +
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 +}
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;
511 +       char *s, *filter = NULL, *extensions = NULL;
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';
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 +                                               }
566 +                                       }
567 +                                       if (*filter == '\0') {
568 +                                               filter = NULL;
569 +                                       }
570 +                               }
571 +                       }
572 +               }
573 +               if (*data->base == '\0') {
574 +                       data->base = NULL;
575 +               }
576 +       }
577 +
578 +       /* parse extensions */
579 +       if (extensions != NULL) {
580 +               int err;
581 +
582 +               err = parseextensions(extensions, data);
583 +               if (err < 0) {
584 +                       /* err should be -1 or -2 */
585 +                       free_data(data);
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 +                       }
593 +                       return (ISC_R_FAILURE);
594 +               }
595 +       }
596 +
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 +
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 +}
699 diff -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");
726 diff -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
789 diff -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.1641 seconds and 3 git commands to generate.