]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
Change SOA-EDIT-API to work like SOA-EDIT-DNSUPDATE
authorChristian Hofstaedtler <christian@hofstaedtler.name>
Thu, 26 Feb 2015 22:30:31 +0000 (23:30 +0100)
committerChristian Hofstaedtler <christian@hofstaedtler.name>
Tue, 10 Mar 2015 11:26:50 +0000 (12:26 +0100)
The SOA-EDIT-DNSUPDATE behaviour makes for a better ruleset for
incremental updates, like they are done via the API.

Also SOA-EDIT-API now defaults to DEFAULT, if it's not given at all
during zone creation (over the API).

docs/markdown/httpapi/api_spec.md
pdns/dnsseckeeper.hh
pdns/rfc2136handler.cc
pdns/serialtweaker.cc
pdns/ws-auth.cc

index c33bcb82e5f1fe7e69e3248b1f52557d6e133348..0c352384e6bbcc8ed379bcc9c1d742952507ab0f 100644 (file)
@@ -336,7 +336,8 @@ zone_collection
 
 * `soa_edit_api` MAY be set. If it is set, on changes to the contents of
   a zone made through the API, the SOA record will be edited according to
-  the SOA-EDIT-API rules. (Which are the same as the SOA-EDIT rules.)
+  the SOA-EDIT-API rules. (Which are the same as the SOA-EDIT-DNSUPDATE rules.)
+  If not set at all during zone creation, defaults to `DEFAULT`.
   **Note**: Authoritative only.
 
 * `account` MAY be set. It's value is defined by local policy.
index 9031eb946af95f74e2e7140561e0fd88b620cc56..c1786e5f42a8f46734508fa960b64f8e2d6d34f8 100644 (file)
@@ -167,8 +167,12 @@ private:
 };
 
 class DNSPacket;
-uint32_t calculateEditSOA(SOAData sd, const string& kind);
 uint32_t localtime_format_YYYYMMDDSS(time_t t, uint32_t seq);
+// for SOA-EDIT
+uint32_t calculateEditSOA(SOAData sd, const string& kind);
 bool editSOA(DNSSECKeeper& dk, const string& qname, DNSPacket* dp);
 bool editSOARecord(DNSResourceRecord& rr, const string& kind);
+// for SOA-EDIT-DNSUPDATE/API
+uint32_t calculateIncreaseSOA(SOAData sd, const string& increaseKind, const string& editKind);
+bool increaseSOARecord(DNSResourceRecord& rr, const string& increaseKind, const string& editKind);
 #endif
index 4b254378e161eac39b91aa4248fd0c138fa65f7c..6be9c4ec9a2dba5e964e79a783b106fe34a7beb0 100644 (file)
@@ -961,39 +961,14 @@ void PacketHandler::increaseSerial(const string &msgPrefix, const DomainInfo *di
       vector<string> soaEditSetting;
       B.getDomainMetadata(di->zone, "SOA-EDIT", soaEditSetting);
       if (soaEditSetting.empty()) {
-        L<<Logger::Error<<msgPrefix<<"Using "<<soaEdit2136<<" for SOA-EDIT-DNSUPDATE increase on DNS update, but SOA-EDIT is not set for domain. Using DEFAULT for SOA-EDIT-DNSUPDATE"<<endl;
+        L<<Logger::Error<<msgPrefix<<"Using "<<soaEdit2136<<" for SOA-EDIT-DNSUPDATE increase on DNS update, but SOA-EDIT is not set for domain \""<< di->zone <<"\". Using DEFAULT for SOA-EDIT-DNSUPDATE"<<endl;
         soaEdit2136 = "DEFAULT";
       } else
         soaEdit = soaEditSetting[0];
     }
   }
 
-
-  if (pdns_iequals(soaEdit2136, "INCREASE"))
-    soa2Update.serial++;
-  else if (pdns_iequals(soaEdit2136, "SOA-EDIT-INCREASE")) {
-    uint32_t newSer = calculateEditSOA(soa2Update, soaEdit);
-    if (newSer <= soa2Update.serial)
-      soa2Update.serial++;
-    else
-      soa2Update.serial = newSer;
-  } else if (pdns_iequals(soaEdit2136, "SOA-EDIT"))
-    soa2Update.serial = calculateEditSOA(soa2Update, soaEdit);
-  else if (pdns_iequals(soaEdit2136, "EPOCH"))
-    soa2Update.serial = time(0);
-  else {
-    time_t now = time(0);
-    struct tm tm;
-    localtime_r(&now, &tm);
-    boost::format fmt("%04d%02d%02d%02d");
-    string newserdate=(fmt % (tm.tm_year+1900) % (tm.tm_mon +1 )% tm.tm_mday % 1).str();
-    uint32_t newser = atol(newserdate.c_str());
-    if (newser <= soa2Update.serial)
-      soa2Update.serial++;
-    else
-      soa2Update.serial = newser;
-  }
-
+  calculateIncreaseSOA(soa2Update, soaEdit2136, soaEdit);
 
   newRec.content = serializeSOAData(soa2Update);
   vector<DNSResourceRecord> rrset;
index c6c4a1775bd48a5338e6efc256c6c5e678770a14..b170f0984b1d80951d5b74e22535f94b2e005f15 100644 (file)
@@ -97,3 +97,50 @@ uint32_t calculateEditSOA(SOAData sd, const string& kind) {
   }
   return sd.serial;
 }
