]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
Auth: Add the pdnsutil backend-lookup command
authorFred Morcos <fred.morcos@open-xchange.com>
Thu, 18 Jul 2024 12:13:50 +0000 (14:13 +0200)
committerFred Morcos <fred.morcos@open-xchange.com>
Thu, 18 Jul 2024 12:21:52 +0000 (14:21 +0200)
This can be used to lookup records from a backend using some filtering like type and
client subnet.

pdns/pdnsutil.cc

index aa890d9dc2b8b41713762726747b716b2d92b30c..7c9018fb05f5595f84b5afdb410a6796086c3ea6 100644 (file)
@@ -1,3 +1,5 @@
+#include "dnsname.hh"
+#include "dnsparser.hh"
 #include "dnsrecords.hh"
 #include <boost/smart_ptr/make_shared_array.hpp>
 #ifdef HAVE_CONFIG_H
@@ -2566,6 +2568,8 @@ try
     cout << "]" << endl;
     cout << "                                   Add a ZSK or KSK to zone and specify algo&bits" << endl;
     cout << "backend-cmd BACKEND CMD [CMD..]    Perform one or more backend commands" << endl;
+    cout << "backend-lookup BACKEND NAME TYPE CLIENT-IP" << endl;
+    cout << "                                   Perform a backend lookup of NAME, TYPE and CLIENT-IP" << endl;
     cout << "b2b-migrate OLD NEW                Move all data from one backend to another" << endl;
     cout << "bench-db [filename]                Bench database backend with queries, one zone per line" << endl;
     cout << "check-zone ZONE                    Check a zone for correctness" << endl;
@@ -4225,6 +4229,49 @@ try
 
     return 0;
   }
+  else if (cmds.at(0) == "backend-lookup") {
+    if (cmds.size() < 5) {
+      cerr << "Usage: backend-lookup BACKEND NAME TYPE CLIENT-IP-SUBNET" << endl;
+      return 1;
+    }
+
+    std::unique_ptr<DNSBackend> matchingBackend{nullptr};
+
+    for (auto& backend : BackendMakers().all()) {
+      if (backend->getPrefix() == cmds.at(1)) {
+        matchingBackend = std::move(backend);
+      }
+    }
+
+    if (matchingBackend == nullptr) {
+      cerr << "Unknown backend '" << cmds.at(1) << "'" << endl;
+      return 1;
+    }
+
+    QType type;
+    type = cmds.at(3);
+
+    DNSName name{cmds.at(2)};
+
+    DNSPacket queryPacket(true);
+    Netmask clientNetmask(cmds.at(4));
+    queryPacket.setRealRemote(clientNetmask);
+
+    matchingBackend->lookup(type, name, -1, &queryPacket);
+
+    bool found = false;
+    DNSZoneRecord resultZoneRecord;
+    while (matchingBackend->get(resultZoneRecord)) {
+      cout << resultZoneRecord.dr.d_name.toString() << "\t" << resultZoneRecord.dr.getContent()->getZoneRepresentation() << "\t" << std::to_string(resultZoneRecord.dr.d_ttl) << "\t" << QClass(resultZoneRecord.dr.d_class).toString() << "\t" << DNSRecordContent::NumberToType(resultZoneRecord.dr.d_type, resultZoneRecord.dr.d_class) << "\t" << endl;
+      found = true;
+    }
+    if (!found) {
+      cerr << "Backend found 0 zone record results" << endl;
+      return 1;
+    }
+
+    return 0;
+  }
   else {
     cerr << "Unknown command '" << cmds.at(0) << "'" << endl;
     return 1;