]> granicus.if.org Git - pdns/commitdiff
Various pdnssec improvements, submitted by Ruben d'Arco:
authorPeter van Dijk <peter.van.dijk@netherlabs.nl>
Mon, 5 Mar 2012 09:17:35 +0000 (09:17 +0000)
committerPeter van Dijk <peter.van.dijk@netherlabs.nl>
Mon, 5 Mar 2012 09:17:35 +0000 (09:17 +0000)
- documentation updates
- check-all-zones and rectify-all-zones
- other minor fixes

*-all-zones have been tested for bindbackend and mysqlbackend, not for sqlite and pg

git-svn-id: svn://svn.powerdns.com/pdns/trunk/pdns@2467 d19b8d6e-7fed-0310-83ef-9ca221ded41b

12 files changed:
modules/gmysqlbackend/gmysqlbackend.cc
modules/gpgsqlbackend/gpgsqlbackend.cc
modules/gsqlite3backend/gsqlite3backend.cc
pdns/backends/bind/bindbackend2.cc
pdns/backends/bind/bindbackend2.hh
pdns/backends/gsql/gsqlbackend.cc
pdns/backends/gsql/gsqlbackend.hh
pdns/dnsbackend.hh
pdns/docs/pdns.xml
pdns/pdnssec.cc
pdns/ueberbackend.cc
pdns/ueberbackend.hh

index a1d7543bb0b7279b678529c1741e665e9f981ed1..0eaba8367450a29be634cc6f1d530a171d1efbf8 100644 (file)
@@ -107,6 +107,8 @@ public:
     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="")
index 5d24595a1ebc506ca5ce9f263050a7ad107af02b..c33eb257780a11d8911e06f814ff1304465ba641 100644 (file)
@@ -106,6 +106,8 @@ public:
     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="")
index 5bdc3428bc35b2b93ac25e841790289361cb75ab..c078853cf36e364d6bd1954381a3b2f65a380e26 100644 (file)
@@ -116,6 +116,8 @@ public:
     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.
index d400b02a65a25cae63c23ffa312c83d567f2687b..3f7369f37c04e9c7e11a9f15dd7b5501e6d144ef 100644 (file)
@@ -296,6 +296,27 @@ void Bind2Backend::getUpdatedMasters(vector<DomainInfo> *changedDomains)
   }
 }
 
+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();
index c5b4d6dc3d735d5691112038d53fba121f8d3ba3..617fa011bc7128f35daac1e503d70b1154025248 100644 (file)
@@ -136,6 +136,7 @@ public:
   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;
index 37f25bb53bcf88b55993be41de48548176711b32..0e500bd09325df1d9414211189530debb57b4088 100644 (file)
@@ -278,6 +278,7 @@ GSQLBackend::GSQLBackend(const string &mode, const string &suffix)
   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)
   {
@@ -674,6 +675,49 @@ bool GSQLBackend::createSlaveDomain(const string &ip, const string &domain, cons
   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: ";
index 6a3638db17bfe2631401a50973df274ecffcac72..cdc328a0cb42ff1cdf6687d0daa46868154e785c 100644 (file)
@@ -4,8 +4,9 @@
 
 #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:
@@ -25,6 +26,7 @@ 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);
@@ -101,6 +103,9 @@ private:
   string d_DeactivateDomainKeyQuery;
   
   string d_getTSIGKeyQuery;
+
+  string d_getAllDomainsQuery;
+
 protected:  
   bool d_dnssecQueries;
 };
index 718e12afa9c91f5ba878152e0451ac20ae230339..3dc8210256d63f3a0329a9b98768bc15cb9ab588 100644 (file)
@@ -100,6 +100,8 @@ public:
   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;
index 7b0ed1c952b813b7ad6e0e66f81036cb86217a93..74f5707d9e4c38a33c24b4efa94d610209d4b6c0 100644 (file)
@@ -10689,6 +10689,22 @@ $ pdnssec rectify-zone powerdnssec.org
              </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>
@@ -10745,14 +10761,23 @@ $ pdnssec rectify-zone powerdnssec.org
            </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>
index 8474f2e59f53b02172637b32d412b0eaac7858c0..d9da6785c3a2a474d691a42e44b7a7c1f5c75578 100644 (file)
@@ -100,6 +100,7 @@ void rectifyZone(DNSSECKeeper& dk, const std::string& zone)
   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;
@@ -155,11 +156,24 @@ void rectifyZone(DNSSECKeeper& dk, const std::string& zone)
     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;
@@ -197,6 +211,24 @@ int checkZone(DNSSECKeeper& dk, const std::string& zone)
   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();
@@ -434,6 +466,7 @@ try
     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";
@@ -443,6 +476,7 @@ try
     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";
@@ -489,6 +523,9 @@ try
     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;
@@ -496,6 +533,9 @@ try
     }
     exit(checkZone(dk, cmds[1]));
   }
+  else if (cmds[0] == "check-all-zones") {
+    exit(checkAllZones(dk));
+  }
 #if 0
   else if(cmds[0] == "signing-server" )
   {
@@ -611,16 +651,24 @@ try
     }
     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) {
index 1b81dfdd2290fa48eacdf9a69deccad783820dd3..8c908ccfabf6b42a163c75e38572a55399b2d4b0 100644 (file)
@@ -435,6 +435,13 @@ void UeberBackend::lookup(const QType &qtype,const string &qname, DNSPacket *pkt
   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) {
index ea8dfbb749d5ac3d1d7d587b0f7f7c9305a044b9..3f82abe9d7cdfc3fbb657b05913aa045603309e8 100644 (file)
@@ -115,6 +115,7 @@ public:
   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();