]> git.ipfire.org Git - thirdparty/dhcp.git/commitdiff
[v4_1_esv] Server now handles prefix/pool prefix length mismatches
authorThomas Markwalder <tmark@isc.org>
Mon, 12 Jun 2017 15:43:15 +0000 (11:43 -0400)
committerThomas Markwalder <tmark@isc.org>
Mon, 12 Jun 2017 15:43:15 +0000 (11:43 -0400)
        Merged in 35378.

RELNOTES
server/confpars.c
server/dhcpv6.c

index 058eab151a4305d034586a8f4894d6ace21b9e0e..cfc13d09e9a9552fc5af9fce00443b0f8862e85c 100644 (file)
--- a/RELNOTES
+++ b/RELNOTES
@@ -140,6 +140,17 @@ by Eric Young (eay@cryptsoft.com).
   freebsd, linux, macos, netbsd, openbsd.
   [ISC-Bugs #36169]
 
+- The server nows checks both the address and length of a prefix delegation
+  when attempting to match it to a prefix pool.  This ensures the server
+  responds properly when pool configurations change such that once valid,
+  "in-pool" delegations are now treated as being invalid.  During lease
+  file loading at startup, the server will discard any PD leases that
+  are deemed "out-of-pool" either by address or mis-matched prefix length.
+  Clients seeking to renew or rebind such leases will get a response of
+  No Binding in the case of the former, and the prefix delegation with
+  lifetimes set to zero in the case of the latter.
+  [ISC-Bugs #35378]
+
                        Changes since 4.1-ESV-R14b1
 - None
 
index 56811612b07340e1dd8b846f8d4a96b639cb1b6f..889aa2833d7cc4de2874a49a42967dc63a15707a 100644 (file)
@@ -5344,13 +5344,16 @@ parse_ia_pd_declaration(struct parse *cfile) {
                        binding_scope_dereference(&scope, MDL);
                }
 
-               /* find the pool this address is in */
+               /* Find the pool this address is in. We need to check prefix
+               * lengths too in case the pool has been reconfigured. */
                pool = NULL;
-               if (find_ipv6_pool(&pool, D6O_IA_PD,
-                                  &iapref->addr) != ISC_R_SUCCESS) {
+               if ((find_ipv6_pool(&pool, D6O_IA_PD,
+                                   &iapref->addr) != ISC_R_SUCCESS) ||
+                    (pool->units != iapref->plen)) {
                        inet_ntop(AF_INET6, &iapref->addr,
                                  addr_buf, sizeof(addr_buf));
-                       log_error("No pool found for prefix %s", addr_buf);
+                       log_error("No pool found for prefix %s/%d", addr_buf,
+                                 iapref->plen);
                        iasubopt_dereference(&iapref, MDL);
                        continue;
                }
index 9099e06777b752932682a20d77df72ac68219364..77bad87e45c0d77ecfe6dd01f3617a8cc03665cb 100644 (file)
@@ -1139,22 +1139,25 @@ try_client_v6_prefix(struct iasubopt **pref,
        if (requested_pref->len < sizeof(tmp_plen) + sizeof(tmp_pref)) {
                return ISC_R_INVALIDARG;
        }
+
        tmp_plen = (int) requested_pref->data[0];
-       if ((tmp_plen < 3) || (tmp_plen > 128) ||
-           ((int)tmp_plen != pool->units)) {
+       if ((tmp_plen < 3) || (tmp_plen > 128)) {
                return ISC_R_FAILURE;
        }
+
        memcpy(&tmp_pref, requested_pref->data + 1, sizeof(tmp_pref));
        if (IN6_IS_ADDR_UNSPECIFIED(&tmp_pref)) {
                return ISC_R_FAILURE;
        }
+
        ia.len = 16;
        memcpy(&ia.iabuf, &tmp_pref, 16);
        if (!is_cidr_mask_valid(&ia, (int) tmp_plen)) {
                return ISC_R_FAILURE;
        }
 
-       if (!ipv6_in_pool(&tmp_pref, pool)) {
+       if (!ipv6_in_pool(&tmp_pref, pool) ||
+           ((int)tmp_plen != pool->units)) {
                return ISC_R_ADDRNOTAVAIL;
        }
 
@@ -1166,6 +1169,7 @@ try_client_v6_prefix(struct iasubopt **pref,
        if (result != ISC_R_SUCCESS) {
                return result;
        }
+
        (*pref)->addr = tmp_pref;
        (*pref)->plen = tmp_plen;
 
@@ -1174,6 +1178,7 @@ try_client_v6_prefix(struct iasubopt **pref,
        if (result != ISC_R_SUCCESS) {
                iasubopt_dereference(pref, MDL);
        }
+
        return result;
 }