Fix problem with domains associated with DHCP hosts at startup.

At startup, the leases file is read by lease_init(), and
in lease_init() undecorated hostnames are expanded into
FQDNs by adding the domain associated with the address
of the lease.

lease_init() happens relavtively early in the startup, party because
if it calls  the dhcp-lease helper script, we don't want that to inherit
a load of sensitive file descriptors. This has implications if domains
are defined using the --domain=example.com,eth0 format since it's long
before we call enumerate_interfaces(), so get_domain fails for such domains.

The patch just moves the hostname expansion function to a seperate
subroutine that gets called later, after enumerate_interfaces().
This commit is contained in:
Simon Kelley
2023-12-03 16:09:08 +00:00
parent cd4db8246e
commit f1beb79429
3 changed files with 43 additions and 10 deletions

View File

@@ -375,6 +375,13 @@ int main (int argc, char **argv)
if (!enumerate_interfaces(1) || !enumerate_interfaces(0)) if (!enumerate_interfaces(1) || !enumerate_interfaces(0))
die(_("failed to find list of interfaces: %s"), NULL, EC_MISC); die(_("failed to find list of interfaces: %s"), NULL, EC_MISC);
#ifdef HAVE_DHCP
/* Determine lease FQDNs after enumerate_interfaces() call, since it needs
to call get_domain and that's only valid for some domain configs once we
have interface addresses. */
lease_calc_fqdns();
#endif
if (option_bool(OPT_NOWILD) || option_bool(OPT_CLEVERBIND)) if (option_bool(OPT_NOWILD) || option_bool(OPT_CLEVERBIND))
{ {
create_bound_listeners(1); create_bound_listeners(1);

View File

@@ -1605,6 +1605,7 @@ void lease_update_from_configs(void);
int do_script_run(time_t now); int do_script_run(time_t now);
void rerun_scripts(void); void rerun_scripts(void);
void lease_find_interfaces(time_t now); void lease_find_interfaces(time_t now);
void lease_calc_fqdns(void);
#ifdef HAVE_SCRIPT #ifdef HAVE_SCRIPT
void lease_add_extradata(struct dhcp_lease *lease, unsigned char *data, void lease_add_extradata(struct dhcp_lease *lease, unsigned char *data,
unsigned int len, int delim); unsigned int len, int delim);

View File

@@ -15,7 +15,6 @@
*/ */
#include "dnsmasq.h" #include "dnsmasq.h"
#ifdef HAVE_DHCP #ifdef HAVE_DHCP
static struct dhcp_lease *leases = NULL, *old_leases = NULL; static struct dhcp_lease *leases = NULL, *old_leases = NULL;
@@ -28,7 +27,6 @@ static int read_leases(time_t now, FILE *leasestream)
struct dhcp_lease *lease; struct dhcp_lease *lease;
int clid_len, hw_len, hw_type; int clid_len, hw_len, hw_type;
int items; int items;
char *domain = NULL;
*daemon->dhcp_buff3 = *daemon->dhcp_buff2 = '\0'; *daemon->dhcp_buff3 = *daemon->dhcp_buff2 = '\0';
@@ -69,8 +67,8 @@ static int read_leases(time_t now, FILE *leasestream)
if (inet_pton(AF_INET, daemon->namebuff, &addr.addr4)) if (inet_pton(AF_INET, daemon->namebuff, &addr.addr4))
{ {
if ((lease = lease4_allocate(addr.addr4))) lease = lease4_allocate(addr.addr4);
domain = get_domain(lease->addr);
hw_len = parse_hex(daemon->dhcp_buff2, (unsigned char *)daemon->dhcp_buff2, DHCP_CHADDR_MAX, NULL, &hw_type); hw_len = parse_hex(daemon->dhcp_buff2, (unsigned char *)daemon->dhcp_buff2, DHCP_CHADDR_MAX, NULL, &hw_type);
/* For backwards compatibility, no explicit MAC address type means ether. */ /* For backwards compatibility, no explicit MAC address type means ether. */
@@ -90,10 +88,7 @@ static int read_leases(time_t now, FILE *leasestream)
} }
if ((lease = lease6_allocate(&addr.addr6, lease_type))) if ((lease = lease6_allocate(&addr.addr6, lease_type)))
{
lease_set_iaid(lease, strtoul(s, NULL, 10)); lease_set_iaid(lease, strtoul(s, NULL, 10));
domain = get_domain6(&lease->addr6);
}
} }
#endif #endif
else else
@@ -114,7 +109,7 @@ static int read_leases(time_t now, FILE *leasestream)
hw_len, hw_type, clid_len, now, 0); hw_len, hw_type, clid_len, now, 0);
if (strcmp(daemon->dhcp_buff, "*") != 0) if (strcmp(daemon->dhcp_buff, "*") != 0)
lease_set_hostname(lease, daemon->dhcp_buff, 0, domain, NULL); lease_set_hostname(lease, daemon->dhcp_buff, 0, NULL, NULL);
ei = atol(daemon->dhcp_buff3); ei = atol(daemon->dhcp_buff3);
@@ -946,6 +941,36 @@ static void kill_name(struct dhcp_lease *lease)
lease->hostname = lease->fqdn = NULL; lease->hostname = lease->fqdn = NULL;
} }
void lease_calc_fqdns(void)
{
struct dhcp_lease *lease;
for (lease = leases; lease; lease = lease->next)
{
char *domain;
if (lease->hostname)
{
#ifdef HAVE_DHCP6
if (lease->flags & (LEASE_TA | LEASE_NA))
domain = get_domain6(&lease->addr6);
else
#endif
domain = get_domain(lease->addr);
if (domain)
{
/* This is called only during startup, before forking, hence safe_malloc() */
lease->fqdn = safe_malloc(strlen(lease->hostname) + strlen(domain) + 2);
strcpy(lease->fqdn, lease->hostname);
strcat(lease->fqdn, ".");
strcat(lease->fqdn, domain);
}
}
}
}
void lease_set_hostname(struct dhcp_lease *lease, const char *name, int auth, char *domain, char *config_domain) void lease_set_hostname(struct dhcp_lease *lease, const char *name, int auth, char *domain, char *config_domain)
{ {
struct dhcp_lease *lease_tmp; struct dhcp_lease *lease_tmp;