]> granicus.if.org Git - pdns/commitdiff
this commit implements a DNSSEC metadata store for the BIND backend. To make
authorBert Hubert <bert.hubert@netherlabs.nl>
Sun, 4 Mar 2012 11:25:26 +0000 (11:25 +0000)
committerBert Hubert <bert.hubert@netherlabs.nl>
Sun, 4 Mar 2012 11:25:26 +0000 (11:25 +0000)
this possible, it has been necessary to define a 'metadata only' mode for
backends, because otherwise every invocation of 'pdnssec' would load all
BIND zones (of which there could be millions).

In turn to make this possible, we have had to teach the BIND backend not to
rely on the DNSSECKeeper anymore, since that would setup a circular
dependency. This means that the BIND backend, when it needs to ask a DNSSEC
metadata-related question, only asks itself. In other words, it will no
longer get DNSSEC related metadata from other backends.

To benefit from the built in DNSSEC store, set
'bind-dnssec-db=/etc/bind/dnssec.sqlite3', issue pdnssec create-bind-db, and
you are in business!

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

pdns/Makefile.am
pdns/backends/bind/Makefile.am
pdns/backends/bind/bindbackend2.cc
pdns/backends/bind/bindbackend2.hh
pdns/backends/bind/binddnssec.cc [new file with mode: 0644]
pdns/bind-dnssec.schema.sqlite3.sql
pdns/dbdnsseckeeper.cc
pdns/dnsbackend.cc
pdns/dnsbackend.hh
pdns/pdnssec.cc

index 672ffe687eecaff566360045548b0acd8f40dcf5..890bff7c1d72b319aad677db17e436c6cad1470f 100644 (file)
@@ -1,7 +1,8 @@
 AM_CXXFLAGS=-DSYSCONFDIR=\"@sysconfdir@\" -DLIBDIR=\"@libdir@\" -DLOCALSTATEDIR=\"@socketdir@\" -Ibackends/bind @THREADFLAGS@ $(LUA_CFLAGS) -Iext/polarssl-1.1.1/include
 AM_CPPFLAGS=-Ibackends/bind $(BOOST_CPPFLAGS) @THREADFLAGS@
 
-EXTRA_DIST = dnslabeltext.rl dnslabeltext.cc mtasker.cc inflighter.cc docs/pdns_control.8  docs/pdns_server.8 docs/zone2sql.8 docs/zone2ldap.8 docs/pdnssec.8
+EXTRA_DIST = dnslabeltext.rl dnslabeltext.cc mtasker.cc inflighter.cc docs/pdns_control.8  \
+       docs/pdns_server.8 docs/zone2sql.8 docs/zone2ldap.8 docs/pdnssec.8
 
 SUBDIRS= ext/polarssl-1.1.1 backends 
 
@@ -30,7 +31,7 @@ dynlistener.cc dynlistener.hh  dynhandler.cc dynhandler.hh  \
 resolver.hh resolver.cc slavecommunicator.cc mastercommunicator.cc communicator.cc communicator.hh dnsproxy.cc \
 dnsproxy.hh randombackend.cc unix_utility.cc common_startup.cc \
 utility.hh iputils.hh common_startup.hh unix_semaphore.cc \
-backends/bind/bindbackend2.cc  \
+backends/bind/bindbackend2.cc  backends/bind/binddnssec.cc \
 backends/bind/bindparser.cc backends/bind/bindlexer.c \
 backends/gsql/gsqlbackend.cc \
 backends/gsql/gsqlbackend.hh backends/gsql/ssql.hh \
@@ -69,12 +70,15 @@ pdnssec_SOURCES=pdnssec.cc dbdnsseckeeper.cc sstuff.hh dnsparser.cc dnsparser.hh
         misc.cc misc.hh rcpgenerator.cc rcpgenerator.hh base64.cc base64.hh unix_utility.cc \
        logger.cc statbag.cc qtype.cc sillyrecords.cc nsecrecords.cc dnssecinfra.cc dnssecinfra.hh \
         base32.cc  ueberbackend.cc dnsbackend.cc arguments.cc packetcache.cc dnspacket.cc  \
