96
112
// suport wildcard searches
98
114
if (qname[0]!='%') {
99
query="select r.Content,r.TimeToLive,r.Priority,r.Type,r.ZoneId,r.Name,r.ChangeDate from Records r,Zones z where r.Name='";
115
query ="select r.Content,r.TimeToLive,r.Priority,r.Type,r.ZoneId,r.Name,r.ChangeDate ";
116
query +="from Records r left join Zones z on r.ZoneId = z.Id where r.Name='";
101
query="select r.Content,r.TimeToLive,r.Priority,r.Type,r.ZoneId,r.Name,r.ChangeDate from Records r,Zones z where r.Name like '";
118
query ="select r.Content,r.TimeToLive,r.Priority,r.Type,r.ZoneId,r.Name,r.ChangeDate ";
119
query +="from Records r left join Zones z on r.ZoneId = z.Id where r.Name like '";
104
122
if (qname.find_first_of("'\\")!=string::npos)
174
192
return theResult;
195
bool PdnsBackend::isMaster(const string &name, const string &ip)
197
bool theResult = false;
198
MYSQL_ROW theRow = NULL;
202
o << "select Master from Zones where Master != '' and Name='"<<sqlEscape(name)<<"'";
204
this->Query(o.str());
206
theRow = mysql_fetch_row(d_result);
218
void PdnsBackend::getUnfreshSlaveInfos(vector<DomainInfo>* unfreshDomains)
220
MYSQL_ROW theRow = NULL;
222
string o = "select Id,Name,Master,UNIX_TIMESTAMP(ChangeDate) from Zones where Master != ''";
226
vector<DomainInfo>allSlaves;
227
while((theRow = mysql_fetch_row(d_result)) != NULL) {
230
di.id = atol(theRow[0]);
232
stringtok(di.masters, theRow[2], ", \t");
233
di.last_check = atol(theRow[3]);
235
di.kind = DomainInfo::Slave;
236
allSlaves.push_back(di);
239
for(vector<DomainInfo>::iterator i=allSlaves.begin(); i!=allSlaves.end();i++) {
244
if((time_t)(i->last_check+sd.refresh) < time(0)) {
246
unfreshDomains->push_back(*i);
251
bool PdnsBackend::getDomainInfo(const string &domain, DomainInfo &di)
253
bool theResult = false;
254
MYSQL_ROW theRow = NULL;
255
vector<string> masters;
258
o << "select Id,Name,Master,UNIX_TIMESTAMP(ChangeDate) from Zones WHERE Name='" << sqlEscape(domain) << "'";
260
this->Query(o.str());
262
theRow = mysql_fetch_row(d_result);
265
di.id = atol(theRow[0]);
267
di.last_check = atol(theRow[3]);
270
/* We have to store record in local variabel... theRow[2] == NULL makes it empty in di.master = theRow[2]???? */
271
if(theRow[2] != NULL)
272
stringtok(masters, theRow[2], " ,\t");
276
di.kind = DomainInfo::Native;
283
if(!getSOA(domain,sd))
284
L<<Logger::Notice<<"No serial for '"<<domain<<"' found - zone is missing?"<<endl;
285
di.serial = sd.serial;
287
catch (AhuException &ae) {
288
L<<Logger::Error<<"Error retrieving serial for '"<<domain<<"': "<<ae.reason<<endl;
291
di.kind = DomainInfo::Slave;
292
di.masters = masters;
301
bool PdnsBackend::startTransaction(const string &qname, int domain_id)
304
o << "delete from Records where ZoneId=" << domain_id;
306
this->Execute("begin");
307
this->Execute(o.str());
314
bool PdnsBackend::feedRecord(const DNSResourceRecord &rr)
316
int qcode = rr.qtype.getCode();
318
/* Check max records to transfer except for SOA and NS records */
319
if((qcode != QType::SOA) && (qcode != QType::NS))
321
if (d_axfrcount == atol(arg()["pdns-"+d_suffix+"max-slave-records"].c_str()) - 1)
323
L<<Logger::Warning<<backendName<<" Maximal AXFR records reached: "<<arg()["pdns-"+d_suffix+"max-slave-records"]
324
<<". Skipping rest of records"<<endl;
327
if (d_axfrcount >= atol(arg()["pdns-"+d_suffix+"max-slave-records"].c_str())) {
331
d_axfrcount++; // increase AXFR count for pdns-max-slave-records
334
/* SOA is not be feeded into Records.. update serial instead */
335
if(qcode == QType::SOA)
337
string::size_type emailpos = rr.content.find(" ", 0) + 1;
338
string::size_type serialpos = rr.content.find(" ", emailpos) + 1;
339
string::size_type other = rr.content.find(" ", serialpos);
340
string serial = rr.content.substr(serialpos, other - serialpos);
343
q << "update Zones set Serial=" << serial << " where Id=" << rr.domain_id;
345
this->Execute(q.str());
351
o << "insert into Records (ZoneId, Name, Type, Content, TimeToLive, Priority, Flags, Active) values ("
352
<< rr.domain_id << ","
353
<< "'" << toLower(sqlEscape(rr.qname)).c_str() << "',"
354
<< "'" << sqlEscape(rr.qtype.getName()).c_str() << "',"
355
<< "'" << sqlEscape(rr.content).c_str() << "',"
357
<< rr.priority << ","
361
this->Execute(o.str());
366
bool PdnsBackend::commitTransaction()
368
this->Execute("commit");
375
bool PdnsBackend::abortTransaction()
377
this->Execute("rollback");
384
void PdnsBackend::setFresh(u_int32_t domain_id)
387
o << "update Zones set ChangeDate = NOW() where Id=" << domain_id;
389
this->Execute(o.str());
177
392
//! For the dynamic loader
178
393
DNSBackend *PdnsBackend::maker()
240
455
declare(suffix,"password","Pdns backend password to connect with","");
241
456
declare(suffix,"socket","Pdns backend socket to connect to","");
242
457
declare(suffix,"soa-refresh","Pdns SOA refresh in seconds","");
458
declare(suffix,"max-slave-records","Pdns backend maximal records to transfer", "100");
245
461
DNSBackend *make(const string &suffix="")