Index: branches/stable/dns.cgi
===================================================================
--- branches/stable/dns.cgi	(revision 725)
+++ branches/stable/dns.cgi	(revision 756)
@@ -3,5 +3,5 @@
 ##
 # $Id$
-# Copyright 2008-2013 Kris Deugau <kdeugau@deepnet.cx>
+# Copyright 2008-2016 Kris Deugau <kdeugau@deepnet.cx>
 # 
 #    This program is free software: you can redistribute it and/or modify
@@ -120,5 +120,5 @@
 $webvar{startwith} =~ s/^(0-9|[a-z]).*/$1/ if $webvar{startwith};
 # not much call for chars not allowed in domain names
-$webvar{filter} =~ s/[^a-zA-Z0-9_.:\@-]//g if $webvar{filter};
+$webvar{filter} =~ s/[^a-zA-Z0-9_.:\@%-]//g if $webvar{filter};
 ## only set 'y' if box is checked, no other values legal
 ## however, see https://secure.deepnet.cx/trac/dnsadmin/ticket/31
@@ -138,4 +138,5 @@
 # @#$%@%@#% XHTML - & in a URL must be escaped.  >:(
 my $uri_self = $ENV{REQUEST_URI};
+$uri_self = "/dns.cgi" if !$uri_self || $uri_self eq '/';
 $uri_self =~ s/\&([a-z])/\&amp\;$1/g;
 
