- Timestamp:
- 01/03/14 14:58:09 (11 years ago)
- Location:
- trunk
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/DNSDB.pm
r581 r583 213 213 force_refresh => 1, 214 214 lowercase => 0, # mangle as little as possible by default 215 showrec_arpa_ns => 0, # show formal .arpa zone name instead of logical CIDR on reverse NS records 215 # show IPs and CIDR blocks as-is for reverse zones. valid values are 216 # 'none' (default, show natural IP or CIDR) 217 # 'zone' (zone name, wherever used) 218 # 'record' (IP or CIDR values in reverse record lists) 219 # 'all' (all IP values in any reverse zone view) 220 showrev_arpa => 'none', 216 221 ); 217 222 … … 243 248 244 249 # Several settings are booleans. Handle multiple possible ways of setting them. 245 for my $boolopt ('log_failures', 'force_refresh', 'lowercase', 'usecache' , 'showrec_arpa_ns') {250 for my $boolopt ('log_failures', 'force_refresh', 'lowercase', 'usecache') { 246 251 if ($self->{$boolopt} ne '1' && $self->{$boolopt} ne '0') { 247 252 # true/false, on/off, yes/no all valid. … … 253 258 } 254 259 } else { 255 warn "Bad $boolopt setting $self->{$boolopt} \n";256 $self->{$boolopt} = 1;260 warn "Bad $boolopt setting $self->{$boolopt}, using default\n"; 261 $self->{$boolopt} = $defconfig{$boolopt}; 257 262 } 258 263 } 264 } 265 266 # Enum-ish option(s) 267 if (!grep /$self->{showrev_arpa}/, ('none','zone','record','all')) { 268 warn "Bad showrev_arpa setting $self->{showrev_arpa}, using default\n"; 269 $self->{showrev_arpa} = 'none'; 259 270 } 260 271 … … 1136 1147 # v4 revzone, formal zone name type 1137 1148 my $tmpzone = $zone; 1149 return ('FAIL', "Non-numerics in apparent IPv4 reverse zone name [$tmpzone]") 1150 if $tmpzone !~ m{^(?:\d+[/-])?[\d\.]+\.in-addr\.arpa\.?$}; 1138 1151 $tmpzone =~ s/\.in-addr\.arpa\.?//; 1139 return ('FAIL', "Non-numerics in apparent IPv4 reverse zone name [$tmpzone]") if $tmpzone !~ m{^(?:\d+[/-])?[\d\.]+$};1140 1152 1141 1153 # Snag the octet pieces … … 1185 1197 } 1186 1198 1187 } elsif ($zone =~ /\.ip6\.arpa $/) {1199 } elsif ($zone =~ /\.ip6\.arpa\.?$/) { 1188 1200 # v6 revzone, formal zone name type 1189 1201 my $tmpzone = $zone; 1202 ##fixme: if-n-when we decide we can support sub-nibble v6 zone names, we'll need to change this segment 1203 return ('FAIL', "Non-hexadecimals in apparent IPv6 reverse zone name [$tmpzone]") 1204 if $tmpzone !~ /^[a-fA-F\d\.]+\.ip6\.arpa\.?$/; 1190 1205 $tmpzone =~ s/\.ip6\.arpa\.?//; 1191 ##fixme: if-n-when we decide we can support sub-nibble v6 zone names, we'll need to change this segment1192 return ('FAIL', "Non-hexadecimals in apparent IPv6 reverse zone name") if $tmpzone !~ /^[a-fA-F\d\.]+$/;1193 1206 my @quads = reverse(split(/\./, $tmpzone)); 1194 1207 $warnmsg .= "Apparent sub-/64 IPv6 reverse zone\n" if $#quads > 15; … … 1196 1209 foreach (@quads) { 1197 1210 $tmpcidr .= $_; 1198 $tmpcidr .= ":" if ++$nc % 4 == 0 ;1211 $tmpcidr .= ":" if ++$nc % 4 == 0 && $nc < $#quads; 1199 1212 } 1200 1213 my $nq = 1 if $nc % 4 != 0; … … 1203 1216 $tmpcidr .= "0"; 1204 1217 } 1205 $tmpcidr .= ($nq ? '::' : ':')."/$mask"; 1218 # polish it off with trailing ::/mask if this is a CIDR block instead of an IP 1219 $tmpcidr .= "::/$mask" if $mask != 128; 1206 1220 } 1207 1221 … … 1215 1229 } 1216 1230 return ('OK', $cidr); 1231 ##fixme: use wantarray() to decide what to return? 1217 1232 } # done _zone2cidr() 1218 1233 … … 1343 1358 $cfg->{force_refresh} = $1 if /^force_refresh\s*=\s*([a-z01]+)/i; 1344 1359 $cfg->{lowercase} = $1 if /^lowercase\s*=\s*([a-z01]+)/i; 1345 $cfg->{showre c_arpa_ns} = $1 if /^showrec_arpa_ns\s*=\s*([a-z01]+)/i;1360 $cfg->{showrev_arpa} = $1 if /^showrev_arpa\s*=\s*([a-z]+)/i; 1346 1361 # not supported in dns.cgi yet 1347 1362 # $cfg->{templatedir} = $1 if m{^templatedir\s*=\s*([a-z0-9/_.-]+)}i; … … 1999 2014 ## DNSDB::revName() 2000 2015 # Return the reverse zone name based on an rDNS ID 2001 # Takes a database handle and the rDNS ID 2016 # Takes a database handle and the rDNS ID, and an optional flag to force return of the CIDR zone 2017 # instead of the formal .arpa zone name 2002 2018 # Returns the reverse zone name or undef on failure 2003 2019 sub revName { … … 2006 2022 my $dbh = $self->{dbh}; 2007 2023 my $revid = shift; 2024 my $cidrflag = shift || 'n'; 2008 2025 my ($revname) = $dbh->selectrow_array("SELECT revnet FROM revzones WHERE rdns_id=?", undef, ($revid) ); 2009 2026 $errstr = $DBI::errstr if !$revname; 2027 my $tmp = new NetAddr::IP $revname; 2028 $revname = _ZONE($tmp, 'ZONE', 'r', '.').($tmp->{isv6} ? '.ip6.arpa' : '.in-addr.arpa') 2029 if ($self->{showrev_arpa} eq 'zone' || $self->{showrev_arpa} eq 'all') && $cidrflag eq 'n'; 2010 2030 return $revname if $revname; 2011 2031 } # end revName() … … 2061 2081 my $self = shift; 2062 2082 my $dbh = $self->{dbh}; 2063 my $zone = NetAddr::IP->new(shift); 2083 my $zone = shift; 2084 2085 # Autodetect formal .arpa zones 2086 if ($zone =~ /\.arpa\.?$/) { 2087 my $code; 2088 ($code,$zone) = _zone2cidr($zone); 2089 return ('FAIL', $zone) if $code eq 'FAIL'; 2090 } 2091 $zone = NetAddr::IP->new($zone); 2064 2092 2065 2093 return ('FAIL',"Zone name must be a valid CIDR netblock") unless ($zone && $zone->addr !~ /^0/); … … 2265 2293 $sql = "SELECT count(*) FROM revzones". 2266 2294 " WHERE group_id IN ($args{curgroup}".($args{childlist} ? ",$args{childlist}" : '').")". 2267 ($args{startwith} ? " AND CAST(revnet AS VARCHAR) ~* ?" : ''). 2268 ($args{filter} ? " AND CAST(revnet AS VARCHAR) ~* ?" : ''); 2295 ($args{startwith} ? " AND CAST(revnet AS VARCHAR) ~* ?" : ''); 2296 # if ($self->{showrev_arpa} eq 'zone' || $self->{showrev_arpa} eq 'all') { 2297 # Just In Case the UI is using formal .arpa notation, and someone enters something reversed, 2298 # we want to match both the formal and natural zone name 2299 $sql .= ($args{filter} ? " AND (CAST(revnet AS VARCHAR) ~* ? OR CAST(revnet AS VARCHAR) ~* ?)" : ''); 2300 push @filterargs, join('[.]',reverse(split(/\[\.\]/,$args{filter}))) if $args{filter}; 2301 # } else { 2302 # $sql .= ($args{filter} ? " AND CAST(revnet AS VARCHAR) ~* ?" : ''); 2303 # } 2269 2304 } 2270 2305 my ($count) = $dbh->selectrow_array($sql, undef, @filterargs); … … 2320 2355 " INNER JOIN groups ON revzones.group_id=groups.group_id". 2321 2356 " WHERE revzones.group_id IN ($args{curgroup}".($args{childlist} ? ",$args{childlist}" : '').")". 2322 ($args{startwith} ? " AND CAST(revnet AS VARCHAR) ~* ?" : ''). 2323 ($args{filter} ? " AND CAST(revnet AS VARCHAR) ~* ?" : ''); 2357 ($args{startwith} ? " AND CAST(revnet AS VARCHAR) ~* ?" : ''); 2358 # if ($self->{showrev_arpa} eq 'zone' || $self->{showrev_arpa} eq 'all') { 2359 # Just In Case the UI is using formal .arpa notation, and someone enters something reversed, 2360 # we want to match both the formal and natural zone name 2361 $sql .= ($args{filter} ? " AND (CAST(revnet AS VARCHAR) ~* ? OR CAST(revnet AS VARCHAR) ~* ?)" : ''); 2362 push @filterargs, join('[.]',reverse(split(/\[\.\]/,$args{filter}))) if $args{filter}; 2363 # } else { 2364 # $sql .= ($args{filter} ? " AND CAST(revnet AS VARCHAR) ~* ?" : ''); 2365 # } 2324 2366 } 2325 2367 # A common tail. … … 2328 2370 " OFFSET ".$args{offset}*$self->{perpage}); 2329 2371 2330 my $ret = $dbh->selectall_arrayref($sql, { Slice => {} }, @filterargs); 2331 return $ret; 2372 my @working; 2373 my $zsth = $dbh->prepare($sql); 2374 $zsth->execute(@filterargs); 2375 while (my $zone = $zsth->fetchrow_hashref) { 2376 if ($args{revrec} eq 'y' && ($self->{showrev_arpa} eq 'zone' || $self->{showrev_arpa} eq 'all')) { 2377 my $tmp = new NetAddr::IP $zone->{zone}; 2378 $zone->{zone} = DNSDB::_ZONE($tmp, 'ZONE', 'r', '.').($tmp->{isv6} ? '.ip6.arpa' : '.in-addr.arpa'); 2379 } 2380 push @working, $zone; 2381 } 2382 return \@working; 2332 2383 } # end getZoneList() 2333 2384 … … 3491 3542 if (!$oldsoa) { 3492 3543 # old SOA record is missing for some reason. create a new one. 3493 my $sql = "INSERT INTO "._rectable($defrec, $revrec)." (group_id, host, type, val, ttl) VALUES (?,?,6,?,?)"; 3544 my $sql = "INSERT INTO "._rectable($defrec, $revrec)." ("._recparent($defrec, $revrec). 3545 ", host, type, val, ttl) VALUES (?,?,6,?,?)"; 3494 3546 $dbh->do($sql, undef, ($soa{id}, "$soa{contact}:$soa{prins}", 3495 3547 "$soa{refresh}:$soa{retry}:$soa{expire}:$soa{minttl}", $soa{ttl}) ); … … 3632 3684 push @bindvars, ($args{filter},$args{filter}) if $args{filter}; 3633 3685 3634 my $ret = $dbh->selectall_arrayref($sql, { Slice => {} }, (@bindvars) ); 3635 $errstr = "Error retrieving records: ".$dbh->errstr if !$ret; 3636 3637 return $ret; 3686 my @working; 3687 my $recsth = $dbh->prepare($sql); 3688 $recsth->execute(@bindvars); 3689 while (my $rec = $recsth->fetchrow_hashref) { 3690 if ($args{revrec} eq 'y' && ($self->{showrev_arpa} eq 'record' || $self->{showrev_arpa} eq 'all')) { 3691 ##enhance: extend {showrev_arpa} eq 'record' to specify record types 3692 my $tmp = new NetAddr::IP $rec->{val}; 3693 $rec->{val} = DNSDB::_ZONE($tmp, 'ZONE', 'r', '.').($tmp->{isv6} ? '.ip6.arpa' : '.in-addr.arpa'); 3694 } 3695 push @working, $rec; 3696 } 3697 return \@working; 3638 3698 } # end getRecList() 3639 3699 … … 3724 3784 3725 3785 # prep for validation 3786 # Autodetect formal .arpa names 3787 if ($$val =~ /\.arpa\.?$/) { 3788 my ($code,$tmpval) = _zone2cidr($$val); 3789 return ('FAIL', $tmpval) if $code eq 'FAIL'; 3790 $$val = $tmpval; 3791 } 3726 3792 my $addr = NetAddr::IP->new($$val); 3727 3793 $$host =~ s/\.+$//; # FQDNs ending in . are an internal detail, and really shouldn't be exposed in the UI. -
trunk/dns.cgi
r581 r583 2004 2004 2005 2005 foreach my $rec (@$foo2) { 2006 # NS records. Need to do this first before we convert the type-value to the text representation2007 if ($rev eq 'y' && $dnsdb->{showrec_arpa_ns} && $rec->{type} == $reverse_typemap{NS}) {2008 my $tmp = new NetAddr::IP $rec->{val};2009 $rec->{val} = DNSDB::_ZONE($tmp, 'ZONE', 'r', '.').($tmp->{isv6} ? '.ip6.arpa' : '.in-addr.arpa');2010 }2011 2006 $rec->{type} = $typemap{$rec->{type}}; 2012 2007 $rec->{fwdzone} = $rev eq 'n'; … … 2034 2029 2035 2030 sub fill_recdata { 2036 $page->param(typelist => $dnsdb->getTypelist($webvar{revrec}, $webvar{type})); 2037 2038 # le sigh. we may get called with many empty %webvar keys 2031 # le sigh. we may get called with many empty %webvar keys 2039 2032 no warnings qw( uninitialized ); 2040 2033 … … 2042 2035 # prefill <domain> or DOMAIN in "Host" space for new records 2043 2036 if ($webvar{revrec} eq 'n') { 2037 $page->param(typelist => $dnsdb->getTypelist($webvar{revrec}, $webvar{type})); 2044 2038 my $domroot = ($webvar{defrec} eq 'y' ? 'DOMAIN' : $dnsdb->domainName($webvar{parentid})); 2045 2039 $page->param(name => ($webvar{name} ? $webvar{name} : $domroot)); … … 2052 2046 my $domroot = ($webvar{defrec} eq 'y' ? 'ADMINDOMAIN' : ".$dnsdb->{domain}"); 2053 2047 $page->param(name => ($webvar{name} ? $webvar{name} : $domroot)); 2054 my $zname = ($webvar{defrec} eq 'y' ? 'ZONE' : $dnsdb->revName($webvar{parentid})); 2048 my $zname = ($webvar{defrec} eq 'y' ? 'ZONE' : $dnsdb->revName($webvar{parentid}, 'y')); 2049 my $cidr = new NetAddr::IP $zname; 2055 2050 $zname =~ s|\d*/\d+$||; 2056 2051 $page->param(address => ($webvar{address} ? $webvar{address} : $zname)); 2052 $page->param(typelist => $dnsdb->getTypelist($webvar{revrec}, 2053 $webvar{type} || ($cidr->{isv6} ? $reverse_typemap{'AAAA+PTR'} : $reverse_typemap{'A+PTR'}))); 2057 2054 } 2058 2055 # retrieve the right ttl instead of falling (way) back to the hardcoded system default … … 2183 2180 ); 2184 2181 # probably don't need this, keeping for reference for now 2185 # foreach (@$zonelist) {2182 # foreach my $rec (@$zonelist) { 2186 2183 # } 2187 2184 $page->param(domtable => $zonelist); -
trunk/dnsdb.conf
r581 r583 38 38 #lowercase = 0 39 39 40 # Show formal .arpa zone name instead of usual CIDR for reverse zone NSrecords?41 #showre c_arpa_ns= 040 # Show formal .arpa zone name instead of the natural IP or CIDR for reverse zone names and records? 41 #showrev_arpa = 0 42 42 43 43 ## General RPC options -
trunk/textrecs.cgi
r581 r583 83 83 $rec->{val} = "$rec->{distance} $rec->{weight} $rec->{port} $rec->{val}" if $rec->{type} eq 'SRV'; 84 84 if ($webvar{revrec} eq 'y') { 85 if ($dnsdb->{showrec_arpa_ns} && $rec->{type} eq 'NS') {86 my $tmp = new NetAddr::IP $rec->{val};87 $rec->{val} = DNSDB::_ZONE($tmp, 'ZONE', 'r', '.').($tmp->{isv6} ? '.ip6.arpa' : '.in-addr.arpa');88 }89 85 printf "%-16s\t%d\t%s\t%s\n", $rec->{val}, $rec->{ttl}, $rec->{type}, $rec->{host}; 90 86 } else {
Note:
See TracChangeset
for help on using the changeset viewer.