]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
ws-auth: Check DNAME records correctly
authorAki Tuomi <cmouse@cmouse.fi>
Mon, 6 Jan 2020 17:54:37 +0000 (19:54 +0200)
committerAki Tuomi <cmouse@cmouse.fi>
Wed, 15 Jan 2020 12:57:44 +0000 (14:57 +0200)
Closes #8641

pdns/ws-auth.cc

index a7a2850b4b24969e8086831cb911d1b96d963617..74296c392fb9ff98178406eb774b879041119030 100644 (file)
@@ -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<uint16_t> 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<uint16_t> exclusiveEntryTypes = { QType::CNAME, QType::DNAME };
+static const std::set<uint16_t> 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)) {