-        backends/bind/bindbackend2.cc  \
+        backends/bind/bindbackend2.cc backends/bind/binddnssec.cc  \
        backends/bind/bindparser.cc backends/bind/bindlexer.c \
        backends/gsql/gsqlbackend.cc \
        backends/gsql/gsqlbackend.hh backends/gsql/ssql.hh zoneparser-tng.cc \
        dynlistener.cc dns.cc randombackend.cc dnssecsigner.cc polarrsakeyinfra.cc md5.cc \
-       signingpipe.cc dnslabeltext.cc ednssubnet.cc cachecleaner.hh
+       signingpipe.cc dnslabeltext.cc ednssubnet.cc cachecleaner.hh bind-dnssec.schema.sqlite3.sql.h
+
+bind-dnssec.schema.sqlite3.sql.h: bind-dnssec.schema.sqlite3.sql
+       ( echo 'static char sqlCreate[]=' ; sed 's/$$/"/g' bind-dnssec.schema.sqlite3.sql | sed 's/^/"/g'  ; echo ';' ) > $@
 
 pdnssec_LDFLAGS=@moduleobjects@ @modulelibs@ @DYNLINKFLAGS@ @LIBDL@ @THREADFLAGS@  $(BOOST_PROGRAM_OPTIONS_LDFLAGS) $(BOOST_SERIALIZATION_LDFLAGS)
 pdnssec_LDADD= ext/polarssl-1.1.1/library/libpolarssl.a $(BOOST_PROGRAM_OPTIONS_LIBS) $(BOOST_SERIALIZATION_LIBS)
index ff667f25731621f3a193868ed110963178a296cc..4eff43c29a8fa77486398695674b949797c2f1a1 100644 (file)
@@ -4,7 +4,7 @@ AM_CPPFLAGS=$(BOOST_CPPFLAGS) @THREADFLAGS@
 
 libbind2backend_la_SOURCES=bindbackend2.cc bindbackend2.hh bindparser.yy \
 bindlexer.l ../../zoneparser-tng.cc ../../misc.cc  \
-bindparser.hh ../../unix_utility.cc
+bindparser.hh ../../unix_utility.cc binddnssec.cc
 
 libbind2backend_la_CXXFLAGS=$(AM_CXXFLAGS)
 libbind2backend_la_CFLAGS=$(AM_CFLAGS)
index 69cc253c0f9501b4b3d5c623038ae7b66b4ae174..aaf5eb4df7462a2354079702d8e3a86fd25ef83c 100644 (file)
@@ -83,6 +83,7 @@ pthread_mutex_t Bind2Backend::s_state_swap_lock=PTHREAD_MUTEX_INITIALIZER;
 string Bind2Backend::s_binddirectory;  
 /* when a query comes in, we find the most appropriate zone and answer from that */
 
