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: dnsdist-1.3.1~118^2~1 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=a843c67ec71513f4ac67e94740a1c31b708959e7;p=pdns auth-api: increase serial after dnssec related updates --- diff --git a/pdns/ws-auth.cc b/pdns/ws-auth.cc index 0afd0c4f9..4ec9e3bf1 100644 --- a/pdns/ws-auth.cc +++ b/pdns/ws-auth.cc @@ -552,7 +552,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()) { @@ -660,13 +660,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); + } } } @@ -1343,7 +1371,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(); @@ -1379,7 +1407,7 @@ static void apiServerZoneDetail(HttpRequest* req, HttpResponse* resp) { if(req->method == "PUT" && !::arg().mustDo("api-readonly")) { // update domain settings - 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 29f164596..250d8bafe 100644 --- a/regression-tests.api/test_Zones.py +++ b/regression-tests.api/test_Zones.py @@ -485,6 +485,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"))