From 12d71ed28ce0bfc3906140e565180489f6f6ac30 Mon Sep 17 00:00:00 2001 From: Simon Kelley Date: Thu, 30 Aug 2012 15:16:41 +0100 Subject: [PATCH] Finesse the check for /etc/hosts names which conflict with DHCP names. --- CHANGELOG | 7 ++++++ src/cache.c | 62 +++++++++++++++++++++++++++++------------------------ 2 files changed, 41 insertions(+), 28 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 73b4c95..ded2d26 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -3,6 +3,13 @@ version 2.64 --dhcp-client-update set. Thanks to Bernd Krumbroeck for spotting the problem. + Finesse the check for /etc/hosts names which conflict with + DHCP names. Previously a name/address pair in /etc/hosts + which didn't match the name/address of a DHCP lease would + generate a warning. Now that only happesn if there is not + also a match. This allows multiple addresses for a name in + /etc/hosts with one of them assigned via DHCP. + version 2.63 Do duplicate dhcp-host address check in --test mode. diff --git a/src/cache.c b/src/cache.c index d0d806c..ee4e763 100644 --- a/src/cache.c +++ b/src/cache.c @@ -1042,7 +1042,7 @@ static void add_dhcp_cname(struct crec *target, time_t ttd) void cache_add_dhcp_entry(char *host_name, int prot, struct all_addr *host_address, time_t ttd) { - struct crec *crec = NULL; + struct crec *crec = NULL, *fail_crec = NULL; unsigned short flags = F_IPV4; int in_hosts = 0; size_t addrlen = sizeof(struct in_addr); @@ -1055,28 +1055,21 @@ void cache_add_dhcp_entry(char *host_name, int prot, } #endif + inet_ntop(prot, host_address, daemon->addrbuff, ADDRSTRLEN); + while ((crec = cache_find_by_name(crec, host_name, 0, flags | F_CNAME))) { /* check all addresses associated with name */ if (crec->flags & F_HOSTS) { - /* if in hosts, don't need DHCP record */ - in_hosts = 1; - - inet_ntop(prot, host_address, daemon->addrbuff, ADDRSTRLEN); if (crec->flags & F_CNAME) my_syslog(MS_DHCP | LOG_WARNING, _("%s is a CNAME, not giving it to the DHCP lease of %s"), host_name, daemon->addrbuff); - else if (memcmp(&crec->addr.addr, host_address, addrlen) != 0) - { - inet_ntop(prot, &crec->addr.addr, daemon->namebuff, MAXDNAME); - my_syslog(MS_DHCP | LOG_WARNING, - _("not giving name %s to the DHCP lease of %s because " - "the name exists in %s with address %s"), - host_name, daemon->addrbuff, - record_source(crec->uid), daemon->namebuff); - } + else if (memcmp(&crec->addr.addr, host_address, addrlen) == 0) + in_hosts = 1; + else + fail_crec = crec; } else if (!(crec->flags & F_DHCP)) { @@ -1086,21 +1079,34 @@ void cache_add_dhcp_entry(char *host_name, int prot, } } - if (in_hosts) + /* if in hosts, don't need DHCP record */ + if (in_hosts) return; - - if ((crec = cache_find_by_addr(NULL, (struct all_addr *)host_address, 0, flags))) - { - if (crec->flags & F_NEG) - { - flags |= F_REVERSE; - cache_scan_free(NULL, (struct all_addr *)host_address, 0, flags); - } - } - else - flags |= F_REVERSE; - - if ((crec = dhcp_spare)) + + /* Name in hosts, address doesn't match */ + if (fail_crec) + { + inet_ntop(prot, &fail_crec->addr.addr, daemon->namebuff, MAXDNAME); + my_syslog(MS_DHCP | LOG_WARNING, + _("not giving name %s to the DHCP lease of %s because " + "the name exists in %s with address %s"), + host_name, daemon->addrbuff, + record_source(fail_crec->uid), daemon->namebuff); + return; + } + + if ((crec = cache_find_by_addr(NULL, (struct all_addr *)host_address, 0, flags))) + { + if (crec->flags & F_NEG) + { + flags |= F_REVERSE; + cache_scan_free(NULL, (struct all_addr *)host_address, 0, flags); + } + } + else + flags |= F_REVERSE; + + if ((crec = dhcp_spare)) dhcp_spare = dhcp_spare->next; else /* need new one */ crec = whine_malloc(sizeof(struct crec));