Index: trunk/DNSDB.pm
===================================================================
--- trunk/DNSDB.pm	(revision 253)
+++ trunk/DNSDB.pm	(revision 254)
@@ -36,5 +36,5 @@
 	&addRec &updateRec &delRec
 	&getTypelist
-	&getParents
+	&parentID
 	&isParent
 	&domStatus &importAXFR
@@ -58,5 +58,5 @@
 		&addRec &updateRec &delRec
 		&getTypelist
-		&getParents
+		&parentID
 		&isParent
 		&domStatus &importAXFR
@@ -2235,28 +2235,47 @@
 
 
-## DNSDB::getParents()
-# Find out which entities are parent to the requested id
-# Returns arrayref containing hash pairs of id/type
-sub getParents {
-  my $dbh = shift;
-  my $id = shift;
-  my $type = shift;
-  my $depth = shift || 'all';	# valid values:  'all', 'immed', <int> (stop at this group ID)
-
-  my @parlist;
-
-  while (1) {
-    my $result = $dbh->selectrow_hashref("SELECT $par_col{$type} FROM $par_tbl{$type} WHERE $id_col{$type} = ?",
-	undef, ($id) );
-    my %tmp = ($result->{$par_col{$type}} => $par_type{$type});
-    unshift @parlist, \%tmp;
-    last if $result->{$par_col{$type}} == 1;	# group 1 is its own parent
-    $id = $result->{$par_col{$type}};
-    $type = $par_type{$type};
-  }
-
-  return \@parlist;
-
-} # end getParents()
+## DNSDB::parentID()
+# Get ID of entity that is nearest parent to requested id
+# Takes a database handle and a hash of entity ID, entity type, optional parent type flag
+# (domain/reverse zone or group), and optional default/live and forward/reverse flags
+# Returns the ID or undef on failure
+sub parentID {
+  my $dbh = shift;
+
+  my %args = @_;
+
+  # clean up the parent-type.  Set it to group if not set;  coerce revzone to domain for simpler logic
+  $args{partype} = 'group' if !$args{partype};
+  $args{partype} = 'domain' if $args{partype} eq 'revzone';
+
+  # clean up defrec and revrec.  default to live record, forward zone
+  $args{defrec} = 'n' if !$args{defrec};
+  $args{revrec} = 'n' if !$args{revrec};
+
+  if ($par_type{$args{partype}} eq 'domain') {
+    # only live records can have a domain/zone parent
+    return unless ($args{type} eq 'record' && $args{defrec} eq 'n');
+    my $result = $dbh->selectrow_hashref("SELECT ".($args{revrec} eq 'n' ? 'domain_id' : 'rdns_id').
+	" FROM records WHERE record_id = ?",
+	undef, ($args{id}) ) or return;
+    return $result;
+  } else {
+    # snag some arguments that will either fall through or be overwritten to save some code duplication
+    my $tmpid = $args{id};
+    my $type = $args{type};
+    if ($type eq 'record' && $args{defrec} eq 'n') {
+      # Live records go through the records table first.
+      ($tmpid) = $dbh->selectrow_array("SELECT ".($args{revrec} eq 'n' ? 'domain_id' : 'rdns_id').
+	" FROM records WHERE record_id = ?",
+	undef, ($args{id}) ) or return;
+      $type = ($args{revrec} eq 'n' ? 'domain' : 'revzone');
+    }
+    my ($result) = $dbh->selectrow_array("SELECT $par_col{$type} FROM $par_tbl{$type} WHERE $id_col{$type} = ?",
+	undef, ($tmpid) );
+    return $result;
+  }
+# should be impossible to get here with even remotely sane arguments
+  return;
+} # end parentID()
 
 
Index: trunk/dns.cgi
===================================================================
--- trunk/dns.cgi	(revision 253)
+++ trunk/dns.cgi	(revision 254)
@@ -314,5 +314,6 @@
       my $stat = domStatus($dbh,$webvar{id},$webvar{domstatus});
 ##fixme  switch to more consise "Enabled <domain"/"Disabled <domain>" as with users?
-      logaction($webvar{id}, $session->param("username"), parentID($webvar{id}, 'dom', 'group'),
+      logaction($webvar{id}, $session->param("username"),
+	parentID($dbh, (id => $webvar{id}, type => 'domain', revrec => $webvar{revrec})),
 	"Changed ".domainName($dbh, $webvar{id})." state to ".($stat ? 'active' : 'inactive'));
       $page->param(resultmsg => "Changed ".domainName($dbh, $webvar{id})." state to ".
@@ -403,5 +404,5 @@
 
   } elsif ($webvar{del} eq 'ok') {
-    my $pargroup = parentID($webvar{id}, 'dom', 'group');
+    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});
@@ -587,5 +588,6 @@
 		if $typemap{$webvar{type}} eq 'SRV';
 	$restr .= " $webvar{address}', TTL $webvar{ttl}";
