From: Miod Vallat Date: Mon, 11 Aug 2025 11:09:20 +0000 (+0200) Subject: Suggest increasing the serial number even if SOA changes but serial doesn't. X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=2e372bc5eb9c286017d1537447d13287c9f3ae02;p=thirdparty%2Fpdns.git Suggest increasing the serial number even if SOA changes but serial doesn't. Fixes: #13169 Signed-off-by: Miod Vallat --- diff --git a/pdns/pdnsutil.cc b/pdns/pdnsutil.cc index a9aea8ef7..5f473378a 100644 --- a/pdns/pdnsutil.cc +++ b/pdns/pdnsutil.cc @@ -1899,11 +1899,23 @@ static bool parseZoneFile(const char* tmpnam, int& errorline, std::vector& records) +{ + auto iter = std::find_if(records.begin(), records.end(), [&info](const DNSRecord& rec) { return rec.d_type == QType::SOA && rec.d_name == info.zone.operator const DNSName&(); }); + // If there is no SOA record, then, well, we can argue its serial number + // did change, because this means someone irresponsible has deleted it. + if (iter == records.end()) { + return false; + } + SOAData newsoa; + fillSOAData(iter->getContent()->getZoneRepresentation(true), newsoa); + return soa.serial == newsoa.serial; +} + // Increase the serial number of the SOA record according to the // SOA-EDIT-INCREASE policy. -// Returns true if successful, with `update' containing the updated -// record, false otherwise. -static bool increaseZoneSerial(UtilBackend &B, DNSSECKeeper& dsk, DomainInfo& info, std::vector& records, const PDNSColors& col, DNSRecord& update) // NOLINT(readability-identifier-length) +static bool increaseZoneSerial(DNSSECKeeper& dsk, DomainInfo& info, std::vector& records, const PDNSColors& col) { auto iter = std::find_if(records.begin(), records.end(), [&info](const DNSRecord& rec) { return rec.d_type == QType::SOA && rec.d_name == info.zone.operator const DNSName&(); }); // There should be one SOA record, therefore iter should be valid... @@ -1912,10 +1924,15 @@ static bool increaseZoneSerial(UtilBackend &B, DNSSECKeeper& dsk, DomainInfo& in if (iter == records.end()) { return false; } + // Since the user may have modified the SOA record (but not its serial + // number), we need to recreate a fresh SOAData from the new record contents. DNSRecord oldSoaDR = *iter; - SOAData soa; - B.getSOAUncached(info.zone, soa); + fillSOAData(oldSoaDR.getContent()->getZoneRepresentation(true), soa); + // copy the few fields not set up by fillSOAData() above. + soa.zonename = info.zone; + soa.ttl = oldSoaDR.d_ttl; + // TODO: do we need to check for presigned? here or maybe even all the way before edit-zone starts? string soaEditKind; @@ -1930,9 +1947,8 @@ static bool increaseZoneSerial(UtilBackend &B, DNSSECKeeper& dsk, DomainInfo& in str << col.green() << "+" << rec.d_name << " " << rec.d_ttl<< " IN " <getZoneRepresentation(true) << col.rst() <