+
+// Used for SOA-EDIT-DNSUPDATE and SOA-EDIT-API.
+uint32_t calculateIncreaseSOA(SOAData sd, const string& increaseKind, const string& editKind) {
+  // These only work when SOA-EDIT is set, otherwise fall back to default.
+  if (!editKind.empty()) {
+    if (pdns_iequals(increaseKind, "SOA-EDIT-INCREASE")) {
+      uint32_t new_serial = calculateEditSOA(sd, editKind);
+      if (new_serial <= sd.serial) {
+        new_serial = sd.serial + 1;
+      }
+      return new_serial;
+    }
+    else if (pdns_iequals(increaseKind, "SOA-EDIT")) {
+      return calculateEditSOA(sd, editKind);
+    }
+  }
+
+  if (pdns_iequals(increaseKind, "INCREASE")) {
+    return sd.serial + 1;
+  }
+  else if (pdns_iequals(increaseKind, "EPOCH")) {
+    return time(0);
+  }
+
+  // DEFAULT case
+  time_t now = time(0);
+  struct tm tm;
+  localtime_r(&now, &tm);
+  boost::format fmt("%04d%02d%02d%02d");
+  string newdate = (fmt % (tm.tm_year + 1900) % (tm.tm_mon + 1) % tm.tm_mday % 1).str();
+  uint32_t new_serial = atol(newdate.c_str());
+  if (new_serial <= sd.serial) {
+    new_serial = sd.serial + 1;
+  }
+  return new_serial;
+}
+
+bool increaseSOARecord(DNSResourceRecord& rr, const string& increaseKind, const string& editKind) {
+  if (increaseKind.empty())
+    return false;
+
+  SOAData sd;
+  fillSOAData(rr.content, sd);
+  sd.serial = calculateIncreaseSOA(sd, increaseKind, editKind);
+  rr.content = serializeSOAData(sd);
+  return true;
+}
index 7b35a91b6460bd0ac6cdeedd9e80f90c249c8f01..9fe2272bd4a76f697156ce98b3bd3d16a53009de 100644 (file)
@@ -626,8 +626,15 @@ static void apiServerZones(HttpRequest* req, HttpResponse* resp) {
       throw ApiException("Nameservers list must be given (but can be empty if NS records are supplied)");
 
     string soa_edit_api_kind;
-    if (document["soa_edit_api"].IsString())
+    if (document["soa_edit_api"].IsString()) {
       soa_edit_api_kind = document["soa_edit_api"].GetString();
+    }
+    else {
+      soa_edit_api_kind = "DEFAULT";
+    }
+    string soa_edit_kind;
+    if (document["soa_edit"].IsString())
+      soa_edit_kind = document["soa_edit"].GetString();
 
     // if records/comments are given, load and check them
     bool have_soa = false;
@@ -651,7 +658,7 @@ static void apiServerZones(HttpRequest* req, HttpResponse* resp) {
 
       if (rr.qtype.getCode() == QType::SOA && pdns_iequals(rr.qname, zonename)) {
         have_soa = true;
-        editSOARecord(rr, soa_edit_api_kind);
+        increaseSOARecord(rr, soa_edit_api_kind, soa_edit_kind);
       }
     }
 
@@ -680,7 +687,7 @@ static void apiServerZones(HttpRequest* req, HttpResponse* resp) {
 
       rr.content = serializeSOAData(sd);
       rr.qtype = "SOA";
-      editSOARecord(rr, soa_edit_api_kind);
+      increaseSOARecord(rr, soa_edit_api_kind, soa_edit_kind);
       new_records.push_back(rr);
     }
 
@@ -948,7 +955,9 @@ static void patchZone(HttpRequest* req, HttpResponse* resp) {
 
   try {
     string soa_edit_api_kind;
+    string soa_edit_kind;
     di.backend->getDomainMetadataOne(zonename, "SOA-EDIT-API", soa_edit_api_kind);
+    di.backend->getDomainMetadataOne(zonename, "SOA-EDIT", soa_edit_kind);
     bool soa_edit_done = false;
 
     for(SizeType rrsetIdx = 0; rrsetIdx < rrsets.Size(); ++rrsetIdx) {
@@ -982,7 +991,7 @@ static void patchZone(HttpRequest* req, HttpResponse* resp) {
             throw ApiException("Record "+rr.qname+"/"+rr.qtype.getName()+" "+rr.content+": Record wrongly bundled with RRset " + qname + "/" + qtype.getName());
 
           if (rr.qtype.getCode() == QType::SOA && pdns_iequals(rr.qname, zonename)) {
-            soa_edit_done = editSOARecord(rr, soa_edit_api_kind);
+            soa_edit_done = increaseSOARecord(rr, soa_edit_api_kind, soa_edit_kind);
           }
         }
 
@@ -1025,7 +1034,7 @@ static void patchZone(HttpRequest* req, HttpResponse* resp) {
       rr.domain_id = di.id;
       rr.auth = 1;
       rr.ttl = sd.ttl;
-      editSOARecord(rr, soa_edit_api_kind);
+      increaseSOARecord(rr, soa_edit_api_kind, soa_edit_kind);
 
       if (!di.backend->replaceRRSet(di.id, rr.qname, rr.qtype, vector<DNSResourceRecord>(1, rr))) {
         throw ApiException("Hosting backend does not support editing records.");