Index: trunk/DNSDB.pm
===================================================================
--- trunk/DNSDB.pm	(revision 273)
+++ trunk/DNSDB.pm	(revision 274)
@@ -39,5 +39,5 @@
 	&changeGroup
 	&loadConfig &connectDB &finish
-	&addDomain &delDomain &domainName &revName &domainID &addRDNS
+	&addDomain &delZone &domainName &revName &domainID &addRDNS
 	&getZoneCount &getZoneList
 	&addGroup &delGroup &getChildren &groupName
@@ -61,5 +61,5 @@
 		&changeGroup
 		&loadConfig &connectDB &finish
-		&addDomain &delDomain &domainName &revName &domainID &addRDNS
+		&addDomain &delZone &domainName &revName &domainID &addRDNS
 		&getZoneCount &getZoneList
 		&addGroup &delGroup &getChildren &groupName
@@ -1266,11 +1266,13 @@
 
 
-## DNSDB::delDomain()
-# Delete a domain.
+## DNSDB::delZone()
+# Delete a forward or reverse zone.
+# Takes a database handle, zone ID, and forward/reverse flag.
 # for now, just delete the records, then the domain.
 # later we may want to archive it in some way instead (status code 2, for example?)
-sub delDomain {
-  my $dbh = shift;
-  my $domid = shift;
+sub delZone {
+  my $dbh = shift;
+  my $zoneid = shift;
+  my $revrec = shift;
 
   # Allow transactions, and raise an exception on errors so we can catch it later.
@@ -1283,10 +1285,30 @@
   # Wrap all the SQL in a transaction
   eval {
-    my $sth = $dbh->prepare("delete from records where domain_id=?");
-    $failmsg = "Failure removing domain records";
-    $sth->execute($domid);
-    $sth = $dbh->prepare("delete from domains where domain_id=?");
-    $failmsg = "Failure removing domain";
-    $sth->execute($domid);
+    # Disentangle custom record types before removing the
+    # ones that are only in the zone to be deleted
+    if ($revrec eq 'n') {
+      my $sth = $dbh->prepare("UPDATE records SET type=?,domain_id=0 WHERE domain_id=? AND type=?");
+      $failmsg = "Failure converting multizone types to single-zone";
+      $sth->execute($reverse_typemap{PTR}, $zoneid, 65280);
+      $sth->execute($reverse_typemap{PTR}, $zoneid, 65281);
+      $sth->execute(65282, $zoneid, 65283);
+      $sth->execute(65282, $zoneid, 65284);
+      $failmsg = "Failure removing domain records";
+      $dbh->do("DELETE FROM records WHERE domain_id=?", undef, ($zoneid));
+      $failmsg = "Failure removing domain";
+      $dbh->do("DELETE FROM domains WHERE domain_id=?", undef, ($zoneid));
+    } else {
+      my $sth = $dbh->prepare("UPDATE records SET type=?,rdns_id=0 WHERE rdns_id=? AND type=?");
+      $failmsg = "Failure converting multizone types to single-zone";
+      $sth->execute($reverse_typemap{A}, $zoneid, 65280);
+      $sth->execute($reverse_typemap{AAAA}, $zoneid, 65281);
+# We don't have an "A template" or "AAAA template" type, although it might be useful for symmetry.
+#      $sth->execute(65285?, $zoneid, 65283);
+#      $sth->execute(65285?, $zoneid, 65284);
+      $failmsg = "Failure removing reverse records";
+      $dbh->do("DELETE FROM records WHERE rdns_id=?", undef, ($zoneid));
+      $failmsg = "Failure removing reverse zone";
+      $dbh->do("DELETE FROM revzones WHERE rdns_id=?", undef, ($zoneid));
+    }
 
     # once we get here, we should have suceeded.
@@ -1302,5 +1324,5 @@
   }
 
-} # end delDomain()
+} # end delZone()
 
 
Index: trunk/dns.cgi
===================================================================
--- trunk/dns.cgi	(revision 273)
+++ trunk/dns.cgi	(revision 274)
@@ -416,5 +416,5 @@
     my $pargroup = parentID($dbh, (id => $webvar{id}, type => 'domain', revrec => $webvar{revrec}));
     my $dom = domainName($dbh, $webvar{id});
