1707. [contrib] sdb/ldap updated to version 1.0-beta.

This commit is contained in:
Mark Andrews 2004-08-27 00:07:23 +00:00
parent c7cfffdfe8
commit 9cc53f2a08
4 changed files with 190 additions and 41 deletions

View file

@ -1,3 +1,5 @@
1707. [contrib] sdb/ldap updated to version 1.0-beta.
1706. [placeholder] rt12328
1705. [placeholder] rt12327

View file

@ -1,12 +1,12 @@
This is the INSTALL file for 0.9. See
This is the INSTALL file for 1.0-beta. 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.
the instructions in doc/misc/sdb, if my instructions don't make sense,
please have a look at those as well.
Copy ldapdb.c to bin/named and ldapdb.h to bin/named/include in the
source tree.
@ -22,11 +22,19 @@ Finally you need to edit bin/named/main.c. Below where it says
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.
Now you should hopefully be able to build as usual; first configure
and then make. 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
LDAPDB_RFC1823API" line near the top of ldapdb.c.
Also, if you're using an LDAPv2 only server, you need to change
the line "#define LDAPDB_LDAP_VERSION 3" in ldapdb.c. Simply
replace 3 with 2. Instead of editing the file, you may define
LDAPDB_LDAP_VERSION yourself.
If you want to use TLS, you need to uncommed the #define LDAPDB_TLS"
line near the top of ldapdb.c.
CONFIGURING
@ -34,26 +42,42 @@ 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/
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 make BIND use a zone stored in LDAP, you will have to put something
like this in named.conf:
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";
database "ldap ldap://158.38.160.245/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)
haven't got the dNSTTL attribute. It is also possible to add a filter to
the URL, say "ldap://host/base???(o=internal)".
Stig Venaas <venaas@uninett.no> 2002-04-17
Version 1.0 also has support for simple LDAP bind, that is, binding to
LDAP using plain text authentication. The bind dn and password is coded
into the URL as extensions, according to RFC 2255. If you want simple
bind with say dn "cn=Manager,dc=venaas,dc=no" and password "secret", the
URL will be something like this:
ldap://158.38.160.245/dc=venaas,dc=com,o=DNS,dc=venaas,dc=no????!bindname=cn=Manager%2cdc=venaas%2cdc=no,!x-bindpw=secret
This URL may also include a filter part if you need it. Note that in
the bind dn, "," is hex-escaped as "%2c". This is necessary since ","
is the separator between the extension elements. The "!" in front of
"bindname" and "x-bindpw" can be omitted if you prefer. "x-bindpw" is
not standardized, but it's used by several other LDAP applications. See
RFC 2255 for details.
Finally, if you enabled TLS when compiling, you can also use TLS if
you like. To do this you use the extension "x-tls", e.g.
ldap://158.38.160.245/dc=venaas,dc=com,o=DNS,dc=venaas,dc=no????!bindname=cn=Manager%2cdc=venaas%2cdc=no,!x-bindpw=secret,x-tls
Stig Venaas <venaas@uninett.no> 2004-08-15

View file

@ -1,7 +1,15 @@
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.
database interface "sdb". This is release 1.0-beta and should be pretty
stable. Note that since version 0.4 a new schema is used. It is not
backwards compatible with versions before 0.4.
1.0-beta fixes a large memory leak. An extension x-tls for enabling TLS
has been added.
1.0-alpha uses LDAPv3 by default and also supports LDAP simple bind. That
is, one can use plain text password for authentication. The bind dn and
password is coded into the URL using extensions bindname and x-bindpw
per RFC 2255.
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)
@ -37,4 +45,4 @@ 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-12-29
Stig Venaas <venaas@uninett.no> 2004-08-15

View file

