Index: trunk/DNSDB.pm
===================================================================
--- trunk/DNSDB.pm	(revision 327)
+++ trunk/DNSDB.pm	(revision 328)
@@ -383,13 +383,23 @@
   my %args = @_;
 
-  # Coerce the hostname to "DOMAIN" for forward default records, "ZONE" for reverse default records,
-  # or the intended parent zone for live records.
-##fixme:  allow for delegating <subdomain>.DOMAIN?
-  if ($args{revrec} eq 'y') {
-    my $pname = ($args{defrec} eq 'y' ? 'ZONE' : revName($dbh,$args{id}));
-    ${$args{host}} = $pname if ${$args{host}} ne $pname;
+  # Check that the target of the record is within the parent.
+  # Yes, host<->val are mixed up here;  can't see a way to avoid it.  :(
+  if ($args{defrec} eq 'n') {
+    # Check if IP/address/zone/"subzone" is within the parent
+    if ($args{revrec} eq 'y') {
+      my $tmpip = NetAddr::IP->new(${$args{val}});
+      my $pname = revName($dbh,$args{id});
+      return ('FAIL',"${$args{val}} not within $pname")
+	 unless _ipparent($dbh, $args{defrec}, $args{revrec}, $args{val}, $args{id}, \$tmpip);
+      # Sub the returned thing for ZONE?  This could get stupid if you have typos...
+      ${$args{val}} =~ s/ZONE/$tmpip->address/;
+    } else {
+      my $pname = domainName($dbh,$args{id});
+      ${$args{host}} = $pname if ${$args{host}} !~ /\.$pname$/;
+    }
   } else {
-    my $pname = ($args{defrec} eq 'y' ? 'DOMAIN' : domainName($dbh,$args{id}));
-    ${$args{host}} = $pname if ${$args{host}} ne $pname;
+    # Default reverse NS records should always refer to the implied parent
+    ${$args{host}} = 'DOMAIN' if $args{revrec} eq 'n';
+    ${$args{val}} = 'ZONE' if $args{revrec} eq 'y';
   }
 
@@ -1766,6 +1776,7 @@
       }
 
-      # Substitute $zone for ZONE in the hostname.
-      $host = _ZONE($zone, $host);
+      # Substitute $zone for ZONE in the hostname, but only for non-NS records.
+      # NS records get this substitution on the value instead.
+      $host = _ZONE($zone, $host) if $type != 2;
 
       # Fill in the forward domain ID if we can find it, otherwise:
@@ -2948,5 +2959,12 @@
 		(id => $id, type => ($revrec eq 'n' ? 'domain' : 'revzone'), revrec => $revrec) )
 	if $defrec eq 'n';
-  $logdata{entry} = "Added ".($defrec eq 'y' ? 'default record' : 'record')." '$$host $typemap{$$rectype} $$val";
+  $logdata{entry} = "Added ".($defrec eq 'y' ? 'default record' : 'record');
+  # NS records for revzones get special treatment
+  if ($revrec eq 'y' && $$rectype == 2) {
+    $logdata{entry} .= " '$$val $typemap{$$rectype} $$host";
+  } else {
+    $logdata{entry} .= " '$$host $typemap{$$rectype} $$val";
+  }
+
   $logdata{entry} .= " [distance $dist]" if $typemap{$$rectype} eq 'MX';
   $logdata{entry} .= " [priority $dist] [weight $weight] [port $port]"
@@ -3083,10 +3101,21 @@
 		(id => $parid, type => ($revrec eq 'n' ? 'domain' : 'revzone'), revrec => $revrec) )
 	if $defrec eq 'n';
-  $logdata{entry} = "Updated ".($defrec eq 'y' ? 'default record' : 'record')." from\n".
-	"'$oldrec->{host} $typemap{$oldrec->{type}} $oldrec->{val}";
+  $logdata{entry} = "Updated ".($defrec eq 'y' ? 'default record' : 'record')." from\n";
+  # NS records for revzones get special treatment
+  if ($revrec eq 'y' && $$rectype == 2) {
+    $logdata{entry} .= " '$oldrec->{val} $typemap{$oldrec->{type}} $oldrec->{host}";
+  } else {
+    $logdata{entry} .= " '$oldrec->{host} $typemap{$oldrec->{type}} $oldrec->{val}";
+  }
   $logdata{entry} .= " [distance $oldrec->{distance}]" if $typemap{$oldrec->{type}} eq 'MX';
   $logdata{entry} .= " [priority $oldrec->{distance}] [weight $oldrec->{weight}] [port $oldrec->{port}]"
 	if $typemap{$oldrec->{type}} eq 'SRV';
-  $logdata{entry} .= "', TTL $oldrec->{ttl}\nto\n'$$host $typemap{$$rectype} $$val";
+  $logdata{entry} .= "', TTL $oldrec->{ttl}\nto\n";
+  # More NS special
+  if ($revrec eq 'y' && $$rectype == 2) {
+    $logdata{entry} .= "'$$val $typemap{$$rectype} $$host";
+  } else {
+    $logdata{entry} .= "'$$host $typemap{$$rectype} $$val";
+  }
   $logdata{entry} .= " [distance $dist]" if $typemap{$$rectype} eq 'MX';
   $logdata{entry} .= " [priority $dist] [weight $weight] [port $port]" if $typemap{$$rectype} eq 'SRV';
Index: trunk/dns.sql
===================================================================
--- trunk/dns.sql	(revision 327)
+++ trunk/dns.sql	(revision 328)
@@ -54,6 +54,6 @@
 1	1	hostmaster.ADMINDOMAIN:ns1.ADMINDOMAIN	6	3600:900:1048576:2560	3600	
 2	1	unused-%r.ADMINDOMAIN	65283	ZONE	3600	
-3	1	ZONE	2	ns2.example.com	7200	\N
-4	1	ZONE	2	ns1.example.com	7200	\N
+3	1	ns2.example.com	2	ZONE	7200	\N
+4	1	ns1.example.com	2	ZONE	7200	\N
 \.
 
