* 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 <string>
MyDNSBackend::~MyDNSBackend() {
if (d_db)
- delete(d_db);
+ delete(d_db);
}
d_db->setLog(::arg().mustDo("query-logging"));
query = "select origin, minimum from "+d_soatable+" where id = ";
- ostringstream o;
- o<<zoneId;
- query+=o.str();
- query+= " and "+d_soawhere;
+ query+=itoa(zoneId);
+ if (!d_soawhere.empty())
+ query+= " and "+d_soawhere;
this->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] == '.')
};
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);
else
query+=name;
- query+=".' and "+d_soawhere;
+ query+=".'";
+ if (! d_soawhere.empty())
+ query += " and "+d_soawhere;
this->Query(query);
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;
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);
} else {
query = "select origin, minimum from "+d_soatable+" where id = ";
- ostringstream o;
- o<<zoneId;
- query+=o.str();
- query+= " and "+d_soawhere;
+ query+=zoneIdStr;
+ if (!d_soawhere.empty())
+ query+= " and "+d_soawhere;
this->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;
if (found) {
+
while (d_db->getRow(rrow)) {
L<<Logger::Warning<<backendName<<" Found more than one matching zone for: "+d_origin<<endl;
};
host=d_db->escape(host);
query = "select type, data, aux, ttl, zone from "+d_rrtable+" where zone = ";
- ostringstream o;
- o<<zoneId;
- query+=o.str();
+ query+= zoneIdStr;
query += " and (name = '"+host+"' or name = '"+sname+"')";
if(qtype.getCode()!=255) { // ANY
query+=" and type='";
query+=qtype.getName();
query+="'";
+
}
- query += " and "+d_rrwhere+" order by type,aux,data";
+ if (!d_rrwhere.empty())
+ query += " and "+d_rrwhere;
+
+
+ if (qtype.getCode() == 255) {
+ query += " union select 'SOA' as type, origin as data, '0' as aux, ttl, id as zone from "+d_soatable+" where id= " + zoneIdStr + " and origin = '"+qname+".'";
+ if (!d_soawhere.empty())
+ query += " and " + d_soawhere;
+ }
+ query += " order by type,aux,data";
this->Query(query);
rr.qname += ".";
rr.qname += d_origin; // Not fully qualified
}
+
}
if (rr.qtype.getCode() == QType::NS || rr.qtype.getCode()==QType::MX ||
rr.last_modified=0;
-
+
return true;
}
--- /dev/null
+--
+-- 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;
+