diff --git a/pdns/lua-auth4.cc b/pdns/lua-auth4.cc index 77f7caa9035e..ea8d380f0d99 100644 --- a/pdns/lua-auth4.cc +++ b/pdns/lua-auth4.cc @@ -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("getTsigName", [](UpdatePolicyQuery& upq) { return upq.tsigName; }); d_lw->registerFunction("getPeerPrincipal", [](UpdatePolicyQuery& upq) { return upq.peerPrincipal; }); /* end of update policy */ + if (!d_include_path.empty()) { + includePath(d_include_path); + } } void AuthLua4::postLoad() { diff --git a/pdns/lua-auth4.hh b/pdns/lua-auth4.hh index fea41d640b99..d154df708849 100644 --- a/pdns/lua-auth4.hh +++ b/pdns/lua-auth4.hh @@ -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&); LuaContext* getLua(); diff --git a/pdns/lua-base4.cc b/pdns/lua-base4.cc index 19e6aef33842..b3d5d1b90f8b 100644 --- a/pdns/lua-base4.cc +++ b/pdns/lua-base4.cc @@ -1,8 +1,10 @@ +#include "config.h" #include #include #include #include #include +#include #include "logger.hh" #include "logging.hh" #include "iputils.hh" @@ -15,24 +17,60 @@ #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 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; diff --git a/pdns/lua-base4.hh b/pdns/lua-base4.hh index 1cf9e4b7c088..1786d0ff78cc 100644 --- a/pdns/lua-base4.hh +++ b/pdns/lua-base4.hh @@ -10,12 +10,14 @@ class BaseLua4 : public boost::noncopyable { protected: std::unique_ptr 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(); diff --git a/pdns/recursordist/lua-recursor4.cc b/pdns/recursordist/lua-recursor4.cc index af5308ad7b29..af79b7e1372c 100644 --- a/pdns/recursordist/lua-recursor4.cc +++ b/pdns/recursordist/lua-recursor4.cc @@ -34,8 +34,6 @@ #include #include "rec-main.hh" -RecursorLua4::RecursorLua4() { prepareContext(); } - boost::optional 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 diff --git a/pdns/recursordist/lua-recursor4.hh b/pdns/recursordist/lua-recursor4.hh index a275184510d4..1a758abb5d9d 100644 --- a/pdns/recursordist/lua-recursor4.hh +++ b/pdns/recursordist/lua-recursor4.hh @@ -72,7 +72,11 @@ struct LuaContext::Pusher 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; diff --git a/pdns/recursordist/rec-lua-conf.cc b/pdns/recursordist/rec-lua-conf.cc index 98a8c15e8865..bd838f846fbf 100644 --- a/pdns/recursordist/rec-lua-conf.cc +++ b/pdns/recursordist/rec-lua-conf.cc @@ -351,7 +351,8 @@ static void rpzPrimary(LuaConfigItems& lci, const boost::variant