mirror of
http://thekelleys.org.uk/git/dnsmasq.git
synced 2026-11-06 15:51:41 +00:00
Compare commits
6
Commits
v2.64test1
...
v2.64test3
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4d0f5b4c44 | ||
|
|
1dedeb87cc | ||
|
|
79cfefd856 | ||
|
|
0c0d4793ac | ||
|
|
12d71ed28c | ||
|
|
9fed0f71c2 |
No files matched your search
@@ -3,6 +3,16 @@ version 2.64
|
|||||||
--dhcp-client-update set. Thanks to Bernd Krumbroeck for
|
--dhcp-client-update set. Thanks to Bernd Krumbroeck for
|
||||||
spotting the problem.
|
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.
|
||||||
|
|
||||||
|
Fix broken vendor-option processing for BOOTP. Thanks to
|
||||||
|
Hans-Joachim Baader for the bug report.
|
||||||
|
|
||||||
|
|
||||||
version 2.63
|
version 2.63
|
||||||
Do duplicate dhcp-host address check in --test mode.
|
Do duplicate dhcp-host address check in --test mode.
|
||||||
|
|||||||
Vendored
+7
-1
@@ -2,7 +2,13 @@ dnsmasq (2.64-1) unstable; urgency=low
|
|||||||
|
|
||||||
* New upstream.
|
* New upstream.
|
||||||
|
|
||||||
-- Simon Kelley <simon@thekelleys.org.uk> Tue, 28 Aug 2012 16:19:15 +0000
|
-- Simon Kelley <simon@thekelleys.org.uk> Tue, 4 Sep 2012 21:50:22 +0000
|
||||||
|
|
||||||
|
dnsmasq (2.63-3) unstable; urgency=low
|
||||||
|
|
||||||
|
* Move adduser dependency to dnsmasq-base. (closes: #686694)
|
||||||
|
|
||||||
|
-- Simon Kelley <simon@thekelleys.org.uk> Tue, 4 Sep 2012 21:44:15 +0000
|
||||||
|
|
||||||
dnsmasq (2.63-2) unstable; urgency=low
|
dnsmasq (2.63-2) unstable; urgency=low
|
||||||
|
|
||||||
|
|||||||
Vendored
+2
-2
@@ -7,7 +7,7 @@ Standards-Version: 3.9.3
|
|||||||
|
|
||||||
Package: dnsmasq
|
Package: dnsmasq
|
||||||
Architecture: all
|
Architecture: all
|
||||||
Depends: netbase, adduser, dnsmasq-base(>= ${source:Version})
|
Depends: netbase, dnsmasq-base(>= ${source:Version})
|
||||||
Suggests: resolvconf
|
Suggests: resolvconf
|
||||||
Conflicts: resolvconf (<<1.15)
|
Conflicts: resolvconf (<<1.15)
|
||||||
Description: Small caching DNS proxy and DHCP/TFTP server
|
Description: Small caching DNS proxy and DHCP/TFTP server
|
||||||
@@ -22,7 +22,7 @@ Description: Small caching DNS proxy and DHCP/TFTP server
|
|||||||
|
|
||||||
Package: dnsmasq-base
|
Package: dnsmasq-base
|
||||||
Architecture: any
|
Architecture: any
|
||||||
Depends: ${shlibs:Depends}
|
Depends: adduser, ${shlibs:Depends}
|
||||||
Breaks: dnsmasq (<< 2.63-1~)
|
Breaks: dnsmasq (<< 2.63-1~)
|
||||||
Replaces: dnsmasq (<< 2.63-1~)
|
Replaces: dnsmasq (<< 2.63-1~)
|
||||||
Description: Small caching DNS proxy and DHCP/TFTP server
|
Description: Small caching DNS proxy and DHCP/TFTP server
|
||||||
|
|||||||
+34
-28
@@ -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,
|
void cache_add_dhcp_entry(char *host_name, int prot,
|
||||||
struct all_addr *host_address, time_t ttd)
|
struct all_addr *host_address, time_t ttd)
|
||||||
{
|
{
|
||||||
struct crec *crec = NULL;
|
struct crec *crec = NULL, *fail_crec = NULL;
|
||||||
unsigned short flags = F_IPV4;
|
unsigned short flags = F_IPV4;
|
||||||
int in_hosts = 0;
|
int in_hosts = 0;
|
||||||
size_t addrlen = sizeof(struct in_addr);
|
size_t addrlen = sizeof(struct in_addr);
|
||||||
@@ -1055,28 +1055,21 @@ void cache_add_dhcp_entry(char *host_name, int prot,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
inet_ntop(prot, host_address, daemon->addrbuff, ADDRSTRLEN);
|
||||||
|
|
||||||
while ((crec = cache_find_by_name(crec, host_name, 0, flags | F_CNAME)))
|
while ((crec = cache_find_by_name(crec, host_name, 0, flags | F_CNAME)))
|
||||||
{
|
{
|
||||||
/* check all addresses associated with name */
|
/* check all addresses associated with name */
|
||||||
if (crec->flags & F_HOSTS)
|
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)
|
if (crec->flags & F_CNAME)
|
||||||
my_syslog(MS_DHCP | LOG_WARNING,
|
my_syslog(MS_DHCP | LOG_WARNING,
|
||||||
_("%s is a CNAME, not giving it to the DHCP lease of %s"),
|
_("%s is a CNAME, not giving it to the DHCP lease of %s"),
|
||||||
host_name, daemon->addrbuff);
|
host_name, daemon->addrbuff);
|
||||||
else if (memcmp(&crec->addr.addr, host_address, addrlen) != 0)
|
else if (memcmp(&crec->addr.addr, host_address, addrlen) == 0)
|
||||||
{
|
in_hosts = 1;
|
||||||
inet_ntop(prot, &crec->addr.addr, daemon->namebuff, MAXDNAME);
|
else
|
||||||
my_syslog(MS_DHCP | LOG_WARNING,
|
fail_crec = crec;
|
||||||
_("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 (!(crec->flags & F_DHCP))
|
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;
|
return;
|
||||||
|
|
||||||
if ((crec = cache_find_by_addr(NULL, (struct all_addr *)host_address, 0, flags)))
|
/* Name in hosts, address doesn't match */
|
||||||
{
|
if (fail_crec)
|
||||||
if (crec->flags & F_NEG)
|
{
|
||||||
{
|
inet_ntop(prot, &fail_crec->addr.addr, daemon->namebuff, MAXDNAME);
|
||||||
flags |= F_REVERSE;
|
my_syslog(MS_DHCP | LOG_WARNING,
|
||||||
cache_scan_free(NULL, (struct all_addr *)host_address, 0, flags);
|
_("not giving name %s to the DHCP lease of %s because "
|
||||||
}
|
"the name exists in %s with address %s"),
|
||||||
}
|
host_name, daemon->addrbuff,
|
||||||
else
|
record_source(fail_crec->uid), daemon->namebuff);
|
||||||
flags |= F_REVERSE;
|
return;
|
||||||
|
}
|
||||||
if ((crec = dhcp_spare))
|
|
||||||
|
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;
|
dhcp_spare = dhcp_spare->next;
|
||||||
else /* need new one */
|
else /* need new one */
|
||||||
crec = whine_malloc(sizeof(struct crec));
|
crec = whine_malloc(sizeof(struct crec));
|
||||||
|
|||||||
+44
-13
@@ -383,15 +383,48 @@ int main (int argc, char **argv)
|
|||||||
/* write pidfile _after_ forking ! */
|
/* write pidfile _after_ forking ! */
|
||||||
if (daemon->runfile)
|
if (daemon->runfile)
|
||||||
{
|
{
|
||||||
FILE *pidfile;
|
int fd, err = 0;
|
||||||
|
|
||||||
|
sprintf(daemon->namebuff, "%d\n", (int) getpid());
|
||||||
|
|
||||||
|
/* Explanation: Some installations of dnsmasq (eg Debian/Ubuntu) locate the pid-file
|
||||||
|
in a directory which is writable by the non-privileged user that dnsmasq runs as. This
|
||||||
|
allows the daemon to delete the file as part of its shutdown. This is a security hole to the
|
||||||
|
extent that an attacker running as the unprivileged user could replace the pidfile with a
|
||||||
|
symlink, and have the target of that symlink overwritten as root next time dnsmasq starts.
|
||||||
|
|
||||||
|
The folowing code first deletes any existing file, and then opens it with the O_EXCL flag,
|
||||||
|
ensuring that the open() fails should there be any existing file (because the unlink() failed,
|
||||||
|
or an attacker exploited the race between unlink() and open()). This ensures that no symlink
|
||||||
|
attack can succeed.
|
||||||
|
|
||||||
|
Any compromise of the non-privileged user still theoretically allows the pid-file to be
|
||||||
|
replaced whilst dnsmasq is running. The worst that could allow is that the usual
|
||||||
|
"shutdown dnsmasq" shell command could be tricked into stopping any other process.
|
||||||
|
|
||||||
|
Note that if dnsmasq is started as non-root (eg for testing) it silently ignores
|
||||||
|
failure to write the pid-file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
unlink(daemon->runfile);
|
||||||
|
|
||||||
/* only complain if started as root */
|
if ((fd = open(daemon->runfile, O_WRONLY|O_CREAT|O_TRUNC|O_EXCL, S_IWUSR|S_IRUSR|S_IRGRP|S_IROTH)) == -1)
|
||||||
if ((pidfile = fopen(daemon->runfile, "w")))
|
|
||||||
{
|
{
|
||||||
fprintf(pidfile, "%d\n", (int) getpid());
|
/* only complain if started as root */
|
||||||
fclose(pidfile);
|
if (getuid() == 0)
|
||||||
|
err = 1;
|
||||||
}
|
}
|
||||||
else if (getuid() == 0)
|
else
|
||||||
|
{
|
||||||
|
if (!read_write(fd, (unsigned char *)daemon->namebuff, strlen(daemon->namebuff), 0))
|
||||||
|
err = 1;
|
||||||
|
|
||||||
|
while (!err && close(fd) == -1)
|
||||||
|
if (!retry_send())
|
||||||
|
err = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (err)
|
||||||
{
|
{
|
||||||
send_event(err_pipe[1], EVENT_PIDFILE, errno, daemon->runfile);
|
send_event(err_pipe[1], EVENT_PIDFILE, errno, daemon->runfile);
|
||||||
_exit(0);
|
_exit(0);
|
||||||
@@ -607,7 +640,7 @@ int main (int argc, char **argv)
|
|||||||
end = &dhcp_tmp->end6;
|
end = &dhcp_tmp->end6;
|
||||||
struct in6_addr subnet = dhcp_tmp->start6;
|
struct in6_addr subnet = dhcp_tmp->start6;
|
||||||
setaddr6part(&subnet, 0);
|
setaddr6part(&subnet, 0);
|
||||||
inet_ntop(AF_INET6, &subnet, daemon->addrbuff, 256);
|
inet_ntop(AF_INET6, &subnet, daemon->dhcp_buff2, 256);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -620,10 +653,8 @@ int main (int argc, char **argv)
|
|||||||
prettyprint_time(p, dhcp_tmp->lease_time);
|
prettyprint_time(p, dhcp_tmp->lease_time);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (daemon->dhcp_buff)
|
inet_ntop(family, start, daemon->dhcp_buff, 256);
|
||||||
inet_ntop(family, start, daemon->dhcp_buff, 256);
|
inet_ntop(family, end, daemon->dhcp_buff3, 256);
|
||||||
if (daemon->dhcp_buff3)
|
|
||||||
inet_ntop(family, end, daemon->dhcp_buff3, 256);
|
|
||||||
if ((dhcp_tmp->flags & CONTEXT_DHCP) || family == AF_INET)
|
if ((dhcp_tmp->flags & CONTEXT_DHCP) || family == AF_INET)
|
||||||
my_syslog(MS_DHCP | LOG_INFO,
|
my_syslog(MS_DHCP | LOG_INFO,
|
||||||
(dhcp_tmp->flags & CONTEXT_RA_STATELESS) ?
|
(dhcp_tmp->flags & CONTEXT_RA_STATELESS) ?
|
||||||
@@ -637,7 +668,7 @@ int main (int argc, char **argv)
|
|||||||
|
|
||||||
if (dhcp_tmp->flags & CONTEXT_RA_NAME)
|
if (dhcp_tmp->flags & CONTEXT_RA_NAME)
|
||||||
my_syslog(MS_DHCP | LOG_INFO, _("DHCPv4-derived IPv6 names on %s"),
|
my_syslog(MS_DHCP | LOG_INFO, _("DHCPv4-derived IPv6 names on %s"),
|
||||||
daemon->addrbuff);
|
daemon->dhcp_buff2);
|
||||||
if (dhcp_tmp->flags & (CONTEXT_RA_ONLY | CONTEXT_RA_NAME | CONTEXT_RA_STATELESS))
|
if (dhcp_tmp->flags & (CONTEXT_RA_ONLY | CONTEXT_RA_NAME | CONTEXT_RA_STATELESS))
|
||||||
{
|
{
|
||||||
if (!(dhcp_tmp->flags & CONTEXT_DEPRECATE))
|
if (!(dhcp_tmp->flags & CONTEXT_DEPRECATE))
|
||||||
@@ -647,7 +678,7 @@ int main (int argc, char **argv)
|
|||||||
prettyprint_time(p, dhcp_tmp->lease_time > 7200 ? dhcp_tmp->lease_time : 7200);
|
prettyprint_time(p, dhcp_tmp->lease_time > 7200 ? dhcp_tmp->lease_time : 7200);
|
||||||
}
|
}
|
||||||
my_syslog(MS_DHCP | LOG_INFO, _("SLAAC on %s %s"),
|
my_syslog(MS_DHCP | LOG_INFO, _("SLAAC on %s %s"),
|
||||||
daemon->addrbuff, daemon->namebuff);
|
daemon->dhcp_buff2, daemon->namebuff);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+19
-8
@@ -493,8 +493,9 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
|
|||||||
lease_set_interface(lease, int_index, now);
|
lease_set_interface(lease, int_index, now);
|
||||||
|
|
||||||
clear_packet(mess, end);
|
clear_packet(mess, end);
|
||||||
|
match_vendor_opts(NULL, daemon->dhcp_opts); /* clear flags */
|
||||||
do_options(context, mess, end, NULL, hostname, get_domain(mess->yiaddr),
|
do_options(context, mess, end, NULL, hostname, get_domain(mess->yiaddr),
|
||||||
netid, subnet_addr, 0, 0, 0, NULL, 0, now);
|
netid, subnet_addr, 0, 0, -1, NULL, 0, now);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -510,17 +511,27 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
|
|||||||
char *pq = daemon->dhcp_buff;
|
char *pq = daemon->dhcp_buff;
|
||||||
unsigned char *pp, *op = option_ptr(opt, 0);
|
unsigned char *pp, *op = option_ptr(opt, 0);
|
||||||
|
|
||||||
/* Set an MBZ bit to indicate receipt of FQDN option - cleared later */
|
fqdn_flags = *op;
|
||||||
fqdn_flags = *op | 0x10;
|
|
||||||
len -= 3;
|
len -= 3;
|
||||||
op += 3;
|
op += 3;
|
||||||
pp = op;
|
pp = op;
|
||||||
|
|
||||||
/* Always force update, since the client has no way to do it itself. */
|
/* NB, the following always sets at least one bit */
|
||||||
if (!option_bool(OPT_FQDN_UPDATE) && !(fqdn_flags & 0x01))
|
if (option_bool(OPT_FQDN_UPDATE))
|
||||||
fqdn_flags |= 0x03;
|
{
|
||||||
|
if (fqdn_flags & 0x01)
|
||||||
fqdn_flags &= ~0x08;
|
{
|
||||||
|
fqdn_flags |= 0x02; /* set O */
|
||||||
|
fqdn_flags &= ~0x01; /* clear S */
|
||||||
|
}
|
||||||
|
fqdn_flags |= 0x08; /* set N */
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!(fqdn_flags & 0x01))
|
||||||
|
fqdn_flags |= 0x03; /* set S and O */
|
||||||
|
fqdn_flags &= ~0x08; /* clear N */
|
||||||
|
}
|
||||||
|
|
||||||
if (fqdn_flags & 0x04)
|
if (fqdn_flags & 0x04)
|
||||||
while (*op != 0 && ((op + (*op) + 1) - pp) < len)
|
while (*op != 0 && ((op + (*op) + 1) - pp) < len)
|
||||||
|
|||||||
Reference in new issue
Block a user