Merge branch '1798-reject-master-zones-with-ds-records-at-the-apex' into 'master'

Resolve "Reject master zones with DS records at the apex."

Closes #1798

See merge request isc-projects/bind9!3435
This commit is contained in:
Ondřej Surý 2020-06-04 14:01:14 +00:00
commit e2f362c55b
8 changed files with 90 additions and 23 deletions

View file

@ -1,3 +1,7 @@
5431. [func] Reject DS records at the zone apex when loading
master files. Log but otherwise ignore attempts to
add DS records at the zone apex via UPDATE. [GL #1798]
5430. [doc] Update docs - with netmgr we're creating separate
socket for each IPv6 interface, just as with IPv4.
[GL #1782]

View file

@ -0,0 +1,4 @@
example. 0 SOA . . 0 0 0 0 0
example. 0 NS .
example. 0 DNSKEY 257 3 10 AwEAAbqjg7xdvnU2Q/gtLw5LOfr5cDeTRjYuEbkzGrUiVSOSoxcTxuao WS/AFPQHuD8OSLiE/CeZ087JowREXl058rRfae8KMrveY17V0wmKs9N1 F1wf/hRDpXiThlRHWlskp8eSEEIqYrrHgWTesy/xDGIEOFM1gwRo0w8j KdRRJeL2hseTMa+m3rTzrYudUsI0BHLW8PiDUCbG5xgdee8/5YR4847i AAqHIiPJ1Z/IT53OIjMmtv5BUykZ8RYjlJxxX+C+dpRKiK73SQaR3hCB XAYOL9WsDp2/fpmEZpewavkMkdC+j2CX+z27MCS3ASO0AeKK0lcNXwND kgreE+Kr7gc=
example. 0 DS 14364 10 2 FD03B2312C8F0FE72C1751EFA1007D743C94EC91594FF0047C23C37CE119BA0C

View file

@ -32,6 +32,8 @@ RNDCCMD="$RNDC -c $SYSTEMTESTTOP/common/rndc.conf -p ${CONTROLPORT} -s"
status=0
n=0
nextpartreset ns3/named.run
# wait for zone transfer to complete
tries=0
while true; do
@ -1087,6 +1089,25 @@ then
echo_i "failed"; status=1
fi
echo_i "check that DS to the zone apex is ignored ($n)"
$DIG $DIGOPTS +tcp +norec example DS @10.53.0.3 > dig.out.pre.test$n || ret=1
grep "status: NOERROR" dig.out.pre.test$n > /dev/null || ret=1
grep "ANSWER: 0," dig.out.pre.test$n > /dev/null || ret=1
nextpart ns3/named.run > /dev/null
# specify zone to override the default of adding to parent zone
$NSUPDATE -d <<END > nsupdate.out-$n 2>&1 || ret=1
server 10.53.0.3 ${PORT}
zone example
update add example 0 in DS 14364 10 2 FD03B2312C8F0FE72C1751EFA1007D743C94EC91594FF0047C23C37CE119BA0C
send
END
msg=": attempt to add a DS record at zone apex ignored"
nextpart ns3/named.run | grep "$msg" > /dev/null || ret=1
$DIG $DIGOPTS +tcp +norec example DS @10.53.0.3 > dig.out.post.test$n || ret=1
grep "status: NOERROR" dig.out.post.test$n > /dev/null || ret=1
grep "ANSWER: 0," dig.out.post.test$n > /dev/null || ret=1
[ $ret = 0 ] || { echo_i "failed"; status=1; }
if $FEATURETEST --gssapi ; then
n=`expr $n + 1`
ret=0

View file

@ -71,6 +71,11 @@ New Features
statements, to limit the number of records of a particular type
that can be added to a domain name via dynamic update. [GL #1657]
- ``named`` and ``named-checkzone`` now reject master zones that
have a DS RRset at the zone apex. Attempts to add DS records
at the zone apex via UPDATE will be logged but otherwise ignored.
DS records belong in the parent zone, not at the zone apex. [GL #1798]
Feature Changes
~~~~~~~~~~~~~~~

View file

@ -154,8 +154,9 @@
#define DNS_R_BADSIG0 (ISC_RESULTCLASS_DNS + 116)
#define DNS_R_TOOMANYRECORDS (ISC_RESULTCLASS_DNS + 117)
#define DNS_R_VERIFYFAILURE (ISC_RESULTCLASS_DNS + 118)
#define DNS_R_ATZONETOP (ISC_RESULTCLASS_DNS + 119)
#define DNS_R_NRESULTS 119 /*%< Number of results */
#define DNS_R_NRESULTS 120 /*%< Number of results */
/*
* DNS wire format rcodes.

View file

@ -339,6 +339,13 @@ static unsigned char ip6_arpa_offsets[] = { 0, 4, 9 };
static dns_name_t const ip6_arpa = DNS_NAME_INITABSOLUTE(ip6_arpa_data,
ip6_arpa_offsets);
static inline bool
dns_master_isprimary(dns_loadctx_t *lctx) {
return ((lctx->options & DNS_MASTER_ZONE) != 0 &&
(lctx->options & DNS_MASTER_SLAVE) == 0 &&
(lctx->options & DNS_MASTER_KEY) == 0);
}
static inline isc_result_t
gettoken(isc_lex_t *lex, unsigned int options, isc_token_t *token, bool eol,
dns_rdatacallbacks_t *callbacks) {
@ -840,10 +847,7 @@ generate(dns_loadctx_t *lctx, char *range, char *lhs, char *gtype, char *rhs,
* RFC2930: TKEY and TSIG are not allowed to be loaded
* from master files.
*/
if ((lctx->options & DNS_MASTER_ZONE) != 0 &&
(lctx->options & DNS_MASTER_SLAVE) == 0 &&
dns_rdatatype_ismeta(type))
{
if (dns_master_isprimary(lctx) && dns_rdatatype_ismeta(type)) {
(*callbacks->error)(callbacks, "%s: %s:%lu: meta RR type '%s'",
"$GENERATE", source, line, gtype);
result = DNS_R_METATYPE;
@ -869,11 +873,8 @@ generate(dns_loadctx_t *lctx, char *range, char *lhs, char *gtype, char *rhs,
goto error_cleanup;
}
if ((lctx->options & DNS_MASTER_ZONE) != 0 &&
(lctx->options & DNS_MASTER_SLAVE) == 0 &&
(lctx->options & DNS_MASTER_KEY) == 0 &&
!dns_name_issubdomain(owner, lctx->top))
{
if (dns_master_isprimary(lctx) &&
!dns_name_issubdomain(owner, lctx->top)) {
char namebuf[DNS_NAME_FORMATSIZE];
dns_name_format(owner, namebuf, sizeof(namebuf));
/*
@ -1541,11 +1542,8 @@ load_text(dns_loadctx_t *lctx) {
callbacks);
}
}
if ((lctx->options & DNS_MASTER_ZONE) != 0 &&
(lctx->options & DNS_MASTER_SLAVE) == 0 &&
(lctx->options & DNS_MASTER_KEY) == 0 &&
!dns_name_issubdomain(new_name, lctx->top))
{
if (dns_master_isprimary(lctx) &&
!dns_name_issubdomain(new_name, lctx->top)) {
char namebuf[DNS_NAME_FORMATSIZE];
dns_name_format(new_name, namebuf,
sizeof(namebuf));
@ -1740,8 +1738,7 @@ load_text(dns_loadctx_t *lctx) {
* RFC1123: MD and MF are not allowed to be loaded from
* master files.
*/
if ((lctx->options & DNS_MASTER_ZONE) != 0 &&
(lctx->options & DNS_MASTER_SLAVE) == 0 &&
if (dns_master_isprimary(lctx) &&
(type == dns_rdatatype_md || type == dns_rdatatype_mf))
{
char typebuf[DNS_RDATATYPE_FORMATSIZE];
@ -1763,10 +1760,7 @@ load_text(dns_loadctx_t *lctx) {
* RFC2930: TKEY and TSIG are not allowed to be loaded
* from master files.
*/
if ((lctx->options & DNS_MASTER_ZONE) != 0 &&
(lctx->options & DNS_MASTER_SLAVE) == 0 &&
dns_rdatatype_ismeta(type))
{
if (dns_master_isprimary(lctx) && dns_rdatatype_ismeta(type)) {
char typebuf[DNS_RDATATYPE_FORMATSIZE];
result = DNS_R_METATYPE;
@ -1902,6 +1896,30 @@ load_text(dns_loadctx_t *lctx) {
}
}
if (dns_rdatatype_atparent(type) &&
dns_master_isprimary(lctx) &&
dns_name_equal(ictx->current, lctx->top))
{
char namebuf[DNS_NAME_FORMATSIZE];
char typebuf[DNS_RDATATYPE_FORMATSIZE];
dns_name_format(ictx->current, namebuf,
sizeof(namebuf));
dns_rdatatype_format(type, typebuf, sizeof(typebuf));
(*callbacks->error)(
callbacks,
"%s:%lu: %s record at top of zone (%s)", source,
line, typebuf, namebuf);
result = DNS_R_ATZONETOP;
if (MANYERRS(lctx, result)) {
SETRESULT(lctx, result);
target = target_ft;
continue;
} else {
goto insist_and_cleanup;
}
}
if (type == dns_rdatatype_rrsig || type == dns_rdatatype_sig) {
covers = dns_rdata_covers(&rdata[rdcount]);
} else {
@ -1963,8 +1981,7 @@ load_text(dns_loadctx_t *lctx) {
}
if ((type == dns_rdatatype_sig || type == dns_rdatatype_nxt) &&
lctx->warn_tcr && (lctx->options & DNS_MASTER_ZONE) != 0 &&
(lctx->options & DNS_MASTER_SLAVE) == 0)
lctx->warn_tcr && dns_master_isprimary(lctx))
{
(*callbacks->warn)(callbacks,
"%s:%lu: old style DNSSEC "

View file

@ -164,6 +164,7 @@ static const char *text[DNS_R_NRESULTS] = {
"SIG(0) in wrong location", /*%< 116 DNS_R_BADSIG0 */
"too many records", /*%< 117 DNS_R_TOOMANYRECORDS */
"verify failure", /*%< 118 DNS_R_VERIFYFAILURE */
"at top of zone", /*%< 119 DNS_R_ATZONETOP */
};
static const char *ids[DNS_R_NRESULTS] = {
@ -290,6 +291,7 @@ static const char *ids[DNS_R_NRESULTS] = {
"DNS_R_BADSIG0",
"DNS_R_TOOMANYRECORDS",
"DNS_R_VERIFYFAILURE",
"DNS_R_ATZONETOP",
};
static const char *rcode_text[DNS_R_NRCODERESULTS] = {

View file

@ -2969,6 +2969,19 @@ update_action(isc_task_t *task, isc_event_t *event) {
soa_serial_changed = true;
}
if (dns_rdatatype_atparent(rdata.type) &&
dns_name_equal(name, zonename)) {
char typebuf[DNS_RDATATYPE_FORMATSIZE];
dns_rdatatype_format(rdata.type, typebuf,
sizeof(typebuf));
update_log(client, zone, LOGLEVEL_PROTOCOL,
"attempt to add a %s record at "
"zone apex ignored",
typebuf);
continue;
}
if (rdata.type == privatetype) {
update_log(client, zone, LOGLEVEL_PROTOCOL,
"attempt to add a private type "