]> git.ipfire.org Git - thirdparty/pdns.git/blobdiff - pdns/ws-auth.cc
Merge pull request #8681 from rgacogne/auth-stats-rings-size
[thirdparty/pdns.git] / pdns / ws-auth.cc
index b860221163aac7ef3cb6ca837f622761d82a5562..e68a3b3a9e19cedb07d281cadcd9c5d5f842c7e2 100644 (file)
@@ -778,10 +778,10 @@ static void updateDomainSettingsFromDocument(UeberBackend& B, const DomainInfo&
 
   if (!document["master_tsig_key_ids"].is_null()) {
     vector<string> metadata;
-    DNSName keyAlgo;
-    string keyContent;
     for(auto value : document["master_tsig_key_ids"].array_items()) {
       auto keyname(apiZoneIdToName(value.string_value()));
+      DNSName keyAlgo;
+      string keyContent;
       B.getTSIGKey(keyname, &keyAlgo, &keyContent);
       if (keyAlgo.empty() || keyContent.empty()) {
         throw ApiException("A TSIG key with the name '"+keyname.toLogString()+"' does not exist");
@@ -794,10 +794,10 @@ static void updateDomainSettingsFromDocument(UeberBackend& B, const DomainInfo&
   }
   if (!document["slave_tsig_key_ids"].is_null()) {
     vector<string> metadata;
-    DNSName keyAlgo;
-    string keyContent;
     for(auto value : document["slave_tsig_key_ids"].array_items()) {
       auto keyname(apiZoneIdToName(value.string_value()));
+      DNSName keyAlgo;
+      string keyContent;
       B.getTSIGKey(keyname, &keyAlgo, &keyContent);
       if (keyAlgo.empty() || keyContent.empty()) {
         throw ApiException("A TSIG key with the name '"+keyname.toLogString()+"' does not exist");
@@ -1535,8 +1535,8 @@ static void apiServerZones(HttpRequest* req, HttpResponse* resp) {
       throw ApiException("You cannot give rrsets AND zone data as text");
 
     auto nameservers = document["nameservers"];
-    if (!nameservers.is_array() && zonekind != DomainInfo::Slave)
-      throw ApiException("Nameservers list must be given (but can be empty if NS records are supplied)");
+    if (!nameservers.is_null() && !nameservers.is_array() && zonekind != DomainInfo::Slave)
+      throw ApiException("Nameservers is not a list");
 
     string soa_edit_api_kind;
     if (document["soa_edit_api"].is_string()) {
@@ -1747,8 +1747,7 @@ static void apiServerZoneDetail(HttpRequest* req, HttpResponse* resp) {
       throw ApiException("Deleting domain '"+zonename.toString()+"' failed: backend delete failed/unsupported");
 
     // clear caches
-    DNSSECKeeper dk(&B);
-    dk.clearCaches(zonename);
+    DNSSECKeeper::clearCaches(zonename);
     purgeAuthCaches(zonename.toString() + "$");
 
     // empty body on success
@@ -1938,6 +1937,8 @@ static void storeChangedPTRs(UeberBackend& B, vector<DNSResourceRecord>& new_ptr
 }
 
 static void patchZone(UeberBackend& B, HttpRequest* req, HttpResponse* resp) {
+  bool zone_disabled;
+  SOAData sd;
   DomainInfo di;
   DNSName zonename = apiZoneIdToName(req->parameters["id"]);
   if (!B.getDomainInfo(zonename, di)) {
@@ -2038,6 +2039,11 @@ static void patchZone(UeberBackend& B, HttpRequest* req, HttpResponse* resp) {
             if (qtype.getCode() != rr.qtype.getCode()
               && (exclusiveEntryTypes.count(qtype.getCode()) != 0
                 || exclusiveEntryTypes.count(rr.qtype.getCode()) != 0)) {
+
+              // leave database handle in a consistent state
+              while (di.backend->get(rr))
+                ;
+
               throw ApiException("RRset "+qname.toString()+" IN "+qtype.getName()+": Conflicts with pre-existing RRset");
             }
           }
@@ -2062,12 +2068,10 @@ static void patchZone(UeberBackend& B, HttpRequest* req, HttpResponse* resp) {
         throw ApiException("Changetype not understood");
     }
 
-    // edit SOA (if needed)
-    if (!soa_edit_api_kind.empty() && !soa_edit_done) {
-      SOAData sd;
-      if (!B.getSOAUncached(zonename, sd))
-        throw ApiException("No SOA found for domain '"+zonename.toString()+"'");
+    zone_disabled = (!B.getSOAUncached(zonename, sd));
 
+    // edit SOA (if needed)
+    if (!zone_disabled && !soa_edit_api_kind.empty() && !soa_edit_done) {
       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))) {
@@ -2086,19 +2090,25 @@ static void patchZone(UeberBackend& B, HttpRequest* req, HttpResponse* resp) {
     throw;
   }
 
+  // Rectify
   DNSSECKeeper dk(&B);
-  string api_rectify;
-  di.backend->getDomainMetadataOne(zonename, "API-RECTIFY", api_rectify);
-  if (dk.isSecuredZone(zonename) && !dk.isPresigned(zonename) && api_rectify == "1") {
-    string error_msg = "";
-    string info;
-    if (!dk.rectifyZone(zonename, error_msg, info, false))
-      throw ApiException("Failed to rectify '" + zonename.toString() + "' " + error_msg);
+  if (!zone_disabled && !dk.isPresigned(zonename)) {
+    string api_rectify;
+    if (!di.backend->getDomainMetadataOne(zonename, "API-RECTIFY", api_rectify) && ::arg().mustDo("default-api-rectify")) {
+      api_rectify = "1";
+    }
+    if (api_rectify == "1") {
+      string info;
+      string error_msg;
+      if (!dk.rectifyZone(zonename, error_msg, info, false)) {
+        throw ApiException("Failed to rectify '" + zonename.toString() + "' " + error_msg);
+      }
+    }
   }
 
   di.backend->commitTransaction();
 
-  purgeAuthCachesExact(zonename);
+  purgeAuthCaches(zonename.toString() + "$");
 
   // now the PTRs
   storeChangedPTRs(B, new_ptrs);