declare(suffix,"deactivate-domain-key-query","", "update cryptokeys set active=0 where domain_id=(select id from domains where name='%s') and cryptokeys.id=%d");
declare(suffix,"remove-domain-key-query","", "delete from cryptokeys where domain_id=(select id from domains where name='%s') and cryptokeys.id=%d");
declare(suffix,"get-tsig-key-query","", "select algorithm, secret from tsigkeys where name='%s'");
+
+ declare(suffix,"get-all-domains-query", "Retrieve all domains", "select records.domain_id, records.name, records.content, domains.type, domains.master, domains.notified_serial, domains.last_check from records, domains where records.domain_id=domains.id and records.type='SOA'");
}
DNSBackend *make(const string &suffix="")
declare(suffix,"deactivate-domain-key-query","", "update cryptokeys set active=false where domain_id=(select id from domains where name=E'%s') and cryptokeys.id=%d");
declare(suffix,"remove-domain-key-query","", "delete from cryptokeys where domain_id=(select id from domains where name=E'%s') and cryptokeys.id=%d");
declare(suffix,"get-tsig-key-query","", "select algorithm, secret from tsigkeys where name=E'%s'");
+
+ declare(suffix,"get-all-domains-query", "Retrieve all domains", "select records.domain_id, records.name, records.content, domains.type, domains.master, domains.notified_serial, domains.last_check from records, domains where records.domain_id=domains.id and records.type='SOA'");
}
DNSBackend *make(const string &suffix="")
declare(suffix,"deactivate-domain-key-query","", "update cryptokeys set active=0 where domain_id=(select id from domains where name='%s') and cryptokeys.id=%d");
declare(suffix,"remove-domain-key-query","", "delete from cryptokeys where domain_id=(select id from domains where name='%s') and cryptokeys.id=%d");
declare(suffix,"get-tsig-key-query","", "select algorithm, secret from tsigkeys where name='%s'");
+
+ declare(suffix,"get-all-domains-query", "Retrieve all domains", "select records.domain_id, records.name, records.content, domains.type, domains.master, domains.notified_serial, domains.last_check from records, domains where records.domain_id=domains.id and records.type='SOA'");
}
//! Constructs a new gSQLite3Backend object.
}
}
+void Bind2Backend::getAllDomains(vector<DomainInfo> *domains) {
+ SOAData soadata;
+
+ shared_ptr<State> state = getState();
+
+ for(id_zone_map_t::const_iterator i = state->id_zone_map.begin(); i != state->id_zone_map.end() ; ++i) {
+ soadata.db=(DNSBackend *)-1; // makes getSOA() skip the cache.
+ this->getSOA(i->second.d_name, soadata);
+ DomainInfo di;
+ di.id=i->first;
+ di.serial=soadata.serial;
+ di.zone=i->second.d_name;
+ di.last_check=i->second.d_lastcheck;
+ di.backend=this;
+ di.kind=i->second.d_masters.empty() ? DomainInfo::Master : DomainInfo::Slave; //TODO: what about Native?
+
+ domains->push_back(di);
+ }
+}
+
+
void Bind2Backend::getUnfreshSlaveInfos(vector<DomainInfo> *unfreshDomains)
{
shared_ptr<State> state = getState();
void lookup(const QType &, const string &qdomain, DNSPacket *p=0, int zoneId=-1);
bool list(const string &target, int id);
bool get(DNSResourceRecord &);
+ void getAllDomains(vector<DomainInfo> *domains);
static DNSBackend *maker();
static pthread_mutex_t s_startup_lock;
d_ZoneLastChangeQuery=getArg("zone-lastchange-query");
d_InfoOfAllMasterDomainsQuery=getArg("info-all-master-query");
d_DeleteZoneQuery=getArg("delete-zone-query");
+ d_getAllDomainsQuery=getArg("get-all-domains-query");
if (d_dnssecQueries)
{
return true;
}
+void GSQLBackend::getAllDomains(vector<DomainInfo> *domains)
+{
+ DLOG(L<<"GSQLBackend retrieving all domains."<<endl);
+
+ try {
+ d_db->doCommand(d_getAllDomainsQuery.c_str());
+ }
+ catch (SSqlException &e) {
+ throw AhuException("Database error trying to retrieve all domains:" + e.txtReason());
+ }
+
+ SSql::row_t row;
+ while (d_db->getRow(row)) {
+
+ DomainInfo di;
+ di.id = atol(row[0].c_str());
+ di.zone = row[1];
+
+ if (!row[4].empty()) {
+ stringtok(di.masters, row[4], " ,\t");
+ }
+ di.last_check=atol(row[6].c_str());
+
+ SOAData sd;
+ fillSOAData(row[2], sd);
+ di.serial = sd.serial;
+ if (!row[5].empty()) {
+ di.notified_serial = atol(row[5].c_str());
+ }
+
+ if (pdns_iequals(row[3], "MASTER"))
+ di.kind = DomainInfo::Master;
+ else if (pdns_iequals(row[3], "SLAVE"))
+ di.kind = DomainInfo::Slave;
+ else
+ di.kind = DomainInfo::Native;
+
+ di.backend = this;
+
+ domains->push_back(di);
+ }
+}
+
bool GSQLBackend::get(DNSResourceRecord &r)
{
// L << "GSQLBackend get() was called for "<<qtype.getName() << " record: ";
#include "../../namespaces.hh"
-/** The GSQLBackend is a DNSBackend that can answer DNS related questions. It looks up data
- in PostgreSQL */
+/*
+GSQLBackend is a generic backend used by other sql backends
+*/
class GSQLBackend : public DNSBackend
{
public:
void lookup(const QType &, const string &qdomain, DNSPacket *p=0, int zoneId=-1);
bool list(const string &target, int domain_id);
bool get(DNSResourceRecord &r);
+ void getAllDomains(vector<DomainInfo> *domains);
bool isMaster(const string &domain, const string &ip);
void alsoNotifies(const string &domain, set<string> *ips);
bool startTransaction(const string &domain, int domain_id=-1);
string d_DeactivateDomainKeyQuery;
string d_getTSIGKeyQuery;
+
+ string d_getAllDomainsQuery;
+
protected:
bool d_dnssecQueries;
};
virtual bool getDomainMetadata(const string& name, const std::string& kind, std::vector<std::string>& meta) { return false; }
virtual bool setDomainMetadata(const string& name, const std::string& kind, const std::vector<std::string>& meta) {return false;}
+ virtual void getAllDomains(vector<DomainInfo> *domains) { }
+
struct KeyData {
unsigned int id;
unsigned int flags;
</para>
</listitem>
</varlistentry>
+ <varlistentry>
+ <term>check-zone ZONE</term>
+ <listitem>
+ <para>
+ Check a zone for DNSSEC correctness. Main goals is to check if the auth flag is set correctly.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>check-all-zones</term>
+ <listitem>
+ <para>
+ Check all zones for DNSSEC correctness. Added in 3.1.
+ </para>
+ </listitem>
+ </varlistentry>
<varlistentry>
<term>deactivate-zone-key ZONE KEY-ID</term>
<listitem>
</listitem>
</varlistentry>
<varlistentry>
- <term>rectify-zone ZONE</term>
+ <term>rectify-zone ZONE [ZONE ..]</term>
<listitem>
<para>
Calculates the 'ordername' and 'auth' fields for a zone called ZONE so they comply with DNSSEC settings.
- Can be used to fix up migrated data. Can always safely be run, it does no harm.
+ Can be used to fix up migrated data. Can always safely be run, it does no harm. Multiple zones can be supplied.
</para>
</listitem>
</varlistentry>
+ <varlistentry>
+ <term>rectify-all-zones</term>
+ <listitem>
+ <para>
+ Do a rectify-zone for all the zones. Be careful when running this. Only
+ bind and gmysql backends are supported. Added in 3.1.
+ </para>
+ </listitem>
+ </varlistentry>
<varlistentry>
<term>remove-zone-key ZONE KEY-ID</term>
<listitem>
scoped_ptr<UeberBackend> B(new UeberBackend("default"));
bool doTransaction=true; // but see above
SOAData sd;
+ sd.db = (DNSBackend*)-1;
if(!B->getSOA(zone, sd)) {
cerr<<"No SOA known for '"<<zone<<"', is such a zone in the database?"<<endl;
sd.db->commitTransaction();
}
+void rectifyAllZones(DNSSECKeeper &dk)
+{
+ scoped_ptr<UeberBackend> B(new UeberBackend("default"));
+ vector<DomainInfo> domainInfo;
+
+ B->getAllDomains(&domainInfo);
+ BOOST_FOREACH(DomainInfo di, domainInfo) {
+ cerr<<"Rectifying "<<di.zone<<": ";
+ rectifyZone(dk, di.zone);
+ }
+ cout<<"Rectified "<<domainInfo.size()<<" zones."<<endl;
+}
+
int checkZone(DNSSECKeeper& dk, const std::string& zone)
{
scoped_ptr<UeberBackend> B(new UeberBackend("default"));
SOAData sd;
-
+ sd.db=(DNSBackend*)-1;
if(!B->getSOA(zone, sd)) {
cout<<"No SOA for zone '"<<zone<<"'"<<endl;
return -1;
return numerrors;
}
+int checkAllZones(DNSSECKeeper &dk)
+{
+ scoped_ptr<UeberBackend> B(new UeberBackend("default"));
+ vector<DomainInfo> domainInfo;
+
+ B->getAllDomains(&domainInfo);
+ int errors=0;
+ BOOST_FOREACH(DomainInfo di, domainInfo) {
+ if (checkZone(dk, di.zone) > 0) {
+ errors++;
+ }
+ }
+ cout<<"Checked "<<domainInfo.size()<<" zones, "<<errors<<" had errors."<<endl;
+ return 0;
+}
+
+
+
void testAlgorithms()
{
DNSCryptoKeyEngine::testAll();
cerr<<" [rsasha1|rsasha256|rsasha512|gost|ecdsa256|ecdsa384]\n";
cerr<<" Add a ZSK or KSK to zone and specify algo&bits\n";
cerr<<"check-zone ZONE Check a zone for correctness\n";
+ cerr<<"check-all-zones Check all zones for correctness\n";
cerr<<"create-bind-db FNAME Create DNSSEC db for BIND backend (bind-dnssec-db)\n";
cerr<<"deactivate-zone-key ZONE KEY-ID Deactivate the key with key id KEY-ID in ZONE\n";
cerr<<"disable-dnssec ZONE Deactivate all keys and unset PRESIGNED in ZONE\n";
cerr<<"import-zone-key ZONE FILE Import from a file a private key, ZSK or KSK\n";
cerr<<" [ksk|zsk] Defaults to KSK\n";
cerr<<"rectify-zone ZONE [ZONE ..] Fix up DNSSEC fields (order, auth)\n";
+ cerr<<"rectify-all-zones Rectify all zones.\n";
cerr<<"remove-zone-key ZONE KEY-ID Remove key with KEY-ID from ZONE\n";
cerr<<"secure-zone ZONE [ZONE ..] Add KSK and two ZSKs\n";
cerr<<"set-nsec3 ZONE 'params' [narrow] Enable NSEC3 with PARAMs. Optionally narrow\n";
for(unsigned int n = 1; n < cmds.size(); ++n)
rectifyZone(dk, cmds[n]);
}
+ else if (cmds[0] == "rectify-all-zones") {
+ rectifyAllZones(dk);
+ }
else if(cmds[0] == "check-zone") {
if(cmds.size() != 2) {
cerr << "Syntax: pdnssec check-zone ZONE"<<endl;
}
exit(checkZone(dk, cmds[1]));
}
+ else if (cmds[0] == "check-all-zones") {
+ exit(checkAllZones(dk));
+ }
#if 0
else if(cmds[0] == "signing-server" )
{
}
vector<string> mustRectify;
dk.startTransaction();
+ unsigned int zoneErrors=0;
for(unsigned int n = 1; n < cmds.size(); ++n) {
const string& zone=cmds[n];
if(secureZone(dk, zone)) {
mustRectify.push_back(zone);
+ } else {
+ zoneErrors++;
}
}
dk.commitTransaction();
BOOST_FOREACH(string& zone, mustRectify)
rectifyZone(dk, zone);
+
+ if (zoneErrors) {
+ return 1;
+ }
+ return 0;
}
else if(cmds[0]=="set-nsec3") {
if(cmds.size() < 2) {
d_handle.parent=this;
}
+void UeberBackend::getAllDomains(vector<DomainInfo> *domains) {
+ for (vector<DNSBackend*>::iterator i = backends.begin(); i != backends.end(); ++i )
+ {
+ (*i)->getAllDomains(domains);
+ }
+}
+
bool UeberBackend::get(DNSResourceRecord &rr)
{
if(d_negcached) {
bool getSOA(const string &domain, SOAData &sd, DNSPacket *p=0);
bool list(const string &target, int domain_id);
bool get(DNSResourceRecord &r);
+ void getAllDomains(vector<DomainInfo> *domains);
static DNSBackend *maker(const map<string,string> &);
static void closeDynListener();