Index: trunk/DNSDB.pm
===================================================================
--- trunk/DNSDB.pm	(revision 644)
+++ trunk/DNSDB.pm	(revision 653)
@@ -597,5 +597,5 @@
       # Forcibly append the domain name if the hostname being added does not end with the current domain name
       my $pname = $self->domainName($args{id});
-      ${$args{host}} =~ s/\.*$/\.$pname/ if ${$args{host}} !~ /$pname$/;
+      ${$args{host}} =~ s/\.*$/\.$pname/ if (${$args{host}} ne '@' && ${$args{host}} !~ /$pname$/);
     }
   } else {
@@ -659,5 +659,5 @@
     # CNAMEs can not be used for parent nodes;  just leaf nodes with no other record types
     # Enforce this for the zone name
-    return ('FAIL', "The bare zone name may not be a CNAME") if ${$args{host}} eq $pname;
+    return ('FAIL', "The bare zone name may not be a CNAME") if ${$args{host}} eq $pname || ${$args{host}} =~ /^\@/;
 
 ##enhance:  Look up the passed value to see if it exists.  Ooo, fancy.
@@ -742,5 +742,5 @@
       # Fetch the domain and append if the passed hostname isn't within it.
       my $pname = ($args{defrec} eq 'y' ? 'DOMAIN' : $self->domainName($args{id}));
-      ${$args{host}} =~ s/\.*$/\.$pname/ if ${$args{host}} !~ /$pname$/;
+      ${$args{host}} =~ s/\.*$/\.$pname/ if (${$args{host}} ne '@' && ${$args{host}} !~ /$pname$/);
       # Validate hostname and target for form
       return ('FAIL', $errstr) if ! _check_hostname_form(${$args{host}}, ${$args{rectype}}, $args{defrec}, $args{revrec});
@@ -817,5 +817,6 @@
     # or the intended parent domain for live records.
     my $pname = ($args{defrec} eq 'y' ? 'DOMAIN' : $self->domainName($args{id}));
-    ${$args{host}} =~ s/\.*$/\.$pname/ if ${$args{host}} !~ /$pname$/;
+    ${$args{host}} =~ s/\.*$/\.$pname/ if (${$args{host}} ne '@' && ${$args{host}} !~ /$pname$/);
+    return ('FAIL', $errstr) if ! _check_hostname_form(${$args{host}}, ${$args{rectype}}, $args{defrec}, $args{revrec});
   } else {
     # MX target check - IP addresses not allowed.  Must be a more or less well-formed hostname.
@@ -855,5 +856,5 @@
     # or the intended parent domain for live records.
     my $pname = ($args{defrec} eq 'y' ? 'DOMAIN' : $self->domainName($args{id}));
-    ${$args{host}} =~ s/\.*$/\.$pname/ if ${$args{host}} !~ /$pname$/;
+    ${$args{host}} =~ s/\.*$/\.$pname/ if (${$args{host}} ne '@' && ${$args{host}} !~ /$pname$/);
     return ('FAIL', $errstr) if ! _check_hostname_form(${$args{host}}, ${$args{rectype}}, $args{defrec}, $args{revrec});
   } else {
@@ -1115,5 +1116,11 @@
       ${$args{fields}} .= "rdns_id,";
       push @{$args{vallist}}, $revid;
-    }
+
+      # Coerce the hostname back to the domain;  this is so it displays and manipulates
+      # sanely in the reverse zone.
+      if (${$args{host}} eq '@') {
+        ${$args{host}} = $self->domainName($args{id});  # errors?  What errors?
+      }
+    } # revrec ne 'y'
 
   } else {	# defrec eq 'y'
@@ -1243,7 +1250,13 @@
   if ($args{defrec} eq 'n') {
     if ($args{revrec} eq 'n') {
-      ($code,$msg) = $self->_validate_1(%args) if ${$args{rectype}} == 65280;
-      ($code,$msg) = $self->_validate_28(%args) if ${$args{rectype}} == 65281;
-      return ($code,$msg) if $code eq 'FAIL';
+
+      # Coerce all hostnames to end in ".DOMAIN" for group/default records,
+      # or the intended parent domain for live records.
+      my $pname = $self->domainName($args{id});
+      ${$args{host}} =~ s/\.*$/\.$pname/ if ${$args{host}} !~ /$pname$/;
+
+      # check for form;  note this checks both normal and "other" hostnames.
+      return ('FAIL', $errstr)
+	if !_check_hostname_form(${$args{host}}, ${$args{rectype}}, $args{defrec}, $args{revrec});
 
       # Check if the requested reverse zone exists - note, an IP fragment won't
@@ -1632,5 +1645,5 @@
     # we don't actually need to test with the real IP passed;  that saves a bit of fiddling.
     _template4_expand(\$tmphost, '10.10.10.10');
-    if ($tmphost =~ /\%/) {
+    if ($tmphost =~ /\%/ || lc($tmphost) !~ /^(?:\*\.)?(?:[0-9a-z_.-]+)$/) {
       $errstr = "Invalid template $hname";
       return;
