]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
Add a flag to the RPZ indicating if it should override the answer from gettag.
authorOtto Moerbeek <otto.moerbeek@open-xchange.com>
Fri, 5 Jun 2020 10:37:47 +0000 (12:37 +0200)
committerOtto Moerbeek <otto.moerbeek@open-xchange.com>
Fri, 5 Jun 2020 10:38:22 +0000 (12:38 +0200)
Defaults to true.

pdns/filterpo.hh
pdns/pdns_recursor.cc
pdns/rec-lua-conf.cc

index 54bdda9c6ee549333ef02c8ef939856b5e90dcee..fc3287b474fa3259d413de27dc1f83c38d00b7d7 100644 (file)
@@ -80,6 +80,7 @@ public:
     std::unordered_set<std::string> 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<DNSRecord> getCustomRecords(const DNSName& qname, uint16_t qtype) const;
     std::vector<DNSRecord> 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<DNSName, DNSFilterEngine::Policy>& polmap, const DNSName& qname, DNSFilterEngine::Policy& pol);
index 74547a626797c65b35e34093c61886397e1039cc..7fa933f2659b42dafdd58293142e96f903c5c98f 100644 (file)
@@ -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);
index 73bffa823e5d3019963fcf006e8aef81f5ff8546..0481c8a0cc06b11d8ef02b8af125a0c4c852660c 100644 (file)
@@ -53,7 +53,7 @@ typename C::value_type::second_type constGet(const C& c, const std::string& name
 
 typedef std::unordered_map<std::string, boost::variant<bool, uint32_t, std::string, std::vector<std::pair<int, std::string>> > > rpzOptions_t;
 
-static void parseRPZParameters(rpzOptions_t& have, std::string& polName, boost::optional<DNSFilterEngine::Policy>& defpol, bool& defpolOverrideLocal, uint32_t& maxTTL, size_t& zoneSizeHint, std::unordered_set<std::string>& tags)
+static void parseRPZParameters(rpzOptions_t& have, std::string& polName, boost::optional<DNSFilterEngine::Policy>& defpol, bool& defpolOverrideLocal, uint32_t& maxTTL, size_t& zoneSizeHint, std::unordered_set<std::string>& tags, bool& overridesGettag)
 {
   if(have.count("policyName")) {
     polName = boost::get<std::string>(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<bool>(have["overridesGettag"]);
+  }
 }
 
 #if HAVE_PROTOBUF
@@ -241,11 +244,12 @@ void loadRecursorLuaConfig(const std::string& fname, luaConfigDelayedThreads& de
         std::string polName("rpzFile");
         std::shared_ptr<DNSFilterEngine::Zone> zone = std::make_shared<DNSFilterEngine::Zone>();
         uint32_t maxTTL = std::numeric_limits<uint32_t>::max();
+        bool overridesGettag = true;
         if(options) {
           auto& have = *options;
           size_t zoneSizeHint = 0;
           std::unordered_set<std::string> 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<<Logger::Warning<<"Loading RPZ from file '"<<filename<<"'"<<endl;
         zone->setName(polName);
+        zone->setPolicyOverridesGettag(overridesGettag);
         loadRPZFromFile(filename, zone, defpol, defpolOverrideLocal, maxTTL);
         lci.dfe.addZone(zone);
         g_log<<Logger::Warning<<"Done loading RPZ from file '"<<filename<<"'"<<endl;
@@ -295,11 +300,13 @@ void loadRecursorLuaConfig(const std::string& fname, luaConfigDelayedThreads& de
           auto& have = *options;
           size_t zoneSizeHint = 0;
           std::unordered_set<std::string> 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<string>(have["tsigname"])));