diff -ru pdns-recursor-4.1.0.orig/validate.cc pdns-recursor-4.1.0/validate.cc
--- pdns-recursor-4.1.0.orig/validate.cc	2018-01-12 16:47:55.749949778 +0100
+++ pdns-recursor-4.1.0/validate.cc	2018-01-12 16:52:18.057068597 +0100
@@ -155,6 +155,20 @@
   return result;
 }
 
+static bool isNSECAncestorDelegation(const DNSName& signer, const DNSName& owner, const std::shared_ptr<NSECRecordContent> nsec)
+{
+  return nsec->d_set.count(QType::NS) &&
+    !nsec->d_set.count(QType::SOA) &&
+    signer.countLabels() < owner.countLabels();
+}
+
+static bool isNSEC3AncestorDelegation(const DNSName& signer, const DNSName& owner, const std::shared_ptr<NSEC3RecordContent> nsec3)
+{
+  return nsec3->d_set.count(QType::NS) &&
+    !nsec3->d_set.count(QType::SOA) &&
+    signer.countLabels() < owner.countLabels();
+}
+
 static bool provesNoDataWildCard(const DNSName& qname, const uint16_t qtype, const cspmap_t& validrrsets)
 {
   LOG("Trying to prove that there is no data in wildcard for "<<qname<<"/"<<QType(qtype).getName()<<endl);
@@ -331,21 +345,18 @@
            that (original) owner name other than DS RRs, and all RRs below that
            owner name regardless of type.
         */
-        if (nsec->d_set.count(QType::NS) && !nsec->d_set.count(QType::SOA) &&
-            signer.countLabels() < owner.countLabels()) {
-          LOG("type is "<<QType(qtype).getName()<<", NS is "<<std::to_string(nsec->d_set.count(QType::NS))<<", SOA is "<<std::to_string(nsec->d_set.count(QType::SOA))<<", signer is "<<signer.toString()<<", owner name is "<<owner.toString()<<endl);
-          /* this is an "ancestor delegation" NSEC RR */
-          if (qname == owner && qtype != QType::DS) {
-            LOG("An ancestor delegation NSEC RR can only deny the existence of a DS"<<endl);
-            continue;
-          }
+        if (qtype != QType::DS && (qname == owner || qname.isPartOf(owner)) && isNSECAncestorDelegation(signer, owner, nsec)) {
+           LOG("type is "<<QType(qtype).getName()<<", NS is "<<std::to_string(nsec->d_set.count(QType::NS))<<", SOA is "<<std::to_string(nsec->d_set.count(QType::SOA))<<", signer is "<<signer<<", owner name is "<<owner<<endl);
+           /* this is an "ancestor delegation" NSEC RR */
+          LOG("An ancestor delegation NSEC RR can only deny the existence of a DS"<<endl);
+          return NODATA;
         }
 
         /* check if the type is denied */
         if(qname == owner) {
           if (nsec->d_set.count(qtype)) {
             LOG("Does _not_ deny existence of type "<<QType(qtype).getName()<<endl);
-            continue;
+            return NODATA;
           }
 
           LOG("Denies existence of type "<<QType(qtype).getName()<<endl);
@@ -443,21 +454,18 @@
            that (original) owner name other than DS RRs, and all RRs below that
            owner name regardless of type.
         */
-        if (nsec3->d_set.count(QType::NS) && !nsec3->d_set.count(QType::SOA) &&
-            signer.countLabels() < v.first.first.countLabels()) {
-          LOG("type is "<<QType(qtype).getName()<<", NS is "<<std::to_string(nsec3->d_set.count(QType::NS))<<", SOA is "<<std::to_string(nsec3->d_set.count(QType::SOA))<<", signer is "<<signer.toString()<<", owner name is "<<v.first.first.toString()<<endl);
-          /* this is an "ancestor delegation" NSEC3 RR */
-          if (beginHash == h && qtype != QType::DS) {
-            LOG("An ancestor delegation NSEC3 RR can only deny the existence of a DS"<<endl);
-            continue;
-          }
+        if (qtype != QType::DS && beginHash == h && isNSEC3AncestorDelegation(signer, v.first.first, nsec3)) {
+           LOG("type is "<<QType(qtype).getName()<<", NS is "<<std::to_string(nsec3->d_set.count(QType::NS))<<", SOA is "<<std::to_string(nsec3->d_set.count(QType::SOA))<<", signer is "<<signer<<", owner name is "<<v.first.first<<endl);
+           /* this is an "ancestor delegation" NSEC3 RR */
+          LOG("An ancestor delegation NSEC3 RR can only deny the existence of a DS"<<endl);
+          return NODATA;
         }
 
         // If the name exists, check if the qtype is denied
         if(beginHash == h) {
           if (nsec3->d_set.count(qtype)) {
             LOG("Does _not_ deny existence of type "<<QType(qtype).getName()<<" for name "<<qname<<" (not opt-out)."<<endl);
-            continue;
+            return NODATA;
           }
 
           LOG("Denies existence of type "<<QType(qtype).getName()<<" for name "<<qname<<" (not opt-out)."<<endl);
@@ -510,6 +518,12 @@
             if(!nsec3)
               continue;
 
+            const DNSName signer = getSigner(v.second.signatures);
+            if (!v.first.first.isPartOf(signer)) {
+              LOG("Owner "<<v.first.first<<" is not part of the signer "<<signer<<", ignoring"<<endl);
+              continue;
+            }
+
             string h = getHashFromNSEC3(closestEncloser, nsec3);
             if (h.empty()) {
               return INSECURE;
@@ -519,6 +533,11 @@
 
             LOG("Comparing "<<toBase32Hex(h)<<" ("<<closestEncloser<<") against "<<toBase32Hex(beginHash)<<endl);
             if(beginHash == h) {
+              if (qtype != QType::DS && isNSEC3AncestorDelegation(signer, v.first.first, nsec3)) {
+                LOG("An ancestor delegation NSEC3 RR can only deny the existence of a DS"<<endl);
+                continue;
+              }
+
               LOG("Closest encloser for "<<qname<<" is "<<closestEncloser<<endl);
               found = true;
               break;
