version 1.1.1.4, 2021/03/17 00:56:46
|
version 1.1.1.5, 2023/09/27 11:02:07
|
Line 1
|
Line 1
|
/* dnsmasq is Copyright (c) 2000-2021 Simon Kelley | /* dnsmasq is Copyright (c) 2000-2022 Simon Kelley |
|
|
This program is free software; you can redistribute it and/or modify |
This program is free software; you can redistribute it and/or modify |
it under the terms of the GNU General Public License as published by |
it under the terms of the GNU General Public License as published by |
Line 105 size_t answer_auth(struct dns_header *header, char *li
|
Line 105 size_t answer_auth(struct dns_header *header, char *li
|
int nameoffset, axfroffset = 0; |
int nameoffset, axfroffset = 0; |
int q, anscount = 0, authcount = 0; |
int q, anscount = 0, authcount = 0; |
struct crec *crecp; |
struct crec *crecp; |
int auth = !local_query, trunc = 0, nxdomain = 1, soa = 0, ns = 0, axfr = 0; | int auth = !local_query, trunc = 0, nxdomain = 1, soa = 0, ns = 0, axfr = 0, out_of_zone = 0; |
struct auth_zone *zone = NULL; |
struct auth_zone *zone = NULL; |
struct addrlist *subnet = NULL; |
struct addrlist *subnet = NULL; |
char *cut; |
char *cut; |
Line 146 size_t answer_auth(struct dns_header *header, char *li
|
Line 146 size_t answer_auth(struct dns_header *header, char *li
|
if (qclass != C_IN) |
if (qclass != C_IN) |
{ |
{ |
auth = 0; |
auth = 0; |
|
out_of_zone = 1; |
continue; |
continue; |
} |
} |
|
|
Line 159 size_t answer_auth(struct dns_header *header, char *li
|
Line 160 size_t answer_auth(struct dns_header *header, char *li
|
|
|
if (!zone) |
if (!zone) |
{ |
{ |
|
out_of_zone = 1; |
auth = 0; |
auth = 0; |
continue; |
continue; |
} |
} |
Line 208 size_t answer_auth(struct dns_header *header, char *li
|
Line 210 size_t answer_auth(struct dns_header *header, char *li
|
if (local_query || in_zone(zone, intr->name, NULL)) |
if (local_query || in_zone(zone, intr->name, NULL)) |
{ |
{ |
found = 1; |
found = 1; |
log_query(flag | F_REVERSE | F_CONFIG, intr->name, &addr, NULL); | log_query(flag | F_REVERSE | F_CONFIG, intr->name, &addr, NULL, 0); |
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, |
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, |
daemon->auth_ttl, NULL, |
daemon->auth_ttl, NULL, |
T_PTR, C_IN, "d", intr->name)) |
T_PTR, C_IN, "d", intr->name)) |
Line 232 size_t answer_auth(struct dns_header *header, char *li
|
Line 234 size_t answer_auth(struct dns_header *header, char *li
|
strcat(name, "."); |
strcat(name, "."); |
strcat(name, zone->domain); |
strcat(name, zone->domain); |
} |
} |
log_query(flag | F_DHCP | F_REVERSE, name, &addr, record_source(crecp->uid)); | log_query(flag | F_DHCP | F_REVERSE, name, &addr, record_source(crecp->uid), 0); |
found = 1; |
found = 1; |
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, |
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, |
daemon->auth_ttl, NULL, |
daemon->auth_ttl, NULL, |
Line 241 size_t answer_auth(struct dns_header *header, char *li
|
Line 243 size_t answer_auth(struct dns_header *header, char *li
|
} |
} |
else if (crecp->flags & (F_DHCP | F_HOSTS) && (local_query || in_zone(zone, name, NULL))) |
else if (crecp->flags & (F_DHCP | F_HOSTS) && (local_query || in_zone(zone, name, NULL))) |
{ |
{ |
log_query(crecp->flags & ~F_FORWARD, name, &addr, record_source(crecp->uid)); | log_query(crecp->flags & ~F_FORWARD, name, &addr, record_source(crecp->uid), 0); |
found = 1; |
found = 1; |
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, |
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, |
daemon->auth_ttl, NULL, |
daemon->auth_ttl, NULL, |
Line 253 size_t answer_auth(struct dns_header *header, char *li
|
Line 255 size_t answer_auth(struct dns_header *header, char *li
|
|
|
} while ((crecp = cache_find_by_addr(crecp, &addr, now, flag))); |
} while ((crecp = cache_find_by_addr(crecp, &addr, now, flag))); |
|
|
|
if (!found && is_rev_synth(flag, &addr, name) && (local_query || in_zone(zone, name, NULL))) |
|
{ |
|
log_query(F_CONFIG | F_REVERSE | flag, name, &addr, NULL, 0); |
|
found = 1; |
|
|
|
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, |
|
daemon->auth_ttl, NULL, |
|
T_PTR, C_IN, "d", name)) |
|
anscount++; |
|
} |
|
|
if (found) |
if (found) |
nxdomain = 0; |
nxdomain = 0; |
else |
else |
log_query(flag | F_NEG | F_NXDOMAIN | F_REVERSE | (auth ? F_AUTH : 0), NULL, &addr, NULL); | log_query(flag | F_NEG | F_NXDOMAIN | F_REVERSE | (auth ? F_AUTH : 0), NULL, &addr, NULL, 0); |
|
|
continue; |
continue; |
} |
} |
Line 273 size_t answer_auth(struct dns_header *header, char *li
|
Line 286 size_t answer_auth(struct dns_header *header, char *li
|
|
|
if (!zone) |
if (!zone) |
{ |
{ |
|
out_of_zone = 1; |
auth = 0; |
auth = 0; |
continue; |
continue; |
} |
} |
Line 286 size_t answer_auth(struct dns_header *header, char *li
|
Line 300 size_t answer_auth(struct dns_header *header, char *li
|
if (rc == 2 && qtype == T_MX) |
if (rc == 2 && qtype == T_MX) |
{ |
{ |
found = 1; |
found = 1; |
log_query(F_CONFIG | F_RRNAME, name, NULL, "<MX>"); | log_query(F_CONFIG | F_RRNAME, name, NULL, "<MX>", 0); |
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, daemon->auth_ttl, |
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, daemon->auth_ttl, |
NULL, T_MX, C_IN, "sd", rec->weight, rec->target)) |
NULL, T_MX, C_IN, "sd", rec->weight, rec->target)) |
anscount++; |
anscount++; |
Line 301 size_t answer_auth(struct dns_header *header, char *li
|
Line 315 size_t answer_auth(struct dns_header *header, char *li
|
if (rc == 2 && qtype == T_SRV) |
if (rc == 2 && qtype == T_SRV) |
{ |
{ |
found = 1; |
found = 1; |
log_query(F_CONFIG | F_RRNAME, name, NULL, "<SRV>"); | log_query(F_CONFIG | F_RRNAME, name, NULL, "<SRV>", 0); |
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, daemon->auth_ttl, |
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, daemon->auth_ttl, |
NULL, T_SRV, C_IN, "sssd", |
NULL, T_SRV, C_IN, "sssd", |
rec->priority, rec->weight, rec->srvport, rec->target)) |
rec->priority, rec->weight, rec->srvport, rec->target)) |
Line 335 size_t answer_auth(struct dns_header *header, char *li
|
Line 349 size_t answer_auth(struct dns_header *header, char *li
|
if (rc == 2 && txt->class == qtype) |
if (rc == 2 && txt->class == qtype) |
{ |
{ |
found = 1; |
found = 1; |
log_query(F_CONFIG | F_RRNAME, name, NULL, querystr(NULL, txt->class)); | log_query(F_CONFIG | F_RRNAME, name, NULL, NULL, txt->class); |
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, daemon->auth_ttl, |
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, daemon->auth_ttl, |
NULL, txt->class, C_IN, "t", txt->len, txt->txt)) |
NULL, txt->class, C_IN, "t", txt->len, txt->txt)) |
anscount++; |
anscount++; |
Line 349 size_t answer_auth(struct dns_header *header, char *li
|
Line 363 size_t answer_auth(struct dns_header *header, char *li
|
if (rc == 2 && qtype == T_TXT) |
if (rc == 2 && qtype == T_TXT) |
{ |
{ |
found = 1; |
found = 1; |
log_query(F_CONFIG | F_RRNAME, name, NULL, "<TXT>"); | log_query(F_CONFIG | F_RRNAME, name, NULL, "<TXT>", 0); |
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, daemon->auth_ttl, |
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, daemon->auth_ttl, |
NULL, T_TXT, C_IN, "t", txt->len, txt->txt)) |
NULL, T_TXT, C_IN, "t", txt->len, txt->txt)) |
anscount++; |
anscount++; |
Line 363 size_t answer_auth(struct dns_header *header, char *li
|
Line 377 size_t answer_auth(struct dns_header *header, char *li
|
if (rc == 2 && qtype == T_NAPTR) |
if (rc == 2 && qtype == T_NAPTR) |
{ |
{ |
found = 1; |
found = 1; |
log_query(F_CONFIG | F_RRNAME, name, NULL, "<NAPTR>"); | log_query(F_CONFIG | F_RRNAME, name, NULL, "<NAPTR>", 0); |
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, daemon->auth_ttl, |
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, daemon->auth_ttl, |
NULL, T_NAPTR, C_IN, "sszzzd", |
NULL, T_NAPTR, C_IN, "sszzzd", |
na->order, na->pref, na->flags, na->services, na->regexp, na->replace)) |
na->order, na->pref, na->flags, na->services, na->regexp, na->replace)) |
Line 393 size_t answer_auth(struct dns_header *header, char *li
|
Line 407 size_t answer_auth(struct dns_header *header, char *li
|
continue; |
continue; |
|
|
found = 1; |
found = 1; |
log_query(F_FORWARD | F_CONFIG | flag, name, &addrlist->addr, NULL); | log_query(F_FORWARD | F_CONFIG | flag, name, &addrlist->addr, NULL, 0); |
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, |
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, |
daemon->auth_ttl, NULL, qtype, C_IN, |
daemon->auth_ttl, NULL, qtype, C_IN, |
qtype == T_A ? "4" : "6", &addrlist->addr)) |
qtype == T_A ? "4" : "6", &addrlist->addr)) |
anscount++; |
anscount++; |
} |
} |
} |
} |
|
|
|
if (!found && is_name_synthetic(flag, name, &addr) ) |
|
{ |
|
nxdomain = 0; |
|
|
|
log_query(F_FORWARD | F_CONFIG | flag, name, &addr, NULL, 0); |
|
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, |
|
daemon->auth_ttl, NULL, qtype, C_IN, qtype == T_A ? "4" : "6", &addr)) |
|
anscount++; |
|
} |
|
|
if (!cut) |
if (!cut) |
{ |
{ |
Line 408 size_t answer_auth(struct dns_header *header, char *li
|
Line 432 size_t answer_auth(struct dns_header *header, char *li
|
if (qtype == T_SOA) |
if (qtype == T_SOA) |
{ |
{ |
auth = soa = 1; /* inhibits auth section */ |
auth = soa = 1; /* inhibits auth section */ |
found = 1; | log_query(F_RRNAME | F_AUTH, zone->domain, NULL, "<SOA>", 0); |
log_query(F_RRNAME | F_AUTH, zone->domain, NULL, "<SOA>"); | |
} |
} |
else if (qtype == T_AXFR) |
else if (qtype == T_AXFR) |
{ |
{ |
Line 444 size_t answer_auth(struct dns_header *header, char *li
|
Line 467 size_t answer_auth(struct dns_header *header, char *li
|
soa = 1; /* inhibits auth section */ |
soa = 1; /* inhibits auth section */ |
ns = 1; /* ensure we include NS records! */ |
ns = 1; /* ensure we include NS records! */ |
axfr = 1; |
axfr = 1; |
found = 1; |
|
axfroffset = nameoffset; |
axfroffset = nameoffset; |
log_query(F_RRNAME | F_AUTH, zone->domain, NULL, "<AXFR>"); | log_query(F_RRNAME | F_AUTH, zone->domain, NULL, "<AXFR>", 0); |
} |
} |
else if (qtype == T_NS) |
else if (qtype == T_NS) |
{ |
{ |
auth = 1; |
auth = 1; |
ns = 1; /* inhibits auth section */ |
ns = 1; /* inhibits auth section */ |
found = 1; | log_query(F_RRNAME | F_AUTH, zone->domain, NULL, "<NS>", 0); |
log_query(F_RRNAME | F_AUTH, zone->domain, NULL, "<NS>"); | |
} |
} |
} |
} |
|
|
Line 471 size_t answer_auth(struct dns_header *header, char *li
|
Line 492 size_t answer_auth(struct dns_header *header, char *li
|
(local_query || filter_zone(zone, flag, &(crecp->addr)))) |
(local_query || filter_zone(zone, flag, &(crecp->addr)))) |
{ |
{ |
*cut = '.'; /* restore domain part */ |
*cut = '.'; /* restore domain part */ |
log_query(crecp->flags, name, &crecp->addr, record_source(crecp->uid)); | log_query(crecp->flags, name, &crecp->addr, record_source(crecp->uid), 0); |
*cut = 0; /* remove domain part */ |
*cut = 0; /* remove domain part */ |
found = 1; |
|
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, |
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, |
daemon->auth_ttl, NULL, qtype, C_IN, |
daemon->auth_ttl, NULL, qtype, C_IN, |
qtype == T_A ? "4" : "6", &crecp->addr)) |
qtype == T_A ? "4" : "6", &crecp->addr)) |
Line 493 size_t answer_auth(struct dns_header *header, char *li
|
Line 513 size_t answer_auth(struct dns_header *header, char *li
|
nxdomain = 0; |
nxdomain = 0; |
if ((crecp->flags & flag) && (local_query || filter_zone(zone, flag, &(crecp->addr)))) |
if ((crecp->flags & flag) && (local_query || filter_zone(zone, flag, &(crecp->addr)))) |
{ |
{ |
log_query(crecp->flags, name, &crecp->addr, record_source(crecp->uid)); | log_query(crecp->flags, name, &crecp->addr, record_source(crecp->uid), 0); |
found = 1; | |
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, |
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, |
daemon->auth_ttl, NULL, qtype, C_IN, |
daemon->auth_ttl, NULL, qtype, C_IN, |
qtype == T_A ? "4" : "6", &crecp->addr)) |
qtype == T_A ? "4" : "6", &crecp->addr)) |
Line 541 size_t answer_auth(struct dns_header *header, char *li
|
Line 560 size_t answer_auth(struct dns_header *header, char *li
|
|
|
if (candidate) |
if (candidate) |
{ |
{ |
log_query(F_CONFIG | F_CNAME, name, NULL, NULL); | log_query(F_CONFIG | F_CNAME, name, NULL, NULL, 0); |
strcpy(name, candidate->target); |
strcpy(name, candidate->target); |
if (!strchr(name, '.')) |
if (!strchr(name, '.')) |
{ |
{ |
Line 559 size_t answer_auth(struct dns_header *header, char *li
|
Line 578 size_t answer_auth(struct dns_header *header, char *li
|
else if (cache_find_non_terminal(name, now)) |
else if (cache_find_non_terminal(name, now)) |
nxdomain = 0; |
nxdomain = 0; |
|
|
log_query(flag | F_NEG | (nxdomain ? F_NXDOMAIN : 0) | F_FORWARD | F_AUTH, name, NULL, NULL); | log_query(flag | F_NEG | (nxdomain ? F_NXDOMAIN : 0) | F_FORWARD | F_AUTH, name, NULL, NULL, 0); |
} |
} |
|
|
} |
} |
Line 589 size_t answer_auth(struct dns_header *header, char *li
|
Line 608 size_t answer_auth(struct dns_header *header, char *li
|
if (subnet->prefixlen >= 16 ) |
if (subnet->prefixlen >= 16 ) |
p += sprintf(p, "%u.", a & 0xff); |
p += sprintf(p, "%u.", a & 0xff); |
a = a >> 8; |
a = a >> 8; |
p += sprintf(p, "%u.in-addr.arpa", a & 0xff); | sprintf(p, "%u.in-addr.arpa", a & 0xff); |
|
|
} |
} |
else |
else |
Line 602 size_t answer_auth(struct dns_header *header, char *li
|
Line 621 size_t answer_auth(struct dns_header *header, char *li
|
int dig = ((unsigned char *)&subnet->addr.addr6)[i>>3]; |
int dig = ((unsigned char *)&subnet->addr.addr6)[i>>3]; |
p += sprintf(p, "%.1x.", (i>>2) & 1 ? dig & 15 : dig >> 4); |
p += sprintf(p, "%.1x.", (i>>2) & 1 ? dig & 15 : dig >> 4); |
} |
} |
p += sprintf(p, "ip6.arpa"); | sprintf(p, "ip6.arpa"); |
|
|
} |
} |
} |
} |
Line 855 size_t answer_auth(struct dns_header *header, char *li
|
Line 874 size_t answer_auth(struct dns_header *header, char *li
|
SET_RCODE(header, NXDOMAIN); |
SET_RCODE(header, NXDOMAIN); |
else |
else |
SET_RCODE(header, NOERROR); /* no error */ |
SET_RCODE(header, NOERROR); /* no error */ |
|
|
header->ancount = htons(anscount); |
header->ancount = htons(anscount); |
header->nscount = htons(authcount); |
header->nscount = htons(authcount); |
header->arcount = htons(0); |
header->arcount = htons(0); |
|
|
|
if (!local_query && out_of_zone) |
|
{ |
|
SET_RCODE(header, REFUSED); |
|
header->ancount = htons(0); |
|
header->nscount = htons(0); |
|
addr.log.rcode = REFUSED; |
|
addr.log.ede = EDE_NOT_AUTH; |
|
log_query(F_UPSTREAM | F_RCODE, "error", &addr, NULL, 0); |
|
return resize_packet(header, ansp - (unsigned char *)header, NULL, 0); |
|
} |
|
|
/* Advertise our packet size limit in our reply */ |
/* Advertise our packet size limit in our reply */ |
if (have_pseudoheader) |
if (have_pseudoheader) |
return add_pseudoheader(header, ansp - (unsigned char *)header, (unsigned char *)limit, daemon->edns_pktsz, 0, NULL, 0, do_bit, 0); |
return add_pseudoheader(header, ansp - (unsigned char *)header, (unsigned char *)limit, daemon->edns_pktsz, 0, NULL, 0, do_bit, 0); |
Line 867 size_t answer_auth(struct dns_header *header, char *li
|
Line 898 size_t answer_auth(struct dns_header *header, char *li
|
} |
} |
|
|
#endif |
#endif |
|
|
|
|
|
|