-    my ($code,$msg) = delDomain($dbh, $webvar{id});
+    my ($code,$msg) = delZone($dbh, $webvar{id}, $webvar{revrec});
     if ($code eq 'OK') {
       logaction($webvar{id}, $session->param("username"), $pargroup, "Deleted domain $dom");
@@ -434,4 +434,14 @@
 
   $webvar{revrec} = 'y';
+
+  if ($session->param('resultmsg')) {
+    $page->param(resultmsg => $session->param('resultmsg'));
+    $session->clear('resultmsg');
+  }
+  if ($session->param('errmsg')) {
+    $page->param(errmsg => $session->param('errmsg'));
+    $session->clear('errmsg');
+  }
+
   $page->param(curpage => $webvar{page});
   listzones();
@@ -480,5 +490,41 @@
   }
 
-#} elsif ($webvar{page} eq 'delrevzone') {
+} elsif ($webvar{page} eq 'delrevzone') {
+
+  changepage(page => "revzones", errmsg => "You are not permitted to delete reverse zones")
+	unless ($permissions{admin} || $permissions{domain_delete});
+
+  # security check - does the user have permission to access this entity?
+  if (!check_scope(id => $webvar{id}, type => 'revzone')) {
+    changepage(page => "revzones", errmsg => "You do not have permission to delete the requested reverse zone");
+  }
+
+  $page->param(id => $webvar{id});
+
+  # first pass = confirm y/n (sorta)
+  if (!defined($webvar{del})) {
+
+    $page->param(del_getconf => 1);
+    $page->param(revzone => revName($dbh,$webvar{id}));
+
+  } elsif ($webvar{del} eq 'ok') {
+    my $pargroup = parentID($dbh, (id => $webvar{id}, type => 'revzone', revrec => $webvar{revrec}));
+    my $zone = revName($dbh, $webvar{id});
+    my ($code,$msg) = delZone($dbh, $webvar{id}, 'y');
+    if ($code eq 'OK') {
+##fixme: logaction needs to take "domid OR revid" and some way to know which it is
+      logaction($webvar{id}, $session->param("username"), $pargroup, "Deleted reverse zone $zone");
+      changepage(page => "revzones", resultmsg => "Deleted reverse zone $zone");
+    } else {
+      logaction($webvar{id}, $session->param("username"), $pargroup, "Failed to delete domain $zone ($msg)")
+	if $config{log_failures};
+#push @debugbits, "got back $code, $msg\n";
+      changepage(page => "revzones", errmsg => "Error deleting reverse zone $zone: $msg");
+    }
+
+  } else {
+    # cancelled.  whee!
+    changepage(page => "revzones");
+  }
 
 } elsif ($webvar{page} eq 'reclist') {
@@ -1205,5 +1251,5 @@
       my $pargroup = parentID($dbh, (id => $webvar{$_}, type => 'domain', revrec => $webvar{revrec}));
       my $dom = domainName($dbh, $webvar{$_});
-      my ($code, $msg) = delDomain($dbh, $webvar{$_});
+      my ($code, $msg) = delZone($dbh, $webvar{$_}, 'n');
       if ($code eq 'OK') {
         logaction($webvar{$_}, $session->param("username"), $pargroup, "Deleted domain $dom");
Index: trunk/templates/delrevzone.tmpl
===================================================================
--- trunk/templates/delrevzone.tmpl	(revision 274)
+++ trunk/templates/delrevzone.tmpl	(revision 274)
@@ -0,0 +1,12 @@
+<TMPL_IF del_getconf>
+<table class="wholepage"><tr>
+<TMPL_INCLUDE NAME="menu.tmpl">
+
+<td align="center" valign="top">
+<h3>Are you really sure you want to delete reverse zone <TMPL_VAR NAME=revzone>?</h3>
+<a href="dns.cgi?sid=<TMPL_VAR NAME=sid>&amp;page=delrevzone&amp;del=cancel&amp;id=<TMPL_VAR NAME=id>">cancel</a> &nbsp; | &nbsp; <a href="dns.cgi?sid=<TMPL_VAR NAME=sid>&amp;page=delrevzone&amp;del=ok&amp;id=<TMPL_VAR NAME=id>">confirm</a>
+</td></tr></table>
+
+<TMPL_ELSE>
+<TMPL_INCLUDE NAME="revzones.tmpl">
+</TMPL_IF>
