]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
Allow root-zones as '.' in the SQL backends
authorPieter Lexis <pieter.lexis@powerdns.com>
Tue, 9 Feb 2016 16:39:10 +0000 (17:39 +0100)
committermind04 <mind04@monshouwer.org>
Fri, 25 Mar 2016 18:47:59 +0000 (19:47 +0100)
Allow importing a root-zone through zone2sql as well.
This also fixes slaving the root with the bind backend and dnssec.

docs/markdown/authoritative/backend-generic-sql.md
pdns/backends/gsql/gsqlbackend.cc
pdns/backends/gsql/ssql.hh
pdns/zone2sql.cc

index 5cd920d774d8d36a98c8354bf7325a6fc220dc99..6bcc02e78bd1f3af1a81eb9a0d239022bf005086 100644 (file)
@@ -8,6 +8,9 @@ backend is needed to cover all needs.
 a '.' in PowerDNS storage! If a trailing '.' is present it will inevitably cause
 problems, problems that may be hard to debug.
 
+**Note**: Since 4.0.0, a root zone or record should have a name of '.' (no quotes).
+This is the only exception to the 'no terminating dot in SQL storage' rule.
+
 # Basic functionality
 All domains in the generic SQL backends have a 'type' field that describes the
 [mode of operation](modes-of-operation.md).
index bcba0baef3f765532d7c98fc59b6772e6a2be4bd..9463180856dda8fcc1dc88fdbe4d6e42c6af83aa 100644 (file)
@@ -1032,7 +1032,7 @@ bool GSQLBackend::list(const DNSName &target, int domain_id, bool include_disabl
 bool GSQLBackend::listSubZone(const DNSName &zone, int domain_id) {
   if (!isOurDomain(nullptr, domain_id)) return false;
 
-  string wildzone = "%." + stripDot(zone.toString());  // tolower()?
+  string wildzone = "%." + toLower(zone.toStringNoDot());
 
   try {
     d_query_name = "list-subzone-query";
@@ -1118,7 +1118,7 @@ bool GSQLBackend::createDomain(const DNSName &domain, const string &type, const
       reset();
   }
   catch(SSqlException &e) {
-    throw DBException("Database error trying to insert new domain '"+domain.toString()+"': "+ e.txtReason());
+    throw DBException("Database error trying to insert new domain '"+domain.toStringRootDot()+"': "+ e.txtReason());
   }
   return true;
 }
index 3b43b24710d56024acf46497fc07cb5b41e7fcfd..17ea9727ee2713a4c5ff12f0939cb1743a18002c 100644 (file)
@@ -47,7 +47,7 @@ public:
   virtual SSqlStatement* bind(const string& name, unsigned long long value)=0;
   virtual SSqlStatement* bind(const string& name, const std::string& value)=0;
   SSqlStatement* bind(const string& name, const DNSName& value) {
-    return bind(name, toLower(value.toStringNoDot()));
+    return bind(name, toLower(value.toStringRootDot()));
   }
   virtual SSqlStatement* bindNull(const string& name)=0;
   virtual SSqlStatement* execute()=0;;
index eefee9252564d7126258cd697af6bfebbf9af48e..bbfed777dc35674d639e89f79306703ac29e25f9 100644 (file)
@@ -110,16 +110,17 @@ static void startNewTransaction()
     cout<<"BEGIN TRANSACTION;"<<endl;
 }
 
-static void emitDomain(const string& domain, const vector<string> *masters = 0) {
+static void emitDomain(const DNSName& domain, const vector<string> *masters = 0) {
+  string iDomain = domain.toStringRootDot();
   if(!::arg().mustDo("slave")) {
     if(g_mode==POSTGRES || g_mode==MYSQL || g_mode==SQLITE) {
-      cout<<"insert into domains (name,type) values ("<<toLower(sqlstr(stripDot(domain)))<<",'NATIVE');"<<endl;
+      cout<<"insert into domains (name,type) values ("<<toLower(sqlstr(iDomain))<<",'NATIVE');"<<endl;
     }
     else if(g_mode==GORACLE) {
-      cout<<"insert into domains (id,name,type) values (domains_id_sequence.nextval,"<<toLower(sqlstr(domain))<<",'NATIVE');"<<endl;
+      cout<<"insert into domains (id,name,type) values (domains_id_sequence.nextval,"<<toLower(sqlstr(iDomain))<<",'NATIVE');"<<endl;
     }
     else if(g_mode==ORACLE) {
-      cout<<"INSERT INTO Zones (id, name, type) VALUES (zones_id_seq.nextval, "<<sqlstr(toLower(domain))<<", 'NATIVE');"<<endl;
+      cout<<"INSERT INTO Zones (id, name, type) VALUES (zones_id_seq.nextval, "<<sqlstr(toLower(iDomain))<<", 'NATIVE');"<<endl;
     }
   }
   else 
@@ -131,12 +132,12 @@ static void emitDomain(const string& domain, const vector<string> *masters = 0)
         for(const string& mstr :  *masters) {
           mstrs.append(mstr);
           mstrs.append(1, ' ');
-        }                  
+        }
       }
       if (mstrs.empty())
-        cout<<"insert into domains (name,type) values ("<<sqlstr(domain)<<",'NATIVE');"<<endl;
+        cout<<"insert into domains (name,type) values ("<<sqlstr(iDomain)<<",'NATIVE');"<<endl;
       else
-        cout<<"insert into domains (name,type,master) values ("<<sqlstr(domain)<<",'SLAVE'"<<", '"<<mstrs<<"');"<<endl;
+        cout<<"insert into domains (name,type,master) values ("<<sqlstr(iDomain)<<",'SLAVE'"<<", '"<<mstrs<<"');"<<endl;
     }
     else if (g_mode == GORACLE || g_mode==ORACLE) {
       cerr<<"Slave import mode not supported with oracle."<<endl;
@@ -145,9 +146,10 @@ static void emitDomain(const string& domain, const vector<string> *masters = 0)
 }
 
 bool g_doJSONComments;
