]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
lua-base4: Add include path feature
authorAki Tuomi <cmouse@cmouse.fi>
Fri, 3 Jun 2022 09:53:13 +0000 (12:53 +0300)
committerAki Tuomi <cmouse@cmouse.fi>
Thu, 25 Jul 2024 04:43:40 +0000 (07:43 +0300)
Loads sorted list of files from given path mask.

pdns/lua-auth4.cc
pdns/lua-auth4.hh
pdns/lua-base4.cc
pdns/lua-base4.hh
pdns/recursordist/lua-recursor4.cc
pdns/recursordist/lua-recursor4.hh
pdns/recursordist/rec-lua-conf.cc

index 77f7caa9035e167ee32389af025cd075b4f2524c..ea8d380f0d99e9caaab5930c79a913c9d8dca26c 100644 (file)
@@ -13,8 +13,6 @@
 
 #include "ueberbackend.hh"
 
-AuthLua4::AuthLua4() { prepareContext(); }
-
 LuaContext* AuthLua4::getLua()
 {
   return d_lw.get();
@@ -84,6 +82,9 @@ void AuthLua4::postPrepareContext() {
   d_lw->registerFunction<DNSName(UpdatePolicyQuery::*)()>("getTsigName", [](UpdatePolicyQuery& upq) { return upq.tsigName; });
   d_lw->registerFunction<std::string(UpdatePolicyQuery::*)()>("getPeerPrincipal", [](UpdatePolicyQuery& upq) { return upq.peerPrincipal; });
 /* end of update policy */
+  if (!d_include_path.empty()) {
+    includePath(d_include_path);
+  }
 }
 
 void AuthLua4::postLoad() {
index fea41d640b99918dfe9d42a66c33b076ab284de7..d154df708849ecc2156c53454629a092c60338e8 100644 (file)
@@ -12,7 +12,9 @@
 class AuthLua4 : public BaseLua4
 {
 public:
-  AuthLua4();
+  AuthLua4(const std::string& includePath="") : BaseLua4(includePath) {
+    prepareContext();
+  };
   bool updatePolicy(const DNSName &qname, const QType& qtype, const DNSName &zonename, const DNSPacket& packet);
   bool axfrfilter(const ComboAddress&, const DNSName&, const DNSResourceRecord&, std::vector<DNSResourceRecord>&);
   LuaContext* getLua();
index 19e6aef3384277e840675838be3166b598125caf..b3d5d1b90f8ba0a75e0e702d4b35fad05dd6957d 100644 (file)
@@ -1,8 +1,10 @@
+#include "config.h"
 #include <cassert>
 #include <fstream>
 #include <unordered_set>
 #include <unordered_map>
 #include <typeinfo>
+#include <sys/stat.h>
 #include "logger.hh"
 #include "logging.hh"
 #include "iputils.hh"
 #include "ext/luawrapper/include/LuaContext.hpp"
 #include "dns_random.hh"
 
-BaseLua4::BaseLua4() = default;
-
-void BaseLua4::loadFile(const std::string& fname)
+void BaseLua4::loadFile(const std::string& fname, bool doPostLoad)
 {
   std::ifstream ifs(fname);
   if (!ifs) {
     auto ret = errno;
     auto msg = stringerror(ret);
-    SLOG(g_log << Logger::Error << "Unable to read configuration file from '" << fname << "': " << msg << endl,
-         g_slog->withName("lua")->error(Logr::Error, ret, "Unable to read configuration file", "file", Logging::Loggable(fname), "msg", Logging::Loggable(msg)));
+    g_log << Logger::Error << "Unable to read configuration file from '" << fname << "': " << msg << endl;
     throw std::runtime_error(msg);
   }
-  loadStream(ifs);
+  loadStream(ifs, doPostLoad);
 };
 
 void BaseLua4::loadString(const std::string &script) {
   std::istringstream iss(script);
-  loadStream(iss);
+  loadStream(iss, true);
+};
+
+void BaseLua4::includePath(const std::string& directory) {
+  std::vector<std::string> vec;
+  const std::string& suffix = "lua";
+  auto directoryError = pdns::visit_directory(directory, [this, &directory, &suffix, &vec]([[maybe_unused]] ino_t inodeNumber, const std::string_view& name) {
+    (void)this;
+    if (boost::starts_with(name, ".")) {
+      return true; // skip any dots
+    }
+    if (boost::ends_with(name, suffix)) {
+      // build name
+      string fullName = directory + "/" + std::string(name);
+      // ensure it's readable file
+      struct stat statInfo
+      {
+      };
+      if (stat(fullName.c_str(), &statInfo) != 0 || !S_ISREG(statInfo.st_mode)) {
+        string msg = fullName + " is not a regular file";
+        g_log << Logger::Error << msg << std::endl;
+        throw PDNSException(msg);
+      }
+      vec.emplace_back(fullName);
+    }
+    return true;
+  });
+
+  if (directoryError) {
+    int err = errno;
+    string msg = directory + " is not accessible: " + stringerror(err);
+    g_log << Logger::Error << msg << std::endl;
+    throw PDNSException(msg);
+  }
+
+  std::sort(vec.begin(), vec.end(), CIStringComparePOSIX());
+
+  for(const auto& file: vec) {
+    loadFile(file, false);
+  }
 };
 
 //  By default no features
@@ -289,10 +327,12 @@ void BaseLua4::prepareContext() {
   d_lw->writeVariable("pdns", d_pd);
 }
 
-void BaseLua4::loadStream(std::istream &stream) {
+void BaseLua4::loadStream(std::istream &stream, bool doPostLoad) {
   d_lw->executeCode(stream);
 
-  postLoad();
+  if (doPostLoad) {
+    postLoad();
+  }
 }
 
 BaseLua4::~BaseLua4() = default;
index 1cf9e4b7c088efc5a61e428349fdb6ef518866c5..1786d0ff78ccc9500e1b8df1c6ce9f72c14be9b2 100644 (file)
@@ -10,12 +10,14 @@ class BaseLua4 : public boost::noncopyable
 {
 protected:
   std::unique_ptr<LuaContext> d_lw; // this is way on top because it must get destroyed _last_
+  std::string d_include_path; // path where scripts to include at postLoad are
 
 public:
-  BaseLua4();
-  void loadFile(const std::string& fname);
-  void loadString(const std::string& script);
-  void loadStream(std::istream& stream);
+  BaseLua4(const std::string &includePath) : d_include_path(includePath) {};
+  void loadFile(const std::string &fname, bool doPostLoad=true);
+  void loadString(const std::string &script);
+  void loadStream(std::istream &stream, bool doPostLoad=true);
+  void includePath(const std::string &directory);
   virtual ~BaseLua4(); // this is so unique_ptr works with an incomplete type
 protected:
   void prepareContext();
index af5308ad7b2972c171b680019bf56d89767b8b2a..af79b7e1372ca75cb7d5a359bf8cc16a40cce130 100644 (file)
@@ -34,8 +34,6 @@
 #include <unordered_set>
 #include "rec-main.hh"
 
-RecursorLua4::RecursorLua4() { prepareContext(); }
-
 boost::optional<dnsheader> RecursorLua4::DNSQuestion::getDH() const
 {
   if (dh != nullptr) {
@@ -495,6 +493,9 @@ void RecursorLua4::postPrepareContext()
       (*event.discardedPolicies)[policy] = true;
     }
   });
+  if (!d_include_path.empty()) {
+    includePath(d_include_path);
+  }
 }
 
 // clang-format on
index a275184510d4bbf1977e843be5600d93df4b02f1..1a758abb5d9d9b000e0e0d65a65e7b92a0478926 100644 (file)
@@ -72,7 +72,11 @@ struct LuaContext::Pusher<pdns_postresolve_ffi_handle*>
 class RecursorLua4 : public BaseLua4
 {
 public:
-  RecursorLua4();
+  RecursorLua4(const std::string& includePath = "") :
+    BaseLua4(includePath)
+  {
+    prepareContext();
+  };
   RecursorLua4(const RecursorLua4&) = delete;
   RecursorLua4(RecursorLua4&&) = delete;
   RecursorLua4& operator=(const RecursorLua4&) = delete;
index 98a8c15e886510bd6425533e5fed506d8b238211..bd838f846fbf2e4430c48690bac4ce7d67cd3c1e 100644 (file)
@@ -351,7 +351,8 @@ static void rpzPrimary(LuaConfigItems& lci, const boost::variant<string, std::ve
 class RecLuaConfigContext : public BaseLua4
 {
 public:
-  RecLuaConfigContext()
+  RecLuaConfigContext() :
+    BaseLua4("")
   {
     prepareContext();
   }