dhcp/dhcp-3.0.5-ldap-configuration.patch

1490 lines
43 KiB
Diff

--- dhcp-3.0.5/common/conflex.c.ldap 2006-02-22 17:43:27.000000000 -0500
+++ dhcp-3.0.5/common/conflex.c 2007-03-29 15:11:19.000000000 -0400
@@ -47,6 +47,7 @@
static enum dhcp_token read_number PROTO ((int, struct parse *));
static enum dhcp_token read_num_or_name PROTO ((int, struct parse *));
static enum dhcp_token intern PROTO ((char *, enum dhcp_token));
+static int read_function PROTO ((struct parse *));
isc_result_t new_parse (cfile, file, inbuf, buflen, name, eolp)
struct parse **cfile;
@@ -74,6 +75,10 @@
tmp -> file = file;
tmp -> eol_token = eolp;
+ if (file != -1) {
+ tmp -> read_function = read_function;;
+ }
+
tmp -> bufix = 0;
tmp -> buflen = buflen;
if (inbuf) {
@@ -113,22 +118,11 @@
int c;
if (cfile -> bufix == cfile -> buflen) {
- if (cfile -> file != -1) {
- cfile -> buflen =
- read (cfile -> file,
- cfile -> inbuf, cfile -> bufsiz);
- if (cfile -> buflen == 0) {
- c = EOF;
- cfile -> bufix = 0;
- } else if (cfile -> buflen < 0) {
- c = EOF;
- cfile -> bufix = cfile -> buflen = 0;
- } else {
- c = cfile -> inbuf [0];
- cfile -> bufix = 1;
- }
- } else
+ if (cfile -> read_function) {
+ c = cfile -> read_function (cfile);
+ } else {
c = EOF;
+ }
} else {
c = cfile -> inbuf [cfile -> bufix];
cfile -> bufix++;
@@ -1128,3 +1122,25 @@
}
return dfv;
}
+
+
+static int
+read_function (struct parse * cfile)
+{
+ int c;
+
+ cfile -> buflen = read (cfile -> file, cfile -> inbuf, cfile -> bufsiz);
+ if (cfile -> buflen == 0) {
+ c = EOF;
+ cfile -> bufix = 0;
+ } else if (cfile -> buflen < 0) {
+ c = EOF;
+ cfile -> bufix = cfile -> buflen = 0;
+ } else {
+ c = cfile -> inbuf [0];
+ cfile -> bufix = 1;
+ }
+
+ return c;
+}
+
--- dhcp-3.0.5/common/print.c.ldap 2007-03-29 15:10:26.000000000 -0400
+++ dhcp-3.0.5/common/print.c 2007-03-29 15:11:19.000000000 -0400
@@ -166,9 +166,9 @@
}
char *print_hw_addr (htype, hlen, data)
- int htype;
- int hlen;
- unsigned char *data;
+ const int htype;
+ const int hlen;
+ const unsigned char *data;
{
static char habuf [49];
char *s;
--- dhcp-3.0.5/includes/dhcpd.h.ldap 2007-03-29 15:10:26.000000000 -0400
+++ dhcp-3.0.5/includes/dhcpd.h 2007-03-29 15:11:19.000000000 -0400
@@ -79,6 +79,11 @@
#include <isc-dhcp/result.h>
#include <omapip/omapip_p.h>
+#if defined(LDAP_CONFIGURATION)
+# include <ldap.h>
+# include <sys/utsname.h> /* for uname() */
+#endif
+
#if !defined (OPTION_HASH_SIZE)
# define OPTION_HASH_SIZE 17
# define OPTION_HASH_PTWO 32 /* Next power of two above option hash. */
@@ -139,6 +144,8 @@
char *inbuf;
unsigned bufix, buflen;
unsigned bufsiz;
+
+ int (*read_function) (struct parse *);
};
/* Variable-length array of data. */
@@ -244,6 +251,27 @@
u_int8_t hbuf [17];
};
+#if defined(LDAP_CONFIGURATION)
+# define LDAP_BUFFER_SIZE 8192
+# define LDAP_METHOD_STATIC 0
+# define LDAP_METHOD_DYNAMIC 1
+
+/* This is a tree of the current configuration we are building from LDAP */
+
+struct ldap_config_stack {
+ LDAPMessage * res; /* Pointer returned from ldap_search */
+ LDAPMessage * ldent; /* Current item in LDAP that we're processing
+ in res */
+ int close_brace; /* Put a closing } after we're through with
+ this item */
+ int processed; /* We set this flag if this base item has been
+ processed. After this base item is processed,
+ we can start processing the children */
+ struct ldap_config_stack *children;
+ struct ldap_config_stack *next;
+};
+#endif
+
typedef enum {
server_startup = 0,
server_running = 1,
@@ -426,6 +454,15 @@
# define DEFAULT_PING_TIMEOUT 1
#endif
+#if defined(LDAP_CONFIGURATION)
+# define SV_LDAP_SERVER 47
+# define SV_LDAP_PORT 48
+# define SV_LDAP_USERNAME 49
+# define SV_LDAP_PASSWORD 50
+# define SV_LDAP_BASE_DN 51
+# define SV_LDAP_METHOD 52
+#endif
+
#if !defined (DEFAULT_DEFAULT_LEASE_TIME)
# define DEFAULT_DEFAULT_LEASE_TIME 43200
#endif
@@ -1531,7 +1568,7 @@
char *quotify_string (const char *, const char *, int);
char *quotify_buf (const unsigned char *, unsigned, const char *, int);
char *print_base64 (const unsigned char *, unsigned, const char *, int);
-char *print_hw_addr PROTO ((int, int, unsigned char *));
+char *print_hw_addr PROTO ((const int, const int, const unsigned char *));
void print_lease PROTO ((struct lease *));
void dump_raw PROTO ((const unsigned char *, unsigned));
void dump_packet_option (struct option_cache *, struct packet *,
@@ -2639,3 +2676,14 @@
#endif /* FAILOVER_PROTOCOL */
const char *binding_state_print (enum failover_state);
+
+/* ldap.c */
+#if defined(LDAP_CONFIGURATION)
+extern struct enumeration ldap_methods;
+isc_result_t ldap_read_config (void);
+int find_haddr_in_ldap (struct host_decl **, int, unsigned,
+ const unsigned char *, const char *, int);
+int find_subclass_in_ldap (struct class *, struct class **,
+ struct data_string *);
+#endif
+
--- dhcp-3.0.5/includes/site.h.ldap 2002-03-12 13:33:39.000000000 -0500
+++ dhcp-3.0.5/includes/site.h 2007-03-29 15:11:19.000000000 -0400
@@ -177,3 +177,13 @@
traces. */
#define TRACING
+
+/* Define this if you want to read your config from LDAP. Read README.ldap
+ about how to set this up */
+
+#define LDAP_CONFIGURATION
+
+#define _PATH_DHCPD_DB "/var/lib/dhcpd/dhcpd.leases"
+#define _PATH_DHCLIENT_DB "/var/lib/dhclient/dhclient.leases"
+#define _PATH_DHCPD_DB "/var/lib/dhcpd/dhcpd.leases"
+#define _PATH_DHCLIENT_DB "/var/lib/dhclient/dhclient.leases"
--- dhcp-3.0.5/server/Makefile.dist.ldap 2004-06-10 13:59:50.000000000 -0400
+++ dhcp-3.0.5/server/Makefile.dist 2007-03-29 15:11:19.000000000 -0400
@@ -25,9 +25,9 @@
CATMANPAGES = dhcpd.cat8 dhcpd.conf.cat5 dhcpd.leases.cat5
SEDMANPAGES = dhcpd.man8 dhcpd.conf.man5 dhcpd.leases.man5
SRCS = dhcpd.c dhcp.c bootp.c confpars.c db.c class.c failover.c \
- omapi.c mdb.c stables.c salloc.c ddns.c
+ omapi.c mdb.c stables.c salloc.c ddns.c ldap.c
OBJS = dhcpd.o dhcp.o bootp.o confpars.o db.o class.o failover.o \
- omapi.o mdb.o stables.o salloc.o ddns.o
+ omapi.o mdb.o stables.o salloc.o ddns.o ldap.o
PROG = dhcpd
MAN = dhcpd.8 dhcpd.conf.5 dhcpd.leases.5
@@ -103,6 +103,6 @@
-e "s#RUNDIR#$(VARRUN)#g" < dhcpd.leases.5 >dhcpd.leases.man5
dhcpd: $(OBJS) $(COBJ) $(DHCPLIB)
- $(CC) $(LFLAGS) -o dhcpd $(OBJS) $(DHCPLIB) $(LIBS)
+ $(CC) $(LFLAGS) -o dhcpd $(OBJS) $(DHCPLIB) $(LIBS) -lldap
# Dependencies (semi-automatically-generated)
--- dhcp-3.0.5/server/class.c.ldap 2004-06-10 13:59:51.000000000 -0400
+++ dhcp-3.0.5/server/class.c 2007-03-29 15:11:19.000000000 -0400
@@ -90,6 +90,7 @@
int matched = 0;
int status;
int ignorep;
+ int classfound;
for (class = collection -> classes; class; class = class -> nic) {
#if defined (DEBUG_CLASS_MATCHING)
@@ -135,9 +136,19 @@
class -> submatch, MDL));
if (status && data.len) {
nc = (struct class *)0;
- if (class_hash_lookup (&nc, class -> hash,
- (const char *)data.data,
- data.len, MDL)) {
+ classfound = class_hash_lookup (&nc,
+ class -> hash,
+ (const char *)data.data,
+ data.len, MDL);
+
+#ifdef LDAP_CONFIGURATION
+ if (!classfound &&
+ find_subclass_in_ldap (class,
+ &nc, &data))
+ classfound = 1;
+#endif
+
+ if (classfound) {
#if defined (DEBUG_CLASS_MATCHING)
log_info ("matches subclass %s.",
print_hex_1 (data.len,
--- dhcp-3.0.5/server/confpars.c.ldap 2007-03-29 15:10:26.000000000 -0400
+++ dhcp-3.0.5/server/confpars.c 2007-03-29 15:11:19.000000000 -0400
@@ -63,7 +63,17 @@
isc_result_t readconf ()
{
- return read_conf_file (path_dhcpd_conf, root_group, ROOT_GROUP, 0);
+ isc_result_t res;
+
+ res = read_conf_file (path_dhcpd_conf, root_group, ROOT_GROUP, 0);
+#if defined(LDAP_CONFIGURATION)
+ if (res != ISC_R_SUCCESS)
+ return (res);
+
+ return ldap_read_config ();
+#else
+ return (res);
+#endif
}
isc_result_t read_conf_file (const char *filename, struct group *group,
--- dhcp-3.0.5/server/dhcpd.c.ldap 2007-03-29 15:10:26.000000000 -0400
+++ dhcp-3.0.5/server/dhcpd.c 2007-03-29 15:11:19.000000000 -0400
@@ -433,6 +433,9 @@
/* Add the ddns update style enumeration prior to parsing. */
add_enumeration (&ddns_styles);
add_enumeration (&syslog_enum);
+#if defined (LDAP_CONFIGURATION)
+ add_enumeration (&ldap_methods);
+#endif
if (!group_allocate (&root_group, MDL))
log_fatal ("Can't allocate root group!");
--- /dev/null 2007-03-29 11:34:09.579686084 -0400
+++ dhcp-3.0.5/server/ldap.c 2007-03-29 15:11:19.000000000 -0400
@@ -0,0 +1,1142 @@
+/* ldap.c
+
+ Routines for reading the configuration from LDAP */
+
+/*
+ * Copyright (c) 1996-2001 Ntelos, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of The Internet Software Consortium nor the names
+ * of its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
+ * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This LDAP module was written by Brian Masney <masneyb@ntelos.net>. It's
+ * development was sponsored by Ntelos, Inc. (www.ntelos.com).
+ */
+
+#include "dhcpd.h"
+
+#if defined(LDAP_CONFIGURATION)
+
+static LDAP * ld = NULL;
+static char *ldap_server = NULL,
+ *ldap_username = NULL,
+ *ldap_password = NULL,
+ *ldap_base_dn = NULL;
+static int ldap_method = LDAP_METHOD_DYNAMIC,
+ disable_ldap = 0;
+static struct ldap_config_stack *ldap_stack = NULL;
+
+
+static void
+ldap_parse_class (struct ldap_config_stack *item, struct parse *cfile)
+{
+ struct berval **temp;
+
+ if ((temp = ldap_get_values_len (ld, item->ldent, "cn")) == NULL ||
+ temp[0]->bv_val == NULL)
+ {
+ if (temp != NULL)
+ ldap_value_free_len (temp);
+
+ return;
+ }
+
+ strncat (cfile->inbuf, "class \"", LDAP_BUFFER_SIZE);
+ strncat (cfile->inbuf, temp[0]->bv_val, LDAP_BUFFER_SIZE);
+ strncat (cfile->inbuf, "\" {\n", LDAP_BUFFER_SIZE);
+
+ item->close_brace = 1;
+ ldap_value_free_len (temp);
+}
+
+
+static void
+ldap_parse_subclass (struct ldap_config_stack *item, struct parse *cfile)
+{
+ struct berval **temp, **classdata;
+
+ if ((temp = ldap_get_values_len (ld, item->ldent, "cn")) == NULL ||
+ temp[0]->bv_val == NULL)
+ {
+ if (temp != NULL)
+ ldap_value_free_len (temp);
+
+ return;
+ }
+
+
+ if ((classdata = ldap_get_values_len (ld, item->ldent,
+ "dhcpClassData")) == NULL ||
+ classdata[0]->bv_val == NULL)
+ {
+ if (classdata != NULL)
+ ldap_value_free_len (classdata);
+ ldap_value_free_len (temp);
+
+ return;
+ }
+
+ strncat (cfile->inbuf, "subclass ", LDAP_BUFFER_SIZE);
+ strncat (cfile->inbuf, (*classdata)->bv_val, LDAP_BUFFER_SIZE);
+ strncat (cfile->inbuf, " ", LDAP_BUFFER_SIZE);
+ strncat (cfile->inbuf, (*temp)->bv_val, LDAP_BUFFER_SIZE);
+ strncat (cfile->inbuf, " {\n", LDAP_BUFFER_SIZE);
+
+ item->close_brace = 1;
+ ldap_value_free_len (temp);
+ ldap_value_free_len (classdata);
+}
+
+
+static void
+ldap_parse_host (struct ldap_config_stack *item, struct parse *cfile)
+{
+ struct berval **temp, **hwaddr;
+
+
+ if ((temp = ldap_get_values_len (ld, item->ldent, "cn")) == NULL ||
+ temp[0]->bv_val == NULL)
+ {
+ if (temp != NULL)
+ ldap_value_free_len (temp);
+
+ return;
+ }
+
+ if ((hwaddr = ldap_get_values_len (ld, item->ldent,
+ "dhcpHWAddress")) == NULL ||
+ hwaddr[0]->bv_val == NULL)
+ {
+ if (hwaddr != NULL)
+ ldap_value_free_len (hwaddr);
+ ldap_value_free_len (temp);
+
+ return;
+ }
+
+ strncat (cfile->inbuf, "host ", LDAP_BUFFER_SIZE);
+ strncat (cfile->inbuf, (*temp)->bv_val, LDAP_BUFFER_SIZE);
+ strncat (cfile->inbuf, " {\nhardware ", LDAP_BUFFER_SIZE);
+ strncat (cfile->inbuf, (*hwaddr)->bv_val, LDAP_BUFFER_SIZE);
+ strncat (cfile->inbuf, ";\n", LDAP_BUFFER_SIZE);
+
+ item->close_brace = 1;
+ ldap_value_free_len (temp);
+ ldap_value_free_len (hwaddr);
+}
+
+
+static void
+ldap_parse_shared_network (struct ldap_config_stack *item, struct parse *cfile)
+{
+ struct berval **temp;
+
+
+ if ((temp = ldap_get_values_len (ld, item->ldent, "cn")) == NULL ||
+ temp[0]->bv_val == NULL)
+ {
+ if (temp != NULL)
+ ldap_value_free_len (temp);
+
+ return;
+ }
+
+ strncat (cfile->inbuf, "shared-network ", LDAP_BUFFER_SIZE);
+ strncat (cfile->inbuf, (*temp)->bv_val, LDAP_BUFFER_SIZE);
+ strncat (cfile->inbuf, " {\n", LDAP_BUFFER_SIZE);
+
+ item->close_brace = 1;
+ ldap_value_free_len (temp);
+}
+
+
+static void
+parse_netmask (int netmask, char *netmaskbuf)
+{
+ unsigned long nm;
+ int i;
+
+ nm = 0;
+ for (i=1; i <= netmask; i++)
+ {
+ nm |= 1 << (32 - i);
+ }
+
+ sprintf (netmaskbuf, "%d.%d.%d.%d", (int) (nm >> 24) & 0xff,
+ (int) (nm >> 16) & 0xff,
+ (int) (nm >> 8) & 0xff,
+ (int) nm & 0xff);
+}
+
+static void
+ldap_parse_subnet (struct ldap_config_stack *item, struct parse *cfile)
+{
+ struct berval **temp, **netmask;
+ char netmaskbuf[16];
+ int i;
+
+ if ((temp = ldap_get_values_len (ld, item->ldent, "cn")) == NULL ||
+ temp[0]->bv_val == NULL)
+ {
+ if (temp != NULL)
+ ldap_value_free_len (temp);
+
+ return;
+ }
+
+ if ((netmask = ldap_get_values_len (ld, item->ldent,
+ "dhcpNetmask")) == NULL ||
+ netmask[0]->bv_val == NULL)
+ {
+ if (netmask != NULL)
+ ldap_value_free_len (netmask);
+ ldap_value_free_len (temp);
+
+ return;
+ }
+
+ strncat (cfile->inbuf, "subnet ", LDAP_BUFFER_SIZE);
+ strncat (cfile->inbuf, temp[0]->bv_val, LDAP_BUFFER_SIZE);
+
+ strncat (cfile->inbuf, " netmask ", LDAP_BUFFER_SIZE);
+ parse_netmask (strtol (netmask[0]->bv_val, NULL, 10), netmaskbuf);
+ strncat (cfile->inbuf, netmaskbuf, LDAP_BUFFER_SIZE);
+
+ strncat (cfile->inbuf, " {\n", LDAP_BUFFER_SIZE);
+
+ ldap_value_free_len (temp);
+ ldap_value_free_len (netmask);
+
+ if ((temp = ldap_get_values_len (ld, item->ldent, "dhcpRange")) != NULL)
+ {
+ strncat (cfile->inbuf, "range", LDAP_BUFFER_SIZE);
+ for (i=0; temp[i] != NULL && temp[i]->bv_val != NULL; i++)
+ {
+ strncat (cfile->inbuf, " ", LDAP_BUFFER_SIZE);
+ strncat (cfile->inbuf, temp[i]->bv_val, LDAP_BUFFER_SIZE);
+ }
+ strncat (cfile->inbuf, ";\n", LDAP_BUFFER_SIZE);
+ ldap_value_free_len (temp);
+ }
+
+ item->close_brace = 1;
+}
+
+
+static void
+ldap_parse_pool (struct ldap_config_stack *item, struct parse *cfile)
+{
+ struct berval **temp;
+ int i;
+
+ strncat (cfile->inbuf, "pool {\n", LDAP_BUFFER_SIZE);
+
+ if ((temp = ldap_get_values_len (ld, item->ldent, "dhcpRange")) != NULL)
+ {
+ strncat (cfile->inbuf, "range", LDAP_BUFFER_SIZE);
+ for (i=0; temp[i] != NULL && temp[i]->bv_val != NULL; i++)
+ {
+ strncat (cfile->inbuf, " ", LDAP_BUFFER_SIZE);
+ strncat (cfile->inbuf, temp[i]->bv_val, LDAP_BUFFER_SIZE);
+ }
+ strncat (cfile->inbuf, ";\n", LDAP_BUFFER_SIZE);
+ ldap_value_free_len (temp);
+ }
+
+ if ((temp = ldap_get_values_len (ld, item->ldent, "dhcpPermitList")) != NULL)
+ {
+ for (i=0; temp[i] != NULL && temp[i]->bv_val != NULL; i++)
+ {
+ strncat (cfile->inbuf, temp[i]->bv_val, LDAP_BUFFER_SIZE);
+ strncat (cfile->inbuf, ";\n", LDAP_BUFFER_SIZE);
+ }
+ ldap_value_free_len (temp);
+ }
+
+ item->close_brace = 1;
+}
+
+
+static void
+ldap_parse_group (struct ldap_config_stack *item, struct parse *cfile)
+{
+ strncat (cfile->inbuf, "group {\n", LDAP_BUFFER_SIZE);
+ item->close_brace = 1;
+}
+
+
+static void
+parse_external_dns (LDAPMessage * ent)
+{
+ char *search[] = {"dhcpOptionsDN", "dhcpSharedNetworkDN", "dhcpSubnetDN",
+ "dhcpGroupDN", "dhcpHostDN", "dhcpClassesDN",
+ "dhcpPoolDN", NULL};
+ LDAPMessage * newres, * newent;
+ struct ldap_config_stack *ns;
+ struct berval **temp;
+ int i, ret;
+
+ for (i=0; search[i] != NULL; i++)
+ {
+ if ((ldap_method == LDAP_METHOD_DYNAMIC) &&
+ (strcmp (search[i], "dhcpHostDN") == 0))
+ continue;
+
+ if ((temp = ldap_get_values_len (ld, ent, search[i])) == NULL)
+ continue;
+
+ if ((ret = ldap_search_ext_s (ld, temp[0]->bv_val, LDAP_SCOPE_BASE,
+ "objectClass=*", NULL, 0,
+ NULL, NULL, NULL, 0,
+ &newres)) != LDAP_SUCCESS)
+ {
+ ldap_value_free_len (temp);
+ ldap_unbind_ext (ld, NULL, NULL);
+ ld = NULL;
+ return;
+ }
+
+ ldap_value_free_len (temp);
+
+ newent = ldap_first_entry (ld, newres);
+ if (newent == NULL)
+ {
+ ldap_msgfree (newres);
+ continue;
+ }
+
+#if defined(DEBUG_LDAP)
+ log_info ("Adding LDAP entry '%s' as child", ldap_get_dn (ld, newent));
+#endif
+
+ ns = dmalloc (sizeof (*ns), MDL);
+ ns->res = newres;
+ ns->ldent = newent;
+ ns->close_brace = 0;
+ ns->processed = 0;
+ ns->children = NULL;
+ ns->next = ldap_stack->children;
+ ldap_stack->children = ns;
+ }
+}
+
+
+static void
+ldap_generate_config_string (struct ldap_config_stack *item, struct parse *cfile)
+{
+ struct berval **objectClass, **temp;
+ int i, j, ignore, found;
+
+ if ((objectClass = ldap_get_values_len (ld, item->ldent,
+ "objectClass")) == NULL)
+ return;
+
+ ignore = 0;
+ found = 1;
+ for (i=0; objectClass[i] != NULL && objectClass[i]->bv_val != NULL; i++)
+ {
+ if (strcmp (objectClass[i]->bv_val, "dhcpSharedNetwork") == 0)
+ ldap_parse_shared_network (item, cfile);
+ else if (strcmp (objectClass[i]->bv_val, "dhcpClass") == 0)
+ ldap_parse_class (item, cfile);
+ else if (strcmp (objectClass[i]->bv_val, "dhcpSubnet") == 0)
+ ldap_parse_subnet (item, cfile);
+ else if (strcmp (objectClass[i]->bv_val, "dhcpPool") == 0)
+ ldap_parse_pool (item, cfile);
+ else if (strcmp (objectClass[i]->bv_val, "dhcpGroup") == 0)
+ ldap_parse_group (item, cfile);
+ else if (strcmp (objectClass[i]->bv_val, "dhcpHost") == 0)
+ {
+ if (ldap_method == LDAP_METHOD_STATIC)
+ ldap_parse_host (item, cfile);
+ else
+ {
+ ignore = 1;
+ break;
+ }
+ }
+ else if (strcmp (objectClass[i]->bv_val, "dhcpSubClass") == 0)
+ {
+ if (ldap_method == LDAP_METHOD_STATIC)
+ ldap_parse_subclass (item, cfile);
+ else
+ {
+ ignore = 1;
+ break;
+ }
+ }
+ else
+ found = 0;
+
+ if (found && cfile->inbuf[0] == '\0')
+ {
+ ignore = 1;
+ break;
+ }
+ }
+
+ ldap_value_free_len (objectClass);
+
+ if (ignore)
+ return;
+
+ if ((temp = ldap_get_values_len (ld, item->ldent, "dhcpOption")) != NULL)
+ {
+ for (j=0; temp[j] != NULL && temp[j]->bv_val != NULL; j++)
+ {
+ strncat (cfile->inbuf, "option ", LDAP_BUFFER_SIZE);
+ strncat (cfile->inbuf, temp[j]->bv_val, LDAP_BUFFER_SIZE);
+ strncat (cfile->inbuf, ";\n", LDAP_BUFFER_SIZE);
+ }
+ ldap_value_free_len (temp);
+ }
+
+ if ((temp = ldap_get_values_len (ld, item->ldent, "dhcpStatements")) != NULL)
+ {
+ for (j=0; temp[j] != NULL && temp[j]->bv_val != NULL; j++)
+ {
+ strncat (cfile->inbuf, temp[j]->bv_val, LDAP_BUFFER_SIZE);
+ strncat (cfile->inbuf, ";\n", LDAP_BUFFER_SIZE);
+ }
+ ldap_value_free_len (temp);
+ }
+
+ parse_external_dns (item->ldent);
+}
+
+
+static void
+free_stack_entry (struct ldap_config_stack *item)
+{
+ ldap_msgfree (item->res);
+ dfree (item, MDL);
+}
+
+
+static void
+next_ldap_entry (struct parse *cfile)
+{
+ struct ldap_config_stack *temp_stack;
+
+ if (ldap_stack->processed && ldap_stack->children != NULL)
+ {
+ temp_stack = ldap_stack->children;
+ if (temp_stack->close_brace)
+ strncat (cfile->inbuf, "}\n", LDAP_BUFFER_SIZE);
+
+ ldap_stack->children = ldap_stack->children->next;
+ free_stack_entry (temp_stack);
+
+ if (ldap_stack->processed && ldap_stack->children != NULL)
+ return;
+ }
+
+ if (ldap_stack->close_brace)
+ {
+ strncat (cfile->inbuf, "}\n", LDAP_BUFFER_SIZE);
+ ldap_stack->close_brace = 0;
+ }
+
+ while (ldap_stack != NULL && ldap_stack->children == NULL &&
+ (ldap_stack->ldent = ldap_next_entry (ld, ldap_stack->ldent)) == NULL)
+ {
+ if (ldap_stack->close_brace)
+ {
+ strncat (cfile->inbuf, "}\n", LDAP_BUFFER_SIZE);
+ ldap_stack->close_brace = 0;
+ }
+
+ temp_stack = ldap_stack;
+ ldap_stack = ldap_stack->next;
+ free_stack_entry (temp_stack);
+ }
+
+ if (ldap_stack != NULL && ldap_stack->children == NULL &&
+ ldap_stack->close_brace)
+ {
+ strncat (cfile->inbuf, "}\n", LDAP_BUFFER_SIZE);
+ ldap_stack->close_brace = 0;
+ }
+}
+
+
+static void
+add_to_config_stack (LDAPMessage * res, LDAPMessage * ent)
+{
+ struct ldap_config_stack *ns;
+
+ ns = dmalloc (sizeof (*ns), MDL);
+ ns->res = res;
+ ns->ldent = ent;
+ ns->close_brace = 0;
+ ns->processed = 0;
+ ns->children = NULL;
+ ns->next = ldap_stack;
+ ldap_stack = ns;
+}
+
+
+static void
+ldap_start (void)
+{
+ struct option_state *options;
+ struct option_cache *oc;
+ struct data_string db;
+ int ret;
+
+ if (ld != NULL)
+ return;
+
+ if (ldap_server == NULL)
+ {
+ options = NULL;
+ option_state_allocate (&options, MDL);
+
+ execute_statements_in_scope ((struct binding_value **) NULL,
+ (struct packet *) NULL, (struct lease *) NULL,
+ (struct client_state *) NULL, (struct option_state *) NULL,
+ options, &global_scope, root_group, (struct group *) NULL);
+
+ memset (&db, 0, sizeof (db));
+ oc = lookup_option (&server_universe, options, SV_LDAP_SERVER);
+ if (oc &&
+ evaluate_option_cache (&db, (struct packet*) NULL,
+ (struct lease *) NULL, (struct client_state *) NULL,
+ options, (struct option_state *) NULL, &global_scope, oc, MDL))
+ {
+ ldap_server = dmalloc (db.len + 1, MDL);
+ if (!ldap_server)
+ log_fatal ("no memory for ldap server");
+ memcpy (ldap_server, db.data, db.len);
+ ldap_server[db.len] = 0;
+ data_string_forget (&db, MDL);
+ }
+
+ oc = lookup_option (&server_universe, options, SV_LDAP_USERNAME);
+ if (oc &&
+ evaluate_option_cache (&db, (struct packet*) NULL,
+ (struct lease *) NULL, (struct client_state *) NULL,
+ options, (struct option_state *) NULL, &global_scope, oc, MDL))
+ {
+ ldap_username = dmalloc (db.len + 1, MDL);
+ if (!ldap_username)
+ log_fatal ("no memory for ldap username");
+ memcpy (ldap_username, db.data, db.len);
+ ldap_username[db.len] = 0;
+ data_string_forget (&db, MDL);
+ }
+
+ oc = lookup_option (&server_universe, options, SV_LDAP_PASSWORD);
+ if (oc &&
+ evaluate_option_cache (&db, (struct packet*) NULL,
+ (struct lease *) NULL, (struct client_state *) NULL,
+ options, (struct option_state *) NULL, &global_scope, oc, MDL))
+ {
+ ldap_password = dmalloc (db.len + 1, MDL);
+ if (!ldap_password)
+ log_fatal ("no memory for ldap password");
+ memcpy (ldap_password, db.data, db.len);
+ ldap_password[db.len] = 0;
+ data_string_forget (&db, MDL);
+ }
+
+ oc = lookup_option (&server_universe, options, SV_LDAP_BASE_DN);
+ if (oc &&
+ evaluate_option_cache (&db, (struct packet*) NULL,
+ (struct lease *) NULL, (struct client_state *) NULL,
+ options, (struct option_state *) NULL, &global_scope, oc, MDL))
+ {
+ ldap_base_dn = dmalloc (db.len + 1, MDL);
+ if (!ldap_base_dn)
+ log_fatal ("no memory for ldap password");
+ memcpy (ldap_base_dn, db.data, db.len);
+ ldap_base_dn[db.len] = 0;
+ data_string_forget (&db, MDL);
+ }
+
+ oc = lookup_option (&server_universe, options, SV_LDAP_METHOD);
+ if (oc &&
+ evaluate_option_cache (&db, (struct packet*) NULL,
+ (struct lease *) NULL, (struct client_state *) NULL,
+ options, (struct option_state *) NULL, &global_scope, oc, MDL))
+ {
+
+ if (db.len == 1)
+ ldap_method = db.data [0];
+ else
+ log_fatal ("invalid dns update type");
+ data_string_forget (&db, MDL);
+ }
+
+ option_state_dereference (&options, MDL);
+ }
+
+ if (ldap_server == NULL || ldap_username == NULL || ldap_password == NULL ||
+ ldap_base_dn == NULL)
+ {
+ log_info ("Not searching LDAP since ldap-server, ldap-username, ldap-password and ldap-base-dn were not specified in the config file");
+ disable_ldap = 1;
+ return;
+ }
+
+#if defined (DEBUG_LDAP)
+ log_info ("Connecting to LDAP server ldap://%s", ldap_server);
+#endif
+
+ char *tmpserver = NULL;
+ if ((tmpserver = malloc(strlen(ldap_server) + 8)) == NULL)
+ {
+ log_error ("Cannot init tmpldapserver string to ldap://%s", ldap_server);
+ disable_ldap = 1;
+ return;
+ }
+
+ if (sprintf(tmpserver, "ldap://%s", ldap_server) == -1)
+ {
+ log_error ("Cannot init tmpldapserver via sprintf()");
+ disable_ldap = 1;
+ return;
+ }
+
+ ldap_initialize (&ld, tmpserver);
+ if (ld == NULL)
+ {
+ log_error ("Cannot init ldap session to %s", ldap_server);
+ disable_ldap = 1;
+ return;
+ }
+
+ free (tmpserver);
+
+ struct berval cred;
+ cred.bv_val = strdup(ldap_password);
+ cred.bv_len = strlen(ldap_password);
+ ret = ldap_sasl_bind_s (ld, ldap_username, LDAP_SASL_SIMPLE,
+ &cred, NULL,NULL, NULL);
+ if (ret != LDAP_SUCCESS)
+ {
+ log_error ("Error: Cannot log into ldap server %s: %s", ldap_server,
+ ldap_err2string (ret));
+ disable_ldap = 1;
+ ldap_unbind_ext (ld, NULL, NULL);
+ ld = NULL;
+ return;
+ }
+
+#if defined (DEBUG_LDAP)
+ log_info ("Successfully logged into LDAP server %s", ldap_server);
+#endif
+}
+
+
+static int
+ldap_read_function (struct parse *cfile)
+{
+ char *dn, eofstring[2] = {EOF, '\0'};
+ struct ldap_config_stack *curentry;
+ LDAPMessage * ent, * res;
+ int ret;
+
+ cfile->inbuf[0] = '\0';
+ cfile->buflen = 0;
+ while (1)
+ {
+ if (ldap_stack == NULL)
+ {
+ strncat (cfile->inbuf, eofstring, LDAP_BUFFER_SIZE);
+ cfile->buflen = strlen (cfile->inbuf);
+ cfile->bufix = 1;
+ return (cfile->inbuf[0]);
+ }
+
+ if (ldap_stack->processed && ldap_stack->children != NULL)
+ curentry = ldap_stack->children;
+ else
+ curentry = ldap_stack;
+
+ dn = ldap_get_dn (ld, curentry->ldent);
+#if defined(DEBUG_LDAP)
+ log_info ("Found LDAP entry '%s'", dn);
+#endif
+
+ ldap_generate_config_string (curentry, cfile);
+ if (strlen (cfile->inbuf) == 0)
+ {
+#if defined(DEBUG_LDAP)
+ log_info ("Skipping LDAP entry '%s'", dn);
+#endif
+ ldap_memfree (dn);
+ dn = NULL;
+ next_ldap_entry (cfile);
+ continue;
+ }
+
+ curentry->processed = 1;
+ break;
+ }
+
+ if (ld == NULL)
+ ldap_start ();
+
+ if (ld == NULL)
+ {
+ strncat (cfile->inbuf, eofstring, LDAP_BUFFER_SIZE);
+ cfile->buflen = strlen (cfile->inbuf);
+ cfile->bufix = 1;
+ return (cfile->inbuf[0]);
+ }
+
+ if ((ret = ldap_search_ext_s (ld, dn, LDAP_SCOPE_ONELEVEL, "objectClass=*",
+ NULL, 0, NULL, NULL, NULL, 0,
+ &res)) != LDAP_SUCCESS)
+ {
+ ldap_unbind_ext (ld, NULL, NULL);
+ ld = NULL;
+
+ strncat (cfile->inbuf, eofstring, LDAP_BUFFER_SIZE);
+ cfile->buflen = strlen (cfile->inbuf);
+ cfile->bufix = 1;
+ return (cfile->inbuf[0]);
+ }
+
+ ldap_memfree (dn);
+
+ ent = ldap_first_entry (ld, res);
+ if (ent != NULL)
+ add_to_config_stack (res, ent);
+ else
+ {
+ ldap_msgfree (res);
+ next_ldap_entry (cfile);
+ }
+
+#if defined (DEBUG_LDAP)
+ log_info ("Sending config line '%s'", cfile->inbuf);
+#endif
+
+ cfile->buflen = strlen (cfile->inbuf);
+ cfile->bufix = 1;
+ return (cfile->inbuf[0]);
+}
+
+
+static char *
+ldap_get_host_name (LDAPMessage * ent)
+{
+ struct berval **name;
+ char *ret;
+
+ ret = NULL;
+ if ((name = ldap_get_values_len (ld, ent, "cn")) == NULL || name[0] == NULL)
+ {
+ if (name != NULL)
+ ldap_value_free_len (name);
+
+#if defined (DEBUG_LDAP)
+ log_info ("Cannot get cn attribute for LDAP entry %s",
+ ldap_get_dn (ld, ent));
+#endif
+ return (NULL);
+ }
+
+ ret = dmalloc (strlen (name[0]->bv_val) + 1, MDL);
+ strcpy (ret, name[0]->bv_val);
+ ldap_value_free_len (name);
+
+ return (ret);
+}
+
+
+isc_result_t
+ldap_read_config (void)
+{
+ struct berval **temp;
+ char *buffer, dn[256];
+ LDAPMessage * ldres, * ent;
+ struct parse *cfile;
+ struct utsname unme;
+ isc_result_t res;
+ int ret;
+
+
+ buffer = dmalloc (LDAP_BUFFER_SIZE, MDL);
+ cfile = (struct parse *) NULL;
+ res = new_parse (&cfile, -1, buffer, LDAP_BUFFER_SIZE, "LDAP", 0);
+ if (res != ISC_R_SUCCESS)
+ return (res);
+
+ cfile->bufix = cfile->buflen = 0;
+ cfile->read_function = ldap_read_function;
+
+ if (ld == NULL)
+ ldap_start ();
+ if (ld == NULL)
+ return (ldap_server == NULL ? ISC_R_SUCCESS : ISC_R_FAILURE);
+
+ uname (&unme);
+ snprintf (dn, sizeof (dn), "(&(objectClass=dhcpServer)(cn=%s))",
+ unme.nodename);
+
+ if ((ret = ldap_search_ext_s (ld, ldap_base_dn, LDAP_SCOPE_SUBTREE, dn, NULL,
+ 0, NULL, NULL, NULL, 0, &ldres)) != LDAP_SUCCESS)
+ {
+ ldap_unbind_ext (ld, NULL, NULL);
+ ld = NULL;
+ log_error ("Cannot search LDAP for %s: %s", dn, ldap_err2string (ret));
+ return (ISC_R_FAILURE);
+ }
+
+ if ((ent = ldap_first_entry (ld, ldres)) == NULL)
+ {
+ ldap_unbind_ext (ld, NULL, NULL);
+ ld = NULL;
+ log_error ("Error: Cannot find LDAP entry matching %s", dn);
+ return (ISC_R_FAILURE);
+ }
+
+#if defined(DEBUG_LDAP)
+ buffer = ldap_get_dn (ld, ent);
+ log_info ("Found LDAP entry '%s'", buffer);
+ ldap_memfree (buffer);
+#endif
+
+ if ((temp = ldap_get_values_len (ld, ent, "dhcpServiceDN")) == NULL ||
+ temp[0]->bv_val == NULL)
+ {
+ if (temp != NULL)
+ ldap_value_free_len (temp);
+
+ ldap_unbind_ext (ld, NULL, NULL);
+ ld = NULL;
+ log_error ("Error: Cannot find LDAP entry matching %s", dn);
+ return (ISC_R_FAILURE);
+ }
+
+ ldap_msgfree (ldres);
+
+ if ((ret = ldap_search_ext_s (ld, temp[0]->bv_val, LDAP_SCOPE_BASE,
+ "objectClass=*", NULL, 0,
+ NULL, NULL, NULL, 0, &ldres)) != LDAP_SUCCESS)
+ {
+ ldap_value_free_len (temp);
+ ldap_unbind_ext (ld, NULL, NULL);
+ ld = NULL;
+ log_error ("Cannot search LDAP for %s: %s", temp[0]->bv_val,
+ ldap_err2string (ret));
+ return (ISC_R_FAILURE);
+ }
+
+ if ((ent = ldap_first_entry (ld, ldres)) == NULL)
+ {
+ ldap_value_free_len (temp);
+ ldap_unbind_ext (ld, NULL, NULL);
+ ld = NULL;
+ log_error ("Error: Cannot find LDAP entry matching %s", temp[0]->bv_val);
+ return (ISC_R_FAILURE);
+ }
+
+ ldap_value_free_len (temp);
+
+ add_to_config_stack (ldres, ent);
+
+ res = conf_file_subparse (cfile, root_group, ROOT_GROUP);
+ end_parse (&cfile);
+
+ return (res);
+}
+
+
+/* This function will parse the dhcpOption and dhcpStatements field in the LDAP
+ entry if it exists. Right now, type will be either HOST_DECL or CLASS_DECL.
+ If we are parsing a HOST_DECL, this always returns 0. If we are parsing a
+ CLASS_DECL, this will return what the current lease limit is in LDAP. If
+ there is no lease limit specified, we return 0 */
+
+static int
+ldap_parse_options (LDAPMessage * ent, struct group *group,
+ int type, struct host_decl *host,
+ struct class **class)
+{
+ struct berval **temp;
+ char option_buffer[8192];
+ int i, declaration, lease_limit;
+ enum dhcp_token token;
+ struct parse *cfile;
+ isc_result_t res;
+ const char *val;
+
+ lease_limit = 0;
+ *option_buffer = '\0';
+ if ((temp = ldap_get_values_len (ld, ent, "dhcpStatements")) != NULL)
+ {
+ for (i=0; temp[i] != NULL && temp[i]->bv_val != NULL; i++)
+ {
+ if (strncasecmp ("lease limit ", temp[i]->bv_val, 12) == 0)
+ {
+ lease_limit = strtol ((temp[i]->bv_val) + 12, NULL, 10);
+ continue;
+ }
+
+ strncat (option_buffer, temp[i]->bv_val, sizeof (option_buffer) - strlen (option_buffer) - 1);
+ strncat (option_buffer, ";\n", sizeof (option_buffer) - strlen (option_buffer) - 1);
+ }
+ ldap_value_free_len (temp);
+ }
+
+ if ((temp = ldap_get_values_len (ld, ent, "dhcpOption")) != NULL)
+ {
+ for (i=0; temp[i] != NULL && temp[i]->bv_val != NULL; i++)
+ {
+ strncat (option_buffer, "option ", sizeof (option_buffer) - strlen (option_buffer) - 1);
+ strncat (option_buffer, temp[i]->bv_val, sizeof (option_buffer) - strlen (option_buffer) - 1);
+ strncat (option_buffer, ";\n", sizeof (option_buffer) - strlen (option_buffer) - 1);
+ }
+ ldap_value_free_len (temp);
+ }
+
+ if (*option_buffer == '\0')
+ return (lease_limit);
+
+ cfile = (struct parse *) NULL;
+ res = new_parse (&cfile, -1, option_buffer, strlen (option_buffer),
+ type == HOST_DECL ? "LDAP-HOST" : "LDAP-SUBCLASS", 0);
+ if (res != ISC_R_SUCCESS)
+ return (lease_limit);
+
+#if defined (DEBUG_LDAP)
+ log_info ("Sending the following options: '%s'", option_buffer);
+#endif
+
+ declaration = 0;
+ do {
+ token = peek_token (&val, NULL, cfile);
+ if (token == END_OF_FILE)
+ break;
+ declaration = parse_statement (cfile, group, type, host, declaration);
+ } while (1);
+
+ end_parse (&cfile);
+
+ return (lease_limit);
+}
+
+
+
+int
+find_haddr_in_ldap (struct host_decl **hp, int htype, unsigned hlen,
+ const unsigned char *haddr, const char *file, int line)
+{
+ char buf[60], *type_str;
+ LDAPMessage * res, *ent;
+ struct host_decl * host;
+ isc_result_t status;
+ int ret;
+
+ if (disable_ldap || ldap_method == LDAP_METHOD_STATIC)
+ return (0);
+
+ if (ld == NULL)
+ ldap_start ();
+ if (ld == NULL)
+ return (0);
+
+ switch (htype)
+ {
+ case HTYPE_ETHER:
+ type_str = "ethernet";
+ break;
+ case HTYPE_IEEE802:
+ type_str = "token-ring";
+ break;
+ case HTYPE_FDDI:
+ type_str = "fddi";
+ break;
+ default:
+ log_info ("Ignoring unknown type %d", htype);
+ return (0);
+ }
+
+ snprintf (buf, sizeof (buf), "dhcpHWAddress=%s %s", type_str,
+ print_hw_addr (htype, hlen, haddr));
+#if defined (DEBUG_LDAP)
+ log_info ("Searching for %s in LDAP tree %s", buf, ldap_base_dn);
+#endif
+
+ if ((ret = ldap_search_ext_s (ld, ldap_base_dn, LDAP_SCOPE_SUBTREE,
+ buf, NULL, 0, NULL, NULL, NULL, 0,
+ &res)) != LDAP_SUCCESS)
+ {
+ if (ret != LDAP_NO_SUCH_OBJECT)
+ {
+ log_error ("Cannot search for %s in LDAP tree %s: %s", buf,
+ ldap_base_dn, ldap_err2string (ret));
+ ldap_unbind_ext (ld, NULL, NULL);
+ ld = NULL;
+ }
+#if defined (DEBUG_LDAP)
+ else
+ log_info ("ldap_search_ext_s returned %s when searching for %s in %s",
+ ldap_err2string (ret), buf, ldap_base_dn);
+#endif
+
+ return (0);
+ }
+
+ if ((ent = ldap_first_entry (ld, res)) != NULL)
+ {
+#if defined (DEBUG_LDAP)
+ log_info ("Found LDAP entry %s", ldap_get_dn (ld, ent));
+#endif
+
+ host = (struct host_decl *)0;
+ status = host_allocate (&host, MDL);
+ if (status != ISC_R_SUCCESS)
+ {
+ log_fatal ("can't allocate host decl struct: %s",
+ isc_result_totext (status));
+ return (0);
+ }
+
+ host->name = ldap_get_host_name (ent);
+ if (host->name == NULL)
+ {
+ host_dereference (&host, MDL);
+ ldap_msgfree (res);
+ return (0);
+ }
+
+ if (!clone_group (&host->group, root_group, MDL))
+ {
+ log_fatal ("can't clone group for host %s", host->name);
+ host_dereference (&host, MDL);
+ return (0);
+ }
+
+ ldap_parse_options (ent, host->group, HOST_DECL, host, NULL);
+
+ *hp = host;
+ ldap_msgfree (res);
+ return (1);
+ }
+
+
+ ldap_msgfree (res);
+ return (0);
+}
+
+
+int
+find_subclass_in_ldap (struct class *class, struct class **newclass,
+ struct data_string *data)
+{
+ LDAPMessage * res, * ent;
+ int ret, lease_limit;
+ isc_result_t status;
+ char buf[1024];
+
+ if (disable_ldap || ldap_method == LDAP_METHOD_STATIC)
+ return (0);
+
+ if (ld == NULL)
+ ldap_start ();
+ if (ld == NULL)
+ return (0);
+
+ snprintf (buf, sizeof (buf), "(&(objectClass=dhcpSubClass)(cn=%s)(dhcpClassData=%s))", print_hex_1 (data->len, data->data, 60), print_hex_2 (strlen (class->name), (const u_int8_t *) class->name, 60));
+#if defined (DEBUG_LDAP)
+ log_info ("Searching LDAP for %s", buf);
+#endif
+
+ if ((ret = ldap_search_ext_s (ld, ldap_base_dn, LDAP_SCOPE_SUBTREE,
+ buf, NULL, 0, NULL, NULL, NULL, 0,
+ &res)) != LDAP_SUCCESS)
+ {
+ if (ret != LDAP_NO_SUCH_OBJECT)
+ {
+ log_error ("Cannot search for %s in LDAP tree %s: %s", buf,
+ ldap_base_dn, ldap_err2string (ret));
+ ldap_unbind_ext (ld, NULL, NULL);
+ ld = NULL;
+ }
+#if defined (DEBUG_LDAP)
+ else
+ log_info ("ldap_search_ext_s returned %s when searching for %s in %s",
+ ldap_err2string (ret), buf, ldap_base_dn);
+#endif
+
+ return (0);
+ }
+
+ if ((ent = ldap_first_entry (ld, res)) != NULL)
+ {
+#if defined (DEBUG_LDAP)
+ log_info ("Found LDAP entry %s", ldap_get_dn (ld, ent));
+#endif
+
+ status = class_allocate (newclass, MDL);
+ if (status != ISC_R_SUCCESS)
+ {
+ log_error ("Cannot allocate memory for a new class");
+ return (0);
+ }
+
+ group_reference (&(*newclass)->group, class->group, MDL);
+ class_reference (&(*newclass)->superclass, class, MDL);
+ lease_limit = ldap_parse_options (ent, (*newclass)->group,
+ CLASS_DECL, NULL, newclass);
+ if (lease_limit == 0)
+ (*newclass)->lease_limit = class->lease_limit;
+ else
+ class->lease_limit = lease_limit;
+
+ if ((*newclass)->lease_limit)
+ {
+ (*newclass)->billed_leases =
+ dmalloc ((*newclass)->lease_limit * sizeof (struct lease *), MDL);
+ if (!(*newclass)->billed_leases)
+ {
+ log_error ("no memory for billing");
+ class_dereference (newclass, MDL);
+ return (0);
+ }
+ memset ((*newclass)->billed_leases, 0,
+ ((*newclass)->lease_limit * sizeof (*newclass)->billed_leases));
+ }
+
+ data_string_copy (&(*newclass)->hash_string, data, MDL);
+
+ ldap_msgfree (res);
+ return (1);
+ }
+
+
+ ldap_msgfree (res);
+ return (0);
+}
+
+#endif
+
--- dhcp-3.0.5/server/mdb.c.ldap 2007-03-29 15:10:26.000000000 -0400
+++ dhcp-3.0.5/server/mdb.c 2007-03-29 15:11:19.000000000 -0400
@@ -373,6 +373,12 @@
const char *file, int line)
{
struct hardware h;
+ int ret;
+
+#if defined(LDAP_CONFIGURATION)
+ if ((ret = find_haddr_in_ldap (hp, htype, hlen, haddr, file, line)))
+ return ret;
+#endif
h.hlen = hlen + 1;
h.hbuf [0] = htype;
--- dhcp-3.0.5/server/stables.c.ldap 2004-06-10 13:59:58.000000000 -0400
+++ dhcp-3.0.5/server/stables.c 2007-03-29 15:11:19.000000000 -0400
@@ -483,12 +483,21 @@
{ "log-facility", "Nsyslog-facilities.", &server_universe, 44 },
{ "do-forward-updates", "f", &server_universe, 45 },
{ "ping-timeout", "T", &server_universe, 46 },
+#if defined(LDAP_CONFIGURATION)
+ { "ldap-server", "t", &server_universe, 47 },
+ { "ldap-port", "d", &server_universe, 48 },
+ { "ldap-username", "t", &server_universe, 49 },
+ { "ldap-password", "t", &server_universe, 50 },
+ { "ldap-base-dn", "t", &server_universe, 51 },
+ { "ldap-method", "Nldap-methods.", &server_universe, 52 },
+#else
{ "unknown-47", "X", &server_universe, 47 },
{ "unknown-48", "X", &server_universe, 48 },
{ "unknown-49", "X", &server_universe, 49 },
{ "unknown-50", "X", &server_universe, 50 },
{ "unknown-51", "X", &server_universe, 51 },
{ "unknown-52", "X", &server_universe, 52 },
+#endif
{ "unknown-53", "X", &server_universe, 53 },
{ "unknown-54", "X", &server_universe, 54 },
{ "unknown-55", "X", &server_universe, 55 },
@@ -694,6 +703,20 @@
{ "option-end", "e", &server_universe, 255 },
};
+#if defined(LDAP_CONFIGURATION)
+struct enumeration_value ldap_values [] = {
+ { "static", LDAP_METHOD_STATIC },
+ { "dynamic", LDAP_METHOD_DYNAMIC },
+ { (char *) 0, 0 }
+};
+
+struct enumeration ldap_methods = {
+ (struct enumeration *)0,
+ "ldap-methods",
+ ldap_values
+};
+#endif
+
struct enumeration_value ddns_styles_values [] = {
{ "none", 0 },
{ "ad-hoc", 1 },