diff --git a/0004-dhcp-4.1.1-tmpfile.patch b/0004-dhcp-4.1.1-tmpfile.patch index 8c88cc3..91cced0 100644 --- a/0004-dhcp-4.1.1-tmpfile.patch +++ b/0004-dhcp-4.1.1-tmpfile.patch @@ -1,32 +1,25 @@ -From 1638d046d2a914164e19c6244df5b4deadaf6938 Mon Sep 17 00:00:00 2001 +From 70f2683580a88180238804546dd24a6a41427282 Mon Sep 17 00:00:00 2001 From: Marius Tomaschewski Date: Thu, 18 Aug 2011 10:06:01 +0200 Subject: [PATCH] dhcp-4.1.1-tmpfile ---- - server/db.c | 17 ++++++----------- - 1 file changed, 6 insertions(+), 11 deletions(-) +Signed-off-by: Marius Tomaschewski diff --git a/server/db.c b/server/db.c -index 82f3841..c2630ea 100644 +index 5238ed8..0c642ad 100644 --- a/server/db.c +++ b/server/db.c -@@ -1088,21 +1088,16 @@ int new_lease_file () - - db_validity = lease_file_is_corrupt; - -- /* %Audit% Truncated filename causes panic. %2004.06.17,Safe% -- * This should never happen since the path is a configuration -- * variable from build-time or command-line. But if it should, -- * either by malice or ignorance, we panic, since the potential -- * for havoc is high. -- */ +@@ -1116,15 +1116,19 @@ int new_lease_file () + * either by malice or ignorance, we panic, since the potential + * for havoc is high. + */ - if (snprintf (newfname, sizeof newfname, "%s.%d", - path_dhcpd_db, (int)t) >= sizeof newfname) -- log_fatal("new_lease_file: lease file path too long"); -- ++ if (snprintf (newfname, sizeof newfname, "%s.XXXXXX", ++ path_dhcpd_db) >= sizeof newfname) + log_fatal("new_lease_file: lease file path too long"); + - db_fd = open (newfname, O_WRONLY | O_TRUNC | O_CREAT, 0664); -+ snprintf (newfname, sizeof(newfname), "%s.XXXXXX", path_dhcpd_db); + db_fd = mkstemp (newfname); if (db_fd < 0) { log_error ("Can't create new lease file: %m"); @@ -36,9 +29,9 @@ index 82f3841..c2630ea 100644 + log_error ("Can't fchmod new lease file: %m"); + goto fail; + } - if ((new_db_file = fdopen(db_fd, "w")) == NULL) { - log_error("Can't fdopen new lease file: %m"); - close(db_fd); + + #if defined (PARANOIA) + /* -- -1.8.4 +2.1.4 diff --git a/0006-dhcp-4.2.5-dhclient-send-hostname-rml.patch b/0006-dhcp-4.2.5-dhclient-send-hostname-rml.patch deleted file mode 100644 index cbedee1..0000000 --- a/0006-dhcp-4.2.5-dhclient-send-hostname-rml.patch +++ /dev/null @@ -1,122 +0,0 @@ -From 94cff63e89710f5e67944d57d76edaec968fe139 Mon Sep 17 00:00:00 2001 -From: Marius Tomaschewski -Date: Thu, 18 Aug 2011 10:49:07 +0200 -Subject: [PATCH] dhcp-4.2.5-dhclient-send-hostname-rml - ---- - client/dhclient.8 | 8 ++++++++ - client/dhclient.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++-- - 2 files changed, 56 insertions(+), 2 deletions(-) - -diff --git a/client/dhclient.8 b/client/dhclient.8 -index 0aa1119..bc34c6a 100644 ---- a/client/dhclient.8 -+++ b/client/dhclient.8 -@@ -60,6 +60,10 @@ dhclient - Dynamic Host Configuration Protocol Client - .I LL|LLT - ] - [ -+.B -H -+.I hostname -+] -+[ - .B -p - .I port-number - ] -@@ -316,6 +320,10 @@ transmits these messages to 255.255.255.255 (the IP limited broadcast - address). Overriding this is mostly useful for debugging purposes. This - feature is not supported in DHCPv6 (\fB-6\fR) mode. - .TP -+.BI \-H \ hostname -+This flag may be used to specify a client hostname that should be sent to -+the DHCP server. Note, that this option is a SUSE/Novell extension. -+.TP - .BI \-g \ relay - .\" mockup relay - Set the giaddr field of all packets to the \fIrelay\fR IP address -diff --git a/client/dhclient.c b/client/dhclient.c -index 203d3d1..b7a14fe 100644 ---- a/client/dhclient.c -+++ b/client/dhclient.c -@@ -119,6 +119,7 @@ main(int argc, char **argv) { - int no_dhclient_db = 0; - int no_dhclient_pid = 0; - int no_dhclient_script = 0; -+ char *dhclient_hostname = NULL; - #ifdef DHCPv6 - int local_family_set = 0; - #endif /* DHCPv6 */ -@@ -231,6 +232,22 @@ main(int argc, char **argv) { - if (++i == argc) - usage(); - mockup_relay = argv[i]; -+ } else if (!strcmp (argv[i], "-H")) { -+ size_t len; -+ if (++i == argc || !argv[i] || *(argv[i]) == '\0') -+ usage (); -+ len = strlen (argv[i]); -+ if (len > HOST_NAME_MAX) { -+ log_error("-H option host-name string \"%s\" is too long:" -+ "maximum length is %d characters", -+ argv[i], HOST_NAME_MAX); -+ exit(1); -+ } else if(check_domain_name(argv[i], len, 0) != 0) { -+ log_error("suspect host-name in -H \"%s\"", -+ argv[i]); -+ exit(1); -+ } -+ dhclient_hostname = argv [i]; - } else if (!strcmp(argv[i], "-nw")) { - nowait = 1; - } else if (!strcmp(argv[i], "-n")) { -@@ -491,6 +508,35 @@ main(int argc, char **argv) { - /* Parse the dhclient.conf file. */ - read_client_conf(); - -+ /* If the user specified a hostname, send it here and now */ -+ if ((dhclient_hostname != NULL) && (*dhclient_hostname != '\0') ) { -+ struct parse *cfile = NULL; -+ char buf[HOST_NAME_MAX + 40]; -+ int len; -+ -+ snprintf (buf, sizeof(buf), "send host-name \"%s\";", -+ dhclient_hostname); -+ len = strlen(buf); -+ -+ status = new_parse (&cfile, -1, buf, len, -+ "host-name option", 0); -+ if (status != ISC_R_SUCCESS) -+ log_fatal ("Cannot parse send host-name statement!"); -+ -+ for (;;) { -+ const char *val = NULL; -+ int token; -+ -+ token = peek_token (&val, (unsigned *)0, cfile); -+ if (token == END_OF_FILE) -+ break; -+ -+ parse_client_statement (cfile, NULL, -+ &top_level_config); -+ } -+ end_parse (&cfile); -+ } -+ - /* Parse the lease database. */ - read_client_leases(); - -@@ -719,9 +765,9 @@ static void usage() - - log_fatal("Usage: dhclient " - #ifdef DHCPv6 -- "[-4|-6] [-SNTP1dvrx] [-nw] [-p ] [-D LL|LLT]\n" -+ "[-4|-6] [-SNTP1dvrx] [-nw] [-H ] [-p ] [-D LL|LLT]\n" - #else /* DHCPv6 */ -- "[-1dvrx] [-nw] [-p ]\n" -+ "[-1dvrx] [-nw] [-H ] [-p ]\n" - #endif /* DHCPv6 */ - " [-s server-addr] [-cf config-file] " - "[-lf lease-file]\n" --- -1.8.4 - diff --git a/0006-dhcp-4.3.2-dhclient-send-hostname-or-fqdn.patch b/0006-dhcp-4.3.2-dhclient-send-hostname-or-fqdn.patch new file mode 100644 index 0000000..d20ae6f --- /dev/null +++ b/0006-dhcp-4.3.2-dhclient-send-hostname-or-fqdn.patch @@ -0,0 +1,131 @@ +From ec55fe43e597e5ea0f8dff5b8edef091c0911801 Mon Sep 17 00:00:00 2001 +From: Marius Tomaschewski +Date: Thu, 18 Aug 2011 10:49:07 +0200 +Subject: [PATCH] dhcp-4.3.2-dhclient-send-hostname-or-fqdn + +Signed-off-by: Marius Tomaschewski + +diff --git a/client/dhclient.8 b/client/dhclient.8 +index 5b05698..d9a26b7 100644 +--- a/client/dhclient.8 ++++ b/client/dhclient.8 +@@ -66,6 +66,10 @@ dhclient - Dynamic Host Configuration Protocol Client + .I LL|LLT + ] + [ ++.B -H ++.I hostname ++] ++[ + .B -p + .I port-number + ] +@@ -326,6 +330,11 @@ transmits these messages to 255.255.255.255 (the IP limited broadcast + address). Overriding this is mostly useful for debugging purposes. This + feature is not supported in DHCPv6 (\fB-6\fR) mode. + .TP ++.BI \-H \ hostname ++This flag may be used to specify a client hostname that should be sent to ++the DHCP server as host-name (ipv4 only) or fqdn to perform dns update. ++Note, that this option is a SUSE/Novell extension. ++.TP + .BI \-g \ relay + .\" mockup relay + Set the giaddr field of all packets to the \fIrelay\fR IP address +diff --git a/client/dhclient.c b/client/dhclient.c +index cf612d1..0e39161 100644 +--- a/client/dhclient.c ++++ b/client/dhclient.c +@@ -124,6 +124,7 @@ main(int argc, char **argv) { + int no_dhclient_db = 0; + int no_dhclient_pid = 0; + int no_dhclient_script = 0; ++ char *dhclient_hostname = NULL; + #ifdef DHCPv6 + int local_family_set = 0; + #endif /* DHCPv6 */ +@@ -241,6 +242,24 @@ main(int argc, char **argv) { + if (++i == argc) + usage(); + mockup_relay = argv[i]; ++ } else if (!strcmp (argv[i], "-H")) { ++ size_t len; ++ if (++i == argc || !argv[i] || *(argv[i]) == '\0') ++ usage (); ++ len = strlen (argv[i]); ++ if (len > HOST_NAME_MAX) { ++ log_error("-H option hostname string \"%s\" is too long:" ++ "maximum length is %d characters", ++ argv[i], HOST_NAME_MAX); ++ exit(1); ++ } else if(check_domain_name(argv[i], len, ++ local_family == AF_INET6 ? 1 : 0) != 0) { ++ log_error("suspect %s in -H option: \"%s\"", ++ local_family == AF_INET6 ? "fqdn" : "hostname", ++ argv[i]); ++ exit(1); ++ } ++ dhclient_hostname = argv [i]; + } else if (!strcmp(argv[i], "-nw")) { + nowait = 1; + } else if (!strcmp(argv[i], "-n")) { +@@ -510,6 +529,48 @@ main(int argc, char **argv) { + /* Parse the dhclient.conf file. */ + read_client_conf(); + ++ /* If the user specified a hostname, send it here and now */ ++ if ((dhclient_hostname != NULL) && (*dhclient_hostname != '\0') ) { ++ struct parse *cfile = NULL; ++ char buf[1024] = {'\0'}; ++ int len; ++ ++ if (strchr(dhclient_hostname, '.')) { ++ len = strlen(dhclient_hostname); ++ snprintf (buf, sizeof(buf), ++ "send fqdn.fqdn \"%s%s\";\n" ++ "send fqdn.encoded on;\n" ++ "send fqdn.server-update on;\n" ++ "also request %s;\n", ++ dhclient_hostname, ++ dhclient_hostname[len - 1] == '.' ? "" : ".", ++ local_family == AF_INET6 ? "dhcp6.fqdn" : "fqdn"); ++ } else if (local_family == AF_INET) { ++ snprintf (buf, sizeof(buf), ++ "send host-name \"%s\";", ++ dhclient_hostname); ++ } ++ if ((len = strlen(buf))) { ++ status = new_parse (&cfile, -1, buf, len, ++ "hostname update options", 0); ++ if (status != ISC_R_SUCCESS) ++ log_fatal ("Cannot parse send host-name statement!"); ++ ++ for (;;) { ++ const char *val = NULL; ++ int token; ++ ++ token = peek_token (&val, (unsigned *)0, cfile); ++ if (token == END_OF_FILE) ++ break; ++ ++ parse_client_statement (cfile, NULL, ++ &top_level_config); ++ } ++ end_parse (&cfile); ++ } ++ } ++ + /* Parse the lease database. */ + read_client_leases(); + +@@ -756,6 +817,7 @@ static void usage() + #else /* DHCPv6 */ + "[-I1dvrxi] [-nw] [-p ] [-D LL|LLT] \n" + #endif /* DHCPv6 */ ++ " [-H hostname]\n" + " [-s server-addr] [-cf config-file]\n" + " [-df duid-file] [-lf lease-file]\n" + " [-pf pid-file] [--no-pid] [-e VAR=val]\n" +-- +2.1.4 + diff --git a/0008-dhcp-4.1.1-P1-lpf-bind-msg-fix.patch b/0007-dhcp-4.1.1-P1-lpf-bind-msg-fix.patch similarity index 97% rename from 0008-dhcp-4.1.1-P1-lpf-bind-msg-fix.patch rename to 0007-dhcp-4.1.1-P1-lpf-bind-msg-fix.patch index caa0c34..e9a6003 100644 --- a/0008-dhcp-4.1.1-P1-lpf-bind-msg-fix.patch +++ b/0007-dhcp-4.1.1-P1-lpf-bind-msg-fix.patch @@ -2,6 +2,7 @@ From a9d31f9f8356fba3fc49ead5afdfd8cca5a4a535 Mon Sep 17 00:00:00 2001 From: Marius Tomaschewski Date: Tue, 12 Jun 2012 08:54:23 +0200 Subject: [PATCH] dhcp-4.1.1-P1-lpf-bind-msg-fix +References: bnc#617795 --- common/lpf.c | 2 +- diff --git a/0007-dhcp-4.2.6-ldap-mt01.patch b/0007-dhcp-4.2.6-ldap-mt01.patch deleted file mode 100644 index 9b35589..0000000 --- a/0007-dhcp-4.2.6-ldap-mt01.patch +++ /dev/null @@ -1,2235 +0,0 @@ -From b61fe9752fa8fe76a9c9dd04c9808e510a8dc3fe Mon Sep 17 00:00:00 2001 -From: Marius Tomaschewski -Date: Mon, 10 Feb 2014 13:59:27 +0100 -Subject: [PATCH] dhcp-4.2.6-ldap-mt01 - -A squashed commit of the following changes: - -commit f3961ac1dea087b365ae7d5b3085a4d5cfb918ac -Author: Marius Tomaschewski -Date: Mon Dec 10 09:56:00 2012 +0100 - - Fixed memory leaks in ldap read config error handling - - Fixed to free ldap results before bailing out when the - dhcpServer object or it's dhcpService references can't - be parsed / resolved. - -commit f0ab39c5a6fcca07d305f45536050ba5af91c599 -Author: Marius Tomaschewski -Date: Fri Nov 30 13:00:32 2012 +0100 - - Fixed subclass class-name and data quoting/escaping - -commit 94869d5c2087d44057954425a588712da2c012cf -Author: Marius Tomaschewski -Date: Thu Nov 29 19:02:25 2012 +0100 - - Resize ldap buffer to not truncate bigger objects - - Fixed parse buffer handling code to not avoid truncation - of config > ~8k from bigger ldap objects. Fixed to free - the ldap config buffer passed to the config parser and - append new config, while the parser is in saved state. - -commit 65bced9870ff1a63599321c021519ce6649af57c -Author: Marius Tomaschewski -Date: Thu Nov 15 14:42:21 2012 +0100 - - dhcp-ldap: reset bufix in ldap_read_function - - Fixed ldap_read_function to reset bufix variable to 0 and - to set buflen to the complete length (do not discard last - character, usually \n). - This caused a parsing error at further run of the function, - e.g. while processing the second dhcpService container that - the dhcpServer object may refer to. - -commit 9b306cdbce9666f1a87a8da9526b5b3cd45da334 -Author: Marius Tomaschewski -Date: Thu Nov 15 12:07:42 2012 +0100 - - dhcp-ldap: memleak fix in subnet range processing - -commit ac85a9311e5f466cae4de4f1c717421b14b8b679 -Author: Marius Tomaschewski -Date: Tue Jun 12 09:44:16 2012 +0200 - - Removed SV_LDAP constant redefinition - -commit c4423481cc65360d1d892fd08eebbdd3887af793 -Author: Marius Tomaschewski -Date: Tue Jan 31 17:38:25 2012 +0100 - - Fixed to escape values used in ldap filters - - Use ldap_bv2escaped_filter_value to escape all values used in - constructed ldap filters, e.g. "o=*Test" in DN (bnc#721829). - -commit d6cdf45ef8b80fc245bd0b8e5aa2962680619a91 -Author: Marius Tomaschewski -Date: Wed Apr 27 16:37:00 2011 +0200 - - ldap connect retry loop while initial startup - - Implemented optional ldap connect retry loop during the initial startup - of the dhcp server for cases where the ldap server is not yet started. - Set the ldap-init-retry option in dhcpd.conf to retry to connect - times with one second between each try (bnc#627617). - (cherry picked from commit c09a950a0f706f86a07dd575752d44d1691eb400) - -commit cc266c5e2c54da8f38d00af99ce37ac7f3701931 -Author: Marius Tomaschewski -Date: Fri Nov 26 15:16:55 2010 +0100 - - Do not link dhclient against libldap - -commit fd61b1d7b14d714ba9066f9331d02cf13b87431e -Author: Marius Tomaschewski -Date: Fri Nov 26 09:32:00 2010 +0100 - - Added --with-ldapcasa configure switch and checks - -commit 551e8f9ffc28ac1671205b33dc5c22caf377e5c5 -Author: Marius Tomaschewski -Date: Thu Oct 1 15:29:16 2009 +0200 - - Added configure check for inet_pton and inet_ntop. - -commit 46f3cc4b58872a15d519f657eb95cd5a0e3f1e00 -Author: Marius Tomaschewski -Date: Fri Nov 26 09:16:52 2010 +0100 - - Changed inclusion order in ldap_casa.c - - Include dhcpd.h first, so config.h is included first and pktinfo - type is known (_GNU_SOURCE required for socket extensions). - -commit d02fdfbc9c43b124323098d322eb157895c98350 -Author: Marius Tomaschewski -Date: Fri Nov 26 08:43:19 2010 +0100 - - Moved includes from ldap_casa.h to ldap_casa.c - -commit 2bf6db555f3accb81b42847181bd3e16ac7b627b -Author: Marius Tomaschewski -Date: Thu Nov 25 09:11:28 2010 +0100 - - Added missed includes/ldap_casa.h file - -commit 856003a7eef4bade55bdadeadeb822a4059da5fe -Author: Marius Tomaschewski -Date: Thu Oct 28 17:17:18 2010 +0200 - - Allow all local addresses for dhcpd failover - - Fixed to allow all local addresses for dhcpd failover peering by name - or address and show the name of affected failover peering in log/error - messages (bnc#597825). - -commit 915ce91842a2316e0b382e8b3771f6bcce9b5b7c -Author: Marius Tomaschewski -Date: Fri Nov 26 13:07:33 2010 +0100 - - Disabled ldap support for DHCPv6 (not implemented yet). - -commit bc287137134aa5b759aa501ebb3c37021b29d55d -Author: Marius Tomaschewski -Date: Tue Sep 29 09:25:09 2009 +0200 - - Free ldap url in ldap rebind function - - Fixes an ldap url memory leak in the dhcp ldap rebind function. - -commit 25f051c769ed435020215fb99d1ea54ba7b2786d -Author: Marius Tomaschewski -Date: Tue Sep 29 09:23:37 2009 +0200 - - Disable external dhcpZoneDN and dhcpFailOverPeerDN - - Applied S Kalyanasundaram's patch disabling incorrect parsing - of external dhcpZoneDN and dhcpFailOverPeerDN references. - -commit c34f12ab1b06f0fcd12c30601e4e83d38ff17e69 -Author: Marius Tomaschewski -Date: Thu Oct 28 16:43:21 2010 +0200 - - Meaningful error message on missed dhcpServiceDN - - Fix to provide more meaningful error message in case of missed - dhcpServiceDN attribute in a dhcpServer object (bnc#392354). - -commit 14e0ba1c80eced74ef84b72e7b840d95f53e2022 -Author: Marius Tomaschewski -Date: Mon Sep 28 23:04:08 2009 +0200 - - Support for dhcpFailOverPeer objects - - Ported support for dhcpFailOverPeer objects (failover peering - definition) by S Kalyanasundaram and Marius Tomaschewski - (fate#303198). - -commit 071b5b5fbbd0064c4c396064cd4460baf77af83e -Author: Marius Tomaschewski -Date: Thu Oct 28 15:56:11 2010 +0200 - - Case insensitive hardware address search - - Added dhcp-server compatibility workaround to search for lower- and - upper-case MAC addresses in the dhcpHWAddress LDAP attribute, for - the case, the ldap server is still using an old schema with case - sensitive match definition (bnc#343069). - -commit 683798b58a15456c0bb03b691d9db4ac706b3519 -Author: Marius Tomaschewski -Date: Mon Sep 28 23:02:31 2009 +0200 - - Missed host brace opening - - Generate proper "host ... {" block begin brace even if no harware - address is specified for the host (bnc#265337). - -commit f65005a662a47cd8126776023633f9b1c0906107 -Author: Marius Tomaschewski -Date: Mon Sep 28 23:01:21 2009 +0200 - - Fix to support dhcpServerDN reference - - Fixes to support new dhcpServerDN reference in dhcpService object - search filter (bnc#258493). - -commit e702ee4a39d401d277bb56e3162c8be6be3ad80a -Author: Marius Tomaschewski -Date: Thu Oct 28 15:45:15 2010 +0200 - - Fix for object-order related parse errors - - Fixed object order related parse errors, that occured in case a dhcp-ldap - object referencing a dhcp-tsigkey, class or failoverpeer object, was parsed - before the declaration of the referenced objects, because of the "random" - object order in ldap results (bnc#250153). - -commit 815559287fec09ae1edd49caad8e110f5ab2bbff -Author: Marius Tomaschewski -Date: Wed Nov 24 16:41:37 2010 +0100 - - Typos in access of the tempbv value in ldap debug log - - Fixed typos in access of the tempbv value in ldap debug log - messages guarded by DEBUG_LDAP. - -commit c5c400475a6d1317cc075cbfc10c420e6231f07e -Author: Marius Tomaschewski -Date: Wed Nov 24 16:23:23 2010 +0100 - - Use LDAP_CFLAGS for common/libdhcp to avoid a SEGV - - Use LDAP_CFLAGS for common/libdhcp.a compilation to avoid a segfault - when dhcp server ldap code is enabled. The parse struct allocated by - new_parse, does not contain/allocate any read_function pointer, when - LDAP_CONFIGURATION is not defined. ---- - common/Makefile.am | 1 + - common/conflex.c | 18 +- - configure.ac | 18 + - contrib/ldap/README.ldap | 6 + - includes/dhcpd.h | 24 +- - includes/ldap_casa.h | 101 ++++ - server/Makefile.am | 2 +- - server/ldap.c | 1143 +++++++++++++++++++++++++++++++++++++--------- - server/ldap_casa.c | 4 +- - server/stables.c | 1 + - 10 files changed, 1078 insertions(+), 240 deletions(-) - create mode 100644 includes/ldap_casa.h - -diff --git a/common/Makefile.am b/common/Makefile.am -index eddef05..631025c 100644 ---- a/common/Makefile.am -+++ b/common/Makefile.am -@@ -7,6 +7,7 @@ libdhcp_a_SOURCES = alloc.c bpf.c comapi.c conflex.c ctrace.c discover.c \ - icmp.c inet.c lpf.c memory.c nit.c ns_name.c options.c \ - packet.c parse.c print.c raw.c resolv.c socket.c \ - tables.c tr.c tree.c upf.c -+libdhcp_a_CFLAGS = $(LDAP_CFLAGS) - man_MANS = dhcp-eval.5 dhcp-options.5 - EXTRA_DIST = $(man_MANS) - -diff --git a/common/conflex.c b/common/conflex.c -index c39e91d..8badcf9 100644 ---- a/common/conflex.c -+++ b/common/conflex.c -@@ -147,13 +147,19 @@ save_parse_state(struct parse *cfile) { - /* - * Return the parser to the previous saved state. - * -- * You must call save_parse_state() before calling -- * restore_parse_state(), but you can call restore_parse_state() any -- * number of times after that. -+ * You must call save_parse_state() every time before calling -+ * restore_parse_state(). -+ * -+ * Note: When the read function callback is in use in ldap mode, -+ * a call to get_char() may reallocate the buffer and will append -+ * config data to the buffer until a state restore. -+ * Do not restore to the (freed) pointer and size, but use new one. - */ - isc_result_t - restore_parse_state(struct parse *cfile) { - struct parse *saved_state; -+ char *inbuf = cfile->inbuf; -+ size_t size = cfile->bufsiz; - - if (cfile->saved_state == NULL) { - return DHCP_R_NOTYET; -@@ -161,7 +167,11 @@ restore_parse_state(struct parse *cfile) { - - saved_state = cfile->saved_state; - memcpy(cfile, saved_state, sizeof(*cfile)); -- cfile->saved_state = saved_state; -+ dfree(cfile->saved_state, MDL); -+ cfile->saved_state = NULL; -+ -+ cfile->inbuf = inbuf; -+ cfile->bufsiz = size; - return ISC_R_SUCCESS; - } - -diff --git a/configure.ac b/configure.ac -index c810de8..e8d8fd1 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -618,20 +618,38 @@ AC_ARG_WITH(ldapcrypto, - [ldapcrypto=$withval], - [ldapcrypto=no]) - -+# LDAP CASA auth support. -+AC_ARG_WITH(ldapcasa, -+ AC_HELP_STRING([--with-ldapcasa], -+ [enable LDAP CASA auth support in dhcpd (default is no)]), -+ [ldapcasa=$withval], -+ [ldapcasa=no]) -+ - # OpenLDAP support is disabled by default, if enabled then SSL support is an - # extra optional that is also disabled by default. Enabling LDAP SSL support - # implies enabling LDAP support. - if test x$ldap = xyes || test x$ldapcrypto = xyes ; then -+ saved_LIBS="$LIBS" -+ LIBS="" - AC_SEARCH_LIBS(ldap_initialize, [ldap], , - AC_MSG_FAILURE([*** Cannot find ldap_initialize with -lldap - do you need to install an OpenLDAP2 Devel package?])) - AC_SEARCH_LIBS(ber_pvt_opt_on, [lber], , - AC_MSG_FAILURE([*** Cannot find ber_pvt_opt_on with -llber - do you need to install an OpenLDAP2 Devel package?])) -+ AC_SUBST(LDAP_LIBS, ["$LIBS"]) -+ LIBS="$saved_LIBS" -+ -+ AC_CHECK_FUNCS([inet_pton inet_ntop]) - - if test x$ldapcrypto = xyes ; then - AC_SUBST(LDAP_CFLAGS, ["-DLDAP_CONFIGURATION -DLDAP_USE_SSL"]) - else - AC_SUBST(LDAP_CFLAGS, ["-DLDAP_CONFIGURATION"]) - fi -+ if test x$ldapcasa = xyes ; then -+ AC_CHECK_HEADERS([micasa_mgmd.h],[ -+ LDAP_CFLAGS="$LDAP_CFLAGS -DLDAP_CASA_AUTH" -+ ], AC_MSG_FAILURE([*** Cannot find micasa_mgmd.h for ldap casa auth support])) -+ fi - fi - - # Append selected warning levels to CFLAGS before substitution (but after -diff --git a/contrib/ldap/README.ldap b/contrib/ldap/README.ldap -index c413790..63b839c 100644 ---- a/contrib/ldap/README.ldap -+++ b/contrib/ldap/README.ldap -@@ -83,6 +83,12 @@ 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 - -+The ldap-init-retry enables an optional ldap connect retry loop with -+the specified number of retries with a one second sleep between each try -+during the initial startup of the dhcp server. -+It allows to catch the condition, that the (remote) ldap server is not yet -+started at the start time of the dhcp server. -+ - 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 -diff --git a/includes/dhcpd.h b/includes/dhcpd.h -index 5830bdb..63d58e5 100644 ---- a/includes/dhcpd.h -+++ b/includes/dhcpd.h -@@ -712,6 +712,7 @@ struct lease_state { - # define SV_LDAP_TLS_CIPHERS 76 - # define SV_LDAP_TLS_RANDFILE 77 - #endif -+# define SV_LDAP_INIT_RETRY 78 - #endif - - #if !defined (DEFAULT_PING_TIMEOUT) -@@ -734,29 +735,6 @@ struct lease_state { - # define DEFAULT_MIN_ACK_DELAY_USECS 10000 /* 1/100 second */ - #endif - --#if defined(LDAP_CONFIGURATION) --# define SV_LDAP_SERVER 60 --# define SV_LDAP_PORT 61 --# define SV_LDAP_USERNAME 62 --# define SV_LDAP_PASSWORD 63 --# define SV_LDAP_BASE_DN 64 --# define SV_LDAP_METHOD 65 --# define SV_LDAP_DEBUG_FILE 66 --# define SV_LDAP_DHCP_SERVER_CN 67 --# define SV_LDAP_REFERRALS 68 --#if defined (LDAP_USE_SSL) --# define SV_LDAP_SSL 69 --# define SV_LDAP_TLS_REQCERT 70 --# define SV_LDAP_TLS_CA_FILE 71 --# define SV_LDAP_TLS_CA_DIR 72 --# define SV_LDAP_TLS_CERT 73 --# define SV_LDAP_TLS_KEY 74 --# define SV_LDAP_TLS_CRLCHECK 75 --# define SV_LDAP_TLS_CIPHERS 76 --# define SV_LDAP_TLS_RANDFILE 77 --#endif --#endif -- - #if !defined (DEFAULT_DEFAULT_LEASE_TIME) - # define DEFAULT_DEFAULT_LEASE_TIME 43200 - #endif -diff --git a/includes/ldap_casa.h b/includes/ldap_casa.h -new file mode 100644 -index 0000000..b1dad7f ---- /dev/null -+++ b/includes/ldap_casa.h -@@ -0,0 +1,101 @@ -+/* ldap_casa.h -+ -+ Definition for CASA modules... */ -+ -+/* 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 -+ */ -+/* -+ * Copyright (c) 2004-2010 by Internet Systems Consortium, Inc. ("ISC") -+ * Copyright (c) 1995-2003 by Internet Software Consortium -+ * -+ * Permission to use, copy, modify, and distribute this software for any -+ * purpose with or without fee is hereby granted, provided that the above -+ * copyright notice and this permission notice appear in all copies. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES -+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR -+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT -+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -+ * -+ * Internet Systems Consortium, Inc. -+ * 950 Charter Street -+ * Redwood City, CA 94063 -+ * -+ * https://www.isc.org/ -+ */ -+ -+#if defined(LDAP_CASA_AUTH) -+#ifndef __LDAP_CASA_H__ -+#define __LDAP_CASA_H__ -+ -+#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/server/Makefile.am b/server/Makefile.am -index dc5d4f3..c4c2417 100644 ---- a/server/Makefile.am -+++ b/server/Makefile.am -@@ -15,7 +15,7 @@ dhcpd_SOURCES = dhcpd.c dhcp.c bootp.c confpars.c db.c class.c failover.c \ - dhcpd_CFLAGS = $(LDAP_CFLAGS) - dhcpd_LDADD = ../common/libdhcp.a ../omapip/libomapi.a \ - ../dhcpctl/libdhcpctl.a ../bind/lib/libdns.a \ -- ../bind/lib/libisc.a -+ ../bind/lib/libisc.a $(LDAP_LIBS) - - man_MANS = dhcpd.8 dhcpd.conf.5 dhcpd.leases.5 - EXTRA_DIST = $(man_MANS) -diff --git a/server/ldap.c b/server/ldap.c -index 8a7d695..6e7f508 100644 ---- a/server/ldap.c -+++ b/server/ldap.c -@@ -40,6 +40,10 @@ - #include "dhcpd.h" - #include - #include -+#include -+#include -+#include -+#include - - #if defined(LDAP_CONFIGURATION) - -@@ -57,7 +61,9 @@ static char *ldap_server = NULL, - static int ldap_port = LDAP_PORT, - ldap_method = LDAP_METHOD_DYNAMIC, - ldap_referrals = -1, -- ldap_debug_fd = -1; -+ ldap_debug_fd = -1, -+ ldap_enable_retry = -1, -+ ldap_init_retry = -1; - #if defined (LDAP_USE_SSL) - static int ldap_use_ssl = -1, /* try TLS if possible */ - ldap_tls_reqcert = -1, -@@ -80,12 +86,269 @@ typedef struct ldap_dn_node { - static ldap_dn_node *ldap_service_dn_head = NULL; - static ldap_dn_node *ldap_service_dn_tail = NULL; - -+static int ldap_read_function (struct parse *cfile); -+ -+static struct parse * -+x_parser_init(const char *name) -+{ -+ struct parse *cfile; -+ isc_result_t res; -+ char *inbuf; -+ -+ inbuf = dmalloc (LDAP_BUFFER_SIZE, MDL); -+ if (inbuf == NULL) -+ return NULL; -+ -+ cfile = (struct parse *) NULL; -+ res = new_parse (&cfile, -1, inbuf, LDAP_BUFFER_SIZE, name, 0); -+ if (res != ISC_R_SUCCESS) -+ { -+ dfree(inbuf, MDL); -+ return NULL; -+ } -+ /* the buffer is still empty */ -+ cfile->bufsiz = LDAP_BUFFER_SIZE; -+ cfile->buflen = cfile->bufix = 0; -+ /* attach ldap read function */ -+ cfile->read_function = ldap_read_function; -+ return cfile; -+} -+ -+static isc_result_t -+x_parser_free(struct parse **cfile) -+{ -+ if (cfile && *cfile) -+ { -+ if ((*cfile)->inbuf) -+ dfree((*cfile)->inbuf, MDL); -+ (*cfile)->inbuf = NULL; -+ (*cfile)->bufsiz = 0; -+ return end_parse(cfile); -+ } -+ return ISC_R_SUCCESS; -+} -+ -+static int -+x_parser_resize(struct parse *cfile, size_t len) -+{ -+ size_t size; -+ char * temp; -+ -+ /* grow by len rounded up at LDAP_BUFFER_SIZE */ -+ size = cfile->bufsiz + (len | (LDAP_BUFFER_SIZE-1)) + 1; -+ -+ /* realloc would be better, but there isn't any */ -+ if ((temp = dmalloc (size, MDL)) != NULL) -+ { -+#if defined (DEBUG_LDAP) -+ log_info ("Reallocated %s buffer from %zu to %zu", -+ cfile->tlname, cfile->bufsiz, size); -+#endif -+ memcpy(temp, cfile->inbuf, cfile->bufsiz); -+ dfree(cfile->inbuf, MDL); -+ cfile->inbuf = temp; -+ cfile->bufsiz = size; -+ return 1; -+ } -+ -+ /* -+ * Hmm... what is worser, consider it as fatal error and -+ * bail out completely or discard config data in hope it -+ * is "only" an option in dynamic host lookup? -+ */ -+ log_error("Unable to reallocated %s buffer from %zu to %zu", -+ cfile->tlname, cfile->bufsiz, size); -+ return 0; -+} - - static char * --x_strncat(char *dst, const char *src, size_t dst_size) -+x_parser_strcat(struct parse *cfile, const char *str) -+{ -+ size_t cur = strlen(cfile->inbuf); -+ size_t len = strlen(str); -+ size_t cnt; -+ -+ if (cur + len >= cfile->bufsiz && !x_parser_resize(cfile, len)) -+ return NULL; -+ -+ cnt = cfile->bufsiz > cur ? cfile->bufsiz - cur - 1 : 0; -+ return strncat(cfile->inbuf, str, cnt); -+} -+ -+static inline void -+x_parser_reset(struct parse *cfile) -+{ -+ cfile->inbuf[0] = '\0'; -+ cfile->bufix = cfile->buflen = 0; -+} -+ -+static inline size_t -+x_parser_length(struct parse *cfile) -+{ -+ cfile->buflen = strlen(cfile->inbuf); -+ return cfile->buflen; -+} -+ -+static char * -+x_strxform(char *dst, const char *src, size_t dst_size, -+ int (*xform)(int)) -+{ -+ if(dst && src && dst_size) -+ { -+ size_t len, pos; -+ -+ len = strlen(src); -+ for(pos=0; pos < len && pos + 1 < dst_size; pos++) -+ dst[pos] = xform((int)src[pos]); -+ dst[pos] = '\0'; -+ -+ return dst; -+ } -+ return NULL; -+} -+ -+static int -+get_host_entry(char *fqdnname, size_t fqdnname_size, -+ char *hostaddr, size_t hostaddr_size) -+{ -+#if defined(MAXHOSTNAMELEN) -+ char hname[MAXHOSTNAMELEN+1]; -+#else -+ char hname[65]; -+#endif -+ struct hostent *hp; -+ -+ if (NULL == fqdnname || 1 >= fqdnname_size) -+ return -1; -+ -+ memset(hname, 0, sizeof(hname)); -+ if (gethostname(hname, sizeof(hname)-1)) -+ return -1; -+ -+ if (NULL == (hp = gethostbyname(hname))) -+ return -1; -+ -+ strncpy(fqdnname, hp->h_name, fqdnname_size-1); -+ fqdnname[fqdnname_size-1] = '\0'; -+ -+ if (hostaddr != NULL) -+ { -+ if (hp->h_addr != NULL) -+ { -+ struct in_addr *aptr = (struct in_addr *)hp->h_addr; -+#if defined(HAVE_INET_NTOP) -+ if (hostaddr_size >= INET_ADDRSTRLEN && -+ inet_ntop(AF_INET, aptr, hostaddr, hostaddr_size) != NULL) -+ { -+ return 0; -+ } -+#else -+ char *astr = inet_ntoa(*aptr); -+ size_t alen = strlen(astr); -+ if (astr && alen > 0 && hostaddr_size > alen) -+ { -+ strncpy(hostaddr, astr, hostaddr_size-1); -+ hostaddr[hostaddr_size-1] = '\0'; -+ return 0; -+ } -+#endif -+ } -+ return -1; -+ } -+ return 0; -+} -+ -+static int -+is_iface_address(struct ifaddrs *addrs, struct in_addr *addr) - { -- size_t len = strlen(dst); -- return strncat(dst, src, dst_size > len ? dst_size - len - 1: 0); -+ struct ifaddrs *ia; -+ struct sockaddr_in *sa; -+ int num = 0; -+ -+ if(addrs == NULL || addr == NULL) -+ return -1; -+ -+ for (ia = addrs; ia != NULL; ia = ia->ifa_next) -+ { -+ ++num; -+ if (ia->ifa_addr && (ia->ifa_flags & IFF_UP) && -+ ia->ifa_addr->sa_family == AF_INET) -+ { -+ sa = (struct sockaddr_in *)(ia->ifa_addr); -+ if (addr->s_addr == sa->sin_addr.s_addr) -+ return num; -+ } -+ } -+ return 0; -+} -+ -+static int -+get_host_address(const char *hostname, char *hostaddr, size_t hostaddr_size, struct ifaddrs *addrs) -+{ -+ if (hostname && *hostname && hostaddr && hostaddr_size) -+ { -+ struct in_addr addr; -+ -+#if defined(HAVE_INET_PTON) -+ if (inet_pton(AF_INET, hostname, &addr) == 1) -+#else -+ if (inet_aton(hostname, &addr) != 0) -+#endif -+ { -+ /* it is already IP address string */ -+ if(strlen(hostname) < hostaddr_size) -+ { -+ strncpy(hostaddr, hostname, hostaddr_size-1); -+ hostaddr[hostaddr_size-1] = '\0'; -+ -+ if (addrs != NULL && is_iface_address (addrs, &addr) > 0) -+ return 1; -+ else -+ return 0; -+ } -+ } -+ else -+ { -+ struct hostent *hp; -+ if ((hp = gethostbyname(hostname)) != NULL && hp->h_addr != NULL) -+ { -+ struct in_addr *aptr = (struct in_addr *)hp->h_addr; -+ int mret = 0; -+ -+ if (addrs != NULL) -+ { -+ char **h; -+ for (h=hp->h_addr_list; *h; h++) -+ { -+ struct in_addr *haddr = (struct in_addr *)*h; -+ if (is_iface_address (addrs, haddr) > 0) -+ { -+ aptr = haddr; -+ mret = 1; -+ } -+ } -+ } -+ -+#if defined(HAVE_INET_NTOP) -+ if (hostaddr_size >= INET_ADDRSTRLEN && -+ inet_ntop(AF_INET, aptr, hostaddr, hostaddr_size) != NULL) -+ { -+ return mret; -+ } -+#else -+ char *astr = inet_ntoa(*aptr); -+ size_t alen = strlen(astr); -+ if (astr && alen > 0 && alen < hostaddr_size) -+ { -+ strncpy(hostaddr, astr, hostaddr_size-1); -+ hostaddr[hostaddr_size-1] = '\0'; -+ return mret; -+ } -+#endif -+ } -+ } -+ } -+ return -1; - } - - static void -@@ -102,19 +365,52 @@ ldap_parse_class (struct ldap_config_stack *item, struct parse *cfile) - 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); -+ x_parser_strcat (cfile, "class \""); -+ x_parser_strcat (cfile, tempbv[0]->bv_val); -+ x_parser_strcat (cfile, "\" {\n"); - - item->close_brace = 1; - ldap_value_free_len (tempbv); - } - -+static int -+is_hex_string(const char *str) -+{ -+ int colon = 1; -+ int xdigit = 0; -+ size_t i; -+ -+ if (!str) -+ return 0; -+ -+ if (*str == '-') -+ str++; -+ -+ for (i=0; str[i]; ++i) -+ { -+ if (str[i] == ':') -+ { -+ xdigit = 0; -+ if(++colon > 1) -+ return 0; -+ } -+ else if(isxdigit((unsigned char)str[i])) -+ { -+ colon = 0; -+ if (++xdigit > 2) -+ return 0; -+ } -+ else -+ return 0; -+ } -+ return i > 0 && !colon; -+} - - static void - ldap_parse_subclass (struct ldap_config_stack *item, struct parse *cfile) - { - struct berval **tempbv, **classdata; -+ char *tmp; - - if ((tempbv = ldap_get_values_len (ld, item->ldent, "cn")) == NULL || - tempbv[0] == NULL) -@@ -136,11 +432,22 @@ ldap_parse_subclass (struct ldap_config_stack *item, struct parse *cfile) - 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); -+ x_parser_strcat (cfile, "subclass \""); -+ x_parser_strcat (cfile, classdata[0]->bv_val); -+ if (is_hex_string(tempbv[0]->bv_val)) -+ { -+ x_parser_strcat (cfile, "\" "); -+ x_parser_strcat (cfile, tempbv[0]->bv_val); -+ x_parser_strcat (cfile, " {\n"); -+ } -+ else -+ { -+ tmp = quotify_string(tempbv[0]->bv_val, MDL); -+ x_parser_strcat (cfile, "\" \""); -+ x_parser_strcat (cfile, tmp); -+ x_parser_strcat (cfile, "\" {\n"); -+ dfree(tmp, MDL); -+ } - - item->close_brace = 1; - ldap_value_free_len (tempbv); -@@ -164,14 +471,18 @@ ldap_parse_host (struct ldap_config_stack *item, struct parse *cfile) - - 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); -+ x_parser_strcat (cfile, "host "); -+ x_parser_strcat (cfile, tempbv[0]->bv_val); -+ x_parser_strcat (cfile, " {\n"); - -- if (hwaddr != NULL && hwaddr[0] != NULL) -+ if (hwaddr != 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); -+ if (hwaddr[0] != NULL) -+ { -+ x_parser_strcat (cfile, "hardware "); -+ x_parser_strcat (cfile, hwaddr[0]->bv_val); -+ x_parser_strcat (cfile, ";\n"); -+ } - ldap_value_free_len (hwaddr); - } - -@@ -194,9 +505,9 @@ ldap_parse_shared_network (struct ldap_config_stack *item, struct parse *cfile) - 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); -+ x_parser_strcat (cfile, "shared-network \""); -+ x_parser_strcat (cfile, tempbv[0]->bv_val); -+ x_parser_strcat (cfile, "\" {\n"); - - item->close_brace = 1; - ldap_value_free_len (tempbv); -@@ -249,14 +560,14 @@ ldap_parse_subnet (struct ldap_config_stack *item, struct parse *cfile) - return; - } - -- x_strncat (cfile->inbuf, "subnet ", LDAP_BUFFER_SIZE); -- x_strncat (cfile->inbuf, tempbv[0]->bv_val, LDAP_BUFFER_SIZE); -+ x_parser_strcat (cfile, "subnet "); -+ x_parser_strcat (cfile, tempbv[0]->bv_val); - -- x_strncat (cfile->inbuf, " netmask ", LDAP_BUFFER_SIZE); -+ x_parser_strcat (cfile, " netmask "); - parse_netmask (strtol (netmaskstr[0]->bv_val, NULL, 10), netmaskbuf); -- x_strncat (cfile->inbuf, netmaskbuf, LDAP_BUFFER_SIZE); -+ x_parser_strcat (cfile, netmaskbuf); - -- x_strncat (cfile->inbuf, " {\n", LDAP_BUFFER_SIZE); -+ x_parser_strcat (cfile, " {\n"); - - ldap_value_free_len (tempbv); - ldap_value_free_len (netmaskstr); -@@ -265,11 +576,12 @@ ldap_parse_subnet (struct ldap_config_stack *item, struct parse *cfile) - { - 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); -+ x_parser_strcat (cfile, "range"); -+ x_parser_strcat (cfile, " "); -+ x_parser_strcat (cfile, tempbv[i]->bv_val); -+ x_parser_strcat (cfile, ";\n"); - } -+ ldap_value_free_len (tempbv); - } - - item->close_brace = 1; -@@ -282,17 +594,17 @@ 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); -+ x_parser_strcat (cfile, "pool {\n"); - - if ((tempbv = ldap_get_values_len (ld, item->ldent, "dhcpRange")) != NULL) - { -- x_strncat (cfile->inbuf, "range", LDAP_BUFFER_SIZE); -+ x_parser_strcat (cfile, "range"); - 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_parser_strcat (cfile, " "); -+ x_parser_strcat (cfile, tempbv[i]->bv_val); - } -- x_strncat (cfile->inbuf, ";\n", LDAP_BUFFER_SIZE); -+ x_parser_strcat (cfile, ";\n"); - ldap_value_free_len (tempbv); - } - -@@ -300,8 +612,8 @@ ldap_parse_pool (struct ldap_config_stack *item, struct parse *cfile) - { - 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); -+ x_parser_strcat (cfile, tempbv[i]->bv_val); -+ x_parser_strcat (cfile, ";\n"); - } - ldap_value_free_len (tempbv); - } -@@ -313,7 +625,7 @@ ldap_parse_pool (struct ldap_config_stack *item, struct parse *cfile) - static void - ldap_parse_group (struct ldap_config_stack *item, struct parse *cfile) - { -- x_strncat (cfile->inbuf, "group {\n", LDAP_BUFFER_SIZE); -+ x_parser_strcat (cfile, "group {\n"); - item->close_brace = 1; - } - -@@ -325,25 +637,25 @@ ldap_parse_key (struct ldap_config_stack *item, struct parse *cfile) - - 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); -+ x_parser_strcat (cfile, "key "); -+ x_parser_strcat (cfile, tempbv[0]->bv_val); -+ x_parser_strcat (cfile, " {\n"); - 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); -+ x_parser_strcat (cfile, "algorithm "); -+ x_parser_strcat (cfile, tempbv[0]->bv_val); -+ x_parser_strcat (cfile, ";\n"); - 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); -+ x_parser_strcat (cfile, "secret "); -+ x_parser_strcat (cfile, tempbv[0]->bv_val); -+ x_parser_strcat (cfile, ";\n"); - ldap_value_free_len (tempbv); - } - -@@ -361,18 +673,18 @@ ldap_parse_zone (struct ldap_config_stack *item, struct parse *cfile) - - 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); -+ x_parser_strcat (cfile, "zone "); -+ x_parser_strcat (cfile, tempbv[0]->bv_val); -+ x_parser_strcat (cfile, " {\n"); - 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_parser_strcat (cfile, "primary "); -+ x_parser_strcat (cfile, tempbv[0]->bv_val); - -- x_strncat (cfile->inbuf, ";\n", LDAP_BUFFER_SIZE); -+ x_parser_strcat (cfile, ";\n"); - ldap_value_free_len (tempbv); - } - -@@ -400,9 +712,9 @@ ldap_parse_zone (struct ldap_config_stack *item, struct parse *cfile) - 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); -+ x_parser_strcat (cfile, "key "); -+ x_parser_strcat (cfile, keyCn); -+ x_parser_strcat (cfile, ";\n"); - - dfree (keyCn, MDL); - } -@@ -415,6 +727,228 @@ ldap_parse_zone (struct ldap_config_stack *item, struct parse *cfile) - - - static void -+ldap_parse_failover (struct ldap_config_stack *item, struct parse *cfile) -+{ -+ struct berval **tempbv, **peername; -+ struct ifaddrs *addrs = NULL; -+ char srvaddr[2][64] = {"\0", "\0"}; -+ int primary, split = 0, match; -+ struct utsname unme; -+ -+ if ((peername = ldap_get_values_len (ld, item->ldent, "cn")) == NULL || -+ peername[0] == NULL) -+ { -+ if (peername != NULL) -+ ldap_value_free_len (peername); -+ -+ // ldap with disabled schema checks? fail to avoid syntax error. -+ log_error("Unable to find mandatory failover peering name attribute"); -+ return; -+ } -+ -+ /* Get all interface addresses */ -+ getifaddrs(&addrs); -+ -+ /* -+ ** when dhcpFailOverPrimaryServer or dhcpFailOverSecondaryServer -+ ** matches one of our IP address, the following valiables are set: -+ ** - primary is 1 when we are primary or 0 when we are secondary -+ ** - srvaddr[0] contains ip address of the primary -+ ** - srvaddr[1] contains ip address of the secondary -+ */ -+ primary = -1; -+ if ((tempbv = ldap_get_values_len (ld, item->ldent, "dhcpFailOverPrimaryServer")) != NULL && -+ tempbv[0] != NULL) -+ { -+ match = get_host_address (tempbv[0]->bv_val, srvaddr[0], sizeof(srvaddr[0]), addrs); -+ if (match >= 0) -+ { -+ /* we are the primary */ -+ if (match > 0) -+ primary = 1; -+ } -+ else -+ { -+ log_info("Can't resolve address of the primary failover '%s' server %s", -+ peername[0]->bv_val, tempbv[0]->bv_val); -+ ldap_value_free_len (tempbv); -+ ldap_value_free_len (peername); -+ if (addrs) -+ freeifaddrs(addrs); -+ return; -+ } -+ } -+ if (tempbv != NULL) -+ ldap_value_free_len (tempbv); -+ -+ if ((tempbv = ldap_get_values_len (ld, item->ldent, "dhcpFailOverSecondaryServer")) != NULL && -+ tempbv[0] != NULL) -+ { -+ match = get_host_address (tempbv[0]->bv_val, srvaddr[1], sizeof(srvaddr[1]), addrs); -+ if (match >= 0) -+ { -+ if (match > 0) -+ { -+ if (primary == 1) -+ { -+ log_info("Both, primary and secondary failover '%s' server" -+ " attributes match our local address", peername[0]->bv_val); -+ ldap_value_free_len (tempbv); -+ ldap_value_free_len (peername); -+ if (addrs) -+ freeifaddrs(addrs); -+ return; -+ } -+ -+ /* we are the secondary */ -+ primary = 0; -+ } -+ } -+ else -+ { -+ log_info("Can't resolve address of the secondary failover '%s' server %s", -+ peername[0]->bv_val, tempbv[0]->bv_val); -+ ldap_value_free_len (tempbv); -+ ldap_value_free_len (peername); -+ if (addrs) -+ freeifaddrs(addrs); -+ return; -+ } -+ } -+ if (tempbv != NULL) -+ ldap_value_free_len (tempbv); -+ -+ -+ if (primary == -1 || srvaddr[0] == '\0' || srvaddr[1] == '\0') -+ { -+ log_error("Could not decide if the server type is primary" -+ " or secondary for failover peering '%s'.", peername[0]->bv_val); -+ ldap_value_free_len (peername); -+ if (addrs) -+ freeifaddrs(addrs); -+ return; -+ } -+ -+ x_parser_strcat (cfile, "failover peer \""); -+ x_parser_strcat (cfile, peername[0]->bv_val); -+ x_parser_strcat (cfile, "\" {\n"); -+ -+ if (primary) -+ x_parser_strcat (cfile, "primary;\n"); -+ else -+ x_parser_strcat (cfile, "secondary;\n"); -+ -+ x_parser_strcat (cfile, "address "); -+ if (primary) -+ x_parser_strcat (cfile, srvaddr[0]); -+ else -+ x_parser_strcat (cfile, srvaddr[1]); -+ x_parser_strcat (cfile, ";\n"); -+ -+ x_parser_strcat (cfile, "peer address "); -+ if (primary) -+ x_parser_strcat (cfile, srvaddr[1]); -+ else -+ x_parser_strcat (cfile, srvaddr[0]); -+ x_parser_strcat (cfile, ";\n"); -+ -+ if ((tempbv = ldap_get_values_len (ld, item->ldent, "dhcpFailOverPrimaryPort")) != NULL && -+ tempbv[0] != NULL) -+ { -+ if (primary) -+ x_parser_strcat (cfile, "port "); -+ else -+ x_parser_strcat (cfile, "peer port "); -+ x_parser_strcat (cfile, tempbv[0]->bv_val); -+ x_parser_strcat (cfile, ";\n"); -+ } -+ if (tempbv != NULL) -+ ldap_value_free_len (tempbv); -+ -+ if ((tempbv = ldap_get_values_len (ld, item->ldent, "dhcpFailOverSecondaryPort")) != NULL && -+ tempbv[0] != NULL) -+ { -+ if (primary) -+ x_parser_strcat (cfile, "peer port "); -+ else -+ x_parser_strcat (cfile, "port "); -+ x_parser_strcat (cfile, tempbv[0]->bv_val); -+ x_parser_strcat (cfile, ";\n"); -+ } -+ if (tempbv != NULL) -+ ldap_value_free_len (tempbv); -+ -+ if ((tempbv = ldap_get_values_len (ld, item->ldent, "dhcpFailOverResponseDelay")) != NULL && -+ tempbv[0] != NULL) -+ { -+ x_parser_strcat (cfile, "max-response-delay "); -+ x_parser_strcat (cfile, tempbv[0]->bv_val); -+ x_parser_strcat (cfile, ";\n"); -+ } -+ if (tempbv != NULL) -+ ldap_value_free_len (tempbv); -+ -+ if ((tempbv = ldap_get_values_len (ld, item->ldent, "dhcpFailOverUnackedUpdates")) != NULL && -+ tempbv[0] != NULL) -+ { -+ x_parser_strcat (cfile, "max-unacked-updates "); -+ x_parser_strcat (cfile, tempbv[0]->bv_val); -+ x_parser_strcat (cfile, ";\n"); -+ } -+ if (tempbv != NULL) -+ ldap_value_free_len (tempbv); -+ -+ if ((tempbv = ldap_get_values_len (ld, item->ldent, "dhcpFailOverLoadBalanceTime")) != NULL && -+ tempbv[0] != NULL) -+ { -+ x_parser_strcat (cfile, "load balance max seconds "); -+ x_parser_strcat (cfile, tempbv[0]->bv_val); -+ x_parser_strcat (cfile, ";\n"); -+ } -+ if (tempbv != NULL) -+ ldap_value_free_len (tempbv); -+ -+ tempbv = NULL; -+ if (primary && -+ (tempbv = ldap_get_values_len (ld, item->ldent, "dhcpMaxClientLeadTime")) != NULL && -+ tempbv[0] != NULL) -+ { -+ x_parser_strcat (cfile, "mclt "); -+ x_parser_strcat (cfile, tempbv[0]->bv_val); -+ x_parser_strcat (cfile, ";\n"); -+ } -+ if (tempbv != NULL) -+ ldap_value_free_len (tempbv); -+ -+ tempbv = NULL; -+ if (primary && -+ (tempbv = ldap_get_values_len (ld, item->ldent, "dhcpFailOverSplit")) != NULL && -+ tempbv[0] != NULL) -+ { -+ x_parser_strcat (cfile, "split "); -+ x_parser_strcat (cfile, tempbv[0]->bv_val); -+ x_parser_strcat (cfile, ";\n"); -+ split = 1; -+ } -+ if (tempbv != NULL) -+ ldap_value_free_len (tempbv); -+ -+ tempbv = NULL; -+ if (primary && !split && -+ (tempbv = ldap_get_values_len (ld, item->ldent, "dhcpFailOverHashBucketAssignment")) != NULL && -+ tempbv[0] != NULL) -+ { -+ x_parser_strcat (cfile, "hba "); -+ x_parser_strcat (cfile, tempbv[0]->bv_val); -+ x_parser_strcat (cfile, ";\n"); -+ } -+ if (tempbv != NULL) -+ ldap_value_free_len (tempbv); -+ -+ item->close_brace = 1; -+} -+ -+static void - add_to_config_stack (LDAPMessage * res, LDAPMessage * ent) - { - struct ldap_config_stack *ns; -@@ -428,7 +962,6 @@ add_to_config_stack (LDAPMessage * res, LDAPMessage * ent) - ldap_stack = ns; - } - -- - static void - ldap_stop() - { -@@ -570,6 +1103,7 @@ ldap_rebind_cb (LDAP *ld, LDAP_CONST char *url, ber_tag_t request, ber_int_t msg - { - log_error ("Error: Cannot init LDAPS session to %s:%d: %s", - ldapurl->lud_host, ldapurl->lud_port, ldap_err2string (ret)); -+ ldap_free_urldesc(ldapurl); - return ret; - } - else -@@ -585,6 +1119,7 @@ ldap_rebind_cb (LDAP *ld, LDAP_CONST char *url, ber_tag_t request, ber_int_t msg - { - log_error ("Error: Cannot start TLS session to %s:%d: %s", - ldapurl->lud_host, ldapurl->lud_port, ldap_err2string (ret)); -+ ldap_free_urldesc(ldapurl); - return ret; - } - else -@@ -609,9 +1144,40 @@ ldap_rebind_cb (LDAP *ld, LDAP_CONST char *url, ber_tag_t request, ber_int_t msg - log_error ("Error: Cannot login into ldap server %s:%d: %s", - ldapurl->lud_host, ldapurl->lud_port, ldap_err2string (ret)); - } -+ ldap_free_urldesc(ldapurl); - return ret; - } - -+static int -+_do_ldap_retry(int ret, const char *server, int port) -+{ -+ static int inform = 1; -+ -+ if (ldap_enable_retry > 0 && ret == LDAP_SERVER_DOWN && ldap_init_retry > 0) -+ { -+ if (inform || (ldap_init_retry % 10) == 0) -+ { -+ inform = 0; -+ log_info ("Can't contact LDAP server %s:%d: retrying for %d sec", -+ server, port, ldap_init_retry); -+ } -+ sleep(1); -+ return ldap_init_retry--; -+ } -+ return 0; -+} -+ -+static struct berval * -+_do_ldap_str2esc_filter_bv(const char *str, ber_len_t len, struct berval *bv_o) -+{ -+ struct berval bv_i; -+ -+ if (!str || !bv_o || (ber_str2bv(str, len, 0, &bv_i) == NULL) || -+ (ldap_bv2escaped_filter_value(&bv_i, bv_o) != 0)) -+ return NULL; -+ return bv_o; -+} -+ - static void - ldap_start (void) - { -@@ -642,6 +1208,7 @@ ldap_start (void) - ldap_debug_file = _do_lookup_dhcp_string_option (options, - SV_LDAP_DEBUG_FILE); - ldap_referrals = _do_lookup_dhcp_enum_option (options, SV_LDAP_REFERRALS); -+ ldap_init_retry = _do_lookup_dhcp_int_option (options, SV_LDAP_INIT_RETRY); - - #if defined (LDAP_USE_SSL) - ldap_use_ssl = _do_lookup_dhcp_enum_option (options, SV_LDAP_SSL); -@@ -854,7 +1421,13 @@ ldap_start (void) - } - else if (ldap_use_ssl != LDAP_SSL_OFF) - { -- if ((ret = ldap_start_tls_s (ld, NULL, NULL)) != LDAP_SUCCESS) -+ do -+ { -+ ret = ldap_start_tls_s (ld, NULL, NULL); -+ } -+ while(_do_ldap_retry(ret, ldap_server, ldap_port) > 0); -+ -+ if (ret != LDAP_SUCCESS) - { - log_error ("Error: Cannot start TLS session to %s:%d: %s", - ldap_server, ldap_port, ldap_err2string (ret)); -@@ -874,8 +1447,14 @@ ldap_start (void) - 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) -+ do -+ { -+ ret = ldap_sasl_bind_s (ld, ldap_username, LDAP_SASL_SIMPLE, -+ &creds, NULL, NULL, NULL); -+ } -+ while(_do_ldap_retry(ret, ldap_server, ldap_port) > 0); -+ -+ if (ret != LDAP_SUCCESS) - { - log_error ("Error: Cannot login into ldap server %s:%d: %s", - ldap_server, ldap_port, ldap_err2string (ret)); -@@ -895,7 +1474,15 @@ parse_external_dns (LDAPMessage * ent) - { - char *search[] = {"dhcpOptionsDN", "dhcpSharedNetworkDN", "dhcpSubnetDN", - "dhcpGroupDN", "dhcpHostDN", "dhcpClassesDN", -- "dhcpPoolDN", NULL}; -+ "dhcpPoolDN", "dhcpZoneDN", "dhcpFailOverPeerDN", NULL}; -+ -+ /* TODO: dhcpKeyDN can't be added. It is referenced in dhcpDnsZone to -+ retrive the key name (cn). Adding keyDN will reflect adding a key -+ declaration inside the zone configuration. -+ -+ dhcpSubClassesDN cant be added. It is also similar to the above. -+ Needs schema change. -+ */ - LDAPMessage * newres, * newent; - struct berval **tempbv; - int i, j, ret; -@@ -935,7 +1522,7 @@ parse_external_dns (LDAPMessage * ent) - } - - #if defined (DEBUG_LDAP) -- log_info ("Adding contents of subtree '%s' to config stack from '%s' reference", tempbv[j], search[i]); -+ log_info ("Adding contents of subtree '%s' to config stack from '%s' reference", tempbv[j]->bv_val, search[i]); - #endif - for (newent = ldap_first_entry (ld, newres); - newent != NULL; -@@ -990,17 +1577,17 @@ next_ldap_entry (struct parse *cfile) - - if (ldap_stack != NULL && ldap_stack->close_brace) - { -- x_strncat (cfile->inbuf, "}\n", LDAP_BUFFER_SIZE); -+ x_parser_strcat (cfile, "}\n"); - ldap_stack->close_brace = 0; - } - - while (ldap_stack != NULL && -- (ldap_stack->ldent == NULL || -- (ldap_stack->ldent = ldap_next_entry (ld, ldap_stack->ldent)) == NULL)) -+ (ldap_stack->ldent == NULL || ( ldap_stack->processed && -+ (ldap_stack->ldent = ldap_next_entry (ld, ldap_stack->ldent)) == NULL))) - { - if (ldap_stack->close_brace) - { -- x_strncat (cfile->inbuf, "}\n", LDAP_BUFFER_SIZE); -+ x_parser_strcat (cfile, "}\n"); - ldap_stack->close_brace = 0; - } - -@@ -1011,7 +1598,7 @@ next_ldap_entry (struct parse *cfile) - - if (ldap_stack != NULL && ldap_stack->close_brace) - { -- x_strncat (cfile->inbuf, "}\n", LDAP_BUFFER_SIZE); -+ x_parser_strcat (cfile, "}\n"); - ldap_stack->close_brace = 0; - } - } -@@ -1067,13 +1654,13 @@ check_statement_end (const char *statement) - - - static isc_result_t --ldap_parse_entry_options (LDAPMessage *ent, char *buffer, size_t size, -+ldap_parse_entry_options (LDAPMessage *ent, struct parse *cfile, - int *lease_limit) - { - struct berval **tempbv; - int i; - -- if (ent == NULL || buffer == NULL || size == 0) -+ if (ent == NULL || cfile == NULL) - return (ISC_R_FAILURE); - - if ((tempbv = ldap_get_values_len (ld, ent, "dhcpStatements")) != NULL) -@@ -1087,16 +1674,16 @@ ldap_parse_entry_options (LDAPMessage *ent, char *buffer, size_t size, - continue; - } - -- x_strncat (buffer, tempbv[i]->bv_val, size); -+ x_parser_strcat (cfile, tempbv[i]->bv_val); - - switch((int) check_statement_end (tempbv[i]->bv_val)) - { - case '}': - case ';': -- x_strncat (buffer, "\n", size); -+ x_parser_strcat (cfile, "\n"); - break; - default: -- x_strncat (buffer, ";\n", size); -+ x_parser_strcat (cfile, ";\n"); - break; - } - } -@@ -1107,15 +1694,15 @@ ldap_parse_entry_options (LDAPMessage *ent, char *buffer, size_t size, - { - for (i=0; tempbv[i] != NULL; i++) - { -- x_strncat (buffer, "option ", size); -- x_strncat (buffer, tempbv[i]->bv_val, size); -+ x_parser_strcat (cfile, "option "); -+ x_parser_strcat (cfile, tempbv[i]->bv_val); - switch ((int) check_statement_end (tempbv[i]->bv_val)) - { - case ';': -- x_strncat (buffer, "\n", size); -+ x_parser_strcat (cfile, "\n"); - break; - default: -- x_strncat (buffer, ";\n", size); -+ x_parser_strcat (cfile, ";\n"); - break; - } - } -@@ -1132,9 +1719,10 @@ ldap_generate_config_string (struct parse *cfile) - struct berval **objectClass; - char *dn; - struct ldap_config_stack *entry; -- LDAPMessage * ent, * res; -+ LDAPMessage * ent, * res, *entfirst, *resfirst; - int i, ignore, found; -- int ret; -+ int ret, parsedn = 1; -+ size_t len = cfile->buflen; - - if (ld == NULL) - ldap_start (); -@@ -1145,7 +1733,8 @@ ldap_generate_config_string (struct parse *cfile) - if ((objectClass = ldap_get_values_len (ld, entry->ldent, - "objectClass")) == NULL) - return; -- -+ -+ entry->processed = 1; - ignore = 0; - found = 1; - for (i=0; objectClass[i] != NULL; i++) -@@ -1164,6 +1753,8 @@ ldap_generate_config_string (struct parse *cfile) - 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, "dhcpFailOverPeer") == 0) -+ ldap_parse_failover (entry, cfile); - else if (strcasecmp (objectClass[i]->bv_val, "dhcpHost") == 0) - { - if (ldap_method == LDAP_METHOD_STATIC) -@@ -1187,7 +1778,7 @@ ldap_generate_config_string (struct parse *cfile) - else - found = 0; - -- if (found && cfile->inbuf[0] == '\0') -+ if (found && x_parser_length(cfile) <= len) - { - ignore = 1; - break; -@@ -1202,23 +1793,36 @@ ldap_generate_config_string (struct parse *cfile) - return; - } - -- ldap_parse_entry_options(entry->ldent, cfile->inbuf, -- LDAP_BUFFER_SIZE-1, NULL); -+ ldap_parse_entry_options(entry->ldent, cfile, NULL); - - dn = ldap_get_dn (ld, entry->ldent); -- -+ if (dn == NULL) -+ { -+ ldap_stop(); -+ return; -+ } - #if defined(DEBUG_LDAP) -- if (dn != NULL) -- log_info ("Found LDAP entry '%s'", dn); -+ 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, -+ if ((ret = ldap_search_ext_s (ld, dn, LDAP_SCOPE_ONELEVEL, -+ "(!(|(|(objectClass=dhcpTSigKey)(objectClass=dhcpClass)) (objectClass=dhcpFailOverPeer)))", -+ NULL, 0, NULL, NULL, - NULL, 0, &res)) != LDAP_SUCCESS) - { -- if (dn) -- ldap_memfree (dn); -+ ldap_memfree (dn); -+ -+ ldap_stop(); -+ return; -+ } -+ -+ if ((ret = ldap_search_ext_s (ld, dn, LDAP_SCOPE_ONELEVEL, -+ "(|(|(objectClass=dhcpTSigKey)(objectClass=dhcpClass)) (objectClass=dhcpFailOverPeer))", -+ NULL, 0, NULL, NULL, -+ NULL, 0, &resfirst)) != LDAP_SUCCESS) -+ { -+ ldap_memfree (dn); -+ ldap_msgfree (res); - - ldap_stop(); - return; -@@ -1226,17 +1830,33 @@ ldap_generate_config_string (struct parse *cfile) - - ldap_memfree (dn); - -- if ((ent = ldap_first_entry (ld, res)) != NULL) -+ ent = ldap_first_entry(ld, res); -+ entfirst = ldap_first_entry(ld, resfirst); -+ -+ if (ent == NULL && entfirst == NULL) -+ { -+ parse_external_dns (entry->ldent); -+ next_ldap_entry (cfile); -+ } -+ -+ if (ent != NULL) - { - add_to_config_stack (res, ent); - parse_external_dns (entry->ldent); -+ parsedn = 0; - } - else -+ ldap_msgfree (res); -+ -+ if (entfirst != NULL) - { -- ldap_msgfree (res); -- parse_external_dns (entry->ldent); -- next_ldap_entry (cfile); -+ add_to_config_stack (resfirst, entfirst); -+ if(parsedn) -+ parse_external_dns (entry->ldent); -+ - } -+ else -+ ldap_msgfree (resfirst); - } - - -@@ -1269,25 +1889,30 @@ ldap_write_debug (const void *buff, size_t size) - static int - ldap_read_function (struct parse *cfile) - { -- cfile->inbuf[0] = '\0'; -- cfile->buflen = 0; -- -- while (ldap_stack != NULL && *cfile->inbuf == '\0') -+ size_t len; -+ -+ /* append when in saved state */ -+ if (cfile->saved_state == NULL) -+ { -+ cfile->inbuf[0] = '\0'; -+ cfile->bufix = 0; -+ cfile->buflen = 0; -+ } -+ len = cfile->buflen; -+ -+ while (ldap_stack != NULL && x_parser_length(cfile) <= len) - ldap_generate_config_string (cfile); - -- if (ldap_stack == NULL && *cfile->inbuf == '\0') -+ if (x_parser_length(cfile) <= len && ldap_stack == NULL) - return (EOF); - -- cfile->bufix = 1; -- cfile->buflen = strlen (cfile->inbuf) - 1; -- if (cfile->buflen > 0) -- ldap_write_debug (cfile->inbuf, cfile->buflen); -- -+ if (cfile->buflen > len) -+ ldap_write_debug (cfile->inbuf + len, cfile->buflen - len); - #if defined (DEBUG_LDAP) -- log_info ("Sending config line '%s'", cfile->inbuf); -+ log_info ("Sending config portion '%s'", cfile->inbuf + len); - #endif - -- return (cfile->inbuf[0]); -+ return (cfile->inbuf[cfile->bufix++]); - } - - -@@ -1322,38 +1947,12 @@ ldap_get_host_name (LDAPMessage * ent) - } - - --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; -+ char *hostdn; - ldap_dn_node *curr = NULL; - struct parse *cfile; - struct utsname unme; -@@ -1361,52 +1960,95 @@ ldap_read_config (void) - size_t length; - int ret, cnt; - struct berval **tempbv = NULL; -+ struct berval bv_o[2]; - -+ if (local_family != AF_INET) -+ return (ISC_R_SUCCESS); -+ -+ cfile = x_parser_init("LDAP"); -+ if (cfile == NULL) -+ return (ISC_R_NOMEMORY); -+ -+ ldap_enable_retry = 1; - if (ld == NULL) - ldap_start (); -+ ldap_enable_retry = 0; -+ - 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); -+ { -+ x_parser_free(&cfile); -+ return (ldap_server == NULL ? ISC_R_SUCCESS : 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) - { -+ if (_do_ldap_str2esc_filter_bv(ldap_dhcp_server_cn, 0, &bv_o[0]) == NULL) -+ { -+ log_error ("Cannot escape ldap filter value %s: %m", ldap_dhcp_server_cn); -+ x_parser_free(&cfile); -+ return (ISC_R_FAILURE); -+ } -+ - snprintf (hfilter, sizeof (hfilter), -- "(&(objectClass=dhcpServer)(cn=%s))", ldap_dhcp_server_cn); -+ "(&(objectClass=dhcpServer)(cn=%s))", bv_o[0].bv_val); -+ -+ ber_memfree(bv_o[0].bv_val); - } - else -- { -- if(0 == getfqhostname(fqdn, sizeof(fqdn))) - { -- snprintf (hfilter, sizeof (hfilter), -- "(&(objectClass=dhcpServer)(|(cn=%s)(cn=%s)))", -- unme.nodename, fqdn); -+ if (_do_ldap_str2esc_filter_bv(unme.nodename, 0, &bv_o[0]) == NULL) -+ { -+ log_error ("Cannot escape ldap filter value %s: %m", unme.nodename); -+ x_parser_free(&cfile); -+ return (ISC_R_FAILURE); -+ } -+ -+ if(0 == get_host_entry(fqdn, sizeof(fqdn), NULL, 0)) -+ { -+ if (_do_ldap_str2esc_filter_bv(fqdn, 0, &bv_o[1]) == NULL) -+ { -+ log_error ("Cannot escape ldap filter value %s: %m", fqdn); -+ ber_memfree(bv_o[0].bv_val); -+ x_parser_free(&cfile); -+ return (ISC_R_FAILURE); -+ } -+ -+ snprintf (hfilter, sizeof (hfilter), -+ "(&(objectClass=dhcpServer)(|(cn=%s)(cn=%s)))", -+ bv_o[0].bv_val, bv_o[1].bv_val); -+ -+ ber_memfree(bv_o[1].bv_val); -+ } -+ else -+ { -+ snprintf (hfilter, sizeof (hfilter), -+ "(&(objectClass=dhcpServer)(cn=%s))", -+ bv_o[0].bv_val); -+ } -+ -+ ber_memfree(bv_o[0].bv_val); - } -- else -+ -+ ldap_enable_retry = 1; -+ do - { -- snprintf (hfilter, sizeof (hfilter), -- "(&(objectClass=dhcpServer)(cn=%s))", unme.nodename); -+ hostres = NULL; -+ ret = ldap_search_ext_s (ld, ldap_base_dn, LDAP_SCOPE_SUBTREE, -+ hfilter, NULL, 0, NULL, NULL, NULL, 0, -+ &hostres); - } -+ while(_do_ldap_retry(ret, ldap_server, ldap_port) > 0); -+ ldap_enable_retry = 0; - -- } -- 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) -+ if(ret != LDAP_SUCCESS) - { - log_error ("Cannot find host LDAP entry %s %s", -- ((ldap_dhcp_server_cn == NULL)?(unme.nodename):(ldap_dhcp_server_cn)), hfilter); -+ ((ldap_dhcp_server_cn == NULL)?(unme.nodename):(ldap_dhcp_server_cn)), hfilter); - if(NULL != hostres) - ldap_msgfree (hostres); - ldap_stop(); -+ x_parser_free(&cfile); - return (ISC_R_FAILURE); - } - -@@ -1415,6 +2057,7 @@ ldap_read_config (void) - log_error ("Error: Cannot find LDAP entry matching %s", hfilter); - ldap_msgfree (hostres); - ldap_stop(); -+ x_parser_free(&cfile); - return (ISC_R_FAILURE); - } - -@@ -1428,7 +2071,9 @@ ldap_read_config (void) - (tempbv = ldap_get_values_len (ld, hostent, "dhcpServiceDN")) == NULL || - tempbv[0] == NULL) - { -- log_error ("Error: Cannot find LDAP entry matching %s", hfilter); -+ log_error ("Error: No dhcp service is associated with the server %s %s", -+ (hostdn ? "dn" : "name"), (hostdn ? hostdn : -+ (ldap_dhcp_server_cn ? ldap_dhcp_server_cn : unme.nodename))); - - if (tempbv != NULL) - ldap_value_free_len (tempbv); -@@ -1437,6 +2082,7 @@ ldap_read_config (void) - ldap_memfree (hostdn); - ldap_msgfree (hostres); - ldap_stop(); -+ x_parser_free(&cfile); - return (ISC_R_FAILURE); - } - -@@ -1444,37 +2090,51 @@ ldap_read_config (void) - 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) -+ res = ldap_parse_entry_options(hostent, cfile, NULL); -+ if (res != ISC_R_SUCCESS) - { -- ldap_write_debug (cfile->inbuf, cfile->buflen); -+ ldap_value_free_len (tempbv); -+ ldap_msgfree (hostres); -+ ldap_memfree (hostdn); -+ ldap_stop(); -+ x_parser_free(&cfile); -+ return res; -+ } - -+ if (x_parser_length(cfile) > 0) -+ { - res = conf_file_subparse (cfile, root_group, ROOT_GROUP); - if (res != ISC_R_SUCCESS) - { - log_error ("LDAP: cannot parse dhcpServer entry '%s'", hostdn); -+ ldap_value_free_len (tempbv); -+ ldap_msgfree (hostres); - ldap_memfree (hostdn); - ldap_stop(); -+ x_parser_free(&cfile); - return res; - } -- cfile->inbuf[0] = '\0'; -+ x_parser_reset(cfile); - } - 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++) - { -+ -+ if (_do_ldap_str2esc_filter_bv(hostdn, 0, &bv_o[0]) == NULL) -+ { -+ log_error ("Cannot escape ldap filter value %s: %m", hostdn); -+ res = ISC_R_FAILURE; -+ break; -+ } -+ - snprintf(sfilter, sizeof(sfilter), "(&(objectClass=dhcpService)" -- "(|(dhcpPrimaryDN=%s)(dhcpSecondaryDN=%s)))", -- hostdn, hostdn); -+ "(|(|(dhcpPrimaryDN=%s)(dhcpSecondaryDN=%s))(dhcpServerDN=%s)))", -+ bv_o[0].bv_val, bv_o[0].bv_val, bv_o[0].bv_val); -+ -+ ber_memfree(bv_o[0].bv_val); -+ - ldres = NULL; - if ((ret = ldap_search_ext_s (ld, tempbv[cnt]->bv_val, LDAP_SCOPE_BASE, - sfilter, NULL, 0, NULL, NULL, NULL, -@@ -1490,7 +2150,7 @@ ldap_read_config (void) - - 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'", -+ log_error ("Error: Cannot find dhcpService DN '%s' with server reference. Please update the LDAP server entry '%s'", - tempbv[cnt]->bv_val, hostdn); - - ldap_msgfree(ldres); -@@ -1534,7 +2194,7 @@ ldap_read_config (void) - log_fatal ("no memory to remember ldap service dn"); - - #if defined (DEBUG_LDAP) -- log_info ("LDAP: Parsing dhcpService DN '%s' ...", tempbv[cnt]); -+ log_info ("LDAP: Parsing dhcpService DN '%s' ...", tempbv[cnt]->bv_val); - #endif - add_to_config_stack (ldres, ent); - res = conf_file_subparse (cfile, root_group, ROOT_GROUP); -@@ -1545,7 +2205,7 @@ ldap_read_config (void) - } - } - -- end_parse (&cfile); -+ x_parser_free(&cfile); - ldap_close_debug_fd(); - - ldap_memfree (hostdn); -@@ -1593,17 +2253,18 @@ ldap_parse_options (LDAPMessage * ent, struct group *group, - 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. */ -+ cfile = x_parser_init(type == HOST_DECL ? "LDAP-HOST" : "LDAP-SUBCLASS"); -+ if (cfile == NULL) -+ return (lease_limit); -+ -+ /* 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]; -@@ -1625,16 +2286,29 @@ ldap_parse_options (LDAPMessage * ent, struct group *group, - - if (temp2 != NULL) - { -- snprintf (filter, sizeof(filter), -- "(&(cn=%.*s)(objectClass=dhcpGroup))", -- (int)(temp2 - temp1), temp1); -+ struct berval bv_o; -+ -+ if (_do_ldap_str2esc_filter_bv(temp1, (temp2 - temp1), &bv_o) == NULL) -+ { -+ log_error ("Cannot escape ldap filter value %.*s: %m", -+ (int)(temp2 - temp1), temp1); -+ filter[0] = '\0'; -+ } -+ else -+ { -+ snprintf (filter, sizeof(filter), -+ "(&(cn=%s)(objectClass=dhcpGroup))", -+ bv_o.bv_val); -+ -+ ber_memfree(bv_o.bv_val); -+ } - - basedn = strchr (temp1, ','); - if (basedn != NULL) - ++basedn; - } - -- if (basedn != NULL && *basedn != '\0') -+ if (basedn != NULL && *basedn != '\0' && filter[0] != '\0') - { - ret = ldap_search_ext_s (ld, basedn, LDAP_SCOPE_SUBTREE, filter, - NULL, 0, NULL, NULL, NULL, 0, &groupdn); -@@ -1642,13 +2316,11 @@ ldap_parse_options (LDAPMessage * ent, struct group *group, - { - if ((entry = ldap_first_entry (ld, groupdn)) != NULL) - { -- res = ldap_parse_entry_options (entry, option_buffer, -- sizeof(option_buffer) - 1, -- &lease_limit); -+ res = ldap_parse_entry_options (entry, cfile, &lease_limit); - if (res != ISC_R_SUCCESS) - { - /* reset option buffer discarding any results */ -- *option_buffer = '\0'; -+ x_parser_reset(cfile); - lease_limit = 0; - } - } -@@ -1659,24 +2331,18 @@ ldap_parse_options (LDAPMessage * ent, struct group *group, - } - } - -- 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); -+ res = ldap_parse_entry_options (ent, cfile, &lease_limit); - if (res != ISC_R_SUCCESS) -- return (lease_limit); -+ { -+ x_parser_free(&cfile); -+ return (lease_limit); -+ } - --#if defined (DEBUG_LDAP) -- log_info ("Sending the following options: '%s'", option_buffer); --#endif -+ if (x_parser_length(cfile) == 0) -+ { -+ x_parser_free(&cfile); -+ return (lease_limit); -+ } - - declaration = 0; - do -@@ -1687,7 +2353,7 @@ ldap_parse_options (LDAPMessage * ent, struct group *group, - declaration = parse_statement (cfile, group, type, host, declaration); - } while (1); - -- end_parse (&cfile); -+ x_parser_free(&cfile); - - return (lease_limit); - } -@@ -1703,7 +2369,14 @@ find_haddr_in_ldap (struct host_decl **hp, int htype, unsigned hlen, - struct host_decl * host; - isc_result_t status; - ldap_dn_node *curr; -+ char up_hwaddr[20]; -+ char lo_hwaddr[20]; - int ret; -+ struct berval bv_o[2]; -+ -+ -+ if (local_family != AF_INET) -+ return (0); - - if (ldap_method == LDAP_METHOD_STATIC) - return (0); -@@ -1733,9 +2406,28 @@ find_haddr_in_ldap (struct host_decl **hp, int htype, unsigned hlen, - ** FIXME: It is not guaranteed, that the dhcpHWAddress attribute - ** contains _exactly_ "type addr" with one space between! - */ -+ snprintf(lo_hwaddr, sizeof(lo_hwaddr), "%s", -+ print_hw_addr (htype, hlen, haddr)); -+ x_strxform(up_hwaddr, lo_hwaddr, sizeof(up_hwaddr), toupper); -+ -+ if (_do_ldap_str2esc_filter_bv(lo_hwaddr, 0, &bv_o[0]) == NULL) -+ { -+ log_error ("Cannot escape ldap filter value %s: %m", lo_hwaddr); -+ return (0); -+ } -+ if (_do_ldap_str2esc_filter_bv(up_hwaddr, 0, &bv_o[1]) == NULL) -+ { -+ log_error ("Cannot escape ldap filter value %s: %m", up_hwaddr); -+ ber_memfree(bv_o[0].bv_val); -+ return (0); -+ } -+ - snprintf (buf, sizeof (buf), -- "(&(objectClass=dhcpHost)(dhcpHWAddress=%s %s))", -- type_str, print_hw_addr (htype, hlen, haddr)); -+ "(&(objectClass=dhcpHost)(|(dhcpHWAddress=%s %s)(dhcpHWAddress=%s %s)))", -+ type_str, bv_o[0].bv_val, type_str, bv_o[1].bv_val); -+ -+ ber_memfree(bv_o[0].bv_val); -+ ber_memfree(bv_o[1].bv_val); - - res = ent = NULL; - for (curr = ldap_service_dn_head; -@@ -1862,7 +2554,13 @@ find_subclass_in_ldap (struct class *class, struct class **newclass, - int ret, lease_limit; - isc_result_t status; - ldap_dn_node *curr; -- char buf[1024]; -+ char buf[2048]; -+ struct berval bv_class; -+ struct berval bv_cdata; -+ char *hex_1; -+ -+ if (local_family != AF_INET) -+ return (0); - - if (ldap_method == LDAP_METHOD_STATIC) - return (0); -@@ -1872,10 +2570,33 @@ find_subclass_in_ldap (struct class *class, struct class **newclass, - if (ld == NULL) - return (0); - -+ hex_1 = print_hex_1 (data->len, data->data, 1024); -+ if (*hex_1 == '"') -+ { -+ /* result is a quotted not hex string: ldap escape the original string */ -+ if (_do_ldap_str2esc_filter_bv(data->data, data->len, &bv_cdata) == NULL) -+ { -+ log_error ("Cannot escape ldap filter value %s: %m", hex_1); -+ return (0); -+ } -+ hex_1 = NULL; -+ } -+ if (_do_ldap_str2esc_filter_bv(class->name, strlen (class->name), &bv_class) == NULL) -+ { -+ log_error ("Cannot escape ldap filter value %s: %m", class->name); -+ if (hex_1 == NULL) -+ ber_memfree(bv_cdata.bv_val); -+ 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)); -+ (hex_1 == NULL ? bv_cdata.bv_val : hex_1), bv_class.bv_val); -+ -+ if (hex_1 == NULL) -+ ber_memfree(bv_cdata.bv_val); -+ ber_memfree(bv_class.bv_val); -+ - #if defined (DEBUG_LDAP) - log_info ("Searching LDAP for %s", buf); - #endif -diff --git a/server/ldap_casa.c b/server/ldap_casa.c -index 952d9b9..cd10157 100644 ---- a/server/ldap_casa.c -+++ b/server/ldap_casa.c -@@ -55,8 +55,10 @@ - */ - - #if defined(LDAP_CASA_AUTH) --#include "ldap_casa.h" - #include "dhcpd.h" -+#include "ldap_casa.h" -+#include -+#include - - int - load_casa (void) -diff --git a/server/stables.c b/server/stables.c -index da25764..cf85334 100644 ---- a/server/stables.c -+++ b/server/stables.c -@@ -259,6 +259,7 @@ static struct option server_options[] = { - { "ldap-tls-ciphers", "t", &server_universe, 76, 1 }, - { "ldap-tls-randfile", "t", &server_universe, 77, 1 }, - #endif /* LDAP_USE_SSL */ -+ { "ldap-init-retry", "d", &server_universe, 78, 1 }, - #endif /* LDAP_CONFIGURATION */ - { NULL, NULL, NULL, 0, 0 } - }; --- -1.8.4 - diff --git a/0010-dhcp-4.2.2-dhclient-option-checks.patch b/0008-dhcp-4.2.2-dhclient-option-checks.patch similarity index 98% rename from 0010-dhcp-4.2.2-dhclient-option-checks.patch rename to 0008-dhcp-4.2.2-dhclient-option-checks.patch index 5e746bd..12b0d0d 100644 --- a/0010-dhcp-4.2.2-dhclient-option-checks.patch +++ b/0008-dhcp-4.2.2-dhclient-option-checks.patch @@ -2,6 +2,7 @@ From 48c1bbb9cbd6d6e71178e82fd45a7409efbb9d72 Mon Sep 17 00:00:00 2001 From: Marius Tomaschewski Date: Wed, 27 Apr 2011 13:56:47 +0200 Subject: [PATCH] dhcp-4.2.2-dhclient-option-checks +References: bnc#643845 --- client/dhclient.c | 6 +++--- diff --git a/0011-dhcp-4.2.6-close-on-exec.patch b/0009-dhcp-4.2.6-close-on-exec.patch similarity index 62% rename from 0011-dhcp-4.2.6-close-on-exec.patch rename to 0009-dhcp-4.2.6-close-on-exec.patch index 076e4f1..04b169d 100644 --- a/0011-dhcp-4.2.6-close-on-exec.patch +++ b/0009-dhcp-4.2.6-close-on-exec.patch @@ -1,29 +1,15 @@ -From 0ae45af28ebda5770465f84ac0f69f28ed6b7b07 Mon Sep 17 00:00:00 2001 +From ecb183516cf0b51ebf0a02f3b46248479fa51e43 Mon Sep 17 00:00:00 2001 From: Marius Tomaschewski Date: Thu, 18 Aug 2011 14:09:06 +0200 Subject: [PATCH] dhcp-4.2.6-close-on-exec ---- - client/clparse.c | 4 ++-- - client/dhclient.c | 10 +++++----- - common/bpf.c | 2 +- - common/discover.c | 4 ++-- - common/dlpi.c | 2 +- - common/nit.c | 2 +- - common/resolv.c | 2 +- - common/upf.c | 2 +- - dst/dst_api.c | 8 ++++---- - dst/prandom.c | 4 ++-- - omapip/trace.c | 6 +++--- - relay/dhcrelay.c | 5 +++-- - server/confpars.c | 2 +- - server/db.c | 6 +++--- - server/dhcpd.c | 4 ++-- - server/ldap.c | 2 +- - 16 files changed, 33 insertions(+), 32 deletions(-) +Merged fixed close-on-exec patch (bnc#732910) + +References: bnc#732910 +Signed-off-by: Marius Tomaschewski diff --git a/client/clparse.c b/client/clparse.c -index 646229f..3e9f9b1 100644 +index 320c42f..b7e4251 100644 --- a/client/clparse.c +++ b/client/clparse.c @@ -221,7 +221,7 @@ int read_client_conf_file (const char *name, struct interface_info *ip, @@ -35,7 +21,7 @@ index 646229f..3e9f9b1 100644 return uerr2isc (errno); cfile = NULL; -@@ -258,7 +258,7 @@ void read_client_leases () +@@ -297,7 +297,7 @@ void read_client_leases () /* Open the lease file. If we can't open it, just return - we can safely trust the server to remember our state. */ @@ -45,10 +31,10 @@ index 646229f..3e9f9b1 100644 cfile = NULL; diff --git a/client/dhclient.c b/client/dhclient.c -index 19a527b..dbc6f38 100644 +index a077b48..ac36e3d 100644 --- a/client/dhclient.c +++ b/client/dhclient.c -@@ -422,7 +422,7 @@ main(int argc, char **argv) { +@@ -438,7 +438,7 @@ main(int argc, char **argv) { long temp; int e; @@ -57,7 +43,7 @@ index 19a527b..dbc6f38 100644 e = fscanf(pidfd, "%ld\n", &temp); oldpid = (pid_t)temp; -@@ -2728,7 +2728,7 @@ void rewrite_client_leases () +@@ -2840,7 +2840,7 @@ void rewrite_client_leases () if (leaseFile != NULL) fclose (leaseFile); @@ -66,7 +52,7 @@ index 19a527b..dbc6f38 100644 if (leaseFile == NULL) { log_error ("can't create %s: %m", path_dhclient_db); return; -@@ -2849,7 +2849,7 @@ write_duid(struct data_string *duid) +@@ -3033,7 +3033,7 @@ write_duid(struct data_string *duid) return DHCP_R_INVALIDARG; if (leaseFile == NULL) { /* XXX? */ @@ -75,7 +61,7 @@ index 19a527b..dbc6f38 100644 if (leaseFile == NULL) { log_error("can't create %s: %m", path_dhclient_db); return ISC_R_IOERROR; -@@ -2897,7 +2897,7 @@ write_client6_lease(struct client_state *client, struct dhc6_lease *lease, +@@ -3081,7 +3081,7 @@ write_client6_lease(struct client_state *client, struct dhc6_lease *lease, return DHCP_R_INVALIDARG; if (leaseFile == NULL) { /* XXX? */ @@ -84,7 +70,7 @@ index 19a527b..dbc6f38 100644 if (leaseFile == NULL) { log_error("can't create %s: %m", path_dhclient_db); return ISC_R_IOERROR; -@@ -3029,7 +3029,7 @@ int write_client_lease (client, lease, rewrite, makesure) +@@ -3213,7 +3213,7 @@ int write_client_lease (client, lease, rewrite, makesure) return 1; if (leaseFile == NULL) { /* XXX */ @@ -94,10 +80,10 @@ index 19a527b..dbc6f38 100644 log_error ("can't create %s: %m", path_dhclient_db); return 0; diff --git a/common/bpf.c b/common/bpf.c -index 559b414..076d9bc 100644 +index 39d4f45..df9facc 100644 --- a/common/bpf.c +++ b/common/bpf.c -@@ -94,7 +94,7 @@ int if_register_bpf (info) +@@ -95,7 +95,7 @@ int if_register_bpf (info) for (b = 0; 1; b++) { /* %Audit% 31 bytes max. %2004.06.17,Safe% */ sprintf(filename, BPF_FORMAT, b); @@ -107,10 +93,10 @@ index 559b414..076d9bc 100644 if (errno == EBUSY) { continue; diff --git a/common/discover.c b/common/discover.c -index 4b40a70..6a0540b 100644 +index 3cd64a7..37af780 100644 --- a/common/discover.c +++ b/common/discover.c -@@ -412,7 +412,7 @@ begin_iface_scan(struct iface_conf_list *ifaces) { +@@ -415,7 +415,7 @@ begin_iface_scan(struct iface_conf_list *ifaces) { int len; int i; @@ -119,7 +105,7 @@ index 4b40a70..6a0540b 100644 if (ifaces->fp == NULL) { log_error("Error opening '/proc/net/dev' to list interfaces"); return 0; -@@ -447,7 +447,7 @@ begin_iface_scan(struct iface_conf_list *ifaces) { +@@ -450,7 +450,7 @@ begin_iface_scan(struct iface_conf_list *ifaces) { #ifdef DHCPv6 if (local_family == AF_INET6) { @@ -129,7 +115,7 @@ index 4b40a70..6a0540b 100644 log_error("Error opening '/proc/net/if_inet6' to " "list IPv6 interfaces; %m"); diff --git a/common/dlpi.c b/common/dlpi.c -index 14e95d2..efaba3a 100644 +index c34adc3..944f21c 100644 --- a/common/dlpi.c +++ b/common/dlpi.c @@ -804,7 +804,7 @@ dlpiopen(const char *ifname) { @@ -142,7 +128,7 @@ index 14e95d2..efaba3a 100644 /* diff --git a/common/nit.c b/common/nit.c -index 3fdef1d..dc62081 100644 +index 316e85f..6aa778b 100644 --- a/common/nit.c +++ b/common/nit.c @@ -75,7 +75,7 @@ int if_register_nit (info) @@ -168,7 +154,7 @@ index 526cebf..2ac8d43 100644 return; } diff --git a/common/upf.c b/common/upf.c -index 6a02077..e5cafcf 100644 +index 34011eb..77d5878 100644 --- a/common/upf.c +++ b/common/upf.c @@ -71,7 +71,7 @@ int if_register_upf (info) @@ -180,70 +166,8 @@ index 6a02077..e5cafcf 100644 if (sock < 0) { if (errno == EBUSY) { continue; -diff --git a/dst/dst_api.c b/dst/dst_api.c -index 3993b1e..aadcc1f 100644 ---- a/dst/dst_api.c -+++ b/dst/dst_api.c -@@ -437,7 +437,7 @@ dst_s_write_private_key(const DST_KEY *key) - PRIVATE_KEY, PATH_MAX); - - /* Do not overwrite an existing file */ -- if ((fp = dst_s_fopen(file, "w", 0600)) != NULL) { -+ if ((fp = dst_s_fopen(file, "we", 0600)) != NULL) { - int nn; - if ((nn = fwrite(encoded_block, 1, len, fp)) != len) { - EREPORT(("dst_write_private_key(): Write failure on %s %d != %d errno=%d\n", -@@ -495,7 +495,7 @@ dst_s_read_public_key(const char *in_name, const unsigned in_id, int in_alg) - * flags, proto, alg stored as decimal (or hex numbers FIXME). - * (FIXME: handle parentheses for line continuation.) - */ -- if ((fp = dst_s_fopen(name, "r", 0)) == NULL) { -+ if ((fp = dst_s_fopen(name, "re", 0)) == NULL) { - EREPORT(("dst_read_public_key(): Public Key not found %s\n", - name)); - return (NULL); -@@ -621,7 +621,7 @@ dst_s_write_public_key(const DST_KEY *key) - return (0); - } - /* create public key file */ -- if ((fp = dst_s_fopen(filename, "w+", 0644)) == NULL) { -+ if ((fp = dst_s_fopen(filename, "w+e", 0644)) == NULL) { - EREPORT(("DST_write_public_key: open of file:%s failed (errno=%d)\n", - filename, errno)); - return (0); -@@ -855,7 +855,7 @@ dst_s_read_private_key_file(char *name, DST_KEY *pk_key, unsigned in_id, - return (0); - } - /* first check if we can find the key file */ -- if ((fp = dst_s_fopen(filename, "r", 0)) == NULL) { -+ if ((fp = dst_s_fopen(filename, "re", 0)) == NULL) { - EREPORT(("dst_s_read_private_key_file: Could not open file %s in directory %s\n", - filename, dst_path[0] ? dst_path : - (char *) getcwd(NULL, PATH_MAX - 1))); -diff --git a/dst/prandom.c b/dst/prandom.c -index d207993..775cb23 100644 ---- a/dst/prandom.c -+++ b/dst/prandom.c -@@ -270,7 +270,7 @@ get_dev_random(u_char *output, unsigned size) - - s = stat("/dev/random", &st); - if (s == 0 && S_ISCHR(st.st_mode)) { -- if ((fd = open("/dev/random", O_RDONLY | O_NONBLOCK)) != -1) { -+ if ((fd = open("/dev/random", O_RDONLY | O_NONBLOCK | O_CLOEXEC)) != -1) { - if ((n = read(fd, output, size)) < 0) - n = 0; - close(fd); -@@ -480,7 +480,7 @@ digest_file(dst_work *work) - work->file_digest = dst_free_key(work->file_digest); - return (0); - } -- if ((fp = fopen(name, "r")) == NULL) -+ if ((fp = fopen(name, "re")) == NULL) - return (0); - for (no = 0; (i = fread(buf, sizeof(*buf), sizeof(buf), fp)) > 0; - no += i) diff --git a/omapip/trace.c b/omapip/trace.c -index 23e4e50..846b42b 100644 +index f4115c1..4410c35 100644 --- a/omapip/trace.c +++ b/omapip/trace.c @@ -138,10 +138,10 @@ isc_result_t trace_begin (const char *filename, @@ -269,10 +193,10 @@ index 23e4e50..846b42b 100644 log_error("Can't open tracefile %s: %m", filename); return; diff --git a/relay/dhcrelay.c b/relay/dhcrelay.c -index 6f42927..4ef6737 100644 +index 15b4997..9d39fae 100644 --- a/relay/dhcrelay.c +++ b/relay/dhcrelay.c -@@ -539,13 +539,14 @@ main(int argc, char **argv) { +@@ -558,13 +558,14 @@ main(int argc, char **argv) { if (no_pid_file == ISC_FALSE) { pfdesc = open(path_dhcrelay_pid, @@ -290,10 +214,10 @@ index 6f42927..4ef6737 100644 log_error("Can't fdopen %s: %m", path_dhcrelay_pid); diff --git a/server/confpars.c b/server/confpars.c -index 684f9c1..3b5a840 100644 +index 4b2907d..6aa5b3f 100644 --- a/server/confpars.c +++ b/server/confpars.c -@@ -110,7 +110,7 @@ isc_result_t read_conf_file (const char *filename, struct group *group, +@@ -111,7 +111,7 @@ isc_result_t read_conf_file (const char *filename, struct group *group, } #endif @@ -303,10 +227,10 @@ index 684f9c1..3b5a840 100644 log_error ("Can't open lease database %s: %m --", path_dhcpd_db); diff --git a/server/db.c b/server/db.c -index c2630ea..59e96dd 100644 +index 0c642ad..e9a38fe 100644 --- a/server/db.c +++ b/server/db.c -@@ -1050,7 +1050,7 @@ void db_startup (testp) +@@ -1072,7 +1072,7 @@ void db_startup (testp) } #endif if (!testp) { @@ -315,51 +239,51 @@ index c2630ea..59e96dd 100644 if (!db_file) log_fatal ("Can't open %s for append.", path_dhcpd_db); expire_all_pools (); -@@ -1089,7 +1089,7 @@ int new_lease_file () - db_validity = lease_file_is_corrupt; +@@ -1120,7 +1120,7 @@ int new_lease_file () + path_dhcpd_db) >= sizeof newfname) + log_fatal("new_lease_file: lease file path too long"); - snprintf (newfname, sizeof(newfname), "%s.XXXXXX", path_dhcpd_db); - db_fd = mkstemp (newfname); + db_fd = mkostemp (newfname, O_CLOEXEC); if (db_fd < 0) { log_error ("Can't create new lease file: %m"); return 0; -@@ -1098,7 +1098,7 @@ int new_lease_file () - log_error ("Can't fchmod new lease file: %m"); - goto fail; +@@ -1145,7 +1145,7 @@ int new_lease_file () } + #endif /* PARANOIA */ + - if ((new_db_file = fdopen(db_fd, "w")) == NULL) { + if ((new_db_file = fdopen(db_fd, "we")) == NULL) { log_error("Can't fdopen new lease file: %m"); close(db_fd); goto fdfail; diff --git a/server/dhcpd.c b/server/dhcpd.c -index b4c1bef..41a9efe 100644 +index eecc89b..afef390 100644 --- a/server/dhcpd.c +++ b/server/dhcpd.c -@@ -805,7 +805,7 @@ main(int argc, char **argv) { +@@ -658,7 +658,7 @@ main(int argc, char **argv) { + */ + if ((lftest == 0) && (no_pid_file == ISC_FALSE)) { + /*Read previous pid file. */ +- if ((i = open(path_dhcpd_pid, O_RDONLY)) >= 0) { ++ if ((i = open(path_dhcpd_pid, O_RDONLY | O_CLOEXEC)) >= 0) { + status = read(i, pbuf, (sizeof pbuf) - 1); + close(i); + if (status > 0) { +@@ -758,7 +758,7 @@ main(int argc, char **argv) { + * appropriate. */ if (no_pid_file == ISC_FALSE) { - /*Read previous pid file. */ -- if ((i = open (path_dhcpd_pid, O_RDONLY)) >= 0) { -+ if ((i = open (path_dhcpd_pid, O_RDONLY | O_CLOEXEC)) >= 0) { - status = read(i, pbuf, (sizeof pbuf) - 1); - close (i); - if (status > 0) { -@@ -824,7 +824,7 @@ main(int argc, char **argv) { - } - - /* Write new pid file. */ - i = open(path_dhcpd_pid, O_WRONLY|O_CREAT|O_TRUNC, 0644); + i = open(path_dhcpd_pid, O_WRONLY|O_CREAT|O_TRUNC|O_CLOEXEC, 0644); if (i >= 0) { sprintf(pbuf, "%d\n", (int) getpid()); - IGNORE_RET (write(i, pbuf, strlen(pbuf))); + IGNORE_RET(write(i, pbuf, strlen(pbuf))); diff --git a/server/ldap.c b/server/ldap.c -index 6e7f508..d1cde27 100644 +index 2893b82..9530d9d 100644 --- a/server/ldap.c +++ b/server/ldap.c -@@ -1252,7 +1252,7 @@ ldap_start (void) +@@ -1442,7 +1442,7 @@ ldap_start (void) if (ldap_debug_file != NULL && ldap_debug_fd == -1) { @@ -369,5 +293,5 @@ index 6e7f508..d1cde27 100644 log_error ("Error opening debug LDAP log file %s: %s", ldap_debug_file, strerror (errno)); -- -1.8.4 +2.1.4 diff --git a/0009-dhcp-4.2.6-xen-checksum.patch b/0009-dhcp-4.2.6-xen-checksum.patch deleted file mode 100644 index dd2592c..0000000 --- a/0009-dhcp-4.2.6-xen-checksum.patch +++ /dev/null @@ -1,274 +0,0 @@ -From 16e50fd8fbd606ba04ac814f9fff883ecb9e110c Mon Sep 17 00:00:00 2001 -From: Marius Tomaschewski -Date: Fri, 18 Feb 2011 13:18:32 +0100 -Subject: [PATCH] dhcp-4.2.6-xen-checksum - ---- - common/bpf.c | 2 +- - common/dlpi.c | 2 +- - common/lpf.c | 84 ++++++++++++++++++++++++++++++++++++++++++-------------- - common/nit.c | 2 +- - common/packet.c | 4 +-- - common/upf.c | 2 +- - includes/dhcpd.h | 2 +- - 7 files changed, 70 insertions(+), 28 deletions(-) - -diff --git a/common/bpf.c b/common/bpf.c -index d6d6013..559b414 100644 ---- a/common/bpf.c -+++ b/common/bpf.c -@@ -480,7 +480,7 @@ ssize_t receive_packet (interface, buf, len, from, hfrom) - /* Decode the IP and UDP headers... */ - offset = decode_udp_ip_header(interface, interface->rbuf, - interface->rbuf_offset, -- from, hdr.bh_caplen, &paylen); -+ from, hdr.bh_caplen, &paylen, 0); - - /* If the IP or UDP checksum was bad, skip the packet... */ - if (offset < 0) { -diff --git a/common/dlpi.c b/common/dlpi.c -index 391fb91..14e95d2 100644 ---- a/common/dlpi.c -+++ b/common/dlpi.c -@@ -691,7 +691,7 @@ ssize_t receive_packet (interface, buf, len, from, hfrom) - length -= offset; - #endif - offset = decode_udp_ip_header (interface, dbuf, bufix, -- from, length, &paylen); -+ from, length, &paylen, 0); - - /* - * If the IP or UDP checksum was bad, skip the packet... -diff --git a/common/lpf.c b/common/lpf.c -index 82c8b76..6639809 100644 ---- a/common/lpf.c -+++ b/common/lpf.c -@@ -30,19 +30,33 @@ - #include "dhcpd.h" - #if defined (USE_LPF_SEND) || defined (USE_LPF_RECEIVE) - #include -+#include - #include - #include - - #include - #include - #include -+#include - #include --#include - #include "includes/netinet/ip.h" - #include "includes/netinet/udp.h" - #include "includes/netinet/if_ether.h" - #include - -+#ifndef PACKET_AUXDATA -+#define PACKET_AUXDATA 8 -+ -+struct tpacket_auxdata -+{ -+ __u32 tp_status; -+ __u32 tp_len; -+ __u32 tp_snaplen; -+ __u16 tp_mac; -+ __u16 tp_net; -+}; -+#endif -+ - /* Reinitializes the specified interface after an address change. This - is not required for packet-filter APIs. */ - -@@ -68,10 +82,14 @@ int if_register_lpf (info) - struct interface_info *info; - { - int sock; -- struct sockaddr sa; -+ union { -+ struct sockaddr_ll ll; -+ struct sockaddr common; -+ } sa; -+ struct ifreq ifr; - - /* Make an LPF socket. */ -- if ((sock = socket(PF_PACKET, SOCK_PACKET, -+ if ((sock = socket(PF_PACKET, SOCK_RAW, - htons((short)ETH_P_ALL))) < 0) { - if (errno == ENOPROTOOPT || errno == EPROTONOSUPPORT || - errno == ESOCKTNOSUPPORT || errno == EPFNOSUPPORT || -@@ -86,11 +104,16 @@ int if_register_lpf (info) - log_fatal ("Open a socket for LPF: %m"); - } - -+ memset (&ifr, 0, sizeof ifr); -+ strncpy (ifr.ifr_name, (const char *)info -> ifp, sizeof ifr.ifr_name); -+ if (ioctl (sock, SIOCGIFINDEX, &ifr)) -+ log_fatal ("Failed to get interface index: %m"); -+ - /* Bind to the interface name */ - memset (&sa, 0, sizeof sa); -- sa.sa_family = AF_PACKET; -- strncpy (sa.sa_data, (const char *)info -> ifp, sizeof sa.sa_data); -- if (bind (sock, &sa, sizeof sa)) { -+ sa.ll.sll_family = AF_PACKET; -+ sa.ll.sll_ifindex = ifr.ifr_ifindex; -+ if (bind (sock, &sa.common, sizeof sa)) { - if (errno == ENOPROTOOPT || errno == EPROTONOSUPPORT || - errno == ESOCKTNOSUPPORT || errno == EPFNOSUPPORT || - errno == EAFNOSUPPORT || errno == EINVAL) { -@@ -172,9 +195,18 @@ static void lpf_gen_filter_setup (struct interface_info *); - void if_register_receive (info) - struct interface_info *info; - { -+ int val; -+ - /* Open a LPF device and hang it on this interface... */ - info -> rfdesc = if_register_lpf (info); - -+ val = 1; -+ if (setsockopt (info -> rfdesc, SOL_PACKET, PACKET_AUXDATA, &val, -+ sizeof val) < 0) { -+ if (errno != ENOPROTOOPT) -+ log_fatal ("Failed to set auxiliary packet data: %m"); -+ } -+ - #if defined (HAVE_TR_SUPPORT) - if (info -> hw_address.hbuf [0] == HTYPE_IEEE802) - lpf_tr_filter_setup (info); -@@ -296,7 +328,6 @@ ssize_t send_packet (interface, packet, raw, len, from, to, hto) - double hh [16]; - double ih [1536 / sizeof (double)]; - unsigned char *buf = (unsigned char *)ih; -- struct sockaddr_pkt sa; - int result; - int fudge; - -@@ -317,17 +348,7 @@ ssize_t send_packet (interface, packet, raw, len, from, to, hto) - (unsigned char *)raw, len); - memcpy (buf + ibufp, raw, len); - -- /* For some reason, SOCK_PACKET sockets can't be connected, -- so we have to do a sentdo every time. */ -- memset (&sa, 0, sizeof sa); -- sa.spkt_family = AF_PACKET; -- strncpy ((char *)sa.spkt_device, -- (const char *)interface -> ifp, sizeof sa.spkt_device); -- sa.spkt_protocol = htons(ETH_P_IP); -- -- result = sendto (interface -> wfdesc, -- buf + fudge, ibufp + len - fudge, 0, -- (const struct sockaddr *)&sa, sizeof sa); -+ result = write (interface -> wfdesc, buf + fudge, ibufp + len - fudge); - if (result < 0) - log_error ("send_packet: %m"); - return result; -@@ -344,14 +365,35 @@ ssize_t receive_packet (interface, buf, len, from, hfrom) - { - int length = 0; - int offset = 0; -+ int nocsum = 0; - unsigned char ibuf [1536]; - unsigned bufix = 0; - unsigned paylen; -- -- length = read (interface -> rfdesc, ibuf, sizeof ibuf); -+ unsigned char cmsgbuf[CMSG_LEN(sizeof(struct tpacket_auxdata))]; -+ struct iovec iov = { -+ .iov_base = ibuf, -+ .iov_len = sizeof ibuf, -+ }; -+ struct msghdr msg = { -+ .msg_iov = &iov, -+ .msg_iovlen = 1, -+ .msg_control = cmsgbuf, -+ .msg_controllen = sizeof(cmsgbuf), -+ }; -+ struct cmsghdr *cmsg; -+ -+ length = recvmsg (interface -> rfdesc, &msg, 0); - if (length <= 0) - return length; - -+ for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) { -+ if (cmsg->cmsg_level == SOL_PACKET && -+ cmsg->cmsg_type == PACKET_AUXDATA) { -+ struct tpacket_auxdata *aux = (void *)CMSG_DATA(cmsg); -+ nocsum = aux->tp_status & TP_STATUS_CSUMNOTREADY; -+ } -+ } -+ - bufix = 0; - /* Decode the physical header... */ - offset = decode_hw_header (interface, ibuf, bufix, hfrom); -@@ -368,7 +410,7 @@ ssize_t receive_packet (interface, buf, len, from, hfrom) - - /* Decode the IP and UDP headers... */ - offset = decode_udp_ip_header (interface, ibuf, bufix, from, -- (unsigned)length, &paylen); -+ (unsigned)length, &paylen, nocsum); - - /* If the IP or UDP checksum was bad, skip the packet... */ - if (offset < 0) -diff --git a/common/nit.c b/common/nit.c -index a43bcf3..3fdef1d 100644 ---- a/common/nit.c -+++ b/common/nit.c -@@ -363,7 +363,7 @@ ssize_t receive_packet (interface, buf, len, from, hfrom) - - /* Decode the IP and UDP headers... */ - offset = decode_udp_ip_header (interface, ibuf, bufix, -- from, length, &paylen); -+ from, length, &paylen, 0); - - /* If the IP or UDP checksum was bad, skip the packet... */ - if (offset < 0) -diff --git a/common/packet.c b/common/packet.c -index 45e96e8..73e786d 100644 ---- a/common/packet.c -+++ b/common/packet.c -@@ -226,7 +226,7 @@ ssize_t - decode_udp_ip_header(struct interface_info *interface, - unsigned char *buf, unsigned bufix, - struct sockaddr_in *from, unsigned buflen, -- unsigned *rbuflen) -+ unsigned *rbuflen, int nocsum) - { - unsigned char *data; - struct ip ip; -@@ -337,7 +337,7 @@ decode_udp_ip_header(struct interface_info *interface, - 8, IPPROTO_UDP + ulen)))); - - udp_packets_seen++; -- if (usum && usum != sum) { -+ if (!nocsum && usum && usum != sum) { - udp_packets_bad_checksum++; - if (udp_packets_seen > 4 && - (udp_packets_seen / udp_packets_bad_checksum) < 2) { -diff --git a/common/upf.c b/common/upf.c -index de2129e..6a02077 100644 ---- a/common/upf.c -+++ b/common/upf.c -@@ -314,7 +314,7 @@ ssize_t receive_packet (interface, buf, len, from, hfrom) - - /* Decode the IP and UDP headers... */ - offset = decode_udp_ip_header (interface, ibuf, bufix, -- from, length, &paylen); -+ from, length, &paylen, 0); - - /* If the IP or UDP checksum was bad, skip the packet... */ - if (offset < 0) -diff --git a/includes/dhcpd.h b/includes/dhcpd.h -index 63d58e5..68262e9 100644 ---- a/includes/dhcpd.h -+++ b/includes/dhcpd.h -@@ -2788,7 +2788,7 @@ ssize_t decode_hw_header (struct interface_info *, unsigned char *, - unsigned, struct hardware *); - ssize_t decode_udp_ip_header (struct interface_info *, unsigned char *, - unsigned, struct sockaddr_in *, -- unsigned, unsigned *); -+ unsigned, unsigned *, int); - - /* ethernet.c */ - void assemble_ethernet_header (struct interface_info *, unsigned char *, --- -1.8.4 - diff --git a/0012-dhcp-4.2.2-quiet-dhclient.patch b/0010-dhcp-4.2.2-quiet-dhclient.patch similarity index 96% rename from 0012-dhcp-4.2.2-quiet-dhclient.patch rename to 0010-dhcp-4.2.2-quiet-dhclient.patch index fb65da4..d619812 100644 --- a/0012-dhcp-4.2.2-quiet-dhclient.patch +++ b/0010-dhcp-4.2.2-quiet-dhclient.patch @@ -2,6 +2,7 @@ From 61b4b713b630febf170c58c9ebbba2e01bb28eff Mon Sep 17 00:00:00 2001 From: Marius Tomaschewski Date: Thu, 18 Aug 2011 15:09:01 +0200 Subject: [PATCH] dhcp-4.2.2-quiet-dhclient +References: bnc#711420 --- client/dhclient.c | 3 +++ diff --git a/0014-Fixed-linux-interface-discovery-using-getifaddrs.patch b/0011-Fixed-linux-interface-discovery-using-getifaddrs.patch similarity index 98% rename from 0014-Fixed-linux-interface-discovery-using-getifaddrs.patch rename to 0011-Fixed-linux-interface-discovery-using-getifaddrs.patch index 7b88477..be45ce8 100644 --- a/0014-Fixed-linux-interface-discovery-using-getifaddrs.patch +++ b/0011-Fixed-linux-interface-discovery-using-getifaddrs.patch @@ -2,6 +2,7 @@ From bd50ec560d7bec064190e4d430c066e170732c0e Mon Sep 17 00:00:00 2001 From: Marius Tomaschewski Date: Tue, 27 Nov 2012 17:44:06 +0100 Subject: [PATCH] Fixed linux interface discovery using getifaddrs +References: bnc#791289,[ISC-Bugs #31992] Unlike dhcp 3.x, dhcp 4.x scans interfaces from /proc/net/dev, which provides only true interface names. When the address set diff --git a/0020-dhcp-4.2.x-chown-server-leases.bnc868253.patch b/0012-dhcp-4.2.x-chown-server-leases.bnc868253.patch similarity index 53% rename from 0020-dhcp-4.2.x-chown-server-leases.bnc868253.patch rename to 0012-dhcp-4.2.x-chown-server-leases.bnc868253.patch index 346705a..8e81885 100644 --- a/0020-dhcp-4.2.x-chown-server-leases.bnc868253.patch +++ b/0012-dhcp-4.2.x-chown-server-leases.bnc868253.patch @@ -1,10 +1,20 @@ -References: bnc#868253 +From 34e6100717f3de5a32ccb3234a949d017f789fdb Mon Sep 17 00:00:00 2001 +From: Marius Tomaschewski +Date: Tue, 10 Jun 2014 02:42:32 +0000 +Subject: [PATCH] dhcp-4.2.x-chown-server-leases.bnc868253 ---- dhcp-4.2.x/server/dhcpd.c -+++ dhcp-4.2.x/server/dhcpd.c 2014/06/10 01:59:13 -@@ -783,8 +783,19 @@ main(int argc, char **argv) { +Fixed dhcp server to chown leases to run user at start + +References: bnc#868253 +Signed-off-by: Marius Tomaschewski + +diff --git a/server/dhcpd.c b/server/dhcpd.c +index afef390..0f5c640 100644 +--- a/server/dhcpd.c ++++ b/server/dhcpd.c +@@ -770,8 +770,19 @@ main(int argc, char **argv) { } - + #if defined (PARANOIA) - /* change uid to the specified one */ + /* ensure, the leases db is owned by the run user/group */ @@ -23,3 +33,6 @@ References: bnc#868253 if (set_gid) { /* setgroups is done, OK */ if (setgroups (0, (void *)0)) +-- +2.1.4 + diff --git a/0013-dhcp-4.2.3-P1-dhclient-log-pid.patch b/0013-dhcp-4.2.3-P1-dhclient-log-pid.patch deleted file mode 100644 index dabb4cf..0000000 --- a/0013-dhcp-4.2.3-P1-dhclient-log-pid.patch +++ /dev/null @@ -1,25 +0,0 @@ -From d571408b5386b9bd72fd123b30298bdca8103b18 Mon Sep 17 00:00:00 2001 -From: Marius Tomaschewski -Date: Tue, 12 Jun 2012 10:21:57 +0200 -Subject: [PATCH] dhcp-4.2.3-P1-dhclient-log-pid - ---- - client/dhclient.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/client/dhclient.c b/client/dhclient.c -index 65d9eeb..8af0a42 100644 ---- a/client/dhclient.c -+++ b/client/dhclient.c -@@ -141,7 +141,7 @@ main(int argc, char **argv) { - else if (fd != -1) - close(fd); - -- openlog("dhclient", LOG_NDELAY, LOG_DAEMON); -+ openlog("dhclient", LOG_NDELAY | LOG_PID, LOG_DAEMON); - - #if !(defined(DEBUG) || defined(__CYGWIN32__)) - setlogmask(LOG_UPTO(LOG_INFO)); --- -1.8.4 - diff --git a/0024-dhcp-4.2.x-dhcpv6-decline-on-DAD-failure.872609.patch b/0013-dhcp-4.2.x-dhcpv6-decline-on-DAD-failure.872609.patch similarity index 100% rename from 0024-dhcp-4.2.x-dhcpv6-decline-on-DAD-failure.872609.patch rename to 0013-dhcp-4.2.x-dhcpv6-decline-on-DAD-failure.872609.patch diff --git a/0014-dhclient6-unsigned-lifetimes-for-script-bsc-926159.patch b/0014-dhclient6-unsigned-lifetimes-for-script-bsc-926159.patch new file mode 100644 index 0000000..ea1e275 --- /dev/null +++ b/0014-dhclient6-unsigned-lifetimes-for-script-bsc-926159.patch @@ -0,0 +1,84 @@ +From 9267da086dcbb39509eae05d1d60ba37596a3f89 Mon Sep 17 00:00:00 2001 +From: Marius Tomaschewski +Date: Wed, 29 Apr 2015 11:18:36 +0200 +Subject: dhclient6: unsigned lifetimes for script (bsc#926159) + +Address/IA lifetimes are all unsigned, don't turn into signed +(negative e.g. in infinite case) when passing them to scripts +and format timestamps as long to not break them on 64bit archs. + +References: bsc#926159 + +diff --git a/client/dhc6.c b/client/dhc6.c +index bec1c87..e4a85fc 100644 +--- a/client/dhc6.c ++++ b/client/dhc6.c +@@ -3877,8 +3877,8 @@ dhc6_marshall_values(const char *prefix, struct client_state *client, + client_envadd(client, prefix, + "ip6_type", "temporary"); + } +- client_envadd(client, prefix, "life_starts", "%d", +- (int)(addr->starts)); ++ client_envadd(client, prefix, "life_starts", "%ld", ++ (long)(addr->starts)); + client_envadd(client, prefix, "preferred_life", "%u", + addr->preferred_life); + client_envadd(client, prefix, "max_life", "%u", +@@ -3889,8 +3889,8 @@ dhc6_marshall_values(const char *prefix, struct client_state *client, + if (ia != NULL) { + client_envadd(client, prefix, "iaid", "%s", + print_hex_1(4, ia->iaid, 12)); +- client_envadd(client, prefix, "starts", "%d", +- (int)(ia->starts)); ++ client_envadd(client, prefix, "starts", "%ld", ++ (long)(ia->starts)); + client_envadd(client, prefix, "renew", "%u", ia->renew); + client_envadd(client, prefix, "rebind", "%u", ia->rebind); + } +diff --git a/client/dhclient.c b/client/dhclient.c +index 2eb28db..4d7394d 100644 +--- a/client/dhclient.c ++++ b/client/dhclient.c +@@ -3119,13 +3119,13 @@ write_client6_lease(struct client_state *client, struct dhc6_lease *lease, + return ISC_R_IOERROR; + + if (ia->ia_type != D6O_IA_TA) +- stat = fprintf(leaseFile, " starts %d;\n" ++ stat = fprintf(leaseFile, " starts %ld;\n" + " renew %u;\n" + " rebind %u;\n", +- (int)ia->starts, ia->renew, ia->rebind); ++ (long)ia->starts, ia->renew, ia->rebind); + else +- stat = fprintf(leaseFile, " starts %d;\n", +- (int)ia->starts); ++ stat = fprintf(leaseFile, " starts %ld;\n", ++ (long)ia->starts); + if (stat <= 0) + return ISC_R_IOERROR; + +@@ -3142,10 +3142,10 @@ write_client6_lease(struct client_state *client, struct dhc6_lease *lease, + if (stat <= 0) + return ISC_R_IOERROR; + +- stat = fprintf(leaseFile, " starts %d;\n" ++ stat = fprintf(leaseFile, " starts %ld;\n" + " preferred-life %u;\n" + " max-life %u;\n", +- (int)addr->starts, addr->preferred_life, ++ (long)addr->starts, addr->preferred_life, + addr->max_life); + if (stat <= 0) + return ISC_R_IOERROR; +@@ -3519,7 +3519,7 @@ void script_write_params (client, prefix, lease) + universes [i], + &es, client_option_envadd); + } +- client_envadd (client, prefix, "expiry", "%d", (int)(lease -> expiry)); ++ client_envadd (client, prefix, "expiry", "%ld", (long)(lease -> expiry)); + } + + /* +-- +2.1.4 + diff --git a/0015-Expose-next-server-DHCPv4-option-to-dhclient-script.patch b/0015-Expose-next-server-DHCPv4-option-to-dhclient-script.patch new file mode 100644 index 0000000..f2383b9 --- /dev/null +++ b/0015-Expose-next-server-DHCPv4-option-to-dhclient-script.patch @@ -0,0 +1,69 @@ +From 5fd4d0595760acd3e4c2524c9747dc5c0042e173 Mon Sep 17 00:00:00 2001 +From: Tomas Hozza +Date: Fri, 29 May 2015 13:56:58 +0200 +Subject: Expose next-server DHCPv4 option to dhclient script + +Currently dhclient does not exposes next-server option +to the dhclient script. this patch fixes this. + +Signed-off-by: Tomas Hozza +References: bsc#928390 + +diff --git a/client/dhclient.c b/client/dhclient.c +index 4d7394d..0c77ae2 100644 +--- a/client/dhclient.c ++++ b/client/dhclient.c +@@ -1104,7 +1104,7 @@ void state_selecting (cpp) + client -> state = S_REQUESTING; + + /* Bind to the address we received. */ +- bind_lease (client); ++ bind_lease (client, NULL); + return; + } + +@@ -1294,11 +1294,12 @@ void dhcpack (packet) + if (client -> new -> rebind < cur_time) + client -> new -> rebind = TIME_MAX; + +- bind_lease (client); ++ bind_lease (client, &packet -> raw -> siaddr); + } + +-void bind_lease (client) ++void bind_lease (client, siaddr) + struct client_state *client; ++ struct in_addr *siaddr; + { + struct timeval tv; + +@@ -1318,6 +1319,13 @@ void bind_lease (client) + if (client->alias) + script_write_params(client, "alias_", client->alias); + ++ if (siaddr) { ++ char buf[INET_ADDRSTRLEN]; ++ ++ if (inet_ntop (AF_INET, (void *) siaddr, buf, sizeof (buf))) ++ client_envadd (client, "new_", "next_server", "%s", buf); ++ } ++ + /* If the BOUND/RENEW code detects another machine using the + offered address, it exits nonzero. We need to send a + DHCPDECLINE and toss the lease. */ +diff --git a/includes/dhcpd.h b/includes/dhcpd.h +index 86d0afe..f0f4b20 100644 +--- a/includes/dhcpd.h ++++ b/includes/dhcpd.h +@@ -2891,7 +2891,7 @@ void state_bound (void *); + void state_stop (void *); + void state_panic (void *); + +-void bind_lease (struct client_state *); ++void bind_lease (struct client_state *, struct in_addr *); + + void make_client_options (struct client_state *, + struct client_lease *, u_int8_t *, +-- +2.1.4 + diff --git a/0015-Ignore-SIGPIPE-to-not-die-in-socket-code.patch b/0015-Ignore-SIGPIPE-to-not-die-in-socket-code.patch deleted file mode 100644 index db0b792..0000000 --- a/0015-Ignore-SIGPIPE-to-not-die-in-socket-code.patch +++ /dev/null @@ -1,70 +0,0 @@ -From d9b443ef38da92bd325f5118a2a6ddc21fae098e Mon Sep 17 00:00:00 2001 -From: Marius Tomaschewski -Date: Thu, 20 Dec 2012 10:25:53 +0100 -Subject: [PATCH] Ignore SIGPIPE to not die in socket code - -Installed SIG_IGN handler for SIGPIPE to not die before -the errno==EPIPE checks in the socket code are reached. -Unlike isc_app_start(), the isc_app_ctxstart() used by -dhcp, does not set any signal handlers. - -Reported upstream as [ISC-Bugs #32222], IMO regression -to [ISC-Bugs #22269] as the SO_NOSIGPIPE socket option -isn't available e.g. on Linux. ---- - omapip/isclib.c | 32 +++++++++++++++++++++++++++++++- - 1 file changed, 31 insertions(+), 1 deletion(-) - -diff --git a/omapip/isclib.c b/omapip/isclib.c -index afab262..9b7ff5f 100644 ---- a/omapip/isclib.c -+++ b/omapip/isclib.c -@@ -69,6 +69,23 @@ isclib_cleanup(void) - return; - } - -+static isc_result_t -+handle_signal(int sig, void (*handler)(int)) { -+ struct sigaction sa; -+ -+ memset(&sa, 0, sizeof(sa)); -+ sa.sa_handler = handler; -+ -+ if (sigfillset(&sa.sa_mask) != 0 || -+ sigaction(sig, &sa, NULL) < 0) { -+ log_error("handle_signal() %d setup: %s", -+ sig, strerror(errno)); -+ return (ISC_R_UNEXPECTED); -+ } -+ -+ return (ISC_R_SUCCESS); -+} -+ - isc_result_t - dhcp_context_create(void) { - isc_result_t result; -@@ -106,7 +123,20 @@ dhcp_context_create(void) { - - result = isc_app_ctxstart(dhcp_gbl_ctx.actx); - if (result != ISC_R_SUCCESS) -- return (result); -+ goto cleanup; -+ -+ /* -+ * Always ignore SIGPIPE. -+ * Otherwise we will die before the errno == EPIPE -+ * checks in the socket code are reached. -+ * -+ * Note: unlike isc_app_start(), isc_app_ctxstart() -+ * does not set any signal handlers. -+ */ -+ result = handle_signal(SIGPIPE, SIG_IGN); -+ if (result != ISC_R_SUCCESS) -+ goto cleanup; -+ - dhcp_gbl_ctx.actx_started = ISC_TRUE; - - result = isc_taskmgr_createinctx(dhcp_gbl_ctx.mctx, --- -1.8.4 - diff --git a/0016-infiniband-support.patch b/0016-infiniband-support.patch new file mode 100644 index 0000000..ac2b7a0 --- /dev/null +++ b/0016-infiniband-support.patch @@ -0,0 +1,1085 @@ +References: bnc#870535,bsc#909189,bsc#910984 + +From 92250da05c2e4e3f1f60d627b52fe3f4f14828d3 Mon Sep 17 00:00:00 2001 +From: Marius Tomaschewski +Date: Mon, 14 Sep 2015 13:42:34 +0200 +Subject: [PATCH] infiniband-support + +Squashed rework based on the following commits: + +commit 8f5918fa4319fc8173ca6e75d6e2ab8c379e980d +Author: Marius Tomaschewski +Date: Mon Sep 14 12:26:12 2015 +0200 + + dhcp 4.3.3 ip over ib support fixes (bsc#910984) + + - verify client-identifier in responses as defined by RFC6864 + - generate RFC4361 client-identifier for infiniband as required by + RFC4390; config file can still override it using send statement. + - fixed to set the ib hwaddr and guard copying/compares to chaddr; + it is used for client-identifier, improved xid and other things. + - fixed lpf send_packet to not break unicast on fallback socket. + +commit 3173fd96fe8873f7924f8b5c3f2a6a34ebe1c90c +Author: root +Date: Tue Mar 25 23:30:18 2014 +0200 + + dhcp 4.3.2 improved xid + + References: bnc#870535 + +commit 7e27105baa2a86469efa17fe70667baa8bcc627f +Author: Jiri Slaby +Date: Wed Dec 10 13:48:03 2014 +0100 + + dhcp-4.2.x-handle-ifa_addr-NULL.909189 + + Fix to not crash in interface discovery when the interface + address is NULL. Bug has been introduced by the infiniband + support patch (bsc#870535). + + References: bsc#909189,bnc#870535 + +commit 7818a340f84c0fe3c750baa721fb4221e2e2d443 +Author: root +Date: Tue Mar 25 23:15:58 2014 +0200 + + dhcp 4.3.2 lpf ip over ib support + + References: bnc#870535 + +diff --git a/client/dhclient.c b/client/dhclient.c +index 0c77ae2..b438629 100644 +--- a/client/dhclient.c ++++ b/client/dhclient.c +@@ -104,6 +104,40 @@ static int check_option_values(struct universe *universe, unsigned int opt, + static void dhclient_ddns_cb_free(dhcp_ddns_cb_t *ddns_cb, + char* file, int line); + ++static void form_interface_duid(struct data_string *duid, struct interface_info *ip, const char *file, int line); ++ ++static int check_client_identifier(struct option_state *packet_options, struct option_state *client_options) ++{ ++ struct option_cache *client_oc; ++ struct option_cache *packet_oc; ++ ++ /* RFC6864 check: ++ * ++ * When a client receives a DHCP message containing a 'client ++ * identifier' option, the client MUST compare that client ++ * identifier to the one it is configured to send. ++ * If the two client identifiers do not match, the client MUST ++ * silently discard the message. ++ */ ++ ++ /* no identifier received: not RFC6864 server ... */ ++ if (!packet_options || !(packet_oc = lookup_option(&dhcp_universe, packet_options, ++ DHO_DHCP_CLIENT_IDENTIFIER))) ++ return 1; ++ ++ /* client does not remember them in some cases ... */ ++ if (!client_options || !(client_oc = lookup_option(&dhcp_universe, client_options, ++ DHO_DHCP_CLIENT_IDENTIFIER))) ++ return 1; ++ ++ /* when we've sent one, the identifiers MUST match */ ++ if (client_oc->data.len != packet_oc->data.len || ++ memcmp(client_oc->data.data, packet_oc->data.data, client_oc->data.len)) ++ return -1; ++ ++ return 0; ++} ++ + #ifndef UNIT_TEST + int + main(int argc, char **argv) { +@@ -635,6 +669,26 @@ main(int argc, char **argv) { + } + } + ++ /* We create a backup seed before rediscovering interfaces in order to ++ have a seed built using all of the available interfaces ++ It's interesting if required interfaces doesn't let us defined ++ a really unique seed due to a lack of valid HW addr later ++ (this is the case with DHCP over IB) ++ We only use the last device as using a sum could broke the ++ uniqueness of the seed among multiple nodes ++ */ ++ unsigned backup_seed = 0; ++ for (ip = interfaces; ip; ip = ip -> next) { ++ int junk; ++ if ( ip -> hw_address.hlen <= sizeof seed ) ++ continue; ++ memcpy (&junk, ++ &ip -> hw_address.hbuf [ip -> hw_address.hlen - ++ sizeof seed], sizeof seed); ++ backup_seed = junk; ++ } ++ ++ + /* At this point, all the interfaces that the script thinks + are relevant should be running, so now we once again call + discover_interfaces(), and this time ask it to actually set +@@ -649,19 +703,42 @@ main(int argc, char **argv) { + Not much entropy, but we're booting, so we're not likely to + find anything better. */ + seed = 0; ++ int seed_flag = 0; + for (ip = interfaces; ip; ip = ip->next) { + int junk; ++ if (ip->hw_address.hlen <= sizeof seed) ++ continue; + memcpy(&junk, + &ip->hw_address.hbuf[ip->hw_address.hlen - + sizeof seed], sizeof seed); + seed += junk; ++ seed_flag = 1; + } +- srandom(seed + cur_time + (unsigned)getpid()); ++ if ( seed_flag == 0 ) { ++ if ( backup_seed != 0 ) { ++ seed = backup_seed; ++ log_info ("xid: rand init seed (0x%x) built using all" ++ " available interfaces",seed); ++ } ++ else { ++ seed = cur_time^((unsigned) gethostid()) ; ++ log_info ("xid: warning: no netdev with useable HWADDR found" ++ " for seed's uniqueness enforcement"); ++ log_info ("xid: rand init seed (0x%x) built using gethostid", ++ seed); ++ } ++ /* we only use seed and no current time as a broadcast reply */ ++ /* will certainly be used by the hwaddrless interface */ ++ srandom(seed); ++ } ++ else ++ srandom(seed + cur_time + (unsigned)getpid()); + + + /* + * Establish a default DUID. We always do so for v6 and +- * do so if desired for v4 via the -D or -i options ++ * do so if desired for v4 via the -D or -i options or ++ * when an infiniband interface is involved. + */ + if ((local_family == AF_INET6) || + ((local_family == AF_INET) && (duid_v4 == 1))) { +@@ -672,6 +749,20 @@ main(int argc, char **argv) { + form_duid(&default_duid, MDL); + write_duid(&default_duid); + } ++ } else { ++ for (ip = interfaces; ip; ip = ip->next) { ++ if (!ip->client || ip->hw_address.hbuf[0] != HTYPE_INFINIBAND) ++ continue; ++ ++ if (default_duid.len == 0) { ++ if (default_duid.buffer != NULL) ++ data_string_forget(&default_duid, MDL); ++ ++ form_duid(&default_duid, MDL); ++ write_duid(&default_duid); ++ break; ++ } ++ } + } + + /* Start a configuration state machine for each interface. */ +@@ -1143,15 +1234,22 @@ void dhcpack (packet) + if (client -> xid == packet -> raw -> xid) + break; + } +- if (!client || +- (packet -> interface -> hw_address.hlen - 1 != +- packet -> raw -> hlen) || +- (memcmp (&packet -> interface -> hw_address.hbuf [1], +- packet -> raw -> chaddr, packet -> raw -> hlen))) { ++ ++ if (!client || (packet -> raw -> hlen && ++ ((packet -> interface -> hw_address.hlen - 1 != ++ packet -> raw -> hlen) || ++ (memcmp (&packet -> interface -> hw_address.hbuf [1], ++ packet -> raw -> chaddr, packet -> raw -> hlen))))) { + #if defined (DEBUG) + log_debug ("DHCPACK in wrong transaction."); + #endif + return; ++ } else ++ if (check_client_identifier(packet->options, client->sent_options) < 0) { ++#if defined (DEBUG) ++ log_debug ("response client identifier does not match ours"); ++#endif ++ return; + } + + if (client -> state != S_REBOOTING && +@@ -1164,7 +1262,7 @@ void dhcpack (packet) + return; + } + +- log_info ("DHCPACK from %s", piaddr (packet -> client_addr)); ++ log_info ("DHCPACK from %s (xid=0x%x)", piaddr (packet -> client_addr), client -> xid); + + lease = packet_to_lease (packet, client); + if (!lease) { +@@ -1629,15 +1727,21 @@ void dhcpoffer (packet) + /* If we're not receptive to an offer right now, or if the offer + has an unrecognizable transaction id, then just drop it. */ + if (!client || +- client -> state != S_SELECTING || +- (packet -> interface -> hw_address.hlen - 1 != +- packet -> raw -> hlen) || +- (memcmp (&packet -> interface -> hw_address.hbuf [1], +- packet -> raw -> chaddr, packet -> raw -> hlen))) { ++ client -> state != S_SELECTING || (packet -> raw -> hlen && ++ ((packet -> interface -> hw_address.hlen - 1 != ++ packet -> raw -> hlen) || ++ (memcmp (&packet -> interface -> hw_address.hbuf [1], ++ packet -> raw -> chaddr, packet -> raw -> hlen))))) { + #if defined (DEBUG) + log_debug ("%s in wrong transaction.", name); + #endif + return; ++ } else ++ if (check_client_identifier(packet->options, client->sent_options) < 0) { ++#if defined (DEBUG) ++ log_debug ("response client identifier does not match ours"); ++#endif ++ return; + } + + sprintf (obuf, "%s from %s", name, piaddr (packet -> client_addr)); +@@ -1875,11 +1979,11 @@ void dhcpnak (packet) + + /* If we're not receptive to an offer right now, or if the offer + has an unrecognizable transaction id, then just drop it. */ +- if (!client || +- (packet -> interface -> hw_address.hlen - 1 != +- packet -> raw -> hlen) || +- (memcmp (&packet -> interface -> hw_address.hbuf [1], +- packet -> raw -> chaddr, packet -> raw -> hlen))) { ++ if (!client || (packet -> raw -> hlen && ++ ((packet -> interface -> hw_address.hlen - 1 != ++ packet -> raw -> hlen) || ++ (memcmp (&packet -> interface -> hw_address.hbuf [1], ++ packet -> raw -> chaddr, packet -> raw -> hlen))))) { + #if defined (DEBUG) + log_debug ("DHCPNAK in wrong transaction."); + #endif +@@ -1894,9 +1998,15 @@ void dhcpnak (packet) + log_debug ("DHCPNAK in wrong state."); + #endif + return; ++ } else ++ if (check_client_identifier(packet->options, client->sent_options) < 0) { ++#if defined (DEBUG) ++ log_debug ("response client identifier does not match ours"); ++#endif ++ return; + } + +- log_info ("DHCPNAK from %s", piaddr (packet -> client_addr)); ++ log_info ("DHCPNAK from %s (xid=0x%x)", piaddr (packet -> client_addr), client -> xid); + + if (!client -> active) { + #if defined (DEBUG) +@@ -2023,10 +2133,10 @@ void send_discover (cpp) + client -> packet.secs = htons (65535); + client -> secs = client -> packet.secs; + +- log_info ("DHCPDISCOVER on %s to %s port %d interval %ld", +- client -> name ? client -> name : client -> interface -> name, +- inet_ntoa (sockaddr_broadcast.sin_addr), +- ntohs (sockaddr_broadcast.sin_port), (long)(client -> interval)); ++ log_info ("DHCPDISCOVER on %s to %s port %d interval %ld (xid=0x%x)", ++ client -> name ? client -> name : client -> interface -> name, ++ inet_ntoa (sockaddr_broadcast.sin_addr), ++ ntohs (sockaddr_broadcast.sin_port), (long)(client -> interval), client -> xid); + + /* Send out a packet. */ + result = send_packet(client->interface, NULL, &client->packet, +@@ -2295,10 +2405,10 @@ void send_request (cpp) + client -> packet.secs = htons (65535); + } + +- log_info ("DHCPREQUEST on %s to %s port %d", ++ log_info ("DHCPREQUEST on %s to %s port %d (xid=0x%x)", + client -> name ? client -> name : client -> interface -> name, + inet_ntoa (destination.sin_addr), +- ntohs (destination.sin_port)); ++ ntohs (destination.sin_port), client -> xid); + + if (destination.sin_addr.s_addr != INADDR_BROADCAST && + fallback_interface) { +@@ -2338,10 +2448,10 @@ void send_decline (cpp) + + int result; + +- log_info ("DHCPDECLINE on %s to %s port %d", ++ log_info ("DHCPDECLINE on %s to %s port %d (xid=0x%x)", + client->name ? client->name : client->interface->name, + inet_ntoa(sockaddr_broadcast.sin_addr), +- ntohs(sockaddr_broadcast.sin_port)); ++ ntohs (sockaddr_broadcast.sin_port), client -> xid); + + /* Send out a packet. */ + result = send_packet(client->interface, NULL, &client->packet, +@@ -2384,10 +2494,10 @@ void send_release (cpp) + return; + } + +- log_info ("DHCPRELEASE on %s to %s port %d", ++ log_info ("DHCPRELEASE on %s to %s port %d (xid=0x%x)", + client -> name ? client -> name : client -> interface -> name, + inet_ntoa (destination.sin_addr), +- ntohs (destination.sin_port)); ++ ntohs (destination.sin_port), client -> xid); + + if (fallback_interface) { + result = send_packet(fallback_interface, NULL, &client->packet, +@@ -2507,10 +2617,17 @@ make_client_options(struct client_state *client, struct client_lease *lease, + * This can be overridden by including a client id in the configuration + * file. + */ +- if (duid_v4 == 1) { ++ if (duid_v4 == 1 || client->interface->hw_address.hbuf[0] == HTYPE_INFINIBAND) { + struct data_string client_identifier; + int hw_idx, hw_len; + ++ if (default_duid.len == 0) { ++ if (default_duid.buffer != NULL) ++ data_string_forget(&default_duid, MDL); ++ ++ form_interface_duid(&default_duid, client->interface, MDL); ++ } ++ + memset(&client_identifier, 0, sizeof(client_identifier)); + client_identifier.len = 1 + 4 + default_duid.len; + if (!buffer_allocate(&client_identifier.buffer, +@@ -2600,12 +2717,13 @@ void make_discover (client, lease) + + client -> packet.op = BOOTREQUEST; + client -> packet.htype = client -> interface -> hw_address.hbuf [0]; +- client -> packet.hlen = client -> interface -> hw_address.hlen - 1; ++ if (client -> interface -> hw_address.hlen - 1 <= sizeof(client -> packet.chaddr)) ++ client -> packet.hlen = client -> interface -> hw_address.hlen - 1; + client -> packet.hops = 0; + client -> packet.xid = random (); + client -> packet.secs = 0; /* filled in by send_discover. */ + +- if (can_receive_unicast_unconfigured (client -> interface)) ++ if (can_receive_unicast_unconfigured (client -> interface) && client -> packet.hlen) + client -> packet.flags = 0; + else + client -> packet.flags = htons (BOOTP_BROADCAST); +@@ -2617,7 +2735,7 @@ void make_discover (client, lease) + memset (&(client -> packet.siaddr), + 0, sizeof client -> packet.siaddr); + client -> packet.giaddr = giaddr; +- if (client -> interface -> hw_address.hlen > 0) ++ if (client -> interface -> hw_address.hlen > 1 && client -> packet.hlen) + memcpy (client -> packet.chaddr, + &client -> interface -> hw_address.hbuf [1], + (unsigned)(client -> interface -> hw_address.hlen - 1)); +@@ -2673,7 +2791,8 @@ void make_request (client, lease) + + client -> packet.op = BOOTREQUEST; + client -> packet.htype = client -> interface -> hw_address.hbuf [0]; +- client -> packet.hlen = client -> interface -> hw_address.hlen - 1; ++ if (client -> interface -> hw_address.hlen - 1 <= sizeof(client -> packet.chaddr)) ++ client -> packet.hlen = client -> interface -> hw_address.hlen - 1; + client -> packet.hops = 0; + client -> packet.xid = client -> xid; + client -> packet.secs = 0; /* Filled in by send_request. */ +@@ -2705,7 +2824,7 @@ void make_request (client, lease) + else + memset (&client -> packet.giaddr, 0, + sizeof client -> packet.giaddr); +- if (client -> interface -> hw_address.hlen > 0) ++ if (client -> interface -> hw_address.hlen > 1 && client -> packet.hlen) + memcpy (client -> packet.chaddr, + &client -> interface -> hw_address.hbuf [1], + (unsigned)(client -> interface -> hw_address.hlen - 1)); +@@ -2747,7 +2866,8 @@ void make_decline (client, lease) + + client -> packet.op = BOOTREQUEST; + client -> packet.htype = client -> interface -> hw_address.hbuf [0]; +- client -> packet.hlen = client -> interface -> hw_address.hlen - 1; ++ if (client -> interface -> hw_address.hlen - 1 <= sizeof(client -> packet.chaddr)) ++ client -> packet.hlen = client -> interface -> hw_address.hlen - 1; + client -> packet.hops = 0; + client -> packet.xid = client -> xid; + client -> packet.secs = 0; /* Filled in by send_request. */ +@@ -2764,9 +2884,10 @@ void make_decline (client, lease) + memset (&client -> packet.siaddr, 0, + sizeof client -> packet.siaddr); + client -> packet.giaddr = giaddr; +- memcpy (client -> packet.chaddr, +- &client -> interface -> hw_address.hbuf [1], +- client -> interface -> hw_address.hlen); ++ if (client -> interface -> hw_address.hlen > 1 && client -> packet.hlen) ++ memcpy (client -> packet.chaddr, ++ &client -> interface -> hw_address.hbuf [1], ++ client -> interface -> hw_address.hlen - 1); + + #ifdef DEBUG_PACKET + dump_raw ((unsigned char *)&client -> packet, client -> packet_length); +@@ -2808,7 +2929,8 @@ void make_release (client, lease) + + client -> packet.op = BOOTREQUEST; + client -> packet.htype = client -> interface -> hw_address.hbuf [0]; +- client -> packet.hlen = client -> interface -> hw_address.hlen - 1; ++ if (client -> interface -> hw_address.hlen - 1 <= sizeof(client -> packet.chaddr)) ++ client -> packet.hlen = client -> interface -> hw_address.hlen - 1; + client -> packet.hops = 0; + client -> packet.xid = random (); + client -> packet.secs = 0; +@@ -2820,9 +2942,10 @@ void make_release (client, lease) + memset (&client -> packet.siaddr, 0, + sizeof client -> packet.siaddr); + client -> packet.giaddr = giaddr; +- memcpy (client -> packet.chaddr, +- &client -> interface -> hw_address.hbuf [1], +- client -> interface -> hw_address.hlen); ++ if (client -> interface -> hw_address.hlen > 1 && client -> packet.hlen) ++ memcpy (client -> packet.chaddr, ++ &client -> interface -> hw_address.hbuf [1], ++ client -> interface -> hw_address.hlen); + + #ifdef DEBUG_PACKET + dump_raw ((unsigned char *)&client -> packet, client -> packet_length); +@@ -2975,17 +3098,13 @@ write_options(struct client_state *client, struct option_state *options, + * is not how it is intended. Upcoming rearchitecting the client should + * address this "one daemon model." + */ +-void +-form_duid(struct data_string *duid, const char *file, int line) ++static void ++form_interface_duid(struct data_string *duid, struct interface_info *ip, const char *file, int line) + { +- struct interface_info *ip; + int len; + char *str; + +- /* For now, just use the first interface on the list. */ +- ip = interfaces; +- +- if (ip == NULL) ++ if (ip == NULL || duid == NULL) + log_fatal("Impossible condition at %s:%d.", MDL); + + if ((ip->hw_address.hlen == 0) || +@@ -3033,6 +3152,13 @@ form_duid(struct data_string *duid, const char *file, int line) + } + } + ++void ++form_duid(struct data_string *duid, const char *file, int line) ++{ ++ /* For now, just use the first interface on the list. */ ++ form_interface_duid(duid, interfaces, file, line); ++} ++ + /* Write the default DUID to the lease store. */ + static isc_result_t + write_duid(struct data_string *duid) +@@ -4368,7 +4494,8 @@ client_dns_update(struct client_state *client, dhcp_ddns_cb_t *ddns_cb) + NULL, client, + client->sent_options, NULL, + &global_scope, oc, MDL)) { +- if ((std_dhcid == 1) && (duid_v4 == 1) && ++ if ((std_dhcid == 1) && (duid_v4 == 1 || ++ client->interface->hw_address.hbuf[0] == HTYPE_INFINIBAND) && + (client_identifier.data[0] == 255)) { + /* + * This appears to be an embedded DUID, +diff --git a/common/bpf.c b/common/bpf.c +index df9facc..23d416a 100644 +--- a/common/bpf.c ++++ b/common/bpf.c +@@ -117,7 +117,7 @@ int if_register_bpf (info) + log_fatal ("Can't attach interface %s to bpf device %s: %m", + info -> name, filename); + +- get_hw_addr(info->name, &info->hw_address); ++ get_hw_addr(info); + + return sock; + } +@@ -199,11 +199,44 @@ struct bpf_insn dhcp_bpf_filter [] = { + BPF_STMT(BPF_RET+BPF_K, 0), + }; + ++/* Packet filter program for DHCP over Infiniband. ++ * It is a generic UDP in IP packet filter (initialized to port 67 in [6].k). ++ * ++ * XXX ++ * Changes to the filter program may require changes to the constant offsets ++ * used in lpf_gen_filter_setup to patch the port in the BPF program! ++ * XXX ++ */ ++struct bpf_insn dhcp_ib_bpf_filter [] = { ++ /* Make sure it's a UDP packet... */ ++ BPF_STMT(BPF_LD + BPF_B + BPF_ABS, 9), ++ BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, IPPROTO_UDP, 0, 6), ++ ++ /* Make sure this isn't a fragment... */ ++ BPF_STMT(BPF_LD + BPF_H + BPF_ABS, 6), ++ BPF_JUMP(BPF_JMP + BPF_JSET + BPF_K, 0x1fff, 4, 0), ++ ++ /* Get the IP header length... */ ++ BPF_STMT(BPF_LDX + BPF_B + BPF_MSH, 0), ++ ++ /* Make sure it's to the right port... */ ++ BPF_STMT(BPF_LD + BPF_H + BPF_IND, 2), ++ BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, 67, 0, 1), ++ ++ /* If we passed all the tests, ask for the whole packet. */ ++ BPF_STMT(BPF_RET + BPF_K, (u_int)-1), ++ ++ /* Otherwise, drop it. */ ++ BPF_STMT(BPF_RET + BPF_K, 0), ++}; ++ + #if defined (DEC_FDDI) + struct bpf_insn *bpf_fddi_filter; + #endif + + int dhcp_bpf_filter_len = sizeof dhcp_bpf_filter / sizeof (struct bpf_insn); ++int dhcp_ib_bpf_filter_len = sizeof dhcp_ib_bpf_filter / sizeof (struct bpf_insn); ++ + #if defined (HAVE_TR_SUPPORT) + struct bpf_insn dhcp_bpf_tr_filter [] = { + /* accept all token ring packets due to variable length header */ +@@ -550,7 +583,9 @@ void maybe_setup_fallback () + + #if defined(USE_BPF_RECEIVE) || defined(USE_BPF_HWADDR) + void +-get_hw_addr(const char *name, struct hardware *hw) { ++get_hw_addr(struct interface_info *info) { ++ const char *name = info->name; ++ struct hardware *hw = &info->hw_address; + struct ifaddrs *ifa; + struct ifaddrs *p; + struct sockaddr_dl *sa; +diff --git a/common/dlpi.c b/common/dlpi.c +index 944f21c..5cc2f3b 100644 +--- a/common/dlpi.c ++++ b/common/dlpi.c +@@ -1330,7 +1330,9 @@ void maybe_setup_fallback () + #endif /* USE_DLPI_SEND */ + + void +-get_hw_addr(const char *name, struct hardware *hw) { ++get_hw_addr(struct interface_info *info) { ++ const char *name = info->name; ++ struct hardware *hw = &info->hw_address; + int sock, unit; + long buf[DLPI_MAXDLBUF]; + union DL_primitives *dlp; +diff --git a/common/lpf.c b/common/lpf.c +index 8582f31..745d3c0 100644 +--- a/common/lpf.c ++++ b/common/lpf.c +@@ -47,12 +47,22 @@ + #include + #include + #include ++#include + #endif + + #if defined (USE_LPF_SEND) || defined (USE_LPF_RECEIVE) + /* Reinitializes the specified interface after an address change. This + is not required for packet-filter APIs. */ + ++/* Default broadcast address for IPoIB */ ++static unsigned char default_ib_bcast_addr[20] = { ++ 0x00, 0xff, 0xff, 0xff, ++ 0xff, 0x12, 0x40, 0x1b, ++ 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, ++ 0xff, 0xff, 0xff, 0xff ++}; ++ + #ifdef USE_LPF_SEND + void if_reinitialize_send (info) + struct interface_info *info; +@@ -80,10 +90,25 @@ int if_register_lpf (info) + struct sockaddr common; + } sa; + struct ifreq ifr; ++ int type; ++ int protocol; + + /* Make an LPF socket. */ +- if ((sock = socket(PF_PACKET, SOCK_RAW, +- htons((short)ETH_P_ALL))) < 0) { ++ get_hw_addr(info); ++ ++ if (info->hw_address.hbuf[0] == HTYPE_INFINIBAND) { ++ /* ++ * Infiniband provides a 4-octet encapsulation ++ * header [08 00 00 00] only, so just omit it. ++ */ ++ type = SOCK_DGRAM; ++ protocol = ETHERTYPE_IP; ++ } else { ++ type = SOCK_RAW; ++ protocol = ETH_P_ALL; ++ } ++ ++ if ((sock = socket(PF_PACKET, type, htons((short)protocol))) < 0) { + if (errno == ENOPROTOOPT || errno == EPROTONOSUPPORT || + errno == ESOCKTNOSUPPORT || errno == EPFNOSUPPORT || + errno == EAFNOSUPPORT || errno == EINVAL) { +@@ -107,6 +132,7 @@ int if_register_lpf (info) + memset (&sa, 0, sizeof sa); + sa.ll.sll_family = AF_PACKET; + sa.ll.sll_ifindex = ifr.ifr_ifindex; ++ sa.ll.sll_protocol = htons(protocol); + if (bind (sock, &sa.common, sizeof sa)) { + if (errno == ENOPROTOOPT || errno == EPROTONOSUPPORT || + errno == ESOCKTNOSUPPORT || errno == EPFNOSUPPORT || +@@ -122,8 +148,6 @@ int if_register_lpf (info) + + } + +- get_hw_addr(info->name, &info->hw_address); +- + return sock; + } + #endif /* USE_LPF_SEND || USE_LPF_RECEIVE */ +@@ -178,6 +202,8 @@ void if_deregister_send (info) + in bpf includes... */ + extern struct sock_filter dhcp_bpf_filter []; + extern int dhcp_bpf_filter_len; ++extern struct sock_filter dhcp_ib_bpf_filter []; ++extern int dhcp_ib_bpf_filter_len; + + #if defined (HAVE_TR_SUPPORT) + extern struct sock_filter dhcp_bpf_tr_filter []; +@@ -185,6 +211,8 @@ extern int dhcp_bpf_tr_filter_len; + static void lpf_tr_filter_setup (struct interface_info *); + #endif + ++static void lpf_ib_filter_setup (struct interface_info *); ++ + static void lpf_gen_filter_setup (struct interface_info *); + + void if_register_receive (info) +@@ -206,12 +234,14 @@ void if_register_receive (info) + } + #endif + +- + #if defined (HAVE_TR_SUPPORT) + if (info -> hw_address.hbuf [0] == HTYPE_IEEE802) + lpf_tr_filter_setup (info); + else + #endif ++ if (info -> hw_address.hbuf [0] == HTYPE_INFINIBAND) ++ lpf_ib_filter_setup (info); ++ else + lpf_gen_filter_setup (info); + + if (!quiet_interface_discovery) +@@ -276,6 +306,38 @@ static void lpf_gen_filter_setup (info) + } + } + ++static void lpf_ib_filter_setup (info) ++ struct interface_info *info; ++{ ++ struct sock_fprog p; ++ ++ memset(&p, 0, sizeof(p)); ++ ++ /* Set up the bpf filter program structure */ ++ p.len = dhcp_ib_bpf_filter_len; ++ p.filter = dhcp_ib_bpf_filter; ++ ++ /* Patch the server port into the LPF program... ++ XXX changes to filter program may require changes ++ to the insn number(s) used below! XXX */ ++ dhcp_ib_bpf_filter [6].k = ntohs ((short)local_port); ++ ++ if (setsockopt (info -> rfdesc, SOL_SOCKET, SO_ATTACH_FILTER, &p, ++ sizeof p) < 0) { ++ if (errno == ENOPROTOOPT || errno == EPROTONOSUPPORT || ++ errno == ESOCKTNOSUPPORT || errno == EPFNOSUPPORT || ++ errno == EAFNOSUPPORT) { ++ log_error ("socket: %m - make sure"); ++ log_error ("CONFIG_PACKET (Packet socket) %s", ++ "and CONFIG_FILTER"); ++ log_error ("(Socket Filtering) are enabled %s", ++ "in your kernel"); ++ log_fatal ("configuration!"); ++ } ++ log_fatal ("Can't install packet filter program: %m"); ++ } ++} ++ + #if defined (HAVE_TR_SUPPORT) + static void lpf_tr_filter_setup (info) + struct interface_info *info; +@@ -315,6 +377,54 @@ static void lpf_tr_filter_setup (info) + #endif /* USE_LPF_RECEIVE */ + + #ifdef USE_LPF_SEND ++ssize_t send_packet_ib(interface, packet, raw, len, from, to, hto) ++ struct interface_info *interface; ++ struct packet *packet; ++ struct dhcp_packet *raw; ++ size_t len; ++ struct in_addr from; ++ struct sockaddr_in *to; ++ struct hardware *hto; ++{ ++ unsigned ibufp = 0; ++ double ih [1536 / sizeof (double)]; ++ unsigned char *buf = (unsigned char *)ih; ++ ssize_t result; ++ ++ union sockunion { ++ struct sockaddr sa; ++ struct sockaddr_ll sll; ++ struct sockaddr_storage ss; ++ } su; ++ ++ assemble_udp_ip_header (interface, buf, &ibufp, from.s_addr, ++ to->sin_addr.s_addr, to->sin_port, ++ (unsigned char *)raw, len); ++ memcpy (buf + ibufp, raw, len); ++ ++ memset(&su, 0, sizeof(su)); ++ su.sll.sll_family = AF_PACKET; ++ su.sll.sll_protocol = htons(ETHERTYPE_IP); ++ ++ if (!(su.sll.sll_ifindex = if_nametoindex(interface->name))) { ++ errno = ENOENT; ++ log_error ("send_packet_ib: %m - failed to get if index"); ++ return -1; ++ } ++ ++ su.sll.sll_hatype = htons(HTYPE_INFINIBAND); ++ su.sll.sll_halen = sizeof(interface->bcast_addr); ++ memcpy(&su.sll.sll_addr, interface->bcast_addr, 20); ++ ++ result = sendto(interface->wfdesc, buf, ibufp + len, 0, ++ &su.sa, sizeof(su)); ++ ++ if (result < 0) ++ log_error ("send_packet_ib: %m"); ++ ++ return result; ++} ++ + ssize_t send_packet (interface, packet, raw, len, from, to, hto) + struct interface_info *interface; + struct packet *packet; +@@ -335,6 +445,10 @@ ssize_t send_packet (interface, packet, raw, len, from, to, hto) + return send_fallback (interface, packet, raw, + len, from, to, hto); + ++ if (interface->hw_address.hbuf[0] == HTYPE_INFINIBAND) ++ return send_packet_ib(interface, packet, raw, ++ len, from, to, hto); ++ + if (hto == NULL && interface->anycast_mac_addr.hlen) + hto = &interface->anycast_mac_addr; + +@@ -439,7 +553,15 @@ ssize_t receive_packet (interface, buf, len, from, hfrom) + + bufix = 0; + /* Decode the physical header... */ +- offset = decode_hw_header (interface, ibuf, bufix, hfrom); ++ if (interface->hw_address.hbuf[0] == HTYPE_INFINIBAND) { ++ /* ETHERTYPE_IP packet, no HW header to decode */ ++ if (hfrom) { ++ memset(hfrom, 0, sizeof(*hfrom)); ++ hfrom->hbuf[0] = HTYPE_INFINIBAND; ++ } ++ } else { ++ offset = decode_hw_header (interface, ibuf, bufix, hfrom); ++ } + + /* If a physical layer checksum failed (dunno of any + physical layer that supports this, but WTH), skip this +@@ -507,33 +629,44 @@ void maybe_setup_fallback () + + #if defined (USE_LPF_RECEIVE) || defined (USE_LPF_HWADDR) + void +-get_hw_addr(const char *name, struct hardware *hw) { +- int sock; +- struct ifreq tmp; +- struct sockaddr *sa; ++get_hw_addr(struct interface_info *info) ++{ ++ const char *name = info->name; ++ struct hardware *hw = &info->hw_address; ++ struct ifaddrs *ifaddrs; ++ struct ifaddrs *ifa; ++ struct sockaddr_ll *sll = NULL; + +- if (strlen(name) >= sizeof(tmp.ifr_name)) { +- log_fatal("Device name too long: \"%s\"", name); +- } ++ if (getifaddrs(&ifaddrs) == -1) ++ log_fatal("Failed to get interfaces"); ++ ++ for (ifa = ifaddrs; ifa != NULL; ifa = ifa->ifa_next) { ++ ++ if (!ifa->ifa_addr) ++ continue; ++ ++ if (ifa->ifa_addr->sa_family != AF_PACKET) ++ continue; + +- sock = socket(AF_INET, SOCK_DGRAM, 0); +- if (sock < 0) { +- log_fatal("Can't create socket for \"%s\": %m", name); ++ if (ifa->ifa_flags & IFF_LOOPBACK) ++ continue; ++ ++ if (strcmp(ifa->ifa_name, name) == 0) { ++ sll = (struct sockaddr_ll *)(void *)ifa->ifa_addr; ++ break; ++ } + } + +- memset(&tmp, 0, sizeof(tmp)); +- strcpy(tmp.ifr_name, name); +- if (ioctl(sock, SIOCGIFHWADDR, &tmp) < 0) { +- log_fatal("Error getting hardware address for \"%s\": %m", +- name); ++ if (sll == NULL || sll->sll_halen >= sizeof(hw->hbuf)) { ++ freeifaddrs(ifaddrs); ++ log_fatal("Failed to get HW address for %s\n", name); + } + +- sa = &tmp.ifr_hwaddr; +- switch (sa->sa_family) { ++ switch (sll->sll_hatype) { + case ARPHRD_ETHER: + hw->hlen = 7; + hw->hbuf[0] = HTYPE_ETHER; +- memcpy(&hw->hbuf[1], sa->sa_data, 6); ++ memcpy(&hw->hbuf[1], sll->sll_addr, 6); + break; + case ARPHRD_IEEE802: + #ifdef ARPHRD_IEEE802_TR +@@ -541,18 +674,37 @@ get_hw_addr(const char *name, struct hardware *hw) { + #endif /* ARPHRD_IEEE802_TR */ + hw->hlen = 7; + hw->hbuf[0] = HTYPE_IEEE802; +- memcpy(&hw->hbuf[1], sa->sa_data, 6); ++ memcpy(&hw->hbuf[1], sll->sll_addr, 6); + break; + case ARPHRD_FDDI: + hw->hlen = 7; + hw->hbuf[0] = HTYPE_FDDI; +- memcpy(&hw->hbuf[1], sa->sa_data, 6); ++ memcpy(&hw->hbuf[1], sll->sll_addr, 6); ++ break; ++ case ARPHRD_INFINIBAND: ++ /* For Infiniband, save the broadcast address and store ++ * the port GUID into the hardware address. ++ */ ++ if (ifa->ifa_flags & IFF_BROADCAST) { ++ struct sockaddr_ll *bll; ++ ++ bll = (struct sockaddr_ll *)ifa->ifa_broadaddr; ++ memcpy(&info->bcast_addr, bll->sll_addr, sll->sll_halen); ++ } else { ++ memcpy(&info->bcast_addr, default_ib_bcast_addr, ++ sizeof(default_ib_bcast_addr)); ++ } ++ ++ hw->hlen = sll->sll_halen + 1; ++ hw->hbuf[0] = HTYPE_INFINIBAND; ++ memcpy(&hw->hbuf[1], sll->sll_addr, sll->sll_halen); + break; + default: ++ freeifaddrs(ifaddrs); + log_fatal("Unsupported device type %ld for \"%s\"", +- (long int)sa->sa_family, name); ++ (long int)sll->sll_family, name); + } + +- close(sock); ++ freeifaddrs(ifaddrs); + } + #endif +diff --git a/common/print.c b/common/print.c +index dfe0593..aa7b8e2 100644 +--- a/common/print.c ++++ b/common/print.c +@@ -162,11 +162,11 @@ char *print_hw_addr (htype, hlen, data) + const int hlen; + const unsigned char *data; + { +- static char habuf [49]; ++ static char habuf [64]; + char *s; + int i; + +- if (hlen <= 0) ++ if (hlen <= 0 || hlen >= sizeof(habuf)) + habuf [0] = 0; + else { + s = habuf; +diff --git a/common/socket.c b/common/socket.c +index e8851b4..2c6fb1c 100644 +--- a/common/socket.c ++++ b/common/socket.c +@@ -328,7 +328,7 @@ void if_register_send (info) + info->wfdesc = if_register_socket(info, AF_INET, 0, NULL); + /* If this is a normal IPv4 address, get the hardware address. */ + if (strcmp(info->name, "fallback") != 0) +- get_hw_addr(info->name, &info->hw_address); ++ get_hw_addr(info); + #if defined (USE_SOCKET_FALLBACK) + /* Fallback only registers for send, but may need to receive as + well. */ +@@ -391,7 +391,7 @@ void if_register_receive (info) + #endif /* IP_PKTINFO... */ + /* If this is a normal IPv4 address, get the hardware address. */ + if (strcmp(info->name, "fallback") != 0) +- get_hw_addr(info->name, &info->hw_address); ++ get_hw_addr(info); + + if (!quiet_interface_discovery) + log_info ("Listening on Socket/%s%s%s", +@@ -505,7 +505,7 @@ if_register6(struct interface_info *info, int do_multicast) { + if (req_multi) + if_register_multicast(info); + +- get_hw_addr(info->name, &info->hw_address); ++ get_hw_addr(info); + + if (!quiet_interface_discovery) { + if (info->shared_network != NULL) { +@@ -561,7 +561,7 @@ if_register_linklocal6(struct interface_info *info) { + info->rfdesc = sock; + info->wfdesc = sock; + +- get_hw_addr(info->name, &info->hw_address); ++ get_hw_addr(info); + + if (!quiet_interface_discovery) { + if (info->shared_network != NULL) { +@@ -1145,7 +1145,9 @@ void maybe_setup_fallback () + #if defined(sun) && defined(USE_V4_PKTINFO) + /* This code assumes the existence of SIOCGLIFHWADDR */ + void +-get_hw_addr(const char *name, struct hardware *hw) { ++get_hw_addr(struct interface_info *info) { ++ const char *name = info->name; ++ struct hardware *hw = &info->hw_address; + struct sockaddr_dl *dladdrp; + int sock, i; + struct lifreq lifr; +diff --git a/includes/dhcpd.h b/includes/dhcpd.h +index f0f4b20..0a04f04 100644 +--- a/includes/dhcpd.h ++++ b/includes/dhcpd.h +@@ -1321,6 +1321,7 @@ struct interface_info { + struct shared_network *shared_network; + /* Networks connected to this interface. */ + struct hardware hw_address; /* Its physical address. */ ++ u_int8_t bcast_addr[HARDWARE_ADDR_LEN]; /* broadcast hw address */ + struct in_addr *addresses; /* Addresses associated with this + * interface. + */ +@@ -2542,7 +2543,7 @@ void print_dns_status (int, struct dhcp_ddns_cb *, isc_result_t); + #endif + const char *print_time(TIME); + +-void get_hw_addr(const char *name, struct hardware *hw); ++void get_hw_addr(struct interface_info *info); + + /* socket.c */ + #if defined (USE_SOCKET_SEND) || defined (USE_SOCKET_RECEIVE) \ +diff --git a/server/dhcp.c b/server/dhcp.c +index 1f007e2..0f53ac2 100644 +--- a/server/dhcp.c ++++ b/server/dhcp.c +@@ -1806,11 +1806,12 @@ void echo_client_id(packet, lease, in_options, out_options) + + /* Check if echo-client-id is enabled */ + oc = lookup_option(&server_universe, in_options, SV_ECHO_CLIENT_ID); +- if (oc && evaluate_boolean_option_cache(&ignorep, packet, lease, ++ if ((packet->raw && packet->raw->hlen == 0) || ++ (oc && evaluate_boolean_option_cache(&ignorep, packet, lease, + NULL, packet->options, + in_options, + (lease ? &lease->scope : NULL), +- oc, MDL)) { ++ oc, MDL))) { + struct data_string client_id; + unsigned int opcode = DHO_DHCP_CLIENT_IDENTIFIER; + +@@ -3592,9 +3593,11 @@ void dhcp_reply (lease) + } else + bufs |= 2; /* XXX */ + +- memcpy (raw.chaddr, +- &lease -> hardware_addr.hbuf [1], sizeof raw.chaddr); +- raw.hlen = lease -> hardware_addr.hlen - 1; ++ if (lease -> hardware_addr.hlen - 1 <= sizeof(raw.chaddr)) ++ raw.hlen = lease -> hardware_addr.hlen - 1; ++ if (lease -> hardware_addr.hlen > 1 && raw.hlen) ++ memcpy (raw.chaddr, ++ &lease -> hardware_addr.hbuf [1], raw.hlen); + raw.htype = lease -> hardware_addr.hbuf [0]; + + /* See if this is a Microsoft client that NUL-terminates its +diff --git a/server/dhcpleasequery.c b/server/dhcpleasequery.c +index 0766b84..c9a1e8b 100644 +--- a/server/dhcpleasequery.c ++++ b/server/dhcpleasequery.c +@@ -295,7 +295,7 @@ dhcpleasequery(struct packet *packet, int ms_nulltp) { + assoc_ips, + nassoc_ips); + +- } else { ++ } else if (packet->raw->hlen) { + + if (packet->raw->hlen+1 > sizeof(h.hbuf)) { + log_info("%s: hardware length too long, " +@@ -405,11 +405,13 @@ dhcpleasequery(struct packet *packet, int ms_nulltp) { + * Set the hardware address fields. + */ + +- packet->raw->hlen = lease->hardware_addr.hlen - 1; + packet->raw->htype = lease->hardware_addr.hbuf[0]; +- memcpy(packet->raw->chaddr, +- &lease->hardware_addr.hbuf[1], +- sizeof(packet->raw->chaddr)); ++ if (lease->hardware_addr.hlen - 1 <= sizeof(packet->raw->chaddr)) ++ packet->raw->hlen = lease->hardware_addr.hlen - 1; ++ if (lease->hardware_addr.hlen > 1 && packet->raw->hlen) ++ memcpy(packet->raw->chaddr, ++ &lease->hardware_addr.hbuf[1], ++ packet->raw->hlen); + + /* + * Set client identifier option. +diff --git a/server/mdb.c b/server/mdb.c +index 9a7da80..539a233 100644 +--- a/server/mdb.c ++++ b/server/mdb.c +@@ -619,6 +619,9 @@ int find_hosts_by_haddr (struct host_decl **hp, int htype, + return ret; + #endif + ++ if (!hlen || hlen > HARDWARE_ADDR_LEN) ++ return 0; ++ + h.hlen = hlen + 1; + h.hbuf [0] = htype; + memcpy (&h.hbuf [1], haddr, hlen); +-- +2.1.4 + diff --git a/0016-server-log-DHCPv6-addresses-assigned-to-clients.patch b/0016-server-log-DHCPv6-addresses-assigned-to-clients.patch deleted file mode 100644 index 7f40ac9..0000000 --- a/0016-server-log-DHCPv6-addresses-assigned-to-clients.patch +++ /dev/null @@ -1,23 +0,0 @@ -From 39c796224826836f0b0d1ab42f93a973545a94b0 Mon Sep 17 00:00:00 2001 -From: Marius Tomaschewski -Date: Mon, 10 Feb 2014 15:12:49 +0100 -Subject: [PATCH] server: log DHCPv6 addresses assigned to clients - ---- - includes/site.h | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/includes/site.h b/includes/site.h -index 3de180c..1b6d0c0 100644 ---- a/includes/site.h -+++ b/includes/site.h -@@ -281,5 +281,5 @@ - This default to off to avoid changes to what is currently - logged. */ - --/* #define LOG_V6_ADDRESSES */ -+#define LOG_V6_ADDRESSES - --- -1.8.4 - diff --git a/0017-dhcp-4.2.6-lpf-ip-over-ib-support.patch b/0017-dhcp-4.2.6-lpf-ip-over-ib-support.patch deleted file mode 100644 index bf54368..0000000 --- a/0017-dhcp-4.2.6-lpf-ip-over-ib-support.patch +++ /dev/null @@ -1,532 +0,0 @@ -From 6bf4a955f815967826994f787d2608d6dadadd91 Mon Sep 17 00:00:00 2001 -From: root -Date: Tue, 25 Mar 2014 23:15:58 +0200 -Subject: [PATCH 1/2] dhcp 4.2.6 lpf ip over ib support - ---- - client/dhclient.c | 31 +++++++ - common/bpf.c | 33 ++++++++ - common/lpf.c | 236 +++++++++++++++++++++++++++++++++++++++++++++--------- - common/socket.c | 8 +- - includes/dhcpd.h | 3 +- - 5 files changed, 266 insertions(+), 45 deletions(-) - -diff --git a/client/dhclient.c b/client/dhclient.c -index 8af0a42..f7dfbef 100644 ---- a/client/dhclient.c -+++ b/client/dhclient.c -@@ -100,6 +100,29 @@ static int check_domain_name_list(const char *ptr, size_t len, int dots); - static int check_option_values(struct universe *universe, unsigned int opt, - const char *ptr, size_t len); - -+static void setup_ib_interface(struct interface_info *ip) -+{ -+ struct group *g; -+ -+ /* Set the broadcast flag */ -+ //ip->client->config->bootp_broadcast_always = 1; -+ -+ /* -+ * Find out if a dhcp-client-identifier option was specified either -+ * in the config file or on the command line -+ */ -+ for (g = ip->client->config->on_transmission; g != NULL; g = g->next) { -+ if ((g->statements != NULL) && -+ (strcmp(g->statements->data.option->option->name, -+ "dhcp-client-identifier") == 0)) { -+ return; -+ } -+ } -+ -+ /* No client ID specified */ -+ log_fatal("dhcp-client-identifier must be specified for InfiniBand"); -+} -+ - int - main(int argc, char **argv) { - int fd; -@@ -619,6 +642,14 @@ main(int argc, char **argv) { - } - srandom(seed + cur_time + (unsigned)getpid()); - -+ /* Setup specific Infiniband options */ -+ for (ip = interfaces; ip; ip = ip->next) { -+ if (ip->client && -+ (ip->hw_address.hbuf[0] == HTYPE_INFINIBAND)) { -+ setup_ib_interface(ip); -+ } -+ } -+ - /* Start a configuration state machine for each interface. */ - #ifdef DHCPv6 - if (local_family == AF_INET6) { -diff --git a/common/bpf.c b/common/bpf.c -index 076d9bc..124281b 100644 ---- a/common/bpf.c -+++ b/common/bpf.c -@@ -198,11 +198,44 @@ struct bpf_insn dhcp_bpf_filter [] = { - BPF_STMT(BPF_RET+BPF_K, 0), - }; - -+/* Packet filter program for DHCP over Infiniband. -+ * -+ * XXX -+ * Changes to the filter program may require changes to the constant offsets -+ * used in lpf_gen_filter_setup to patch the port in the BPF program! -+ * XXX -+ */ -+struct bpf_insn dhcp_ib_bpf_filter [] = { -+ /* Packet filter for Infiniband */ -+ /* Make sure it's a UDP packet... */ -+ BPF_STMT(BPF_LD + BPF_B + BPF_ABS, 9), -+ BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, IPPROTO_UDP, 0, 6), -+ -+ /* Make sure this isn't a fragment... */ -+ BPF_STMT(BPF_LD + BPF_H + BPF_ABS, 6), -+ BPF_JUMP(BPF_JMP + BPF_JSET + BPF_K, 0x1fff, 4, 0), -+ -+ /* Get the IP header length... */ -+ BPF_STMT(BPF_LDX + BPF_B + BPF_MSH, 0), -+ -+ /* Make sure it's to the right port... */ -+ BPF_STMT(BPF_LD + BPF_H + BPF_IND, 2), -+ BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, 67, 0, 1), -+ -+ /* If we passed all the tests, ask for the whole packet. */ -+ BPF_STMT(BPF_RET + BPF_K, (u_int)-1), -+ -+ /* Otherwise, drop it. */ -+ BPF_STMT(BPF_RET + BPF_K, 0), -+}; -+ - #if defined (DEC_FDDI) - struct bpf_insn *bpf_fddi_filter; - #endif - - int dhcp_bpf_filter_len = sizeof dhcp_bpf_filter / sizeof (struct bpf_insn); -+int dhcp_ib_bpf_filter_len = sizeof dhcp_ib_bpf_filter / sizeof (struct bpf_insn); -+ - #if defined (HAVE_TR_SUPPORT) - struct bpf_insn dhcp_bpf_tr_filter [] = { - /* accept all token ring packets due to variable length header */ -diff --git a/common/lpf.c b/common/lpf.c -index 6639809..a428870 100644 ---- a/common/lpf.c -+++ b/common/lpf.c -@@ -43,6 +43,7 @@ - #include "includes/netinet/udp.h" - #include "includes/netinet/if_ether.h" - #include -+#include - - #ifndef PACKET_AUXDATA - #define PACKET_AUXDATA 8 -@@ -60,6 +61,15 @@ struct tpacket_auxdata - /* Reinitializes the specified interface after an address change. This - is not required for packet-filter APIs. */ - -+/* Default broadcast address for IPoIB */ -+static unsigned char default_ib_bcast_addr[20] = { -+ 0x00, 0xff, 0xff, 0xff, -+ 0xff, 0x12, 0x40, 0x1b, -+ 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, -+ 0xff, 0xff, 0xff, 0xff -+}; -+ - #ifdef USE_LPF_SEND - void if_reinitialize_send (info) - struct interface_info *info; -@@ -87,10 +97,21 @@ int if_register_lpf (info) - struct sockaddr common; - } sa; - struct ifreq ifr; -+ int type; -+ int protocol; - - /* Make an LPF socket. */ -- if ((sock = socket(PF_PACKET, SOCK_RAW, -- htons((short)ETH_P_ALL))) < 0) { -+ get_hw_addr(info); -+ -+ if (info->hw_address.hbuf[0] == HTYPE_INFINIBAND) { -+ type = SOCK_DGRAM; -+ protocol = ETHERTYPE_IP; -+ } else { -+ type = SOCK_RAW; -+ protocol = ETH_P_ALL; -+ } -+ -+ if ((sock = socket(PF_PACKET, type, htons((short)protocol))) < 0) { - if (errno == ENOPROTOOPT || errno == EPROTONOSUPPORT || - errno == ESOCKTNOSUPPORT || errno == EPFNOSUPPORT || - errno == EAFNOSUPPORT || errno == EINVAL) { -@@ -112,6 +133,7 @@ int if_register_lpf (info) - /* Bind to the interface name */ - memset (&sa, 0, sizeof sa); - sa.ll.sll_family = AF_PACKET; -+ sa.ll.sll_protocol = htons(protocol); - sa.ll.sll_ifindex = ifr.ifr_ifindex; - if (bind (sock, &sa.common, sizeof sa)) { - if (errno == ENOPROTOOPT || errno == EPROTONOSUPPORT || -@@ -127,8 +149,6 @@ int if_register_lpf (info) - log_fatal ("Bind socket to interface: %m"); - } - -- get_hw_addr(info->name, &info->hw_address); -- - return sock; - } - #endif /* USE_LPF_SEND || USE_LPF_RECEIVE */ -@@ -183,6 +203,8 @@ void if_deregister_send (info) - in bpf includes... */ - extern struct sock_filter dhcp_bpf_filter []; - extern int dhcp_bpf_filter_len; -+extern struct sock_filter dhcp_ib_bpf_filter []; -+extern int dhcp_ib_bpf_filter_len; - - #if defined (HAVE_TR_SUPPORT) - extern struct sock_filter dhcp_bpf_tr_filter []; -@@ -200,11 +222,13 @@ void if_register_receive (info) - /* Open a LPF device and hang it on this interface... */ - info -> rfdesc = if_register_lpf (info); - -- val = 1; -- if (setsockopt (info -> rfdesc, SOL_PACKET, PACKET_AUXDATA, &val, -- sizeof val) < 0) { -- if (errno != ENOPROTOOPT) -- log_fatal ("Failed to set auxiliary packet data: %m"); -+ if (info->hw_address.hbuf[0] != HTYPE_INFINIBAND) { -+ val = 1; -+ if (setsockopt (info -> rfdesc, SOL_PACKET, PACKET_AUXDATA, -+ &val, sizeof val) < 0) { -+ if (errno != ENOPROTOOPT) -+ log_fatal ("Failed to set auxiliary packet data: %m"); -+ } - } - - #if defined (HAVE_TR_SUPPORT) -@@ -250,15 +274,28 @@ static void lpf_gen_filter_setup (info) - - memset(&p, 0, sizeof(p)); - -- /* Set up the bpf filter program structure. This is defined in -- bpf.c */ -- p.len = dhcp_bpf_filter_len; -- p.filter = dhcp_bpf_filter; -- -- /* Patch the server port into the LPF program... -- XXX changes to filter program may require changes -- to the insn number(s) used below! XXX */ -- dhcp_bpf_filter [8].k = ntohs ((short)local_port); -+ if (info->hw_address.hbuf[0] == HTYPE_INFINIBAND) { -+ /* Set up the bpf filter program structure. */ -+ p.len = dhcp_ib_bpf_filter_len; -+ p.filter = dhcp_ib_bpf_filter; -+ -+ /* Patch the server port into the LPF program... -+ XXX -+ changes to filter program may require changes -+ to the insn number(s) used below! -+ XXX */ -+ dhcp_ib_bpf_filter[6].k = ntohs ((short)local_port); -+ } else { -+ /* Set up the bpf filter program structure. -+ This is defined in bpf.c */ -+ p.len = dhcp_bpf_filter_len; -+ p.filter = dhcp_bpf_filter; -+ -+ /* Patch the server port into the LPF program... -+ XXX changes to filter program may require changes -+ to the insn number(s) used below! XXX */ -+ dhcp_bpf_filter [8].k = ntohs ((short)local_port); -+ } - - if (setsockopt (info -> rfdesc, SOL_SOCKET, SO_ATTACH_FILTER, &p, - sizeof p) < 0) { -@@ -315,6 +352,54 @@ static void lpf_tr_filter_setup (info) - #endif /* USE_LPF_RECEIVE */ - - #ifdef USE_LPF_SEND -+ssize_t send_packet_ib(interface, packet, raw, len, from, to, hto) -+ struct interface_info *interface; -+ struct packet *packet; -+ struct dhcp_packet *raw; -+ size_t len; -+ struct in_addr from; -+ struct sockaddr_in *to; -+ struct hardware *hto; -+{ -+ unsigned ibufp = 0; -+ double ih [1536 / sizeof (double)]; -+ unsigned char *buf = (unsigned char *)ih; -+ ssize_t result; -+ -+ union sockunion { -+ struct sockaddr sa; -+ struct sockaddr_ll sll; -+ struct sockaddr_storage ss; -+ } su; -+ -+ assemble_udp_ip_header (interface, buf, &ibufp, from.s_addr, -+ to->sin_addr.s_addr, to->sin_port, -+ (unsigned char *)raw, len); -+ memcpy (buf + ibufp, raw, len); -+ -+ memset(&su, 0, sizeof(su)); -+ su.sll.sll_family = AF_PACKET; -+ su.sll.sll_protocol = htons(ETHERTYPE_IP); -+ -+ if (!(su.sll.sll_ifindex = if_nametoindex(interface->name))) { -+ errno = ENOENT; -+ log_error ("send_packet_ib: %m - failed to get if index"); -+ return -1; -+ } -+ -+ su.sll.sll_hatype = htons(HTYPE_INFINIBAND); -+ su.sll.sll_halen = sizeof(interface->bcast_addr); -+ memcpy(&su.sll.sll_addr, interface->bcast_addr, 20); -+ -+ result = sendto(interface->wfdesc, buf, ibufp + len, 0, -+ &su.sa, sizeof(su)); -+ -+ if (result < 0) -+ log_error ("send_packet_ib: %m"); -+ -+ return result; -+} -+ - ssize_t send_packet (interface, packet, raw, len, from, to, hto) - struct interface_info *interface; - struct packet *packet; -@@ -335,6 +420,11 @@ ssize_t send_packet (interface, packet, raw, len, from, to, hto) - return send_fallback (interface, packet, raw, - len, from, to, hto); - -+ if (interface->hw_address.hbuf[0] == HTYPE_INFINIBAND) { -+ return send_packet_ib(interface, packet, raw, len, from, -+ to, hto); -+ } -+ - if (hto == NULL && interface->anycast_mac_addr.hlen) - hto = &interface->anycast_mac_addr; - -@@ -356,6 +446,42 @@ ssize_t send_packet (interface, packet, raw, len, from, to, hto) - #endif /* USE_LPF_SEND */ - - #ifdef USE_LPF_RECEIVE -+ssize_t receive_packet_ib (interface, buf, len, from, hfrom) -+ struct interface_info *interface; -+ unsigned char *buf; -+ size_t len; -+ struct sockaddr_in *from; -+ struct hardware *hfrom; -+{ -+ int length = 0; -+ int offset = 0; -+ unsigned char ibuf [1536]; -+ unsigned bufix = 0; -+ unsigned paylen; -+ -+ length = read(interface->rfdesc, ibuf, sizeof(ibuf)); -+ -+ if (length <= 0) -+ return length; -+ -+ offset = decode_udp_ip_header(interface, ibuf, bufix, from, -+ (unsigned)length, &paylen, 0); -+ -+ if (offset < 0) -+ return 0; -+ -+ bufix += offset; -+ length -= offset; -+ -+ if (length < paylen) -+ log_fatal("Internal inconsistency at %s:%d.", MDL); -+ -+ /* Copy out the data in the packet... */ -+ memcpy(buf, &ibuf[bufix], paylen); -+ -+ return (ssize_t)paylen; -+} -+ - ssize_t receive_packet (interface, buf, len, from, hfrom) - struct interface_info *interface; - unsigned char *buf; -@@ -382,6 +508,10 @@ ssize_t receive_packet (interface, buf, len, from, hfrom) - }; - struct cmsghdr *cmsg; - -+ if (interface->hw_address.hbuf[0] == HTYPE_INFINIBAND) { -+ return receive_packet_ib(interface, buf, len, from, hfrom); -+ } -+ - length = recvmsg (interface -> rfdesc, &msg, 0); - if (length <= 0) - return length; -@@ -462,33 +592,41 @@ void maybe_setup_fallback () - } - - void --get_hw_addr(const char *name, struct hardware *hw) { -- int sock; -- struct ifreq tmp; -- struct sockaddr *sa; -+get_hw_addr(struct interface_info *info) -+{ -+ struct hardware *hw = &info->hw_address; -+ char *name = info->name; -+ struct ifaddrs *ifaddrs; -+ struct ifaddrs *ifa; -+ struct sockaddr_ll *sll = NULL; - -- if (strlen(name) >= sizeof(tmp.ifr_name)) { -- log_fatal("Device name too long: \"%s\"", name); -- } -+ if (getifaddrs(&ifaddrs) == -1) -+ log_fatal("Failed to get interfaces"); - -- sock = socket(AF_INET, SOCK_DGRAM, 0); -- if (sock < 0) { -- log_fatal("Can't create socket for \"%s\": %m", name); -+ for (ifa = ifaddrs; ifa != NULL; ifa = ifa->ifa_next) { -+ -+ if (ifa->ifa_addr->sa_family != AF_PACKET) -+ continue; -+ -+ if (ifa->ifa_flags & IFF_LOOPBACK) -+ continue; -+ -+ if (strcmp(ifa->ifa_name, name) == 0) { -+ sll = (struct sockaddr_ll *)(void *)ifa->ifa_addr; -+ break; -+ } - } - -- memset(&tmp, 0, sizeof(tmp)); -- strcpy(tmp.ifr_name, name); -- if (ioctl(sock, SIOCGIFHWADDR, &tmp) < 0) { -- log_fatal("Error getting hardware address for \"%s\": %m", -- name); -+ if (sll == NULL) { -+ freeifaddrs(ifaddrs); -+ log_fatal("Failed to get HW address for %s\n", name); - } - -- sa = &tmp.ifr_hwaddr; -- switch (sa->sa_family) { -+ switch (sll->sll_hatype) { - case ARPHRD_ETHER: - hw->hlen = 7; - hw->hbuf[0] = HTYPE_ETHER; -- memcpy(&hw->hbuf[1], sa->sa_data, 6); -+ memcpy(&hw->hbuf[1], sll->sll_addr, 6); - break; - case ARPHRD_IEEE802: - #ifdef ARPHRD_IEEE802_TR -@@ -496,18 +634,36 @@ get_hw_addr(const char *name, struct hardware *hw) { - #endif /* ARPHRD_IEEE802_TR */ - hw->hlen = 7; - hw->hbuf[0] = HTYPE_IEEE802; -- memcpy(&hw->hbuf[1], sa->sa_data, 6); -+ memcpy(&hw->hbuf[1], sll->sll_addr, 6); - break; - case ARPHRD_FDDI: - hw->hlen = 7; - hw->hbuf[0] = HTYPE_FDDI; -- memcpy(&hw->hbuf[1], sa->sa_data, 6); -+ memcpy(&hw->hbuf[1], sll->sll_addr, 6); - break; -+ case ARPHRD_INFINIBAND: -+ /* For Infiniband, save the broadcast address and store -+ * the port GUID into the hardware address. -+ */ -+ if (ifa->ifa_flags & IFF_BROADCAST) { -+ struct sockaddr_ll *bll; -+ -+ bll = (struct sockaddr_ll *)ifa->ifa_broadaddr; -+ memcpy(&info->bcast_addr, bll->sll_addr, 20); -+ } else { -+ memcpy(&info->bcast_addr, default_ib_bcast_addr, -+ 20); -+ } -+ -+ hw->hlen = 1; -+ hw->hbuf[0] = HTYPE_INFINIBAND; -+ break; - default: -+ freeifaddrs(ifaddrs); - log_fatal("Unsupported device type %ld for \"%s\"", -- (long int)sa->sa_family, name); -+ (long int)sll->sll_family, name); - } - -- close(sock); -+ freeifaddrs(ifaddrs); - } - #endif -diff --git a/common/socket.c b/common/socket.c -index e111d82..04c86e3 100644 ---- a/common/socket.c -+++ b/common/socket.c -@@ -322,7 +322,7 @@ void if_register_send (info) - info->wfdesc = if_register_socket(info, AF_INET, 0, NULL); - /* If this is a normal IPv4 address, get the hardware address. */ - if (strcmp(info->name, "fallback") != 0) -- get_hw_addr(info->name, &info->hw_address); -+ get_hw_addr(info); - #if defined (USE_SOCKET_FALLBACK) - /* Fallback only registers for send, but may need to receive as - well. */ -@@ -385,7 +385,7 @@ void if_register_receive (info) - #endif /* IP_PKTINFO... */ - /* If this is a normal IPv4 address, get the hardware address. */ - if (strcmp(info->name, "fallback") != 0) -- get_hw_addr(info->name, &info->hw_address); -+ get_hw_addr(info); - - if (!quiet_interface_discovery) - log_info ("Listening on Socket/%s%s%s", -@@ -499,7 +499,7 @@ if_register6(struct interface_info *info, int do_multicast) { - if (req_multi) - if_register_multicast(info); - -- get_hw_addr(info->name, &info->hw_address); -+ get_hw_addr(info); - - if (!quiet_interface_discovery) { - if (info->shared_network != NULL) { -@@ -555,7 +555,7 @@ if_register_linklocal6(struct interface_info *info) { - info->rfdesc = sock; - info->wfdesc = sock; - -- get_hw_addr(info->name, &info->hw_address); -+ get_hw_addr(info); - - if (!quiet_interface_discovery) { - if (info->shared_network != NULL) { -diff --git a/includes/dhcpd.h b/includes/dhcpd.h -index 68262e9..a52992b 100644 ---- a/includes/dhcpd.h -+++ b/includes/dhcpd.h -@@ -1217,6 +1217,7 @@ struct interface_info { - struct shared_network *shared_network; - /* Networks connected to this interface. */ - struct hardware hw_address; /* Its physical address. */ -+ u_int8_t bcast_addr[20]; /* Infiniband broadcast address */ - struct in_addr *addresses; /* Addresses associated with this - * interface. - */ -@@ -2346,7 +2347,7 @@ void print_dns_status (int, struct dhcp_ddns_cb *, isc_result_t); - #endif - const char *print_time(TIME); - --void get_hw_addr(const char *name, struct hardware *hw); -+void get_hw_addr(struct interface_info *info); - - /* socket.c */ - #if defined (USE_SOCKET_SEND) || defined (USE_SOCKET_RECEIVE) \ --- -1.7.12.4 - diff --git a/0017-server-no-success-report-before-send.919959.patch b/0017-server-no-success-report-before-send.919959.patch new file mode 100644 index 0000000..bc8502f --- /dev/null +++ b/0017-server-no-success-report-before-send.919959.patch @@ -0,0 +1,104 @@ +From ce15607bca2509bc2abd440000d25498ad589e27 Mon Sep 17 00:00:00 2001 +From: Marius Tomaschewski +Date: Mon, 14 Sep 2015 15:31:37 +0200 +Subject: [PATCH] server: no success report before send (bsc#919959) +References: bsc#919959 + +--- + server/dhcp.c | 53 ++++++++++++++++++++++++++++++----------------------- + 1 file changed, 30 insertions(+), 23 deletions(-) + +diff --git a/server/dhcp.c b/server/dhcp.c +index 0f53ac2..3a610e8 100644 +--- a/server/dhcp.c ++++ b/server/dhcp.c +@@ -3643,22 +3643,6 @@ void dhcp_reply (lease) + } else + s = (char *)0; + +- /* Say what we're doing... */ +- log_info ("%s on %s to %s %s%s%svia %s", +- (state -> offer +- ? (state -> offer == DHCPACK ? "DHCPACK" : "DHCPOFFER") +- : "BOOTREPLY"), +- piaddr (lease -> ip_addr), +- (lease -> hardware_addr.hlen +- ? print_hw_addr (lease -> hardware_addr.hbuf [0], +- lease -> hardware_addr.hlen - 1, +- &lease -> hardware_addr.hbuf [1]) +- : print_hex_1(lease->uid_len, lease->uid, 60)), +- s ? "(" : "", s ? s : "", s ? ") " : "", +- (state -> giaddr.s_addr +- ? inet_ntoa (state -> giaddr) +- : state -> ip -> name)); +- + /* Set up the hardware address... */ + hto.hlen = lease -> hardware_addr.hlen; + memcpy (hto.hbuf, lease -> hardware_addr.hbuf, hto.hlen); +@@ -3695,12 +3679,13 @@ void dhcp_reply (lease) + "packet over %s interface.", MDL, + packet_length, + fallback_interface->name); +- } + ++ free_lease_state (state, MDL); ++ lease -> state = (struct lease_state *)0; ++ return; ++ } + +- free_lease_state (state, MDL); +- lease -> state = (struct lease_state *)0; +- return; ++ goto report; + } + + /* If the client is RENEWING, unicast to the client using the +@@ -3733,11 +3718,13 @@ void dhcp_reply (lease) + " packet over %s interface.", MDL, + packet_length, + fallback_interface->name); ++ ++ free_lease_state (state, MDL); ++ lease -> state = (struct lease_state *)0; ++ return; + } + +- free_lease_state (state, MDL); +- lease -> state = (struct lease_state *)0; +- return; ++ goto report; + } + + /* If it comes from a client that already knows its address +@@ -3765,8 +3752,28 @@ void dhcp_reply (lease) + log_error ("%s:%d: Failed to send %d byte long " + "packet over %s interface.", MDL, + packet_length, state->ip->name); ++ ++ free_lease_state (state, MDL); ++ lease -> state = (struct lease_state *)0; ++ return; + } + ++report: ++ /* Say what we're doing... */ ++ log_info ("%s on %s to %s %s%s%svia %s", ++ (state -> offer ++ ? (state -> offer == DHCPACK ? "DHCPACK" : "DHCPOFFER") ++ : "BOOTREPLY"), ++ piaddr (lease -> ip_addr), ++ (lease -> hardware_addr.hlen ++ ? print_hw_addr (lease -> hardware_addr.hbuf [0], ++ lease -> hardware_addr.hlen - 1, ++ &lease -> hardware_addr.hbuf [1]) ++ : print_hex_1(lease->uid_len, lease->uid, 60)), ++ s ? "(" : "", s ? s : "", s ? ") " : "", ++ (state -> giaddr.s_addr ++ ? inet_ntoa (state -> giaddr) ++ : state -> ip -> name)); + + /* Free all of the entries in the option_state structure + now that we're done with them. */ +-- +2.1.4 + diff --git a/0018-client-fail-on-script-pre-init-error-bsc-912098.patch b/0018-client-fail-on-script-pre-init-error-bsc-912098.patch new file mode 100644 index 0000000..d9f2da4 --- /dev/null +++ b/0018-client-fail-on-script-pre-init-error-bsc-912098.patch @@ -0,0 +1,50 @@ +From 937561ef8c09e3281caba3c859e80ce2fcf23ce4 Mon Sep 17 00:00:00 2001 +From: Marius Tomaschewski +Date: Mon, 14 Sep 2015 18:53:34 +0200 +Subject: [PATCH] client: fail on script pre-init error (bsc#912098) +References: bsc#912098 + +diff --git a/client/dhclient.c b/client/dhclient.c +index b438629..82d6ed5 100644 +--- a/client/dhclient.c ++++ b/client/dhclient.c +@@ -632,7 +632,8 @@ main(int argc, char **argv) { + * in case somebody cares. + */ + script_init(NULL, "NBI", NULL); +- script_go(NULL); ++ if (script_go(NULL)) ++ log_fatal("dhclient-script was unable to pre-init"); + + /* + * If we haven't been asked to persist, waiting for new +@@ -644,6 +645,8 @@ main(int argc, char **argv) { + exit(0); + } + } else if (!release_mode && !exit_mode) { ++ unsigned int failed = 0; ++ + /* Call the script with the list of interfaces. */ + for (ip = interfaces; ip; ip = ip->next) { + /* +@@ -665,7 +668,16 @@ main(int argc, char **argv) { + "alias_", + ip->client->alias); + } +- script_go(ip->client); ++ if (script_go(ip->client)) { ++ log_info("%s: unable to pre-init requested interface %s", ++ path_dhclient_script, ip->name); ++ ip->flags &= ~(INTERFACE_REQUESTED|INTERFACE_AUTOMATIC); ++ failed++; ++ } ++ } ++ if (failed) { ++ log_fatal("%s: unable to pre-init requested interfaces", ++ path_dhclient_script); + } + } + +-- +2.1.4 + diff --git a/0018-dhcp-4.2.6-improved-xid.patch b/0018-dhcp-4.2.6-improved-xid.patch deleted file mode 100644 index 7ac4762..0000000 --- a/0018-dhcp-4.2.6-improved-xid.patch +++ /dev/null @@ -1,154 +0,0 @@ -From 3a2059b67c3adfccd65f1e10aebf8ba73d51bcd1 Mon Sep 17 00:00:00 2001 -From: root -Date: Tue, 25 Mar 2014 23:30:18 +0200 -Subject: [PATCH 2/2] dhcp 4.2.6 improved xid - ---- - client/dhclient.c | 70 ++++++++++++++++++++++++++++++++++++++++++++----------- - 1 file changed, 56 insertions(+), 14 deletions(-) - -diff --git a/client/dhclient.c b/client/dhclient.c -index f7dfbef..bfa99fb 100644 ---- a/client/dhclient.c -+++ b/client/dhclient.c -@@ -619,6 +619,26 @@ main(int argc, char **argv) { - } - } - -+ /* We create a backup seed before rediscovering interfaces in order to -+ have a seed built using all of the available interfaces -+ It's interesting if required interfaces doesn't let us defined -+ a really unique seed due to a lack of valid HW addr later -+ (this is the case with DHCP over IB) -+ We only use the last device as using a sum could broke the -+ uniqueness of the seed among multiple nodes -+ */ -+ unsigned backup_seed = 0; -+ for (ip = interfaces; ip; ip = ip -> next) { -+ int junk; -+ if ( ip -> hw_address.hlen <= sizeof seed ) -+ continue; -+ memcpy (&junk, -+ &ip -> hw_address.hbuf [ip -> hw_address.hlen - -+ sizeof seed], sizeof seed); -+ backup_seed = junk; -+ } -+ -+ - /* At this point, all the interfaces that the script thinks - are relevant should be running, so now we once again call - discover_interfaces(), and this time ask it to actually set -@@ -633,14 +653,36 @@ main(int argc, char **argv) { - Not much entropy, but we're booting, so we're not likely to - find anything better. */ - seed = 0; -+ int seed_flag = 0; - for (ip = interfaces; ip; ip = ip->next) { - int junk; -+ if (ip->hw_address.hlen <= sizeof seed) -+ continue; - memcpy(&junk, - &ip->hw_address.hbuf[ip->hw_address.hlen - - sizeof seed], sizeof seed); - seed += junk; -+ seed_flag = 1; - } -- srandom(seed + cur_time + (unsigned)getpid()); -+ if ( seed_flag == 0 ) { -+ if ( backup_seed != 0 ) { -+ seed = backup_seed; -+ log_info ("xid: rand init seed (0x%x) built using all" -+ " available interfaces",seed); -+ } -+ else { -+ seed = cur_time^((unsigned) gethostid()) ; -+ log_info ("xid: warning: no netdev with useable HWADDR found" -+ " for seed's uniqueness enforcement"); -+ log_info ("xid: rand init seed (0x%x) built using gethostid", -+ seed); -+ } -+ /* we only use seed and no current time as a broadcast reply */ -+ /* will certainly be used by the hwaddrless interface */ -+ srandom(seed); -+ } -+ else -+ srandom(seed + cur_time + (unsigned)getpid()); - - /* Setup specific Infiniband options */ - for (ip = interfaces; ip; ip = ip->next) { -@@ -1143,7 +1185,7 @@ void dhcpack (packet) - return; - } - -- log_info ("DHCPACK from %s", piaddr (packet -> client_addr)); -+ log_info ("DHCPACK from %s (xid=0x%x)", piaddr (packet -> client_addr), client -> xid); - - lease = packet_to_lease (packet, client); - if (!lease) { -@@ -1861,7 +1903,7 @@ void dhcpnak (packet) - return; - } - -- log_info ("DHCPNAK from %s", piaddr (packet -> client_addr)); -+ log_info ("DHCPNAK from %s (xid=0x%x)", piaddr (packet -> client_addr), client -> xid); - - if (!client -> active) { - #if defined (DEBUG) -@@ -1988,10 +2030,10 @@ void send_discover (cpp) - client -> packet.secs = htons (65535); - client -> secs = client -> packet.secs; - -- log_info ("DHCPDISCOVER on %s to %s port %d interval %ld", -- client -> name ? client -> name : client -> interface -> name, -- inet_ntoa (sockaddr_broadcast.sin_addr), -- ntohs (sockaddr_broadcast.sin_port), (long)(client -> interval)); -+ log_info ("DHCPDISCOVER on %s to %s port %d interval %ld (xid=0x%x)", -+ client -> name ? client -> name : client -> interface -> name, -+ inet_ntoa (sockaddr_broadcast.sin_addr), -+ ntohs (sockaddr_broadcast.sin_port), (long)(client -> interval), client -> xid); - - /* Send out a packet. */ - result = send_packet(client->interface, NULL, &client->packet, -@@ -2260,10 +2302,10 @@ void send_request (cpp) - client -> packet.secs = htons (65535); - } - -- log_info ("DHCPREQUEST on %s to %s port %d", -+ log_info ("DHCPREQUEST on %s to %s port %d (xid=0x%x)", - client -> name ? client -> name : client -> interface -> name, - inet_ntoa (destination.sin_addr), -- ntohs (destination.sin_port)); -+ ntohs (destination.sin_port), client -> xid); - - if (destination.sin_addr.s_addr != INADDR_BROADCAST && - fallback_interface) { -@@ -2303,10 +2345,10 @@ void send_decline (cpp) - - int result; - -- log_info ("DHCPDECLINE on %s to %s port %d", -- client->name ? client->name : client->interface->name, -+ log_info ("DHCPDECLINE on %s to %s port %d (xid=0x%x)", -+ client->name ? client->name : client->interface->name, - inet_ntoa(sockaddr_broadcast.sin_addr), -- ntohs(sockaddr_broadcast.sin_port)); -+ ntohs (sockaddr_broadcast.sin_port), client -> xid); - - /* Send out a packet. */ - result = send_packet(client->interface, NULL, &client->packet, -@@ -2349,10 +2391,10 @@ void send_release (cpp) - return; - } - -- log_info ("DHCPRELEASE on %s to %s port %d", -+ log_info ("DHCPRELEASE on %s to %s port %d (xid=0x%x)", - client -> name ? client -> name : client -> interface -> name, - inet_ntoa (destination.sin_addr), -- ntohs (destination.sin_port)); -+ ntohs (destination.sin_port), client -> xid); - - if (fallback_interface) { - result = send_packet(fallback_interface, NULL, &client->packet, --- -1.7.12.4 - diff --git a/0019-dhcp-4.2.4-P1-interval.patch b/0019-dhcp-4.2.4-P1-interval.patch new file mode 100644 index 0000000..ebfa60d --- /dev/null +++ b/0019-dhcp-4.2.4-P1-interval.patch @@ -0,0 +1,33 @@ +commit 9a312e3cd914da2b6f32651c94d1d1d4fb0bf359 +Author: Jiri Popelka +Date: Fri Jul 27 10:00:49 2012 +0200 + + isc_time_nowplusinterval() is not safe with 64-bit time_t (#662254, #789601) + +References: bsc#947780 +Index: dhcp-4.2.4-P2/common/dispatch.c +=================================================================== +--- dhcp-4.2.4-P2.orig/common/dispatch.c ++++ dhcp-4.2.4-P2/common/dispatch.c +@@ -320,7 +320,20 @@ void add_timeout (when, where, what, ref + q->next = timeouts; + timeouts = q; + +- isc_interval_set(&interval, sec & DHCP_SEC_MAX, usec * 1000); ++ /* isc_time_nowplusinterval() is not safe with 64-bit time_t and will ++ * return an error for sufficiently large intervals. We have to limit ++ * the interval to INT_MAX or less to ensure the interval doesn't ++ * overflow 32 bits, since the returned isc_time_t fields are ++ * 32-bit unsigned ints. ++ * ++ * HACK: The 9 is a magic number of seconds, since some time may have ++ * gone by since the last call to gettimeofday() and the one in ++ * isc_time_nowplusinterval(). ++ */ ++ if (sec > TIME_MAX) ++ sec = TIME_MAX - 9; ++ ++ isc_interval_set(&interval, sec, usec * 1000); + status = isc_time_nowplusinterval(&expires, &interval); + if (status != ISC_R_SUCCESS) { + /* diff --git a/0019-dhcp-4.2.x-ldap-debug-write.bnc835818.patch b/0019-dhcp-4.2.x-ldap-debug-write.bnc835818.patch deleted file mode 100644 index 40d00bf..0000000 --- a/0019-dhcp-4.2.x-ldap-debug-write.bnc835818.patch +++ /dev/null @@ -1,13 +0,0 @@ -References: bnc#835818 - ---- dhcp-4.2.x-ldap/server/ldap.c -+++ dhcp-4.2.x-ldap/server/ldap.c 2014/04/15 01:34:59 -@@ -2103,6 +2103,8 @@ ldap_read_config (void) - - if (x_parser_length(cfile) > 0) - { -+ ldap_write_debug (cfile->inbuf, cfile->buflen); -+ - res = conf_file_subparse (cfile, root_group, ROOT_GROUP); - if (res != ISC_R_SUCCESS) - { diff --git a/0021-dhcp-4.2.4-P2-bnc878846-conf-to-ldap.patch b/0021-dhcp-4.2.4-P2-bnc878846-conf-to-ldap.patch deleted file mode 100644 index ecb6107..0000000 --- a/0021-dhcp-4.2.4-P2-bnc878846-conf-to-ldap.patch +++ /dev/null @@ -1,32 +0,0 @@ -Index: dhcp-4.2.4-P2/contrib/ldap/dhcpd-conf-to-ldap -=================================================================== ---- dhcp-4.2.4-P2/contrib/ldap/dhcpd-conf-to-ldap -+++ dhcp-4.2.4-P2/contrib/ldap/dhcpd-conf-to-ldap -@@ -486,14 +486,23 @@ sub parse_subclass - $subclass = next_token (0); - parse_error () if !defined ($subclass); - -- $tmp = next_token (0); -- parse_error () if !defined ($tmp); -- parse_error () if !($tmp eq '{'); -- -+ if (substr($subclass,-1) eq ';') { -+ $tmp = ";"; -+ $subclass = substr($subclass,0,-1); -+ } else { -+ $tmp = next_token (0); -+ parse_error () if !defined ($tmp); -+ } -+ parse_error () if !($tmp eq '{' or $tmp eq ';'); - add_dn_to_stack ("cn=$subclass"); - $curentry{'type'} = 'subclass'; - $curentry{'class'} = $class; - $curentry{'subclass'} = $subclass; -+ -+ if ($tmp eq ';') { -+ print_entry () if %curentry; -+ remove_dn_from_stack (); -+ } - } - - diff --git a/0022-dhcp-4.2.x-contrib-conf-to-ldap-reorder.886094.patch b/0022-dhcp-4.2.x-contrib-conf-to-ldap-reorder.886094.patch deleted file mode 100644 index 532b2e7..0000000 --- a/0022-dhcp-4.2.x-contrib-conf-to-ldap-reorder.886094.patch +++ /dev/null @@ -1,250 +0,0 @@ -Author: Ales Novak -Subject: reorder config entries for ldap tree -References: bsc#886094, ISC-Bugs#37876 -Upstream: sent - -Reorder config to add all global options or option declarations -to the dhcpService object instead to create new service object, -e.g.: - -option opt-one code 1 = text; -class "class-one" { - option opt-one "..."; -}; -option opt-two code 2 = text; -class "class-two" { - option opt-two "..."; -}; - -has to contain both options (declarations) in the dhcpService, -followed by other objects as the dhcpClass objects under the -service in the ldap tree. ---- dhcp-4.2.4-P2/contrib/ldap/dhcpd-conf-to-ldap -+++ dhcp-4.2.4-P2/contrib/ldap/dhcpd-conf-to-ldap -@@ -137,6 +137,7 @@ add_dn_to_stack - local ($dn) = @_; - - $current_dn = "$dn, $current_dn"; -+ $curentry{'current_dn'} = $current_dn; - } - - -@@ -154,6 +155,26 @@ parse_error - exit (1); - } - -+sub -+new_entry -+{ -+ if (%curentry) { -+ $curentry{'current_dn'} = $current_dn; -+ push(@entrystack, {%curentry}); -+ undef(%curentry); -+ } -+} -+ -+sub -+pop_entry -+{ -+ if (%curentry) { -+ push(@outputlist, {%curentry}); -+ } -+ $rentry = pop(@entrystack); -+ %curentry = %$rentry if $rentry; -+} -+ - - sub - print_entry -@@ -167,7 +188,7 @@ print_entry - print "cn: $server\n"; - print "objectClass: top\n"; - print "objectClass: dhcpServer\n"; -- print "dhcpServiceDN: $current_dn\n"; -+ print "dhcpServiceDN: $curentry{'current_dn'}\n"; - if(grep(/FaIlOvEr/i, @use)) - { - foreach my $fo_peer (keys %failover) -@@ -179,7 +200,7 @@ print_entry - } - print "\n"; - -- print "dn: $current_dn\n"; -+ print "dn: $curentry{'current_dn'}\n"; - print "cn: $dhcpcn\n"; - print "objectClass: top\n"; - print "objectClass: dhcpService\n"; -@@ -195,7 +216,7 @@ print_entry - } - elsif ($curentry{'type'} eq 'subnet') - { -- print "dn: $current_dn\n"; -+ print "dn: $curentry{'current_dn'}\n"; - print "cn: " . $curentry{'ip'} . "\n"; - print "objectClass: top\n"; - print "objectClass: dhcpSubnet\n"; -@@ -215,7 +236,7 @@ print_entry - } - elsif ($curentry{'type'} eq 'shared-network') - { -- print "dn: $current_dn\n"; -+ print "dn: $curentry{'current_dn'}\n"; - print "cn: " . $curentry{'descr'} . "\n"; - print "objectClass: top\n"; - print "objectClass: dhcpSharedNetwork\n"; -@@ -226,7 +247,7 @@ print_entry - } - elsif ($curentry{'type'} eq 'group') - { -- print "dn: $current_dn\n"; -+ print "dn: $curentry{'current_dn'}\n"; - print "cn: group", $curentry{'idx'}, "\n"; - print "objectClass: top\n"; - print "objectClass: dhcpGroup\n"; -@@ -237,7 +258,7 @@ print_entry - } - elsif ($curentry{'type'} eq 'host') - { -- print "dn: $current_dn\n"; -+ print "dn: $curentry{'current_dn'}\n"; - print "cn: " . $curentry{'host'} . "\n"; - print "objectClass: top\n"; - print "objectClass: dhcpHost\n"; -@@ -254,7 +275,7 @@ print_entry - } - elsif ($curentry{'type'} eq 'pool') - { -- print "dn: $current_dn\n"; -+ print "dn: $curentry{'current_dn'}\n"; - print "cn: pool", $curentry{'idx'}, "\n"; - print "objectClass: top\n"; - print "objectClass: dhcpPool\n"; -@@ -273,7 +294,7 @@ print_entry - } - elsif ($curentry{'type'} eq 'class') - { -- print "dn: $current_dn\n"; -+ print "dn: $curentry{'current_dn'}\n"; - print "cn: " . $curentry{'class'} . "\n"; - print "objectClass: top\n"; - print "objectClass: dhcpClass\n"; -@@ -284,7 +305,7 @@ print_entry - } - elsif ($curentry{'type'} eq 'subclass') - { -- print "dn: $current_dn\n"; -+ print "dn: $curentry{'current_dn'}\n"; - print "cn: " . $curentry{'subclass'} . "\n"; - print "objectClass: top\n"; - print "objectClass: dhcpSubClass\n"; -@@ -344,7 +365,7 @@ sub parse_subnet - { - local ($ip, $tmp, $netmask); - -- print_entry () if %curentry; -+ new_entry (); - - $ip = next_token (0); - parse_error () if !defined ($ip); -@@ -374,7 +395,7 @@ sub parse_shared_network - { - local ($descr, $tmp); - -- print_entry () if %curentry; -+ new_entry (); - - $descr = next_token (0); - parse_error () if !defined ($descr); -@@ -393,7 +414,7 @@ sub parse_host - { - local ($descr, $tmp); - -- print_entry () if %curentry; -+ new_entry (); - - $host = next_token (0); - parse_error () if !defined ($host); -@@ -412,7 +433,7 @@ sub parse_group - { - local ($descr, $tmp); - -- print_entry () if %curentry; -+ new_entry (); - - $tmp = next_token (0); - parse_error () if !defined ($tmp); -@@ -435,7 +456,7 @@ sub parse_pool - { - local ($descr, $tmp); - -- print_entry () if %curentry; -+ new_entry (); - - $tmp = next_token (0); - parse_error () if !defined ($tmp); -@@ -458,7 +479,7 @@ sub parse_class - { - local ($descr, $tmp); - -- print_entry () if %curentry; -+ new_entry (); - - $class = next_token (0); - parse_error () if !defined ($class); -@@ -478,7 +499,7 @@ sub parse_subclass - { - local ($descr, $tmp); - -- print_entry () if %curentry; -+ new_entry (); - - $class = next_token (0); - parse_error () if !defined ($class); -@@ -500,7 +521,7 @@ sub parse_subclass - $curentry{'subclass'} = $subclass; - - if ($tmp eq ';') { -- print_entry () if %curentry; -+ pop_entry (); - remove_dn_from_stack (); - } - } -@@ -691,11 +712,11 @@ print STDERR "\n"; - my $token; - my $token_number = 0; - my $line_number = 0; --my %curentry; - my $cursubnet = ''; - my %curcounter = ( '' => { pool => 0, group => 0 } ); - - $current_dn = "$dhcpdn"; -+$curentry{'current_dn'} = $current_dn; - $curentry{'descr'} = $dhcpcn; - $line = ''; - %failover = (); -@@ -704,7 +725,7 @@ while (($token = next_token (1))) - { - if ($token eq '}') - { -- print_entry () if %curentry; -+ pop_entry (); - if($current_dn =~ /.+?,\s*${dhcpdn}$/) { - # don't go below dhcpdn ... - remove_dn_from_stack (); -@@ -762,6 +783,16 @@ while (($token = next_token (1))) - } - } - -+pop_entry (); -+ -+while ($#outputlist >= 0) { -+ $rentry = pop(@outputlist); -+ if ($rentry) { -+ %curentry = %$rentry; -+ print_entry (); -+ } -+} -+ - close(STDIN) if($i_conf); - close(STDOUT) if($o_ldif); - diff --git a/0023-dhcp-4.2.x-ddns-tsig-hmac-sha-support.890731.patch b/0023-dhcp-4.2.x-ddns-tsig-hmac-sha-support.890731.patch deleted file mode 100644 index 7cdd810..0000000 --- a/0023-dhcp-4.2.x-ddns-tsig-hmac-sha-support.890731.patch +++ /dev/null @@ -1,92 +0,0 @@ -Author: Thomas Markwalder -Subject: Addes addtional HMAC TSIG algorithms to DDNS -References: bsc#890731, ISC-Bugs#36947 -Upstream: yes - -TSIG-authenticated dynamic DNS updates now support the use of these -additional algorithms: hmac-sha1, hmac_sha224, hmac_sha256, hmac_sha384, -and hmac_sha512. [ISC-Bugs #36947] - -RFC4635 updates RFC2845 and mandates hmac-sha1 and hmac-sha256 support. - -diff --git a/includes/omapip/isclib.h b/includes/omapip/isclib.h -index fc45ef3..a9df110 100644 ---- a/includes/omapip/isclib.h -+++ b/includes/omapip/isclib.h -@@ -104,6 +104,11 @@ extern dhcp_context_t dhcp_gbl_ctx; - #define DHCP_MAXDNS_WIRE 256 - #define DHCP_MAXNS 3 - #define DHCP_HMAC_MD5_NAME "HMAC-MD5.SIG-ALG.REG.INT." -+#define DHCP_HMAC_SHA1_NAME "HMAC-SHA1.SIG-ALG.REG.INT." -+#define DHCP_HMAC_SHA224_NAME "HMAC-SHA224.SIG-ALG.REG.INT." -+#define DHCP_HMAC_SHA256_NAME "HMAC-SHA256.SIG-ALG.REG.INT." -+#define DHCP_HMAC_SHA384_NAME "HMAC-SHA384.SIG-ALG.REG.INT." -+#define DHCP_HMAC_SHA512_NAME "HMAC-SHA512.SIG-ALG.REG.INT." - - isc_result_t dhcp_isc_name(unsigned char *namestr, - dns_fixedname_t *namefix, -diff --git a/omapip/isclib.c b/omapip/isclib.c -index 9b7ff5f..e9cb321 100644 ---- a/omapip/isclib.c -+++ b/omapip/isclib.c -@@ -230,12 +230,24 @@ isclib_make_dst_key(char *inname, - dns_name_t *name; - dns_fixedname_t name0; - isc_buffer_t b; -+ unsigned int algorithm_code; - - isc_buffer_init(&b, secret, length); - isc_buffer_add(&b, length); - -- /* We only support HMAC_MD5 currently */ -- if (strcasecmp(algorithm, DHCP_HMAC_MD5_NAME) != 0) { -+ if (strcasecmp(algorithm, DHCP_HMAC_MD5_NAME) == 0) { -+ algorithm_code = DST_ALG_HMACMD5; -+ } else if (strcasecmp(algorithm, DHCP_HMAC_SHA1_NAME) == 0) { -+ algorithm_code = DST_ALG_HMACSHA1; -+ } else if (strcasecmp(algorithm, DHCP_HMAC_SHA224_NAME) == 0) { -+ algorithm_code = DST_ALG_HMACSHA224; -+ } else if (strcasecmp(algorithm, DHCP_HMAC_SHA256_NAME) == 0) { -+ algorithm_code = DST_ALG_HMACSHA256; -+ } else if (strcasecmp(algorithm, DHCP_HMAC_SHA384_NAME) == 0) { -+ algorithm_code = DST_ALG_HMACSHA384; -+ } else if (strcasecmp(algorithm, DHCP_HMAC_SHA512_NAME) == 0) { -+ algorithm_code = DST_ALG_HMACSHA512; -+ } else { - return(DHCP_R_INVALIDARG); - } - -@@ -244,7 +256,7 @@ isclib_make_dst_key(char *inname, - return(result); - } - -- return(dst_key_frombuffer(name, DST_ALG_HMACMD5, DNS_KEYOWNER_ENTITY, -+ return(dst_key_frombuffer(name, algorithm_code, DNS_KEYOWNER_ENTITY, - DNS_KEYPROTO_DNSSEC, dns_rdataclass_in, - &b, dhcp_gbl_ctx.mctx, dstkey)); - } -diff --git a/server/dhcpd.conf.5 b/server/dhcpd.conf.5 -index e639db6..def7bec 100644 ---- a/server/dhcpd.conf.5 -+++ b/server/dhcpd.conf.5 -@@ -1388,11 +1388,16 @@ dnssec-keygen, the above key would be created as follows: - dnssec-keygen -a HMAC-MD5 -b 128 -n USER DHCP_UPDATER - .fi - .PP --If you are using the BIND 8 dnskeygen program, the following command will --generate a key as seen above: --.PP -+The key name, algorithm, and secret must match that being used by the DNS -+server. The DHCP server currently supports the following algorithms: - .nf -- dnskeygen -H 128 -u -c -n DHCP_UPDATER -+ -+ HMAC-MD5 -+ HMAC-SHA1 -+ HMAC-SHA224 -+ HMAC-SHA256 -+ HMAC-SHA384 -+ HMAC-SHA512 - .fi - .PP - You may wish to enable logging of DNS updates on your DNS server. diff --git a/0025-dhcp-4.2.x-dhcpv6-retransmission-until-MRD.872609.patch b/0025-dhcp-4.2.x-dhcpv6-retransmission-until-MRD.872609.patch deleted file mode 100644 index 4ab93e8..0000000 --- a/0025-dhcp-4.2.x-dhcpv6-retransmission-until-MRD.872609.patch +++ /dev/null @@ -1,57 +0,0 @@ -Author: Jiri Popelka -References: bsc#872609, ISC-Bugs#21238 -Upstream: yes - -In client initiated message exchanges stop retransmission upon -reaching the MRD rather than at some point after it (#559153) -(Submitted to dhcp-bugs@isc.org - [ISC-Bugs #21238]) - -diff --git a/client/dhc6.c b/client/dhc6.c -index f8ad25d..63cbb65 100644 ---- a/client/dhc6.c -+++ b/client/dhc6.c -@@ -365,7 +365,7 @@ dhc6_retrans_init(struct client_state *client) - static void - dhc6_retrans_advance(struct client_state *client) - { -- struct timeval elapsed; -+ struct timeval elapsed, elapsed_after_RT; - - /* elapsed = cur - start */ - elapsed.tv_sec = cur_tv.tv_sec - client->start_time.tv_sec; -@@ -382,6 +382,8 @@ dhc6_retrans_advance(struct client_state *client) - elapsed.tv_sec += 1; - elapsed.tv_usec -= 1000000; - } -+ elapsed_after_RT.tv_sec = elapsed.tv_sec; -+ elapsed_after_RT.tv_usec = elapsed.tv_usec; - - /* - * RT for each subsequent message transmission is based on the previous -@@ -419,13 +421,10 @@ dhc6_retrans_advance(struct client_state *client) - elapsed.tv_usec -= 1000000; - } - if (elapsed.tv_sec >= client->MRD) { -- /* -- * wake at RT + cur = start + MRD -- */ -- client->RT = client->MRD + -- (client->start_time.tv_sec - cur_tv.tv_sec); -- client->RT = client->RT * 100 + -- (client->start_time.tv_usec - cur_tv.tv_usec) / 10000; -+ client->RT = client->MRD - elapsed_after_RT.tv_sec; -+ client->RT = client->RT * 100 - elapsed_after_RT.tv_usec / 10000; -+ if (client->RT < 0) -+ client->RT = 0; - } - client->txcount++; - } -@@ -1502,7 +1501,7 @@ check_timing6 (struct client_state *client, u_int8_t msg_type, - } - - /* Check if finished (-1 argument). */ -- if ((client->MRD != 0) && (elapsed.tv_sec > client->MRD)) { -+ if ((client->MRD != 0) && (elapsed.tv_sec >= client->MRD)) { - log_info("Max retransmission duration exceeded."); - return(CHK_TIM_MRD_EXCEEDED); - } diff --git a/0026-dhcp-4.2.x-disable-unused-ddns-port-in-server.891655.patch b/0026-dhcp-4.2.x-disable-unused-ddns-port-in-server.891655.patch deleted file mode 100644 index fe73ae9..0000000 --- a/0026-dhcp-4.2.x-disable-unused-ddns-port-in-server.891655.patch +++ /dev/null @@ -1,292 +0,0 @@ -Author: William Preston -Subject: do not bind ddns socket in server when ddns-update-style is none -References: bsc#891655 -Upstream: yes - -backported from commit 61ef216b8dc05bc4245b61eee812038757d12ffe -by Shawn Routhier with changes. - -diff --git a/client/dhclient.c b/client/dhclient.c -index bfa99fb..93f1dfc 100644 ---- a/client/dhclient.c -+++ b/client/dhclient.c -@@ -171,7 +171,7 @@ main(int argc, char **argv) { - #endif - - /* Set up the isc and dns library managers */ -- status = dhcp_context_create(); -+ status = dhcp_context_create(DHCP_CONTEXT_PRE_DB | DHCP_CONTEXT_POST_DB); - if (status != ISC_R_SUCCESS) - log_fatal("Can't initialize context: %s", - isc_result_totext(status)); -diff --git a/dhcpctl/dhcpctl.c b/dhcpctl/dhcpctl.c -index a4aee7f..2217956 100644 ---- a/dhcpctl/dhcpctl.c -+++ b/dhcpctl/dhcpctl.c -@@ -43,7 +43,7 @@ dhcpctl_status dhcpctl_initialize () - isc_result_t status; - - /* Set up the isc and dns library managers */ -- status = dhcp_context_create(); -+ status = dhcp_context_create(DHCP_CONTEXT_PRE_DB | DHCP_CONTEXT_POST_DB); - if (status != ISC_R_SUCCESS) - return status; - -diff --git a/includes/omapip/isclib.h b/includes/omapip/isclib.h -index a9df110..05a18f1 100644 ---- a/includes/omapip/isclib.h -+++ b/includes/omapip/isclib.h -@@ -121,7 +121,9 @@ isclib_make_dst_key(char *inname, - int length, - dst_key_t **dstkey); - --isc_result_t dhcp_context_create(void); -+#define DHCP_CONTEXT_PRE_DB 1 -+#define DHCP_CONTEXT_POST_DB 2 -+isc_result_t dhcp_context_create(int flags); - void isclib_cleanup(void); - - void dhcp_signal_handler(int signal); -diff --git a/omapip/isclib.c b/omapip/isclib.c -index e9cb321..d833bc9 100644 ---- a/omapip/isclib.c -+++ b/omapip/isclib.c -@@ -87,98 +87,102 @@ handle_signal(int sig, void (*handler)(int)) { - } - - isc_result_t --dhcp_context_create(void) { -+dhcp_context_create(int flags) { - isc_result_t result; - -- /* -- * Set up the error messages, this isn't the right place -- * for this call but it is convienent for now. -- */ -- result = dhcp_result_register(); -- if (result != ISC_R_SUCCESS) { -- log_fatal("register_table() %s: %u", "failed", result); -- } -- -- memset(&dhcp_gbl_ctx, 0, sizeof (dhcp_gbl_ctx)); -+ if ((flags & DHCP_CONTEXT_PRE_DB) != 0) { -+ /* -+ * Set up the error messages, this isn't the right place -+ * for this call but it is convienent for now. -+ */ -+ result = dhcp_result_register(); -+ if (result != ISC_R_SUCCESS) { -+ log_fatal("register_table() %s: %u", "failed", result); -+ } -+ -+ memset(&dhcp_gbl_ctx, 0, sizeof (dhcp_gbl_ctx)); - -- isc_lib_register(); -+ isc_lib_register(); - -- /* get the current time for use as the random seed */ -- gettimeofday(&cur_tv, (struct timezone *)0); -- isc_random_seed(cur_tv.tv_sec); -+ /* get the current time for use as the random seed */ -+ gettimeofday(&cur_tv, (struct timezone *)0); -+ isc_random_seed(cur_tv.tv_sec); - - #if defined (NSUPDATE) -- result = dns_lib_init(); -- if (result != ISC_R_SUCCESS) -- goto cleanup; -+ result = dns_lib_init(); -+ if (result != ISC_R_SUCCESS) -+ goto cleanup; -+#else -+ /* The dst library is inited as part of dns_lib_init, we don't -+ * need it if NSUPDATE is enabled */ -+ result = dst_lib_init(dhcp_gbl_ctx.mctx, NULL, 0); -+ if (result != ISC_R_SUCCESS) -+ goto cleanup; - #endif - -- result = isc_mem_create(0, 0, &dhcp_gbl_ctx.mctx); -- if (result != ISC_R_SUCCESS) -- goto cleanup; -- -- result = isc_appctx_create(dhcp_gbl_ctx.mctx, &dhcp_gbl_ctx.actx); -- if (result != ISC_R_SUCCESS) -- goto cleanup; -- -- result = isc_app_ctxstart(dhcp_gbl_ctx.actx); -- if (result != ISC_R_SUCCESS) -- goto cleanup; -- -- /* -- * Always ignore SIGPIPE. -- * Otherwise we will die before the errno == EPIPE -- * checks in the socket code are reached. -- * -- * Note: unlike isc_app_start(), isc_app_ctxstart() -- * does not set any signal handlers. -- */ -- result = handle_signal(SIGPIPE, SIG_IGN); -- if (result != ISC_R_SUCCESS) -- goto cleanup; -- -- dhcp_gbl_ctx.actx_started = ISC_TRUE; -- -- result = isc_taskmgr_createinctx(dhcp_gbl_ctx.mctx, -- dhcp_gbl_ctx.actx, -- 1, 0, -- &dhcp_gbl_ctx.taskmgr); -- if (result != ISC_R_SUCCESS) -- goto cleanup; -- -- result = isc_socketmgr_createinctx(dhcp_gbl_ctx.mctx, -- dhcp_gbl_ctx.actx, -- &dhcp_gbl_ctx.socketmgr); -- if (result != ISC_R_SUCCESS) -- goto cleanup; -- -- result = isc_timermgr_createinctx(dhcp_gbl_ctx.mctx, -- dhcp_gbl_ctx.actx, -- &dhcp_gbl_ctx.timermgr); -- if (result != ISC_R_SUCCESS) -- goto cleanup; -- -- result = isc_task_create(dhcp_gbl_ctx.taskmgr, 0, &dhcp_gbl_ctx.task); -- if (result != ISC_R_SUCCESS) -- goto cleanup; -+ result = isc_mem_create(0, 0, &dhcp_gbl_ctx.mctx); -+ if (result != ISC_R_SUCCESS) -+ goto cleanup; -+ -+ result = isc_appctx_create(dhcp_gbl_ctx.mctx, &dhcp_gbl_ctx.actx); -+ if (result != ISC_R_SUCCESS) -+ goto cleanup; -+ -+ result = isc_app_ctxstart(dhcp_gbl_ctx.actx); -+ if (result != ISC_R_SUCCESS) -+ goto cleanup; -+ -+ /* -+ * Always ignore SIGPIPE. -+ * Otherwise we will die before the errno == EPIPE -+ * checks in the socket code are reached. -+ * -+ * Note: unlike isc_app_start(), isc_app_ctxstart() -+ * does not set any signal handlers. -+ */ -+ result = handle_signal(SIGPIPE, SIG_IGN); -+ if (result != ISC_R_SUCCESS) -+ goto cleanup; -+ -+ dhcp_gbl_ctx.actx_started = ISC_TRUE; -+ -+ result = isc_taskmgr_createinctx(dhcp_gbl_ctx.mctx, -+ dhcp_gbl_ctx.actx, -+ 1, 0, -+ &dhcp_gbl_ctx.taskmgr); -+ if (result != ISC_R_SUCCESS) -+ goto cleanup; -+ -+ result = isc_socketmgr_createinctx(dhcp_gbl_ctx.mctx, -+ dhcp_gbl_ctx.actx, -+ &dhcp_gbl_ctx.socketmgr); -+ if (result != ISC_R_SUCCESS) -+ goto cleanup; -+ -+ result = isc_timermgr_createinctx(dhcp_gbl_ctx.mctx, -+ dhcp_gbl_ctx.actx, -+ &dhcp_gbl_ctx.timermgr); -+ if (result != ISC_R_SUCCESS) -+ goto cleanup; -+ -+ result = isc_task_create(dhcp_gbl_ctx.taskmgr, 0, &dhcp_gbl_ctx.task); -+ if (result != ISC_R_SUCCESS) -+ goto cleanup; -+ } - - #if defined (NSUPDATE) -- result = dns_client_createx(dhcp_gbl_ctx.mctx, -- dhcp_gbl_ctx.actx, -- dhcp_gbl_ctx.taskmgr, -- dhcp_gbl_ctx.socketmgr, -- dhcp_gbl_ctx.timermgr, -- 0, -- &dhcp_gbl_ctx.dnsclient); -- if (result != ISC_R_SUCCESS) -- goto cleanup; --#else -- /* The dst library is inited as part of dns_lib_init, we don't -- * need it if NSUPDATE is enabled */ -- result = dst_lib_init(dhcp_gbl_ctx.mctx, NULL, 0); -- if (result != ISC_R_SUCCESS) -- goto cleanup; -- -+ if ((flags & DHCP_CONTEXT_POST_DB) != 0) { -+ -+ result = dns_client_createx(dhcp_gbl_ctx.mctx, -+ dhcp_gbl_ctx.actx, -+ dhcp_gbl_ctx.taskmgr, -+ dhcp_gbl_ctx.socketmgr, -+ dhcp_gbl_ctx.timermgr, -+ 0, -+ &dhcp_gbl_ctx.dnsclient); -+ if (result != ISC_R_SUCCESS) -+ goto cleanup; -+ } - #endif - return(ISC_R_SUCCESS); - -diff --git a/omapip/test.c b/omapip/test.c -index e97a61f..2735716 100644 ---- a/omapip/test.c -+++ b/omapip/test.c -@@ -45,7 +45,7 @@ int main (int argc, char **argv) - omapi_object_t *connection = (omapi_object_t*)0; - isc_result_t status; - -- status = dhcp_context_create(); -+ status = dhcp_context_create(DHCP_CONTEXT_PRE_DB | DHCP_CONTEXT_POST_DB); - if (status != ISC_R_SUCCESS) { - fprintf(stderr, "Can't initialize context: %s\n", - isc_result_totext(status)); -diff --git a/relay/dhcrelay.c b/relay/dhcrelay.c -index 4ef6737..15e5c46 100644 ---- a/relay/dhcrelay.c -+++ b/relay/dhcrelay.c -@@ -195,7 +195,7 @@ main(int argc, char **argv) { - #endif - - /* Set up the isc and dns library managers */ -- status = dhcp_context_create(); -+ status = dhcp_context_create(DHCP_CONTEXT_PRE_DB | DHCP_CONTEXT_POST_DB); - if (status != ISC_R_SUCCESS) - log_fatal("Can't initialize context: %s", - isc_result_totext(status)); -diff --git a/server/dhcpd.c b/server/dhcpd.c -index b28c34c..434db00 100644 ---- a/server/dhcpd.c -+++ b/server/dhcpd.c -@@ -281,7 +281,7 @@ main(int argc, char **argv) { - close(fd); - - /* Set up the isc and dns library managers */ -- status = dhcp_context_create(); -+ status = dhcp_context_create(DHCP_CONTEXT_PRE_DB); - if (status != ISC_R_SUCCESS) - log_fatal("Can't initialize context: %s", - isc_result_totext(status)); -@@ -1100,6 +1100,11 @@ void postconf_initialization (int quiet) - if (ddns_update_style == DDNS_UPDATE_STYLE_AD_HOC) { - log_fatal("ddns-update-style ad_hoc no longer supported"); - } -+ -+ if (ddns_update_style != DDNS_UPDATE_STYLE_NONE && dhcp_context_create(DHCP_CONTEXT_POST_DB) -+ != ISC_R_SUCCESS) -+ log_fatal("Unable to complete ddns initialization"); -+ - #else - /* If we don't have support for updates compiled in tell the user */ - if (ddns_update_style != DDNS_UPDATE_STYLE_NONE) { --- -2.1.2 - diff --git a/0027-dhcp-4.2.x-handle-ifa_addr-NULL.909189.patch b/0027-dhcp-4.2.x-handle-ifa_addr-NULL.909189.patch deleted file mode 100644 index 4988906..0000000 --- a/0027-dhcp-4.2.x-handle-ifa_addr-NULL.909189.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 17e0eabe7700d02b48ed8b0a923427caad3b7b4b Mon Sep 17 00:00:00 2001 -From: Jiri Slaby -Date: Wed, 10 Dec 2014 13:48:03 +0100 -Subject: [PATCH] dhcp-4.2.x-handle-ifa_addr-NULL.909189 - -References: bsc#909189,bnc#870535 - -Fix to not crash in interface discovery when the interface -address is NULL. Bug has been introduced by the infiniband -support patch (bsc#870535). - -diff --git a/common/lpf.c b/common/lpf.c -index 9dc6053..892ccce 100644 ---- a/common/lpf.c -+++ b/common/lpf.c -@@ -605,6 +605,9 @@ get_hw_addr(struct interface_info *info) - - for (ifa = ifaddrs; ifa != NULL; ifa = ifa->ifa_next) { - -+ if (!ifa->ifa_addr) -+ continue; -+ - if (ifa->ifa_addr->sa_family != AF_PACKET) - continue; - --- -2.2.0 - diff --git a/dhcp-4.2.6.tar.gz b/dhcp-4.2.6.tar.gz deleted file mode 100644 index 27af539..0000000 --- a/dhcp-4.2.6.tar.gz +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:ab3aaab3c938a1c0e44fd75ee4d51682d35eb8328e991006cc6ee17514bfe291 -size 8935311 diff --git a/dhcp-4.2.6.tar.gz.asc b/dhcp-4.2.6.tar.gz.asc deleted file mode 100644 index 0e9dcfc..0000000 --- a/dhcp-4.2.6.tar.gz.asc +++ /dev/null @@ -1,11 +0,0 @@ ------BEGIN PGP SIGNATURE----- -Version: GnuPG v1.4.12 (NetBSD) - -iQEcBAABAgAGBQJS79gLAAoJEEWseFcYnNvFa08H+wRSA6dSHI6I86Qth7rDLvUX -JpGUILrypagAadb6a+UzpvEluhP8hg8Lex/PnskgOHDhkBqqiQLKp38B+2/LqxhU -Tx+yh9TikCLEf/I5vj6CWhZT7nip3WqfhXv+Z0EeIxsjgXPw6VEgGPpj/M6F8qqM -dmGmuzBWeXSnMEIwDGGW03dijN0ngfWl+9Be9A3l7dzfUAUVM6PwtLt72GA60K98 -/X8ZOgsRy6vOI9Nc7R6JPPD9lxx7Qp6meN0y3OtXjSZ1tvdeEjk2HGNJaNh4P/oZ -vzwi1yxAVA7JY8XPPJsBydruFfTB2Qx5M/Kn57bQOZnlWwSgXds2pEbv2JfgpYU= -=sDT9 ------END PGP SIGNATURE----- diff --git a/dhcp-4.3.3.tar.gz b/dhcp-4.3.3.tar.gz new file mode 100644 index 0000000..53fc989 --- /dev/null +++ b/dhcp-4.3.3.tar.gz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:553c4945b09b1c1b904c4780f34f72aaefa2fc8c6556715de0bc9d4e3d255ede +size 9205539 diff --git a/dhcp-4.3.3.tar.gz.asc b/dhcp-4.3.3.tar.gz.asc new file mode 100644 index 0000000..1dc4267 --- /dev/null +++ b/dhcp-4.3.3.tar.gz.asc @@ -0,0 +1,11 @@ +-----BEGIN PGP SIGNATURE----- +Version: GnuPG v1 + +iQEcBAABAgAGBQJV5YwhAAoJEG+m68mRGkwC0yYH/2qvlrVxE9odY8mooEWL3Mw4 +h7KycYZC5js2rY+u2DT7UHE3UnD671NzZQyGVYZaHYfFo3daW0OIt+CXV+H14jOt +Ai2OXU+6HiKNhT3WhCeoA4YFU1wflnxVeT0Cx7J40AUDewjkuAthZrF1jXrh8djQ +1VJ1Dq6HtkX5P1X+L84ugsMosXRoqMWmnUITE6GdzKqK29VQ8Y3jnCF1PJE1BwFJ +kYC3iwPjLKfPElEPROuK7bFUej1mr8agTM8lBcipMCtYx6R4DJoyviZ81tI+TzOm +PvPySKcM59o89XOqdgJ9xM2onlWCZHFLuw8ngY7MnyGFWLD92wFktAK6K6H2gWQ= +=Ezci +-----END PGP SIGNATURE----- diff --git a/dhcp.changes b/dhcp.changes index 4c7e639..4722981 100644 --- a/dhcp.changes +++ b/dhcp.changes @@ -1,3 +1,74 @@ +------------------------------------------------------------------- +Tue Oct 13 12:59:00 UTC 2015 - mt@suse.de + +- Applied a patch by Jiri Popelka catching dhcp server aborts with + "Unable to set up timer: out of range" on very long or infinite + timer intervals / lease lifetimes (bsc#947780) + [+ 0019-dhcp-4.2.4-P1-interval.patch] +- Corrected patch references in and a missed (bsc#919959) patch + description in previous changelog entry. + +------------------------------------------------------------------- +Mon Sep 14 14:39:34 UTC 2015 - mt@suse.de + +- Update to dhcp-4.3.3 (fate#319067) provinding many bug fixes, + features and obsoletes several patches we were using before. + For complete changelog, please read the RELNOTES file shipped + along with this package or online at: + https://kb.isc.org/article/AA-01297/82/DHCP-4.3.3-Release-Notes.html +- Replaced hostname patch with a dhcpv6 and fqdn aware variant: + [- 0006-dhcp-4.2.5-dhclient-send-hostname-rml.patch, + + 0006-dhcp-4.3.2-dhclient-send-hostname-or-fqdn.patch] +- Removed obsolete patches included upstream now: + [- 0007-dhcp-4.2.6-ldap-mt01.patch, + - 0009-dhcp-4.2.6-xen-checksum.patch, + - 0013-dhcp-4.2.3-P1-dhclient-log-pid.patch, + - 0015-Ignore-SIGPIPE-to-not-die-in-socket-code.patch, + - 0016-server-log-DHCPv6-addresses-assigned-to-clients.patch, + - 0019-dhcp-4.2.x-ldap-debug-write.bnc835818.patch, + - 0021-dhcp-4.2.4-P2-bnc878846-conf-to-ldap.patch, + - 0022-dhcp-4.2.x-contrib-conf-to-ldap-reorder.886094.patch, + - 0023-dhcp-4.2.x-ddns-tsig-hmac-sha-support.890731.patch, + - 0025-dhcp-4.2.x-dhcpv6-retransmission-until-MRD.872609.patch, + - 0026-dhcp-4.2.x-disable-unused-ddns-port-in-server.891655.patch] +- Adjusted patch numbers in the spec file: + [- 0008-dhcp-4.1.1-P1-lpf-bind-msg-fix.patch, + - 0010-dhcp-4.2.2-dhclient-option-checks.patch, + - 0011-dhcp-4.2.6-close-on-exec.patch, + - 0012-dhcp-4.2.2-quiet-dhclient.patch, + - 0014-Fixed-linux-interface-discovery-using-getifaddrs.patch, + - 0020-dhcp-4.2.x-chown-server-leases.bnc868253.patch, + - 0024-dhcp-4.2.x-dhcpv6-decline-on-DAD-failure.872609.patch, + + 0007-dhcp-4.1.1-P1-lpf-bind-msg-fix.patch, + + 0008-dhcp-4.2.2-dhclient-option-checks.patch, + + 0009-dhcp-4.2.6-close-on-exec.patch, + + 0010-dhcp-4.2.2-quiet-dhclient.patch, + + 0011-Fixed-linux-interface-discovery-using-getifaddrs.patch, + + 0012-dhcp-4.2.x-chown-server-leases.bnc868253.patch, + + 0013-dhcp-4.2.x-dhcpv6-decline-on-DAD-failure.872609.patch] +- Fixed to not pass DHCPv6 address lifetimes a positive (unsigned + 32bit) integers to scripts and properly format timestamps as long + to not break them on 64bit architectures (bsc#926159). + [+ 0014-dhclient6-unsigned-lifetimes-for-script-bsc-926159.patch] +- dhclient: expose next-server DHCPv4 option to script (bsc#928390) + [+ 0015-Expose-next-server-DHCPv4-option-to-dhclient-script.patch] +- Replaced infiniband support patch with fixed variant (bsc#910984): + [- 0017-dhcp-4.2.6-lpf-ip-over-ib-support.patch, + - 0018-dhcp-4.2.6-improved-xid.patch, + - 0027-dhcp-4.2.x-handle-ifa_addr-NULL.909189.patch, + + 0016-infiniband-support.patch] +- Moved dhcp-devel package include files and static libraries + to /usr/include/dhcp and /usr/lib/dhcp subdirectories. + DHCP requires a specific bind library version and conflicts + with the files shipped by bind-devel package, which is not + source and binary compatible (bsc#910686). +- Corrected changes to provide complete patch file references. +- Fixed server to not report success before send (bsc#919959) + [+ 0017-server-no-success-report-before-send.919959.patch] +- Fixed dhclient to check pre-init results reported by dhclient-script + and fail if pre-init fails for a requested interface (bsc#912098). + [+ 0018-client-fail-on-script-pre-init-error-bsc-912098.patch] + ------------------------------------------------------------------- Tue Feb 3 18:37:59 UTC 2015 - coolo@suse.com diff --git a/dhcp.keyring b/dhcp.keyring index d7caddc..5ffc091 100644 --- a/dhcp.keyring +++ b/dhcp.keyring @@ -1,33 +1,36 @@ -pub 2048R/189CDBC5 2013-01-31 Internet Systems Consortium, Inc. (Signing key, 2013) -sub 2048R/7F3D1D53 2013-01-31 [expires: 2015-01-31] +pub 2048R/911A4C02 2014-12-02 [verfällt: 2017-01-31] +uid Internet Systems Consortium, Inc. (Signing key, 2015-2016) +sig 911A4C02 2014-12-02 [selfsig] +sub 2048R/1BD14881 2014-12-02 [verfällt: 2017-01-31] +sig 911A4C02 2014-12-02 [keybind] -----BEGIN PGP PUBLIC KEY BLOCK----- -Version: GnuPG v1.4.12 (NetBSD) +Version: GnuPG v1.4.11 (GNU/Linux) -mQENBFEKeFYBCADaN83gsb0VDjlGZkYra0PPlHz/eczKBU+/6I/VBq/FcsFEc27/ -O8IE05rIID10rXLjZ0k8y4ydvhI40eVZfxwaFvQEX/StVtU1ie3F7TS02ZuJ1yal -YRtU29hhnZ5icDdiJ98gcZSH2WKhIWLRpmc60Lja/sTsO0lkLPJe9x2MDuzkQu9M -Z7hlMgqZxZ1I/mQ/KsjT3oUt8euwyntg8/w/cpY8H0EVjyBnZWV2yejsLnbCo947 -hbjvUMSluGs7AZP0d+yqpGNsgRQ9iHy0NiL3ELdBqD22cqGRGTkX76KcLoXvqLVY -450bBtXsI2uUXy5iL/eUkUP2JgWQybjju/M3ABEBAAG0SEludGVybmV0IFN5c3Rl -bXMgQ29uc29ydGl1bSwgSW5jLiAoU2lnbmluZyBrZXksIDIwMTMpIDxjb2Rlc2ln -bkBpc2Mub3JnPokBPgQTAQIAKAUCUQp4VgIbAwUJA8JnAAYLCQgHAwIGFQgCCQoL -BBYCAwECHgECF4AACgkQRax4Vxic28XzIQf6AwLblJ98KI6l8gWqKVHMErYgl9+Q -RiIxrqJtyn4OjeZHX9diVjv2HlsRjnTpNl5MiSB9tXvq+GX696w6dtpoqYjZEQoP -ZCwE2USR6XO71eYO3rxLBnc0ymRvQm4zB2YKqworQDym0+wE8xiGBO8LyyVDfS5G -aGWXl0YJkfNYXzhEp6toIiLwRE0uP0TarHcHCo2CboVBgODvDZqwSBfT+i6dT+Gy -6nVEh3j7XnqgjCQ25cGev9sHR3hobT/fxG0F2YZ7sMwpWj9q0Y/dOlY7SV/ZGSs+ -ubKQ55BWsTjJRrNqyDX8QLb8oVic5q/yQkV+RTs1sP5s6JSs0KqQdyR3ZbkBDQRR -CnhWAQgApxtu688JKcr6NXWOneWXn1Pti2jRhdVKNlNkGgLJ76vQTVdMmmTDwEty -YQM6C9qjIXj8cEwz+LGRUXoCXOX9Yokf5oOjNpQutn4KVS+IRvWMYaK0qsTaa/c0 -FaIiFWvswyGucXAX/q9H5IoK8uYKXv5ww7+x3l1etg9/QdDQ/CANyMQbjBn38Wfn -Fy/zoUl+mMZLfqs+3NwT5C+m/4M99SoyC7XQLaZt3PBO4rVjUnMkCgiXsNdDIZnv -0XgUKyzSgrdPZcqKEG3yj8v5aTOC2k60Ffw1/ytA3hyfxLmdxxsyGyNQ4ZY8ZxmB -Z6AyUWVK95bL4oQqUCqfzSscHpWokQARAQABiQElBBgBAgAPBQJRCnhWAhsMBQkD -wmcAAAoJEEWseFcYnNvF4JAH/0MlU+Iwu5k6II3KufE2agMsRD2hk1VkpZcC08qi -LfHxX/4HrCZd7jcViLpFeK+I5JaDM2G21Co9jBMoPh+EUDnalG3eglXgeNEbUfAZ -pM7c9UejTNVmrw6crcgeUhKS2l0oBu9gRRlcSJEYY8XngfKJHBscCrsafp3RMVkO -m4Ti4CcxOot3uQ10U8GojjtWp7bgqIaFBF8aV8vugXJLl9IHqgVEtvo9miM+0Tfi -evOzuZMrgVY4zI2ZiLcrVM1KuIeZ2nIKbNWkJpDH2ZwUfsIx/KTxjpqld+NStzGQ -B9v1wazIBDHQU4hq5ddOlk0lrLDAmMJzHbavlduWmFRkuv4= -=bGLP +mQENBFR9szQBCADAwiKoEyFh32NHLc+c1vGgZ2lDKvXd7MoZZAOM2NUJkaDqt+Xy +537ycGmZRqukpGUsa0fDeqjOq+l4paX3QnW1DEs8ypnWi5Zme4lYHysmNeG33ihe +SMeGRbnZi+9VTho3NGv3iM9gtRMDXTB5wi7OCu0XNypUtR2afP9F9EgRs4nJ5iMz +o5c1y0wH4y+lJ33NCHZDj8ditl64yMbuVlZOD3UxoQqw/8E6T4rHly64g9s6Ld7o +YybSN/hKIXFZRqrTebEd2LwZqGhPQIgYDUdumwvtw6jfrosbMOx0tan3esnxlptl +fbkmOsoi8pPJqlo2VtLBx9XN53ZFMqc/Pj3tABEBAAG0TUludGVybmV0IFN5c3Rl +bXMgQ29uc29ydGl1bSwgSW5jLiAoU2lnbmluZyBrZXksIDIwMTUtMjAxNikgPGNv +ZGVzaWduQGlzYy5vcmc+iQE9BBMBAgAoBQJUfbM0AhsDBQkEEtKABgsJCAcDAgYV +CAIJCgsEFgIDAQIeAQIXgAAKCRBvpuvJkRpMAhD3B/ip18kQSE4//Yt8VMF6kciD +bcCQAOwy45/1frZaX9wS5ri/pdHxB0vw4SwrpJgJEkLGG0sEzRwS87QeFCtGDhIw +J/+5JX6in0cJ+hr2G7DJUpVgKp3Y8lEZ3ch+gAZ3k45uzzoOTT4tm6uXWlkOnlPJ +jUb1s9bVzL9zUsJ7XaV5x4aR3Bw53/izJEIaxWHj1CEjAzRC7wPQpo/EK+fWzFBf +enSCBJEvW1vkomtb1jMdj+uhod1LzFdXHdQjDCSKn/Glpn/YcZ9/LkiUSwNLTpL4 +CxDbEis4QWNDndAR/u9REC1zDW/xQEC3UxsB06Zm9NaWjAHy8s0rOihgoetaroa5 +AQ0EVH2zNAEIAK3gbs1saWWHWGxsPuhOf+x18g0/+N7f4fZE7TTetPNhdOgY0LGx +ul9VHRoZgvPbnm+BZmZhYGMr/oWlTEuF+sa/Dr8SKqVDjYIj0qOzimMLYgaKYV8S +Q8LhUFtUQjm5V5J/FQ97NzO2fPgEIo7JbIVrhsPEms+1gl9yanKW/+HUovl7KUyN +RovfaJdpO4uyuY9CGz875DqE39EhflBWN96bpCUmp9O/VQs4eJTp6pkv2EkMVcEa +dtFXAVFlSFe/OUd83gbVXM9NCRfY98ZJaB2OnI1/lU8OomdHOt+z6h7bdtC/w42q +sjBmu+y2Fth4WXzPd7WbfvVdlMjbBHZLn8EAEQEAAYkBJQQYAQIADwUCVH2zNAIb +DAUJBBLSgAAKCRBvpuvJkRpMAhEXB/0Xq9NqR7vgSZTed7esSMWqOLWZloKdjxys +3BA9h3EXCkF6gMdE4b6OkIUH0V2aFCYJXZmyFol0tq50aETD62aCgCOVtxlkx5VH +tTLl/T1Venf9TDISiEmDBI+3DDqjA3YOH86Fql7Jq+EMZx4e2L50PWWyRR3Lzjp6 +TFe9Xh4rqQJoI0OBtLyX13Nfe/Ar4Z85DX6O1sv/CM0aWkfGbdMAeeHrDVRKaraH +ULyyX4kfu+mZj8AthxMpVDyaHil9WCX1uwGo+6rkiuAMvURbn05h5C92t2QUQJE1 +rvBKpzLEBW8qQq5foo+8yHHWpzue4i4r2uEJ3+FLUsjtlU+3F+Pq +=dem0 -----END PGP PUBLIC KEY BLOCK----- diff --git a/dhcp.spec b/dhcp.spec index b7a64ce..54d5558 100644 --- a/dhcp.spec +++ b/dhcp.spec @@ -16,7 +16,7 @@ # -%define isc_version 4.2.6 +%define isc_version 4.3.3 %define susefw2dir %{_sysconfdir}/sysconfig/SuSEfirewall2.d/services %define omc_prefix /usr/share/omc %define omc_svcdir %{omc_prefix}/svcinfo.d @@ -41,7 +41,7 @@ BuildRequires: openldap2-devel %endif BuildRequires: dos2unix BuildRequires: libtool -Version: 4.2.6 +Version: 4.3.3 Release: 0 Summary: Common Files Used by ISC DHCP Software License: BSD-3-Clause @@ -91,49 +91,33 @@ Patch2: 0002-dhcp-4.1.1-paranoia.patch Patch3: 0003-dhcp-4.2.2-man-includes.patch Patch4: 0004-dhcp-4.1.1-tmpfile.patch Patch5: 0005-dhcp-4.1.1-dhclient-exec-filedes.patch -Patch6: 0006-dhcp-4.2.5-dhclient-send-hostname-rml.patch -# PATCH-FIX-UPSTREAM ldap-patch bnc#788787,bnc#784640 -Patch7: 0007-dhcp-4.2.6-ldap-mt01.patch +Patch6: 0006-dhcp-4.3.2-dhclient-send-hostname-or-fqdn.patch # PATCH-FIX-UPSTREAM lpf-bind-msg-fix bnc#617795 -Patch8: 0008-dhcp-4.1.1-P1-lpf-bind-msg-fix.patch -# PATCH-FIX-SLE xen-checksum bnc#668194 -Patch9: 0009-dhcp-4.2.6-xen-checksum.patch +Patch7: 0007-dhcp-4.1.1-P1-lpf-bind-msg-fix.patch # PATCH-FIX-SLE dhclient-option-checks bnc#675052 -Patch10: 0010-dhcp-4.2.2-dhclient-option-checks.patch +Patch8: 0008-dhcp-4.2.2-dhclient-option-checks.patch # PATCH-FIX-OPENSUSE close-on-exec bnc#732910 -Patch11: 0011-dhcp-4.2.6-close-on-exec.patch +Patch9: 0009-dhcp-4.2.6-close-on-exec.patch # PATCH-FIX-OPENSUSE quiet-dhclient bnc#711420 -Patch12: 0012-dhcp-4.2.2-quiet-dhclient.patch -# PATCH-FIX-OPENSUSE dhclient-log-pid -Patch13: 0013-dhcp-4.2.3-P1-dhclient-log-pid.patch +Patch10: 0010-dhcp-4.2.2-quiet-dhclient.patch # PATCH-FIX-UPSTREAM use-getifaddrs bnc#791289,ISC-Bugs#31992 -Patch14: 0014-Fixed-linux-interface-discovery-using-getifaddrs.patch -# PATCH-FIX-UPSTREAM no-die-on-SIGPIPE bnc#794578,ISC-Bugs#32222 -Patch15: 0015-Ignore-SIGPIPE-to-not-die-in-socket-code.patch -# PATCH-FEATURE-UPSTREAM log-dhcpv6-client-addresses ISC-Bugs#26377 -Patch16: 0016-server-log-DHCPv6-addresses-assigned-to-clients.patch -# PATCH-FIX-SLE dhcp-4.2.6-lpf-ip-over-ib-support bnc#870535 -Patch17: 0017-dhcp-4.2.6-lpf-ip-over-ib-support.patch -# PATCH-FIX-SLE dhcp-4.2.6-improved-xid bnc#870535 -Patch18: 0018-dhcp-4.2.6-improved-xid.patch -# PATCH-FIX-SLE dhcp-4.2.x-ldap-debug-write bug#835818 -Patch19: 0019-dhcp-4.2.x-ldap-debug-write.bnc835818.patch +Patch11: 0011-Fixed-linux-interface-discovery-using-getifaddrs.patch # PATCH-FIX-OPENSUSE dhcp-4.2.x-chown-server-leases bnc#868253 -Patch20: 0020-dhcp-4.2.x-chown-server-leases.bnc868253.patch -# PATCH-FIX-SLE dhcp-4.2.4-P2-bnc878846-conf-to-ldap bnc#878846 -Patch21: 0021-dhcp-4.2.4-P2-bnc878846-conf-to-ldap.patch -# PATCH-FIX-SLE dhcp-4.2.x-contrib-conf-to-ldap-reorder bnc#886094 -Patch22: 0022-dhcp-4.2.x-contrib-conf-to-ldap-reorder.886094.patch -# PATCH-FIX-OPENSUSE dhcp-4.2.x-ddns-tsig-hmac-sha-support bnc#890731 -Patch23: 0023-dhcp-4.2.x-ddns-tsig-hmac-sha-support.890731.patch +Patch12: 0012-dhcp-4.2.x-chown-server-leases.bnc868253.patch # PATCH-FIX-SLE dhcp-4.2.x-dhcpv6-decline-on-DAD-failure bnc#872609 -Patch24: 0024-dhcp-4.2.x-dhcpv6-decline-on-DAD-failure.872609.patch -# PATCH-FIX-SLE dhcp-4.2.x-dhcpv6-retransmission-until-MRD bnc#872609 -Patch25: 0025-dhcp-4.2.x-dhcpv6-retransmission-until-MRD.872609.patch -# PATCH-FIX-SLE dhcp-4.2.x-disable-unused-ddns-port-in-server bnc#891655 -Patch26: 0026-dhcp-4.2.x-disable-unused-ddns-port-in-server.891655.patch -# PATCH-FIX-SLE dhcp-4.2.x-handle-ifa_addr-NULL bsc#909189 -Patch27: 0027-dhcp-4.2.x-handle-ifa_addr-NULL.909189.patch +Patch13: 0013-dhcp-4.2.x-dhcpv6-decline-on-DAD-failure.872609.patch +# PATCH-FIX-SLE dhclient6-unsigned-lifetimes-for-script bsc#926159 +Patch14: 0014-dhclient6-unsigned-lifetimes-for-script-bsc-926159.patch +# PATCH-FIX-SLE Expose-next-server-DHCPv4-option-to-dhclient-script bsc#928390 +Patch15: 0015-Expose-next-server-DHCPv4-option-to-dhclient-script.patch +# PATCH-FIX-SLE infiniband-support bnc#870535,bsc#909189,bsc#910984 +Patch16: 0016-infiniband-support.patch +# PATCH-FIX-SLE server-no-success-report-before-send bsc#919959 +Patch17: 0017-server-no-success-report-before-send.919959.patch +# PATCH-FIX-SLE client-fail-on-script-pre-init-error bsc#912098 +Patch18: 0018-client-fail-on-script-pre-init-error-bsc-912098.patch +# PATCH-FIX-SLE dhcp-4.2.4-P1-interval bsc#947780 +Patch19: 0019-dhcp-4.2.4-P1-interval.patch ## PreReq: /bin/touch /sbin/chkconfig sysconfig BuildRoot: %{_tmppath}/%{name}-%{version}-build @@ -167,7 +151,6 @@ PreReq: %insserv_prereq %fillup_prereq /bin/cat /bin/mkdir /bin/cp Summary: Header Files and Libraries for dhcpctl API Group: Development/Libraries/C and C++ Requires: dhcp = %{version} -Conflicts: bind-devel %if %{with_doc_package} @@ -253,9 +236,7 @@ Authors: %patch4 -p1 %patch5 -p1 %patch6 -p1 -%if %{with_ldap} %patch7 -p1 -%endif %patch8 -p1 %patch9 -p1 %patch10 -p1 @@ -268,14 +249,6 @@ Authors: %patch17 -p1 %patch18 -p1 %patch19 -p1 -%patch20 -p1 -%patch21 -p1 -%patch22 -p1 -%patch23 -p1 -%patch24 -p1 -%patch25 -p1 -%patch26 -p1 -%patch27 -p1 ## find . -type f -name \*.cat\* -exec rm -f {} \; dos2unix contrib/ms2isc/* @@ -317,8 +290,8 @@ export RPM_OPT_FLAGS LDFLAGS export CFLAGS FFLAGS CXXFLAGS # %{?suse_update_config:%{suse_update_config -f}} -libtoolize --force -autoreconf -i +#libtoolize --force +#autoreconf -f -i # %configure \ --enable-dhcpv6 \ @@ -495,15 +468,20 @@ rm -f $RPM_BUILD_ROOT/etc/{dhcpd,dhclient}.conf.example find contrib doc/examples -type f | xargs chmod -x # install bind libs+includes needed for dhcp-devel pushd bind -install -d -m0755 $RPM_BUILD_ROOT%_includedir/ +install -d -m0755 $RPM_BUILD_ROOT%_includedir/dhcp/ for i in include/* ; do - cp -r $i $RPM_BUILD_ROOT%_includedir/ + cp -r $i $RPM_BUILD_ROOT%_includedir/dhcp/ done -install -d -m0755 $RPM_BUILD_ROOT%_libdir/ +install -d -m0755 $RPM_BUILD_ROOT%_libdir/dhcp/ for l in lib/lib*.a ; do - install -m0644 $l $RPM_BUILD_ROOT%_libdir/ + install -m0644 $l $RPM_BUILD_ROOT%_libdir/dhcp/ done popd +# move also all dhcp-devel files to dhcp subdirectories +mv $RPM_BUILD_ROOT%_includedir/{dhcpctl,isc-dhcp,omapip} \ + $RPM_BUILD_ROOT%_includedir/dhcp/ +mv $RPM_BUILD_ROOT%_libdir/lib*.* \ + $RPM_BUILD_ROOT%_libdir/dhcp/ %pre server /usr/sbin/useradd -r -g nogroup -s /bin/false -c "DHCP server daemon" -d /var/lib/dhcp dhcpd 2> /dev/null ||: @@ -727,8 +705,10 @@ if ! test -f /.buildenv; then rm -rf $RPM_BUILD_ROOT; fi %files devel %defattr(-,root,root) -%_libdir/lib* -%{_prefix}/include/* +%dir %_libdir/dhcp +%_libdir/dhcp/lib* +%dir %{_prefix}/include/dhcp +%{_prefix}/include/dhcp/* %doc %{_mandir}/man3/omapi.3.gz %doc %{_mandir}/man3/dhcpctl.3.gz