@@ -455,4 +456,5 @@
 
   if ($code eq 'OK') {
+    $webvar{domain} = lc($webvar{domain}) if $dnsdb->{lowercase};
     $dnsdb->mailNotify("New ".($webvar{makeactive} eq 'on' ? 'Active' : 'Inactive')." Domain Created",
 	($webvar{makeactive} eq 'on' ? 'Active' : 'Inactive').qq( domain "$webvar{domain}" added by ).
@@ -1795,9 +1797,6 @@
 ##fixme:  where should we call this from?
     $id = $webvar{id};
-    if (!check_scope(id => $id, type => 'user')) {
-      $page->param(errmsg => "You are not permitted to view log entries for the requested user");
-      goto DONELOG;
-    }
-    $page->param(logfor => 'user '.$dnsdb->userFullName($id));
+##fixme:  don't include username on out-of-scope users
+    $page->param(logfor => 'user '.($id ? $dnsdb->userFullName($id) : $webvar{fname}));
   } elsif ($webvar{ltype} && $webvar{ltype} eq 'dom') {
     $id = $webvar{id};
@@ -1821,5 +1820,24 @@
   }
   $webvar{ltype} = 'group' if !$webvar{ltype};
-  my $lcount = $dnsdb->getLogCount(id => $id, logtype => $webvar{ltype}) or push @debugbits, $dnsdb->errstr;
+
+  # Done here since we want to allow more arbitrary blobs in the log filter
+  if (defined($webvar{logfilter})) {
+    $session->param('logfilter', '') if !$session->param('logfilter');
+    if ($webvar{logfilter} ne $session->param('logfilter')) {
+      $uri_self =~ s/\&amp;offset=[^&]//;
+      $offset = 0;
+    }
+    $session->param('logfilter', $webvar{logfilter})
+  }
+  my $logfilter = $session->param('logfilter');
+  $filter = $logfilter;
+  $page->param(logfilter => $logfilter);
+
+  my $lcount = $dnsdb->getLogCount(id => $id, group => $logingroup, fname => $webvar{fname},
+    logtype => $webvar{ltype}, filter => $logfilter);
+  if (!$lcount) {
+    $page->param(errmsg => $dnsdb->errstr);
+    $lcount = 0;
+  }
 
   $page->param(id => $id);
@@ -1840,16 +1858,22 @@
 
   # Set up the column headings with the sort info
-  my @cols = ('fname','username','entry','stamp');
-  my %colnames = (fname => 'Name', username => 'Username', entry => 'Log Entry', stamp => 'Date/Time');
+  my @cols = ('fname','domain','revzone','entry','stamp');
+  my %colnames = (fname => 'Name', domain => 'Forward zone', revzone => 'Reverse zone',
+      entry => 'Log Entry', stamp => 'Date/Time');
   fill_colheads($sortby, $sortorder, \@cols, \%colnames);
 
 ##fixme:  increase per-page limit or use separate limit for log?  some ops give *lots* of entries...
-  my $logentries = $dnsdb->getLogEntries(id => $id, logtype => $webvar{ltype},
-	offset => $webvar{offset}, sortby => $sortby, sortorder => $sortorder);
-  $page->param(logentries => $logentries);
+  my $logentries = $dnsdb->getLogEntries(id => $id, group => $logingroup, fname => $webvar{fname},
+        logtype => $webvar{ltype},
+	offset => $webvar{offset}, sortby => $sortby, sortorder => $sortorder, filter => $logfilter);
+  if (!$logentries) {
+    $page->param(errmsg => $dnsdb->errstr);
+  } else {
+    # undef $logentries is inexplicably puking instead of showing "no entries found",
+    # like all the rest of the methods that return a list the same way.  idunno...
+    $page->param(logentries => $logentries);
+  }
 
 ##fixme:
-# - filtering
-# - show reverse zone column?
 # - on log record creation, bundle "parented" log actions (eg, "AXFR record blah for domain foo",
 #   or "Add record bar for new domain baz") into one entry (eg, "AXFR domain foo", "Add domain baz")?
@@ -1858,4 +1882,51 @@
   # scope check fail target
   DONELOG: ;
+
+} elsif ($webvar{page} eq 'recsearch') {
+
+  # we do this for the domain and record list filter/search - it should be extremely rare to
+  # need to search on characters outside this set until we get into IDNs
+  # note this is a little larger due to template records
+  $webvar{searchfor} =~ s/[^a-zA-Z0-9_.:\@%-]//g if $webvar{searchfor};
+
+  # save the search in the session, same as the "filter" in various other lists...
+  if (defined($webvar{searchfor})) {
+    if ($session->param('recsearch') && $webvar{searchfor} ne $session->param('recsearch')) {
+      $uri_self =~ s/\&amp;offset=[^&]//;
+      $offset = 0;
+    }
+    $session->param(recsearch => $webvar{searchfor});
+  }
+  my $searchfor = $session->param('recsearch');
+
+  $sortby = 'host';
+  $session->param($webvar{page}.'sortby', $webvar{sortby}) if $webvar{sortby};
+  $session->param($webvar{page}.'order', $webvar{order}) if $webvar{order};
+  $sortby = $session->param($webvar{page}.'sortby') if $session->param($webvar{page}.'sortby');
+  $sortorder = $session->param($webvar{page}.'order') if $session->param($webvar{page}.'order');
+
+  # some magic to label and linkify the column headers for sorting
+  my @cols = ('domain','revzone','host','type','val');
+  my %colheads = (domain => "Domain (Group)", revzone => "Reverse zone (Group)", host => "Host",
+	type => "Type", val => "IP/value");
+  # only users allowed to see location/view data get this column
+  if ($permissions{admin} || $permissions{location_view}) {
+    $colheads{location} = "Location";
+    push @cols, 'location';
+  }
+  fill_colheads($sortby, $sortorder, \@cols, \%colheads);
+
+  # pgcount.tmpl
+  my $count = $dnsdb->recSearchCount(searchfor => $searchfor, group => $logingroup);
+  fill_pgcount($count, "records");
+  fill_fpnla($count);
+
+  # and a bit for fpnla.tmpl
+  $page->param(curpage => $webvar{page});
+
+  $page->param(searchfor => $searchfor);
+  my $recset = $dnsdb->recSearch(searchfor => $searchfor, group => $logingroup, offset => $webvar{offset},
+    sortby => $sortby, sortorder => $sortorder);
+  $page->param(searchresults => $recset);
 
 } # end $webvar{page} dance