-	logaction($webvar{parentid}, $session->param("username"), parentID($webvar{parentid}, 'dom', 'group'), $restr);
+	logaction($webvar{parentid}, $session->param("username"),
+		parentID($dbh, (id => $webvar{parentid}, type => 'domain', revrec => $webvar{revrec})), $restr);
       }
       my %pageparams = (page => "reclist", id => $webvar{parentid},
@@ -608,5 +610,6 @@
 		"Failed adding default record '$webvar{name} $typemap{$webvar{type}} $webvar{address}', TTL $webvar{ttl} ($msg)");
 	} else {
-	  logaction($webvar{parentid}, $session->param("username"), parentID($webvar{parentid}, 'dom', 'group'),
+	  logaction($webvar{parentid}, $session->param("username"),
+		parentID($dbh, (id => $webvar{parentid}, type => 'domain', revrec => $webvar{revrec})),
 		"Failed adding record '$webvar{name} $typemap{$webvar{type}} $webvar{address}', TTL $webvar{ttl} ($msg)");
 	}
@@ -658,5 +661,8 @@
 	my $restr = "Updated record from '$oldrec->{host} $typemap{$oldrec->{type}} $oldrec->{val}', TTL $oldrec->{ttl}\n".
 		"to '$webvar{name} $typemap{$webvar{type}} $webvar{address}', TTL $webvar{ttl}";
-	logaction($webvar{parentid}, $session->param("username"), parentID($webvar{id}, 'rec', 'group'), $restr);
+	logaction($webvar{parentid}, $session->param("username"),
+		parentID($dbh, (id => $webvar{id}, type => 'record', defrec => $webvar{defrec},
+			revrec => $webvar{revrec}, partype => 'group')),
+		$restr);
 	changepage(page => "reclist", id => $webvar{parentid}, defrec => $webvar{defrec}, resultmsg => $restr);
       }
@@ -675,5 +681,6 @@
 		"Failed updating default record '$typemap{$webvar{type}} $webvar{name} $webvar{address}', TTL $webvar{ttl} ($msg)");
 	} else {
-	  logaction($webvar{parentid}, $session->param("username"), parentID($webvar{parentid}, 'dom', 'group'),
+	  logaction($webvar{parentid}, $session->param("username"),
+		parentID($dbh, (id => $webvar{parentid}, type => 'domain', revrec => $webvar{revrec})),
 		"Failed updating record '$typemap{$webvar{type}} $webvar{name} $webvar{address}', TTL $webvar{ttl} ($msg)");
 	}
@@ -735,5 +742,7 @@
 	my $recclass = ($webvar{revrec} eq 'n' ? 'record' : 'reverse record');
 	my $restr = "Deleted $recclass '$rec->{host} $typemap{$rec->{type}} $rec->{val}', TTL $rec->{ttl}";
-	logaction($rec->{parid}, $session->param("username"), parentID($rec->{parid}, 'dom', 'group'), $restr);
+	logaction($rec->{parid}, $session->param("username"),
+		parentID($dbh, (id => $rec->{parid}, type => 'domain', revrec => $webvar{revrec})),
+		$restr);
 	changepage(page => "reclist", id => $webvar{parentid}, defrec => $webvar{defrec},
 		revrec => $webvar{revrec}, resultmsg => $restr);
@@ -747,5 +756,6 @@
 		" TTL $rec->{ttl} ($msg)");
 	} else {
-	  logaction($rec->{parid}, $session->param("username"), parentID($rec->{parid}, 'dom', 'group'),
+	  logaction($rec->{parid}, $session->param("username"),
+		parentID($dbh, (id => $rec->{parid}, type => 'domain', revrec => $webvar{revrec})),
 		"Failed deleting record '$rec->{host} $typemap{$rec->{type}} $rec->{val}', TTL $rec->{ttl} ($msg)");
 	}
@@ -828,5 +838,5 @@
       $logdomain = 0;
     } else {
-      $loggroup = parentID($logdomain, 'dom', 'group', $webvar{defrec});
+      $loggroup = parentID($dbh, (id => $logdomain, type => 'domain', revrec => $webvar{revrec}));
     }
 
