Handle CNAMEs to DS records when confirming absence of DS for DNSSEC.
diff --git a/src/forward.c b/src/forward.c
index 8c3e71c..b40dda3 100644
--- a/src/forward.c
+++ b/src/forward.c
@@ -851,7 +851,7 @@
 		   Avoid caching a reply with sigs if there's a vaildated break in the 
 		   DS chain, so we don't return replies from cache missing sigs. */
 		status = STAT_INSECURE_DS;
-	      else if (status == STAT_NO_NS)
+	      else if (status == STAT_NO_NS || status == STAT_NO_SIG)
 		status = STAT_BOGUS;
 	    }
 	  else if (forward->flags & FREC_CHECK_NOSIGN)
@@ -997,7 +997,7 @@
 			   Avoid caching a reply with sigs if there's a vaildated break in the 
 			   DS chain, so we don't return replies from cache missing sigs. */
 			status = STAT_INSECURE_DS;
-		      else if (status == STAT_NO_NS)
+		      else if (status == STAT_NO_NS || status == STAT_NO_SIG)
 			status = STAT_BOGUS; 
 		    }
 		  else if (forward->flags & FREC_CHECK_NOSIGN)
@@ -1456,6 +1456,21 @@
       if (status == STAT_BOGUS)
 	return STAT_BOGUS;
 
+      if (status == STAT_NO_SIG && *keyname != 0)
+	{
+	  /* There is a validated CNAME chain that doesn't end in a DS record. Start 
+	     the search again in that domain. */
+	  blockdata_free(forward->orig_domain);
+	  forward->name_start = strlen(keyname);
+	  forward->name_len = forward->name_start + 1;
+	  if (!(forward->orig_domain = blockdata_alloc(keyname, forward->name_len)))
+	    return STAT_BOGUS;
+	  
+	  strcpy(name, keyname);
+	  status = 0; /* force to cache when we iterate. */
+	  continue;
+	}
+      
       /* There's a proven DS record, or we're within a zone, where there doesn't need
 	 to be a DS record. Add a name and try again. 
 	 If we've already tried the whole name, then fail */
@@ -1572,6 +1587,21 @@
 	      return STAT_INSECURE;
 	    }
 	  
+	  if (status == STAT_NO_SIG && *keyname != 0)
+	    {
+	      /* There is a validated CNAME chain that doesn't end in a DS record. Start 
+		 the search again in that domain. */
+	      blockdata_free(block);
+	      name_len = strlen(keyname) + 1;
+	      name_start = name + name_len - 1;
+	      
+	      if (!(block = blockdata_alloc(keyname, name_len)))
+		return STAT_BOGUS;
+	      
+	      strcpy(name, keyname);
+	      continue;
+	    }
+	  
 	  if (status == STAT_BOGUS)
 	    {
 	      free(packet);
@@ -1627,7 +1657,7 @@
 	{
 	  if (new_status == STAT_NO_DS)
 	    new_status = STAT_INSECURE_DS;
-	  else if (new_status == STAT_NO_NS)
+	  else if (new_status == STAT_NO_NS || new_status == STAT_NO_SIG)
 	    new_status = STAT_BOGUS;
 	}
     }
@@ -1692,7 +1722,7 @@
 		    {
 		      if (new_status == STAT_NO_DS)
 			new_status = STAT_INSECURE_DS;
-		      else if (new_status == STAT_NO_NS)
+		      else if (new_status == STAT_NO_NS || new_status == STAT_NO_SIG)
 			new_status = STAT_BOGUS; /* Validated no DS */
 		    }
 		}