diff --git a/lib/ns/query.c b/lib/ns/query.c index ca76df4f3d..4fd70e6fbc 100644 --- a/lib/ns/query.c +++ b/lib/ns/query.c @@ -47,6 +47,7 @@ #include #include #include +#include #include #include #include @@ -10137,6 +10138,7 @@ query_cname(query_ctx_t *qctx) { dns_name_copy(&cname.cname, tname); dns_rdata_freestruct(&cname); + ns_client_qnamereplace(qctx->client, tname); qctx->want_restart = true; if (!WANTRECURSION(qctx->client)) { @@ -10260,6 +10262,37 @@ query_dname(query_ctx_t *qctx) { goto cleanup; } + /* + * If the target is a denied alias, and both the `except-from` list + * and the subdomain rule of the `deny-answer-aliases` + * configuration option (see ARM) don't give an exception, then + * answer with a SERVFAIL. + */ + dns_fixedname_t fdeniedname; + dns_name_t *deniedname = dns_fixedname_initname(&fdeniedname); + if (qctx->view->denyanswernames != NULL && + dns_nametree_covered(qctx->view->denyanswernames, qctx->fname, + deniedname, 0) && + !dns_nametree_covered(qctx->view->answernames_exclude, + qctx->client->query.qname, NULL, 0) && + !dns_name_issubdomain(qctx->client->query.qname, deniedname)) + { + char qnamebuf[DNS_NAME_FORMATSIZE]; + char tnamebuf[DNS_NAME_FORMATSIZE]; + + dns_name_format(qctx->client->query.qname, qnamebuf, + sizeof(qnamebuf)); + dns_name_format(qctx->fname, tnamebuf, sizeof(tnamebuf)); + ns_client_log(qctx->client, NS_LOGCATEGORY_QUERIES, + NS_LOGMODULE_QUERY, ISC_LOG_NOTICE, + "DNAME target %s denied for %s (cache)", tnamebuf, + qnamebuf); + QUERY_ERROR(qctx, DNS_R_SERVFAIL); + ns_client_releasename(qctx->client, &qctx->fname); + (void)ns_query_done(qctx); + goto cleanup; + } + ns_client_keepname(qctx->client, qctx->fname, qctx->dbuf); /*