From: Aki Tuomi Date: Sat, 26 Dec 2015 18:30:11 +0000 (+0200) Subject: Verify domain ownership X-Git-Tag: dnsdist-1.0.0-alpha2~118^2~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=182f7513802bffb4ab3dd373eadb8f1a64012e22;p=thirdparty%2Fpdns.git Verify domain ownership GSQLBackend must ensure it checks that it won't return true for domains that it does not actually have any ownership for, if it does, it will block other backends from working. --- diff --git a/modules/gmysqlbackend/gmysqlbackend.cc b/modules/gmysqlbackend/gmysqlbackend.cc index 33173c1756..434ffcaa6b 100644 --- a/modules/gmysqlbackend/gmysqlbackend.cc +++ b/modules/gmysqlbackend/gmysqlbackend.cc @@ -129,6 +129,7 @@ public: declare(suffix, "delete-comments-query", "", "DELETE FROM comments WHERE domain_id=?"); declare(suffix, "search-records-query", "", record_query+" name LIKE ? OR content LIKE ? LIMIT ?"); declare(suffix, "search-comments-query", "", "SELECT domain_id,name,type,modified_at,account,comment FROM comments WHERE name LIKE ? OR comment LIKE ? LIMIT ?"); + declare(suffix, "is-our-domain-query", "", "SELECT id FROM domains WHERE id = ? OR name = ?"); } DNSBackend *make(const string &suffix="") diff --git a/modules/godbcbackend/godbcbackend.cc b/modules/godbcbackend/godbcbackend.cc index c5d1811add..4d787046f3 100644 --- a/modules/godbcbackend/godbcbackend.cc +++ b/modules/godbcbackend/godbcbackend.cc @@ -130,6 +130,7 @@ public: declare(suffix, "delete-comments-query", "", "DELETE FROM comments WHERE domain_id=?"); declare(suffix, "search-records-query", "", record_query+" name LIKE ? OR content LIKE ? LIMIT ?"); declare(suffix, "search-comments-query", "", "SELECT domain_id,name,type,modified_at,account,comment FROM comments WHERE name LIKE ? OR comment LIKE ? LIMIT ?"); + declare(suffix, "is-our-domain-query", "", "SELECT id FROM domains WHERE id = ? OR name = ?"); } //! Constructs a new gODBCBackend object. diff --git a/modules/goraclebackend/goraclebackend.cc b/modules/goraclebackend/goraclebackend.cc index 88a5074977..5414a66afe 100644 --- a/modules/goraclebackend/goraclebackend.cc +++ b/modules/goraclebackend/goraclebackend.cc @@ -142,6 +142,7 @@ public: declare(suffix, "delete-comments-query", "", "DELETE FROM comments WHERE domain_id=:domain_id"); declare(suffix, "search-records-query", "", record_query+" name LIKE :value OR content LIKE :value2 LIMIT :limit"); declare(suffix, "search-comments-query", "", "SELECT domain_id,name,type,modified_at,account,comment FROM comments WHERE name LIKE :value OR comment LIKE :value2 LIMIT :limit"); + declare(suffix, "is-our-domain-query", "", "SELECT id FROM domains WHERE id = :id OR name = :zone"); } diff --git a/modules/gpgsqlbackend/gpgsqlbackend.cc b/modules/gpgsqlbackend/gpgsqlbackend.cc index 9f2b55472d..832f9a90fc 100644 --- a/modules/gpgsqlbackend/gpgsqlbackend.cc +++ b/modules/gpgsqlbackend/gpgsqlbackend.cc @@ -124,7 +124,7 @@ public: declare(suffix, "delete-comments-query", "", "DELETE FROM comments WHERE domain_id=$1"); declare(suffix, "search-records-query", "", record_query+" name LIKE $1 OR content LIKE $2 LIMIT $3"); declare(suffix, "search-comments-query", "", "SELECT domain_id,name,type,modified_at,account,comment FROM comments WHERE name LIKE $1 OR comment LIKE $2 LIMIT $3"); - + declare(suffix, "is-our-domain-query", "", "SELECT id FROM domains WHERE id = $1 OR name = $2"); } DNSBackend *make(const string &suffix="") diff --git a/modules/gsqlite3backend/gsqlite3backend.cc b/modules/gsqlite3backend/gsqlite3backend.cc index 888b399b55..a764d8eedc 100644 --- a/modules/gsqlite3backend/gsqlite3backend.cc +++ b/modules/gsqlite3backend/gsqlite3backend.cc @@ -140,6 +140,7 @@ public: declare(suffix, "delete-comments-query", "", "DELETE FROM comments WHERE domain_id=:domain_id"); declare(suffix, "search-records-query", "", record_query+" name LIKE :value OR content LIKE :value2 LIMIT :limit"); declare(suffix, "search-comments-query", "", "SELECT domain_id,name,type,modified_at,account,comment FROM comments WHERE name LIKE :value OR comment LIKE :value2 LIMIT :limit"); + declare(suffix, "is-our-domain-query", "", "SELECT id FROM domains WHERE id = :id OR name = :zone"); } //! Constructs a new gSQLite3Backend object. diff --git a/pdns/backends/gsql/gsqlbackend.cc b/pdns/backends/gsql/gsqlbackend.cc index 9d2c02e189..f396129486 100644 --- a/pdns/backends/gsql/gsqlbackend.cc +++ b/pdns/backends/gsql/gsqlbackend.cc @@ -129,6 +129,8 @@ GSQLBackend::GSQLBackend(const string &mode, const string &suffix) d_SearchRecordsQuery = getArg("search-records-query"); d_SearchCommentsQuery = getArg("search-comments-query"); + d_IsOurDomainQuery = getArg("is-our-domain-query"); + d_query_stmt = NULL; d_NoIdQuery_stmt = NULL; d_IdQuery_stmt = NULL; @@ -191,6 +193,7 @@ GSQLBackend::GSQLBackend(const string &mode, const string &suffix) d_DeleteCommentsQuery_stmt = NULL; d_SearchRecordsQuery_stmt = NULL; d_SearchCommentsQuery_stmt = NULL; + d_IsOurDomainQuery_stmt = NULL; } void GSQLBackend::setNotified(uint32_t domain_id, uint32_t serial) @@ -223,6 +226,8 @@ void GSQLBackend::setFresh(uint32_t domain_id) bool GSQLBackend::isMaster(const DNSName &domain, const string &ip) { + if (!isOurDomain(domain)) return false; + try { d_MasterOfDomainsZoneQuery_stmt-> bind("domain", domain)-> @@ -254,6 +259,8 @@ bool GSQLBackend::isMaster(const DNSName &domain, const string &ip) bool GSQLBackend::setMaster(const DNSName &domain, const string &ip) { + if (!isOurDomain(domain)) return false; + try { d_UpdateMasterOfZoneQuery_stmt-> bind("master", ip)-> @@ -269,6 +276,8 @@ bool GSQLBackend::setMaster(const DNSName &domain, const string &ip) bool GSQLBackend::setKind(const DNSName &domain, const DomainInfo::DomainKind kind) { + if (!isOurDomain(domain)) return false; + try { d_UpdateKindOfZoneQuery_stmt-> bind("kind", toUpper(DomainInfo::getKindString(kind)))-> @@ -284,6 +293,8 @@ bool GSQLBackend::setKind(const DNSName &domain, const DomainInfo::DomainKind ki bool GSQLBackend::setAccount(const DNSName &domain, const string &account) { + if (!isOurDomain(domain)) return false; + try { d_UpdateAccountOfZoneQuery_stmt-> bind("account", account)-> @@ -299,6 +310,8 @@ bool GSQLBackend::setAccount(const DNSName &domain, const string &account) bool GSQLBackend::getDomainInfo(const DNSName &domain, DomainInfo &di) { + if (!isOurDomain(domain)) return false; + /* fill DomainInfo from database info: id,name,master IP(s),last_check,notified_serial,type,account */ try { @@ -440,6 +453,7 @@ bool GSQLBackend::updateDNSSECOrderNameAndAuth(uint32_t domain_id, const DNSName { if(!d_dnssecQueries) return false; + if (!isOurDomain(DNSName(""), domain_id)) return false; if (!ordername.empty()) { if (qtype == QType::ANY) { @@ -503,6 +517,8 @@ bool GSQLBackend::updateDNSSECOrderNameAndAuth(uint32_t domain_id, const DNSName bool GSQLBackend::updateEmptyNonTerminals(uint32_t domain_id, const DNSName& zonename, set& insert, set& erase, bool remove) { + if (!isOurDomain(DNSName(""), domain_id)) return false; + if(remove) { try { d_removeEmptyNonTerminalsFromZoneQuery_stmt-> @@ -558,6 +574,8 @@ bool GSQLBackend::getBeforeAndAfterNamesAbsolute(uint32_t id, const string& qnam { if(!d_dnssecQueries) return false; + if (!isOurDomain(DNSName(""),id)) return false; + // cerr<<"gsql before/after called for id="< @@ -675,6 +694,7 @@ bool GSQLBackend::activateDomainKey(const DNSName& name, unsigned int id) { if(!d_dnssecQueries) return false; + if (!isOurDomain(name)) return false; try { d_ActivateDomainKeyQuery_stmt-> @@ -693,6 +713,7 @@ bool GSQLBackend::deactivateDomainKey(const DNSName& name, unsigned int id) { if(!d_dnssecQueries) return false; + if (!isOurDomain(name)) return false; try { d_DeactivateDomainKeyQuery_stmt-> @@ -711,6 +732,7 @@ bool GSQLBackend::removeDomainKey(const DNSName& name, unsigned int id) { if(!d_dnssecQueries) return false; + if (!isOurDomain(name)) return false; try { d_RemoveDomainKeyQuery_stmt-> @@ -820,6 +842,7 @@ bool GSQLBackend::getDomainKeys(const DNSName& name, unsigned int kind, std::vec { if(!d_dnssecQueries) return false; + if (!isOurDomain(name)) return false; try { d_ListDomainKeysQuery_stmt-> @@ -862,6 +885,8 @@ void GSQLBackend::alsoNotifies(const DNSName &domain, set *ips) bool GSQLBackend::getAllDomainMetadata(const DNSName& name, std::map >& meta) { + if (!isOurDomain(name)) return false; + try { d_GetAllDomainMetadataQuery_stmt-> bind("domain", name)-> @@ -919,6 +944,7 @@ bool GSQLBackend::setDomainMetadata(const DNSName& name, const std::string& kind { if(!d_dnssecQueries && isDnssecDomainMetadata(kind)) return false; + if (!isOurDomain(name)) return false; try { d_ClearDomainMetadataQuery_stmt-> @@ -990,6 +1016,8 @@ void GSQLBackend::lookup(const QType &qtype,const DNSName &qname, DNSPacket *pkt bool GSQLBackend::list(const DNSName &target, int domain_id, bool include_disabled) { + if (!isOurDomain(target, domain_id)) return false; + DLOG(L<<"GSQLBackend constructing handle for list of domain id '"< *domains, bool include_disabl bool GSQLBackend::replaceRRSet(uint32_t domain_id, const DNSName& qname, const QType& qt, const vector& rrset) { + if (!isOurDomain(DNSName(""), domain_id)) return false; + try { if (qt != QType::ANY) { d_DeleteRRSetQuery_stmt-> @@ -1318,6 +1349,8 @@ bool GSQLBackend::feedRecord(const DNSResourceRecord &r, string *ordername) bool GSQLBackend::feedEnts(int domain_id, map& nonterm) { + if (!isOurDomain(DNSName(""), domain_id)) return false; + for(const auto& nt: nonterm) { try { d_InsertEntQuery_stmt-> @@ -1338,6 +1371,7 @@ bool GSQLBackend::feedEnts3(int domain_id, const DNSName &domain, map=0 && !isOurDomain(DNSName(""), domain_id)) return false; + try { d_db->startTransaction(); if(domain_id >= 0) { @@ -1410,11 +1446,12 @@ bool GSQLBackend::abortTransaction() bool GSQLBackend::calculateSOASerial(const DNSName& domain, const SOAData& sd, time_t& serial) { + if (!isOurDomain(DNSName(""), sd.domain_id)) return false; if (d_ZoneLastChangeQuery.empty()) { // query not set => fall back to default impl return DNSBackend::calculateSOASerial(domain, sd, serial); } - + try { d_ZoneLastChangeQuery_stmt-> bind("domain_id", sd.domain_id)-> @@ -1438,6 +1475,8 @@ bool GSQLBackend::calculateSOASerial(const DNSName& domain, const SOAData& sd, t bool GSQLBackend::listComments(const uint32_t domain_id) { + if (!isOurDomain(DNSName(""), domain_id)) return false; + try { d_query_name = "list-comments-query"; d_query_stmt = d_ListCommentsQuery_stmt; @@ -1659,6 +1698,26 @@ void GSQLBackend::extractComment(const SSqlStatement::row_t& row, Comment& comme comment.content = row[5]; } +bool GSQLBackend::isOurDomain(const DNSName &zone, int domain_id) { + try { + d_IsOurDomainQuery_stmt-> + bind("id", domain_id)-> + bind("zone", zone)-> + execute()-> + getResult(d_result)-> + reset(); + + if (!d_result.empty()) { + d_result.clear(); + return true; + } + } catch (SSqlException &e) { + throw PDNSException("GSQLBackend unable to verify ownership of domain: "+e.txtReason()); + } + + return false; +} + SSqlStatement::~SSqlStatement() { // make sure vtable won't break } diff --git a/pdns/backends/gsql/gsqlbackend.hh b/pdns/backends/gsql/gsqlbackend.hh index 1029c42c9e..b0c511dcb3 100644 --- a/pdns/backends/gsql/gsqlbackend.hh +++ b/pdns/backends/gsql/gsqlbackend.hh @@ -92,6 +92,7 @@ public: d_DeleteCommentsQuery_stmt = d_db->prepare(d_DeleteCommentsQuery, 1); d_SearchRecordsQuery_stmt = d_db->prepare(d_SearchRecordsQuery, 3); d_SearchCommentsQuery_stmt = d_db->prepare(d_SearchCommentsQuery, 3); + d_IsOurDomainQuery_stmt = d_db->prepare(d_IsOurDomainQuery, 2); } } @@ -162,6 +163,7 @@ public: release(&d_DeleteCommentsQuery_stmt); release(&d_SearchRecordsQuery_stmt); release(&d_SearchCommentsQuery_stmt); + release(&d_IsOurDomainQuery_stmt); } void lookup(const QType &, const DNSName &qdomain, DNSPacket *p=0, int zoneId=-1); @@ -223,7 +225,7 @@ public: string directBackendCmd(const string &query); bool searchRecords(const string &pattern, int maxResults, vector& result); bool searchComments(const string &pattern, int maxResults, vector& result); - + bool isOurDomain(const DNSName &zone, int domain_id=-1); protected: string pattern2SQLPattern(const string& pattern); void extractRecord(const SSqlStatement::row_t& row, DNSResourceRecord& rr); @@ -311,6 +313,8 @@ private: string d_SearchRecordsQuery; string d_SearchCommentsQuery; + string d_IsOurDomainQuery; + SSqlStatement* d_query_stmt; SSqlStatement* d_NoIdQuery_stmt; @@ -374,7 +378,7 @@ private: SSqlStatement* d_DeleteCommentsQuery_stmt; SSqlStatement* d_SearchRecordsQuery_stmt; SSqlStatement* d_SearchCommentsQuery_stmt; - + SSqlStatement* d_IsOurDomainQuery_stmt; protected: bool d_dnssecQueries; };