]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
Verify domain ownership
authorAki Tuomi <cmouse@cmouse.fi>
Sat, 26 Dec 2015 18:30:11 +0000 (20:30 +0200)
committerAki Tuomi <cmouse@cmouse.fi>
Sun, 27 Dec 2015 13:20:13 +0000 (15:20 +0200)
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.

modules/gmysqlbackend/gmysqlbackend.cc
modules/godbcbackend/godbcbackend.cc
modules/goraclebackend/goraclebackend.cc
modules/gpgsqlbackend/gpgsqlbackend.cc
modules/gsqlite3backend/gsqlite3backend.cc
pdns/backends/gsql/gsqlbackend.cc
pdns/backends/gsql/gsqlbackend.hh

index 33173c1756a0da7822f7d2f88c2558c1d916d08d..434ffcaa6bceccfd143ba314500046218250696e 100644 (file)
@@ -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="")
index c5d1811add11d6014fc5a7e1f3ef7bdf90551565..4d787046f31cafffbd9af9f44e0d824c8d44d49c 100644 (file)
@@ -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.
index 88a507497724f0b68a7fa6583fb54e87b69f40c4..5414a66afe1564de18b999d1d7ec2e4574668fd4 100644 (file)
@@ -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");
 
   }
 
index 9f2b55472d2149b15e3dd2a9e026b86f4cc966f7..832f9a90fc473258107ce83ec1cbe9fbb59a3f14 100644 (file)
@@ -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="")
index 888b399b5572f1275e0ea676cca7f421b677dd0f..a764d8eedc3df07932e46aff77a2fc5d2fc3ce8d 100644 (file)
@@ -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.
index 9d2c02e189a030bd5dd8f62aef7b5d5c31a40e2e..f3961294869bf24dfa4e44c18286080a5abc9c46 100644 (file)
@@ -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<DNSName>& insert, set<DNSName>& 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="<<id<<", qname='"<<qname<<"'"<<endl;
   after.clear();
 
@@ -655,6 +673,7 @@ int GSQLBackend::addDomainKey(const DNSName& name, const KeyData& key)
 {
   if(!d_dnssecQueries)
     return -1;
+  if (!isOurDomain(name)) return false;
 
   try {
     d_AddDomainKeyQuery_stmt->
@@ -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<string> *ips)
 
 bool GSQLBackend::getAllDomainMetadata(const DNSName& name, std::map<std::string, std::vector<std::string> >& 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 '"<<domain_id<<"'"<<endl);
 
   try {
@@ -1009,7 +1037,8 @@ bool GSQLBackend::list(const DNSName &target, int domain_id, bool include_disabl
 }
 
 bool GSQLBackend::listSubZone(const DNSName &zone, int domain_id) {
-  
+  if (!isOurDomain(DNSName(""), domain_id)) return false;
+
   string wildzone = "%." + stripDot(zone.toString());  // tolower()?
 
   try {
@@ -1222,6 +1251,8 @@ void GSQLBackend::getAllDomains(vector<DomainInfo> *domains, bool include_disabl
 
 bool GSQLBackend::replaceRRSet(uint32_t domain_id, const DNSName& qname, const QType& qt, const vector<DNSResourceRecord>& 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<DNSName,bool>& 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<DNSName,bo
 {
   if(!d_dnssecQueries)
       return false;
+  if (!isOurDomain(DNSName(""), domain_id)) return false;
 
   string ordername;
 
@@ -1370,6 +1404,8 @@ bool GSQLBackend::feedEnts3(int domain_id, const DNSName &domain, map<DNSName,bo
 
 bool GSQLBackend::startTransaction(const DNSName &domain, int domain_id)
 {
+  if (domain_id >=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 
 }
index 1029c42c9e4af4f44749dbf50e980ffdaf29f758..b0c511dcb3be86c3e86f15bc440082888804e4a0 100644 (file)
@@ -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<DNSResourceRecord>& result);
   bool searchComments(const string &pattern, int maxResults, vector<Comment>& 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;
 };