From 0da25ae6a8124555ffae535f69f2f492cd450d0d Mon Sep 17 00:00:00 2001 From: David Cantrell Date: Jan 10 2008 22:26:34 +0000 Subject: Reverting dhcp for rawhide to 3.1.0 for the time being. 4.0.0 is still in the works. --- diff --git a/README.ldap b/README.ldap deleted file mode 100644 index 2263050..0000000 --- a/README.ldap +++ /dev/null @@ -1,192 +0,0 @@ -LDAP Support in DHCP -Brian Masney -Last updated 3/23/2003 - -This document describes setting up the DHCP server to read it's configuration -from LDAP. This work is based on the IETF document -draft-ietf-dhc-ldap-schema-01.txt included in the doc directory. For the -latest version of this document, please see http://home.ntelos.net/~masneyb. - -First question on most people's mind is "Why do I want to store my -configuration in LDAP?" If you run a small DHCP server, and the configuration -on it rarely changes, then you won't need to store your configuration in LDAP. -But, if you have several DHCP servers, and you want an easy way to manage your -configuration, this can be a solution. - -The first step will be to setup your LDAP server. I am using OpenLDAP from -www.openldap.org. Building and installing OpenLDAP is beyond the scope of -this document. There is plenty of documentation out there about this. Once -you have OpenLDAP installed, you will have to edit your slapd.conf file. I -added the following 2 lines to my configuration file: - -include /etc/ldap/schema/dhcp.schema -index dhcpHWAddress eq -index dhcpClassData eq - -The first line tells it to include the dhcp schema file. You will find this -file under the contrib directory in this distribution. You will need to copy -this file to where your other schema files are (maybe -/usr/local/openldap/etc/openldap/schema/). The second line sets up an index -for the dhcpHWAddress parameter. The third parameter is for reading subclasses -from LDAP every time a DHCP request comes in. Make sure you run the slapindex -command and restart slapd to have these changes to into effect. - -Now that you have LDAP setup, you should be able to use gq -(http://biot.com/gq/) to verify that the dhcp schema file is loaded into LDAP. -Pull up gq, and click on the Schema tab. Go under objectClasses, and you -should see at least the following object classes listed: dhcpClass, dhcpGroup, -dhcpHost, dhcpOptions, dhcpPool, dhcpServer, dhcpService, dhcpSharedNetwork, -dhcpSubClass, and dhcpSubnet. If you do not see these, you need to check over -your LDAP configuration before you go any further. - -You should now be ready to build DHCP. If you would like to enable LDAP over -SSL, you will need to perform the following steps: - - * Edit the includes/site.h file and uncomment the USE_SSL line - or specify "-DUSE_SSL" via CFLAGS. - * Edit the dst/Makefile.dist file and remove md5_dgst.c and md5_dgst.o - from the SRC= and OBJ= lines (around line 24) - * Now run configure in the base source directory. If you chose to enable - LDAP over SSL, you must append -lcrypto -lssl to the LIBS= line in the - file work.os/server/Makefile (replace os with your operating system, - linux-2.2 on my machine). You should now be able to type make to build - your DHCP server. - -If you choose to not enable LDAP over SSL, then you only need to run configure -and make in the toplevel source directory. - -Once you have DHCP installed, you will need to setup your initial plaintext -config file. In my /etc/dhcpd.conf file, I have: - -ldap-server "localhost"; -ldap-port 389; -ldap-username "cn=DHCP User, dc=ntelos, dc=net"; -ldap-password "blah"; -ldap-base-dn "dc=ntelos, dc=net"; -ldap-method dynamic; -ldap-debug-file "/var/log/dhcp-ldap-startup.log"; - -If SSL has been enabled at compile time using the USE_SSL flag, the dhcp -server trys to use TLS if possible, but continues without TLS if not. - -You can modify this behaviour using following option in /etc/dhcpd.conf: - -ldap-ssl - off: disables TLS/LDAPS. - ldaps: enables LDAPS -- don't forget to set ldap-port to 636. - start_tls: enables TLS using START_TLS command - on: enables LDAPS if ldap-port is set to 636 or TLS in - other cases. - -See also "man 5 ldap.conf" for description the following TLS related -options: - ldap-tls-reqcert, ldap-tls-ca-file, ldap-tls-ca-dir, ldap-tls-cert - ldap-tls-key, ldap-tls-crlcheck, ldap-tls-ciphers, ldap-tls-randfile - -All of these parameters should be self explanatory except for the ldap-method. -You can set this to static or dynamic. If you set it to static, the -configuration is read once on startup, and LDAP isn't used anymore. But, if -you set this to dynamic, the configuration is read once on startup, and the -hosts that are stored in LDAP are looked up every time a DHCP request comes -in. - -When the optional statement ldap-debug-file is specified, on startup the DHCP -server will write out the configuration that it generated from LDAP. If you -are getting errors about your LDAP configuration, this is a good place to -start looking. - -The next step is to set up your LDAP tree. Here is an example config that will -give a 10.100.0.x address to machines that have a host entry in LDAP. -Otherwise, it will give a 10.200.0.x address to them. (NOTE: replace -dc=ntelos, dc=net with your base dn). If you would like to convert your -existing dhcpd.conf file to LDIF format, there is a script -contrib/dhcpd-conf-to-ldap.pl that will convert it for you. Type -dhcpd-conf-to-ldap.pl --help to see the usage information for this script. - -# You must specify the server's host name in LDAP that you are going to run -# DHCP on and point it to which config tree you want to use. Whenever DHCP -# first starts up, it will do a search for this entry to find out which -# config to use -dn: cn=brian.ntelos.net, dc=ntelos, dc=net -objectClass: top -objectClass: dhcpServer -cn: brian.ntelos.net -dhcpServiceDN: cn=DHCP Service Config, dc=ntelos, dc=net - -# Here is the config tree that brian.ntelos.net points to. -dn: cn=DHCP Service Config, dc=ntelos, dc=net -cn: DHCP Service Config -objectClass: top -objectClass: dhcpService -dhcpPrimaryDN: dc=ntelos, dc=net -dhcpStatements: ddns-update-style none -dhcpStatements: default-lease-time 600 -dhcpStatements: max-lease-time 7200 - -# Set up a shared network segment -dn: cn=WV Test, cn=DHCP Service Config, dc=ntelos, dc=net -cn: WV -objectClass: top -objectClass: dhcpSharedNetwork - -# Set up a subnet declaration with a pool statement. Also note that we have -# a dhcpOptions object with this entry -dn: cn=10.100.0.0, cn=WV Test, cn=DHCP Service Config, dc=ntelos, dc=net -cn: 10.100.0.0 -objectClass: top -objectClass: dhcpSubnet -objectClass: dhcpOptions -dhcpOption: domain-name-servers 10.100.0.2 -dhcpOption: routers 10.100.0.1 -dhcpOption: subnet-mask 255.255.255.0 -dhcpOption: broadcast-address 10.100.0.255 -dhcpNetMask: 24 - -# Set up a pool for this subnet. Only known hosts will get these IPs -dn: cn=Known Pool, cn=10.100.0.0, cn=WV Test, cn=DHCP Service Config, dc=ntelos, dc=net -cn: Known Pool -objectClass: top -objectClass: dhcpPool -dhcpRange: 10.100.0.3 10.100.0.254 -dhcpPermitList: deny unknown-clients - -# Set up another subnet declaration with a pool statement -dn: cn=10.200.0.0, cn=WV Test, cn=DHCP Service Config, dc=ntelos, dc=net -cn: 10.200.0.0 -objectClass: top -objectClass: dhcpSubnet -objectClass: dhcpOptions -dhcpOption: domain-name-servers 10.200.0.2 -dhcpOption: routers 10.200.0.1 -dhcpOption: subnet-mask 255.255.255.0 -dhcpOption: broadcast-address 10.200.0.255 -dhcpNetMask: 24 - -# Set up a pool for this subnet. Only unknown hosts will get these IPs -dn: cn=Known Pool, cn=10.200.0.0, cn=WV Test, cn=DHCP Service Config, dc=ntelos, dc=net -cn: Known Pool -objectClass: top -objectClass: dhcpPool -dhcpRange: 10.200.0.3 10.200.0.254 -dhcpPermitList: deny known clients - -# Set aside a group for all of our known MAC addresses -dn: cn=Customers, cn=DHCP Service Config, dc=ntelos, dc=net -objectClass: top -objectClass: dhcpGroup -cn: Customers - -# Host entry for my laptop -dn: cn=brianlaptop, cn=Customers, cn=DHCP Service Config, dc=ntelos, dc=net -objectClass: top -objectClass: dhcpHost -cn: brianlaptop -dhcpHWAddress: ethernet 00:00:00:00:00:00 - -You can use the command slapadd to load all of these entries into your LDAP -server. After you load this, you should be able to start up DHCP. If you run -into problems reading the configuration, try running dhcpd with the -d flag. -If you still have problems, edit the site.conf file in the DHCP source and -add the line: COPTS= -DDEBUG_LDAP and recompile DHCP. (make sure you run make -clean and rerun configure before you rebuild). - diff --git a/dhcp-3.0.5-dhclient-decline-backoff.patch b/dhcp-3.0.5-dhclient-decline-backoff.patch deleted file mode 100644 index 67729f5..0000000 --- a/dhcp-3.0.5-dhclient-decline-backoff.patch +++ /dev/null @@ -1,58 +0,0 @@ ---- dhcp-3.0.5/client/dhclient.c.decline 2007-03-30 15:29:58.000000000 -0400 -+++ dhcp-3.0.5/client/dhclient.c 2007-03-30 15:50:25.000000000 -0400 -@@ -934,6 +934,7 @@ - void *cpp; - { - struct client_state *client = cpp; -+ enum dhcp_state init_state = client->state; - - ASSERT_STATE(state, S_INIT); - -@@ -946,9 +947,16 @@ - client -> first_sending = cur_time; - client -> interval = client -> config -> initial_interval; - -- /* Add an immediate timeout to cause the first DHCPDISCOVER packet -- to go out. */ -- send_discover (client); -+ if (init_state != S_DECLINED) { -+ /* Add an immediate timeout to cause the first DHCPDISCOVER packet -+ to go out. */ -+ send_discover(client); -+ } else { -+ /* We've received an OFFER and it has been DECLINEd by dhclient-script. -+ * wait for a random time between 1 and backoff_cutoff seconds before -+ * trying again. */ -+ add_timeout(cur_time + ((1 + (random() >> 2)) % client->config->backoff_cutoff), send_discover, client, 0, 0); -+ } - } - - /* state_selecting is called when one or more DHCPOFFER packets have been -@@ -1215,6 +1223,7 @@ - send_decline (client); - destroy_client_lease (client -> new); - client -> new = (struct client_lease *)0; -+ client -> state = S_DECLINED; - state_init (client); - return; - } -@@ -3183,6 +3192,7 @@ - case S_INIT: - case S_REBINDING: - case S_STOPPED: -+ case S_DECLINED: - break; - } - client -> state = S_INIT; ---- dhcp-3.0.5/includes/dhcpd.h.decline 2007-03-30 15:30:14.000000000 -0400 -+++ dhcp-3.0.5/includes/dhcpd.h 2007-03-30 15:50:53.000000000 -0400 -@@ -704,7 +704,8 @@ - S_BOUND = 5, - S_RENEWING = 6, - S_REBINDING = 7, -- S_STOPPED = 8 -+ S_STOPPED = 8, -+ S_DECLINED = 9 - }; - - /* Authentication and BOOTP policy possibilities (not all values work diff --git a/dhcp-3.0.5-enable-timeout-functions.patch b/dhcp-3.0.5-enable-timeout-functions.patch deleted file mode 100644 index 3d91d14..0000000 --- a/dhcp-3.0.5-enable-timeout-functions.patch +++ /dev/null @@ -1,15 +0,0 @@ ---- dhcp-3.0.5/common/dispatch.c.ecat 2006-02-22 17:43:27.000000000 -0500 -+++ dhcp-3.0.5/common/dispatch.c 2007-03-30 15:54:15.000000000 -0400 -@@ -195,7 +195,6 @@ - } - } - --#if defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT) - void cancel_all_timeouts () - { - struct timeout *t, *n; -@@ -216,4 +215,3 @@ - dfree (t, MDL); - } - } --#endif diff --git a/dhcp-3.0.5-errwarn-message.patch b/dhcp-3.0.5-errwarn-message.patch deleted file mode 100644 index c31e1a2..0000000 --- a/dhcp-3.0.5-errwarn-message.patch +++ /dev/null @@ -1,29 +0,0 @@ ---- dhcp-3.0.5/omapip/errwarn.c.message 2007-03-29 15:03:12.000000000 -0400 -+++ dhcp-3.0.5/omapip/errwarn.c 2007-03-29 15:08:50.000000000 -0400 -@@ -80,20 +80,13 @@ - - #if !defined (NOMINUM) - log_error ("%s", ""); -- log_error ("If you did not get this software from ftp.isc.org, please"); -- log_error ("get the latest from ftp.isc.org and install that before"); -- log_error ("requesting help."); -+ log_error ("This version of ISC DHCP is based on the release available"); -+ log_error ("on ftp.isc.org. Features have been added and other changes"); -+ log_error ("have been made to the base software release in order to make"); -+ log_error ("it work better with this distribution."); - log_error ("%s", ""); -- log_error ("If you did get this software from ftp.isc.org and have not"); -- log_error ("yet read the README, please read it before requesting help."); -- log_error ("If you intend to request help from the dhcp-server@isc.org"); -- log_error ("mailing list, please read the section on the README about"); -- log_error ("submitting bug reports and requests for help."); -- log_error ("%s", ""); -- log_error ("Please do not under any circumstances send requests for"); -- log_error ("help directly to the authors of this software - please"); -- log_error ("send them to the appropriate mailing list as described in"); -- log_error ("the README file."); -+ log_error ("Please report for this software via the Red Hat Bugzilla site:"); -+ log_error (" http://bugzilla.redhat.com"); - log_error ("%s", ""); - log_error ("exiting."); - #endif diff --git a/dhcp-3.0.5-failover-ports.patch b/dhcp-3.0.5-failover-ports.patch deleted file mode 100644 index aa0d68f..0000000 --- a/dhcp-3.0.5-failover-ports.patch +++ /dev/null @@ -1,22 +0,0 @@ ---- dhcp-3.0.5/server/confpars.c.failover 2007-03-30 16:28:08.000000000 -0400 -+++ dhcp-3.0.5/server/confpars.c 2007-03-30 16:32:39.000000000 -0400 -@@ -998,10 +998,17 @@ - parse_warn (cfile, "peer address may not be omitted"); - - /* XXX - when/if we get a port number assigned, just set as default */ -+ /* See Red Hat Bugzilla 167292: -+ * we do now: dhcp-failover 647/tcp -+ * dhcp-failover 647/udp -+ * dhcp-failover 847/tcp -+ * dhcp-failover 847/udp -+ * IANA registration by Bernard Volz -+ */ - if (!peer -> me.port) -- parse_warn (cfile, "local port may not be omitted"); -+ peer -> me.port = 647; - if (!peer -> partner.port) -- parse_warn (cfile, "peer port may not be omitted"); -+ peer -> partner.port = 847; - - if (peer -> i_am == primary) { - if (!peer -> hba) { diff --git a/dhcp-3.0.5-release-by-ifup.patch b/dhcp-3.0.5-release-by-ifup.patch deleted file mode 100644 index 2091b42..0000000 --- a/dhcp-3.0.5-release-by-ifup.patch +++ /dev/null @@ -1,84 +0,0 @@ ---- dhcp-3.0.5/client/dhclient.c.release 2007-03-30 15:30:14.000000000 -0400 -+++ dhcp-3.0.5/client/dhclient.c 2007-03-30 15:29:58.000000000 -0400 -@@ -366,9 +366,81 @@ - } - } - fclose(pidfd); -+ } else { -+ /* handle release for interfaces requested with Red Hat -+ * /sbin/ifup - pidfile will be /var/run/dhclient-$interface.pid -+ */ -+ -+ if ((path_dhclient_pid == NULL) || (*path_dhclient_pid == '\0')) -+ path_dhclient_pid = "/var/run/dhclient.pid"; -+ -+ char *new_path_dhclient_pid; -+ struct interface_info *ip; -+ int pdp_len = strlen(path_dhclient_pid), pfx, dpfx; -+ -+ /* find append point: beginning of any trailing '.pid' -+ * or '-$IF.pid' */ -+ for (pfx=pdp_len; (pfx >= 0) && (path_dhclient_pid[pfx] != '.') && (path_dhclient_pid[pfx] != '/'); pfx--); -+ if (pfx == -1) -+ pfx = pdp_len; -+ -+ if (path_dhclient_pid[pfx] == '/') -+ pfx += 1; -+ -+ for (dpfx=pfx; (dpfx >= 0) && (path_dhclient_pid[dpfx] != '-') && (path_dhclient_pid[dpfx] != '/'); dpfx--); -+ if ((dpfx > -1) && (path_dhclient_pid[dpfx] != '/')) -+ pfx = dpfx; -+ -+ for (ip = interfaces; ip; ip = ip->next) { -+ if (interfaces_requested && (ip->flags & (INTERFACE_REQUESTED)) && (ip->name != NULL)) { -+ int n_len = strlen(ip->name); -+ -+ new_path_dhclient_pid = (char*) malloc(pfx + n_len + 6); -+ strncpy(new_path_dhclient_pid, path_dhclient_pid, pfx); -+ sprintf(new_path_dhclient_pid + pfx, "-%s.pid", ip->name); -+ -+ if ((pidfd = fopen(new_path_dhclient_pid, "r")) != NULL) { -+ e = fscanf(pidfd, "%ld\n", &temp); -+ oldpid = (pid_t)temp; -+ -+ if (e != 0 && e != EOF) { -+ if (oldpid) { -+ if (kill(oldpid, SIGTERM) == 0) -+ unlink(path_dhclient_pid); -+ } -+ } -+ -+ fclose(pidfd); -+ } -+ -+ free(new_path_dhclient_pid); -+ } -+ } -+ } -+ } else { -+ FILE *pidfp = NULL; -+ long temp = 0; -+ pid_t dhcpid = 0; -+ int dhc_running = 0; -+ char procfn[256] = ""; -+ -+ if ((pidfp = fopen(path_dhclient_pid, "r")) != NULL) { -+ if ((fscanf(pidfp, "%ld", &temp)==1) && ((dhcpid=(pid_t)temp) > 0)) { -+ snprintf(procfn,256,"/proc/%u",dhcpid); -+ dhc_running = (access(procfn, F_OK) == 0); -+ } -+ -+ fclose(pidfp); -+ } -+ -+ if (dhc_running) { -+ log_fatal("dhclient(%u) is already running - exiting. ", dhcpid); -+ return(1); - } - } - -+ write_client_pid_file(); -+ - if (!quiet) { - log_info ("%s %s", message, DHCP_VERSION); - log_info (copyright); diff --git a/dhcp-3.0.5-selinux.patch b/dhcp-3.0.5-selinux.patch deleted file mode 100644 index f412b25..0000000 --- a/dhcp-3.0.5-selinux.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- dhcp-3.0.5/client/dhclient.c.selinux 2007-03-30 16:11:54.000000000 -0400 -+++ dhcp-3.0.5/client/dhclient.c 2007-03-30 16:12:27.000000000 -0400 -@@ -3009,6 +3009,8 @@ - wstatus = 0; - } - } else { -+ if (leaseFile) -+ fclose(leaseFile); - execve (scriptName, argv, envp); - log_error ("execve (%s, ...): %m", scriptName); - exit (0); diff --git a/dhcp-3.0.5-unicast-bootp.patch b/dhcp-3.0.5-unicast-bootp.patch deleted file mode 100644 index dada189..0000000 --- a/dhcp-3.0.5-unicast-bootp.patch +++ /dev/null @@ -1,97 +0,0 @@ ---- dhcp-3.0.5/server/bootp.c.unicast 2005-05-18 15:54:17.000000000 -0400 -+++ dhcp-3.0.5/server/bootp.c 2007-03-30 16:16:00.000000000 -0400 -@@ -62,6 +62,7 @@ - char msgbuf [1024]; - int ignorep; - int peer_has_leases = 0; -+ int norelay = 0; - - if (packet -> raw -> op != BOOTREQUEST) - return; -@@ -77,7 +78,7 @@ - ? inet_ntoa (packet -> raw -> giaddr) - : packet -> interface -> name); - -- if (!locate_network (packet)) { -+ if ((norelay = locate_network (packet)) == 0) { - log_info ("%s: network unknown", msgbuf); - return; - } -@@ -357,6 +358,13 @@ - from, &to, &hto); - goto out; - } -+ } else if (norelay == 2) { -+ to.sin_addr = raw.ciaddr; -+ to.sin_port = remote_port; -+ if (fallback_interface) { -+ result = send_packet (fallback_interface, (struct packet *)0, &raw, outgoing.packet_length, from, &to, &hto); -+ goto out; -+ } - - /* If it comes from a client that already knows its address - and is not requesting a broadcast response, and we can ---- dhcp-3.0.5/server/dhcp.c.unicast 2007-03-30 16:13:36.000000000 -0400 -+++ dhcp-3.0.5/server/dhcp.c 2007-03-30 16:19:35.000000000 -0400 -@@ -3817,6 +3817,7 @@ - struct data_string data; - struct subnet *subnet = (struct subnet *)0; - struct option_cache *oc; -+ int norelay = 0; - - /* See if there's a subnet selection option. */ - oc = lookup_option (&dhcp_universe, packet -> options, -@@ -3826,12 +3827,24 @@ - from the interface, if there is one. If not, fail. */ - if (!oc && !packet -> raw -> giaddr.s_addr) { - if (packet -> interface -> shared_network) { -- shared_network_reference -- (&packet -> shared_network, -- packet -> interface -> shared_network, MDL); -- return 1; -+ struct in_addr any_addr; -+ any_addr.s_addr = INADDR_ANY; -+ -+ if (!packet -> packet_type && memcmp(&packet -> raw -> ciaddr, &any_addr, 4)) { -+ struct iaddr cip; -+ memcpy(cip.iabuf, &packet -> raw -> ciaddr, 4); -+ cip.len = 4; -+ if (!find_grouped_subnet(&subnet, packet->interface->shared_network, cip, MDL)) -+ norelay = 2; -+ } -+ -+ if (!norelay) { -+ shared_network_reference(&packet -> shared_network, packet -> interface -> shared_network, MDL); -+ return 1; -+ } -+ } else { -+ return 0; - } -- return 0; - } - - /* If there's an SSO, and it's valid, use it to figure out the -@@ -3853,7 +3866,10 @@ - data_string_forget (&data, MDL); - } else { - ia.len = 4; -- memcpy (ia.iabuf, &packet -> raw -> giaddr, 4); -+ if (norelay) -+ memcpy (ia.iabuf, &packet->raw->ciaddr, 4); -+ else -+ memcpy (ia.iabuf, &packet->raw->giaddr, 4); - } - - /* If we know the subnet on which the IP address lives, use it. */ -@@ -3861,7 +3877,10 @@ - shared_network_reference (&packet -> shared_network, - subnet -> shared_network, MDL); - subnet_dereference (&subnet, MDL); -- return 1; -+ if (norelay) -+ return norelay; -+ else -+ return 1; - } - - /* Otherwise, fail. */ diff --git a/dhcp-3.0.6-memory.patch b/dhcp-3.0.6-memory.patch deleted file mode 100644 index c08a429..0000000 --- a/dhcp-3.0.6-memory.patch +++ /dev/null @@ -1,37 +0,0 @@ -diff -up dhcp-3.0.6/minires/ns_name.c.memory dhcp-3.0.6/minires/ns_name.c ---- dhcp-3.0.6/minires/ns_name.c.memory 2004-06-10 13:59:40.000000000 -0400 -+++ dhcp-3.0.6/minires/ns_name.c 2007-07-10 11:43:29.000000000 -0400 -@@ -71,6 +71,11 @@ ns_name_ntop(const u_char *src, char *ds - dn = dst; - eom = dst + dstsiz; - -+ if (dn >= eom) { -+ errno = EMSGSIZE; -+ return (-1); -+ } -+ - while ((n = *cp++) != 0) { - if ((n & NS_CMPRSFLGS) != 0) { - /* Some kind of compression pointer. */ -diff -up dhcp-3.0.6/common/packet.c.memory dhcp-3.0.6/common/packet.c ---- dhcp-3.0.6/common/packet.c.memory 2007-05-01 16:42:55.000000000 -0400 -+++ dhcp-3.0.6/common/packet.c 2007-07-10 11:43:29.000000000 -0400 -@@ -140,6 +140,7 @@ void assemble_udp_ip_header (interface, - struct ip ip; - struct udphdr udp; - -+ memset( &ip, '\0', sizeof ip); - /* Fill out the IP header */ - IP_V_SET (&ip, 4); - IP_HL_SET (&ip, 20); -diff -up dhcp-3.0.6/common/lpf.c.memory dhcp-3.0.6/common/lpf.c ---- dhcp-3.0.6/common/lpf.c.memory 2007-07-10 11:43:29.000000000 -0400 -+++ dhcp-3.0.6/common/lpf.c 2007-07-10 11:43:29.000000000 -0400 -@@ -246,6 +246,7 @@ static void lpf_tr_filter_setup (info) - struct interface_info *info; - { - struct sock_fprog p; -+ memset(&p,'\0', sizeof(struct sock_fprog)); - - /* Set up the bpf filter program structure. This is defined in - bpf.c */ diff --git a/dhcp-4.0.0-default-requested-options.patch b/dhcp-4.0.0-default-requested-options.patch deleted file mode 100644 index 444258f..0000000 --- a/dhcp-4.0.0-default-requested-options.patch +++ /dev/null @@ -1,34 +0,0 @@ -diff -up dhcp-4.0.0/client/clparse.c.dho dhcp-4.0.0/client/clparse.c ---- dhcp-4.0.0/client/clparse.c.dho 2007-12-29 06:32:16.000000000 -1000 -+++ dhcp-4.0.0/client/clparse.c 2007-12-29 06:35:41.000000000 -1000 -@@ -37,7 +37,7 @@ - - struct client_config top_level_config; - --#define NUM_DEFAULT_REQUESTED_OPTS 9 -+#define NUM_DEFAULT_REQUESTED_OPTS 12 - struct option *default_requested_options[NUM_DEFAULT_REQUESTED_OPTS + 1]; - - static void parse_client_default_duid(struct parse *cfile); -@@ -107,6 +107,21 @@ isc_result_t read_client_conf () - option_code_hash_lookup(&default_requested_options[8], - dhcpv6_universe.code_hash, &code, 0, MDL); - -+ /* 10 */ -+ code = DHO_NIS_DOMAIN; -+ option_code_hash_lookup(&default_requested_options[9], -+ dhcp_universe.code_hash, &code, 0, MDL); -+ -+ /* 11 */ -+ code = DHO_NIS_SERVERS; -+ option_code_hash_lookup(&default_requested_options[10], -+ dhcp_universe.code_hash, &code, 0, MDL); -+ -+ /* 12 */ -+ code = DHO_NTP_SERVERS; -+ option_code_hash_lookup(&default_requested_options[11], -+ dhcp_universe.code_hash, &code, 0, MDL); -+ - for (code = 0 ; code < NUM_DEFAULT_REQUESTED_OPTS ; code++) { - if (default_requested_options[code] == NULL) - log_fatal("Unable to find option definition for " diff --git a/dhcp-4.0.0-dhclient-anycast.patch b/dhcp-4.0.0-dhclient-anycast.patch deleted file mode 100644 index 508f0aa..0000000 --- a/dhcp-4.0.0-dhclient-anycast.patch +++ /dev/null @@ -1,70 +0,0 @@ -diff -up dhcp-4.0.0/common/lpf.c.anycast dhcp-4.0.0/common/lpf.c ---- dhcp-4.0.0/common/lpf.c.anycast 2007-12-29 06:44:46.000000000 -1000 -+++ dhcp-4.0.0/common/lpf.c 2007-12-29 10:40:11.000000000 -1000 -@@ -331,6 +331,9 @@ ssize_t send_packet (interface, packet, - return send_fallback (interface, packet, raw, - len, from, to, hto); - -+ if (hto == NULL && interface->anycast_mac_addr.hlen) -+ hto = &interface->anycast_mac_addr; -+ - /* Assemble the headers... */ - assemble_hw_header (interface, (unsigned char *)hh, &hbufp, hto); - fudge = hbufp % 4; /* IP header must be word-aligned. */ -diff -up dhcp-4.0.0/common/conflex.c.anycast dhcp-4.0.0/common/conflex.c ---- dhcp-4.0.0/common/conflex.c.anycast 2007-12-29 06:44:46.000000000 -1000 -+++ dhcp-4.0.0/common/conflex.c 2007-12-29 10:39:30.000000000 -1000 -@@ -715,6 +715,8 @@ intern(char *atom, enum dhcp_token dfv) - } - if (!strcasecmp (atom + 1, "nd")) - return AND; -+ if (!strcasecmp (atom + 1, "nycast-mac")) -+ return ANYCAST_MAC; - if (!strcasecmp (atom + 1, "ppend")) - return APPEND; - if (!strcasecmp (atom + 1, "llow")) -diff -up dhcp-4.0.0/includes/dhcpd.h.anycast dhcp-4.0.0/includes/dhcpd.h ---- dhcp-4.0.0/includes/dhcpd.h.anycast 2007-12-29 06:44:46.000000000 -1000 -+++ dhcp-4.0.0/includes/dhcpd.h 2007-12-29 10:42:56.000000000 -1000 -@@ -1188,6 +1188,7 @@ struct interface_info { - int dlpi_sap_length; - struct hardware dlpi_broadcast_addr; - # endif /* DLPI_SEND || DLPI_RECEIVE */ -+ struct hardware anycast_mac_addr; - }; - - struct hardware_link { -diff -up dhcp-4.0.0/includes/dhctoken.h.anycast dhcp-4.0.0/includes/dhctoken.h ---- dhcp-4.0.0/includes/dhctoken.h.anycast 2007-12-29 06:44:46.000000000 -1000 -+++ dhcp-4.0.0/includes/dhctoken.h 2007-12-29 10:44:00.000000000 -1000 -@@ -346,7 +346,8 @@ enum dhcp_token { - WHITESPACE = 649, - TOKEN_ALSO = 650, - AFTER = 651, -- BOOTP_BROADCAST_ALWAYS = 652 -+ BOOTP_BROADCAST_ALWAYS = 652, -+ ANYCAST_MAC = 653 - }; - - #define is_identifier(x) ((x) >= FIRST_TOKEN && \ -diff -up dhcp-4.0.0/client/clparse.c.anycast dhcp-4.0.0/client/clparse.c ---- dhcp-4.0.0/client/clparse.c.anycast 2007-12-29 06:44:46.000000000 -1000 -+++ dhcp-4.0.0/client/clparse.c 2007-12-29 10:38:55.000000000 -1000 -@@ -550,6 +550,17 @@ void parse_client_statement (cfile, ip, - } - return; - -+ case ANYCAST_MAC: -+ token = next_token (&val, (unsigned *)0, cfile); -+ if (ip) { -+ parse_hardware_param (cfile, &ip -> anycast_mac_addr); -+ } else { -+ parse_warn (cfile, "anycast mac address parameter %s", -+ "not allowed here."); -+ skip_to_semi (cfile); -+ } -+ return; -+ - case REQUEST: - token = next_token (&val, (unsigned *)0, cfile); - if (config -> requested_options == default_requested_options) diff --git a/dhcp-4.0.0-dhclient-usage.patch b/dhcp-4.0.0-dhclient-usage.patch deleted file mode 100644 index 4f12754..0000000 --- a/dhcp-4.0.0-dhclient-usage.patch +++ /dev/null @@ -1,43 +0,0 @@ -diff -up dhcp-4.0.0/client/dhclient.c.usage dhcp-4.0.0/client/dhclient.c ---- dhcp-4.0.0/client/dhclient.c.usage 2007-12-31 18:05:29.000000000 -1000 -+++ dhcp-4.0.0/client/dhclient.c 2007-12-31 18:05:43.000000000 -1000 -@@ -893,21 +893,30 @@ main(int argc, char **argv) { - - static void usage () - { -- log_info ("%s %s", message, PACKAGE_VERSION); -- log_info (copyright); -- log_info (arr); -- log_info (url); -+ printf ("%s %s", message, PACKAGE_VERSION); -+ printf (copyright); -+ printf ("\n"); -+ printf (arr); -+ printf ("\n"); -+ printf (url); -+ printf ("\n"); - -- log_error ("Usage: dhclient %s %s", -+ printf ("Usage: dhclient %s %s", - #ifdef DHCPv6 - "[-4|-6] [-1dvrx] [-nw] [-p ]", - #else /* DHCPv6 */ - "[-1dvrx] [-nw] [-p ]", - #endif /* DHCPv6 */ -- "[-s server]"); -- log_error (" [-cf config-file] [-lf lease-file]%s", -- "[-pf pid-file] [-e VAR=val]"); -- log_fatal (" [-sf script-file] [interface]"); -+ "[-s server]\n"); -+ printf (" [-cf config-file] [-lf lease-file]%s", -+ "[-pf pid-file] [-e VAR=val]\n"); -+ printf (" [ -I ] [-B]\n"); -+ printf (" [ -H | -F ] [ -T ]\n"); -+ printf (" [ -V ]\n"); -+ printf (" [ -R ]\n"); -+ printf (" [-sf script-file] [interface]\n"); -+ -+ exit (EXIT_FAILURE); - } - - isc_result_t find_class (struct class **c, diff --git a/dhcp-4.0.0-fast-timeout.patch b/dhcp-4.0.0-fast-timeout.patch deleted file mode 100644 index 90a0658..0000000 --- a/dhcp-4.0.0-fast-timeout.patch +++ /dev/null @@ -1,15 +0,0 @@ -diff -up dhcp-4.0.0/client/dhclient.c.fast dhcp-4.0.0/client/dhclient.c ---- dhcp-4.0.0/client/dhclient.c.fast 2007-12-29 06:07:14.000000000 -1000 -+++ dhcp-4.0.0/client/dhclient.c 2007-12-29 06:08:07.000000000 -1000 -@@ -3624,10 +3624,7 @@ isc_result_t dhclient_interface_startup_ - ip -> flags |= INTERFACE_RUNNING; - for (client = ip -> client; client; client = client -> next) { - client -> state = S_INIT; -- /* Set up a timeout to start the initialization -- process. */ -- add_timeout (cur_time + random () % 5, -- state_reboot, client, 0, 0); -+ add_timeout (cur_time, state_reboot, client, 0, 0); - } - } - return ISC_R_SUCCESS; diff --git a/dhcp-4.0.0-ldap-configuration.patch b/dhcp-4.0.0-ldap-configuration.patch deleted file mode 100644 index b46acd2..0000000 --- a/dhcp-4.0.0-ldap-configuration.patch +++ /dev/null @@ -1,2682 +0,0 @@ -diff -up dhcp-4.0.0/server/Makefile.am.ldap dhcp-4.0.0/server/Makefile.am ---- dhcp-4.0.0/server/Makefile.am.ldap 2007-05-29 06:32:11.000000000 -1000 -+++ dhcp-4.0.0/server/Makefile.am 2008-01-02 11:18:44.000000000 -1000 -@@ -4,12 +4,12 @@ dist_sysconf_DATA = dhcpd.conf - sbin_PROGRAMS = dhcpd - dhcpd_SOURCES = dhcpd.c dhcp.c bootp.c confpars.c db.c class.c failover.c \ - omapi.c mdb.c stables.c salloc.c ddns.c dhcpleasequery.c \ -- dhcpv6.c mdb6.c -+ dhcpv6.c mdb6.c ldap.c ldap_casa.c - - # libomapi.a this is here twice to handle circular library dependencies :( --dhcpd_LDADD = ../common/libdhcp.a ../omapip/libomapi.a ../dst/libdst.a \ -+dhcpd_LDADD = ../common/libdhcp.a ../omapip/libomapi.a ../dst/libdstnomd5.a \ - ../dhcpctl/libdhcpctl.a ../minires/libres.a \ -- ../omapip/libomapi.a -+ ../omapip/libomapi.a -lldap - - man_MANS = dhcpd.8 dhcpd.conf.5 dhcpd.leases.5 - EXTRA_DIST = $(man_MANS) -diff -up dhcp-4.0.0/server/mdb.c.ldap dhcp-4.0.0/server/mdb.c ---- dhcp-4.0.0/server/mdb.c.ldap 2007-11-30 11:51:43.000000000 -1000 -+++ dhcp-4.0.0/server/mdb.c 2008-01-02 11:18:44.000000000 -1000 -@@ -600,6 +600,12 @@ int find_hosts_by_haddr (struct host_dec - 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; -diff -up /dev/null dhcp-4.0.0/server/ldap_casa.c ---- /dev/null 2007-12-31 11:39:52.874087547 -1000 -+++ dhcp-4.0.0/server/ldap_casa.c 2008-01-02 11:18:44.000000000 -1000 -@@ -0,0 +1,138 @@ -+/* ldap_casa.c -+ -+ CASA routines for DHCPD... */ -+ -+/* Copyright (c) 2004 Internet Systems Consorium, Inc. ("ISC") -+ * Copyright (c) 1995-2003 Internet Software Consortium. -+ * Copyright (c) 2006 Novell, 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 ISC, ISC DHCP, 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 INTERNET SYSTEMS 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 ISC 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 file was written by S Kalyanasundaram -+ */ -+ -+#if defined(LDAP_CASA_AUTH) -+#include "ldap_casa.h" -+#include "dhcpd.h" -+ -+int -+load_casa (void) -+{ -+ if( !(casaIDK = dlopen(MICASA_LIB,RTLD_LAZY))) -+ return 0; -+ p_miCASAGetCredential = (CASA_GetCredential_T) dlsym(casaIDK, "miCASAGetCredential"); -+ p_miCASASetCredential = (CASA_SetCredential_T) dlsym(casaIDK, "miCASASetCredential"); -+ p_miCASARemoveCredential = (CASA_RemoveCredential_T) dlsym(casaIDK, "miCASARemoveCredential"); -+ -+ if((p_miCASAGetCredential == NULL) || -+ (p_miCASASetCredential == NULL) || -+ (p_miCASARemoveCredential == NULL)) -+ { -+ if(casaIDK) -+ dlclose(casaIDK); -+ casaIDK = NULL; -+ p_miCASAGetCredential = NULL; -+ p_miCASASetCredential = NULL; -+ p_miCASARemoveCredential = NULL; -+ return 0; -+ } -+ else -+ return 1; -+} -+ -+static void -+release_casa(void) -+{ -+ if(casaIDK) -+ { -+ dlclose(casaIDK); -+ casaIDK = NULL; -+ } -+ -+ p_miCASAGetCredential = NULL; -+ p_miCASASetCredential = NULL; -+ p_miCASARemoveCredential = NULL; -+ -+} -+ -+int -+load_uname_pwd_from_miCASA (char **ldap_username, char **ldap_password) -+ { -+ int result = 0; -+ uint32_t credentialtype = SSCS_CRED_TYPE_SERVER_F; -+ SSCS_BASIC_CREDENTIAL credential; -+ SSCS_SECRET_ID_T applicationSecretId; -+ char *tempVar = NULL; -+ -+ const char applicationName[10] = "dhcp-ldap"; -+ -+ if ( load_casa() ) -+ { -+ memset(&credential, 0, sizeof(SSCS_BASIC_CREDENTIAL)); -+ memset(&applicationSecretId, 0, sizeof(SSCS_SECRET_ID_T)); -+ -+ applicationSecretId.len = strlen(applicationName) + 1; -+ memcpy (applicationSecretId.id, applicationName, applicationSecretId.len); -+ -+ credential.unFlags = USERNAME_TYPE_CN_F; -+ -+ result = p_miCASAGetCredential (0, -+ &applicationSecretId,NULL,&credentialtype, -+ &credential,NULL); -+ -+ if(credential.unLen) -+ { -+ tempVar = dmalloc (credential.unLen + 1, MDL); -+ if (!tempVar) -+ log_fatal ("no memory for ldap_username"); -+ memcpy(tempVar , credential.username, credential.unLen); -+ *ldap_username = tempVar; -+ -+ tempVar = dmalloc (credential.pwordLen + 1, MDL); -+ if (!tempVar) -+ log_fatal ("no memory for ldap_password"); -+ memcpy(tempVar, credential.password, credential.pwordLen); -+ *ldap_password = tempVar; -+ -+#if defined (DEBUG_LDAP) -+ log_info ("Authentication credential taken from CASA"); -+#endif -+ -+ release_casa(); -+ return 1; -+ -+ } -+ else -+ { -+ release_casa(); -+ return 0; -+ } -+ } -+ else -+ return 0; //casa libraries not loaded -+ } -+ -+#endif /* LDAP_CASA_AUTH */ -+ -diff -up dhcp-4.0.0/server/dhcpd.c.ldap dhcp-4.0.0/server/dhcpd.c ---- dhcp-4.0.0/server/dhcpd.c.ldap 2007-11-30 11:51:43.000000000 -1000 -+++ dhcp-4.0.0/server/dhcpd.c 2008-01-02 11:18:44.000000000 -1000 -@@ -505,6 +505,14 @@ main(int argc, char **argv) { - /* 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); -+#if defined (USE_SSL) -+ add_enumeration (&ldap_ssl_usage_enum); -+ add_enumeration (&ldap_tls_reqcert_enum); -+ add_enumeration (&ldap_tls_crlcheck_enum); -+#endif -+#endif - - if (!group_allocate (&root_group, MDL)) - log_fatal ("Can't allocate root group!"); -diff -up /dev/null dhcp-4.0.0/server/ldap.c ---- /dev/null 2007-12-31 11:39:52.874087547 -1000 -+++ dhcp-4.0.0/server/ldap.c 2008-01-02 11:18:44.000000000 -1000 -@@ -0,0 +1,2004 @@ -+/* ldap.c -+ -+ Routines for reading the configuration from LDAP */ -+ -+/* -+ * Copyright (c) 2003-2006 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 . Its -+ * development was sponsored by Ntelos, Inc. (www.ntelos.com). -+ */ -+ -+#include "dhcpd.h" -+#include -+#include -+ -+#if defined(LDAP_CONFIGURATION) -+ -+#if defined(LDAP_CASA_AUTH) -+#include "ldap_casa.h" -+#endif -+ -+static LDAP * ld = NULL; -+static char *ldap_server = NULL, -+ *ldap_username = NULL, -+ *ldap_password = NULL, -+ *ldap_base_dn = NULL, -+ *ldap_dhcp_server_cn = NULL, -+ *ldap_debug_file = NULL; -+static int ldap_port = LDAP_PORT, -+ ldap_method = LDAP_METHOD_DYNAMIC, -+ ldap_referrals = -1, -+ ldap_debug_fd = -1; -+#if defined (USE_SSL) -+static int ldap_use_ssl = -1, /* try TLS if possible */ -+ ldap_tls_reqcert = -1, -+ ldap_tls_crlcheck = -1; -+static char *ldap_tls_ca_file = NULL, -+ *ldap_tls_ca_dir = NULL, -+ *ldap_tls_cert = NULL, -+ *ldap_tls_key = NULL, -+ *ldap_tls_ciphers = NULL, -+ *ldap_tls_randfile = NULL; -+#endif -+static struct ldap_config_stack *ldap_stack = NULL; -+ -+typedef struct ldap_dn_node { -+ struct ldap_dn_node *next; -+ size_t refs; -+ char *dn; -+} ldap_dn_node; -+ -+static ldap_dn_node *ldap_service_dn_head = NULL; -+static ldap_dn_node *ldap_service_dn_tail = NULL; -+ -+ -+static char * -+x_strncat(char *dst, const char *src, size_t dst_size) -+{ -+ size_t len = strlen(dst); -+ return strncat(dst, src, dst_size > len ? dst_size - len - 1: 0); -+} -+ -+static void -+ldap_parse_class (struct ldap_config_stack *item, struct parse *cfile) -+{ -+ struct berval **tempbv; -+ -+ if ((tempbv = ldap_get_values_len (ld, item->ldent, "cn")) == NULL || -+ tempbv[0] == NULL) -+ { -+ if (tempbv != NULL) -+ ldap_value_free_len (tempbv); -+ -+ return; -+ } -+ -+ x_strncat (cfile->inbuf, "class \"", LDAP_BUFFER_SIZE); -+ x_strncat (cfile->inbuf, tempbv[0]->bv_val, LDAP_BUFFER_SIZE); -+ x_strncat (cfile->inbuf, "\" {\n", LDAP_BUFFER_SIZE); -+ -+ item->close_brace = 1; -+ ldap_value_free_len (tempbv); -+} -+ -+ -+static void -+ldap_parse_subclass (struct ldap_config_stack *item, struct parse *cfile) -+{ -+ struct berval **tempbv, **classdata; -+ -+ if ((tempbv = ldap_get_values_len (ld, item->ldent, "cn")) == NULL || -+ tempbv[0] == NULL) -+ { -+ if (tempbv != NULL) -+ ldap_value_free_len (tempbv); -+ -+ return; -+ } -+ -+ if ((classdata = ldap_get_values_len (ld, item->ldent, -+ "dhcpClassData")) == NULL || -+ classdata[0] == NULL) -+ { -+ if (classdata != NULL) -+ ldap_value_free_len (classdata); -+ ldap_value_free_len (tempbv); -+ -+ return; -+ } -+ -+ x_strncat (cfile->inbuf, "subclass ", LDAP_BUFFER_SIZE); -+ x_strncat (cfile->inbuf, classdata[0]->bv_val, LDAP_BUFFER_SIZE); -+ x_strncat (cfile->inbuf, " ", LDAP_BUFFER_SIZE); -+ x_strncat (cfile->inbuf, tempbv[0]->bv_val, LDAP_BUFFER_SIZE); -+ x_strncat (cfile->inbuf, " {\n", LDAP_BUFFER_SIZE); -+ -+ item->close_brace = 1; -+ ldap_value_free_len (tempbv); -+ ldap_value_free_len (classdata); -+} -+ -+ -+static void -+ldap_parse_host (struct ldap_config_stack *item, struct parse *cfile) -+{ -+ struct berval **tempbv, **hwaddr; -+ -+ if ((tempbv = ldap_get_values_len (ld, item->ldent, "cn")) == NULL || -+ tempbv[0] == NULL) -+ { -+ if (tempbv != NULL) -+ ldap_value_free_len (tempbv); -+ -+ return; -+ } -+ -+ hwaddr = ldap_get_values_len (ld, item->ldent, "dhcpHWAddress"); -+ -+ x_strncat (cfile->inbuf, "host ", LDAP_BUFFER_SIZE); -+ x_strncat (cfile->inbuf, tempbv[0]->bv_val, LDAP_BUFFER_SIZE); -+ -+ if (hwaddr != NULL && hwaddr[0] != NULL) -+ { -+ x_strncat (cfile->inbuf, " {\nhardware ", LDAP_BUFFER_SIZE); -+ x_strncat (cfile->inbuf, hwaddr[0]->bv_val, LDAP_BUFFER_SIZE); -+ x_strncat (cfile->inbuf, ";\n", LDAP_BUFFER_SIZE); -+ ldap_value_free_len (hwaddr); -+ } -+ -+ item->close_brace = 1; -+ ldap_value_free_len (tempbv); -+} -+ -+ -+static void -+ldap_parse_shared_network (struct ldap_config_stack *item, struct parse *cfile) -+{ -+ struct berval **tempbv; -+ -+ if ((tempbv = ldap_get_values_len (ld, item->ldent, "cn")) == NULL || -+ tempbv[0] == NULL) -+ { -+ if (tempbv != NULL) -+ ldap_value_free_len (tempbv); -+ -+ return; -+ } -+ -+ x_strncat (cfile->inbuf, "shared-network \"", LDAP_BUFFER_SIZE); -+ x_strncat (cfile->inbuf, tempbv[0]->bv_val, LDAP_BUFFER_SIZE); -+ x_strncat (cfile->inbuf, "\" {\n", LDAP_BUFFER_SIZE); -+ -+ item->close_brace = 1; -+ ldap_value_free_len (tempbv); -+} -+ -+ -+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 **tempbv, **netmaskstr; -+ char netmaskbuf[16]; -+ int i; -+ -+ if ((tempbv = ldap_get_values_len (ld, item->ldent, "cn")) == NULL || -+ tempbv[0] == NULL) -+ { -+ if (tempbv != NULL) -+ ldap_value_free_len (tempbv); -+ -+ return; -+ } -+ -+ if ((netmaskstr = ldap_get_values_len (ld, item->ldent, -+ "dhcpNetmask")) == NULL || -+ netmaskstr[0] == NULL) -+ { -+ if (netmaskstr != NULL) -+ ldap_value_free_len (netmaskstr); -+ ldap_value_free_len (tempbv); -+ -+ return; -+ } -+ -+ x_strncat (cfile->inbuf, "subnet ", LDAP_BUFFER_SIZE); -+ x_strncat (cfile->inbuf, tempbv[0]->bv_val, LDAP_BUFFER_SIZE); -+ -+ x_strncat (cfile->inbuf, " netmask ", LDAP_BUFFER_SIZE); -+ parse_netmask (strtol (netmaskstr[0]->bv_val, NULL, 10), netmaskbuf); -+ x_strncat (cfile->inbuf, netmaskbuf, LDAP_BUFFER_SIZE); -+ -+ x_strncat (cfile->inbuf, " {\n", LDAP_BUFFER_SIZE); -+ -+ ldap_value_free_len (tempbv); -+ ldap_value_free_len (netmaskstr); -+ -+ if ((tempbv = ldap_get_values_len (ld, item->ldent, "dhcpRange")) != NULL) -+ { -+ for (i=0; tempbv[i] != NULL; i++) -+ { -+ x_strncat (cfile->inbuf, "range", LDAP_BUFFER_SIZE); -+ x_strncat (cfile->inbuf, " ", LDAP_BUFFER_SIZE); -+ x_strncat (cfile->inbuf, tempbv[i]->bv_val, LDAP_BUFFER_SIZE); -+ x_strncat (cfile->inbuf, ";\n", LDAP_BUFFER_SIZE); -+ } -+ } -+ -+ item->close_brace = 1; -+} -+ -+ -+static void -+ldap_parse_pool (struct ldap_config_stack *item, struct parse *cfile) -+{ -+ struct berval **tempbv; -+ int i; -+ -+ x_strncat (cfile->inbuf, "pool {\n", LDAP_BUFFER_SIZE); -+ -+ if ((tempbv = ldap_get_values_len (ld, item->ldent, "dhcpRange")) != NULL) -+ { -+ x_strncat (cfile->inbuf, "range", LDAP_BUFFER_SIZE); -+ for (i=0; tempbv[i] != NULL; i++) -+ { -+ x_strncat (cfile->inbuf, " ", LDAP_BUFFER_SIZE); -+ x_strncat (cfile->inbuf, tempbv[i]->bv_val, LDAP_BUFFER_SIZE); -+ } -+ x_strncat (cfile->inbuf, ";\n", LDAP_BUFFER_SIZE); -+ ldap_value_free_len (tempbv); -+ } -+ -+ if ((tempbv = ldap_get_values_len (ld, item->ldent, "dhcpPermitList")) != NULL) -+ { -+ for (i=0; tempbv[i] != NULL; i++) -+ { -+ x_strncat (cfile->inbuf, tempbv[i]->bv_val, LDAP_BUFFER_SIZE); -+ x_strncat (cfile->inbuf, ";\n", LDAP_BUFFER_SIZE); -+ } -+ ldap_value_free_len (tempbv); -+ } -+ -+ item->close_brace = 1; -+} -+ -+ -+static void -+ldap_parse_group (struct ldap_config_stack *item, struct parse *cfile) -+{ -+ x_strncat (cfile->inbuf, "group {\n", LDAP_BUFFER_SIZE); -+ item->close_brace = 1; -+} -+ -+ -+static void -+ldap_parse_key (struct ldap_config_stack *item, struct parse *cfile) -+{ -+ struct berval **tempbv; -+ -+ if ((tempbv = ldap_get_values_len (ld, item->ldent, "cn")) != NULL) -+ { -+ x_strncat (cfile->inbuf, "key ", LDAP_BUFFER_SIZE); -+ x_strncat (cfile->inbuf, tempbv[0]->bv_val, LDAP_BUFFER_SIZE); -+ x_strncat (cfile->inbuf, " {\n", LDAP_BUFFER_SIZE); -+ ldap_value_free_len (tempbv); -+ } -+ -+ if ((tempbv = ldap_get_values_len (ld, item->ldent, "dhcpKeyAlgorithm")) != NULL) -+ { -+ x_strncat (cfile->inbuf, "algorithm ", LDAP_BUFFER_SIZE); -+ x_strncat (cfile->inbuf, tempbv[0]->bv_val, LDAP_BUFFER_SIZE); -+ x_strncat (cfile->inbuf, ";\n", LDAP_BUFFER_SIZE); -+ ldap_value_free_len (tempbv); -+ } -+ -+ if ((tempbv = ldap_get_values_len (ld, item->ldent, "dhcpKeySecret")) != NULL) -+ { -+ x_strncat (cfile->inbuf, "secret ", LDAP_BUFFER_SIZE); -+ x_strncat (cfile->inbuf, tempbv[0]->bv_val, LDAP_BUFFER_SIZE); -+ x_strncat (cfile->inbuf, ";\n", LDAP_BUFFER_SIZE); -+ ldap_value_free_len (tempbv); -+ } -+ -+ item->close_brace = 1; -+} -+ -+ -+static void -+ldap_parse_zone (struct ldap_config_stack *item, struct parse *cfile) -+{ -+ char *cnFindStart, *cnFindEnd; -+ struct berval **tempbv; -+ char *keyCn; -+ size_t len; -+ -+ if ((tempbv = ldap_get_values_len (ld, item->ldent, "cn")) != NULL) -+ { -+ x_strncat (cfile->inbuf, "zone ", LDAP_BUFFER_SIZE); -+ x_strncat (cfile->inbuf, tempbv[0]->bv_val, LDAP_BUFFER_SIZE); -+ x_strncat (cfile->inbuf, " {\n", LDAP_BUFFER_SIZE); -+ ldap_value_free_len (tempbv); -+ } -+ -+ if ((tempbv = ldap_get_values_len (ld, item->ldent, "dhcpDnsZoneServer")) != NULL) -+ { -+ x_strncat (cfile->inbuf, "primary ", LDAP_BUFFER_SIZE); -+ x_strncat (cfile->inbuf, tempbv[0]->bv_val, LDAP_BUFFER_SIZE); -+ -+ x_strncat (cfile->inbuf, ";\n", LDAP_BUFFER_SIZE); -+ ldap_value_free_len (tempbv); -+ } -+ -+ if ((tempbv = ldap_get_values_len (ld, item->ldent, "dhcpKeyDN")) != NULL) -+ { -+ cnFindStart = strchr(tempbv[0]->bv_val,'='); -+ if (cnFindStart != NULL) -+ cnFindEnd = strchr(++cnFindStart,','); -+ else -+ cnFindEnd = NULL; -+ -+ if (cnFindEnd != NULL && cnFindEnd > cnFindStart) -+ { -+ len = cnFindEnd - cnFindStart; -+ keyCn = dmalloc (len + 1, MDL); -+ } -+ else -+ { -+ len = 0; -+ keyCn = NULL; -+ } -+ -+ if (keyCn != NULL) -+ { -+ strncpy (keyCn, cnFindStart, len); -+ keyCn[len] = '\0'; -+ -+ x_strncat (cfile->inbuf, "key ", LDAP_BUFFER_SIZE); -+ x_strncat (cfile->inbuf, keyCn, LDAP_BUFFER_SIZE); -+ x_strncat (cfile->inbuf, ";\n", LDAP_BUFFER_SIZE); -+ -+ dfree (keyCn, MDL); -+ } -+ -+ ldap_value_free_len (tempbv); -+ } -+ -+ item->close_brace = 1; -+} -+ -+ -+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->next = ldap_stack; -+ ldap_stack = ns; -+} -+ -+ -+static void -+ldap_stop() -+{ -+ struct sigaction old, new; -+ -+ if (ld == NULL) -+ return; -+ -+ /* -+ ** ldap_unbind after a LDAP_SERVER_DOWN result -+ ** causes a SIGPIPE and dhcpd gets terminated, -+ ** since it doesn't handle it... -+ */ -+ -+ new.sa_flags = 0; -+ new.sa_handler = SIG_IGN; -+ sigemptyset (&new.sa_mask); -+ sigaction (SIGPIPE, &new, &old); -+ -+ ldap_unbind_ext_s (ld, NULL, NULL); -+ ld = NULL; -+ -+ sigaction (SIGPIPE, &old, &new); -+} -+ -+ -+static char * -+_do_lookup_dhcp_string_option (struct option_state *options, int option_name) -+{ -+ struct option_cache *oc; -+ struct data_string db; -+ char *ret; -+ -+ memset (&db, 0, sizeof (db)); -+ oc = lookup_option (&server_universe, options, option_name); -+ 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) && -+ db.data != NULL && *db.data != '\0') -+ -+ { -+ ret = dmalloc (db.len + 1, MDL); -+ if (ret == NULL) -+ log_fatal ("no memory for ldap option %d value", option_name); -+ -+ memcpy (ret, db.data, db.len); -+ ret[db.len] = 0; -+ data_string_forget (&db, MDL); -+ } -+ else -+ ret = NULL; -+ -+ return (ret); -+} -+ -+ -+static int -+_do_lookup_dhcp_int_option (struct option_state *options, int option_name) -+{ -+ struct option_cache *oc; -+ struct data_string db; -+ int ret; -+ -+ memset (&db, 0, sizeof (db)); -+ oc = lookup_option (&server_universe, options, option_name); -+ 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) && -+ db.data != NULL && *db.data != '\0') -+ { -+ ret = strtol ((const char *) db.data, NULL, 10); -+ data_string_forget (&db, MDL); -+ } -+ else -+ ret = 0; -+ -+ return (ret); -+} -+ -+ -+static int -+_do_lookup_dhcp_enum_option (struct option_state *options, int option_name) -+{ -+ struct option_cache *oc; -+ struct data_string db; -+ int ret = -1; -+ -+ memset (&db, 0, sizeof (db)); -+ oc = lookup_option (&server_universe, options, option_name); -+ 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) && -+ db.data != NULL && *db.data != '\0') -+ { -+ if (db.len == 1) -+ ret = db.data [0]; -+ else -+ log_fatal ("invalid option name %d", option_name); -+ -+ data_string_forget (&db, MDL); -+ } -+ else -+ ret = 0; -+ -+ return (ret); -+} -+ -+int -+ldap_rebind_cb (LDAP *ld, LDAP_CONST char *url, ber_tag_t request, ber_int_t msgid, void *parms) -+{ -+ int ret; -+ LDAPURLDesc *ldapurl = NULL; -+ char *who = NULL; -+ struct berval creds; -+ -+ log_info("LDAP rebind to '%s'", url); -+ if ((ret = ldap_url_parse(url, &ldapurl)) != LDAP_SUCCESS) -+ { -+ log_error ("Error: Can not parse ldap rebind url '%s': %s", -+ url, ldap_err2string(ret)); -+ return ret; -+ } -+ -+ -+#if defined (USE_SSL) -+ if (strcasecmp(ldapurl->lud_scheme, "ldaps") == 0) -+ { -+ int opt = LDAP_OPT_X_TLS_HARD; -+ if ((ret = ldap_set_option (ld, LDAP_OPT_X_TLS, &opt)) != LDAP_SUCCESS) -+ { -+ log_error ("Error: Cannot init LDAPS session to %s:%d: %s", -+ ldapurl->lud_host, ldapurl->lud_port, ldap_err2string (ret)); -+ return ret; -+ } -+ else -+ { -+ log_info ("LDAPS session successfully enabled to %s", ldap_server); -+ } -+ } -+ else -+ if (strcasecmp(ldapurl->lud_scheme, "ldap") == 0 && -+ ldap_use_ssl != LDAP_SSL_OFF) -+ { -+ if ((ret = ldap_start_tls_s (ld, NULL, NULL)) != LDAP_SUCCESS) -+ { -+ log_error ("Error: Cannot start TLS session to %s:%d: %s", -+ ldapurl->lud_host, ldapurl->lud_port, ldap_err2string (ret)); -+ return ret; -+ } -+ else -+ { -+ log_info ("TLS session successfully started to %s:%d", -+ ldapurl->lud_host, ldapurl->lud_port); -+ } -+ } -+#endif -+ -+ -+ if (ldap_username != NULL || *ldap_username != '\0') -+ { -+ who = ldap_username; -+ creds.bv_val = strdup(ldap_password); -+ creds.bv_len = strlen(ldap_password); -+ } -+ -+ if ((ret = ldap_sasl_bind_s (ld, who, LDAP_SASL_SIMPLE, &creds, -+ NULL, NULL, NULL)) != LDAP_SUCCESS) -+ { -+ log_error ("Error: Cannot login into ldap server %s:%d: %s", -+ ldapurl->lud_host, ldapurl->lud_port, ldap_err2string (ret)); -+ } -+ return ret; -+} -+ -+static void -+ldap_start (void) -+{ -+ struct option_state *options; -+ int ret, version; -+ char *uri = NULL; -+ struct berval creds; -+ -+ 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); -+ -+ ldap_server = _do_lookup_dhcp_string_option (options, SV_LDAP_SERVER); -+ ldap_dhcp_server_cn = _do_lookup_dhcp_string_option (options, -+ SV_LDAP_DHCP_SERVER_CN); -+ ldap_port = _do_lookup_dhcp_int_option (options, SV_LDAP_PORT); -+ ldap_base_dn = _do_lookup_dhcp_string_option (options, SV_LDAP_BASE_DN); -+ ldap_method = _do_lookup_dhcp_enum_option (options, SV_LDAP_METHOD); -+ ldap_debug_file = _do_lookup_dhcp_string_option (options, -+ SV_LDAP_DEBUG_FILE); -+ ldap_referrals = _do_lookup_dhcp_enum_option (options, SV_LDAP_REFERRALS); -+ -+#if defined (USE_SSL) -+ ldap_use_ssl = _do_lookup_dhcp_enum_option (options, SV_LDAP_SSL); -+ if( ldap_use_ssl != LDAP_SSL_OFF) -+ { -+ ldap_tls_reqcert = _do_lookup_dhcp_enum_option (options, SV_LDAP_TLS_REQCERT); -+ ldap_tls_ca_file = _do_lookup_dhcp_string_option (options, SV_LDAP_TLS_CA_FILE); -+ ldap_tls_ca_dir = _do_lookup_dhcp_string_option (options, SV_LDAP_TLS_CA_DIR); -+ ldap_tls_cert = _do_lookup_dhcp_string_option (options, SV_LDAP_TLS_CERT); -+ ldap_tls_key = _do_lookup_dhcp_string_option (options, SV_LDAP_TLS_KEY); -+ ldap_tls_crlcheck = _do_lookup_dhcp_enum_option (options, SV_LDAP_TLS_CRLCHECK); -+ ldap_tls_ciphers = _do_lookup_dhcp_string_option (options, SV_LDAP_TLS_CIPHERS); -+ ldap_tls_randfile = _do_lookup_dhcp_string_option (options, SV_LDAP_TLS_RANDFILE); -+ } -+#endif -+ -+#if defined (LDAP_CASA_AUTH) -+ if (!load_uname_pwd_from_miCASA(&ldap_username,&ldap_password)) -+ { -+#if defined (DEBUG_LDAP) -+ log_info ("Authentication credential taken from file"); -+#endif -+#endif -+ -+ ldap_username = _do_lookup_dhcp_string_option (options, SV_LDAP_USERNAME); -+ ldap_password = _do_lookup_dhcp_string_option (options, SV_LDAP_PASSWORD); -+ -+#if defined (LDAP_CASA_AUTH) -+ } -+#endif -+ -+ option_state_dereference (&options, MDL); -+ } -+ -+ if (ldap_server == NULL || ldap_base_dn == NULL) -+ { -+ log_info ("Not searching LDAP since ldap-server, ldap-port and ldap-base-dn were not specified in the config file"); -+ ldap_method = LDAP_METHOD_STATIC; -+ return; -+ } -+ -+ if (ldap_debug_file != NULL && ldap_debug_fd == -1) -+ { -+ if ((ldap_debug_fd = open (ldap_debug_file, O_CREAT | O_TRUNC | O_WRONLY, -+ S_IRUSR | S_IWUSR)) < 0) -+ log_error ("Error opening debug LDAP log file %s: %s", ldap_debug_file, -+ strerror (errno)); -+ } -+ -+#if defined (DEBUG_LDAP) -+ log_info ("Connecting to LDAP server %s:%d", ldap_server, ldap_port); -+#endif -+ -+#if defined (USE_SSL) -+ if (ldap_use_ssl == -1) -+ { -+ /* -+ ** There was no "ldap-ssl" option in dhcpd.conf (also not "off"). -+ ** Let's try, if we can use an anonymous TLS session without to -+ ** verify the server certificate -- if not continue without TLS. -+ */ -+ int opt = LDAP_OPT_X_TLS_ALLOW; -+ if ((ret = ldap_set_option (NULL, LDAP_OPT_X_TLS_REQUIRE_CERT, -+ &opt)) != LDAP_SUCCESS) -+ { -+ log_error ("Warning: Cannot set LDAP TLS require cert option to 'allow': %s", -+ ldap_err2string (ret)); -+ } -+ } -+ -+ if (ldap_use_ssl != LDAP_SSL_OFF) -+ { -+ if (ldap_tls_reqcert != -1) -+ { -+ if ((ret = ldap_set_option (NULL, LDAP_OPT_X_TLS_REQUIRE_CERT, -+ &ldap_tls_reqcert)) != LDAP_SUCCESS) -+ { -+ log_error ("Cannot set LDAP TLS require cert option: %s", -+ ldap_err2string (ret)); -+ } -+ } -+ -+ if( ldap_tls_ca_file != NULL) -+ { -+ if ((ret = ldap_set_option (NULL, LDAP_OPT_X_TLS_CACERTFILE, -+ ldap_tls_ca_file)) != LDAP_SUCCESS) -+ { -+ log_error ("Cannot set LDAP TLS CA certificate file %s: %s", -+ ldap_tls_ca_file, ldap_err2string (ret)); -+ } -+ } -+ if( ldap_tls_ca_dir != NULL) -+ { -+ if ((ret = ldap_set_option (NULL, LDAP_OPT_X_TLS_CACERTDIR, -+ ldap_tls_ca_dir)) != LDAP_SUCCESS) -+ { -+ log_error ("Cannot set LDAP TLS CA certificate dir %s: %s", -+ ldap_tls_ca_dir, ldap_err2string (ret)); -+ } -+ } -+ if( ldap_tls_cert != NULL) -+ { -+ if ((ret = ldap_set_option (NULL, LDAP_OPT_X_TLS_CERTFILE, -+ ldap_tls_cert)) != LDAP_SUCCESS) -+ { -+ log_error ("Cannot set LDAP TLS client certificate file %s: %s", -+ ldap_tls_cert, ldap_err2string (ret)); -+ } -+ } -+ if( ldap_tls_key != NULL) -+ { -+ if ((ret = ldap_set_option (NULL, LDAP_OPT_X_TLS_KEYFILE, -+ ldap_tls_key)) != LDAP_SUCCESS) -+ { -+ log_error ("Cannot set LDAP TLS certificate key file %s: %s", -+ ldap_tls_key, ldap_err2string (ret)); -+ } -+ } -+ if( ldap_tls_crlcheck != -1) -+ { -+ int opt = ldap_tls_crlcheck; -+ if ((ret = ldap_set_option (NULL, LDAP_OPT_X_TLS_CRLCHECK, -+ &opt)) != LDAP_SUCCESS) -+ { -+ log_error ("Cannot set LDAP TLS crl check option: %s", -+ ldap_err2string (ret)); -+ } -+ } -+ if( ldap_tls_ciphers != NULL) -+ { -+ if ((ret = ldap_set_option (NULL, LDAP_OPT_X_TLS_CIPHER_SUITE, -+ ldap_tls_ciphers)) != LDAP_SUCCESS) -+ { -+ log_error ("Cannot set LDAP TLS cipher suite %s: %s", -+ ldap_tls_ciphers, ldap_err2string (ret)); -+ } -+ } -+ if( ldap_tls_randfile != NULL) -+ { -+ if ((ret = ldap_set_option (NULL, LDAP_OPT_X_TLS_RANDOM_FILE, -+ ldap_tls_randfile)) != LDAP_SUCCESS) -+ { -+ log_error ("Cannot set LDAP TLS random file %s: %s", -+ ldap_tls_randfile, ldap_err2string (ret)); -+ } -+ } -+ } -+#endif -+ -+ /* enough for 'ldap://+ + hostname + ':' + port number */ -+ uri = malloc(strlen(ldap_server) + 16); -+ if (uri == NULL) -+ { -+ log_error ("Cannot build ldap init URI %s:%d", ldap_server, ldap_port); -+ return; -+ } -+ -+ sprintf("ldap://%s:%d", ldap_server, ldap_port); -+ ldap_initialize(&ld, uri); -+ -+ if (ld == NULL) -+ { -+ log_error ("Cannot init ldap session to %s:%d", ldap_server, ldap_port); -+ return; -+ } -+ -+ free(uri); -+ -+ version = LDAP_VERSION3; -+ if ((ret = ldap_set_option (ld, LDAP_OPT_PROTOCOL_VERSION, &version)) != LDAP_OPT_SUCCESS) -+ { -+ log_error ("Cannot set LDAP version to %d: %s", version, -+ ldap_err2string (ret)); -+ } -+ -+ if (ldap_referrals != -1) -+ { -+ if ((ret = ldap_set_option (ld, LDAP_OPT_REFERRALS, ldap_referrals ? -+ LDAP_OPT_ON : LDAP_OPT_OFF)) != LDAP_OPT_SUCCESS) -+ { -+ log_error ("Cannot %s LDAP referrals option: %s", -+ (ldap_referrals ? "enable" : "disable"), -+ ldap_err2string (ret)); -+ } -+ } -+ -+ if ((ret = ldap_set_rebind_proc(ld, ldap_rebind_cb, NULL)) != LDAP_SUCCESS) -+ { -+ log_error ("Warning: Cannot set ldap rebind procedure: %s", -+ ldap_err2string (ret)); -+ } -+ -+#if defined (USE_SSL) -+ if (ldap_use_ssl == LDAP_SSL_LDAPS || -+ (ldap_use_ssl == LDAP_SSL_ON && ldap_port == LDAPS_PORT)) -+ { -+ int opt = LDAP_OPT_X_TLS_HARD; -+ if ((ret = ldap_set_option (ld, LDAP_OPT_X_TLS, &opt)) != LDAP_SUCCESS) -+ { -+ log_error ("Error: Cannot init LDAPS session to %s:%d: %s", -+ ldap_server, ldap_port, ldap_err2string (ret)); -+ ldap_stop(); -+ return; -+ } -+ else -+ { -+ log_info ("LDAPS session successfully enabled to %s:%d", -+ ldap_server, ldap_port); -+ } -+ } -+ else if (ldap_use_ssl != LDAP_SSL_OFF) -+ { -+ if ((ret = ldap_start_tls_s (ld, NULL, NULL)) != LDAP_SUCCESS) -+ { -+ log_error ("Error: Cannot start TLS session to %s:%d: %s", -+ ldap_server, ldap_port, ldap_err2string (ret)); -+ ldap_stop(); -+ return; -+ } -+ else -+ { -+ log_info ("TLS session successfully started to %s:%d", -+ ldap_server, ldap_port); -+ } -+ } -+#endif -+ -+ if (ldap_username != NULL && *ldap_username != '\0') -+ { -+ creds.bv_val = strdup(ldap_password); -+ creds.bv_len = strlen(ldap_password); -+ -+ if ((ret == ldap_sasl_bind_s (ld, ldap_username, LDAP_SASL_SIMPLE, -+ &creds, NULL, NULL, NULL)) != LDAP_SUCCESS) -+ { -+ log_error ("Error: Cannot login into ldap server %s:%d: %s", -+ ldap_server, ldap_port, ldap_err2string (ret)); -+ ldap_stop(); -+ return; -+ } -+ } -+ -+#if defined (DEBUG_LDAP) -+ log_info ("Successfully logged into LDAP server %s", ldap_server); -+#endif -+} -+ -+ -+static void -+parse_external_dns (LDAPMessage * ent) -+{ -+ char *search[] = {"dhcpOptionsDN", "dhcpSharedNetworkDN", "dhcpSubnetDN", -+ "dhcpGroupDN", "dhcpHostDN", "dhcpClassesDN", -+ "dhcpPoolDN", NULL}; -+ LDAPMessage * newres, * newent; -+ struct berval **tempbv; -+ int i, j, ret; -+#if defined (DEBUG_LDAP) -+ char *dn; -+ -+ dn = ldap_get_dn (ld, ent); -+ if (dn != NULL) -+ { -+ log_info ("Parsing external DNs for '%s'", dn); -+ ldap_memfree (dn); -+ } -+#endif -+ -+ if (ld == NULL) -+ ldap_start (); -+ if (ld == NULL) -+ return; -+ -+ for (i=0; search[i] != NULL; i++) -+ { -+ if ((tempbv = ldap_get_values_len (ld, ent, search[i])) == NULL) -+ continue; -+ -+ for (j=0; tempbv[j] != NULL; j++) -+ { -+ if (*tempbv[j]->bv_val == '\0') -+ continue; -+ -+ if ((ret = ldap_search_ext_s(ld, tempbv[j]->bv_val, LDAP_SCOPE_BASE, -+ "objectClass=*", NULL, 0, NULL, -+ NULL, NULL, 0, &newres)) != LDAP_SUCCESS) -+ { -+ ldap_value_free_len (tempbv); -+ ldap_stop(); -+ return; -+ } -+ -+#if defined (DEBUG_LDAP) -+ log_info ("Adding contents of subtree '%s' to config stack from '%s' reference", tempbv[j], search[i]); -+#endif -+ for (newent = ldap_first_entry (ld, newres); -+ newent != NULL; -+ newent = ldap_next_entry (ld, newent)) -+ { -+#if defined (DEBUG_LDAP) -+ dn = ldap_get_dn (ld, newent); -+ if (dn != NULL) -+ { -+ log_info ("Adding LDAP result set starting with '%s' to config stack", dn); -+ ldap_memfree (dn); -+ } -+#endif -+ -+ add_to_config_stack (newres, newent); -+ /* don't free newres here */ -+ } -+ } -+ -+ ldap_value_free_len (tempbv); -+ } -+} -+ -+ -+static void -+free_stack_entry (struct ldap_config_stack *item) -+{ -+ struct ldap_config_stack *look_ahead_pointer = item; -+ int may_free_msg = 1; -+ -+ while (look_ahead_pointer->next != NULL) -+ { -+ look_ahead_pointer = look_ahead_pointer->next; -+ if (look_ahead_pointer->res == item->res) -+ { -+ may_free_msg = 0; -+ break; -+ } -+ } -+ -+ if (may_free_msg) -+ ldap_msgfree (item->res); -+ -+ dfree (item, MDL); -+} -+ -+ -+static void -+next_ldap_entry (struct parse *cfile) -+{ -+ struct ldap_config_stack *temp_stack; -+ -+ if (ldap_stack != NULL && ldap_stack->close_brace) -+ { -+ x_strncat (cfile->inbuf, "}\n", LDAP_BUFFER_SIZE); -+ ldap_stack->close_brace = 0; -+ } -+ -+ while (ldap_stack != NULL && -+ (ldap_stack->ldent == NULL || -+ (ldap_stack->ldent = ldap_next_entry (ld, ldap_stack->ldent)) == NULL)) -+ { -+ if (ldap_stack->close_brace) -+ { -+ x_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->close_brace) -+ { -+ x_strncat (cfile->inbuf, "}\n", LDAP_BUFFER_SIZE); -+ ldap_stack->close_brace = 0; -+ } -+} -+ -+ -+static char -+check_statement_end (const char *statement) -+{ -+ char *ptr; -+ -+ if (statement == NULL || *statement == '\0') -+ return ('\0'); -+ -+ /* -+ ** check if it ends with "}", e.g.: -+ ** "zone my.domain. { ... }" -+ ** optionally followed by spaces -+ */ -+ ptr = strrchr (statement, '}'); -+ if (ptr != NULL) -+ { -+ /* skip following white-spaces */ -+ for (++ptr; isspace ((int)*ptr); ptr++); -+ -+ /* check if we reached the end */ -+ if (*ptr == '\0') -+ return ('}'); /* yes, block end */ -+ else -+ return (*ptr); -+ } -+ -+ /* -+ ** this should not happen, but... -+ ** check if it ends with ";", e.g.: -+ ** "authoritative;" -+ ** optionally followed by spaces -+ */ -+ ptr = strrchr (statement, ';'); -+ if (ptr != NULL) -+ { -+ /* skip following white-spaces */ -+ for (++ptr; isspace ((int)*ptr); ptr++); -+ -+ /* check if we reached the end */ -+ if (*ptr == '\0') -+ return (';'); /* ends with a ; */ -+ else -+ return (*ptr); -+ } -+ -+ return ('\0'); -+} -+ -+ -+static isc_result_t -+ldap_parse_entry_options (LDAPMessage *ent, char *buffer, size_t size, -+ int *lease_limit) -+{ -+ struct berval **tempbv; -+ int i; -+ -+ if (ent == NULL || buffer == NULL || size == 0) -+ return (ISC_R_FAILURE); -+ -+ if ((tempbv = ldap_get_values_len (ld, ent, "dhcpStatements")) != NULL) -+ { -+ for (i=0; tempbv[i] != NULL; i++) -+ { -+ if (lease_limit != NULL && -+ strncasecmp ("lease limit ", tempbv[i]->bv_val, 12) == 0) -+ { -+ *lease_limit = (int) strtol ((tempbv[i]->bv_val) + 12, NULL, 10); -+ continue; -+ } -+ -+ x_strncat (buffer, tempbv[i]->bv_val, size); -+ -+ switch((int) check_statement_end (tempbv[i]->bv_val)) -+ { -+ case '}': -+ case ';': -+ x_strncat (buffer, "\n", size); -+ break; -+ default: -+ x_strncat (buffer, ";\n", size); -+ break; -+ } -+ } -+ ldap_value_free_len (tempbv); -+ } -+ -+ if ((tempbv = ldap_get_values_len (ld, ent, "dhcpOption")) != NULL) -+ { -+ for (i=0; tempbv[i] != NULL; i++) -+ { -+ x_strncat (buffer, "option ", size); -+ x_strncat (buffer, tempbv[i]->bv_val, size); -+ switch ((int) check_statement_end (tempbv[i]->bv_val)) -+ { -+ case ';': -+ x_strncat (buffer, "\n", size); -+ break; -+ default: -+ x_strncat (buffer, ";\n", size); -+ break; -+ } -+ } -+ ldap_value_free_len (tempbv); -+ } -+ -+ return (ISC_R_SUCCESS); -+} -+ -+ -+static void -+ldap_generate_config_string (struct parse *cfile) -+{ -+ struct berval **objectClass; -+ char *dn; -+ struct ldap_config_stack *entry; -+ LDAPMessage * ent, * res; -+ int i, ignore, found; -+ int ret; -+ -+ if (ld == NULL) -+ ldap_start (); -+ if (ld == NULL) -+ return; -+ -+ entry = ldap_stack; -+ if ((objectClass = ldap_get_values_len (ld, entry->ldent, -+ "objectClass")) == NULL) -+ return; -+ -+ ignore = 0; -+ found = 1; -+ for (i=0; objectClass[i] != NULL; i++) -+ { -+ if (strcasecmp (objectClass[i]->bv_val, "dhcpSharedNetwork") == 0) -+ ldap_parse_shared_network (entry, cfile); -+ else if (strcasecmp (objectClass[i]->bv_val, "dhcpClass") == 0) -+ ldap_parse_class (entry, cfile); -+ else if (strcasecmp (objectClass[i]->bv_val, "dhcpSubnet") == 0) -+ ldap_parse_subnet (entry, cfile); -+ else if (strcasecmp (objectClass[i]->bv_val, "dhcpPool") == 0) -+ ldap_parse_pool (entry, cfile); -+ else if (strcasecmp (objectClass[i]->bv_val, "dhcpGroup") == 0) -+ ldap_parse_group (entry, cfile); -+ else if (strcasecmp (objectClass[i]->bv_val, "dhcpTSigKey") == 0) -+ ldap_parse_key (entry, cfile); -+ else if (strcasecmp (objectClass[i]->bv_val, "dhcpDnsZone") == 0) -+ ldap_parse_zone (entry, cfile); -+ else if (strcasecmp (objectClass[i]->bv_val, "dhcpHost") == 0) -+ { -+ if (ldap_method == LDAP_METHOD_STATIC) -+ ldap_parse_host (entry, cfile); -+ else -+ { -+ ignore = 1; -+ break; -+ } -+ } -+ else if (strcasecmp (objectClass[i]->bv_val, "dhcpSubClass") == 0) -+ { -+ if (ldap_method == LDAP_METHOD_STATIC) -+ ldap_parse_subclass (entry, cfile); -+ else -+ { -+ ignore = 1; -+ break; -+ } -+ } -+ else -+ found = 0; -+ -+ if (found && cfile->inbuf[0] == '\0') -+ { -+ ignore = 1; -+ break; -+ } -+ } -+ -+ ldap_value_free_len (objectClass); -+ -+ if (ignore) -+ { -+ next_ldap_entry (cfile); -+ return; -+ } -+ -+ ldap_parse_entry_options(entry->ldent, cfile->inbuf, -+ LDAP_BUFFER_SIZE-1, NULL); -+ -+ dn = ldap_get_dn (ld, entry->ldent); -+ -+#if defined(DEBUG_LDAP) -+ if (dn != NULL) -+ log_info ("Found LDAP entry '%s'", dn); -+#endif -+ -+ if (dn == NULL || -+ (ret = ldap_search_ext_s (ld, dn, LDAP_SCOPE_ONELEVEL, -+ "objectClass=*", NULL, 0, NULL, NULL, -+ NULL, 0, &res)) != LDAP_SUCCESS) -+ { -+ if (dn) -+ ldap_memfree (dn); -+ -+ ldap_stop(); -+ return; -+ } -+ -+ ldap_memfree (dn); -+ -+ if ((ent = ldap_first_entry (ld, res)) != NULL) -+ { -+ add_to_config_stack (res, ent); -+ parse_external_dns (entry->ldent); -+ } -+ else -+ { -+ ldap_msgfree (res); -+ parse_external_dns (entry->ldent); -+ next_ldap_entry (cfile); -+ } -+} -+ -+ -+static void -+ldap_close_debug_fd() -+{ -+ if (ldap_debug_fd != -1) -+ { -+ close (ldap_debug_fd); -+ ldap_debug_fd = -1; -+ } -+} -+ -+ -+static void -+ldap_write_debug (const void *buff, size_t size) -+{ -+ if (ldap_debug_fd != -1) -+ { -+ if (write (ldap_debug_fd, buff, size) < 0) -+ { -+ log_error ("Error writing to LDAP debug file %s: %s." -+ " Disabling log file.", ldap_debug_file, -+ strerror (errno)); -+ ldap_close_debug_fd(); -+ } -+ } -+} -+ -+static int -+ldap_read_function (struct parse *cfile) -+{ -+ cfile->inbuf[0] = '\0'; -+ cfile->buflen = 0; -+ -+ while (ldap_stack != NULL && *cfile->inbuf == '\0') -+ ldap_generate_config_string (cfile); -+ -+ if (ldap_stack == NULL && *cfile->inbuf == '\0') -+ return (EOF); -+ -+ cfile->bufix = 1; -+ cfile->buflen = strlen (cfile->inbuf); -+ if (cfile->buflen > 0) -+ ldap_write_debug (cfile->inbuf, cfile->buflen); -+ -+#if defined (DEBUG_LDAP) -+ log_info ("Sending config line '%s'", cfile->inbuf); -+#endif -+ -+ 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) -+ ret = ldap_get_dn (ld, ent); -+ if (ret != NULL) -+ { -+ log_info ("Cannot get cn attribute for LDAP entry %s", ret); -+ ldap_memfree(ret); -+ } -+#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); -+} -+ -+ -+static int -+getfqhostname(char *fqhost, size_t size) -+{ -+#if defined(MAXHOSTNAMELEN) -+ char hname[MAXHOSTNAMELEN]; -+#else -+ char hname[65]; -+#endif -+ struct hostent *hp; -+ -+ if(NULL == fqhost || 1 >= size) -+ return -1; -+ -+ memset(hname, 0, sizeof(hname)); -+ if( gethostname(hname, sizeof(hname)-1)) -+ return -1; -+ -+ if(NULL == (hp = gethostbyname(hname))) -+ return -1; -+ -+ strncpy(fqhost, hp->h_name, size-1); -+ fqhost[size-1] = '\0'; -+ return 0; -+} -+ -+ -+isc_result_t -+ldap_read_config (void) -+{ -+ LDAPMessage * ldres, * hostres, * ent, * hostent; -+ char hfilter[1024], sfilter[1024], fqdn[257]; -+ char *buffer, *hostdn; -+ ldap_dn_node *curr = NULL; -+ struct parse *cfile; -+ struct utsname unme; -+ isc_result_t res; -+ size_t length; -+ int ret, cnt; -+ struct berval **tempbv = NULL; -+ -+ if (ld == NULL) -+ ldap_start (); -+ if (ld == NULL) -+ return (ldap_server == NULL ? ISC_R_SUCCESS : ISC_R_FAILURE); -+ -+ buffer = dmalloc (LDAP_BUFFER_SIZE+1, MDL); -+ if (buffer == NULL) -+ return (ISC_R_FAILURE); -+ -+ cfile = (struct parse *) NULL; -+ res = new_parse (&cfile, -1, buffer, LDAP_BUFFER_SIZE, "LDAP", 0); -+ if (res != ISC_R_SUCCESS) -+ return (res); -+ -+ uname (&unme); -+ if (ldap_dhcp_server_cn != NULL) -+ { -+ snprintf (hfilter, sizeof (hfilter), -+ "(&(objectClass=dhcpServer)(cn=%s))", ldap_dhcp_server_cn); -+ } -+ else -+ { -+ if(0 == getfqhostname(fqdn, sizeof(fqdn))) -+ { -+ snprintf (hfilter, sizeof (hfilter), -+ "(&(objectClass=dhcpServer)(|(cn=%s)(cn=%s)))", -+ unme.nodename, fqdn); -+ } -+ else -+ { -+ snprintf (hfilter, sizeof (hfilter), -+ "(&(objectClass=dhcpServer)(cn=%s))", unme.nodename); -+ } -+ -+ } -+ hostres = NULL; -+ if ((ret = ldap_search_ext_s (ld, ldap_base_dn, LDAP_SCOPE_SUBTREE, -+ hfilter, NULL, 0, NULL, NULL, NULL, 0, -+ &hostres)) != LDAP_SUCCESS) -+ { -+ log_error ("Cannot find host LDAP entry %s %s", -+ ((ldap_dhcp_server_cn == NULL)?(unme.nodename):(ldap_dhcp_server_cn)), hfilter); -+ if(NULL != hostres) -+ ldap_msgfree (hostres); -+ ldap_stop(); -+ return (ISC_R_FAILURE); -+ } -+ -+ if ((hostent = ldap_first_entry (ld, hostres)) == NULL) -+ { -+ log_error ("Error: Cannot find LDAP entry matching %s", hfilter); -+ ldap_msgfree (hostres); -+ ldap_stop(); -+ return (ISC_R_FAILURE); -+ } -+ -+ hostdn = ldap_get_dn (ld, hostent); -+#if defined(DEBUG_LDAP) -+ if (hostdn != NULL) -+ log_info ("Found dhcpServer LDAP entry '%s'", hostdn); -+#endif -+ -+ if (hostdn == NULL || -+ (tempbv = ldap_get_values_len (ld, hostent, "dhcpServiceDN")) == NULL || -+ tempbv[0] == NULL) -+ { -+ log_error ("Error: Cannot find LDAP entry matching %s", hfilter); -+ -+ if (tempbv != NULL) -+ ldap_value_free_len (tempbv); -+ -+ if (hostdn) -+ ldap_memfree (hostdn); -+ ldap_msgfree (hostres); -+ ldap_stop(); -+ return (ISC_R_FAILURE); -+ } -+ -+#if defined(DEBUG_LDAP) -+ log_info ("LDAP: Parsing dhcpServer options '%s' ...", hostdn); -+#endif -+ -+ cfile->inbuf[0] = '\0'; -+ ldap_parse_entry_options(hostent, cfile->inbuf, LDAP_BUFFER_SIZE, NULL); -+ cfile->buflen = strlen (cfile->inbuf); -+ if(cfile->buflen > 0) -+ { -+ ldap_write_debug (cfile->inbuf, cfile->buflen); -+ -+ res = conf_file_subparse (cfile, root_group, ROOT_GROUP); -+ if (res != ISC_R_SUCCESS) -+ { -+ log_error ("LDAP: cannot parse dhcpServer entry '%s'", hostdn); -+ ldap_memfree (hostdn); -+ ldap_stop(); -+ return res; -+ } -+ cfile->inbuf[0] = '\0'; -+ } -+ ldap_msgfree (hostres); -+ -+ /* -+ ** attach ldap (tree) read function now -+ */ -+ cfile->bufix = cfile->buflen = 0; -+ cfile->read_function = ldap_read_function; -+ -+ res = ISC_R_SUCCESS; -+ for (cnt=0; tempbv[cnt] != NULL; cnt++) -+ { -+ snprintf(sfilter, sizeof(sfilter), "(&(objectClass=dhcpService)" -+ "(|(dhcpPrimaryDN=%s)(dhcpSecondaryDN=%s)))", -+ hostdn, hostdn); -+ ldres = NULL; -+ if ((ret = ldap_search_ext_s (ld, tempbv[cnt]->bv_val, LDAP_SCOPE_BASE, -+ sfilter, NULL, 0, NULL, NULL, NULL, -+ 0, &ldres)) != LDAP_SUCCESS) -+ { -+ log_error ("Error searching for dhcpServiceDN '%s': %s. Please update the LDAP entry '%s'", -+ tempbv[cnt]->bv_val, ldap_err2string (ret), hostdn); -+ if(NULL != ldres) -+ ldap_msgfree(ldres); -+ res = ISC_R_FAILURE; -+ break; -+ } -+ -+ if ((ent = ldap_first_entry (ld, ldres)) == NULL) -+ { -+ log_error ("Error: Cannot find dhcpService DN '%s' with primary or secondary server reference. Please update the LDAP server entry '%s'", -+ tempbv[cnt]->bv_val, hostdn); -+ -+ ldap_msgfree(ldres); -+ res = ISC_R_FAILURE; -+ break; -+ } -+ -+ /* -+ ** FIXME: how to free the remembered dn's on exit? -+ ** This should be OK if dmalloc registers the -+ ** memory it allocated and frees it on exit.. -+ */ -+ -+ curr = dmalloc (sizeof (*curr), MDL); -+ if (curr != NULL) -+ { -+ length = strlen (tempbv[cnt]->bv_val); -+ curr->dn = dmalloc (length + 1, MDL); -+ if (curr->dn == NULL) -+ { -+ dfree (curr, MDL); -+ curr = NULL; -+ } -+ else -+ strcpy (curr->dn, tempbv[cnt]->bv_val); -+ } -+ -+ if (curr != NULL) -+ { -+ curr->refs++; -+ -+ /* append to service-dn list */ -+ if (ldap_service_dn_tail != NULL) -+ ldap_service_dn_tail->next = curr; -+ else -+ ldap_service_dn_head = curr; -+ -+ ldap_service_dn_tail = curr; -+ } -+ else -+ log_fatal ("no memory to remember ldap service dn"); -+ -+#if defined (DEBUG_LDAP) -+ log_info ("LDAP: Parsing dhcpService DN '%s' ...", tempbv[cnt]); -+#endif -+ add_to_config_stack (ldres, ent); -+ res = conf_file_subparse (cfile, root_group, ROOT_GROUP); -+ if (res != ISC_R_SUCCESS) -+ { -+ log_error ("LDAP: cannot parse dhcpService entry '%s'", tempbv[cnt]->bv_val); -+ break; -+ } -+ } -+ -+ end_parse (&cfile); -+ ldap_close_debug_fd(); -+ -+ ldap_memfree (hostdn); -+ ldap_value_free_len (tempbv); -+ -+ if (res != ISC_R_SUCCESS) -+ { -+ struct ldap_config_stack *temp_stack; -+ -+ while ((curr = ldap_service_dn_head) != NULL) -+ { -+ ldap_service_dn_head = curr->next; -+ dfree (curr->dn, MDL); -+ dfree (curr, MDL); -+ } -+ -+ ldap_service_dn_tail = NULL; -+ -+ while ((temp_stack = ldap_stack) != NULL) -+ { -+ ldap_stack = temp_stack->next; -+ free_stack_entry (temp_stack); -+ } -+ -+ ldap_stop(); -+ } -+ -+ /* Unbind from ldap immediately after reading config in static mode. */ -+ if (ldap_method == LDAP_METHOD_STATIC) -+ ldap_stop(); -+ -+ 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) -+{ -+ int declaration, lease_limit; -+ char option_buffer[8192]; -+ enum dhcp_token token; -+ struct parse *cfile; -+ isc_result_t res; -+ const char *val; -+ -+ lease_limit = 0; -+ *option_buffer = '\0'; -+ -+ /* This block of code will try to find the parent of the host, and -+ if it is a group object, fetch the options and apply to the host. */ -+ if (type == HOST_DECL) -+ { -+ char *hostdn, *basedn, *temp1, *temp2, filter[1024]; -+ LDAPMessage *groupdn, *entry; -+ int ret; -+ -+ hostdn = ldap_get_dn (ld, ent); -+ if( hostdn != NULL) -+ { -+ basedn = NULL; -+ -+ temp1 = strchr (hostdn, '='); -+ if (temp1 != NULL) -+ temp1 = strchr (++temp1, '='); -+ if (temp1 != NULL) -+ temp2 = strchr (++temp1, ','); -+ else -+ temp2 = NULL; -+ -+ if (temp2 != NULL) -+ { -+ snprintf (filter, sizeof(filter), -+ "(&(cn=%.*s)(objectClass=dhcpGroup))", -+ (int)(temp2 - temp1), temp1); -+ -+ basedn = strchr (temp1, ','); -+ if (basedn != NULL) -+ ++basedn; -+ } -+ -+ if (basedn != NULL && *basedn != '\0') -+ { -+ ret = ldap_search_ext_s (ld, basedn, LDAP_SCOPE_SUBTREE, filter, -+ NULL, 0, NULL, NULL, NULL, 0, &groupdn); -+ if (ret == LDAP_SUCCESS) -+ { -+ if ((entry = ldap_first_entry (ld, groupdn)) != NULL) -+ { -+ res = ldap_parse_entry_options (entry, option_buffer, -+ sizeof(option_buffer) - 1, -+ &lease_limit); -+ if (res != ISC_R_SUCCESS) -+ { -+ /* reset option buffer discarding any results */ -+ *option_buffer = '\0'; -+ lease_limit = 0; -+ } -+ } -+ ldap_msgfree( groupdn); -+ } -+ } -+ ldap_memfree( hostdn); -+ } -+ } -+ -+ res = ldap_parse_entry_options (ent, option_buffer, sizeof(option_buffer) - 1, -+ &lease_limit); -+ if (res != ISC_R_SUCCESS) -+ return (lease_limit); -+ -+ option_buffer[sizeof(option_buffer) - 1] = '\0'; -+ 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[128], *type_str; -+ LDAPMessage * res, *ent; -+ struct host_decl * host; -+ isc_result_t status; -+ ldap_dn_node *curr; -+ int ret; -+ -+ if (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); -+ } -+ -+ /* -+ ** FIXME: It is not guaranteed, that the dhcpHWAddress attribute -+ ** contains _exactly_ "type addr" with one space between! -+ */ -+ snprintf (buf, sizeof (buf), -+ "(&(objectClass=dhcpHost)(dhcpHWAddress=%s %s))", -+ type_str, print_hw_addr (htype, hlen, haddr)); -+ -+ res = ent = NULL; -+ for (curr = ldap_service_dn_head; -+ curr != NULL && *curr->dn != '\0'; -+ curr = curr->next) -+ { -+#if defined (DEBUG_LDAP) -+ log_info ("Searching for %s in LDAP tree %s", buf, curr->dn); -+#endif -+ ret = ldap_search_ext_s (ld, curr->dn, LDAP_SCOPE_SUBTREE, buf, NULL, 0, -+ NULL, NULL, NULL, 0, &res); -+ -+ if(ret == LDAP_SERVER_DOWN) -+ { -+ log_info ("LDAP server was down, trying to reconnect..."); -+ -+ ldap_stop(); -+ ldap_start(); -+ if(ld == NULL) -+ { -+ log_info ("LDAP reconnect failed - try again later..."); -+ return (0); -+ } -+ -+ ret = ldap_search_ext_s (ld, curr->dn, LDAP_SCOPE_SUBTREE, buf, NULL, -+ 0, NULL, NULL, NULL, 0, &res); -+ } -+ -+ if (ret == LDAP_SUCCESS) -+ { -+ if( (ent = ldap_first_entry (ld, res)) != NULL) -+ break; /* search OK and have entry */ -+ -+#if defined (DEBUG_LDAP) -+ log_info ("No host entry for %s in LDAP tree %s", -+ buf, curr->dn); -+#endif -+ if(res) -+ { -+ ldap_msgfree (res); -+ res = NULL; -+ } -+ } -+ else -+ { -+ if(res) -+ { -+ ldap_msgfree (res); -+ res = NULL; -+ } -+ -+ if (ret != LDAP_NO_SUCH_OBJECT && ret != LDAP_SUCCESS) -+ { -+ log_error ("Cannot search for %s in LDAP tree %s: %s", buf, -+ curr->dn, ldap_err2string (ret)); -+ ldap_stop(); -+ return (0); -+ } -+#if defined (DEBUG_LDAP) -+ else -+ { -+ log_info ("ldap_search_ext_s returned %s when searching for %s in %s", -+ ldap_err2string (ret), buf, curr->dn); -+ } -+#endif -+ } -+ } -+ -+ if (res && ent) -+ { -+#if defined (DEBUG_LDAP) -+ char *dn = ldap_get_dn (ld, ent); -+ if (dn != NULL) -+ { -+ log_info ("Found dhcpHWAddress LDAP entry %s", dn); -+ ldap_memfree(dn); -+ } -+#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)); -+ ldap_msgfree (res); -+ 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); -+ ldap_msgfree (res); -+ return (0); -+ } -+ -+ ldap_parse_options (ent, host->group, HOST_DECL, host, NULL); -+ -+ *hp = host; -+ ldap_msgfree (res); -+ return (1); -+ } -+ -+ -+ if(res) 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; -+ ldap_dn_node *curr; -+ char buf[1024]; -+ -+ if (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), (u_int8_t *) class->name, 60)); -+#if defined (DEBUG_LDAP) -+ log_info ("Searching LDAP for %s", buf); -+#endif -+ -+ res = ent = NULL; -+ for (curr = ldap_service_dn_head; -+ curr != NULL && *curr->dn != '\0'; -+ curr = curr->next) -+ { -+#if defined (DEBUG_LDAP) -+ log_info ("Searching for %s in LDAP tree %s", buf, curr->dn); -+#endif -+ ret = ldap_search_ext_s (ld, curr->dn, LDAP_SCOPE_SUBTREE, buf, NULL, 0, -+ NULL, NULL, NULL, 0, &res); -+ -+ if(ret == LDAP_SERVER_DOWN) -+ { -+ log_info ("LDAP server was down, trying to reconnect..."); -+ -+ ldap_stop(); -+ ldap_start(); -+ -+ if(ld == NULL) -+ { -+ log_info ("LDAP reconnect failed - try again later..."); -+ return (0); -+ } -+ -+ ret = ldap_search_ext_s (ld, curr->dn, LDAP_SCOPE_SUBTREE, buf, -+ NULL, 0, NULL, NULL, NULL, 0, &res); -+ } -+ -+ if (ret == LDAP_SUCCESS) -+ { -+ if( (ent = ldap_first_entry (ld, res)) != NULL) -+ break; /* search OK and have entry */ -+ -+#if defined (DEBUG_LDAP) -+ log_info ("No subclass entry for %s in LDAP tree %s", -+ buf, curr->dn); -+#endif -+ if(res) -+ { -+ ldap_msgfree (res); -+ res = NULL; -+ } -+ } -+ else -+ { -+ if(res) -+ { -+ ldap_msgfree (res); -+ res = NULL; -+ } -+ -+ if (ret != LDAP_NO_SUCH_OBJECT && ret != LDAP_SUCCESS) -+ { -+ log_error ("Cannot search for %s in LDAP tree %s: %s", buf, -+ curr->dn, ldap_err2string (ret)); -+ ldap_stop(); -+ return (0); -+ } -+#if defined (DEBUG_LDAP) -+ else -+ { -+ log_info ("ldap_search_ext_s returned %s when searching for %s in %s", -+ ldap_err2string (ret), buf, curr->dn); -+ } -+#endif -+ } -+ } -+ -+ if (res && ent) -+ { -+#if defined (DEBUG_LDAP) -+ char *dn = ldap_get_dn (ld, ent); -+ if (dn != NULL) -+ { -+ log_info ("Found subclass LDAP entry %s", dn); -+ ldap_memfree(dn); -+ } -+#endif -+ -+ status = class_allocate (newclass, MDL); -+ if (status != ISC_R_SUCCESS) -+ { -+ log_error ("Cannot allocate memory for a new class"); -+ ldap_msgfree (res); -+ 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); -+ ldap_msgfree (res); -+ 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); -+ } -+ -+ if(res) ldap_msgfree (res); -+ return (0); -+} -+ -+#endif -diff -up dhcp-4.0.0/server/confpars.c.ldap dhcp-4.0.0/server/confpars.c ---- dhcp-4.0.0/server/confpars.c.ldap 2007-11-30 11:51:43.000000000 -1000 -+++ dhcp-4.0.0/server/confpars.c 2008-01-02 11:18:44.000000000 -1000 -@@ -60,7 +60,17 @@ void parse_trace_setup () - - 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, -diff -up dhcp-4.0.0/server/class.c.ldap dhcp-4.0.0/server/class.c ---- dhcp-4.0.0/server/class.c.ldap 2007-09-05 07:32:10.000000000 -1000 -+++ dhcp-4.0.0/server/class.c 2008-01-02 11:18:44.000000000 -1000 -@@ -84,6 +84,7 @@ int check_collection (packet, lease, col - int matched = 0; - int status; - int ignorep; -+ int classfound; - - for (class = collection -> classes; class; class = class -> nic) { - #if defined (DEBUG_CLASS_MATCHING) -@@ -129,9 +130,15 @@ int check_collection (packet, lease, col - 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, -diff -up dhcp-4.0.0/server/stables.c.ldap dhcp-4.0.0/server/stables.c ---- dhcp-4.0.0/server/stables.c.ldap 2007-11-20 08:34:37.000000000 -1000 -+++ dhcp-4.0.0/server/stables.c 2008-01-02 11:18:44.000000000 -1000 -@@ -238,9 +238,107 @@ static struct option server_options[] = - { "dhcpv6-lease-file-name", "t", &server_universe, 54, 1 }, - { "dhcpv6-pid-file-name", "t", &server_universe, 55, 1 }, - { "limit-addrs-per-ia", "L", &server_universe, 56, 1 }, -+#if defined(LDAP_CONFIGURATION) -+ { "ldap-server", "t", &server_universe, 57, 1 }, -+ { "ldap-port", "d", &server_universe, 58, 1 }, -+ { "ldap-username", "t", &server_universe, 59, 1 }, -+ { "ldap-password", "t", &server_universe, 60, 1 }, -+ { "ldap-base-dn", "t", &server_universe, 61, 1 }, -+ { "ldap-method", "Nldap-methods.", &server_universe, 62, 1 }, -+ { "ldap-debug-file", "t", &server_universe, 63, 1 }, -+ { "ldap-dhcp-server-cn", "t", &server_universe, 64, 1 }, -+ { "ldap-referrals", "f", &server_universe, 65, 1 }, -+#if defined(USE_SSL) -+ { "ldap-ssl", "Nldap-ssl-usage.", &server_universe, 66, 1 }, -+ { "ldap-tls-reqcert", "Nldap-tls-reqcert.", &server_universe, 67, 1 }, -+ { "ldap-tls-ca-file", "t", &server_universe, 68, 1 }, -+ { "ldap-tls-ca-dir", "t", &server_universe, 69, 1 }, -+ { "ldap-tls-cert", "t", &server_universe, 70, 1 }, -+ { "ldap-tls-key", "t", &server_universe, 71, 1 }, -+ { "ldap-tls-crlcheck", "Nldap-tls-crlcheck.", &server_universe, 72, 1 }, -+ { "ldap-tls-ciphers", "t", &server_universe, 73, 1 }, -+ { "ldap-tls-randfile", "t", &server_universe, 74, 1 }, -+#else -+ { "unknown-66", "X", &server_universe, 66, 1 }, -+ { "unknown-67", "X", &server_universe, 67, 1 }, -+ { "unknown-68", "X", &server_universe, 68, 1 }, -+ { "unknown-69", "X", &server_universe, 69, 1 }, -+ { "unknown-70", "X", &server_universe, 70, 1 }, -+ { "unknown-71", "X", &server_universe, 71, 1 }, -+ { "unknown-72", "X", &server_universe, 72, 1 }, -+ { "unknown-73", "X", &server_universe, 73, 1 }, -+ { "unknown-74", "X", &server_universe, 74, 1 }, -+#endif -+#else -+ { "unknown-57", "X", &server_universe, 57, 1 }, -+ { "unknown-58", "X", &server_universe, 58, 1 }, -+ { "unknown-59", "X", &server_universe, 59, 1 }, -+ { "unknown-60", "X", &server_universe, 60, 1 }, -+ { "unknown-61", "X", &server_universe, 61, 1 }, -+ { "unknown-62", "X", &server_universe, 62, 1 }, -+ { "unknown-63", "X", &server_universe, 63, 1 }, -+ { "unknown-64", "X", &server_universe, 64, 1 }, -+ { "unknown-65", "X", &server_universe, 65, 1 }, -+#endif - { NULL, NULL, NULL, 0, 0 } - }; - -+#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 -+}; -+ -+#if defined(USE_SSL) -+struct enumeration_value ldap_ssl_usage_values [] = { -+ { "off", LDAP_SSL_OFF }, -+ { "on",LDAP_SSL_ON }, -+ { "ldaps", LDAP_SSL_LDAPS }, -+ { "start_tls", LDAP_SSL_TLS }, -+ { (char *) 0, 0 } -+}; -+ -+struct enumeration ldap_ssl_usage_enum = { -+ (struct enumeration *)0, -+ "ldap-ssl-usage", -+ ldap_ssl_usage_values -+}; -+ -+struct enumeration_value ldap_tls_reqcert_values [] = { -+ { "never", LDAP_OPT_X_TLS_NEVER }, -+ { "hard", LDAP_OPT_X_TLS_HARD }, -+ { "demand", LDAP_OPT_X_TLS_DEMAND}, -+ { "allow", LDAP_OPT_X_TLS_ALLOW }, -+ { "try", LDAP_OPT_X_TLS_TRY }, -+ { (char *) 0, 0 } -+}; -+struct enumeration ldap_tls_reqcert_enum = { -+ (struct enumeration *)0, -+ "ldap-tls-reqcert", -+ ldap_tls_reqcert_values -+}; -+ -+struct enumeration_value ldap_tls_crlcheck_values [] = { -+ { "none", LDAP_OPT_X_TLS_CRL_NONE}, -+ { "peer", LDAP_OPT_X_TLS_CRL_PEER}, -+ { "all", LDAP_OPT_X_TLS_CRL_ALL }, -+ { (char *) 0, 0 } -+}; -+struct enumeration ldap_tls_crlcheck_enum = { -+ (struct enumeration *)0, -+ "ldap-tls-crlcheck", -+ ldap_tls_crlcheck_values -+}; -+#endif -+#endif -+ - struct enumeration_value ddns_styles_values [] = { - { "none", 0 }, - { "ad-hoc", 1 }, -diff -up dhcp-4.0.0/dst/Makefile.am.ldap dhcp-4.0.0/dst/Makefile.am ---- dhcp-4.0.0/dst/Makefile.am.ldap 2007-05-29 06:32:10.000000000 -1000 -+++ dhcp-4.0.0/dst/Makefile.am 2008-01-02 11:19:10.000000000 -1000 -@@ -2,7 +2,12 @@ AM_CPPFLAGS = -DMINIRES_LIB -DHMAC_MD5 - - lib_LIBRARIES = libdst.a - -+noinst_LIBRARIES = libdstnomd5.a -+ - libdst_a_SOURCES = dst_support.c dst_api.c hmac_link.c md5_dgst.c \ - base64.c prandom.c - -+libdstnomd5_a_SOURCES = dst_support.c dst_api.c hmac_link.c \ -+ base64.c prandom.c -+ - EXTRA_DIST = dst_internal.h md5.h md5_locl.h -diff -up dhcp-4.0.0/common/print.c.ldap dhcp-4.0.0/common/print.c ---- dhcp-4.0.0/common/print.c.ldap 2007-10-01 04:47:35.000000000 -1000 -+++ dhcp-4.0.0/common/print.c 2008-01-02 11:18:44.000000000 -1000 -@@ -163,9 +163,9 @@ char *print_base64 (const unsigned char - } - - 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; -diff -up dhcp-4.0.0/common/conflex.c.ldap dhcp-4.0.0/common/conflex.c ---- dhcp-4.0.0/common/conflex.c.ldap 2007-10-31 09:13:33.000000000 -1000 -+++ dhcp-4.0.0/common/conflex.c 2008-01-02 11:18:44.000000000 -1000 -@@ -43,6 +43,7 @@ static enum dhcp_token read_string PROTO - 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; -@@ -76,6 +77,10 @@ isc_result_t new_parse (cfile, file, inb - tmp->file = file; - tmp->eol_token = eolp; - -+ if (file != -1) { -+ tmp -> read_function = read_function; -+ } -+ - if (inbuf != NULL) { - tmp->inbuf = inbuf; - tmp->buflen = buflen; -@@ -170,9 +175,13 @@ static int get_char (cfile) - /* My kingdom for WITH... */ - int c; - -- if (cfile->bufix == cfile->buflen) -- c = EOF; -- else { -+ if (cfile->bufix == cfile->buflen) { -+ if (cfile -> read_function) { -+ c = cfile -> read_function (cfile); -+ } else { -+ c = EOF; -+ } -+ } else { - c = cfile->inbuf [cfile->bufix]; - cfile->bufix++; - } -@@ -1415,3 +1424,23 @@ intern(char *atom, enum dhcp_token dfv) - } - 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; -+} -diff -up dhcp-4.0.0/includes/dhcpd.h.ldap dhcp-4.0.0/includes/dhcpd.h ---- dhcp-4.0.0/includes/dhcpd.h.ldap 2007-12-08 09:36:00.000000000 -1000 -+++ dhcp-4.0.0/includes/dhcpd.h 2008-01-02 11:18:44.000000000 -1000 -@@ -101,6 +101,11 @@ typedef time_t TIME; - #include - #include - -+#if defined(LDAP_CONFIGURATION) -+# include -+# include /* for uname() */ -+#endif -+ - #if !defined (BYTE_NAME_HASH_SIZE) - # define BYTE_NAME_HASH_SIZE 401 /* Default would be ridiculous. */ - #endif -@@ -290,6 +295,8 @@ struct parse { - size_t bufsiz; - - struct parse *saved_state; -+ -+ int (*read_function) (struct parse *); - }; - - /* Variable-length array of data. */ -@@ -421,6 +428,32 @@ struct hardware { - u_int8_t hbuf [17]; - }; - -+#if defined(LDAP_CONFIGURATION) -+# define LDAP_BUFFER_SIZE 8192 -+# define LDAP_METHOD_STATIC 0 -+# define LDAP_METHOD_DYNAMIC 1 -+#if defined (USE_SSL) -+# define LDAP_SSL_OFF 0 -+# define LDAP_SSL_ON 1 -+# define LDAP_SSL_TLS 2 -+# define LDAP_SSL_LDAPS 3 -+#endif -+ -+/* 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, -@@ -626,6 +659,29 @@ struct lease_state { - # 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 -+# define SV_LDAP_DEBUG_FILE 53 -+# define SV_LDAP_DHCP_SERVER_CN 54 -+# define SV_LDAP_REFERRALS 55 -+#if defined (USE_SSL) -+# define SV_LDAP_SSL 56 -+# define SV_LDAP_TLS_REQCERT 57 -+# define SV_LDAP_TLS_CA_FILE 58 -+# define SV_LDAP_TLS_CA_DIR 59 -+# define SV_LDAP_TLS_CERT 60 -+# define SV_LDAP_TLS_KEY 61 -+# define SV_LDAP_TLS_CRLCHECK 62 -+# define SV_LDAP_TLS_CIPHERS 63 -+# define SV_LDAP_TLS_RANDFILE 64 -+#endif -+#endif -+ - #if !defined (DEFAULT_DEFAULT_LEASE_TIME) - # define DEFAULT_DEFAULT_LEASE_TIME 43200 - #endif -@@ -2035,7 +2091,7 @@ extern int db_time_format; - 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 *, -@@ -3158,6 +3214,20 @@ OMAPI_OBJECT_ALLOC_DECL (dhcp_failover_l - - const char *binding_state_print (enum failover_state); - -+/* ldap.c */ -+#if defined(LDAP_CONFIGURATION) -+extern struct enumeration ldap_methods; -+#if defined (USE_SSL) -+extern struct enumeration ldap_ssl_usage_enum; -+extern struct enumeration ldap_tls_reqcert_enum; -+extern struct enumeration ldap_tls_crlcheck_enum; -+#endif -+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 - - /* mdb6.c */ - HASH_FUNCTIONS_DECL(ia_na, unsigned char *, struct ia_na, ia_na_hash_t); -diff -up dhcp-4.0.0/includes/site.h.ldap dhcp-4.0.0/includes/site.h ---- dhcp-4.0.0/includes/site.h.ldap 2006-07-31 12:19:51.000000000 -1000 -+++ dhcp-4.0.0/includes/site.h 2008-01-02 11:18:44.000000000 -1000 -@@ -183,3 +183,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 this if you want to enable LDAP over a SSL connection. You will need -+ to add -lcrypto -lssl to the LIBS= line of server/Makefile */ -+ -+#define USE_SSL -diff -up /dev/null dhcp-4.0.0/includes/ldap_casa.h ---- /dev/null 2007-12-31 11:39:52.874087547 -1000 -+++ dhcp-4.0.0/includes/ldap_casa.h 2008-01-02 11:18:44.000000000 -1000 -@@ -0,0 +1,83 @@ -+/* ldap_casa.h -+ -+ Definition for CASA modules... */ -+ -+/* Copyright (c) 2004 Internet Systems Consorium, Inc. ("ISC") -+ * Copyright (c) 1995-2003 Internet Software Consortium. -+ * Copyright (c) 2006 Novell, 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 ISC, ISC DHCP, 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 INTERNET SYSTEMS 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 ISC 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 file was written by S Kalyanasundaram -+ */ -+ -+#if defined(LDAP_CASA_AUTH) -+#ifndef __LDAP_CASA_H__ -+#define __LDAP_CASA_H__ -+ -+#include -+#include -+#include -+ -+#define MICASA_LIB "libmicasa.so.1" -+ -+SSCS_TYPEDEF_LIBCALL(int, CASA_GetCredential_T) -+( -+ uint32_t ssFlags, -+ SSCS_SECRET_ID_T *appSecretID, -+ SSCS_SECRET_ID_T *sharedSecretID, -+ uint32_t *credentialType, -+ void *credential, -+ SSCS_EXT_T *ext -+); -+SSCS_TYPEDEF_LIBCALL(int, CASA_SetCredential_T) -+( -+ uint32_t ssFlags, -+ SSCS_SECRET_ID_T *appSecretID, -+ SSCS_SECRET_ID_T *sharedSecretID, -+ uint32_t credentialType, -+ void *credential, -+ SSCS_EXT_T *ext -+); -+ -+SSCS_TYPEDEF_LIBCALL(int, CASA_RemoveCredential_T) -+( -+ uint32_t ssFlags, -+ SSCS_SECRET_ID_T *appSecretID, -+ SSCS_SECRET_ID_T *sharedSecretID, -+ SSCS_EXT_T *ext -+); -+static CASA_GetCredential_T p_miCASAGetCredential = NULL; -+static CASA_SetCredential_T p_miCASASetCredential = NULL; -+static CASA_RemoveCredential_T p_miCASARemoveCredential = NULL; -+static void *casaIDK = NULL; -+ -+int load_casa(void); -+static void release_casa(void); -+int load_uname_pwd_from_miCASA(char **, char **); -+ -+#endif /* __LDAP_CASA_H__ */ -+#endif /* LDAP_CASA_AUTH */ -+ diff --git a/dhcp-4.0.0-libdhcp4client.patch b/dhcp-4.0.0-libdhcp4client.patch deleted file mode 100644 index 730cd62..0000000 --- a/dhcp-4.0.0-libdhcp4client.patch +++ /dev/null @@ -1,1204 +0,0 @@ -diff -up dhcp-4.0.0/configure.ac.libdhcp4client dhcp-4.0.0/configure.ac ---- dhcp-4.0.0/configure.ac.libdhcp4client 2007-12-14 08:24:56.000000000 -1000 -+++ dhcp-4.0.0/configure.ac 2008-01-02 18:27:51.000000000 -1000 -@@ -20,9 +20,37 @@ if test "$GCC" = "yes"; then - fi - fi - --AC_PROG_RANLIB -+AC_PROG_LIBTOOL -+ - AC_CONFIG_HEADERS([includes/config.h]) - -+dnl Versioning -+dnl (from glib's configure.in ...) -+dnl Making releases: -+dnl DHCP_MICRO_VERSION += 1; -+dnl DHCP_INTERFACE_AGE += 1; -+dnl DHCP_BINARY_AGE += 1; -+dnl if any functions have been added, set DHCP_INTERFACE_AGE to 0. -+dnl if backwards compatibility has been broken (e.g., functions removed, -+dnl function signatures changed), -+dnl set DHCP_BINARY_AGE and DHCP_INTERFACE_AGE to 0. -+DHCP_MAJOR_VERSION=4 -+DHCP_MINOR_VERSION=0 -+DHCP_MICRO_VERSION=0 -+DHCP_INTERFACE_AGE=0 -+DHCP_BINARY_AGE=0 -+DHCP_VERSION_SUFFIX= -+DHCP_VERSION=$DHCP_MAJOR_VERSION.$DHCP_MINOR_VERSION.$DHCP_MICRO_VERSION$DHCP_VERSION_SUFFIX -+ -+LT_RELEASE=$DHCP_MAJOR_VERSION.$DHCP_MINOR_VERSION -+LT_CURRENT=`expr $DHCP_MICRO_VERSION - $DHCP_INTERFACE_AGE` -+LT_REVISION=$DHCP_INTERFACE_AGE -+AC_SUBST(DHCP_VERSION) -+AC_SUBST(LT_RELEASE) -+AC_SUBST(LT_CURRENT) -+AC_SUBST(LT_REVISION) -+AC_SUBST(LT_AGE) -+ - # we sometimes need to know byte order for building packets - AC_C_BIGENDIAN(AC_SUBST(byte_order, BIG_ENDIAN), - AC_SUBST(byte_order, LITTLE_ENDIAN)) -diff -up dhcp-4.0.0/omapip/Makefile.am.libdhcp4client dhcp-4.0.0/omapip/Makefile.am ---- dhcp-4.0.0/omapip/Makefile.am.libdhcp4client 2007-05-29 06:32:11.000000000 -1000 -+++ dhcp-4.0.0/omapip/Makefile.am 2008-01-02 19:05:36.000000000 -1000 -@@ -1,10 +1,18 @@ - lib_LIBRARIES = libomapi.a -+noinst_LIBRARIES = libomapiLIBDHCP.a - noinst_PROGRAMS = svtest - - libomapi_a_SOURCES = protocol.c buffer.c alloc.c result.c connection.c \ - errwarn.c listener.c dispatch.c generic.c support.c \ - handle.c message.c convert.c hash.c auth.c inet_addr.c \ - array.c trace.c mrtrace.c toisc.c iscprint.c -+ -+libomapiLIBDHCP_a_CFLAGS = -DLIBDHCP -+libomapiLIBDHCP_a_SOURCES = alloc.c array.c auth.c buffer.c connection.c \ -+ convert.c dispatch.c errwarn.c handle.c hash.c listener.c \ -+ mrtrace.c result.c support.c toisc.c trace.c generic.c message.c \ -+ protocol.c -+ - man_MANS = omapi.3 - EXTRA_DIST = $(man_MANS) - -diff -up dhcp-4.0.0/omapip/dispatch.c.libdhcp4client dhcp-4.0.0/omapip/dispatch.c ---- dhcp-4.0.0/omapip/dispatch.c.libdhcp4client 2007-11-30 11:51:43.000000000 -1000 -+++ dhcp-4.0.0/omapip/dispatch.c 2008-01-02 17:18:02.000000000 -1000 -@@ -37,7 +37,7 @@ - #include - #include - --static omapi_io_object_t omapi_io_states; -+omapi_io_object_t omapi_io_states; - time_t cur_time; - - OMAPI_OBJECT_ALLOC (omapi_io, -diff -up dhcp-4.0.0/omapip/errwarn.c.libdhcp4client dhcp-4.0.0/omapip/errwarn.c ---- dhcp-4.0.0/omapip/errwarn.c.libdhcp4client 2008-01-02 17:18:01.000000000 -1000 -+++ dhcp-4.0.0/omapip/errwarn.c 2008-01-02 17:18:02.000000000 -1000 -@@ -37,6 +37,11 @@ - #include - #include - -+#ifdef LIBDHCP -+#include -+extern LIBDHCP_Control *libdhcp_control; -+#endif -+ - #ifdef DEBUG - int log_perror = -1; - #else -@@ -46,7 +51,9 @@ int log_priority; - void (*log_cleanup) (void); - - #define CVT_BUF_MAX 1023 -+#ifndef LIBDHCP - static char mbuf [CVT_BUF_MAX + 1]; -+#endif - static char fbuf [CVT_BUF_MAX + 1]; - - /* Log an error message, then exit... */ -@@ -56,6 +63,16 @@ void log_fatal (const char * fmt, ... ) - va_list list; - - do_percentm (fbuf, fmt); -+ -+#ifdef LIBDHCP -+ if (libdhcp_control && (libdhcp_control->eh)) { -+ va_start (list, fmt); -+ libdhcp_control->eh(libdhcp_control, LOG_FATAL, fbuf, list); -+ va_end(list); -+ libdhcp_control->finished = 1; -+ return; -+ } -+#else - - /* %Audit% This is log output. %2004.06.17,Safe% - * If we truncate we hope the user can get a hint from the log. -@@ -89,6 +106,7 @@ void log_fatal (const char * fmt, ... ) - if (log_cleanup) - (*log_cleanup) (); - exit (1); -+#endif - } - - /* Log an error message... */ -@@ -99,6 +117,13 @@ int log_error (const char * fmt, ...) - - do_percentm (fbuf, fmt); - -+#ifdef LIBDHCP -+ if (libdhcp_control && libdhcp_control->eh) { -+ va_start (list, fmt); -+ libdhcp_control->eh(libdhcp_control, LOG_ERR, fbuf, list); -+ va_end(list); -+ } -+#else - /* %Audit% This is log output. %2004.06.17,Safe% - * If we truncate we hope the user can get a hint from the log. - */ -@@ -114,7 +139,7 @@ int log_error (const char * fmt, ...) - write (STDERR_FILENO, mbuf, strlen (mbuf)); - write (STDERR_FILENO, "\n", 1); - } -- -+#endif - return 0; - } - -@@ -126,6 +151,13 @@ int log_info (const char *fmt, ...) - - do_percentm (fbuf, fmt); - -+#ifdef LIBDHCP -+ if (libdhcp_control && libdhcp_control->eh) { -+ va_start (list, fmt); -+ libdhcp_control->eh(libdhcp_control, LOG_INFO, fbuf, list); -+ va_end(list); -+ } -+#else - /* %Audit% This is log output. %2004.06.17,Safe% - * If we truncate we hope the user can get a hint from the log. - */ -@@ -141,7 +173,7 @@ int log_info (const char *fmt, ...) - write (STDERR_FILENO, mbuf, strlen (mbuf)); - write (STDERR_FILENO, "\n", 1); - } -- -+#endif - return 0; - } - -@@ -152,7 +184,13 @@ int log_debug (const char *fmt, ...) - va_list list; - - do_percentm (fbuf, fmt); -- -+#ifdef LIBDHCP -+ if (libdhcp_control && libdhcp_control->eh) { -+ va_start (list, fmt); -+ libdhcp_control->eh(libdhcp_control, LOG_DEBUG, fbuf, list); -+ va_end(list); -+ } -+#else - /* %Audit% This is log output. %2004.06.17,Safe% - * If we truncate we hope the user can get a hint from the log. - */ -@@ -168,7 +206,7 @@ int log_debug (const char *fmt, ...) - write (STDERR_FILENO, mbuf, strlen (mbuf)); - write (STDERR_FILENO, "\n", 1); - } -- -+#endif - return 0; - } - -diff -up dhcp-4.0.0/omapip/alloc.c.libdhcp4client dhcp-4.0.0/omapip/alloc.c ---- dhcp-4.0.0/omapip/alloc.c.libdhcp4client 2007-07-12 20:43:42.000000000 -1000 -+++ dhcp-4.0.0/omapip/alloc.c 2008-01-02 17:18:02.000000000 -1000 -@@ -37,6 +37,33 @@ - - #include - -+#ifdef LIBDHCP -+/* OK, we need a quick and dirty way of freeing all memory used by libdhcp. -+ All pointers will be stored in a glibc tree on alloc, and removed on free. -+ This is not too expensive for light single-call library use. -+*/ -+#include -+extern void tdestroy (void *root, void (*free_node)(void *nodep)); -+static void *all_pointers=0L; -+static int ptr_comparator(const void *p1, const void *p2) { -+ return ((p1 == p2) ? 0 : ((p1 > p2) ? 1 : -1)); -+} -+ -+static void record_pointer(void *ptr) { -+ tsearch(ptr, &(all_pointers), ptr_comparator); -+} -+ -+static void forget_pointer(void *ptr) { -+ tdelete(ptr, &(all_pointers), ptr_comparator); -+} -+ -+void omapi_free_all_pointers(void) { -+ if (all_pointers != NULL) -+ tdestroy(all_pointers, free); -+ all_pointers = NULL; -+} -+#endif -+ - #if defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL) || \ - defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT) - struct dmalloc_preamble *dmalloc_list; -@@ -72,7 +99,9 @@ dmalloc(unsigned size, const char *file, - return NULL; - - foo = malloc(len); -- -+#ifdef LIBDHCP -+ record_pointer(foo); -+#endif - if (!foo) - return NULL; - bar = (void *)(foo + DMDOFFSET); -@@ -191,6 +220,9 @@ dfree(void *ptr, const char *file, int l - 0, (unsigned char *)ptr + DMDOFFSET, 0, 1, RC_MALLOC); - #endif - free (ptr); -+#ifdef LIBDHCP -+ forget_pointer(ptr); -+#endif - } - - #if defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL) || \ -diff -up dhcp-4.0.0/dst/Makefile.am.libdhcp4client dhcp-4.0.0/dst/Makefile.am ---- dhcp-4.0.0/dst/Makefile.am.libdhcp4client 2008-01-02 17:18:01.000000000 -1000 -+++ dhcp-4.0.0/dst/Makefile.am 2008-01-02 17:45:26.000000000 -1000 -@@ -2,11 +2,15 @@ AM_CPPFLAGS = -DMINIRES_LIB -DHMAC_MD5 - - lib_LIBRARIES = libdst.a - --noinst_LIBRARIES = libdstnomd5.a -+noinst_LIBRARIES = libdstnomd5.a libdstLIBDHCP.a - - libdst_a_SOURCES = dst_support.c dst_api.c hmac_link.c md5_dgst.c \ - base64.c prandom.c - -+libdstLIBDHCP_a_CFLAGS = -DLIBDHCP -+libdstLIBDHCP_a_SOURCES = dst_support.c dst_api.c hmac_link.c md5_dgst.c \ -+ base64.c prandom.c -+ - libdstnomd5_a_SOURCES = dst_support.c dst_api.c hmac_link.c \ - base64.c prandom.c - -diff -up dhcp-4.0.0/dst/hmac_link.c.libdhcp4client dhcp-4.0.0/dst/hmac_link.c ---- dhcp-4.0.0/dst/hmac_link.c.libdhcp4client 2007-12-05 14:50:22.000000000 -1000 -+++ dhcp-4.0.0/dst/hmac_link.c 2008-01-02 17:18:02.000000000 -1000 -@@ -39,6 +39,10 @@ static const char rcsid[] = "$Header: /p - - #include "dst_internal.h" - -+#ifdef LIBDHCP -+extern void* dmalloc(size_t,char *,int); -+#endif -+ - #ifdef USE_MD5 - # include "md5.h" - # ifndef _MD5_H_ -@@ -87,7 +91,11 @@ dst_hmac_md5_sign(const int mode, DST_KE - MD5_CTX *ctx = NULL; - - if (mode & SIG_MODE_INIT) -+#ifdef LIBDHCP -+ ctx = (MD5_CTX *) dmalloc(sizeof(*ctx),__FILE__,__LINE__); -+#else - ctx = (MD5_CTX *) malloc(sizeof(*ctx)); -+#endif - else if (context) - ctx = (MD5_CTX *) *context; - if (ctx == NULL) -@@ -154,7 +162,11 @@ dst_hmac_md5_verify(const int mode, DST_ - MD5_CTX *ctx = NULL; - - if (mode & SIG_MODE_INIT) -+#ifdef LIBDHCP -+ ctx = (MD5_CTX *) dmalloc(sizeof(*ctx),__FILE__,__LINE__); -+#else - ctx = (MD5_CTX *) malloc(sizeof(*ctx)); -+#endif - else if (context) - ctx = (MD5_CTX *) *context; - if (ctx == NULL) -@@ -218,8 +230,11 @@ dst_buffer_to_hmac_md5(DST_KEY *dkey, co - - if (dkey == NULL || key == NULL || keylen < 0) - return (-1); -- -+#ifdef LIBDHCP -+ if ((hkey = (HMAC_Key *) dmalloc(sizeof(HMAC_Key),__FILE__,__LINE__)) == NULL) -+#else - if ((hkey = (HMAC_Key *) malloc(sizeof(HMAC_Key))) == NULL) -+#endif - return (-2); - - memset(hkey->hk_ipad, 0, sizeof(hkey->hk_ipad)); -@@ -348,7 +363,11 @@ dst_hmac_md5_key_from_file_format(DST_KE - if (eol == NULL) - return (-4); - len = eol - p; -+#ifdef LIBDHCP -+ tmp = dmalloc(len + 2,__FILE__,__LINE__); -+#else - tmp = malloc(len + 2); -+#endif - memcpy(tmp, p, len); - *(tmp + len) = 0x0; - key_len = b64_pton((char *)tmp, key, HMAC_LEN+1); /* see above */ -@@ -440,8 +459,11 @@ dst_hmac_md5_generate_key(DST_KEY *key, - return(0); - - len = size > 64 ? 64 : size; -+#ifdef LIBDHCP -+ buff = dmalloc(len+8,__FILE__,__LINE__); -+#else - buff = malloc(len+8); -- -+#endif - n = dst_random(DST_RAND_SEMI, len, buff); - n += dst_random(DST_RAND_KEY, len, buff); - if (n <= len) { /* failed getting anything */ -@@ -464,7 +486,11 @@ dst_hmac_md5_init() - { - if (dst_t_func[KEY_HMAC_MD5] != NULL) - return (1); -+#ifdef LIBDHCP -+ dst_t_func[KEY_HMAC_MD5] = dmalloc(sizeof(struct dst_func),__FILE__,__LINE__); -+#else - dst_t_func[KEY_HMAC_MD5] = malloc(sizeof(struct dst_func)); -+#endif - if (dst_t_func[KEY_HMAC_MD5] == NULL) - return (0); - memset(dst_t_func[KEY_HMAC_MD5], 0, sizeof(struct dst_func)); -diff -up dhcp-4.0.0/common/Makefile.am.libdhcp4client dhcp-4.0.0/common/Makefile.am ---- dhcp-4.0.0/common/Makefile.am.libdhcp4client 2007-11-16 01:04:11.000000000 -1000 -+++ dhcp-4.0.0/common/Makefile.am 2008-01-02 17:23:13.000000000 -1000 -@@ -1,11 +1,17 @@ - AM_CPPFLAGS = -I.. -DLOCALSTATEDIR='"@localstatedir@"' - --noinst_LIBRARIES = libdhcp.a -+noinst_LIBRARIES = libdhcp.a libdhcpLIBDHCP.a - libdhcp_a_SOURCES = alloc.c bpf.c comapi.c conflex.c ctrace.c discover.c \ - dispatch.c dlpi.c dns.c ethernet.c execute.c fddi.c \ - icmp.c inet.c lpf.c memory.c nit.c options.c packet.c \ - parse.c print.c raw.c resolv.c socket.c tables.c tr.c \ - tree.c upf.c heap.c -+libdhcpLIBDHCP_a_CFLAGS = -DLIBDHCP -+libdhcpLIBDHCP_a_SOURCES = alloc.c bpf.c comapi.c conflex.c ctrace.c \ -+ discover.c dispatch.c dlpi.c dns.c ethernet.c \ -+ execute.c inet.c lpf.c memory.c nit.c options.c \ -+ packet.c parse.c print.c socket.c tables.c tr.c \ -+ tree.c upf.c - man_MANS = dhcp-eval.5 dhcp-options.5 - EXTRA_DIST = $(man_MANS) - -diff -up dhcp-4.0.0/common/discover.c.libdhcp4client dhcp-4.0.0/common/discover.c ---- dhcp-4.0.0/common/discover.c.libdhcp4client 2007-10-05 12:29:51.000000000 -1000 -+++ dhcp-4.0.0/common/discover.c 2008-01-02 17:18:02.000000000 -1000 -@@ -883,6 +883,10 @@ add_ipv6_addr_to_interface(struct interf - register that interface with the network I/O software, figure out what - subnet it's on, and add it to the list of interfaces. */ - -+#ifdef LIBDHCP -+int have_setup_fallback = 0; -+#endif -+ - void - discover_interfaces(int state) { - struct iface_conf_list ifaces; -@@ -902,7 +906,9 @@ discover_interfaces(int state) { - isc_result_t status; - int wifcount = 0; - -+#ifndef LIBDHCP - static int setup_fallback = 0; -+#endif - - if (!begin_iface_scan(&ifaces)) { - log_fatal("Can't get list of interfaces."); -@@ -1242,10 +1248,17 @@ discover_interfaces(int state) { - log_fatal ("Not configured to listen on any interfaces!"); - } - -+#ifdef LIBDHCP -+ if ((local_family == AF_INET) && !have_setup_fallback) { -+ have_setup_fallback = 1; -+ maybe_setup_fallback (); -+ } -+#else - if ((local_family == AF_INET) && !setup_fallback) { - setup_fallback = 1; - maybe_setup_fallback(); - } -+#endif - - #if defined (F_SETFD) - if (fallback_interface) { -diff -up dhcp-4.0.0/common/tree.c.libdhcp4client dhcp-4.0.0/common/tree.c ---- dhcp-4.0.0/common/tree.c.libdhcp4client 2007-08-22 03:41:37.000000000 -1000 -+++ dhcp-4.0.0/common/tree.c 2008-01-02 17:18:02.000000000 -1000 -@@ -41,7 +41,7 @@ - # include - #endif - --struct binding_scope *global_scope; -+struct binding_scope __attribute__ ((visibility ("default"))) *global_scope; - - static int do_host_lookup PROTO ((struct data_string *, - struct dns_host_entry *)); -@@ -2859,6 +2859,7 @@ int evaluate_numeric_expression (result, - result of that evaluation. There should never be both an expression - and a valid data_string. */ - -+__attribute__ ((visibility ("default"))) - int evaluate_option_cache (result, packet, lease, client_state, - in_options, cfg_options, scope, oc, file, line) - struct data_string *result; -diff -up dhcp-4.0.0/common/options.c.libdhcp4client dhcp-4.0.0/common/options.c ---- dhcp-4.0.0/common/options.c.libdhcp4client 2007-11-30 11:51:43.000000000 -1000 -+++ dhcp-4.0.0/common/options.c 2008-01-02 17:18:02.000000000 -1000 -@@ -3392,6 +3392,7 @@ fqdn6_universe_decode(struct option_stat - return 0; - } - -+__attribute__ ((visibility ("default"))) - void option_space_foreach (struct packet *packet, struct lease *lease, - struct client_state *client_state, - struct option_state *in_options, -diff -up dhcp-4.0.0/common/dispatch.c.libdhcp4client dhcp-4.0.0/common/dispatch.c ---- dhcp-4.0.0/common/dispatch.c.libdhcp4client 2008-01-02 17:18:02.000000000 -1000 -+++ dhcp-4.0.0/common/dispatch.c 2008-01-02 17:18:02.000000000 -1000 -@@ -34,8 +34,24 @@ - - #include "dhcpd.h" - --struct timeout *timeouts; --static struct timeout *free_timeouts; -+struct timeout { -+#ifndef LIBDHCP -+ struct timeout *next; -+#endif -+ TIME when; -+ void (*func) PROTO ((void *)); -+ void *what; -+ tvref_t ref; -+ tvunref_t unref; -+}; -+ -+#ifdef LIBDHCP -+static struct timeout *timeouts = NULL; -+static int ntimeouts = 0; -+#else -+static struct timeout *timeouts = NULL; -+static struct timeout *free_timeouts = NULL; -+#endif - - void set_time(TIME t) - { -@@ -48,9 +64,41 @@ void set_time(TIME t) - - struct timeval *process_outstanding_timeouts (struct timeval *tvp) - { -+#ifdef LIBDHCP -+ int i; -+ struct timeout t = { 0 }; -+#endif - /* Call any expired timeouts, and then if there's - still a timeout registered, time out the select - call then. */ -+#ifdef LIBDHCP -+ if (!ntimeouts) -+ return NULL; -+ -+ for (i = 0; i < ntimeouts && timeouts[i].when <= cur_time;) { -+ struct timeout *new_timeouts; -+ size_t n; -+ -+ memmove(&t, &timeouts[i], sizeof (t)); -+ -+ n = (ntimeouts - i - 1) * sizeof (t); -+ memmove(&timeouts[i+1], &timeouts[i], n); -+ -+ n = --ntimeouts * sizeof (t); -+ new_timeouts = realloc(timeouts, n); -+ /* XXX broken API, no way to return error here */ -+ if (new_timeouts || !n) -+ timeouts = new_timeouts; -+ -+ if (t.func) -+ t.func(t.what); -+ if (t.unref) -+ t.unref(t.what, MDL); -+ } -+ if (tvp && ntimeouts) { -+ tvp->tv_sec = timeouts[0].when; -+ tvp->tv_usec = 0; -+#else - another: - if (timeouts) { - struct timeout *t; -@@ -68,9 +116,15 @@ struct timeval *process_outstanding_time - tvp -> tv_sec = timeouts -> when; - tvp -> tv_usec = 0; - } -+#endif - return tvp; -+#ifdef LIBDHCP -+ } -+ return NULL; -+#else - } else - return (struct timeval *)0; -+#endif - } - - /* Wait for packets to come in using select(). When one does, call -@@ -99,13 +153,28 @@ void add_timeout (when, where, what, ref - tvref_t ref; - tvunref_t unref; - { -+#ifdef LIBDHCP -+ struct timeout t = { -+ .when = when, -+ .func = where, -+ .what = what, -+ .ref = ref, -+ .unref = unref -+ }; -+ struct timeout *new_timeouts; -+ int i, pos = 0; -+#else - struct timeout *t, *q; -+#endif - - /* See if this timeout supersedes an existing timeout. */ -+#ifdef LIBDHCP -+ for (i = 0; i < ntimeouts; i++) { -+ struct timeout *q = &timeouts[i]; -+#else - t = (struct timeout *)0; - for (q = timeouts; q; q = q -> next) { -- if ((where == NULL || q -> func == where) && -- q -> what == what) { -+ if ((where == NULL || q -> func == where) && q -> what == what) { - if (t) - t -> next = q -> next; - else -@@ -114,7 +183,29 @@ void add_timeout (when, where, what, ref - } - t = q; - } -+#endif - -+#ifdef LIBDHCP -+ /* If this one is already in the list with a different time, -+ * remove it and re-add */ -+ if ((where == NULL || q->func == where) && -+ q->what == what) { -+ size_t n = (--ntimeouts - i) * sizeof (*q); -+ memmove(&t, q, sizeof (t)); -+ -+ if (n) -+ memmove(&timeouts[i], &timeouts[i+1], n); -+ -+ if (ntimeouts) { -+ new_timeouts = realloc(timeouts, ntimeouts * sizeof (*q)); -+ /* XXX broken API, no way to return error here */ -+ if (new_timeouts) -+ timeouts = new_timeouts; -+ } else { -+ timeouts = NULL; -+ } -+ add_timeout(when, where, what, ref, unref); -+#else - /* If we didn't supersede a timeout, allocate a timeout - structure now. */ - if (!q) { -@@ -123,7 +214,7 @@ void add_timeout (when, where, what, ref - free_timeouts = q -> next; - } else { - q = ((struct timeout *) -- dmalloc (sizeof (struct timeout), MDL)); -+ dmalloc (sizeof (struct timeout), MDL)); - if (!q) - log_fatal ("add_timeout: no memory!"); - } -@@ -153,22 +244,76 @@ void add_timeout (when, where, what, ref - if (t -> next -> when > q -> when) { - q -> next = t -> next; - t -> next = q; -+#endif - return; -+#ifdef LIBDHCP -+ } else if (timeouts[i].when > when) { -+ pos = i; -+#endif - } - } - -+#ifdef LIBDHCP -+ /* If we didn't supersede an existing timeout, then pos is set -+ * to the timeout which will post after this one. Insert this -+ * one before it. */ -+ -+ new_timeouts = realloc(timeouts, sizeof (t) * (ntimeouts+1)); -+ /* XXX broken API, no way to return error here */ -+ if (new_timeouts) { -+ /* ntimeouts = 10 -+ * pos = 3; -+ * n = 10-3 * sizeof (t) = 7 * sizeof (t) -+ */ -+ size_t n = (ntimeouts - pos) * sizeof (t); -+ -+ timeouts = new_timeouts; -+ memmove(&timeouts[pos+1], &timeouts[pos], n); -+ memmove(&timeouts[pos], &t, sizeof (t)); -+ ntimeouts++; -+ } -+#else - /* End of list. */ - t -> next = q; - q -> next = (struct timeout *)0; -+#endif - } - - void cancel_timeout (where, what) - void (*where) PROTO ((void *)); - void *what; - { -+#ifdef LIBDHCP -+ struct timeout t; -+ int i = 0; -+#else - struct timeout *t, *q; -+#endif - - /* Look for this timeout on the list, and unlink it if we find it. */ -+#ifdef LIBDHCP -+ for (i = 0; i < ntimeouts; i++) { -+ struct timeout *new_timeouts, *q = &timeouts[i]; -+ -+ if (q->func == where && q->what == what) { -+ size_t n; -+ -+ memmove(&t, q, sizeof (t)); -+ -+ n = (ntimeouts - i - 1) * sizeof (t); -+ memmove(&timeouts[i+1], &timeouts[i], n); -+ -+ n = --ntimeouts * sizeof (t); -+ new_timeouts = realloc(timeouts, n); -+ /* XXX broken API, no way to return error here */ -+ if (new_timeouts || !n) -+ timeouts = new_timeouts; -+ -+ if (t.unref) -+ t.unref(t.what, MDL); -+ } -+ } -+#else - t = (struct timeout *)0; - for (q = timeouts; q; q = q -> next) { - if (q -> func == where && q -> what == what) { -@@ -188,10 +333,15 @@ void cancel_timeout (where, what) - q -> next = free_timeouts; - free_timeouts = q; - } -+#endif - } - - void cancel_all_timeouts () - { -+#ifdef LIBDHCP -+ cur_time = TIME_MAX; -+ process_outstanding_timeouts(NULL); -+#else - struct timeout *t, *n; - for (t = timeouts; t; t = n) { - n = t -> next; -@@ -200,13 +350,20 @@ void cancel_all_timeouts () - t -> next = free_timeouts; - free_timeouts = t; - } -+#endif - } - -+__attribute__ ((visibility ("default"))) - void relinquish_timeouts () - { -+#ifdef LIBDHCP -+ while (ntimeouts) -+ cancel_timeout(timeouts[0].func, timeouts[0].what); -+#else - struct timeout *t, *n; - for (t = free_timeouts; t; t = n) { - n = t -> next; - dfree (t, MDL); - } -+#endif - } -diff -up dhcp-4.0.0/common/alloc.c.libdhcp4client dhcp-4.0.0/common/alloc.c ---- dhcp-4.0.0/common/alloc.c.libdhcp4client 2007-10-23 14:54:11.000000000 -1000 -+++ dhcp-4.0.0/common/alloc.c 2008-01-02 17:18:02.000000000 -1000 -@@ -1004,7 +1004,11 @@ int executable_statement_reference (ptr, - return 1; - } - -+#ifdef LIBDHCP -+struct packet *free_packets; -+#else - static struct packet *free_packets; -+#endif - - #if defined (DEBUG_MEMORY_LEAKAGE) || \ - defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT) -diff -up dhcp-4.0.0/includes/dhcpd.h.libdhcp4client dhcp-4.0.0/includes/dhcpd.h ---- dhcp-4.0.0/includes/dhcpd.h.libdhcp4client 2008-01-02 17:18:02.000000000 -1000 -+++ dhcp-4.0.0/includes/dhcpd.h 2008-01-02 17:18:02.000000000 -1000 -@@ -1199,14 +1199,6 @@ struct hardware_link { - - typedef void (*tvref_t)(void *, void *, const char *, int); - typedef void (*tvunref_t)(void *, const char *, int); --struct timeout { -- struct timeout *next; -- TIME when; -- void (*func) PROTO ((void *)); -- void *what; -- tvref_t ref; -- tvunref_t unref; --}; - - struct protocol { - struct protocol *next; -@@ -1664,7 +1656,6 @@ extern const char *path_dhcpd_pid; - - extern int dhcp_max_agent_option_packet_length; - --int main(int, char **); - void postconf_initialization(int); - void postdb_startup(void); - void cleanup PROTO ((void)); -@@ -2337,7 +2328,6 @@ extern void (*bootp_packet_handler) PROT - extern void (*dhcpv6_packet_handler)(struct interface_info *, - const char *, int, - int, const struct iaddr *, isc_boolean_t); --extern struct timeout *timeouts; - extern omapi_object_type_t *dhcp_type_interface; - #if defined (TRACING) - extern trace_type_t *interface_trace; -diff -up dhcp-4.0.0/client/Makefile.am.libdhcp4client dhcp-4.0.0/client/Makefile.am ---- dhcp-4.0.0/client/Makefile.am.libdhcp4client 2007-12-12 09:23:42.000000000 -1000 -+++ dhcp-4.0.0/client/Makefile.am 2008-01-02 19:06:30.000000000 -1000 -@@ -1,10 +1,18 @@ - dist_sysconf_DATA = dhclient.conf - sbin_PROGRAMS = dhclient -+lib_LTLIBRARIES = libdhcp4client.la - dhclient_SOURCES = clparse.c dhclient.c dhc6.c \ - scripts/bsdos scripts/freebsd scripts/linux scripts/netbsd \ - scripts/nextstep scripts/openbsd scripts/solaris - dhclient_LDADD = ../common/libdhcp.a ../minires/libres.a \ - ../omapip/libomapi.a ../dst/libdst.a -+libdhcp4client_la_CFLAGS = -DLIBDHCP -DLOCALSTATEDIR='"@localstatedir@"' -+libdhcp4client_la_LDFLAGS = -version-info \ -+ $(LT_CURRENT):$(LT_REVISION):$(LT_AGE) \ -+ -release $(LT_RELEASE) -+libdhcp4client_la_SOURCES = clparse.c dhclient.c -+libdhcp4client_la_LIBADD = ../common/libdhcpLIBDHCP.a ../dst/libdstLIBDHCP.a \ -+ ../omapip/libomapiLIBDHCP.a ../minires/libres.a - man_MANS = dhclient.8 dhclient-script.8 dhclient.conf.5 dhclient.leases.5 - EXTRA_DIST = $(man_MANS) - -diff -up dhcp-4.0.0/client/dhclient.c.libdhcp4client dhcp-4.0.0/client/dhclient.c ---- dhcp-4.0.0/client/dhclient.c.libdhcp4client 2008-01-02 17:18:02.000000000 -1000 -+++ dhcp-4.0.0/client/dhclient.c 2008-01-02 19:02:04.000000000 -1000 -@@ -83,14 +83,50 @@ int nowait=0; - char *mockup_relay = NULL; - int bootp_broadcast_always = 0; - -+#ifdef LIBDHCP -+FILE *leaseFile = NULL; -+#endif -+ - extern u_int32_t default_requested_options[]; - - static void usage PROTO ((void)); - - static isc_result_t write_duid(struct data_string *duid); - --int --main(int argc, char **argv) { -+#ifdef LIBDHCP -+#include "isc-dhcp/libdhcp_control.h" -+LIBDHCP_Control *libdhcp_control; -+static void libdhcp_dispatch(void) -+{ -+ struct timeval tv = { 0, 0 }, *tvp; -+ isc_result_t status; -+ -+ /* Wait for a packet, or a timeout, or libdhcp being finished */ -+ do { -+ tvp = process_outstanding_timeouts(&tv); -+ status = omapi_one_dispatch(0, tvp); -+ -+ if (libdhcp_control && ((status == ISC_R_TIMEDOUT) || (libdhcp_control->timeout && (time(NULL) >= (libdhcp_control->timeout + libdhcp_control->now))))) { -+ if (libdhcp_control->callback) -+ libdhcp_control->callback(libdhcp_control, DHC_TIMEDOUT, NULL); -+ -+ break; -+ } -+ } while ((status != ISC_R_TIMEDOUT) && ((!libdhcp_control) || (!(libdhcp_control->finished)))); -+} -+ -+extern void omapi_free_all_pointers(void); -+ -+__attribute__ ((visibility ("default"))) -+int dhcpv4_client (LIBDHCP_Control *libdhcp_ctl, int argc, char **argv, -+ char **envp) -+#else -+int main(int argc, char **argv, char **envp) -+#endif -+{ -+#ifdef LIBDHCP -+ libdhcp_control = libdhcp_ctl; -+#endif - int fd; - int i; - struct interface_info *ip; -@@ -122,6 +158,7 @@ main(int argc, char **argv) { - /* Initialize client globals. */ - memset(&default_duid, 0, sizeof(default_duid)); - -+#ifndef LIBDHCP - /* Make sure that file descriptors 0 (stdin), 1, (stdout), and - 2 (stderr) are open. To do this, we assume that when we - open a file the lowest available file descriptor is used. */ -@@ -140,6 +177,7 @@ main(int argc, char **argv) { - #if !(defined (DEBUG) || defined (__CYGWIN32__)) - setlogmask (LOG_UPTO (LOG_INFO)); - #endif -+#endif - - /* Set up the OMAPI. */ - status = omapi_init (); -@@ -485,8 +523,12 @@ main(int argc, char **argv) { - } - } - -+#ifdef LIBDHCP -+ if (libdhcp_control && (libdhcp_control->capability & DHCP_USE_PID_FILE)) -+#endif - write_client_pid_file(); - -+#ifndef LIBDHCP - if (!quiet) { - log_info ("%s %s", message, PACKAGE_VERSION); - log_info (copyright); -@@ -497,6 +539,7 @@ main(int argc, char **argv) { - log_perror = 0; - quiet_interface_discovery = 1; - } -+#endif - - /* If we're given a relay agent address to insert, for testing - purposes, figure out what it is. */ -@@ -702,11 +745,17 @@ main(int argc, char **argv) { - arg_conf_len = 0; - } - -+#ifdef LIBDHCP -+ if (libdhcp_control && (libdhcp_control->capability & DHCP_USE_LEASE_DATABASE)) { -+#endif - /* Parse the lease database. */ - read_client_leases (); - - /* Rewrite the lease database... */ - rewrite_client_leases (); -+#ifdef LIBDHCP -+ } -+#endif - - /* XXX */ - /* config_counter(&snd_counter, &rcv_counter); */ -@@ -725,7 +774,7 @@ main(int argc, char **argv) { - if (!persist) { - /* Nothing more to do. */ - log_info ("No broadcast interfaces found - exiting."); -- exit (0); -+ return (0); - } - } else if (!release_mode && !exit_mode) { - /* Call the script with the list of interfaces. */ -@@ -863,6 +912,7 @@ main(int argc, char **argv) { - dmalloc_outstanding = 0; - #endif - -+#ifndef LIBDHCP - /* If we're not supposed to wait before getting the address, - don't. */ - if (nowait) -@@ -875,6 +925,126 @@ main(int argc, char **argv) { - - /* Start dispatching packets and timeouts... */ - dispatch (); -+#else -+ if (libdhcp_control) { -+ if (libdhcp_control->timeout) -+ libdhcp_control->now = time(NULL); -+ else -+ libdhcp_control->now = 0; -+ } -+ -+ libdhcp_dispatch(); -+ -+ /* libdhcp is finished with us. */ -+ -+ /* close all file descriptors: */ -+ for (ip = interfaces; ip; ip = ip->next) { -+ shutdown(ip->wfdesc, SHUT_RDWR); -+ close(ip->wfdesc); -+ -+ if (ip->rfdesc != ip->wfdesc) -+ close(ip->rfdesc); -+ } -+ -+ if (fallback_interface != 0) { -+ ip = fallback_interface; -+ shutdown(ip->wfdesc, SHUT_RDWR); -+ close(ip->wfdesc); -+ -+ if (ip->rfdesc != ip->wfdesc) -+ close(ip->rfdesc); -+ } -+ -+ if (leaseFile) -+ fclose (leaseFile); -+ -+ closelog(); -+ -+ char *current_pid_file = _PATH_DHCLIENT_PID; -+ -+ /* Free ALL allocated memory: */ -+ omapi_free_all_pointers(); -+ -+ /* Re-Initialize globals: */ -+ client_env = 0; -+ client_env_count = 0; -+ default_lease_time = 43200; -+ -+ dhcp_max_agent_option_packet_length = 0; -+ iaddr_any.len = 4; -+ memset(&(iaddr_any.iabuf[0]), '\0', 4); -+ iaddr_broadcast.len = 4; -+ memset(&(iaddr_broadcast.iabuf[0]), 0xff, 4); -+ interfaces_requested = 0; -+ leaseFile = 0; -+ -+ libdhcp_control = 0; -+ -+ local_port = 0; -+ no_daemon = 0; -+ nowait = 0; -+ onetry = 0; -+ quiet = 0; -+ max_lease_time = 86400; -+ path_dhclient_conf = _PATH_DHCLIENT_CONF; -+ path_dhclient_db = _PATH_DHCLIENT_DB; -+ path_dhclient_pid = _PATH_DHCLIENT_PID; -+ strcpy(&(path_dhclient_script_array[0]), _PATH_DHCLIENT_SCRIPT); -+ path_dhclient_script = path_dhclient_script_array; -+ remote_port = 0; -+ resolver_inited = 0; -+ log_perror = 1; -+ global_scope = NULL; -+ root_group = NULL; -+ group_name_hash = NULL; -+ interfaces = NULL; -+ dummy_interfaces = NULL; -+ fallback_interface = NULL; -+ extern int have_setup_fallback; -+ have_setup_fallback = 0; -+ quiet_interface_discovery = 1; -+#ifndef LIBDHCP -+ timeouts = NULL; -+#endif -+ dhcp_type_interface = NULL; -+ interface_vector = NULL; -+ interface_count = 0; -+ interface_max = 0; -+ name_servers = 0; -+ domains = 0; -+ dhcp_type_interface = NULL; -+ dhcp_type_group = NULL; -+ dhcp_type_shared_network = NULL; -+ dhcp_type_control = NULL; -+ memset(&dhcp_universe, '\0', sizeof(struct universe)); -+ memset(&nwip_universe, '\0', sizeof(struct universe)); -+ memset(&fqdn_universe, '\0', sizeof(struct universe)); -+ universe_hash = 0; -+ universes = 0; -+ universe_count = 0; -+ universe_max = 0; -+ config_universe = 0; -+ extern struct hash_bucket *free_hash_buckets; -+ free_hash_buckets = NULL; -+ extern struct dhcp_packet *dhcp_free_list; -+ dhcp_free_list = NULL; -+ extern struct packet *packet_free_list; -+ packet_free_list = NULL; -+ extern struct binding_value *free_binding_values; -+ free_binding_values = NULL; -+ extern struct expression *free_expressions; -+ free_expressions = NULL; -+ extern struct option_cache *free_option_caches; -+ free_option_caches = NULL; -+ extern struct packet *free_packets; -+ free_packets = NULL; -+ extern pair free_pairs; -+ free_pairs = NULL; -+ extern omapi_io_object_t omapi_io_states; -+ memset(&omapi_io_states, '\0', sizeof(omapi_io_states)); -+ dhcp_control_object = NULL; -+ unlink(current_pid_file); -+#endif - - /*NOTREACHED*/ - return 0; -@@ -1270,7 +1440,20 @@ void dhcpack (packet) - if (client -> new -> rebind < cur_time) - client -> new -> rebind = TIME_MAX; - -+#ifdef LIBDHCP -+ /* We need the server's siaddr for the 'bootServer' -+ * pump option -+ */ -+ u_int32_t set_siaddr = 0; -+ set_siaddr = client->packet.siaddr.s_addr; -+ client->packet.siaddr.s_addr = packet->raw->siaddr.s_addr; -+#endif -+ - bind_lease (client); -+ -+#ifdef LIBDHCP -+ client->packet.siaddr.s_addr = set_siaddr; -+#endif - } - - void bind_lease (client) -@@ -1306,6 +1489,9 @@ void bind_lease (client) - return; - } - -+#ifdef LIBDHCP -+ if (libdhcp_control && (libdhcp_control->capability & DHCP_USE_LEASE_DATABASE)) -+#endif - /* Write out the new lease. */ - write_client_lease (client, client -> new, 0, 0); - -@@ -1398,10 +1584,12 @@ void state_stop (cpp) - } - } - -+#ifndef LIBDHCP - int commit_leases () - { - return 0; - } -+#endif - - int write_lease (lease) - struct lease *lease; -@@ -2074,6 +2262,10 @@ void state_panic (cpp) - tell the shell script that we failed to allocate an address, - and try again later. */ - if (onetry) { -+#ifdef LIBDHCP -+ script_init (client, "FAIL", (struct string_list *)0); -+ return; -+#endif - if (!quiet) - log_info ("Unable to obtain a lease on first try.%s", - " Exiting."); -@@ -2691,7 +2883,9 @@ void destroy_client_lease (lease) - free_client_lease (lease, MDL); - } - -+#ifndef LIBDHCP - FILE *leaseFile = NULL; -+#endif - int leases_written = 0; - - void rewrite_client_leases () -@@ -3218,6 +3412,54 @@ void script_write_params (client, prefix - int script_go (client) - struct client_state *client; - { -+#ifdef LIBDHCP -+ struct string_list *sp; -+ -+ if (libdhcp_control && libdhcp_control->callback) { -+ int dhcmsg; -+ char *reason=""; -+ -+ for (sp = client->env; sp; sp = sp->next) -+ if (strncmp(sp->string, "reason=", 7) == 0) { -+ reason = sp->string + 7; -+ break; -+ } -+ -+ if (strcmp(reason,"NBI") == 0) -+ dhcmsg = DHC4_NBI; -+ else if (strcmp(reason,"PREINIT") == 0) -+ dhcmsg = DHC4_PREINIT; -+ else if (strcmp(reason,"BOUND") == 0) -+ dhcmsg = DHC4_BOUND; -+ else if (strcmp(reason,"RENEW") == 0) -+ dhcmsg = DHC4_RENEW; -+ else if (strcmp(reason,"REBOOT") == 0) -+ dhcmsg = DHC4_REBOOT; -+ else if (strcmp(reason,"REBIND") == 0) -+ dhcmsg = DHC4_REBIND; -+ else if (strcmp(reason,"STOP") == 0) -+ dhcmsg = DHC4_STOP; -+ else if (strcmp(reason,"MEDIUM") == 0) -+ dhcmsg = DHC4_MEDIUM; -+ else if (strcmp(reason,"TIMEOUT") == 0) -+ dhcmsg = DHC4_TIMEOUT; -+ else if (strcmp(reason,"FAIL") == 0) -+ dhcmsg = DHC4_FAIL; -+ else if (strcmp(reason,"EXPIRE") == 0) -+ dhcmsg = DHC4_EXPIRE; -+ else if (strcmp(reason,"RELEASE") == 0) -+ dhcmsg = DHC4_RELEASE; -+ else -+ dhcmsg = DHC4_NBI; -+ -+ (*libdhcp_control->callback) (libdhcp_control, dhcmsg, client); -+ -+ if (libdhcp_control->decline) -+ return 1; -+ } -+ -+ return 0; -+#else - char *scriptName; - char *argv [2]; - char **envp; -@@ -3294,6 +3536,7 @@ int script_go (client) - time(&cur_time); - return (WIFEXITED (wstatus) ? - WEXITSTATUS (wstatus) : -WTERMSIG (wstatus)); -+#endif - } - - void client_envadd (struct client_state *client, -@@ -3376,6 +3619,9 @@ void go_daemon () - - /* Don't become a daemon if the user requested otherwise. */ - if (no_daemon) { -+#ifdef LIBDHCP -+ if (libdhcp_control && (libdhcp_control->capability & DHCP_USE_PID_FILE )) -+#endif - write_client_pid_file (); - return; - } -@@ -3385,6 +3631,10 @@ void go_daemon () - return; - state = 1; - -+#ifdef LIBDHCP -+ return; -+#endif -+ - /* Stop logging to stderr... */ - log_perror = 0; - diff --git a/dhcp-4.0.0-manpages.patch b/dhcp-4.0.0-manpages.patch deleted file mode 100644 index 7779145..0000000 --- a/dhcp-4.0.0-manpages.patch +++ /dev/null @@ -1,533 +0,0 @@ -diff -up dhcp-4.0.0/server/dhcpd.conf.5.manpages dhcp-4.0.0/server/dhcpd.conf.5 ---- dhcp-4.0.0/server/dhcpd.conf.5.manpages 2007-11-20 08:34:37.000000000 -1000 -+++ dhcp-4.0.0/server/dhcpd.conf.5 2008-01-02 11:26:38.000000000 -1000 -@@ -513,6 +513,9 @@ pool { - }; - .fi - .PP -+Dynamic BOOTP leases are not compatible with failover, and, as such, -+you need to disallow BOOTP in pools that you are using failover for. -+.PP - The server currently does very little sanity checking, so if you - configure it wrong, it will just fail in odd ways. I would recommend - therefore that you either do failover or don't do failover, but don't -@@ -527,9 +530,9 @@ primary server might look like this: - failover peer "foo" { - primary; - address anthrax.rc.vix.com; -- port 519; -+ port 647; - peer address trantor.rc.vix.com; -- peer port 520; -+ peer port 847; - max-response-delay 60; - max-unacked-updates 10; - mclt 3600; -@@ -588,9 +591,7 @@ statement - .B port \fIport-number\fR\fB;\fR - .PP - The \fBport\fR statement declares the TCP port on which the server --should listen for connections from its failover peer. This statement --may not currently be omitted, because the failover protocol does not --yet have a reserved TCP port number. -+should listen for connections from its failover peer. - .RE - .PP - The -@@ -602,10 +603,8 @@ statement - .PP - The \fBpeer port\fR statement declares the TCP port to which the - server should connect to reach its failover peer for failover --messages. This statement may not be omitted because the failover --protocol does not yet have a reserved TCP port number. The port --number declared in the \fBpeer port\fR statement may be the same as --the port number declared in the \fBport\fR statement. -+messages. The port number declared in the \fBpeer port\fR statement -+may be the same as the port number declared in the \fBport\fR statement. - .RE - .PP - The -@@ -1272,7 +1271,7 @@ the zone containing PTR records - for IS - .PP - .nf - key DHCP_UPDATER { -- algorithm HMAC-MD5.SIG-ALG.REG.INT; -+ algorithm hmac-md5; - secret pRP5FapFoJ95JEL06sv4PQ==; - }; - -@@ -1295,7 +1294,7 @@ dhcpd.conf file: - .PP - .nf - key DHCP_UPDATER { -- algorithm HMAC-MD5.SIG-ALG.REG.INT; -+ algorithm hmac-md5; - secret pRP5FapFoJ95JEL06sv4PQ==; - }; - -@@ -2433,7 +2432,8 @@ statement - The \fInext-server\fR statement is used to specify the host address of - the server from which the initial boot file (specified in the - \fIfilename\fR statement) is to be loaded. \fIServer-name\fR should --be a numeric IP address or a domain name. -+be a numeric IP address or a domain name. If no \fInext-server\fR statement -+applies to a given client, the address 0.0.0.0 is used. - .RE - .PP - The -diff -up dhcp-4.0.0/common/dhcp-options.5.manpages dhcp-4.0.0/common/dhcp-options.5 ---- dhcp-4.0.0/common/dhcp-options.5.manpages 2007-09-17 07:52:01.000000000 -1000 -+++ dhcp-4.0.0/common/dhcp-options.5 2008-01-02 11:26:38.000000000 -1000 -@@ -896,6 +896,21 @@ classless IP routing - it does not inclu - classless IP routing is now the most widely deployed routing standard, - this option is virtually useless, and is not implemented by any of the - popular DHCP clients, for example the Microsoft DHCP client. -+.PP -+NOTE to @PRODUCTNAME@ dhclient users: -+.br -+dhclient-script interprets trailing 0 octets of the target as indicating -+the subnet class of the route, so for the following static-routes value: -+.br -+ option static-routes 172.0.0.0 172.16.2.254, -+.br -+ 192.168.0.0 192.168.2.254; -+.br -+dhclient-script will create routes: -+.br -+ 172/8 via 172.16.2.254 dev $interface -+.br -+ 192.168/16 via 192.168.2.254 dev $interface - .RE - .PP - .nf -diff -up dhcp-4.0.0/client/dhclient-script.8.manpages dhcp-4.0.0/client/dhclient-script.8 ---- dhcp-4.0.0/client/dhclient-script.8.manpages 2006-02-24 13:16:27.000000000 -1000 -+++ dhcp-4.0.0/client/dhclient-script.8 2008-01-02 11:26:38.000000000 -1000 -@@ -47,7 +47,7 @@ customizations are needed, they should b - exit hooks provided (see HOOKS for details). These hooks will allow the - user to override the default behaviour of the client in creating a - .B /etc/resolv.conf --file. -+file, and to handle DHCP options not handled by default. - .PP - No standard client script exists for some operating systems, even though - the actual client may work, so a pioneering user may well need to create -@@ -91,6 +91,26 @@ present. The - .B ETCDIR/dhclient-exit-hooks - script can modify the valid of exit_status to change the exit status - of dhclient-script. -+.PP -+Immediately after dhclient brings an interface UP with a new IP address, -+subnet mask, and routes, in the REBOOT/BOUND states, it will check for the -+existence of an executable -+.B ETCDIR/dhclient-up-hooks -+script, and source it if found. This script can handle DHCP options in -+the environment that are not handled by default. A per-interface. -+.B ETCDIR/dhclient-${IF}-up-hooks -+script will override the generic script and be sourced when interface -+$IF has been brought up. -+.PP -+Immediately before dhclient brings an interface DOWN, removing its IP -+address, subnet mask, and routes, in the STOP/RELEASE states, it will -+check for the existence of an executable -+.B ETCDIR/dhclient-down-hooks -+script, and source it if found. This script can handle DHCP options in -+the environment that are not handled by default. A per-interface -+.B ETCDIR/dhclient-${IF}-down-hooks -+script will override the generic script and be sourced when interface -+$IF is about to be brought down. - .SH OPERATION - When dhclient needs to invoke the client configuration script, it - defines a set of variables in the environment, and then invokes -diff -up dhcp-4.0.0/client/dhclient.conf.5.manpages dhcp-4.0.0/client/dhclient.conf.5 ---- dhcp-4.0.0/client/dhclient.conf.5.manpages 2007-08-23 06:06:08.000000000 -1000 -+++ dhcp-4.0.0/client/dhclient.conf.5 2008-01-02 11:26:38.000000000 -1000 -@@ -186,9 +186,9 @@ responding to the client send the client - options. Only the option names should be specified in the request - statement - not option parameters. By default, the DHCP server - requests the subnet-mask, broadcast-address, time-offset, routers, --domain-name, domain-name-servers and host-name options. Note that if --you enter a 'request' statement, you over-ride this default and these --options will not be requested. -+domain-name, domain-name-servers host-name, nis-domain, nis-servers, -+and ntp-servers options. Note that if you enter a 'request' statement, -+you over-ride this default and these options will not be requested. - .PP - In some cases, it may be desirable to send no parameter request list - at all. To do this, simply write the request statement but specify -@@ -626,6 +626,18 @@ database and will record the media type - Whenever the client tries to renew the lease, it will use that same - media type. The lease must expire before the client will go back to - cycling through media types. -+.PP -+ \fBbootp-broadcast-always;\fR -+.PP -+The -+.B bootp-broadcast-always -+statement instructs dhclient to always set the bootp broadcast flag in -+request packets, so that servers will always broadcast replies. -+This is equivalent to supplying the dhclient -B argument, and has -+the same effect as specifying 'always-broadcast' in the server's dhcpd.conf. -+This option is provided as an extension to enable dhclient to work -+on IBM s390 Linux guests. -+.PP - .SH SAMPLE - The following configuration file is used on a laptop running NetBSD - 1.3. The laptop has an IP alias of 192.5.5.213, and has one -diff -up dhcp-4.0.0/client/dhclient.8.manpages dhcp-4.0.0/client/dhclient.8 ---- dhcp-4.0.0/client/dhclient.8.manpages 2007-10-04 07:13:25.000000000 -1000 -+++ dhcp-4.0.0/client/dhclient.8 2008-01-02 11:26:38.000000000 -1000 -@@ -91,6 +91,33 @@ relay - .B -w - ] - [ -+.B -B -+] -+[ -+.B -I -+.I dhcp-client-identifier -+] -+[ -+.B -H -+.I host-name -+] -+[ -+.B -F -+.I fqdn.fqdn -+] -+[ -+.B -V -+.I vendor-class-identifier -+] -+[ -+.B -R -+.I request-option-list -+] -+[ -+.B -T -+.I timeout -+] -+[ - .B -v - ] - [ -@@ -118,16 +145,6 @@ important details about the network to w - the location of a default router, the location of a name server, and - so on. - .PP --If given the -4 command line argument (default), dhclient will use the --DHCPv4 protocol to obtain an IPv4 address and configuration parameters. --.PP --If given the -6 command line argument, dhclient will use the DHCPv6 --protocol to obtain whatever IPv6 addresses are available along with --configuration parameters. Information-request is not yet supported. --.PP --If given the --version command line argument, dhclient will print its --version number and exit. --.PP - On startup, dhclient reads the - .IR dhclient.conf - for configuration instructions. It then gets a list of all the -@@ -181,67 +198,183 @@ file. If interfaces are specified in t - only configure interfaces that are either specified in the - configuration file or on the command line, and will ignore all other - interfaces. --.PP --If the DHCP client should listen and transmit on a port other than the --standard (port 68), the --.B -p --flag may used. It should be followed by the udp port number that --dhclient should use. This is mostly useful for debugging purposes. --If a different port is specified for the client to listen on and --transmit on, the client will also use a different destination port - --one greater than the specified destination port. --.PP --The DHCP client normally transmits any protocol messages it sends --before acquiring an IP address to, 255.255.255.255, the IP limited --broadcast address. For debugging purposes, it may be useful to have --the server transmit these messages to some other address. This can --be specified with the --.B -s --flag, followed by the IP address or domain name of the destination. --.PP --For testing purposes, the giaddr field of all packets that the client --sends can be set using the --.B -g --flag, followed by the IP address to send. This is only useful for testing, --and should not be expected to work in any consistent or useful way. --.PP --The DHCP client will normally run in the foreground until it has --configured an interface, and then will revert to running in the --background. To run force dhclient to always run as a foreground --process, the --.B -d --flag should be specified. This is useful when running the client --under a debugger, or when running it out of inittab on System V --systems. --.PP --The dhclient daemon creates its own environment when executing the --dhclient-script to do the grunt work of interface configuration. --To define extra environment variables and their values, use the --.B -e --flag, followed by the environment variable name and value assignment, --just as one would assign a variable in a shell. Eg: --.B -e --.I IF_METRIC=1 --.PP --The client normally prints no output during its startup sequence. It --can be made to emit verbose messages displaying the startup sequence events --until it has acquired an address by supplying the --.B -v --command line argument. In either case, the client logs messages using --the --.B syslog (3) --facility. A --.B -q --command line argument is provided for backwards compatibility, but since --dhclient is quiet by default, it has no effect. --.PP --The client normally doesn't release the current lease as it is not --required by the DHCP protocol. Some cable ISPs require their clients --to notify the server if they wish to release an assigned IP address. -+.SH OPTIONS -+.TP -+.BI \-4 -+Use the DHCPv4 protocol to obtain an IPv4 address and configuration -+parameters. -+ -+.TP -+.BI \-6 -+Use the DHCPv6 protocol to obtain whatever IPv6 addresses are available -+along with configuration parameters. Information-request is not yet -+supported. -+ -+.TP -+.BI \-p\ -+The UDP port number the DHCP client should listen and transmit on. If -+unspecified, -+.B dhclient -+uses the default port 68. This option is mostly useful for debugging -+purposes. If a different port is specified for the client to listen and -+transmit on, the client will also use a different destination port - one -+greater than the specified destination port. -+ -+.TP -+.BI \-d -+Force -+.B dhclient -+to run as a foreground process. This is useful when running the client -+under a debugger, or when running it out of inittab on System V systems. -+ -+.TP -+.BI \-e\ VAR=value -+Define additional environment variables for the environment where -+dhclient-script executes. You may specify multiple -+.B \-e -+options on the command line. -+ -+.TP -+.BI \-q -+Suppress all terminal and log output except error messages. -+ -+.TP -+.BI \-1 -+Try one to get a lease. On failure, exit with code 2. -+ -+.TP -+.BI \-r -+Tell -+.B dhclient -+to release the current lease it has from the server. This is not required -+by the DHCP protocol, but some ISPs require their clients to notify the -+server if they wish to release an assigned IP address. -+ -+.TP -+.BI \-lf\ -+Path to the lease database file. If unspecified, the default -+.B DBDIR/dhclient.leases -+is used. -+ -+.TP -+.BI \-pf\ -+Path to the process ID file. If unspecified, the default -+.B RUNDIR/dhclient.pid -+is used. -+ -+.TP -+.BI \-cf\ -+Path to the client configuration file. If unspecified, the default -+.B ETCDIR/dhclient.conf -+is used. -+ -+.TP -+.BI \-sf\ -+Path to the network configuration script invoked by -+.B dhclient -+when it gets a lease. If unspecified, the default -+.B CLIENTBINDIR/dhclient-script -+is used. -+ -+.TP -+.BI \-s\ -+Specifiy the server IP address or fully qualified domain name to transmit -+DHCP protocol messages to. Normally, -+.B dhclient -+transmits these messages to 255.255.255.255 (the IP limited broadcast -+address). Overriding this is mostly useful for debugging purposes. -+ -+.TP -+.BI \-g\ -+Only for debugging. Set the giaddr field of all packets the client -+sends to the IP address specified. This should not be expected to work -+in any consistent or useful way. -+ -+.TP -+.BI \-n -+Do not configure any interfaces. Most useful combined with the -+.B -w -+option. -+ -+.TP -+.BI \-nw -+Become a daemon process immediately (nowait) rather than waiting until an IP -+address has been acquired. -+ -+.TP -+.BI \-w -+Keep running even if no network interfaces are found. The -+.B omshell -+program can be used to notify the client when a network interface has been -+added or removed so it can attempt to configure an IP address on that -+interface. -+ -+.TP -+.BI \-B -+Set the BOOTP broadcast flag in request packets so servers will always -+broadcast replies. -+ -+.TP -+.BI \-I\ -+Specify the dhcp-client-identifier option to send to the DHCP server. -+ -+.TP -+.BI \-H\ -+Specify the host-name option to send to the DHCP server. The host-name -+string only contains the client's hostname prefix, to which the server will -+append the ddns-domainname or domain-name options, if any, to derive the -+fully qualified domain name of the client. The -+.B -H -+option cannot be used with the -+.B -F -+option. -+ -+.TP -+.BI \-F\ -+Specify the fqdn.fqdn option to send to the DHCP server. This option cannot -+be used with the -+.B -H -+option. The fqdn.fqdn option must specify the complete domain name of the -+client host, which the server may use for dynamic DNS updates. -+ -+.TP -+.BI \-V\ -+Specify the vendor-class-identifier option to send to the DHCP server. -+ -+.TP -+.BI \-R\