]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
auth: detect possible metadata cache pollution 9520/head
authorKees Monshouwer <mind04@monshouwer.org>
Mon, 31 Aug 2020 19:12:48 +0000 (21:12 +0200)
committermind04 <mind04@monshouwer.org>
Thu, 7 Jan 2021 20:20:21 +0000 (21:20 +0100)
pdns/backends/gsql/gsqlbackend.hh
pdns/dbdnsseckeeper.cc
pdns/dnsbackend.hh
pdns/dnsseckeeper.hh
pdns/ueberbackend.cc
pdns/ueberbackend.hh

index 6f7c5c53681e13f6718694394ef4e217804e6c3b..87084d2d4e769949c73a2afd855bfc0ae984f977 100644 (file)
@@ -259,7 +259,7 @@ protected:
     reconnect();
   }
   virtual void reconnect() { }
-  virtual bool inTransaction()
+  virtual bool inTransaction() override
   {
     return d_inTransaction;
   }
index bce257f00ef17b1087018acf9956d0776a43843a..0373d5bb3a5042d1e65bd3832bb69dddd8184926 100644 (file)
@@ -222,6 +222,13 @@ void DNSSECKeeper::getFromMetaOrDefault(const DNSName& zname, const std::string&
 
 bool DNSSECKeeper::getFromMeta(const DNSName& zname, const std::string& key, std::string& value)
 {
+  if (d_metaUpdate) {
+    if (d_keymetadb->inTransaction()) {
+      throw runtime_error("DNSSECKeeper::getFromMeta() called after an update from within a transactiona.");
+    }
+    d_metaUpdate=false;
+  }
+
   static int ttl = ::arg().asNum("domain-metadata-cache-ttl");
 
   if(!((++s_ops) % 100000)) {
@@ -388,6 +395,10 @@ bool DNSSECKeeper::checkNSEC3PARAM(const NSEC3PARAMRecordContent& ns3p, string&
 
 bool DNSSECKeeper::setNSEC3PARAM(const DNSName& zname, const NSEC3PARAMRecordContent& ns3p, const bool& narrow)
 {
+  if (d_keymetadb->inTransaction()) {
+    d_metaUpdate = true;
+  }
+
   string error_msg = "";
   if (!checkNSEC3PARAM(ns3p, error_msg))
     throw runtime_error("NSEC3PARAMs provided for zone '"+zname.toLogString()+"' are invalid: " + error_msg);
@@ -408,12 +419,20 @@ bool DNSSECKeeper::setNSEC3PARAM(const DNSName& zname, const NSEC3PARAMRecordCon
 
 bool DNSSECKeeper::unsetNSEC3PARAM(const DNSName& zname)
 {
+  if (d_keymetadb->inTransaction()) {
+    d_metaUpdate = true;
+  }
+
   return (d_keymetadb->setDomainMetadata(zname, "NSEC3PARAM", vector<string>()) && d_keymetadb->setDomainMetadata(zname, "NSEC3NARROW", vector<string>())) && clearMetaCache(zname);
 }
 
 
 bool DNSSECKeeper::setPresigned(const DNSName& zname)
 {
+  if (d_keymetadb->inTransaction()) {
+    d_metaUpdate = true;
+  }
+
   vector<string> meta;
   meta.push_back("1");
   return d_keymetadb->setDomainMetadata(zname, "PRESIGNED", meta) && clearMetaCache(zname);
@@ -421,6 +440,10 @@ bool DNSSECKeeper::setPresigned(const DNSName& zname)
 
 bool DNSSECKeeper::unsetPresigned(const DNSName& zname)
 {
+  if (d_keymetadb->inTransaction()) {
+    d_metaUpdate = true;
+  }
+
   return d_keymetadb->setDomainMetadata(zname, "PRESIGNED", vector<string>()) && clearMetaCache(zname);
 }
 
@@ -435,6 +458,10 @@ bool DNSSECKeeper::unsetPresigned(const DNSName& zname)
  */
 bool DNSSECKeeper::setPublishCDS(const DNSName& zname, const string& digestAlgos)
 {
+  if (d_keymetadb->inTransaction()) {
+    d_metaUpdate = true;
+  }
+
   vector<string> meta;
   meta.push_back(digestAlgos);
   return d_keymetadb->setDomainMetadata(zname, "PUBLISH-CDS", meta) && clearMetaCache(zname);
@@ -453,6 +480,10 @@ void DNSSECKeeper::getPublishCDS(const DNSName& zname, std::string& value)
  */
 bool DNSSECKeeper::unsetPublishCDS(const DNSName& zname)
 {
+  if (d_keymetadb->inTransaction()) {
+    d_metaUpdate = true;
+  }
+
   return d_keymetadb->setDomainMetadata(zname, "PUBLISH-CDS", vector<string>()) && clearMetaCache(zname);
 }
 
@@ -464,6 +495,10 @@ bool DNSSECKeeper::unsetPublishCDS(const DNSName& zname)
  */
 bool DNSSECKeeper::setPublishCDNSKEY(const DNSName& zname, bool deleteAlg)
 {
+  if (d_keymetadb->inTransaction()) {
+    d_metaUpdate = true;
+  }
+
   vector<string> meta;
   meta.push_back(deleteAlg ? "0" : "1");
   return d_keymetadb->setDomainMetadata(zname, "PUBLISH-CDNSKEY", meta) && clearMetaCache(zname);
@@ -482,6 +517,10 @@ void DNSSECKeeper::getPublishCDNSKEY(const DNSName& zname, std::string& value)
  */
 bool DNSSECKeeper::unsetPublishCDNSKEY(const DNSName& zname)
 {
+  if (d_keymetadb->inTransaction()) {
+    d_metaUpdate = true;
+  }
+
   return d_keymetadb->setDomainMetadata(zname, "PUBLISH-CDNSKEY", vector<string>()) && clearMetaCache(zname);
 }
 
index 3d68b7d8626b20a9f1ccb6d9cded9224771e7ea4..62394515f724dea741bf8fe21574884cea2264c7 100644 (file)
@@ -263,6 +263,11 @@ public:
     return false;
   }
 
+  virtual bool inTransaction()
+  {
+    return false;
+  }
+
   virtual void reload()
   {
   }
index 2d61046f88003fefc30334e93bcf2064dfc573e4..cf821a6d076e49316277ac6ab279e4b16cde1a96 100644 (file)
@@ -246,6 +246,7 @@ private:
   bool getFromMetaNoCache(const DNSName& name, const std::string& kind, std::string& value);
 
   int64_t d_metaCacheCleanAction{0};
+  bool d_metaUpdate{false};
 
   struct KeyCacheEntry
   {
index e3a852747a355fb3ec8b822d2e110e4c6b6116a2..9ac2ebb9c9db871483bd6d7c265e03019aa412e5 100644 (file)
@@ -304,6 +304,16 @@ void UeberBackend::getUpdatedMasters(vector<DomainInfo>* domains)
   }
 }
 
+bool UeberBackend::inTransaction()
+{
+  for (auto* b : backends )
+  {
+    if(b->inTransaction())
+      return true;
+  }
+  return false;
+}
+
 bool UeberBackend::getAuth(const DNSName &target, const QType& qtype, SOAData* sd, bool cachedOk)
 {
   // A backend can respond to our authority request with the 'best' match it
index 57b1e96482fbc66ec66670e2bed9e8439c592918..873b098f161455422df73a700cdbf59180b8f69f 100644 (file)
@@ -132,6 +132,8 @@ public:
   void reload();
   bool searchRecords(const string &pattern, int maxResults, vector<DNSResourceRecord>& result);
   bool searchComments(const string &pattern, int maxResults, vector<Comment>& result);
+
+  bool inTransaction();
 private:
   handle d_handle;
   vector<DNSZoneRecord> d_answers;