From 13b17e886c41fbe39e6fd4b6247aeabb1d191eca Mon Sep 17 00:00:00 2001 From: Bert Hubert Date: Thu, 4 Oct 2012 08:14:04 +0000 Subject: [PATCH] make sure that 'any' queries to mydnsbackend also respond with the SOA record. Plus add helpful schema. Code from ticket 439 (by peter). git-svn-id: svn://svn.powerdns.com/pdns/trunk/pdns@2751 d19b8d6e-7fed-0310-83ef-9ca221ded41b --- modules/mydnsbackend/mydnsbackend.cc | 61 +++++++++++++++++----------- modules/mydnsbackend/schema.sql | 41 +++++++++++++++++++ 2 files changed, 79 insertions(+), 23 deletions(-) create mode 100644 modules/mydnsbackend/schema.sql diff --git a/modules/mydnsbackend/mydnsbackend.cc b/modules/mydnsbackend/mydnsbackend.cc index 7825d22a05..18ee7bdf41 100644 --- a/modules/mydnsbackend/mydnsbackend.cc +++ b/modules/mydnsbackend/mydnsbackend.cc @@ -16,6 +16,7 @@ * for even simple lookups is daft. It's quite trivial to craft a request * that'll require 128 database queries to answer with a servfail! * + * If you do not know what mydns is: http://mydns.bboy.net/ */ #include @@ -66,7 +67,7 @@ MyDNSBackend::MyDNSBackend(const string &suffix) { MyDNSBackend::~MyDNSBackend() { if (d_db) - delete(d_db); + delete(d_db); } @@ -86,17 +87,14 @@ bool MyDNSBackend::list(const string &target, int zoneId) { d_db->setLog(::arg().mustDo("query-logging")); query = "select origin, minimum from "+d_soatable+" where id = "; - ostringstream o; - o<Query(query); - if(!d_db->getRow(rrow)) { - // No such zone - return false; - } + if(!d_db->getRow(rrow)) + return false; // No such zone d_origin = rrow[0]; if (d_origin[d_origin.length()-1] == '.') @@ -108,8 +106,10 @@ bool MyDNSBackend::list(const string &target, int zoneId) { }; query = "select type, data, aux, ttl, zone, name from "+d_rrtable+" where zone = "; - query+=o.str(); - query += " and "+d_rrwhere; + query+=itoa(zoneId); + if (!d_rrwhere.empty()) + query += " and "+d_rrwhere; + this->Query(query); @@ -134,7 +134,9 @@ bool MyDNSBackend::getSOA(const string& name, SOAData& soadata, DNSPacket*) { else query+=name; - query+=".' and "+d_soawhere; + query+=".'"; + if (! d_soawhere.empty()) + query += " and "+d_soawhere; this->Query(query); @@ -166,6 +168,7 @@ bool MyDNSBackend::getSOA(const string& name, SOAData& soadata, DNSPacket*) { void MyDNSBackend::lookup(const QType &qtype, const string &qname, DNSPacket *p, int zoneId) { string query; string sname; + string zoneIdStr = itoa(zoneId); SSql::row_t rrow; bool found = false; @@ -193,11 +196,14 @@ void MyDNSBackend::lookup(const QType &qtype, const string &qname, DNSPacket *p, pos = 0; sdom = sname; while (!sdom.empty() && pos != string::npos) { - query = "select id, origin, minimum from "+d_soatable+" where origin = '"+sdom+"' and "+d_soawhere; + query = "select id, origin, minimum from "+d_soatable+" where origin = '"+sdom+"'"; + if (!d_soawhere.empty()) + query += " and "+d_soawhere; this->Query(query); if(d_db->getRow(rrow)) { zoneId = atol(rrow[0].c_str()); + zoneIdStr=rrow[0]; d_origin = rrow[1]; if (d_origin[d_origin.length()-1] == '.') d_origin.erase(d_origin.length()-1); @@ -212,15 +218,14 @@ void MyDNSBackend::lookup(const QType &qtype, const string &qname, DNSPacket *p, } else { query = "select origin, minimum from "+d_soatable+" where id = "; - ostringstream o; - o<Query(query); if(!d_db->getRow(rrow)) { - throw AhuException("lookup() passed zoneId = "+o.str()+" but no such zone!"); + throw AhuException("lookup() passed zoneId = "+zoneIdStr+" but no such zone!"); } found = true; @@ -232,6 +237,7 @@ void MyDNSBackend::lookup(const QType &qtype, const string &qname, DNSPacket *p, if (found) { + while (d_db->getRow(rrow)) { L<escape(host); query = "select type, data, aux, ttl, zone from "+d_rrtable+" where zone = "; - ostringstream o; - o<Query(query); @@ -294,6 +308,7 @@ bool MyDNSBackend::get(DNSResourceRecord &rr) { rr.qname += "."; rr.qname += d_origin; // Not fully qualified } + } if (rr.qtype.getCode() == QType::NS || rr.qtype.getCode()==QType::MX || @@ -315,7 +330,7 @@ bool MyDNSBackend::get(DNSResourceRecord &rr) { rr.last_modified=0; - + return true; } diff --git a/modules/mydnsbackend/schema.sql b/modules/mydnsbackend/schema.sql new file mode 100644 index 0000000000..710e6ffb9f --- /dev/null +++ b/modules/mydnsbackend/schema.sql @@ -0,0 +1,41 @@ +-- +-- Table layouts for mydns 1.1.0 (Mar 2012) +-- Copyright (C) 2002-2005 Don Moore +-- +-- You might create these tables with a command like: +-- +-- $ mydns --create-tables | mysql -hHOST -p -uUSER DATABASE +-- +-- + +-- +-- Table structure for table 'soa' (zones of authority) +-- +CREATE TABLE IF NOT EXISTS soa ( + id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, + origin CHAR(255) NOT NULL, + ns CHAR(255) NOT NULL, + mbox CHAR(255) NOT NULL, + serial INT UNSIGNED NOT NULL default '1', + refresh INT UNSIGNED NOT NULL default '28800', + retry INT UNSIGNED NOT NULL default '7200', + expire INT UNSIGNED NOT NULL default '604800', + minimum INT UNSIGNED NOT NULL default '86400', + ttl INT UNSIGNED NOT NULL default '86400', + UNIQUE KEY (origin) +) TYPE=MyISAM; + +-- +-- Table structure for table 'rr' (resource records) +-- +CREATE TABLE IF NOT EXISTS rr ( + id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, + zone INT UNSIGNED NOT NULL, + name CHAR(64) NOT NULL, + type ENUM('A','AAAA','CNAME','HINFO','MX','NAPTR','NS','PTR','RP','SRV','TXT'), + data CHAR(128) NOT NULL, + aux INT UNSIGNED NOT NULL, + ttl INT UNSIGNED NOT NULL default '86400', + UNIQUE KEY rr (zone,name,type,data) +) TYPE=MyISAM; + -- 2.47.3