--- 9.3.0 released ---
+1707. [contrib] sdb/ldap updated to version 1.0-beta.
+
1701. [doc] A minimal named.conf man page.
1700. [func] nslookup is no longer to be treated as deprecated.
-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.
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
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:
+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/
+
+To make BIND use a zone stored in LDAP, you will have to put something
+like this in 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)".
+
+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> 2002-04-17
+Stig Venaas <venaas@uninett.no> 2004-08-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)
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
/*
- * 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>
char *filterone;
int filteronelen;
char *filtername;
+ char *bindname;
+ char *bindpw;
+#ifdef LDAPDB_TLS
+ int tls;
+#endif
};
/* used by ldapdb_getconn */
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,
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;
}
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;
*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;
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);
}
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);
}
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)
void *driverdata, void **dbdata)
{
struct ldapdb_data *data;
- char *s, *filter = NULL;
+ char *s, *filter = NULL, *extensions = NULL;
int defaultttl;
UNUSED(driverdata);
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;
- if ((data->base != NULL && unhex(data->base) == NULL) || (filter != NULL && unhex(filter) == NULL)) {
+ 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;