Fix DHCPv6 to do access control correctly when it's configured with --listen-address.

This commit is contained in:
Simon Kelley
2012-10-16 20:38:31 +01:00
parent 2022310f95
commit be6cfb42ab
2 changed files with 31 additions and 8 deletions

View File

@@ -37,6 +37,10 @@ version 2.64
single machine, in the same way as for DHCPv4. Thanks to single machine, in the same way as for DHCPv4. Thanks to
Gene Czarcinski and Vladislav Grishenko for work on this. Gene Czarcinski and Vladislav Grishenko for work on this.
Fix DHCPv6 to do access control correctly when it's
configured with --listen-address. Thanks to
Gene Czarcinski for sorting this out.
version 2.63 version 2.63
Do duplicate dhcp-host address check in --test mode. Do duplicate dhcp-host address check in --test mode.

View File

@@ -21,7 +21,7 @@
struct iface_param { struct iface_param {
struct dhcp_context *current; struct dhcp_context *current;
struct in6_addr fallback; struct in6_addr fallback;
int ind; int ind, addr_match;
}; };
static int complete_context6(struct in6_addr *local, int prefix, static int complete_context6(struct in6_addr *local, int prefix,
@@ -87,7 +87,6 @@ void dhcp6_packet(time_t now)
char control6[CMSG_SPACE(sizeof(struct in6_pktinfo))]; char control6[CMSG_SPACE(sizeof(struct in6_pktinfo))];
} control_u; } control_u;
struct sockaddr_in6 from; struct sockaddr_in6 from;
struct all_addr dest;
ssize_t sz; ssize_t sz;
struct ifreq ifr; struct ifreq ifr;
struct iname *tmp; struct iname *tmp;
@@ -114,14 +113,14 @@ void dhcp6_packet(time_t now)
p.c = CMSG_DATA(cmptr); p.c = CMSG_DATA(cmptr);
if_index = p.p->ipi6_ifindex; if_index = p.p->ipi6_ifindex;
dest.addr.addr6 = p.p->ipi6_addr;
} }
if (!indextoname(daemon->dhcp6fd, if_index, ifr.ifr_name)) if (!indextoname(daemon->dhcp6fd, if_index, ifr.ifr_name))
return; return;
if (!iface_check(AF_INET6, (struct all_addr *)&dest, ifr.ifr_name)) for (tmp = daemon->if_except; tmp; tmp = tmp->next)
return; if (tmp->name && (strcmp(tmp->name, ifr.ifr_name) == 0))
return;
for (tmp = daemon->dhcp_except; tmp; tmp = tmp->next) for (tmp = daemon->dhcp_except; tmp; tmp = tmp->next)
if (tmp->name && (strcmp(tmp->name, ifr.ifr_name) == 0)) if (tmp->name && (strcmp(tmp->name, ifr.ifr_name) == 0))
@@ -136,11 +135,23 @@ void dhcp6_packet(time_t now)
parm.current = NULL; parm.current = NULL;
parm.ind = if_index; parm.ind = if_index;
parm.addr_match = 0;
memset(&parm.fallback, 0, IN6ADDRSZ); memset(&parm.fallback, 0, IN6ADDRSZ);
if (!iface_enumerate(AF_INET6, &parm, complete_context6)) if (!iface_enumerate(AF_INET6, &parm, complete_context6))
return; return;
if (daemon->if_names || daemon->if_addrs)
{
for (tmp = daemon->if_names; tmp; tmp = tmp->next)
if (tmp->name && (strcmp(tmp->name, ifr.ifr_name) == 0))
break;
if (!tmp && !parm.addr_match)
return;
}
lease_prune(NULL, now); /* lose any expired leases */ lease_prune(NULL, now); /* lose any expired leases */
port = dhcp6_reply(parm.current, if_index, ifr.ifr_name, &parm.fallback, port = dhcp6_reply(parm.current, if_index, ifr.ifr_name, &parm.fallback,
@@ -167,6 +178,7 @@ static int complete_context6(struct in6_addr *local, int prefix,
{ {
struct dhcp_context *context; struct dhcp_context *context;
struct iface_param *param = vparam; struct iface_param *param = vparam;
struct iname *tmp;
(void)scope; /* warning */ (void)scope; /* warning */
(void)dad; (void)dad;
@@ -176,6 +188,13 @@ static int complete_context6(struct in6_addr *local, int prefix,
!IN6_IS_ADDR_LINKLOCAL(local) && !IN6_IS_ADDR_LINKLOCAL(local) &&
!IN6_IS_ADDR_MULTICAST(local)) !IN6_IS_ADDR_MULTICAST(local))
{ {
/* if we have --listen-address config, see if the
arrival interface has a matching address. */
for (tmp = daemon->if_addrs; tmp; tmp = tmp->next)
if (tmp->addr.sa.sa_family == AF_INET6 &&
IN6_ARE_ADDR_EQUAL(&tmp->addr.in6.sin6_addr, local))
param->addr_match = 1;
/* Determine a globally address on the arrival interface, even /* Determine a globally address on the arrival interface, even
if we have no matching dhcp-context, because we're only if we have no matching dhcp-context, because we're only
allocating on remote subnets via relays. This allocating on remote subnets via relays. This