]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
Make increaseSOARecord and RFC2136 code variant-aware.
authorMiod Vallat <miod.vallat@powerdns.com>
Wed, 7 May 2025 12:01:03 +0000 (14:01 +0200)
committerMiod Vallat <miod.vallat@powerdns.com>
Mon, 26 May 2025 11:49:13 +0000 (13:49 +0200)
pdns/auth-zonecache.cc
pdns/auth-zonecache.hh
pdns/dnsseckeeper.hh
pdns/packethandler.cc
pdns/rfc2136handler.cc
pdns/serialtweaker.cc
pdns/tcpreceiver.cc
pdns/ws-auth.cc

index 904c75abd4b49bbfe7dd1d6bf9d3a93df135066a..342e269d5fa1c46595687d7460365f363c6464b9 100644 (file)
@@ -108,13 +108,13 @@ std::string AuthZoneCache::getVariantFromView(const ZoneName& zone, const std::s
   return variant;
 }
 
-void AuthZoneCache::setZoneVariant(std::unique_ptr<DNSPacket>& packet)
+void AuthZoneCache::setZoneVariant(DNSPacket& packet)
 {
-  Netmask net = packet->getRealRemote();
+  Netmask net = packet.getRealRemote();
   string view = getViewFromNetwork(&net);
-  packet->qdomainzone = ZoneName(packet->qdomain);
-  string variant = getVariantFromView(packet->qdomainzone, view);
-  packet->qdomainzone.setVariant(variant);
+  packet.qdomainzone = ZoneName(packet.qdomain);
+  string variant = getVariantFromView(packet.qdomainzone, view);
+  packet.qdomainzone.setVariant(variant);
 }
 #endif // ] PDNS_AUTH
 
index ae511d1e569e8e9d5d11ebf42e42d183a67ad79d..c4459e86c3f88b48bc778d4f154ca5107d95a523 100644 (file)
@@ -59,7 +59,7 @@ public:
 
   // Variant lookup
   std::string getVariantFromView(const ZoneName& zone, const std::string& view);
-  void setZoneVariant(std::unique_ptr<DNSPacket>& packet);
+  void setZoneVariant(DNSPacket& packet);
 
   size_t size() { return *d_statnumentries; } //!< number of entries in the cache
 
index d2bdd492047c4124333edc28bce1a0a1a686e639..c454a1d71488b6ddc20c731534d1bdb56d019dfa 100644 (file)
@@ -309,6 +309,6 @@ uint32_t localtime_format_YYYYMMDDSS(time_t t, uint32_t seq);
 uint32_t calculateEditSOA(uint32_t old_serial, DNSSECKeeper& dsk, const ZoneName& zonename);
 uint32_t calculateEditSOA(uint32_t old_serial, const string& kind, const ZoneName& zonename);
 // for SOA-EDIT-DNSUPDATE/API
-bool increaseSOARecord(DNSResourceRecord& dr, const string& increaseKind, const string& editKind);
+bool increaseSOARecord(DNSResourceRecord& rr, const string& increaseKind, const string& editKind, const ZoneName& zonename);
 bool makeIncreasedSOARecord(SOAData& sd, const string& increaseKind, const string& editKind, DNSResourceRecord& rrout);
 DNSZoneRecord makeEditedDNSZRFromSOAData(DNSSECKeeper& dk, const SOAData& sd, DNSResourceRecord::Place place=DNSResourceRecord::ANSWER);
