From: Kees Monshouwer Date: Mon, 31 Aug 2020 16:41:53 +0000 (+0200) Subject: auth: avoid metadata cache polution in the api code X-Git-Tag: auth-4.4.0-alpha1~3^2~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=cf0541a3496c649cf368475e48848fe84ad53914;p=thirdparty%2Fpdns.git auth: avoid metadata cache polution in the api code --- diff --git a/pdns/dbdnsseckeeper.cc b/pdns/dbdnsseckeeper.cc index 47cee9baa5..14e1cd253f 100644 --- a/pdns/dbdnsseckeeper.cc +++ b/pdns/dbdnsseckeeper.cc @@ -59,9 +59,9 @@ bool DNSSECKeeper::doesDNSSEC() return d_keymetadb->doesDNSSEC(); } -bool DNSSECKeeper::isSecuredZone(const DNSName& zone) +bool DNSSECKeeper::isSecuredZone(const DNSName& zone, bool useCache) { - if(isPresigned(zone)) + if(isPresigned(zone, useCache)) return true; keyset_t keys = getKeys(zone); // does the cache @@ -74,10 +74,15 @@ bool DNSSECKeeper::isSecuredZone(const DNSName& zone) return false; } -bool DNSSECKeeper::isPresigned(const DNSName& name) +bool DNSSECKeeper::isPresigned(const DNSName& name, bool useCache) { string meta; - getFromMeta(name, "PRESIGNED", meta); + if (useCache) { + getFromMeta(name, "PRESIGNED", meta); + } + else { + getFromMetaNoCache(name, "PRESIGNED", meta); + } return meta=="1"; } @@ -270,12 +275,24 @@ bool DNSSECKeeper::getFromMeta(const DNSName& zname, const std::string& key, std return ret; } -void DNSSECKeeper::getSoaEdit(const DNSName& zname, std::string& value) +bool DNSSECKeeper::getFromMetaNoCache(const DNSName& name, const std::string& kind, std::string& value) +{ + std::vector meta; + if (d_keymetadb->getDomainMetadata(name, kind, meta)) { + if(!meta.empty()) { + value = *meta.begin(); + return true; + } + } + return false; +} + +void DNSSECKeeper::getSoaEdit(const DNSName& zname, std::string& value, bool useCache) { static const string soaEdit(::arg()["default-soa-edit"]); static const string soaEditSigned(::arg()["default-soa-edit-signed"]); - if (isPresigned(zname)) { + if (isPresigned(zname, useCache)) { // SOA editing on a presigned zone never makes sense return; } @@ -283,7 +300,7 @@ void DNSSECKeeper::getSoaEdit(const DNSName& zname, std::string& value) getFromMeta(zname, "SOA-EDIT", value); if ((!soaEdit.empty() || !soaEditSigned.empty()) && value.empty()) { - if (!soaEditSigned.empty() && isSecuredZone(zname)) + if (!soaEditSigned.empty() && isSecuredZone(zname, useCache)) value=soaEditSigned; if (value.empty()) value=soaEdit; @@ -305,10 +322,15 @@ uint64_t DNSSECKeeper::dbdnssecCacheSizes(const std::string& str) return (uint64_t)-1; } -bool DNSSECKeeper::getNSEC3PARAM(const DNSName& zname, NSEC3PARAMRecordContent* ns3p, bool* narrow) +bool DNSSECKeeper::getNSEC3PARAM(const DNSName& zname, NSEC3PARAMRecordContent* ns3p, bool* narrow, bool useCache) { string value; - getFromMeta(zname, "NSEC3PARAM", value); + if(useCache) { + getFromMeta(zname, "NSEC3PARAM", value); + } + else { + getFromMetaNoCache(zname, "NSEC3PARAM", value); + } if(value.empty()) { // "no NSEC3" return false; } @@ -326,7 +348,12 @@ bool DNSSECKeeper::getNSEC3PARAM(const DNSName& zname, NSEC3PARAMRecordContent* } } if(narrow) { - getFromMeta(zname, "NSEC3NARROW", value); + if(useCache) { + getFromMeta(zname, "NSEC3NARROW", value); + } + else { + getFromMetaNoCache(zname, "NSEC3NARROW", value); + } *narrow = (value=="1"); } return true; @@ -658,7 +685,7 @@ bool DNSSECKeeper::unSecureZone(const DNSName& zone, string& error, string& info * \param doTransaction Whether or not to wrap the rectify in a transaction */ bool DNSSECKeeper::rectifyZone(const DNSName& zone, string& error, string& info, bool doTransaction) { - if (isPresigned(zone)) { + if (isPresigned(zone, doTransaction)) { error = "Rectify presigned zone '"+zone.toLogString()+"' is not allowed/necessary."; return false; } @@ -708,11 +735,11 @@ bool DNSSECKeeper::rectifyZone(const DNSName& zone, string& error, string& info, } NSEC3PARAMRecordContent ns3pr; - bool securedZone = isSecuredZone(zone); + bool securedZone = isSecuredZone(zone, doTransaction); bool haveNSEC3 = false, isOptOut = false, narrow = false; if(securedZone) { - haveNSEC3 = getNSEC3PARAM(zone, &ns3pr, &narrow); + haveNSEC3 = getNSEC3PARAM(zone, &ns3pr, &narrow, doTransaction); isOptOut = (haveNSEC3 && ns3pr.d_flags); if(!haveNSEC3) { diff --git a/pdns/dnsseckeeper.hh b/pdns/dnsseckeeper.hh index f323b3adb1..56ddc226d8 100644 --- a/pdns/dnsseckeeper.hh +++ b/pdns/dnsseckeeper.hh @@ -192,7 +192,7 @@ public: static void clearCaches(const DNSName& name); bool doesDNSSEC(); - bool isSecuredZone(const DNSName& zone); + bool isSecuredZone(const DNSName& zone, bool useCache=true); keyset_t getEntryPoints(const DNSName& zname); keyset_t getKeys(const DNSName& zone, bool useCache = true); DNSSECPrivateKey getKeyById(const DNSName& zone, unsigned int id); @@ -205,12 +205,12 @@ public: bool unpublishKey(const DNSName& zname, unsigned int id); bool checkKeys(const DNSName& zname, vector* errorMessages = nullptr); - bool getNSEC3PARAM(const DNSName& zname, NSEC3PARAMRecordContent* n3p=0, bool* narrow=0); + bool getNSEC3PARAM(const DNSName& zname, NSEC3PARAMRecordContent* n3p=0, bool* narrow=0, bool useCache=true); bool checkNSEC3PARAM(const NSEC3PARAMRecordContent& ns3p, string& msg); bool setNSEC3PARAM(const DNSName& zname, const NSEC3PARAMRecordContent& n3p, const bool& narrow=false); bool unsetNSEC3PARAM(const DNSName& zname); bool getPreRRSIGs(UeberBackend& db, const DNSName& signer, const DNSName& qname, const DNSName& wildcardname, const QType& qtype, DNSResourceRecord::Place, vector& rrsigs, uint32_t signTTL); - bool isPresigned(const DNSName& zname); + bool isPresigned(const DNSName& zname, bool useCache=true); bool setPresigned(const DNSName& zname); bool unsetPresigned(const DNSName& zname); bool setPublishCDNSKEY(const DNSName& zname); @@ -235,7 +235,7 @@ public: void getFromMetaOrDefault(const DNSName& zname, const std::string& key, std::string& value, const std::string& defaultvalue); bool getFromMeta(const DNSName& zname, const std::string& key, std::string& value); - void getSoaEdit(const DNSName& zname, std::string& value); + void getSoaEdit(const DNSName& zname, std::string& value, bool useCache=true); bool unSecureZone(const DNSName& zone, std::string& error, std::string& info); bool rectifyZone(const DNSName& zone, std::string& error, std::string& info, bool doTransaction); @@ -243,6 +243,8 @@ public: typedef std::map > METAValues; private: + bool getFromMetaNoCache(const DNSName& name, const std::string& kind, std::string& value); + int64_t d_metaCacheCleanAction{0}; struct KeyCacheEntry diff --git a/pdns/ws-auth.cc b/pdns/ws-auth.cc index 32bb9ad27b..77d66a77e3 100644 --- a/pdns/ws-auth.cc +++ b/pdns/ws-auth.cc @@ -331,7 +331,9 @@ static Json::object getZoneInfo(const DomainInfo& di, DNSSECKeeper* dk) { }; if (dk) { obj["dnssec"] = dk->isSecuredZone(di.zone); - obj["edited_serial"] = (double)calculateEditSOA(di.serial, *dk, di.zone); + string soa_edit; + dk->getSoaEdit(di.zone, soa_edit, false); + obj["edited_serial"] = (double)calculateEditSOA(di.serial, soa_edit, di.zone); } return obj; } @@ -697,6 +699,7 @@ static void updateDomainSettingsFromDocument(UeberBackend& B, const DomainInfo& bool isDNSSECZone = dk.isSecuredZone(zonename); + bool isPresigned = dk.isPresigned(zonename); if (dnssecInJSON) { if (dnssecDocVal) { @@ -737,7 +740,7 @@ static void updateDomainSettingsFromDocument(UeberBackend& B, const DomainInfo& if (!dk.unSecureZone(zonename, error, info)) { throw ApiException("Error while un-securing zone '"+ zonename.toString()+"': " + error); } - isDNSSECZone = dk.isSecuredZone(zonename); + isDNSSECZone = dk.isSecuredZone(zonename, false); if (isDNSSECZone) { throw ApiException("Unable to un-secure zone '"+ zonename.toString()+"'"); } @@ -773,7 +776,7 @@ static void updateDomainSettingsFromDocument(UeberBackend& B, const DomainInfo& } } - if (shouldRectify && !dk.isPresigned(zonename)) { + if (shouldRectify && !isPresigned) { // Rectify string api_rectify; di.backend->getDomainMetadataOne(zonename, "API-RECTIFY", api_rectify);