From ce8c5899612fa270b32d93928c664d0c7f2d597e Mon Sep 17 00:00:00 2001 From: Kees Monshouwer Date: Tue, 13 Apr 2021 15:15:23 +0200 Subject: [PATCH] auth: make sure we recheck SOA for notifies --- modules/bindbackend/bindbackend2.cc | 14 ++++++++++++-- modules/bindbackend/bindbackend2.hh | 2 ++ modules/lmdbbackend/lmdbbackend.cc | 7 +++++++ modules/lmdbbackend/lmdbbackend.hh | 1 + modules/remotebackend/httpconnector.cc | 4 ++++ modules/remotebackend/remotebackend.cc | 12 ++++++++++++ modules/remotebackend/remotebackend.hh | 1 + pdns/backends/gsql/gsqlbackend.cc | 20 +++++++++++++------- pdns/backends/gsql/gsqlbackend.hh | 2 ++ pdns/dnsbackend.hh | 9 +++++++-- pdns/slavecommunicator.cc | 4 ++++ 11 files changed, 65 insertions(+), 11 deletions(-) diff --git a/modules/bindbackend/bindbackend2.cc b/modules/bindbackend/bindbackend2.cc index 1d3312ed2d..675e818677 100644 --- a/modules/bindbackend/bindbackend2.cc +++ b/modules/bindbackend/bindbackend2.cc @@ -184,15 +184,25 @@ void Bind2Backend::setNotified(uint32_t id, uint32_t serial) safePutBBDomainInfo(bbd); } -void Bind2Backend::setFresh(uint32_t domain_id) +void Bind2Backend::setLastCheck(uint32_t domain_id, time_t lastcheck) { BB2DomainInfo bbd; if (safeGetBBDomainInfo(domain_id, &bbd)) { - bbd.d_lastcheck = time(nullptr); + bbd.d_lastcheck = lastcheck; safePutBBDomainInfo(bbd); } } +void Bind2Backend::setStale(uint32_t domain_id) +{ + setLastCheck(domain_id, 0); +} + +void Bind2Backend::setFresh(uint32_t domain_id) +{ + setLastCheck(domain_id, time(nullptr)); +} + bool Bind2Backend::startTransaction(const DNSName& qname, int id) { if (id < 0) { diff --git a/modules/bindbackend/bindbackend2.hh b/modules/bindbackend/bindbackend2.hh index 93c1fe85e1..e5bd7cf9c7 100644 --- a/modules/bindbackend/bindbackend2.hh +++ b/modules/bindbackend/bindbackend2.hh @@ -199,6 +199,7 @@ public: static DNSBackend* maker(); static std::mutex s_startup_lock; + void setStale(uint32_t domain_id) override; void setFresh(uint32_t domain_id) override; void setNotified(uint32_t id, uint32_t serial) override; bool startTransaction(const DNSName& qname, int id) override; @@ -251,6 +252,7 @@ private: static bool safeRemoveBBDomainInfo(const DNSName& name); shared_ptr d_dnssecdb; bool getNSEC3PARAM(const DNSName& name, NSEC3PARAMRecordContent* ns3p); + void setLastCheck(uint32_t domain_id, time_t lastcheck); class handle { public: diff --git a/modules/lmdbbackend/lmdbbackend.cc b/modules/lmdbbackend/lmdbbackend.cc index 03b0d5438a..d2d0fc8add 100644 --- a/modules/lmdbbackend/lmdbbackend.cc +++ b/modules/lmdbbackend/lmdbbackend.cc @@ -932,6 +932,13 @@ bool LMDBBackend::setAccount(const DNSName& domain, const std::string& account) }); } +void LMDBBackend::setStale(uint32_t domain_id) +{ + genChangeDomain(domain_id, [](DomainInfo& di) { + di.last_check = 0; + }); +} + void LMDBBackend::setFresh(uint32_t domain_id) { genChangeDomain(domain_id, [](DomainInfo& di) { diff --git a/modules/lmdbbackend/lmdbbackend.hh b/modules/lmdbbackend/lmdbbackend.hh index 9951841d09..a489770b6c 100644 --- a/modules/lmdbbackend/lmdbbackend.hh +++ b/modules/lmdbbackend/lmdbbackend.hh @@ -97,6 +97,7 @@ public: } bool setDomainMetadata(const DNSName& name, const std::string& kind, const std::vector& meta) override; + void setStale(uint32_t domain_id) override; void setFresh(uint32_t domain_id) override; void setNotified(uint32_t id, uint32_t serial) override; bool setAccount(const DNSName& domain, const std::string& account) override; diff --git a/modules/remotebackend/httpconnector.cc b/modules/remotebackend/httpconnector.cc index 795a9f72b7..99c0676e0e 100644 --- a/modules/remotebackend/httpconnector.cc +++ b/modules/remotebackend/httpconnector.cc @@ -260,6 +260,10 @@ void HTTPConnector::restful_requestbuilder(const std::string& method, const Json req.preparePost(); verb = "PATCH"; } + else if (method == "setStale") { + req.preparePost(); + verb = "PATCH"; + } else if (method == "setFresh") { req.preparePost(); verb = "PATCH"; diff --git a/modules/remotebackend/remotebackend.cc b/modules/remotebackend/remotebackend.cc index 5da00da83d..248a55004f 100644 --- a/modules/remotebackend/remotebackend.cc +++ b/modules/remotebackend/remotebackend.cc @@ -927,6 +927,18 @@ void RemoteBackend::getUnfreshSlaveInfos(vector* domains) } } +void RemoteBackend::setStale(uint32_t domain_id) +{ + Json query = Json::object{ + {"method", "setStale"}, + {"parameters", Json::object{{"id", static_cast(domain_id)}}}}; + + Json answer; + if (this->send(query) == false || this->recv(answer) == false) { + g_log << Logger::Error << kBackendId << " Failed to execute RPC for RemoteBackend::setStale(" << domain_id << ")" << endl; + } +} + void RemoteBackend::setFresh(uint32_t domain_id) { Json query = Json::object{ diff --git a/modules/remotebackend/remotebackend.hh b/modules/remotebackend/remotebackend.hh index 7c2b6c129f..7832682a1c 100644 --- a/modules/remotebackend/remotebackend.hh +++ b/modules/remotebackend/remotebackend.hh @@ -202,6 +202,7 @@ public: void getUpdatedMasters(vector* domains) override; void alsoNotifies(const DNSName& domain, set* ips) override; void getUnfreshSlaveInfos(vector* domains) override; + void setStale(uint32_t domain_id) override; void setFresh(uint32_t domain_id) override; static DNSBackend* maker(); diff --git a/pdns/backends/gsql/gsqlbackend.cc b/pdns/backends/gsql/gsqlbackend.cc index 5f55bd48a6..a44026c99f 100644 --- a/pdns/backends/gsql/gsqlbackend.cc +++ b/pdns/backends/gsql/gsqlbackend.cc @@ -207,22 +207,28 @@ void GSQLBackend::setNotified(uint32_t domain_id, uint32_t serial) } } -void GSQLBackend::setFresh(uint32_t domain_id) +void GSQLBackend::setLastCheck(uint32_t domain_id, time_t lastcheck) { try { reconnectIfNeeded(); - d_UpdateLastCheckOfZoneQuery_stmt-> - bind("last_check", time(nullptr))-> - bind("domain_id", domain_id)-> - execute()-> - reset(); + d_UpdateLastCheckOfZoneQuery_stmt->bind("last_check", lastcheck)->bind("domain_id", domain_id)->execute()->reset(); } catch (SSqlException &e) { - throw PDNSException("GSQLBackend unable to refresh domain_id "+itoa(domain_id)+": "+e.txtReason()); + throw PDNSException("GSQLBackend unable to update last_check for domain_id " + itoa(domain_id) + ": " + e.txtReason()); } } +void GSQLBackend::setStale(uint32_t domain_id) +{ + setLastCheck(domain_id, 0); +} + +void GSQLBackend::setFresh(uint32_t domain_id) +{ + setLastCheck(domain_id, time(nullptr)); +} + bool GSQLBackend::setMasters(const DNSName &domain, const vector &masters) { vector masters_s; diff --git a/pdns/backends/gsql/gsqlbackend.hh b/pdns/backends/gsql/gsqlbackend.hh index 0aa79f54a6..207992da3a 100644 --- a/pdns/backends/gsql/gsqlbackend.hh +++ b/pdns/backends/gsql/gsqlbackend.hh @@ -198,6 +198,7 @@ public: bool deleteDomain(const DNSName &domain) override; bool superMasterAdd(const string &ip, const string &nameserver, const string &account) override; bool superMasterBackend(const string &ip, const DNSName &domain, const vector&nsset, string *nameserver, string *account, DNSBackend **db) override; + void setStale(uint32_t domain_id) override; void setFresh(uint32_t domain_id) override; void getUnfreshSlaveInfos(vector *domains) override; void getUpdatedMasters(vector *updatedDomains) override; @@ -244,6 +245,7 @@ protected: string pattern2SQLPattern(const string& pattern); void extractRecord(SSqlStatement::row_t& row, DNSResourceRecord& rr); void extractComment(SSqlStatement::row_t& row, Comment& c); + void setLastCheck(uint32_t domain_id, time_t lastcheck); bool isConnectionUsable() { if (d_db) { return d_db->isConnectionUsable(); diff --git a/pdns/dnsbackend.hh b/pdns/dnsbackend.hh index f200a0526a..4341183394 100644 --- a/pdns/dnsbackend.hh +++ b/pdns/dnsbackend.hh @@ -311,12 +311,17 @@ public: virtual void getUpdatedMasters(vector* domains) { } - + + //! Called by PowerDNS to inform a backend that a domain need to be checked for freshness + virtual void setStale(uint32_t domain_id) + { + } + //! Called by PowerDNS to inform a backend that a domain has been checked for freshness virtual void setFresh(uint32_t domain_id) { - } + //! Called by PowerDNS to inform a backend that the changes in the domain have been reported to slaves virtual void setNotified(uint32_t id, uint32_t serial) { diff --git a/pdns/slavecommunicator.cc b/pdns/slavecommunicator.cc index 619c7e6660..0038a126c2 100644 --- a/pdns/slavecommunicator.cc +++ b/pdns/slavecommunicator.cc @@ -951,6 +951,10 @@ void CommunicatorClass::slaveRefresh(PacketHandler *P) } else if (newCount % 10 == 0) { g_log<setStale(di.id); + } continue; } -- 2.47.2