index b586c6aae1b12e650972727d2623c52dc784921f..019d8633daf5a766fded3b4b27a94a35152764e6 100644 (file)
@@ -370,7 +370,7 @@ void PacketHandler::getBestDNAMESynth(DNSPacket& p, DNSName &target, vector<DNSZ
     if(!ret.empty()) {
       return;
     }
-    if(subdomain.countLabels()) {
+    if(subdomain.countLabels() != 0) {
       prefix.appendRawLabel(subdomain.getRawLabels()[0]); // XXX DNSName pain this feels wrong
     }
     if(subdomain == d_sd.qname()) { // stop at SOA
@@ -1959,6 +1959,14 @@ std::unique_ptr<DNSPacket> PacketHandler::opcodeNotify(DNSPacket& pkt, bool /* n
 
 std::unique_ptr<DNSPacket> PacketHandler::opcodeUpdate(DNSPacket& pkt, bool /* noCache */)
 {
+  if (g_views) {
+    // Make this variant-aware without performing the complete UeberBackend::getAuth work
+    g_zoneCache.setZoneVariant(pkt);
+  }
+  else {
+    pkt.qdomainzone = ZoneName(pkt.qdomain);
+  }
+
   S.inc("dnsupdate-queries");
   int res=processUpdate(pkt);
   if (res == RCode::Refused) {
index d4844427d4ea988acc60d89b4e48b51749dace20..7d74864a1be3e5b831ef50ca59c5751ce1b98b63 100644 (file)
@@ -377,12 +377,16 @@ uint PacketHandler::performUpdate(const string &msgPrefix, const DNSRecord *rr,
 
     if (rrType == QType::NSEC3PARAM) {
       g_log<<Logger::Notice<<msgPrefix<<"Deleting NSEC3PARAM from zone, resetting ordernames."<<endl;
-      if (rr->d_class == QClass::ANY)
-        d_dk.unsetNSEC3PARAM(ZoneName(rr->d_name));
+      // Be sure to use a ZoneName with a variant matching the domain we are
+      // working on, for the sake of unsetNSEC3PARAM.
+      ZoneName zonename(rr->d_name, di->zone.getVariant());
+      if (rr->d_class == QClass::ANY) {
+        d_dk.unsetNSEC3PARAM(zonename);
+      }
       else if (rr->d_class == QClass::NONE) {
         NSEC3PARAMRecordContent nsec3rr(rr->getContent()->getZoneRepresentation(), di->zone);
         if (*haveNSEC3 && ns3pr->getZoneRepresentation() == nsec3rr.getZoneRepresentation())
-          d_dk.unsetNSEC3PARAM(ZoneName(rr->d_name));
+          d_dk.unsetNSEC3PARAM(zonename);
         else
           return 0;
       } else
@@ -546,7 +550,7 @@ uint PacketHandler::performUpdate(const string &msgPrefix, const DNSRecord *rr,
 
 int PacketHandler::forwardPacket(const string &msgPrefix, const DNSPacket& p, const DomainInfo& di) {
   vector<string> forward;
-  B.getDomainMetadata(ZoneName(p.qdomain), "FORWARD-DNSUPDATE", forward);
+  B.getDomainMetadata(p.qdomainzone, "FORWARD-DNSUPDATE", forward);
 
   if (forward.size() == 0 && ! ::arg().mustDo("forward-dnsupdate")) {
     g_log << Logger::Notice << msgPrefix << "Not configured to forward to primary, returning Refused." << endl;
@@ -669,8 +673,7 @@ int PacketHandler::processUpdate(DNSPacket& packet) { // NOLINT(readability-func
   if (! ::arg().mustDo("dnsupdate"))
     return RCode::Refused;
 
-  ZoneName zonename(packet.qdomain);
-  string msgPrefix="UPDATE (" + std::to_string(packet.d.id) + ") from " + packet.getRemoteString() + " for " + zonename.toLogString() + ": ";
+  string msgPrefix="UPDATE (" + std::to_string(packet.d.id) + ") from " + packet.getRemoteString() + " for " + packet.qdomainzone.toLogString() + ": ";
   g_log<<Logger::Info<<msgPrefix<<"Processing started."<<endl;
 
   // if there is policy, we delegate all checks to it
@@ -678,7 +681,7 @@ int PacketHandler::processUpdate(DNSPacket& packet) { // NOLINT(readability-func
 
     // Check permissions - IP based
     vector<string> allowedRanges;
-    B.getDomainMetadata(zonename, "ALLOW-DNSUPDATE-FROM", allowedRanges);
+    B.getDomainMetadata(packet.qdomainzone, "ALLOW-DNSUPDATE-FROM", allowedRanges);
     if (! ::arg()["allow-dnsupdate-from"].empty())
       stringtok(allowedRanges, ::arg()["allow-dnsupdate-from"], ", \t" );
 
@@ -695,7 +698,7 @@ int PacketHandler::processUpdate(DNSPacket& packet) { // NOLINT(readability-func
 
     // Check permissions - TSIG based.
     vector<string> tsigKeys;
-    B.getDomainMetadata(zonename, "TSIG-ALLOW-DNSUPDATE", tsigKeys);
+    B.getDomainMetadata(packet.qdomainzone, "TSIG-ALLOW-DNSUPDATE", tsigKeys);
     if (tsigKeys.size() > 0) {
       bool validKey = false;
 
@@ -763,8 +766,8 @@ int PacketHandler::processUpdate(DNSPacket& packet) { // NOLINT(readability-func
 
   DomainInfo di;
   di.backend=nullptr;
-  if(!B.getDomainInfo(zonename, di) || (di.backend == nullptr)) {
-    g_log<<Logger::Error<<msgPrefix<<"Can't determine backend for domain '"<<zonename<<"' (or backend does not support DNS update operation)"<<endl;
+  if(!B.getDomainInfo(packet.qdomainzone, di) || (di.backend == nullptr)) {
+    g_log<<Logger::Error<<msgPrefix<<"Can't determine backend for domain '"<<packet.qdomainzone<<"' (or backend does not support DNS update operation)"<<endl;
     return RCode::NotAuth;
   }
 
@@ -789,8 +792,8 @@ int PacketHandler::processUpdate(DNSPacket& packet) { // NOLINT(readability-func
 
   std::lock_guard<std::mutex> l(s_rfc2136lock); //TODO: i think this lock can be per zone, not for everything
   g_log<<Logger::Info<<msgPrefix<<"starting transaction."<<endl;
-  if (!di.backend->startTransaction(zonename, UnknownDomainID)) { // Not giving the domain_id means that we do not delete the existing records.
-    g_log<<Logger::Error<<msgPrefix<<"Backend for domain "<<zonename<<" does not support transaction. Can't do Update packet."<<endl;
+  if (!di.backend->startTransaction(packet.qdomainzone, UnknownDomainID)) { // Not giving the domain_id means that we do not delete the existing records.
+    g_log<<Logger::Error<<msgPrefix<<"Backend for domain "<<packet.qdomainzone<<" does not support transaction. Can't do Update packet."<<endl;
     return RCode::NotImp;
   }
 
@@ -1004,7 +1007,7 @@ int PacketHandler::processUpdate(DNSPacket& packet) { // NOLINT(readability-func
       // Notify secondaries
       if (di.kind == DomainInfo::Primary) {
         vector<string> notify;
-        B.getDomainMetadata(zonename, "NOTIFY-DNSUPDATE", notify);
+        B.getDomainMetadata(packet.qdomainzone, "NOTIFY-DNSUPDATE", notify);
         if (!notify.empty() && notify.front() == "1") {
           Communicator.notifyDomain(di.zone, &B);
         }
index 57fcdfb67035e03fbd4b40cba200c27ca8ea0e08..9d593baf07c076e822f5092df5f2713c6aaef111 100644 (file)
@@ -130,14 +130,15 @@ static uint32_t calculateIncreaseSOA(uint32_t old_serial, const string& increase
  *
  * @return true if changes may have been made
  */
-bool increaseSOARecord(DNSResourceRecord& rr, const string& increaseKind, const string& editKind) {
+bool increaseSOARecord(DNSResourceRecord& rr, const string& increaseKind, const string& editKind, const ZoneName& zonename) { // NOLINT(readability-identifier-length)
   if (increaseKind.empty())
     return false;
 
   SOAData sd;
+  sd.zonename = zonename;
   fillSOAData(rr.content, sd);
 
-  sd.serial = calculateIncreaseSOA(sd.serial, increaseKind, editKind, ZoneName(rr.qname));
+  sd.serial = calculateIncreaseSOA(sd.serial, increaseKind, editKind, zonename);
   rr.content = makeSOAContent(sd)->getZoneRepresentation(true);
   return true;
 }
index 53952774d0b218a72f18d69b1c0d5555d4b21d5c..6a218b94baba283e2fe45cacfce925a4ea75a109 100644 (file)
@@ -370,14 +370,14 @@ void TCPNameserver::doConnection(int fd)
 
       if(packet->qtype.getCode()==QType::AXFR) {
         packet->d_xfr=true;
-        g_zoneCache.setZoneVariant(packet);
+        g_zoneCache.setZoneVariant(*packet);
         doAXFR(packet->qdomainzone, packet, fd);
         continue;
       }
 
       if(packet->qtype.getCode()==QType::IXFR) {
         packet->d_xfr=true;
-        g_zoneCache.setZoneVariant(packet);
+        g_zoneCache.setZoneVariant(*packet);
         doIXFR(packet, fd);
         continue;
       }
index 825fc5e32fad59b8bae06ab10087142a1fdd21bb..8fb21c33c104785e6be9521124951bc464764af8 100644 (file)
@@ -2359,7 +2359,7 @@ static void patchZone(UeberBackend& backend, const ZoneName& zonename, DomainInf
             for (DNSResourceRecord& resourceRecord : new_records) {
               resourceRecord.domain_id = static_cast<int>(domainInfo.id);
               if (resourceRecord.qtype.getCode() == QType::SOA && resourceRecord.qname == zonename.operator const DNSName&()) {
-                soa_edit_done = increaseSOARecord(resourceRecord, soa_edit_api_kind, soa_edit_kind);
+                soa_edit_done = increaseSOARecord(resourceRecord, soa_edit_api_kind, soa_edit_kind, zonename);
               }
             }
             checkNewRecords(new_records, zonename);