@ -1,18 +1,31 @@
/*
* ldapdb.c version 0.9
* ldapdb.c version 1.0-beta
*
* Copyright (C) 2002 Stig Venaas
* 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 RFC1823API */
/* #define LDAPDB_RFC1823API */
/* Using LDAPv3 by default, change this if you want v2 */
#ifndef LDAPDB_LDAP_VERSION
#define LDAPDB_LDAP_VERSION 3
#endif
#include <config.h>
@ -55,6 +68,11 @@ struct ldapdb_data {
char *filterone;
int filteronelen;
char *filtername;
char *bindname;
char *bindpw;
#ifdef LDAPDB_TLS
int tls;
#endif
};
/* used by ldapdb_getconn */
@ -160,7 +178,7 @@ ldapdb_getconn(struct ldapdb_data *data)
conndata = malloc(sizeof(*conndata));
if (conndata == NULL)
return (NULL);
(char *)conndata->index = data->hostport;
conndata->index = data->hostport;
conndata->size = strlen(data->hostport);
conndata->data = NULL;
ldapdb_insert((struct ldapdb_entry **)&threaddata->data,
@ -173,12 +191,27 @@ ldapdb_getconn(struct ldapdb_data *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;
if (ldap_simple_bind_s(*ldp, NULL, NULL) != LDAP_SUCCESS) {
#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;
}
@ -191,9 +224,9 @@ ldapdb_search(const char *zone, const char *name, void *dbdata, void *retdata)
isc_result_t result = ISC_R_NOTFOUND;
LDAP **ldp;
LDAPMessage *res, *e;
char *fltr, *a, **vals, **names = NULL;
char *fltr, *a, **vals = NULL, **names = NULL;
char type[64];
#ifdef RFC1823API
#ifdef LDAPDB_RFC1823API
void *ptr;
#else
BerElement *ptr;
@ -278,7 +311,7 @@ ldapdb_search(const char *zone, const char *name, void *dbdata, void *retdata)
*s = toupper(*s);
s = strstr(a, "RECORD");
if ((s == NULL) || (s == a) || (s - a >= (signed int)sizeof(type))) {
#ifndef RFC1823API
#ifndef LDAPDB_RFC1823API
ldap_memfree(a);
#endif
continue;
@ -302,7 +335,7 @@ ldapdb_search(const char *zone, const char *name, void *dbdata, void *retdata)
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 RFC1823API
#ifndef LDAPDB_RFC1823API
ldap_memfree(a);
if (ptr != NULL)
ber_free(ptr, 0);
@ -315,21 +348,23 @@ ldapdb_search(const char *zone, const char *name, void *dbdata, void *retdata)
}
ldap_value_free(vals);
}
#ifndef RFC1823API
#ifndef LDAPDB_RFC1823API
ldap_memfree(a);
#endif
}
#ifndef RFC1823API
#ifndef LDAPDB_RFC1823API
if (ptr != NULL)
ber_free(ptr, 0);
#endif
if (name == NULL)
ldap_value_free(names);
/* cleanup this result */
/* free this result */
ldap_msgfree(res);
}
/* free final result */
ldap_msgfree(res);
return (result);
}
@ -371,7 +406,56 @@ unhex(char *in)
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)
@ -393,7 +477,7 @@ ldapdb_create(const char *zone, int argc, char **argv,
void *driverdata, void **dbdata)
{
struct ldapdb_data *data;
char *s, *filter = NULL;
char *s, *filter = NULL, *extensions = NULL;
int defaultttl;
UNUSED(driverdata);
@ -439,6 +523,15 @@ ldapdb_create(const char *zone, int argc, char **argv,
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;
@ -449,15 +542,37 @@ ldapdb_create(const char *zone, int argc, char **argv,
if (*data->base == '\0') {
data->base = NULL;
}
}
if ((data->base != NULL && unhex(data->base) == NULL) || (filter != NULL && unhex(filter) == NULL)) {
/* parse extensions */
if (extensions != NULL) {
int err;
err = parseextensions(extensions, data);
if (err < 0) {
/* err should be -1 or -2 */
free_data(data);
isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, ISC_LOG_ERROR,
"LDAP sdb zone '%s': bad hex values", zone);
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;