@@ -936,5 +946,5 @@
   } elsif ($webvar{del} eq 'ok') {
     my $deleteme = groupName($dbh,$webvar{id}); # get this before we delete it...
-    my $delparent = parentID($webvar{id}, 'group','group');
+    my $delparent = parentID($dbh, (id => $webvar{id}, type => 'group'));
     my ($code,$msg) = delGroup($dbh, $webvar{id});
     if ($code eq 'OK') {
@@ -1079,9 +1089,11 @@
       my ($code, $msg) = changeGroup($dbh, 'domain', $webvar{$_}, $webvar{destgroup});
       if ($code eq 'OK') {
-        logaction($webvar{$_}, $session->param("username"), parentID($webvar{$_}, 'dom', 'group'),
+        logaction($webvar{$_}, $session->param("username"),
+		parentID($dbh, (id => $webvar{$_}, type => 'domain', revrec => $webvar{revrec})),
 		"Moved domain ".domainName($dbh, $webvar{$_})." to group $newgname");
         $row{domok} = ($code eq 'OK');
       } else {
-        logaction($webvar{$_}, $session->param("username"), parentID($webvar{$_}, 'dom', 'group'),
+        logaction($webvar{$_}, $session->param("username"),
+		parentID($dbh, (id => $webvar{$_}, type => 'domain', revrec => $webvar{revrec})),
 		"Failed to move domain ".domainName($dbh, $webvar{$_})." to group $newgname: $msg")
 		if $config{log_failures};
@@ -1110,6 +1122,7 @@
 ##fixme:  error handling on status change
       my $stat = domStatus($dbh,$webvar{$_},($webvar{bulkaction} eq 'activate' ? 'domon' : 'domoff'));
-      logaction($webvar{$_}, $session->param("username"), parentID($webvar{$_}, 'dom', 'group'),
-		"Changed domain ".domainName($dbh, $webvar{$_})." state to ".($stat ? 'active' : 'inactive'));
+      logaction($webvar{$_}, $session->param("username"),
+	parentID($dbh, (id => $webvar{$_}, type => 'domain', revrec => $webvar{revrec})),
+	"Changed domain ".domainName($dbh, $webvar{$_})." state to ".($stat ? 'active' : 'inactive'));
       $row{domok} = 1;
 #      $row{domok} = ($code eq 'OK');
@@ -1135,5 +1148,5 @@
       }
       $row{domain} = domainName($dbh,$webvar{$_});
-      my $pargroup = parentID($webvar{$_}, 'dom', 'group');
+      my $pargroup = parentID($dbh, (id => $webvar{$_}, type => 'domain', revrec => $webvar{revrec}));
       my $dom = domainName($dbh, $webvar{$_});
       my ($code, $msg) = delDomain($dbh, $webvar{$_});
@@ -1168,5 +1181,5 @@
     if ($flag && ($permissions{admin} || $permissions{user_edit})) {
       my $stat = userStatus($dbh,$webvar{id},$webvar{userstatus});
-      logaction(0, $session->param("username"), parentID($webvar{id}, 'user', 'group'),
+      logaction(0, $session->param("username"), parentID($dbh, (id => $webvar{id}, type => 'user')),
 	($stat ? 'Enabled' : 'Disabled')." ".userFullName($dbh, $webvar{id}, '%u'));
       $page->param(resultmsg => ($stat ? 'Enabled' : 'Disabled')." ".userFullName($dbh, $webvar{id}, '%u'));
@@ -2255,40 +2268,4 @@
 
 
-##fixme:  generalize to return appropriate id on all cases (ie, use $partype)
-sub parentID {
-  my $id = shift;
-  my $idtype = shift;
-  my $partype = shift;
-  my $defrec = shift || '';
-
-  my $sql = '';
-
-  if ($idtype eq 'dom') {
-    return $id if $defrec eq 'y';  # "domain" + default records, we're really looking at a group.
-    $sql = "SELECT group_id FROM domains WHERE domain_id=?";
-  } elsif ($idtype eq 'rec') {
-    if ($defrec eq 'y') {
-      $sql = "SELECT group_id FROM default_records WHERE record_id=?";
-    } else {
-      $sql = "SELECT d.group_id FROM domains d".
-    	" INNER JOIN records r ON d.domain_id=r.domain_id".
-	" WHERE r.record_id=?";
-    }
-  } elsif ($idtype eq 'group') {
-    $sql = "SELECT parent_group_id FROM groups WHERE group_id=?";
-  } elsif ($idtype eq 'user') {
-    $sql = "SELECT group_id FROM users WHERE user_id=?";
-  } else {
-    return "FOO", "BAR";  # can't get here.... we think.
-  }
-  my $sth = $dbh->prepare($sql);
-  $sth->execute($id);
-  my ($retid) = $sth->fetchrow_array;
-  return $retid if $retid;
-  # ahh! fall of the edge of the world if things went sideways
-  ##fixme:  really need to do a little more error handling, I think
-} # end parentID()
-
-
 # we have to do this in a variety of places;  let's make it consistent
 sub fill_permissions {
