]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
import pdnssec rectifyZone() from master
authorKees Monshouwer <mind04@monshouwer.org>
Wed, 29 Apr 2015 20:57:01 +0000 (22:57 +0200)
committermind04 <mind04@monshouwer.org>
Thu, 30 Apr 2015 22:12:17 +0000 (00:12 +0200)
pdns/pdnssec.cc

index 6d059d83ea98d9d7711dcabcf0ed439753afa49a..f3d36fa12d9a707f95012702bff9a1bffcb84f1f 100644 (file)
@@ -178,18 +178,19 @@ bool rectifyZone(DNSSECKeeper& dk, const std::string& zone)
   if(!B.getSOA(zone, sd)) {
     cerr<<"No SOA known for '"<<zone<<"', is such a zone in the database?"<<endl;
     return false;
-  } 
+  }
   sd.db->list(zone, sd.domain_id);
 
   DNSResourceRecord rr;
-  set<string> qnames, nsset, dsnames, nonterm, insnonterm, delnonterm;
+  set<string> qnames, nsset, dsnames, insnonterm, delnonterm;
+  map<string,bool> nonterm;
   bool doent=true;
-  
+
   while(sd.db->get(rr)) {
     if (rr.qtype.getCode())
     {
       qnames.insert(rr.qname);
-      if(rr.qtype.getCode() == QType::NS && !pdns_iequals(rr.qname, zone)) 
+      if(rr.qtype.getCode() == QType::NS && !pdns_iequals(rr.qname, zone))
         nsset.insert(rr.qname);
       if(rr.qtype.getCode() == QType::DS)
         dsnames.insert(rr.qname);
@@ -202,21 +203,25 @@ bool rectifyZone(DNSSECKeeper& dk, const std::string& zone)
   NSEC3PARAMRecordContent ns3pr;
   bool narrow;
   bool haveNSEC3=dk.getNSEC3PARAM(zone, &ns3pr, &narrow);
+  bool isOptOut=(haveNSEC3 && ns3pr.d_flags);
   if(sd.db->doesDNSSEC())
   {
-    if(!haveNSEC3) 
+    if(!haveNSEC3)
       cerr<<"Adding NSEC ordering information "<<endl;
-    else if(!narrow)
-      cerr<<"Adding NSEC3 hashed ordering information for '"<<zone<<"'"<<endl;
-    else 
+    else if(!narrow) {
+      if(!isOptOut)
+        cerr<<"Adding NSEC3 hashed ordering information for '"<<zone<<"'"<<endl;
+      else
+        cerr<<"Adding NSEC3 opt-out hashed ordering information for '"<<zone<<"'"<<endl;
+    } else
       cerr<<"Erasing NSEC3 ordering since we are narrow, only setting 'auth' fields"<<endl;
   }
   else
     cerr<<"Non DNSSEC zone, only adding empty non-terminals"<<endl;
-  
+
   if(doTransaction)
     sd.db->startTransaction("", -1);
-    
+
   bool realrr=true;
   string hashed;
 
@@ -239,14 +244,17 @@ bool rectifyZone(DNSSECKeeper& dk, const std::string& zone)
 
     if(haveNSEC3)
     {
-      if(!narrow) {
+      if(!narrow && (realrr || !isOptOut || nonterm.find(qname)->second)) {
         hashed=toLower(toBase32Hex(hashQNameWithSalt(ns3pr.d_iterations, ns3pr.d_salt, qname)));
         if(g_verbose)
           cerr<<"'"<<qname<<"' -> '"<< hashed <<"'"<<endl;
         sd.db->updateDNSSECOrderAndAuthAbsolute(sd.domain_id, qname, hashed, auth);
       }
-      else
+      else {
+        if(!realrr)
+          auth=false;
         sd.db->nullifyDNSSECOrderNameAndUpdateAuth(sd.domain_id, qname, auth);
+      }
     }
     else // NSEC
     {
@@ -260,33 +268,39 @@ bool rectifyZone(DNSSECKeeper& dk, const std::string& zone)
       if (dsnames.count(qname))
         sd.db->setDNSSECAuthOnDsRecord(sd.domain_id, qname);
       if (!auth || nsset.count(qname)) {
-        if(haveNSEC3 && ns3pr.d_flags)
+        if(isOptOut)
           sd.db->nullifyDNSSECOrderNameAndAuth(sd.domain_id, qname, "NS");
         sd.db->nullifyDNSSECOrderNameAndAuth(sd.domain_id, qname, "A");
         sd.db->nullifyDNSSECOrderNameAndAuth(sd.domain_id, qname, "AAAA");
       }
 
-      if(auth && doent)
+      if(doent)
       {
         shorter=qname;
         while(!pdns_iequals(shorter, zone) && chopOff(shorter))
         {
-          if(!qnames.count(shorter) && !nonterm.count(shorter))
+          if(!qnames.count(shorter))
           {
             if(!(maxent))
             {
-              cerr<<"Zone '"<<zone<<"' has too many empty non terminals."<<endl;
+              if (!::arg().asNum("max-ent-entries"))
+                cerr<<"Zone '"<<zone<<"' has too many empty non terminals."<<endl;
               insnonterm.clear();
               delnonterm.clear();
               doent=false;
               break;
             }
-            nonterm.insert(shorter);
-            if (!delnonterm.count(shorter))
+
+            if (!delnonterm.count(shorter) && !nonterm.count(shorter))
               insnonterm.insert(shorter);
             else
               delnonterm.erase(shorter);
-            --maxent;
+
+            if (!nonterm.count(shorter)) {
+              nonterm.insert(pair<string, bool>(shorter, auth));
+              --maxent;
+            } else if (auth)
+              nonterm[shorter]=true;
           }
         }
       }
@@ -303,7 +317,11 @@ bool rectifyZone(DNSSECKeeper& dk, const std::string& zone)
     if(doent)
     {
       realrr=false;
-      qnames=nonterm;
+      qnames.clear();
+      pair<string,bool> nt;
+      BOOST_FOREACH(nt, nonterm){
+        qnames.insert(nt.first);
+      }
       goto dononterm;
     }
   }