From: Aki Tuomi Date: Mon, 6 Jan 2020 17:54:37 +0000 (+0200) Subject: ws-auth: Check DNAME records correctly X-Git-Tag: auth-4.3.0-beta1~4^2~2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5e73d266fefd3c1bf0cc6f77748fe00d3d426c2a;p=thirdparty%2Fpdns.git ws-auth: Check DNAME records correctly Closes #8641 --- diff --git a/pdns/ws-auth.cc b/pdns/ws-auth.cc index a7a2850b4b..74296c392f 100644 --- a/pdns/ws-auth.cc +++ b/pdns/ws-auth.cc @@ -59,7 +59,7 @@ static void makePtr(const DNSResourceRecord& rr, DNSResourceRecord* ptr); // QTypes that MUST NOT have multiple records of the same type in a given RRset. static const std::set onlyOneEntryTypes = { QType::CNAME, QType::DNAME, QType::SOA }; // QTypes that MUST NOT be used with any other QType on the same name. -static const std::set exclusiveEntryTypes = { QType::CNAME, QType::DNAME }; +static const std::set exclusiveEntryTypes = { QType::CNAME }; AuthWebServer::AuthWebServer() : d_tid(0), @@ -2029,6 +2029,8 @@ static void patchZone(UeberBackend& B, HttpRequest* req, HttpResponse* resp) { if (replace_records) { bool ent_present = false; + bool dname_seen = false, ns_seen = false; + di.backend->lookup(QType(QType::ANY), qname, di.id); DNSResourceRecord rr; while (di.backend->get(rr)) { @@ -2037,6 +2039,10 @@ static void patchZone(UeberBackend& B, HttpRequest* req, HttpResponse* resp) { /* that's fine, we will override it */ continue; } + if (qtype == QType::DNAME || rr.qtype == QType::DNAME) + dname_seen = true; + if (qtype == QType::NS || rr.qtype == QType::NS) + ns_seen = true; if (qtype.getCode() != rr.qtype.getCode() && (exclusiveEntryTypes.count(qtype.getCode()) != 0 || exclusiveEntryTypes.count(rr.qtype.getCode()) != 0)) { @@ -2049,6 +2055,9 @@ static void patchZone(UeberBackend& B, HttpRequest* req, HttpResponse* resp) { } } + if (dname_seen && ns_seen && qname != zonename) { + throw ApiException("RRset "+qname.toString()+" IN "+qtype.getName()+": Cannot have both NS and DNAME except in zone apex"); + } if (!new_records.empty() && ent_present) { QType qt_ent{0}; if (!di.backend->replaceRRSet(di.id, qname, qt_ent, new_records)) {