]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
Introduce ZoneName::toStringFull to emit variant names... 15512/head
authorPeter van Dijk <peter.van.dijk@powerdns.com>
Fri, 23 May 2025 14:50:05 +0000 (16:50 +0200)
committerMiod Vallat <miod.vallat@powerdns.com>
Mon, 26 May 2025 11:49:13 +0000 (13:49 +0200)
...and use it for error report in ws-auth.

the size of this commit shows that perhaps we should have
ZoneName::toString() emit the variant. This commit will not
be folded into a previous one, so that it is easy to revert
and rework later.

pdns/dnsname.cc
pdns/dnsname.hh
pdns/ws-auth.cc

index c63931d34a2edc64643b664e867ed781e8121d6b..13c5cdb19e0b3826f2928f0bd2c72849cbb8e510 100644 (file)
@@ -828,6 +828,22 @@ std::string ZoneName::toLogString() const
   return ret;
 }
 
+std::string ZoneName::toStringFull(const std::string& separator, const bool trailing) const
+{
+  std::string ret = d_name.toString(separator, trailing);
+  if (!d_variant.empty()) {
+    if (!trailing) {
+      ret.push_back('.');
+    }
+    // toString of root emits "" if no trailing, "." if trailing
+    if (d_name.isRoot()) {
+      ret.push_back('.');
+    }
+    ret += d_variant;
+  }
+  return ret;
+}
+
 size_t ZoneName::hash(size_t init) const
 {
   if (!d_variant.empty()) {
index c30c35e1718b44409a9ddefc43210ea47ffd21ee..630e9be4d8511e791baf685bbe186d597586e30d 100644 (file)
@@ -361,12 +361,13 @@ public:
   bool operator==(const ZoneName& rhs) const { return d_name == rhs.d_name && d_variant == rhs.d_variant; }
   bool operator!=(const ZoneName& rhs) const { return !operator==(rhs); }
 
-  // IMPORTANT! None of the "toString" routines will output the variant, but toLogString().
+  // IMPORTANT! None of the "toString" routines will output the variant, but toLogString() and toStringFull().
   std::string toString(const std::string& separator=".", const bool trailing=true) const { return d_name.toString(separator, trailing); }
   void toString(std::string& output, const std::string& separator=".", const bool trailing=true) const { d_name.toString(output, separator, trailing); }
   std::string toLogString() const;
   std::string toStringNoDot() const { return d_name.toStringNoDot(); }
   std::string toStringRootDot() const { return d_name.toStringRootDot(); }
+  std::string toStringFull(const std::string& separator=".", const bool trailing=true) const;
 
   bool chopOff() { return d_name.chopOff(); }
   ZoneName makeLowerCase() const
index 8fb21c33c104785e6be9521124951bc464764af8..56b12f7dba22c95e68c444b43a00c5ab3621371e 100644 (file)
@@ -672,7 +672,7 @@ static void checkDefaultDNSSECAlgos()
 
 static void throwUnableToSecure(const ZoneName& zonename)
 {
-  throw ApiException("No backend was able to secure '" + zonename.toString() + "', most likely because no DNSSEC"
+  throw ApiException("No backend was able to secure '" + zonename.toStringFull() + "', most likely because no DNSSEC"
                      + "capable backends are loaded, or because the backends have DNSSEC disabled. Check your configuration.");
 }
 
@@ -857,11 +857,11 @@ static void updateDomainSettingsFromDocument(UeberBackend& backend, DomainInfo&
         string info;
         string error;
         if (!dnssecKeeper.unSecureZone(zonename, error)) {
-          throw ApiException("Error while un-securing zone '" + zonename.toString() + "': " + error);
+          throw ApiException("Error while un-securing zone '" + zonename.toStringFull() + "': " + error);
         }
         isDNSSECZone = dnssecKeeper.isSecuredZone(zonename, false);
         if (isDNSSECZone) {
-          throw ApiException("Unable to un-secure zone '" + zonename.toString() + "'");
+          throw ApiException("Unable to un-secure zone '" + zonename.toStringFull() + "'");
         }
         shouldRectify = true;
         updateNsec3Param = true;
@@ -872,13 +872,13 @@ static void updateDomainSettingsFromDocument(UeberBackend& backend, DomainInfo&
   if (nsec3paramInJSON || updateNsec3Param) {
     shouldRectify = true;
     if (!isDNSSECZone && !nsec3paramDocVal.empty()) {
-      throw ApiException("NSEC3PARAM value provided for zone '" + zonename.toString() + "', but zone is not DNSSEC secured.");
+      throw ApiException("NSEC3PARAM value provided for zone '" + zonename.toStringFull() + "', but zone is not DNSSEC secured.");
     }
 
     if (nsec3paramDocVal.empty()) {
       // Switch to NSEC
       if (!dnssecKeeper.unsetNSEC3PARAM(zonename)) {
-        throw ApiException("Unable to remove NSEC3PARAMs from zone '" + zonename.toString());
+        throw ApiException("Unable to remove NSEC3PARAMs from zone '" + zonename.toStringFull());
       }
     }
     else {
@@ -886,10 +886,10 @@ static void updateDomainSettingsFromDocument(UeberBackend& backend, DomainInfo&
       NSEC3PARAMRecordContent ns3pr(nsec3paramDocVal);
       string error_msg;
       if (!dnssecKeeper.checkNSEC3PARAM(ns3pr, error_msg)) {
-        throw ApiException("NSEC3PARAMs provided for zone '" + zonename.toString() + "' are invalid. " + error_msg);
+        throw ApiException("NSEC3PARAMs provided for zone '" + zonename.toStringFull() + "' are invalid. " + error_msg);
       }
       if (!dnssecKeeper.setNSEC3PARAM(zonename, ns3pr, boolFromJson(document, "nsec3narrow", false))) {
-        throw ApiException("NSEC3PARAMs provided for zone '" + zonename.toString() + "' passed our basic sanity checks, but cannot be used with the current backend.");
+        throw ApiException("NSEC3PARAMs provided for zone '" + zonename.toStringFull() + "' passed our basic sanity checks, but cannot be used with the current backend.");
       }
     }
   }
@@ -901,7 +901,7 @@ static void updateDomainSettingsFromDocument(UeberBackend& backend, DomainInfo&
       string error_msg;
       if (!dnssecKeeper.rectifyZone(zonename, error_msg, info, false) && !domainInfo.isSecondaryType()) {
         // for Secondary zones, it is possible that rectifying was not needed (example: empty zone).
-        throw ApiException("Failed to rectify '" + zonename.toString() + "' " + error_msg);
+        throw ApiException("Failed to rectify '" + zonename.toStringFull() + "' " + error_msg);
       }
     }
 
@@ -930,14 +930,14 @@ static void updateDomainSettingsFromDocument(UeberBackend& backend, DomainInfo&
     vector<string> metadata;
     extractJsonTSIGKeyIds(backend, document["master_tsig_key_ids"], metadata);
     if (!domainInfo.backend->setDomainMetadata(zonename, "TSIG-ALLOW-AXFR", metadata)) {
-      throw HttpInternalServerErrorException("Unable to set new TSIG primary keys for zone '" + zonename.toLogString() + "'");
+      throw HttpInternalServerErrorException("Unable to set new TSIG primary keys for zone '" + zonename.toStringFull() + "'");
     }
   }
   if (!document["slave_tsig_key_ids"].is_null()) {
     vector<string> metadata;
     extractJsonTSIGKeyIds(backend, document["slave_tsig_key_ids"], metadata);
     if (!domainInfo.backend->setDomainMetadata(zonename, "AXFR-MASTER-TSIG", metadata)) {
-      throw HttpInternalServerErrorException("Unable to set new TSIG secondary keys for zone '" + zonename.toLogString() + "'");
+      throw HttpInternalServerErrorException("Unable to set new TSIG secondary keys for zone '" + zonename.toStringFull() + "'");
     }
   }
 }
@@ -1069,7 +1069,7 @@ static void apiZoneMetadataPOST(HttpRequest* req, HttpResponse* resp)
   vector<string> vecMetadata;
 
   if (!zoneData.backend.getDomainMetadata(zoneData.zoneName, kind, vecMetadata)) {
-    throw ApiException("Could not retrieve metadata entries for domain '" + zoneData.zoneName.toString() + "'");
+    throw ApiException("Could not retrieve metadata entries for domain '" + zoneData.zoneName.toStringFull() + "'");
   }
 
   const auto& metadata = document["metadata"];
@@ -1090,7 +1090,7 @@ static void apiZoneMetadataPOST(HttpRequest* req, HttpResponse* resp)
   }
 
   if (!zoneData.backend.setDomainMetadata(zoneData.zoneName, kind, vecMetadata)) {
-    throw ApiException("Could not update metadata entries for domain '" + zoneData.zoneName.toString() + "'");
+    throw ApiException("Could not update metadata entries for domain '" + zoneData.zoneName.toStringFull() + "'");
   }
 
   DNSSECKeeper::clearMetaCache(zoneData.zoneName);
@@ -1162,7 +1162,7 @@ static void apiZoneMetadataKindPUT(HttpRequest* req, HttpResponse* resp)
   }
 
   if (!zoneData.backend.setDomainMetadata(zoneData.zoneName, kind, vecMetadata)) {
-    throw ApiException("Could not update metadata entries for domain '" + zoneData.zoneName.toString() + "'");
+    throw ApiException("Could not update metadata entries for domain '" + zoneData.zoneName.toStringFull() + "'");
   }
 
   DNSSECKeeper::clearMetaCache(zoneData.zoneName);
@@ -1186,7 +1186,7 @@ static void apiZoneMetadataKindDELETE(HttpRequest* req, HttpResponse* resp)
 
   vector<string> metadata; // an empty vector will do it
   if (!zoneData.backend.setDomainMetadata(zoneData.zoneName, kind, metadata)) {
-    throw ApiException("Could not delete metadata for domain '" + zoneData.zoneName.toString() + "' (" + kind + ")");
+    throw ApiException("Could not delete metadata for domain '" + zoneData.zoneName.toStringFull() + "' (" + kind + ")");
   }
 
   DNSSECKeeper::clearMetaCache(zoneData.zoneName);
@@ -1512,26 +1512,26 @@ static void apiZoneCryptokeysPUT(HttpRequest* req, HttpResponse* resp)
   bool published = boolFromJson(document, "published", true);
   if (active) {
     if (!zoneData.dnssecKeeper.activateKey(zoneData.zoneName, inquireKeyId)) {
-      resp->setErrorResult("Could not activate Key: " + req->parameters["key_id"] + " in Zone: " + zoneData.zoneName.toString(), 422);
+      resp->setErrorResult("Could not activate Key: " + req->parameters["key_id"] + " in Zone: " + zoneData.zoneName.toStringFull(), 422);
       return;
     }
   }
   else {
     if (!zoneData.dnssecKeeper.deactivateKey(zoneData.zoneName, inquireKeyId)) {
-      resp->setErrorResult("Could not deactivate Key: " + req->parameters["key_id"] + " in Zone: " + zoneData.zoneName.toString(), 422);
+      resp->setErrorResult("Could not deactivate Key: " + req->parameters["key_id"] + " in Zone: " + zoneData.zoneName.toStringFull(), 422);
       return;
     }
   }
 
   if (published) {
     if (!zoneData.dnssecKeeper.publishKey(zoneData.zoneName, inquireKeyId)) {
-      resp->setErrorResult("Could not publish Key: " + req->parameters["key_id"] + " in Zone: " + zoneData.zoneName.toString(), 422);
+      resp->setErrorResult("Could not publish Key: " + req->parameters["key_id"] + " in Zone: " + zoneData.zoneName.toStringFull(), 422);
       return;
     }
   }
   else {
     if (!zoneData.dnssecKeeper.unpublishKey(zoneData.zoneName, inquireKeyId)) {
-      resp->setErrorResult("Could not unpublish Key: " + req->parameters["key_id"] + " in Zone: " + zoneData.zoneName.toString(), 422);
+      resp->setErrorResult("Could not unpublish Key: " + req->parameters["key_id"] + " in Zone: " + zoneData.zoneName.toStringFull(), 422);
       return;
     }
   }
@@ -1984,18 +1984,18 @@ static void apiServerZonesPOST(HttpRequest* req, HttpResponse* resp)
       NSEC3PARAMRecordContent ns3pr(document["nsec3param"].string_value());
       string error_msg;
       if (!dnssecKeeper.checkNSEC3PARAM(ns3pr, error_msg)) {
-        throw ApiException("NSEC3PARAMs provided for zone '" + zonename.toString() + "' are invalid. " + error_msg);
+        throw ApiException("NSEC3PARAMs provided for zone '" + zonename.toStringFull() + "' are invalid. " + error_msg);
       }
     }
   }
 
   // no going back after this
   if (!backend.createDomain(zonename, kind.value_or(DomainInfo::Native), primaries.value_or(vector<ComboAddress>()), account.value_or(""))) {
-    throw ApiException("Creating domain '" + zonename.toString() + "' failed: backend refused");
+    throw ApiException("Creating domain '" + zonename.toStringFull() + "' failed: backend refused");
   }
 
   if (!backend.getDomainInfo(zonename, domainInfo)) {
-    throw ApiException("Creating domain '" + zonename.toString() + "' failed: lookup of domain ID failed");
+    throw ApiException("Creating domain '" + zonename.toStringFull() + "' failed: lookup of domain ID failed");
   }
 
   domainInfo.backend->startTransaction(zonename, domainInfo.id);
@@ -2183,7 +2183,7 @@ static void apiServerZoneDetailDELETE(HttpRequest* req, HttpResponse* resp)
   zoneData.domainInfo.backend->startTransaction(zoneData.zoneName, UnknownDomainID);
   try {
     if (!zoneData.domainInfo.backend->deleteDomain(zoneData.zoneName)) {
-      throw ApiException("Deleting domain '" + zoneData.zoneName.toString() + "' failed: backend delete failed/unsupported");
+      throw ApiException("Deleting domain '" + zoneData.zoneName.toStringFull() + "' failed: backend delete failed/unsupported");
     }
 
     zoneData.domainInfo.backend->commitTransaction();
@@ -2249,12 +2249,12 @@ static void apiServerZoneAxfrRetrieve(HttpRequest* req, HttpResponse* resp)
   ZoneData zoneData{req};
 
   if (zoneData.domainInfo.primaries.empty()) {
-    throw ApiException("Domain '" + zoneData.zoneName.toString() + "' is not a secondary domain (or has no primary defined)");
+    throw ApiException("Domain '" + zoneData.zoneName.toStringFull() + "' is not a secondary domain (or has no primary defined)");
   }
 
   shuffle(zoneData.domainInfo.primaries.begin(), zoneData.domainInfo.primaries.end(), pdns::dns_random_engine());
   Communicator.addSuckRequest(zoneData.zoneName, zoneData.domainInfo.primaries.front(), SuckRequest::Api);
-  resp->setSuccessResult("Added retrieval request for '" + zoneData.zoneName.toString() + "' from primary " + zoneData.domainInfo.primaries.front().toLogString());
+  resp->setSuccessResult("Added retrieval request for '" + zoneData.zoneName.toStringFull() + "' from primary " + zoneData.domainInfo.primaries.front().toLogString());
 }
 
 static void apiServerZoneNotify(HttpRequest* req, HttpResponse* resp)
@@ -2273,13 +2273,13 @@ static void apiServerZoneRectify(HttpRequest* req, HttpResponse* resp)
   ZoneData zoneData{req};
 
   if (zoneData.dnssecKeeper.isPresigned(zoneData.zoneName)) {
-    throw ApiException("Zone '" + zoneData.zoneName.toString() + "' is pre-signed, not rectifying.");
+    throw ApiException("Zone '" + zoneData.zoneName.toStringFull() + "' is pre-signed, not rectifying.");
   }
 
   string error_msg;
   string info;
   if (!zoneData.dnssecKeeper.rectifyZone(zoneData.zoneName, error_msg, info, true)) {
-    throw ApiException("Failed to rectify '" + zoneData.zoneName.toString() + "' " + error_msg);
+    throw ApiException("Failed to rectify '" + zoneData.zoneName.toStringFull() + "' " + error_msg);
   }
 
   resp->setSuccessResult("Rectified");
@@ -2465,7 +2465,7 @@ static void patchZone(UeberBackend& backend, const ZoneName& zonename, DomainInf
     string info;
     string error_msg;
     if (!dnssecKeeper.rectifyZone(zonename, error_msg, info, false)) {
-      throw ApiException("Failed to rectify '" + zonename.toString() + "' " + error_msg);
+      throw ApiException("Failed to rectify '" + zonename.toStringFull() + "' " + error_msg);
     }
   }
 
@@ -2708,12 +2708,12 @@ static void apiServerViewsPOST(HttpRequest* req, HttpResponse* resp)
   ZoneName zonename = apiNameToZoneName(stringFromJson(document, "name"));
 
   if (!backend.getDomainInfo(zonename, domainInfo)) {
-    throw ApiException("Zone " + zonename.toString() + "does not exist");
+    throw ApiException("Zone " + zonename.toStringFull() + "does not exist");
   }
   std::string view{req->parameters["view"]};
 
   if (!domainInfo.backend->viewAddZone(view, zonename)) {
-    throw ApiException("Failed to add " + zonename.toString() + " to view " + view);
+    throw ApiException("Failed to add " + zonename.toStringFull() + " to view " + view);
   }
   // Notify zone cache of the new association
   if (g_zoneCache.isEnabled()) {
@@ -2735,7 +2735,7 @@ static void apiServerViewsDELETE(HttpRequest* req, HttpResponse* resp)
   std::string view{req->parameters["view"]};
 
   if (!zoneData.domainInfo.backend->viewDelZone(view, zoneData.zoneName)) {
-    throw ApiException("Failed to remove " + zoneData.zoneName.toString() + " from view " + view);
+    throw ApiException("Failed to remove " + zoneData.zoneName.toStringFull() + " from view " + view);
   }
   // Notify zone cache of the removed association
   if (g_zoneCache.isEnabled()) {