Fix DNAME when QTYPE is CNAME or ANY

The synthesised CNAME is not supposed to be followed when the
QTYPE is CNAME or ANY as the lookup is satisfied by the CNAME
record.
This commit is contained in:
Mark Andrews 2020-11-17 11:03:21 +11:00
parent ff2bc7891e
commit e980affba0
5 changed files with 68 additions and 6 deletions

View file

@ -1,3 +1,6 @@
5534. [bug] The synthesised CNAME from a DNAME was incorrectly
followed when the QTYPE was CNAME or ANY. [GL #2280]
5533. [func] Add "stale-refresh-time" option, a time window that
starts after a failed lookup, during which stale rrset
will be served directly from cache before a new

View file

@ -20,3 +20,4 @@ ns A 10.53.0.1
www CNAME server.example.net.
inzone CNAME a.example.com.
a A 10.53.0.1
dname DNAME @

View file

@ -127,6 +127,54 @@ grep "a.example.com.*A.*10.53.0.1" dig.out.test$n > /dev/null || ret=1
[ $ret -eq 0 ] || echo_i "failed"
status=`expr $status + $ret`
n=`expr $n + 1`
echo_i "check that in-zone CNAME records does not return target data when QTYPE is CNAME (rd=1/ra=1) ($n)"
ret=0
$DIG $DIGOPTS @10.53.0.2 -t cname inzone.example.com > dig.out.test$n || ret=1
grep 'ANSWER: 1,' dig.out.test$n > /dev/null || ret=1
grep 'flags: qr aa rd ra;' dig.out.test$n > /dev/null || ret=1
grep 'inzone\.example\.com\..*CNAME.a\.example\.com\.' dig.out.test$n > /dev/null || ret=1
grep 'a\.example\.com\..*A.10\.53\.0\.1' dig.out.test$n > /dev/null && ret=1
[ $ret -eq 0 ] || echo_i "failed"
status=`expr $status + $ret`
n=`expr $n + 1`
echo_i "check that in-zone CNAME records does not return target data when QTYPE is ANY (rd=1/ra=1) ($n)"
ret=0
$DIG $DIGOPTS @10.53.0.2 -t any inzone.example.com > dig.out.test$n || ret=1
grep 'ANSWER: 1,' dig.out.test$n > /dev/null || ret=1
grep 'flags: qr aa rd ra;' dig.out.test$n > /dev/null || ret=1
grep 'inzone\.example\.com\..*CNAME.a\.example\.com\.' dig.out.test$n > /dev/null || ret=1
grep 'a\.example\.com\..*A.10\.53\.0\.1' dig.out.test$n > /dev/null && ret=1
[ $ret -eq 0 ] || echo_i "failed"
status=`expr $status + $ret`
n=`expr $n + 1`
echo_i "check that in-zone DNAME records does not return target data when QTYPE is CNAME (rd=1/ra=1) ($n)"
ret=0
$DIG $DIGOPTS @10.53.0.2 -t cname inzone.dname.example.com > dig.out.test$n || ret=1
grep 'ANSWER: 2,' dig.out.test$n > /dev/null || ret=1
grep 'flags: qr aa rd ra;' dig.out.test$n > /dev/null || ret=1
grep 'dname\.example\.com\..*DNAME.example\.com\.' dig.out.test$n > /dev/null || ret=1
grep 'inzone\.dname\.example\.com\..*CNAME.inzone\.example\.com\.' dig.out.test$n > /dev/null || ret=1
grep 'inzone\.example\.com\..*CNAME.a\.example\.com\.' dig.out.test$n > /dev/null && ret=1
grep 'a\.example\.com\..*A.10\.53\.0\.1' dig.out.test$n > /dev/null && ret=1
[ $ret -eq 0 ] || echo_i "failed"
status=`expr $status + $ret`
n=`expr $n + 1`
echo_i "check that in-zone DNAME records does not return target data when QTYPE is ANY (rd=1/ra=1) ($n)"
ret=0
$DIG $DIGOPTS @10.53.0.2 -t any inzone.dname.example.com > dig.out.test$n || ret=1
grep 'ANSWER: 2,' dig.out.test$n > /dev/null || ret=1
grep 'flags: qr aa rd ra;' dig.out.test$n > /dev/null || ret=1
grep 'dname\.example\.com\..*DNAME.example\.com\.' dig.out.test$n > /dev/null || ret=1
grep 'inzone\.dname\.example\.com\..*CNAME.inzone\.example\.com\.' dig.out.test$n > /dev/null || ret=1
grep 'inzone\.example\.com.*CNAME.a\.example\.com\.' dig.out.test$n > /dev/null && ret=1
grep 'a\.example\.com.*A.10\.53\.0\.1' dig.out.test$n > /dev/null && ret=1
[ $ret -eq 0 ] || echo_i "failed"
status=`expr $status + $ret`
n=`expr $n + 1`
echo_i "check that CHAOS addresses are compared correctly ($n)"
ret=0

View file

@ -65,3 +65,6 @@ Bug Fixes
- ``named`` could crash with an assertion failure if a TCP connection is closed
while the request is still processing. [GL #2227]
- The synthesised CNAME from a DNAME was incorrectly followed when the QTYPE
was CNAME or ANY. [GL #2280]

View file

@ -9897,13 +9897,20 @@ query_dname(query_ctx_t *qctx) {
}
/*
* Switch to the new qname and restart.
* If the original query was not for a CNAME or ANY then follow the
* CNAME.
*/
ns_client_qnamereplace(qctx->client, qctx->fname);
qctx->fname = NULL;
qctx->want_restart = true;
if (!WANTRECURSION(qctx->client)) {
qctx->options |= DNS_GETDB_NOLOG;
if (qctx->qtype != dns_rdatatype_cname &&
qctx->qtype != dns_rdatatype_any) {
/*
* Switch to the new qname and restart.
*/
ns_client_qnamereplace(qctx->client, qctx->fname);
qctx->fname = NULL;
qctx->want_restart = true;
if (!WANTRECURSION(qctx->client)) {
qctx->options |= DNS_GETDB_NOLOG;
}
}
query_addauth(qctx);