]> granicus.if.org Git - pdns/commitdiff
auth-api: increase serial after dnssec related updates
authorKees Monshouwer <mind04@monshouwer.org>
Thu, 3 May 2018 22:56:51 +0000 (00:56 +0200)
committermind04 <mind04@monshouwer.org>
Fri, 4 May 2018 21:17:17 +0000 (23:17 +0200)
pdns/ws-auth.cc
regression-tests.api/test_Zones.py

index 70f4ce779da0a78f4bed30bc53f07a44294cbf16..5482b9c0e69c1dd4f9d7d5d3a59aae534c830f06 100644 (file)
@@ -547,7 +547,7 @@ static void throwUnableToSecure(const DNSName& zonename) {
       + "capable backends are loaded, or because the backends have DNSSEC disabled. Check your configuration.");
 }
 
-static void updateDomainSettingsFromDocument(UeberBackend& B, const DomainInfo& di, const DNSName& zonename, const Json document) {
+static void updateDomainSettingsFromDocument(UeberBackend& B, const DomainInfo& di, const DNSName& zonename, const Json document, HttpResponse* resp) {
   string zonemaster;
   bool shouldRectify = false;
   for(auto value : document["masters"].array_items()) {
@@ -655,13 +655,41 @@ static void updateDomainSettingsFromDocument(UeberBackend& B, const DomainInfo&
     }
   }
 
-  string api_rectify;
-  di.backend->getDomainMetadataOne(zonename, "API-RECTIFY", api_rectify);
-  if (shouldRectify && dk.isSecuredZone(zonename) && !dk.isPresigned(zonename) && api_rectify == "1") {
-    string info;
-    string error_msg = "";
-    if (!dk.rectifyZone(zonename, error_msg, info, true))
-      throw ApiException("Failed to rectify '" + zonename.toString() + "' " + error_msg);
+  if (shouldRectify && !dk.isPresigned(zonename)) {
+    // Rectify
+    string api_rectify;
+    di.backend->getDomainMetadataOne(zonename, "API-RECTIFY", api_rectify);
+    if (api_rectify == "1") {
+      string info;
+      string error_msg;
+      if (!dk.rectifyZone(zonename, error_msg, info, true)) {
+        throw ApiException("Failed to rectify '" + zonename.toString() + "' " + error_msg);
+      }
+    }
+
+    // Increase serial
+    string soa_edit_api_kind;
+    di.backend->getDomainMetadataOne(zonename, "SOA-EDIT-API", soa_edit_api_kind);
+    if (!soa_edit_api_kind.empty()) {
+      SOAData sd;
+      if (!B.getSOAUncached(zonename, sd, true))
+        return;
+
+      string soa_edit_kind;
+      di.backend->getDomainMetadataOne(zonename, "SOA-EDIT", soa_edit_kind);
+
+      DNSResourceRecord rr;
+      if (makeIncreasedSOARecord(sd, soa_edit_api_kind, soa_edit_kind, rr)) {
+        if (!di.backend->replaceRRSet(di.id, rr.qname, rr.qtype, vector<DNSResourceRecord>(1, rr))) {
+          throw ApiException("Hosting backend does not support editing records.");
+        }
+      }
+
+      // return old and new serials in headers
+      resp->headers["X-PDNS-Old-Serial"] = std::to_string(sd.serial);
+      fillSOAData(rr.content, sd);
+      resp->headers["X-PDNS-New-Serial"] = std::to_string(sd.serial);
+    }
   }
 }
 
@@ -1339,7 +1367,7 @@ static void apiServerZones(HttpRequest* req, HttpResponse* resp) {
       di.backend->feedComment(c);
     }
 
-    updateDomainSettingsFromDocument(B, di, zonename, document);
+    updateDomainSettingsFromDocument(B, di, zonename, document, resp);
 
     di.backend->commitTransaction();
 
@@ -1373,7 +1401,7 @@ static void apiServerZoneDetail(HttpRequest* req, HttpResponse* resp) {
     if(!B.getDomainInfo(zonename, di))
       throw ApiException("Could not find domain '"+zonename.toString()+"'");
 
-    updateDomainSettingsFromDocument(B, di, zonename, req->json());
+    updateDomainSettingsFromDocument(B, di, zonename, req->json(), resp);
 
     resp->body = "";
     resp->status = 204; // No Content, but indicate success
index 02896cd0c852afc6936a2277a826027005ec76ef..6d4c7f845be531777d5592122bd53fa1140e1bd5 100644 (file)
@@ -440,6 +440,37 @@ class AuthZones(ApiTestCase, AuthZonesHelperMixin):
         self.assertEquals(data['kind'], 'NSEC3NARROW')
         self.assertEquals(data['metadata'][0], '1')
 
+    def test_create_zone_dnssec_serial(self):
+        """
+        Create a zone set/unset "dnssec" and see if the serial was increased
+        after every step
+        """
+        name = unique_zone_name()
+        name, payload, data = self.create_zone()
+
+        soa_serial = get_first_rec(data, name, 'SOA')['content'].split(' ')[2]
+        self.assertEquals(soa_serial[-2:], '01')
+
+        self.session.put(self.url("/api/v1/servers/localhost/zones/" + name),
+                         data=json.dumps({'dnssec': True}))
+        r = self.session.get(self.url("/api/v1/servers/localhost/zones/" + name))
+
+        data = r.json()
+        soa_serial = get_first_rec(data, name, 'SOA')['content'].split(' ')[2]
+
+        self.assertEquals(r.status_code, 200)
+        self.assertEquals(soa_serial[-2:], '02')
+
+        self.session.put(self.url("/api/v1/servers/localhost/zones/" + name),
+                         data=json.dumps({'dnssec': False}))
+        r = self.session.get(self.url("/api/v1/servers/localhost/zones/" + name))
+
+        data = r.json()
+        soa_serial = get_first_rec(data, name, 'SOA')['content'].split(' ')[2]
+
+        self.assertEquals(r.status_code, 200)
+        self.assertEquals(soa_serial[-2:], '03')
+
     def test_zone_absolute_url(self):
         name, payload, data = self.create_zone()
         r = self.session.get(self.url("/api/v1/servers/localhost/zones"))