-static void emitRecord(const string& zoneName, const DNSName &DNSqname, const string &qtype, const string &ocontent, int ttl, const string& comment="")
+static void emitRecord(const DNSName& zoneName, const DNSName &DNSqname, const string &qtype, const string &ocontent, int ttl, const string& comment="")
 {
-  string qname = stripDot(DNSqname.toString());
+  string qname = DNSqname.toStringRootDot();
+  string zname = zoneName.toStringRootDot();
   int prio=0;
   int disabled=0;
   string recordcomment;
@@ -182,7 +184,7 @@ static void emitRecord(const string& zoneName, const DNSName &DNSqname, const st
   }
 
   bool auth = true;
-  if(qtype == "NS" && !pdns_iequals(qname, zoneName)) {
+  if(qtype == "NS" && !pdns_iequals(qname, zname)) {
     auth=false;
   }
 
@@ -191,36 +193,36 @@ static void emitRecord(const string& zoneName, const DNSName &DNSqname, const st
       sqlstr(toLower(qname))<<", "<<
       sqlstr(qtype)<<", "<<
       sqlstr(stripDotContent(content))<<", "<<ttl<<", "<<prio<<", "<<disabled<<
-      " from domains where name="<<toLower(sqlstr(zoneName))<<";\n";
+      " from domains where name="<<toLower(sqlstr(zname))<<";\n";
 
     if(!recordcomment.empty()) {
-      cout<<"insert into comments (domain_id,name,type,modified_at, comment) select id, "<<toLower(sqlstr(stripDot(qname)))<<", "<<sqlstr(qtype)<<", "<<time(0)<<", "<<sqlstr(recordcomment)<<" from domains where name="<<toLower(sqlstr(zoneName))<<";\n";
+      cout<<"insert into comments (domain_id,name,type,modified_at, comment) select id, "<<toLower(sqlstr(stripDot(qname)))<<", "<<sqlstr(qtype)<<", "<<time(0)<<", "<<sqlstr(recordcomment)<<" from domains where name="<<toLower(sqlstr(zname))<<";\n";
     }
   }
   else if(g_mode==POSTGRES) {
     cout<<"insert into records (domain_id, name, ordername, auth, type,content,ttl,prio,disabled) select id ,"<<
       sqlstr(toLower(qname))<<", "<<
-      sqlstr(toLower(labelReverse(makeRelative(qname, zoneName))))<<", '"<< (auth  ? 't' : 'f') <<"', "<<
+      sqlstr(toLower(labelReverse(makeRelative(qname, zname))))<<", '"<< (auth  ? 't' : 'f') <<"', "<<
       sqlstr(qtype)<<", "<<
       sqlstr(stripDotContent(content))<<", "<<ttl<<", "<<prio<<", '"<<(disabled ? 't': 'f') <<
-      "' from domains where name="<<toLower(sqlstr(zoneName))<<";\n";
+      "' from domains where name="<<toLower(sqlstr(zname))<<";\n";
   }
   else if(g_mode==GORACLE) {
     cout<<"insert into Records (id, domain_id, name, type, content, ttl, prio, disabled) select RECORDS_ID_SEQUENCE.nextval,id ,"<<
       sqlstr(toLower(qname))<<", "<<
       sqlstr(qtype)<<", "<<
       sqlstr(stripDotContent(content))<<", "<<ttl<<", "<<prio<<", "<<disabled<<
-      " from Domains where name="<<toLower(sqlstr(zoneName))<<";\n";
+      " from Domains where name="<<toLower(sqlstr(zname))<<";\n";
   }
   else if(g_mode==ORACLE) {
     cout<<"INSERT INTO Records (id, zone_id, fqdn, ttl, type, content) SELECT records_id_seq.nextval, id, "<<
       sqlstr(toLower(qname))<<", "<<
       ttl<<", "<<sqlstr(qtype)<<", "<<
       sqlstr(stripDotContent(content))<<
-      " FROM Zones WHERE name="<<toLower(sqlstr(zoneName))<<";"<<endl;
+      " FROM Zones WHERE name="<<toLower(sqlstr(zname))<<";"<<endl;
   }
   else if (g_mode == MYDNS) {
-    string zoneNameDot = zoneName + ".";
+    string zoneNameDot = zname + ".";
     if (qtype == "A" || qtype == "AAAA" || qtype == "CNAME" || qtype == "HINFO" || qtype == "MX" || qtype == "NAPTR" || 
         qtype == "NS" || qtype == "PTR" || qtype == "RP" || qtype == "SRV" || qtype == "TXT")
     {
@@ -371,7 +373,7 @@ try
           try {
             startNewTransaction();
             
-            emitDomain(i->name.toStringNoDot(), &(i->masters));
+            emitDomain(i->name, &(i->masters));
             
             ZoneParserTNG zpt(i->filename, i->name, BP.getDirectory());
             DNSResourceRecord rr;
@@ -383,7 +385,7 @@ try
               if(rr.qtype.getCode() == QType::SOA)
                 seenSOA=true;
 
-              emitRecord(i->name.toStringNoDot(), rr.qname, rr.qtype.getName(), rr.content, rr.ttl, comment);
+              emitRecord(i->name, rr.qname, rr.qtype.getName(), rr.content, rr.ttl, comment);
             }
             num_domainsdone++;
           }
@@ -424,7 +426,7 @@ try
          seenSOA=true;
         if(!haveEmittedZone) {
           if(!zpt.getZoneName().empty()){
-            emitDomain(zpt.getZoneName().toStringNoDot());
+            emitDomain(zpt.getZoneName());
             haveEmittedZone = true;
           } else {
             // We have no zonename yet, don't emit
@@ -432,7 +434,7 @@ try
           }
         }
 
-        emitRecord(zpt.getZoneName().toStringNoDot(), rr.qname, rr.qtype.getName(), rr.content, rr.ttl, comment);
+        emitRecord(zpt.getZoneName(), rr.qname, rr.qtype.getName(), rr.content, rr.ttl, comment);
       }
       num_domainsdone=1;
     }