From: Kees Monshouwer Date: Thu, 3 May 2018 22:56:51 +0000 (+0200) Subject: auth-api: increase serial after dnssec related updates X-Git-Tag: auth-4.1.2~1^2~2 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=c23555ddc593c3dea458c0d4e21a0ac7f453133c;p=pdns auth-api: increase serial after dnssec related updates --- diff --git a/pdns/ws-auth.cc b/pdns/ws-auth.cc index 70f4ce779..5482b9c0e 100644 --- a/pdns/ws-auth.cc +++ b/pdns/ws-auth.cc @@ -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(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 diff --git a/regression-tests.api/test_Zones.py b/regression-tests.api/test_Zones.py index 02896cd0c..6d4c7f845 100644 --- a/regression-tests.api/test_Zones.py +++ b/regression-tests.api/test_Zones.py @@ -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"))