+
 BB2DomainInfo::BB2DomainInfo()
 {
   d_loaded=false;
@@ -449,8 +450,8 @@ string Bind2Backend::DLReloadNowHandler(const vector<string>&parts, Utility::pid
   for(vector<string>::const_iterator i=parts.begin()+1;i<parts.end();++i) {
     if(state->name_id_map.count(*i)) {
       BB2DomainInfo& bbd=state->id_zone_map[state->name_id_map[*i]];
-      
-      queueReload(&bbd);
+      Bind2Backend bb2;
+      bb2.queueReload(&bbd);
       ret<< *i << ": "<< (bbd.d_loaded ? "": "[rejected]") <<"\t"<<bbd.d_status<<"\n";      
     }
     else
@@ -500,7 +501,7 @@ string Bind2Backend::DLListRejectsHandler(const vector<string>&parts, Utility::p
   return ret.str();
 }
 
-Bind2Backend::Bind2Backend(const string &suffix)
+Bind2Backend::Bind2Backend(const string &suffix, bool loadZones)
 {
 #if __GNUC__ >= 3
     std::ios_base::sync_with_stdio(false);
@@ -508,15 +509,19 @@ Bind2Backend::Bind2Backend(const string &suffix)
   d_logprefix="[bind"+suffix+"backend]";
   setArgPrefix("bind"+suffix);
   Lock l(&s_startup_lock);
-
+  
   d_transaction_id=0;
+  setupDNSSEC();
   if(!s_first) {
     return;
   }
-  s_first=0;
+  
   s_state = shared_ptr<State>(new State);
-  loadConfig();
-
+  if(loadZones) {
+    loadConfig();
+    s_first=0;
+  }
+  
   extern DynListener *dl;
   dl->registerFunc("BIND-RELOAD-NOW", &DLReloadNowHandler);
   dl->registerFunc("BIND-DOMAIN-STATUS", &DLDomStatusHandler);
@@ -618,7 +623,6 @@ void Bind2Backend::loadConfig(string* status)
     }
 
     sort(domains.begin(), domains.end()); // put stuff in inode order
-    DNSSECKeeper dk;
     for(vector<BindDomainInfo>::const_iterator i=domains.begin();
         i!=domains.end();
         ++i) 
@@ -660,7 +664,7 @@ void Bind2Backend::loadConfig(string* status)
           L<<Logger::Info<<d_logprefix<<" parsing '"<<i->name<<"' from file '"<<i->filename<<"'"<<endl;
 
           NSEC3PARAMRecordContent ns3pr;
-          bool nsec3zone=dk.getNSEC3PARAM(i->name, &ns3pr);
+          bool nsec3zone=getNSEC3PARAM(i->name, &ns3pr);
         
           try {
             // we need to allocate a new vector so we don't kill the original, which is still in use!
@@ -790,9 +794,8 @@ void Bind2Backend::queueReload(BB2DomainInfo *bbd)
     ZoneParserTNG zpt(bbd->d_filename, bbd->d_name, s_binddirectory);
     DNSResourceRecord rr;
     string hashed;
-    DNSSECKeeper dk;
     NSEC3PARAMRecordContent ns3pr;
-    bool nsec3zone=dk.getNSEC3PARAM(bbd->d_name, &ns3pr);
+    bool nsec3zone=getNSEC3PARAM(bbd->d_name, &ns3pr);
     while(zpt.get(rr)) {
       if(nsec3zone)
         hashed=toLower(toBase32Hex(hashQNameWithSalt(ns3pr.d_iterations, ns3pr.d_salt, rr.qname)));
@@ -862,11 +865,10 @@ bool Bind2Backend::getBeforeAndAfterNamesAbsolute(uint32_t id, const std::string
 {
   shared_ptr<State> state = s_state;
   BB2DomainInfo& bbd = state->id_zone_map[id];  
-  DNSSECKeeper dk;
   NSEC3PARAMRecordContent ns3pr;
   string auth=state->id_zone_map[id].d_name;
     
-  if(!dk.getNSEC3PARAM(auth, &ns3pr)) {
+  if(!getNSEC3PARAM(auth, &ns3pr)) {
     //cerr<<"in bind2backend::getBeforeAndAfterAbsolute: no nsec3 for "<<auth<<endl;
     return findBeforeAndAfterUnhashed(bbd, qname, unhashed, before, after);
   
@@ -1066,8 +1068,8 @@ bool Bind2Backend::handle::get_normal(DNSResourceRecord &r)
   r.ttl=(d_iter)->ttl;
   r.priority=(d_iter)->priority;
 
-  if(!d_iter->auth && r.qtype.getCode() != QType::A && r.qtype.getCode()!=QType::AAAA && r.qtype.getCode() != QType::NS)
-    cerr<<"Warning! Unauth response!"<<endl;
+  //if(!d_iter->auth && r.qtype.getCode() != QType::A && r.qtype.getCode()!=QType::AAAA && r.qtype.getCode() != QType::NS)
+  //  cerr<<"Warning! Unauth response for qtype "<< r.qtype.getName() << " for '"<<r.qname<<"'"<<endl;
   r.auth = d_iter->auth;
 
   d_iter++;
@@ -1221,12 +1223,19 @@ class Bind2Factory : public BackendFactory
          declare(suffix,"supermaster-config","Location of (part of) named.conf where pdns can write zone-statements to","");
          declare(suffix,"supermasters","List of IP-addresses of supermasters","");
          declare(suffix,"supermaster-destdir","Destination directory for newly added slave zones",::arg()["config-dir"]);
+         declare(suffix,"dnssec-db","Filename to store & access our DNSSEC metadatabase, empty for none", "");
       }
 
       DNSBackend *make(const string &suffix="")
       {
          return new Bind2Backend(suffix);
       }
+      
+      DNSBackend *makeMetadataOnly(const string &suffix="")
+      {
+        return new Bind2Backend(suffix, false);
+      }
+
 };
 
 //! Magic class that is activated when the dynamic library is loaded
index dde2cfc4d3178bd6a13ac156709c6b71b8226d1c..de1b77ce96e5e14420a332afdde318fac9dbe3bb 100644 (file)
@@ -1,6 +1,6 @@
 /*
     PowerDNS Versatile Database Driven Nameserver
-    Copyright (C) 2002-2010  PowerDNS.COM BV
+    Copyright (C) 2002-2012  PowerDNS.COM BV
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License version 2 as 
@@ -33,6 +33,7 @@
 #include <sys/stat.h>
 #include <unistd.h>
 #include "misc.hh"
+#include "dnsbackend.hh"
 
 #include "namespaces.hh"
 using namespace ::boost::multi_index;
@@ -118,15 +119,19 @@ private:
   time_t d_checkinterval;
 };
 
+class SSQLite3;
+class NSEC3PARAMRecordContent;
+
 class Bind2Backend : public DNSBackend
 {
 public:
-  Bind2Backend(const string &suffix=""); //!< Makes our connection to the database. Calls exit(1) if it fails.
+  Bind2Backend(const string &suffix="", bool loadZones=true); 
   ~Bind2Backend();
   void getUnfreshSlaveInfos(vector<DomainInfo> *unfreshDomains);
   void getUpdatedMasters(vector<DomainInfo> *changedDomains);
   bool getDomainInfo(const string &domain, DomainInfo &di);
   time_t getCtime(const string &fname);
+  // DNSSEC
   virtual bool getBeforeAndAfterNamesAbsolute(uint32_t id, const std::string& qname, std::string& unhashed, std::string& before, std::string& after);
   void lookup(const QType &, const string &qdomain, DNSPacket *p=0, int zoneId=-1);
   bool list(const string &target, int id);
@@ -145,6 +150,19 @@ public:
   bool updateDNSSECOrderAndAuthAbsolute(uint32_t domain_id, const std::string& qname, const std::string& ordername, bool auth);
   void alsoNotifies(const string &domain, set<string> *ips);
 
+// the DNSSEC related (getDomainMetadata has broader uses too)
+  virtual bool getDomainMetadata(const string& name, const std::string& kind, std::vector<std::string>& meta);
+  virtual bool setDomainMetadata(const string& name, const std::string& kind, const std::vector<std::string>& meta);
+  virtual bool getDomainKeys(const string& name, unsigned int kind, std::vector<KeyData>& keys);
+  virtual bool removeDomainKey(const string& name, unsigned int id);
+  virtual int addDomainKey(const string& name, const KeyData& key);
+  virtual bool activateDomainKey(const string& name, unsigned int id);
+  virtual bool deactivateDomainKey(const string& name, unsigned int id);
+  virtual bool getTSIGKey(const string& name, string* algorithm, string* content);
+  void createDNSSECDB(const string& fname="");
+  // end of DNSSEC 
+
+
   typedef map<string, int, CIStringCompare> name_id_map_t;
   typedef map<uint32_t, BB2DomainInfo> id_zone_map_t;
 
@@ -164,6 +182,9 @@ public:
   bool createSlaveDomain(const string &ip, const string &domain, const string &account);
   
 private:
+  void setupDNSSEC();
+  shared_ptr<SSQLite3> d_dnssecdb;
+  bool getNSEC3PARAM(const std::string& zname, NSEC3PARAMRecordContent* ns3p);
   class handle
   {
   public:
@@ -217,7 +238,7 @@ private:
   ofstream *d_of;
   handle d_handle;
 
-  static void queueReload(BB2DomainInfo *bbd);
+  void queueReload(BB2DomainInfo *bbd);
   bool findBeforeAndAfterUnhashed(BB2DomainInfo& bbd, const std::string& qname, std::string& unhashed, std::string& before, std::string& after);
   void reload();
   static string DLDomStatusHandler(const vector<string>&parts, Utility::pid_t ppid);
diff --git a/pdns/backends/bind/binddnssec.cc b/pdns/backends/bind/binddnssec.cc
new file mode 100644 (file)
index 0000000..791e0d4
--- /dev/null
@@ -0,0 +1,234 @@
+/*
+    PowerDNS Versatile Database Driven Nameserver
+    Copyright (C) 2002-2012  PowerDNS.COM BV
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License version 2
+    as published by the Free Software Foundation
+    
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+*/
+#include "bindbackend2.hh"
+#include "../../../modules/gsqlite3backend/ssqlite3.hh"
+#include "dnsrecords.hh"
+#include "bind-dnssec.schema.sqlite3.sql.h"
+
+void Bind2Backend::setupDNSSEC()
+{
+  // cerr<<"Settting up dnssec db.. "<<getArg("dnssec-db") <<endl;
+  if(getArg("dnssec-db").empty())
+    return;
+  try {
+    d_dnssecdb = shared_ptr<SSQLite3>(new SSQLite3(getArg("dnssec-db")));
+  }
+  catch(SSqlException& se) {
+    // this error is meant to kill the server dead - it makes no sense to continue..
+    throw runtime_error("Error opening DNSSEC database in BIND backend: "+se.txtReason());
+  }
+}
+
+void Bind2Backend::createDNSSECDB(const string& fname)
+{
+  string dbname = fname.empty() ? getArg("dnssec-db") : fname;
+  if(dbname.empty())
+    throw AhuException("Unable to generate DNSSEC database for BIND backend since no name was configured for it");
+  
+  try {
+    SSQLite3 db(dbname, true); // create=ok
+    db.doCommand(sqlCreate);
+  }
+  catch(SSqlException& se) {
+    throw AhuException("Error creating database in BIND backend: "+se.txtReason());
+  }
+}
+
+
+bool Bind2Backend::getNSEC3PARAM(const std::string& zname, NSEC3PARAMRecordContent* ns3p)
+{
+  string value;
+  
+  vector<string> meta;
+  getDomainMetadata(zname, "NSEC3PARAM", meta);
+  if(!meta.empty())
+    value=*meta.begin();
+  
+  if(value.empty()) { // "no NSEC3"
+    return false;
+  }
+     
+  if(ns3p) {
+    NSEC3PARAMRecordContent* tmp=dynamic_cast<NSEC3PARAMRecordContent*>(DNSRecordContent::mastermake(QType::NSEC3PARAM, 1, value));
+    *ns3p = *tmp;
+    delete tmp;
+  }
+  return true;
+}
+
+bool Bind2Backend::getDomainMetadata(const string& name, const std::string& kind, std::vector<std::string>& meta)
+{
+  if(!d_dnssecdb)
+    return false;
+    
+  // cerr<<"Asked to get metadata for zone '"<<name<<"'|"<<kind<<"\n";
+  
+  boost::format fmt("select content from domainmetadata where domain='%s' and kind='%s'");
+  try {
+    d_dnssecdb->doQuery((fmt % d_dnssecdb->escape(name) % d_dnssecdb->escape(kind)).str());
+  
+    vector<string> row;
+    while(d_dnssecdb->getRow(row)) {
+      meta.push_back(row[0]);
+    }
+  }
+  catch(SSqlException& se) {
+    throw AhuException("Error accessing DNSSEC database in BIND backend: "+se.txtReason());
+  }
+  return true;
+}
+
+bool Bind2Backend::setDomainMetadata(const string& name, const std::string& kind, const std::vector<std::string>& meta)
+{
+  if(!d_dnssecdb)
+    return false;
+  
+  boost::format fmt("delete from domainmetadata where domain='%s' and kind='%s'");
+  boost::format fmt2("insert into domainmetadata (domain, kind, content) values ('%s','%s', '%s')");
+  try {
+    d_dnssecdb->doCommand((fmt % d_dnssecdb->escape(name) % d_dnssecdb->escape(kind)).str());
+    if(!meta.empty())
+      d_dnssecdb->doCommand((fmt2 % d_dnssecdb->escape(name) % d_dnssecdb->escape(kind) % d_dnssecdb->escape(meta.begin()->c_str())).str());
+  }
+  catch(SSqlException& se) {
+    throw AhuException("Error accessing DNSSEC database in BIND backend: "+se.txtReason());
+  }
+  return true;
+
+}
+
+bool Bind2Backend::getDomainKeys(const string& name, unsigned int kind, std::vector<KeyData>& keys)
+{
+  // cerr<<"Asked to get keys for zone '"<<name<<"'\n";
+  if(!d_dnssecdb)
+    return false;
+  boost::format fmt("select id,flags, active, content from cryptokeys where domain='%s'");
+  try {
+    d_dnssecdb->doQuery((fmt % d_dnssecdb->escape(name)).str());
+    KeyData kd;
+    vector<string> row;
+    while(d_dnssecdb->getRow(row)) {
+      kd.id = atoi(row[0].c_str());
+      kd.flags = atoi(row[1].c_str());
+      kd.active = atoi(row[2].c_str());
+      kd.content = row[3];
+      keys.push_back(kd);
+    }
+  }
+  catch(SSqlException& se) {
+    throw AhuException("Error accessing DNSSEC database in BIND backend: "+se.txtReason());
+  }
+  
+  return true;
+}
+
+bool Bind2Backend::removeDomainKey(const string& name, unsigned int id)
+{
+  if(!d_dnssecdb)
+    return false;
+  
+  cerr<<"Asked to remove key "<<id<<" in zone '"<<name<<"'\n";
+  
+  boost::format fmt("delete from cryptokeys where domain='%s' and id=%d");
+  try {
+    d_dnssecdb->doCommand((fmt % d_dnssecdb->escape(name) % id).str());
+  }
+  catch(SSqlException& se) {
+    cerr<<se.txtReason()  <<endl;
+  }
+  
+  return true;
+}
+
+int Bind2Backend::addDomainKey(const string& name, const KeyData& key)
+{
+  if(!d_dnssecdb)
+    return false;
+  
+  //cerr<<"Asked to add a key to zone '"<<name<<"'\n";
+  
+  boost::format fmt("insert into cryptokeys (domain, flags, active, content) values ('%s', %d, %d, '%s')");
+  try {
+    d_dnssecdb->doCommand((fmt % d_dnssecdb->escape(name) % key.flags % key.active % d_dnssecdb->escape(key.content)).str());
+  }
+  catch(SSqlException& se) {
+    throw AhuException("Error accessing DNSSEC database in BIND backend: "+se.txtReason());    
+  }
+  
+  return true;
+}
+
+bool Bind2Backend::activateDomainKey(const string& name, unsigned int id)
+{
+  // cerr<<"Asked to activate key "<<id<<" inzone '"<<name<<"'\n";
+  if(!d_dnssecdb)
+    return false;
+  
+  boost::format fmt("update cryptokeys set active=1 where domain='%s' and id=%d");
+  try {
+    d_dnssecdb->doCommand((fmt % d_dnssecdb->escape(name) % id).str());
+  }
+  catch(SSqlException& se) {
+    throw AhuException("Error accessing DNSSEC database in BIND backend: "+se.txtReason());    
+  }
+  
+  return true;
+}
+
+bool Bind2Backend::deactivateDomainKey(const string& name, unsigned int id)
+{
+  // cerr<<"Asked to deactivate key "<<id<<" inzone '"<<name<<"'\n";
+  if(!d_dnssecdb)
+    return false;
+    
+  boost::format fmt("update cryptokeys set active=0 where domain='%s' and id=%d");
+  try {
+    d_dnssecdb->doCommand((fmt % d_dnssecdb->escape(name) % id).str());
+  }
+  catch(SSqlException& se) {
+    throw AhuException("Error accessing DNSSEC database in BIND backend: "+se.txtReason());
+  }
+  
+  return true;
+}
+
+bool Bind2Backend::getTSIGKey(const string& name, string* algorithm, string* content)
+{
+  if(!d_dnssecdb)
+    return false;
+  boost::format fmt("select algorithm, secret from tsigkeys where name='%s'");
+  
+  try {
+    d_dnssecdb->doQuery( (fmt % d_dnssecdb->escape(name)).str());
+  }
+  catch (SSqlException &e) {
+    throw AhuException("GSQLBackend unable to retrieve named TSIG key: "+e.txtReason());
+  }
+  
+  SSql::row_t row;
+  
+  content->clear();
+  while(d_dnssecdb->getRow(row)) {
+    *algorithm = row[0];
+    *content=row[1];
+  }
+
+  return !content->empty();
+
+}
index 1fdff1d95e26e6bdbff067e1fcf165381d51c363..34a7645cd8f6cc780afdde49282167320a9bc52d 100644 (file)
@@ -1,7 +1,7 @@
 create table domainmetadata (
- id             INTEGER PRIMARY KEY,
+ id            INTEGER PRIMARY KEY,
  domain        VARCHAR(255) COLLATE NOCASE,
- kind           VARCHAR(16) COLLATE NOCASE,
+ kind          VARCHAR(16) COLLATE NOCASE,
  content       TEXT
 );
 
index 60a6f2bce831896d2ae9e74dc60cd918a6535d23..39c7fddf285e6ef9fee2f3765020a63007a5ac0a 100644 (file)
@@ -232,8 +232,6 @@ bool DNSSECKeeper::getNSEC3PARAM(const std::string& zname, NSEC3PARAMRecordConte
     getFromMeta(zname, "NSEC3NARROW", value);
     *narrow = (value=="1");
   }
-  
-  
   return true;
 }
 
index 89371b54dde33d37b6771e81f39f1cee00dbf0d1..acff3dff04b11d0e4d801eb5638e2c436b220df9 100644 (file)
@@ -163,7 +163,7 @@ int BackendMakerClass::numLauncheable()
   return d_instances.size();
 }
 
-vector<DNSBackend *>BackendMakerClass::all(bool skipBIND)
+vector<DNSBackend *>BackendMakerClass::all(bool metadataOnly)
 {
   vector<DNSBackend *>ret;
   if(d_instances.empty())
@@ -171,9 +171,11 @@ vector<DNSBackend *>BackendMakerClass::all(bool skipBIND)
 
   try {
     for(vector<pair<string,string> >::const_iterator i=d_instances.begin();i!=d_instances.end();++i) {
-      if(skipBIND && i->first=="bind")
-        continue;
-      DNSBackend *made=d_repository[i->first]->make(i->second);
+      DNSBackend *made;
+      if(metadataOnly)
+        made = d_repository[i->first]->makeMetadataOnly(i->second);
+      else 
+        made = d_repository[i->first]->make(i->second);
       if(!made)
         throw AhuException("Unable to launch backend '"+i->first+"'");
 
index 6f904b0d4e6de1ff274afcc300a8f5b5f4343295..718e12afa9c91f5ba878152e0451ac20ae230339 100644 (file)
@@ -235,6 +235,10 @@ public:
   BackendFactory(const string &name) : d_name(name) {}
   virtual ~BackendFactory(){}
   virtual DNSBackend *make(const string &suffix)=0;
+  virtual DNSBackend *makeMetadataOnly(const string &suffix)
+  {
+    return this->make(suffix);
+  }
   virtual void declareArguments(const string &suffix=""){}
   const string &getName() const;
   
index 8162a515307f3d2129cb0e1b0fd27e5171fb6e93..62e0b5259b2a1110a0582774a38f89555c834f2f 100644 (file)
@@ -12,6 +12,7 @@
 #include "zoneparser-tng.hh"
 #include "signingpipe.hh"
 #include <boost/scoped_ptr.hpp>
+#include "bindbackend2.hh"
 
 StatBag S;
 PacketCache PC;
@@ -433,6 +434,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<<"create-bind-db [FNAME]           Create a DNSSEC database for BIND backend\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<<"export-zone-dnskey ZONE KEY-ID   Export to stdout the public DNSKEY described\n";
@@ -462,7 +464,11 @@ try
   reportAllTypes();
   DNSSECKeeper dk;
 
-  if(cmds[0] == "rectify-zone") {
+  if(cmds[0] == "create-bind-db") {
+    Bind2Backend b2b;
+    b2b.createDNSSECDB(cmds.size() > 1 ? cmds[1] : "");
+  }
+  else if(cmds[0] == "rectify-zone") {
     if(cmds.size() < 2) {
       cerr << "Syntax: pdnssec rectify-zone ZONE [ZONE..]"<<endl;
       return 0;