#!/usr/local/bin/perl # Reverse # # Douglas Thrift # # $Id$ use strict; use warnings; use Net::hostent; use POSIX qw(:time_h :unistd_h); use Socket; my @hostnames; open DAT, "$ENV{HOME}/.reverse.dat" or die "$0: $!"; while () { $hostnames[$#hostnames + 1] = $& if (/^[^#].*$/); } close DAT; my $namedb = geteuid == 0 ? '/etc/namedb' : '.'; open CONF, "$namedb/named.conf" or die "$0: $!"; my $conf; while () { $conf .= $_; } my $updated = 0; for my $hostname (@hostnames) { my $host = gethostbyname $hostname; if (defined $host) { my $address = inet_ntoa($host->addr); my $zone = join ('.', reverse unpack('C4', $host->addr)) . '.in-addr.arpa'; $host = gethostbyaddr ($host->addr, AF_INET); if (!defined ($host) || $host->name ne $hostname) { my $serialnum = strftime('%Y%m%d01', localtime); if ($conf =~ /\n# $hostname\nzone "((\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.in-addr\.arpa)" {\n\ttype master;\n\tfile "reverse\/\1";\n};\n/) { next if ($1 eq $zone); open ZONE, '>', "$namedb/reverse/$zone" or die "$0: $!"; my $oldaddress = "$5.$4.$3.$2"; my $oldzone = $1; my $oldzonefile = "$namedb/reverse/$oldzone"; open OLDZONE, $oldzonefile; $oldaddress =~ s/\./\\./g; $oldzone =~ s/\./\\./g; while () { s/$oldzone/$zone/; s/\d{10} ; serial$/$serialnum ; serial/; print ZONE; } close OLDZONE; unlink $oldzonefile; $conf =~ s/\t$oldaddress;/\t$address;/g; $conf =~ s/"((?:reverse\/)?)$oldzone"/"$1$zone"/g; } else { open ZONE, '>', "$namedb/reverse/$zone" or die "$0: $!"; print ZONE "\$ORIGIN . \$TTL 3600 ; 1 hour $zone IN SOA ns.douglasthrift.net. admin.douglasthrift.net. ( $serialnum ; serial 7200 ; refresh (2 hours) 3600 ; retry (1 hour) 604800 ; expire (1 week) 3600 ; minimum (1 hour) ) NS ns.douglasthrift.net. PTR $hostname. "; $conf .= " # $hostname zone \"$zone\" { type master; file \"reverse/$zone\"; }; "; } close ZONE; $updated = 1; } } elsif ($conf =~ s/\n# $hostname\nzone "(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\.in-addr\.arpa)" {\n\ttype master;\n\tfile "reverse\/\1";\n};\n//) { unlink "$namedb/reverse/$1"; $updated = 1; } } if ($updated) { open CONF, '>', "$namedb/named.conf" or die "$0: $!"; print CONF $conf; } close CONF; exec {'/usr/sbin/rndc'} 'rndc', 'reconfig' or die "$0: $!" if ($updated && geteuid == 0);