From: Otto Moerbeek Date: Fri, 5 Jun 2020 10:37:47 +0000 (+0200) Subject: Add a flag to the RPZ indicating if it should override the answer from gettag. X-Git-Tag: dnsdist-1.5.0-rc3~10^2~2 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=db27d56f07fa88b90b28924eff7e7082141a697c;p=thirdparty%2Fpdns.git Add a flag to the RPZ indicating if it should override the answer from gettag. Defaults to true. --- diff --git a/pdns/filterpo.hh b/pdns/filterpo.hh index 54bdda9c6e..fc3287b474 100644 --- a/pdns/filterpo.hh +++ b/pdns/filterpo.hh @@ -80,6 +80,7 @@ public: std::unordered_set d_tags; std::string d_name; Priority d_priority{maximumPriority}; + bool d_policyOverridesGettag{true}; }; struct Policy @@ -139,6 +140,13 @@ public: return notSet; } + bool policyOverridesGettag() const { + if (d_zoneData) { + return d_zoneData->d_policyOverridesGettag; + } + return true; + } + std::vector getCustomRecords(const DNSName& qname, uint16_t qtype) const; std::vector getRecords(const DNSName& qname) const; @@ -191,6 +199,10 @@ public: { d_zoneData->d_tags = std::move(tags); } + void setPolicyOverridesGettag(bool flag) + { + d_zoneData->d_policyOverridesGettag = flag; + } const std::string& getName() const { return d_zoneData->d_name; @@ -262,6 +274,7 @@ public: void setPriority(Priority p) { d_zoneData->d_priority = p; } + private: static DNSName maskToRPZ(const Netmask& nm); static bool findExactNamedPolicy(const std::unordered_map& polmap, const DNSName& qname, DNSFilterEngine::Policy& pol); diff --git a/pdns/pdns_recursor.cc b/pdns/pdns_recursor.cc index 74547a6267..7fa933f265 100644 --- a/pdns/pdns_recursor.cc +++ b/pdns/pdns_recursor.cc @@ -1442,10 +1442,10 @@ static void startDoResolve(void *p) } } - // If we are doing RPZ and a policy was matched, it takes precedence over an answer from gettag_ffi - // So process the gettag_ffi answer only if no RPZ action was done or matched - // This might need more sophistication for the type != None && kind == NoAction case... - if (!wantsRPZ || appliedPolicy.d_type == DNSFilterEngine::PolicyType::None || appliedPolicy.d_kind == DNSFilterEngine::PolicyKind::NoAction) { + // If we are doing RPZ and a policy was matched, it normally takes precedence over an answer from gettag. + // So process the gettag_ffi answer only if no RPZ action was done or matched or the policy indicates gettag should + // have precedence. + if (!wantsRPZ || !appliedPolicy.policyOverridesGettag() || appliedPolicy.d_type == DNSFilterEngine::PolicyType::None || appliedPolicy.d_kind == DNSFilterEngine::PolicyKind::NoAction) { if (dc->d_rcode != boost::none) { /* we have a response ready to go, most likely from gettag_ffi */ ret = std::move(dc->d_records); diff --git a/pdns/rec-lua-conf.cc b/pdns/rec-lua-conf.cc index 73bffa823e..0481c8a0cc 100644 --- a/pdns/rec-lua-conf.cc +++ b/pdns/rec-lua-conf.cc @@ -53,7 +53,7 @@ typename C::value_type::second_type constGet(const C& c, const std::string& name typedef std::unordered_map> > > rpzOptions_t; -static void parseRPZParameters(rpzOptions_t& have, std::string& polName, boost::optional& defpol, bool& defpolOverrideLocal, uint32_t& maxTTL, size_t& zoneSizeHint, std::unordered_set& tags) +static void parseRPZParameters(rpzOptions_t& have, std::string& polName, boost::optional& defpol, bool& defpolOverrideLocal, uint32_t& maxTTL, size_t& zoneSizeHint, std::unordered_set& tags, bool& overridesGettag) { if(have.count("policyName")) { polName = boost::get(have["policyName"]); @@ -88,6 +88,9 @@ static void parseRPZParameters(rpzOptions_t& have, std::string& polName, boost:: tags.insert(tag.second); } } + if (have.count("overridesGettag")) { + overridesGettag = boost::get(have["overridesGettag"]); + } } #if HAVE_PROTOBUF @@ -241,11 +244,12 @@ void loadRecursorLuaConfig(const std::string& fname, luaConfigDelayedThreads& de std::string polName("rpzFile"); std::shared_ptr zone = std::make_shared(); uint32_t maxTTL = std::numeric_limits::max(); + bool overridesGettag = true; if(options) { auto& have = *options; size_t zoneSizeHint = 0; std::unordered_set tags; - parseRPZParameters(have, polName, defpol, defpolOverrideLocal, maxTTL, zoneSizeHint, tags); + parseRPZParameters(have, polName, defpol, defpolOverrideLocal, maxTTL, zoneSizeHint, tags, overridesGettag); if (zoneSizeHint > 0) { zone->reserve(zoneSizeHint); } @@ -253,6 +257,7 @@ void loadRecursorLuaConfig(const std::string& fname, luaConfigDelayedThreads& de } g_log<setName(polName); + zone->setPolicyOverridesGettag(overridesGettag); loadRPZFromFile(filename, zone, defpol, defpolOverrideLocal, maxTTL); lci.dfe.addZone(zone); g_log< tags; - parseRPZParameters(have, polName, defpol, defpolOverrideLocal, maxTTL, zoneSizeHint, tags); + bool overridesGettag = true; + parseRPZParameters(have, polName, defpol, defpolOverrideLocal, maxTTL, zoneSizeHint, tags, overridesGettag); if (zoneSizeHint > 0) { zone->reserve(zoneSizeHint); } zone->setTags(std::move(tags)); + zone->setPolicyOverridesGettag(overridesGettag); if(have.count("tsigname")) { tt.name=DNSName(toLower(boost::get(have["tsigname"])));