summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Markwalder <tmark@isc.org>2017-06-12 11:43:15 -0400
committerThomas Markwalder <tmark@isc.org>2017-06-12 11:43:15 -0400
commit2d70dfc69b6a97c3afdbc81513234f2d31e3eacc (patch)
tree5098f4dde63c6db3bf5e6b3adcdfeb5d349d7690
parent2a796026d948970d93a3bb16536614de9b7e9cdc (diff)
downloadisc-dhcp-2d70dfc69b6a97c3afdbc81513234f2d31e3eacc.tar.gz
[v4_1_esv] Server now handles prefix/pool prefix length mismatches
Merged in 35378.
-rw-r--r--RELNOTES11
-rw-r--r--server/confpars.c11
-rw-r--r--server/dhcpv6.c11
3 files changed, 26 insertions, 7 deletions
diff --git a/RELNOTES b/RELNOTES
index 058eab15..cfc13d09 100644
--- 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
diff --git a/server/confpars.c b/server/confpars.c
index 56811612..889aa283 100644
--- a/server/confpars.c
+++ b/server/confpars.c
@@ -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;
}
diff --git a/server/dhcpv6.c b/server/dhcpv6.c
index 9099e067..77bad87e 100644
--- a/server/dhcpv6.c
+++ b/server/dhcpv6.c
@@ -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;
}