]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
Check backend capabilities before attempting some operations.
authorMiod Vallat <miod.vallat@powerdns.com>
Mon, 31 Mar 2025 14:23:32 +0000 (16:23 +0200)
committerMiod Vallat <miod.vallat@powerdns.com>
Mon, 7 Apr 2025 10:03:33 +0000 (12:03 +0200)
This allows us to give better error messages to the users.

Fixes: #15006
pdns/pdnsutil.cc

index 4bbb0f9b3d76b708048098b678ee93afe1a0d6bc..fb7c1c4bcfa49f190236c919a9c33b10f3ba8a61 100644 (file)
@@ -304,6 +304,11 @@ static int checkZone(DNSSECKeeper &dk, UeberBackend &B, const DNSName& zone, con
     }
   }
 
+  if (suppliedrecords == nullptr && (di.backend->getCapabilities() & DNSBackend::CAP_LIST) == 0) {
+    cout << "Backend for zone '" << zone << "' does not support listing its contents." << endl;
+    return 1;
+  }
+
   SOAData sd;
   try {
     if (!B.getSOAUncached(zone, sd)) {
@@ -1133,6 +1138,11 @@ static int listZone(const DNSName &zone) {
     cerr << "Zone '" << zone << "' not found!" << endl;
     return EXIT_FAILURE;
   }
+  if ((di.backend->getCapabilities() & DNSBackend::CAP_LIST) == 0) {
+    cerr << "Backend for zone '" << zone << "' does not support listing its contents," << endl;
+    return EXIT_FAILURE;
+  }
+
   di.backend->list(zone, di.id);
   DNSResourceRecord rr;
   cout<<"$ORIGIN ."<<endl;
@@ -1239,6 +1249,10 @@ static int editZone(const DNSName &zone, const PDNSColors& col) {
     cerr << "Zone '" << zone << "' not found!" << endl;
     return EXIT_FAILURE;
   }
+  if ((di.backend->getCapabilities() & DNSBackend::CAP_LIST) == 0) {
+    cerr << "Backend for zone '" << zone << "' does not support listing its contents," << endl;
+    return EXIT_FAILURE;
+  }
 
   if (isatty(STDIN_FILENO) == 0) {
     cerr << "edit-zone requires a terminal" << endl;
@@ -4299,6 +4313,10 @@ static int B2BMigrate(vector<string>& cmds, const std::string_view synopsis)
     return 1;
   }
 
+  if ((src->getCapabilities() & DNSBackend::CAP_LIST) == 0) {
+    cerr << "Source backend does not support listing zone contents." << endl;
+    return 1;
+  }
   cout<<"Moving zone(s) from "<<src->getPrefix()<<" to "<<tgt->getPrefix()<<endl;
 
   vector<DomainInfo> domains;
@@ -4347,12 +4365,15 @@ static int B2BMigrate(vector<string>& cmds, const std::string_view synopsis)
     // move comments
     nc=0;
     if (src->listComments(di.id)) {
+      if ((tgt->getCapabilities() & DNSBackend::CAP_COMMENTS) == 0) {
+        throw PDNSException("Target backend does not support comments - remove them first");
+      }
       Comment c; // NOLINT(readability-identifier-length)
       while(src->getComment(c)) {
         // NOLINTNEXTLINE(bugprone-narrowing-conversions,cppcoreguidelines-narrowing-conversions)
         c.domain_id = di_new.id;
         if (!tgt->feedComment(c)) {
-          throw PDNSException("Target backend does not support comments - remove them first");
+          throw PDNSException("Failed to feed zone comments");
         }
         nc++;
       }
@@ -4420,6 +4441,11 @@ static int backendCmd(vector<string>& cmds, const std::string_view synopsis)
     return 1;
   }
 
+  if ((matchingBackend->getCapabilities() & DNSBackend::CAP_DIRECT) == 0) {
+    cerr << "Backend '" << cmds.at(1) << "' does not support direct commands" << endl;
+    return 1;
+  }
+
   for (auto i = next(begin(cmds), 2); i != end(cmds); ++i) {
     cerr << "== " << *i << endl;
     cout << matchingBackend->directBackendCmd(*i);