From 560b29399c6a9ecdf3845b258e1f6aeb97c57ac88185fad6b9be122dffe93ac8 Mon Sep 17 00:00:00 2001 From: Marius Tomaschewski Date: Wed, 25 Jul 2012 20:48:38 +0000 Subject: [PATCH] - Update to ISC dhcp-4.2.4-P1 release, providing security fixes (bnc#772924) - Moved lease file check to a separate action so it is not used in restart -- it can fail when the daemon rewrites the lease causing a restart failure then (bnc#762108 regression). - Request dhcp6.sntp-servers in /etc/dhclient6.conf and forward to netconfig for processing (bnc#770236). - Removed RFC 4833 TZ options from client requests [unused]. - Update to ISC dhcp-4.2.4 release, fixing a dhcpv6 server assert crash while accessing lease on heap (bnc#767661) and providing... OBS-URL: https://build.opensuse.org/package/show/network:dhcp/dhcp?expand=0&rev=92 --- dhclient-script | 3 + dhclient.conf | 4 +- dhclient6.conf | 17 +- dhcp-4.2.3-P1-dhclient-option_param-a.diff | 41 --- ....2.3-P1-dhclient-zero-length-options.patch | 65 ---- dhcp-4.2.3-P1-ldap-patch-mt01.diff.bz2 | 3 - dhcp-4.2.3-P2-ldap-filter-value-escape.patch | 200 ------------ dhcp-4.2.3-P2.tar.bz2 | 3 - dhcp-4.2.4-P1.tar.bz2 | 3 + ....2.4-dhclient-option-checks.bnc675052.diff | 17 +- dhcp-4.2.4-ldap-patch-mt01.patch.bz2 | 3 + dhcp-4.2.4-parsing-and-printing-options.patch | 298 ++++++++++++++++++ dhcp.changes | 113 +++++++ dhcp.spec | 16 +- rc.dhcpd | 75 +++-- rc.dhcpd6 | 75 +++-- 16 files changed, 540 insertions(+), 396 deletions(-) delete mode 100644 dhcp-4.2.3-P1-dhclient-option_param-a.diff delete mode 100644 dhcp-4.2.3-P1-dhclient-zero-length-options.patch delete mode 100644 dhcp-4.2.3-P1-ldap-patch-mt01.diff.bz2 delete mode 100644 dhcp-4.2.3-P2-ldap-filter-value-escape.patch delete mode 100644 dhcp-4.2.3-P2.tar.bz2 create mode 100644 dhcp-4.2.4-P1.tar.bz2 rename dhcp-4.2.2-dhclient-option-checks.bnc675052.diff => dhcp-4.2.4-dhclient-option-checks.bnc675052.diff (74%) create mode 100644 dhcp-4.2.4-ldap-patch-mt01.patch.bz2 create mode 100644 dhcp-4.2.4-parsing-and-printing-options.patch diff --git a/dhclient-script b/dhclient-script index 733a1a0..2e71a4f 100644 --- a/dhclient-script +++ b/dhclient-script @@ -68,6 +68,9 @@ netconfig_modify() { (new_dhcp6_server_id) k='DHCP6SID' ;; (new_dhcp6_domain_search) k='DNSSEARCH' ;; (new_dhcp6_name_servers) k='DNSSERVERS' ;; + (new_dhcp6_sntp_servers) k='NTPSERVERS' ;; + #(new_dhcp6_nis_domain) k='NISDOMAIN' ;; + #(new_dhcp6_nis_servers) k='NISSERVERS' ;; (*) k="dhclient6_${v#new_}" ;; esac ;; diff --git a/dhclient.conf b/dhclient.conf index 130340d..023e1e1 100644 --- a/dhclient.conf +++ b/dhclient.conf @@ -45,8 +45,8 @@ request subnet-mask, broadcast-address, routers, domain-name-servers, nis-domain, nis-servers, nds-context, nds-servers, nds-tree-name, netbios-name-servers, netbios-dd-server, - netbios-node-type, netbios-scope, ntp-servers, - rfc4833-tz-posix-string, rfc4833-tz-name; + netbios-node-type, netbios-scope, ntp-servers; +# rfc4833-tz-posix-string, rfc4833-tz-name; # We request above options, require only the IP configuration: require subnet-mask; diff --git a/dhclient6.conf b/dhclient6.conf index 1b3aff8..5ea1bf4 100644 --- a/dhclient6.conf +++ b/dhclient6.conf @@ -1,13 +1,22 @@ # Client configuration file example for DHCPv6 +# Define RFC 4833 timezone options: option dhcp6.rfc4833-tz-posix-string code 41 = string; option dhcp6.rfc4833-tz-name code 42 = string; +# You may add the options you've declared now to the request, +# but it is still needed to use them in a netconfig module or +# dhclient-script. I didn't found the time to implement it +# yet -- feel free to provide a module / patch. +# dhcp6.rfc4833-tz-posix-string, dhcp6.rfc4833-tz-name; # The client side command to enable rapid-commit (2 packet exchange) send dhcp6.rapid-commit; -# name-servers and domain-search are requested by default. -# here is the way to request sip-servers-addresses too -also request dhcp6.sip-servers-addresses, - dhcp6.rfc4833-tz-posix-string, dhcp6.rfc4833-tz-name; +# The name-servers and domain-search are requested by default. +# +# We request also sntp-servers, see dhcp-options(5) for more, +# but make sure, the underlying software using it supports IPv6 +# (e.g. ypbind <= 1.35 doesn't, don't add nis-servers/domain!) +# +also request dhcp6.sntp-servers; diff --git a/dhcp-4.2.3-P1-dhclient-option_param-a.diff b/dhcp-4.2.3-P1-dhclient-option_param-a.diff deleted file mode 100644 index db11c28..0000000 --- a/dhcp-4.2.3-P1-dhclient-option_param-a.diff +++ /dev/null @@ -1,41 +0,0 @@ -From 3e3874a4e322536a683d2c22602c6c1a3f39df8e Mon Sep 17 00:00:00 2001 -From: Marius Tomaschewski -Date: Thu, 5 Jan 2012 16:20:42 +0100 -Subject: [PATCH] dhclient: parse_option_param: Bad format a - -When the server provides options using the "a" array type, such as: -option rfc3442-classless-routes code 121 = array of unsigned integer 8; -the option is stored into the lease file, but when the client reads the -lease file next time, it complains about, because "a" array type aren't -recognized in the parsing loop and the option (lease?) discarded. - -Signed-off-by: Marius Tomaschewski ---- - common/parse.c | 4 ++-- - 1 files changed, 2 insertions(+), 2 deletions(-) - -diff --git a/common/parse.c b/common/parse.c -index 61488c1..0fca63c 100644 ---- a/common/parse.c -+++ b/common/parse.c -@@ -5518,7 +5518,7 @@ int parse_option_decl (oc, cfile) - /* Parse the option data... */ - do { - for (fmt = option -> format; *fmt; fmt++) { -- if (*fmt == 'A') -+ if (*fmt == 'A' || *fmt == 'a') - break; - if (*fmt == 'o' && fmt != option -> format) - continue; -@@ -5732,7 +5732,7 @@ int parse_option_decl (oc, cfile) - } - } - token = next_token (&val, (unsigned *)0, cfile); -- } while (*fmt == 'A' && token == COMMA); -+ } while ((*fmt == 'A' || *fmt == 'a') && token == COMMA); - - if (token != SEMI) { - parse_warn (cfile, "semicolon expected."); --- -1.7.7 - diff --git a/dhcp-4.2.3-P1-dhclient-zero-length-options.patch b/dhcp-4.2.3-P1-dhclient-zero-length-options.patch deleted file mode 100644 index 9127c45..0000000 --- a/dhcp-4.2.3-P1-dhclient-zero-length-options.patch +++ /dev/null @@ -1,65 +0,0 @@ -From 70330e5cb91616dd235b63e54b9fe0dc15f3d61b Mon Sep 17 00:00:00 2001 -From: Marius Tomaschewski -Date: Thu, 5 Jan 2012 16:28:50 +0100 -Subject: [PATCH] zero-length option lease parse error in dhclient6 - -common/parse.c: -Use peek_token only or the next_token call behind the while loop -will cause two warnings / errors in the log: - lease line XX: semicolon expected. - lease line XX: Unexpected end of file. - [there is a } behind the semicolon as the next token in my case] -and the option (lease?) gets discarded. -To reproduce, use "send dhcp6.rapid-commit;" to /etc/dhclient6.conf, -remove the lease file and start the client. When the lease is bound, -kill the client and start it again. - -client/dhclient.c: -More of cosmetic nature - do not print zero-length options like there -would be a value missed, e.g. " option dhcp6.rapid-commit ;". - -Signed-off-by: Marius Tomaschewski ---- - client/dhclient.c | 11 ++++++++--- - common/parse.c | 2 +- - 2 files changed, 9 insertions(+), 4 deletions(-) - -diff --git a/client/dhclient.c b/client/dhclient.c -index bee8e1d..ee87aa6 100644 ---- a/client/dhclient.c -+++ b/client/dhclient.c -@@ -2769,10 +2769,15 @@ void write_lease_option (struct option_cache *oc, - } - if (evaluate_option_cache (&ds, packet, lease, client_state, - in_options, cfg_options, scope, oc, MDL)) { -- fprintf(leaseFile, "%soption %s%s%s %s;\n", preamble, -- name, dot, oc->option->name, -- pretty_print_option(oc->option, ds.data, ds.len, -+ if(oc->option->format && oc->option->format[0] == 'Z' && ds.len == 0) { -+ fprintf(leaseFile, "%soption %s%s%s;\n", preamble, -+ name, dot, oc->option->name); -+ } else { -+ fprintf(leaseFile, "%soption %s%s%s %s;\n", preamble, -+ name, dot, oc->option->name, -+ pretty_print_option(oc->option, ds.data, ds.len, - 1, 1)); -+ } - data_string_forget (&ds, MDL); - } - } -diff --git a/common/parse.c b/common/parse.c -index 0fca63c..fe661d5 100644 ---- a/common/parse.c -+++ b/common/parse.c -@@ -5715,7 +5715,7 @@ int parse_option_decl (oc, cfile) - goto alloc; - - case 'Z': /* Zero-length option */ -- token = next_token(&val, (unsigned *)0, cfile); -+ token = peek_token(&val, (unsigned *)0, cfile); - if (token != SEMI) { - parse_warn(cfile, - "semicolon expected."); --- -1.7.7 - diff --git a/dhcp-4.2.3-P1-ldap-patch-mt01.diff.bz2 b/dhcp-4.2.3-P1-ldap-patch-mt01.diff.bz2 deleted file mode 100644 index ff5d76d..0000000 --- a/dhcp-4.2.3-P1-ldap-patch-mt01.diff.bz2 +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:f791f5490fe238a97f1d6875e8e7ba1423cb71dbb7203c0887e2522c0d9e83a6 -size 11872 diff --git a/dhcp-4.2.3-P2-ldap-filter-value-escape.patch b/dhcp-4.2.3-P2-ldap-filter-value-escape.patch deleted file mode 100644 index 5d6b5ba..0000000 --- a/dhcp-4.2.3-P2-ldap-filter-value-escape.patch +++ /dev/null @@ -1,200 +0,0 @@ -From e8ad30e0ed9dcb77cb1a87e5e676f4dc56a36afa Mon Sep 17 00:00:00 2001 -From: Marius Tomaschewski -Date: Tue, 31 Jan 2012 17:38:25 +0100 -Subject: [PATCH] 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). - -Signed-off-by: Marius Tomaschewski ---- - server/ldap.c | 116 +++++++++++++++++++++++++++++++++++++++++++++++--------- - 1 files changed, 97 insertions(+), 19 deletions(-) - -diff --git a/server/ldap.c b/server/ldap.c -index 68acbbb..274e934 100644 ---- a/server/ldap.c -+++ b/server/ldap.c -@@ -1024,6 +1024,17 @@ _do_ldap_retry(int ret, const char *server, int port) - 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) - { -@@ -1801,6 +1812,7 @@ 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); -@@ -1825,24 +1837,49 @@ ldap_read_config (void) - 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); -+ return (ISC_R_FAILURE); -+ } -+ - snprintf (hfilter, sizeof (hfilter), -- "(&(objectClass=dhcpServer)(cn=%s))", ldap_dhcp_server_cn); -- } -- else -- { -- if(0 == get_host_entry(fqdn, sizeof(fqdn), NULL, 0)) -- { -- snprintf (hfilter, sizeof (hfilter), -- "(&(objectClass=dhcpServer)(|(cn=%s)(cn=%s)))", -- unme.nodename, fqdn); -+ "(&(objectClass=dhcpServer)(cn=%s))", bv_o[0].bv_val); -+ -+ ber_memfree(bv_o[0].bv_val); - } - else - { -- snprintf (hfilter, sizeof (hfilter), -- "(&(objectClass=dhcpServer)(cn=%s))", unme.nodename); -- } -+ if (_do_ldap_str2esc_filter_bv(unme.nodename, 0, &bv_o[0]) == NULL) -+ { -+ log_error ("Cannot escape ldap filter value %s: %m", unme.nodename); -+ 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); -+ 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); -+ } - - ldap_enable_retry = 1; - do -@@ -1929,9 +1966,20 @@ ldap_read_config (void) - 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))(dhcpServerDN=%s)))", -- hostdn, hostdn, hostdn); -+ 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, -@@ -2082,16 +2130,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); -@@ -2163,6 +2224,8 @@ find_haddr_in_ldap (struct host_decl **hp, int htype, unsigned hlen, - char up_hwaddr[20]; - char lo_hwaddr[20]; - int ret; -+ struct berval bv_o[2]; -+ - - if (local_family != AF_INET) - return (0); -@@ -2199,9 +2262,24 @@ find_haddr_in_ldap (struct host_decl **hp, int htype, unsigned hlen, - 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)(dhcpHWAddress=%s %s)))", -- type_str, lo_hwaddr, type_str, up_hwaddr); -+ 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; --- -1.7.7 - diff --git a/dhcp-4.2.3-P2.tar.bz2 b/dhcp-4.2.3-P2.tar.bz2 deleted file mode 100644 index 4eb0ee6..0000000 --- a/dhcp-4.2.3-P2.tar.bz2 +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:ba303393c9e986c51265c6ffded0d8bab1abeb3fe37103d4385802345a2b1109 -size 9369048 diff --git a/dhcp-4.2.4-P1.tar.bz2 b/dhcp-4.2.4-P1.tar.bz2 new file mode 100644 index 0000000..2bff6d4 --- /dev/null +++ b/dhcp-4.2.4-P1.tar.bz2 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8f93249ff9bd7bcf3a11cec51dc7cc5d5d7ce9767abd09fc20d7427e01f42fa4 +size 8022549 diff --git a/dhcp-4.2.2-dhclient-option-checks.bnc675052.diff b/dhcp-4.2.4-dhclient-option-checks.bnc675052.diff similarity index 74% rename from dhcp-4.2.2-dhclient-option-checks.bnc675052.diff rename to dhcp-4.2.4-dhclient-option-checks.bnc675052.diff index 6414600..53058c8 100644 --- a/dhcp-4.2.2-dhclient-option-checks.bnc675052.diff +++ b/dhcp-4.2.4-dhclient-option-checks.bnc675052.diff @@ -1,8 +1,8 @@ diff --git a/client/dhclient.c b/client/dhclient.c -index 9fd7ccc..82c26bb 100644 +index 1afccd5..37ec809 100644 --- a/client/dhclient.c +++ b/client/dhclient.c -@@ -3251,7 +3251,7 @@ void script_write_params (client, prefix, lease) +@@ -3275,7 +3275,7 @@ void script_write_params (client, prefix, lease) } else { log_error("suspect value in %s " "option - discarded", @@ -11,7 +11,7 @@ index 9fd7ccc..82c26bb 100644 } } -@@ -3264,7 +3264,7 @@ void script_write_params (client, prefix, lease) +@@ -3288,7 +3288,7 @@ void script_write_params (client, prefix, lease) } else { log_error("suspect value in %s " "option - discarded", @@ -19,8 +19,8 @@ index 9fd7ccc..82c26bb 100644 + "server-name"); } } - -@@ -4193,7 +4193,7 @@ static int check_domain_name(const char *ptr, size_t len, int dots) + +@@ -4216,7 +4216,7 @@ static int check_domain_name(const char *ptr, size_t len, int dots) const char *p; /* not empty or complete length not over 255 characters */ @@ -30,10 +30,10 @@ index 9fd7ccc..82c26bb 100644 /* consists of [[:alnum:]-]+ labels separated by [.] */ diff --git a/common/options.c b/common/options.c -index 80fd8db..6b95f3b 100644 +index e485222..bc9bb97 100644 --- a/common/options.c +++ b/common/options.c -@@ -3916,7 +3916,7 @@ pretty_escape(char **dst, char *dend, const unsigned char **src, +@@ -3918,7 +3918,7 @@ pretty_escape(char **dst, char *dend, const unsigned char **src, } } else if (**src == '"' || **src == '\'' || **src == '$' || **src == '`' || **src == '\\' || **src == '|' || @@ -42,6 +42,3 @@ index 80fd8db..6b95f3b 100644 if (*dst + 2 > dend) return -1; --- -1.7.3.4 - diff --git a/dhcp-4.2.4-ldap-patch-mt01.patch.bz2 b/dhcp-4.2.4-ldap-patch-mt01.patch.bz2 new file mode 100644 index 0000000..36a8d62 --- /dev/null +++ b/dhcp-4.2.4-ldap-patch-mt01.patch.bz2 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3143784b9de510e9ef0ec4010ce00904308600d8fa2d23cacb240ec5592e81af +size 10882 diff --git a/dhcp-4.2.4-parsing-and-printing-options.patch b/dhcp-4.2.4-parsing-and-printing-options.patch new file mode 100644 index 0000000..4d678b7 --- /dev/null +++ b/dhcp-4.2.4-parsing-and-printing-options.patch @@ -0,0 +1,298 @@ +From 29c3de8d0973c66c9c8261c0f3d0deeccfd29994 Mon Sep 17 00:00:00 2001 +From: Marius Tomaschewski +Date: Tue, 12 Jun 2012 10:01:10 +0200 +Subject: [PATCH] dhcp-4.2.4-parsing-and-printing-options + +- Fix some issues in the code for parsing and printing options. + [ISC-Bugs #27314] - properly parse a zero length option from + a lease file. + [ISC-Bugs #22796] - properly determine if we parsed a 16 or 32 bit + value in evaluate_numeric_expression (extract-int). + [ISC-Bugs #22625] - properly print options that have several fields + followed by an array of something for example "fIa" + [ISC-Bugs #27289] - properly parse options in declarations that have + several fields followed by an array of something for example "fIa" + + This patch obsoletes the following (bnc#739696) patches: + - dhclient: parse_option_param: Bad format a + [complete, upstream corrected version] + - zero-length option lease parse error in dhclient6 + [upstream accepted variant] + - properly determine if we parsed a 16 or 32 bit value + [additional upstream patch] +--- + client/dhclient.c | 19 +++++++++++++--- + common/options.c | 60 +++++++++++++++++++++++++++++++++++++++++++++------- + common/parse.c | 23 ++++++++++++++++--- + common/tables.c | 7 +++-- + common/tree.c | 35 ++++++++++++++++++++---------- + 5 files changed, 113 insertions(+), 31 deletions(-) + +diff --git a/client/dhclient.c b/client/dhclient.c +index f920c64..025337a 100644 +--- a/client/dhclient.c ++++ b/client/dhclient.c +@@ -2793,10 +2793,21 @@ void write_lease_option (struct option_cache *oc, + } + if (evaluate_option_cache (&ds, packet, lease, client_state, + in_options, cfg_options, scope, oc, MDL)) { +- fprintf(leaseFile, "%soption %s%s%s %s;\n", preamble, +- name, dot, oc->option->name, +- pretty_print_option(oc->option, ds.data, ds.len, +- 1, 1)); ++ /* The option name */ ++ fprintf(leaseFile, "%soption %s%s%s", preamble, ++ name, dot, oc->option->name); ++ ++ /* The option value if there is one */ ++ if ((oc->option->format == NULL) || ++ (oc->option->format[0] != 'Z')) { ++ fprintf(leaseFile, " %s", ++ pretty_print_option(oc->option, ds.data, ++ ds.len, 1, 1)); ++ } ++ ++ /* The closing semi-colon and newline */ ++ fprintf(leaseFile, ";\n"); ++ + data_string_forget (&ds, MDL); + } + } +diff --git a/common/options.c b/common/options.c +index bc9bb97..fa27688 100644 +--- a/common/options.c ++++ b/common/options.c +@@ -1683,6 +1683,8 @@ const char *pretty_print_option (option, data, len, emit_commas, emit_quotes) + const unsigned char *dp = data; + char comma; + unsigned long tval; ++ isc_boolean_t a_array = ISC_FALSE; ++ int len_used; + + if (emit_commas) + comma = ','; +@@ -1707,6 +1709,8 @@ const char *pretty_print_option (option, data, len, emit_commas, emit_quotes) + fmtbuf [l] = option -> format [i]; + switch (option -> format [i]) { + case 'a': ++ a_array = ISC_TRUE; ++ /* Fall through */ + case 'A': + --numelem; + fmtbuf [l] = 0; +@@ -1735,6 +1739,8 @@ const char *pretty_print_option (option, data, len, emit_commas, emit_quotes) + hunksize++; + comma = ':'; + numhunk = 0; ++ a_array = ISC_TRUE; ++ hunkinc = 1; + } + fmtbuf [l + 1] = 0; + break; +@@ -1828,13 +1834,34 @@ const char *pretty_print_option (option, data, len, emit_commas, emit_quotes) + len - hunksize); + + /* If this is an array, compute its size. */ +- if (!numhunk) +- numhunk = len / hunksize; +- /* See if we got an exact number of hunks. */ +- if (numhunk > 0 && numhunk * hunksize < len) +- log_error ("%s: %d extra bytes at end of array\n", +- option -> name, +- len - numhunk * hunksize); ++ if (numhunk == 0) { ++ if (a_array == ISC_TRUE) { ++ /* ++ * It is an 'a' type array - we repeat the ++ * last format type. A binary string for 'X' ++ * is also like this. hunkinc is the size ++ * of the last format type and we add 1 to ++ * cover the entire first record. ++ */ ++ numhunk = ((len - hunksize) / hunkinc) + 1; ++ len_used = hunksize + ((numhunk - 1) * hunkinc); ++ } else { ++ /* ++ * It is an 'A' type array - we repeat the ++ * entire record ++ */ ++ numhunk = len / hunksize; ++ len_used = numhunk * hunksize; ++ } ++ ++ /* See if we got an exact number of hunks. */ ++ if (len_used < len) { ++ log_error ("%s: %d extra bytes at end of array\n", ++ option -> name, ++ len - len_used); ++ } ++ } ++ + + /* A one-hunk array prints the same as a single hunk. */ + if (numhunk < 0) +@@ -1842,7 +1869,24 @@ const char *pretty_print_option (option, data, len, emit_commas, emit_quotes) + + /* Cycle through the array (or hunk) printing the data. */ + for (i = 0; i < numhunk; i++) { +- for (j = 0; j < numelem; j++) { ++ if ((a_array == ISC_TRUE) && (i != 0) && (numelem > 0)) { ++ /* ++ * For 'a' type of arrays we repeat ++ * only the last format character ++ * We should never hit the case of numelem == 0 ++ * but let's include the check to be safe. ++ */ ++ j = numelem - 1; ++ } else { ++ /* ++ * for other types of arrays or the first ++ * time through for 'a' types, we go through ++ * the entire set of format characters. ++ */ ++ j = 0; ++ } ++ ++ for (; j < numelem; j++) { + switch (fmtbuf [j]) { + case 't': + /* endbuf-1 leaves room for NULL. */ +diff --git a/common/parse.c b/common/parse.c +index 434085a..f72c0d6 100644 +--- a/common/parse.c ++++ b/common/parse.c +@@ -5518,11 +5518,26 @@ int parse_option_decl (oc, cfile) + if (status != ISC_R_SUCCESS || option == NULL) + return 0; + ++ fmt = option->format; ++ + /* Parse the option data... */ + do { +- for (fmt = option -> format; *fmt; fmt++) { +- if (*fmt == 'A') ++ for (; *fmt; fmt++) { ++ if (*fmt == 'A') { ++ /* 'A' is an array of records, start at ++ * the beginning ++ */ ++ fmt = option->format; ++ break; ++ } ++ ++ if (*fmt == 'a') { ++ /* 'a' is an array of the last field, ++ * back up one format character ++ */ ++ fmt--; + break; ++ } + if (*fmt == 'o' && fmt != option -> format) + continue; + switch (*fmt) { +@@ -5718,7 +5733,7 @@ int parse_option_decl (oc, cfile) + goto alloc; + + case 'Z': /* Zero-length option */ +- token = next_token(&val, (unsigned *)0, cfile); ++ token = peek_token(&val, (unsigned *)0, cfile); + if (token != SEMI) { + parse_warn(cfile, + "semicolon expected."); +@@ -5735,7 +5750,7 @@ int parse_option_decl (oc, cfile) + } + } + token = next_token (&val, (unsigned *)0, cfile); +- } while (*fmt == 'A' && token == COMMA); ++ } while (*fmt && token == COMMA); + + if (token != SEMI) { + parse_warn (cfile, "semicolon expected."); +diff --git a/common/tables.c b/common/tables.c +index c820d83..d224dc1 100644 +--- a/common/tables.c ++++ b/common/tables.c +@@ -64,9 +64,10 @@ HASH_FUNCTIONS (option_code, const unsigned *, struct option, + some event. The special all-ones value means 'infinite'. May either + be printed as a decimal, eg, "3600", or as this name, eg, "infinite". + f - flag (true or false) +- A - array of whatever precedes (e.g., IA means array of IP addresses) +- a - array of the preceding character (e.g., IIa means two or more IP +- addresses) ++ A - array of all that precedes (e.g., fIA means array of records of ++ a flag and an IP address) ++ a - array of the preceding character (e.g., fIa means a single flag ++ followed by an array of IP addresses) + U - name of an option space (universe) + F - implicit flag - the presence of the option indicates that the + flag is true. +diff --git a/common/tree.c b/common/tree.c +index 3c978b0..7754398 100644 +--- a/common/tree.c ++++ b/common/tree.c +@@ -2409,6 +2409,7 @@ int evaluate_numeric_expression (result, packet, lease, client_state, + struct binding *binding; + struct binding_value *bv; + unsigned long ileft, iright; ++ int rc = 0; + + switch (expr -> op) { + case expr_check: +@@ -2477,32 +2478,42 @@ int evaluate_numeric_expression (result, packet, lease, client_state, + status = (evaluate_data_expression + (&data, packet, lease, client_state, in_options, + cfg_options, scope, expr -> data.extract_int, MDL)); +- if (status && data.len >= 2) ++ if (status && data.len >= 2) { + *result = getUShort (data.data); ++ rc = 1; ++ } + #if defined (DEBUG_EXPRESSIONS) +- log_debug ("num: extract_int16 (%s) = %ld", +- ((status && data.len >= 2) ? +- print_hex_1 (data.len, data.data, 60) : "NULL"), +- *result); ++ if (rc == 1) { ++ log_debug ("num: extract_int16 (%s) = %ld", ++ print_hex_1(data.len, data.data, 60) ++ *result); ++ } else { ++ log_debug ("num: extract_int16 (NULL) = NULL"); ++ } + #endif + if (status) data_string_forget (&data, MDL); +- return (status && data.len >= 2); ++ return (rc); + + case expr_extract_int32: + memset (&data, 0, sizeof data); + status = (evaluate_data_expression + (&data, packet, lease, client_state, in_options, + cfg_options, scope, expr -> data.extract_int, MDL)); +- if (status && data.len >= 4) ++ if (status && data.len >= 4) { + *result = getULong (data.data); ++ rc = 1; ++ } + #if defined (DEBUG_EXPRESSIONS) +- log_debug ("num: extract_int32 (%s) = %ld", +- ((status && data.len >= 4) ? +- print_hex_1 (data.len, data.data, 60) : "NULL"), +- *result); ++ if (rc == 1) { ++ log_debug ("num: extract_int32 (%s) = %ld", ++ print_hex_1 (data.len, data.data, 60), ++ *result); ++ } else { ++ log_debug ("num: extract_int32 (NULL) = NULL"); ++ } + #endif + if (status) data_string_forget (&data, MDL); +- return (status && data.len >= 4); ++ return (rc); + + case expr_const_int: + *result = expr -> data.const_int; +-- +1.7.7 + diff --git a/dhcp.changes b/dhcp.changes index c5e2bdc..481cfdb 100644 --- a/dhcp.changes +++ b/dhcp.changes @@ -1,3 +1,116 @@ +------------------------------------------------------------------- +Wed Jul 25 18:13:59 UTC 2012 - mt@suse.com + +- Update to ISC dhcp-4.2.4-P1 release, providing following security + fixes (bnc#772924): + - Previously the server code was relaxed to allow packets with zero + length client ids to be processed. Under some situations use of + zero length client ids can cause the server to go into an infinite + loop. As such ids are not valid according to RFC 2132 section 9.14 + the server no longer accepts them. Client ids with a length of 1 + are also invalid but the server still accepts them in order to + minimize disruption. The restriction will likely be tightened in + the future to disallow ids with a length of 1. + Thanks to Markus Hietava of Codenomicon CROSS project for the + finding this issue and CERT-FI for vulnerability coordination. + [ISC-Bugs #29851] CVE: CVE-2012-3571 + - When attempting to convert a DUID from a client id option + into a hardware address handle unexpected client ids properly. + Thanks to Markus Hietava of Codenomicon CROSS project for the + finding this issue and CERT-FI for vulnerability coordination. + [ISC-Bugs #29852] CVE: CVE-2012-3570 + - A pair of memory leaks were found and fixed. Thanks to Glen + Eustace of Massey University, New Zealand for finding this issue. + [ISC-Bugs #30024] CVE: CVE-2012-3954 +- Moved lease file check to a separate action so it is not used in + restart -- it can fail when the daemon rewrites the lease causing + a restart failure then (bnc#762108 regression). +- Request dhcp6.sntp-servers in /etc/dhclient6.conf and forward to + netconfig for processing (bnc#770236). +- Removed RFC 4833 TZ options from client requests [unused]. + +------------------------------------------------------------------- +Tue Jun 19 06:40:03 UTC 2012 - mt@suse.com + +- Update to ISC dhcp-4.2.4 release, fixing a dhcpv6 server assert + crash while accessing lease on heap (bnc#767661) and providing + the following fixes: + - Rotate the lease file when running in v6 mode. + Thanks to Christoph Moench-Tegeder at Astaro for the + report and the first version of the patch. [ISC-Bugs #24887] + - Fixed the code that checks if an address the server is planning + to hand out is in a reserved range. This would appear as the + server being out of addresses in pools with particular ranges. + [ISC-Bugs #26498] + - In the DDNS code handle error conditions more gracefully and + add more logging code. The major change is to handle unexpected + cancel events from the DNS client code. [ISC-Bugs #26287] + - Tidy up the receive calls and eliminate the need for found_pkt. + [ISC-Bugs #25066] + - Add support for Infiniband over sockets to the server and + relay code. We've tested this on Solaris and hope to expand + support for Infiniband in the future. This patch also corrects + some issues we found in the socket code. [ISC-Bugs #24245] + - Add a compile time check for the presence of the noreturn attribute + and use it for log_fatal if it's available. This will help code + checking programs to eliminate false positives. [ISC-Bugs #27539] + - Fixed many compilation problems ("set, but not used" warnings) for + gcc 4.6 that may affect Ubuntu 11.10 users. [ISC-Bugs #27588] + - Modify the code that determines if an outstanding DDNS request + should be cancelled. This patch results in cancelling the + outstanding request less often. It fixes the problem caused + by a client doing a release where the TXT and PTR records + weren't removed from the DNS. [ISC-BUGS #27858] + - Use offsetof() instead of sizeof() to get the sizes for + dhcpv6_relay_packet and dhcpv6_packet in several more places. + Thanks to a report from Bruno Verstuyft and Vincent Demaertelaere + of Excentis. [ISC-Bugs #27941] + - Remove outdated note in the description of the bootp keyword about + the option not satisfying the requirement of failover peers for + denying dynamic bootp clients. [ISC-bugs #28574] + - Multiple items to clean up IPv6 address processing. When processing + an IA that we've seen check to see if the addresses are usable + (not in use by somebody else) before handing it out. + When reading in leases from the file discard expired addresses. + When picking an address for a client include the IA ID in + addition to the client ID to generally pick different addresses + for different IAs. [ISC-Bugs #23138] [ISC-Bugs #27945] + [ISC-Bugs #25586] [ISC-Bugs #27684] + - Remove unnecessary checks in the lease query code and clean up + several compiler issues (some dereferences of NULL and treating + an int as a boolean). [ISC-Bugs #26203] + - Fix the NA and PD allocation code to handle the case where a client + provides a preference and the server doesn't have any addresses or + prefixes available. Previoulsy the server ignored the request with + this patch it replies with a NoAddrsAvail or NoPrefixAvail response. + By default the code performs according to the errata of August 2010 + for RFC 3315 section 17.2.2; to enable the previous style see the + section on RFC3315_PRE_ERRATA_2010_08 in includes/site.h. + This option may be removed in the future. Thanks to Jiri Popelka at + Red Hat for the patch. [ISC-Bugs #22676] + - Fix up some issues found by static analysis. A potential memory leak + and NULL dereference in omapi. The use of a boolean test instead of + a bitwise test in dst. [ISC-Bugs #28941] +- Replaced our patches with a complete and upstream verified patch: + - Fix some issues in the code for parsing and printing options. + [ISC-Bugs #27314] - properly parse a zero length option from + a lease file. + [ISC-Bugs #22796] - properly determine if we parsed a 16 or + 32 bit value in evaluate_numeric_expression (extract-int). + [ISC-Bugs #22625] - properly print options that have several + fields followed by an array of something for example "fIa" + [ISC-Bugs #27289] - properly parse options in declarations + that have several fields followed by an array of something + for example "fIa" + This patch obsoletes the following (bnc#739696) patches: + - dhclient: parse_option_param: Bad format a + - zero-length option lease parse error in dhclient6 +- Merged ldap and options check patches for the new version +- Fixed dhcp-server init script to check syntax and fail while + force-reload and restart to avoid stopping of running daemon + followed by start failure (bnc#762108). Added libgcc_s.so to + chroot, so the server can report assert/crash line. + ------------------------------------------------------------------- Wed Mar 28 15:06:47 UTC 2012 - mt@suse.com diff --git a/dhcp.spec b/dhcp.spec index 8e24455..0eeb5ef 100644 --- a/dhcp.spec +++ b/dhcp.spec @@ -16,7 +16,7 @@ # -%define isc_version 4.2.3-P2 +%define isc_version 4.2.4-P1 %define susefw2dir %{_sysconfdir}/sysconfig/SuSEfirewall2.d/services %define omc_prefix /usr/share/omc %define omc_svcdir %{omc_prefix}/svcinfo.d @@ -36,7 +36,7 @@ BuildRequires: openldap2-devel %endif BuildRequires: dos2unix BuildRequires: libtool -Version: 4.2.3.P2 +Version: 4.2.4.P1 Release: 0. Summary: Common Files Used by ISC DHCP Software License: BSD-3-Clause @@ -80,16 +80,14 @@ Patch15: contrib-lease-path.diff Patch20: dhcp-4.1.1-dhclient-exec-filedes.diff Patch21: dhcp-4.2.2-dhclient-send-hostname-rml.diff ## patch repo lives here: http://www.suse.de/~mt/git/dhcp-ldap.git/ -Patch30: dhcp-4.2.3-P1-ldap-patch-mt01.diff.bz2 -Patch31: dhcp-4.2.3-P2-ldap-filter-value-escape.patch +Patch30: dhcp-4.2.4-ldap-patch-mt01.patch.bz2 Patch40: dhcp-4.1.1-P1-lpf-bind-msg-fix.diff Patch44: dhcp-4.2.2-xen-checksum.diff -Patch45: dhcp-4.2.2-dhclient-option-checks.bnc675052.diff +Patch45: dhcp-4.2.4-dhclient-option-checks.bnc675052.diff Patch46: dhcp-4.2.2-close-on-exec.diff Patch47: dhcp-4.2.2-quiet-dhclient.bnc711420.diff -Patch48: dhcp-4.2.3-P1-dhclient-option_param-a.diff -Patch49: dhcp-4.2.3-P1-dhclient-log-pid.diff -Patch50: dhcp-4.2.3-P1-dhclient-zero-length-options.patch +Patch48: dhcp-4.2.3-P1-dhclient-log-pid.diff +Patch49: dhcp-4.2.4-parsing-and-printing-options.patch ## PreReq: /bin/touch /sbin/chkconfig sysconfig BuildRoot: %{_tmppath}/%{name}-%{version}-build @@ -209,7 +207,6 @@ Authors: %patch21 -p1 %if %{with_ldap} %patch30 -p1 -%patch31 -p1 %endif %patch40 -p1 %patch44 -p1 @@ -218,7 +215,6 @@ Authors: %patch47 -p1 %patch48 -p1 %patch49 -p1 -%patch50 -p1 ## find . -type f -name \*.cat\* -exec rm -f {} \; dos2unix contrib/ms2isc/* diff --git a/rc.dhcpd b/rc.dhcpd index ebc0e66..8704db5 100644 --- a/rc.dhcpd +++ b/rc.dhcpd @@ -221,7 +221,7 @@ case "$1" in get_ldd_deps() { :; } fi cplibs=`for i in /$libdir/{libresolv.so.*,libnss_*.so.*} \ - /$libdir/{libpthread.so.0,libdl.so.2} ; + /$libdir/{libpthread.so.0,libdl.so.2,libgcc_s.so.*} ; do if [ -s "$i" ] ; then echo "$i" @@ -352,26 +352,35 @@ case "$1" in rc_status ;; restart) - ## Stop the service and regardless of whether it was - ## running or not, start it again. - $0 stop - sleep 3 - $0 start - - # Remember status and be quiet - rc_status + ## Check syntax and when it is OK, stop the service + ## and regardless of whether it was running or not, + ## start it again. + if ! $0 check-syntax &>/dev/null ; then + echo -n "Syntax check reports errors, see log messages" + rc_failed + rc_status -v + else + $0 stop + sleep 3 + $0 start + # Remember status and be quiet + rc_status + fi ;; force-reload) ## Signal the daemon to reload its config. Most daemons ## do this on signal 1 (SIGHUP). ## If it does not support it, restart. - echo -n "Reload service $DAEMON" - if [ "$SUPPORTS_HUP" = "yes" ]; then + echo -n "Reload service $DAEMON" killproc -p $DAEMON_STATE/$DAEMON_PIDFILE -HUP $DAEMON_BIN #touch $DAEMON_STATE/$DAEMON_PIDFILE rc_status -v + elif ! $0 check-syntax &>/dev/null ; then + echo -n "Syntax check reports errors, see log messages" + rc_failed + rc_status -v else $0 stop && sleep 3 && $0 start rc_status @@ -419,31 +428,39 @@ case "$1" in test $rc = 1 && echo restart ;; check-syntax|syntax-check) - echo "Checking syntax of $DAEMON_CONF: " + echo -n "Checking syntax of $DAEMON_CONF: " ## this nice bit is from Edwin Groothuis: ## check syntax (quiet) $DAEMON_BIN $DHCPDv_OPT -q -t -cf $DAEMON_CONF - if ! [ $? -eq 0 ]; then + rc_status + if [ $? -ne 0 ]; then + echo "" ## check syntax (verbose) $DAEMON_BIN $DHCPDv_OPT -t -cf $DAEMON_CONF - echo -e '\nConfig is NOT okay\n' - else - echo 'Config is okay. Hope you also specified existent network devices ;) ' - - ## in v3, lease file checking is also implemented - if [ $DAEMON_BIN != "/usr/sbin/dhcpd-2" ]; then - ## check leases file (quiet) - $DAEMON_BIN $DHCPDv_OPT -q -T -cf $DAEMON_CONF -lf ${DAEMON_STATE}/db/$DAEMON_LEASES - if ! [ $? -eq 0 ]; then - ## check leases file (verbose) - $DAEMON_BIN $DHCPDv_OPT -T -cf $DAEMON_CONF -lf ${DAEMON_STATE}/db/$DAEMON_LEASES - echo -e '\nLease file is NOT okay' - else - echo 'Lease file is okay' - fi - fi + echo -ne '\nConfig is NOT okay' + rc_failed fi + rc_status -v + ;; + check-lease|check-lease-file) + echo -n "Checking lease file $DAEMON_LEASES: " + + if [ -s ${DAEMON_STATE}/db/$DAEMON_LEASES ] ; then + ## check leases file (quiet) + $DAEMON_BIN $DHCPDv_OPT -q -T -cf /dev/null -lf ${DAEMON_STATE}/db/$DAEMON_LEASES + rc_status + if [ $? -ne 0 ]; then + echo "" + ## check leases file (verbose) + $DAEMON_BIN $DHCPDv_OPT -T -cf $DAEMON_CONF -lf ${DAEMON_STATE}/db/$DAEMON_LEASES + echo -ne '\nLease file is NOT okay' + rc_failed + fi + else + rc_status -u + fi + rc_status -v ;; *) echo "Usage: $0 {start|stop|status|try-restart|restart|force-reload|reload|probe|check-syntax} [-v]" diff --git a/rc.dhcpd6 b/rc.dhcpd6 index bc656db..28ac5f4 100644 --- a/rc.dhcpd6 +++ b/rc.dhcpd6 @@ -224,7 +224,7 @@ case "$1" in get_ldd_deps() { :; } fi cplibs=`for i in /$libdir/{libresolv.so.*,libnss_*.so.*} \ - /$libdir/{libpthread.so.0,libdl.so.2} ; + /$libdir/{libpthread.so.0,libdl.so.2,libgcc_s.so.*} ; do if [ -s "$i" ] ; then echo "$i" @@ -355,26 +355,35 @@ case "$1" in rc_status ;; restart) - ## Stop the service and regardless of whether it was - ## running or not, start it again. - $0 stop - sleep 3 - $0 start - - # Remember status and be quiet - rc_status + ## Check syntax and when it is OK, stop the service + ## and regardless of whether it was running or not, + ## start it again. + if ! $0 check-syntax &>/dev/null ; then + echo -n "Syntax check reports errors, see log messages" + rc_failed + rc_status -v + else + $0 stop + sleep 3 + $0 start + # Remember status and be quiet + rc_status + fi ;; force-reload) ## Signal the daemon to reload its config. Most daemons ## do this on signal 1 (SIGHUP). ## If it does not support it, restart. - echo -n "Reload service $DAEMON" - if [ "$SUPPORTS_HUP" = "yes" ]; then + echo -n "Reload service $DAEMON" killproc -p $DAEMON_STATE/$DAEMON_PIDFILE -HUP $DAEMON_BIN #touch $DAEMON_STATE/$DAEMON_PIDFILE rc_status -v + elif ! $0 check-syntax &>/dev/null ; then + echo -n "Syntax check reports errors, see log messages" + rc_failed + rc_status -v else $0 stop && sleep 3 && $0 start rc_status @@ -422,31 +431,39 @@ case "$1" in test $rc = 1 && echo restart ;; check-syntax|syntax-check) - echo "Checking syntax of $DAEMON_CONF: " + echo -n "Checking syntax of $DAEMON_CONF: " ## this nice bit is from Edwin Groothuis: ## check syntax (quiet) $DAEMON_BIN $DHCPDv_OPT -q -t -cf $DAEMON_CONF - if ! [ $? -eq 0 ]; then + rc_status + if [ $? -ne 0 ]; then + echo "" ## check syntax (verbose) $DAEMON_BIN $DHCPDv_OPT -t -cf $DAEMON_CONF - echo -e '\nConfig is NOT okay\n' - else - echo 'Config is okay. Hope you also specified existent network devices ;) ' - - ## in v3, lease file checking is also implemented - if [ $DAEMON_BIN != "/usr/sbin/dhcpd-2" ]; then - ## check leases file (quiet) - $DAEMON_BIN $DHCPDv_OPT -q -T -cf $DAEMON_CONF -lf ${DAEMON_STATE}/db/$DAEMON_LEASES - if ! [ $? -eq 0 ]; then - ## check leases file (verbose) - $DAEMON_BIN $DHCPDv_OPT -T -cf $DAEMON_CONF -lf ${DAEMON_STATE}/db/$DAEMON_LEASES - echo -e '\nLease file is NOT okay' - else - echo 'Lease file is okay' - fi - fi + echo -ne '\nConfig is NOT okay' + rc_failed fi + rc_status -v + ;; + check-lease|check-lease-file) + echo -n "Checking lease file $DAEMON_LEASES: " + + if [ -s ${DAEMON_STATE}/db/$DAEMON_LEASES ] ; then + ## check leases file (quiet) + $DAEMON_BIN $DHCPDv_OPT -q -T -cf /dev/null -lf ${DAEMON_STATE}/db/$DAEMON_LEASES + rc_status + if [ $? -ne 0 ]; then + echo "" + ## check leases file (verbose) + $DAEMON_BIN $DHCPDv_OPT -T -cf $DAEMON_CONF -lf ${DAEMON_STATE}/db/$DAEMON_LEASES + echo -ne '\nLease file is NOT okay' + rc_failed + fi + else + rc_status -u + fi + rc_status -v ;; *) echo "Usage: $0 {start|stop|status|try-restart|restart|force-reload|reload|probe|check-syntax} [-v]"