update-serial
changeset 31 1cea07056124
parent 30 5ac92c1ffdf9
equal deleted inserted replaced
30:5ac92c1ffdf9 31:1cea07056124
     2 # (c) 1998 Heiko Schlittermann <heiko@datom.de>
     2 # (c) 1998 Heiko Schlittermann <heiko@datom.de>
     3 #
     3 #
     4 # … work in progress do integrate dnssec (branch suess)
     4 # … work in progress do integrate dnssec (branch suess)
     5 #
     5 #
     6 # Update the serial numbers in zone files
     6 # Update the serial numbers in zone files
     7 # The serial number needs to match a specified pattern (see 
     7 # The serial number needs to match a specified pattern (see
     8 # the line marked w/ PATTERN.
     8 # the line marked w/ PATTERN.
     9 # 
     9 #
    10 # ToDo:
    10 # ToDo:
    11 # . test against an md5 sum, not just the date of the stamp file
    11 # . test against an md5 sum, not just the date of the stamp file
    12 # . FIXME: handle `/' in file names (currently only working in 
    12 # . FIXME: handle `/' in file names (currently only working in
    13 #   the current directory)
    13 #   the current directory)
    14 # . optionally reload the named
    14 # . optionally reload the named
    15 
       
    16 
    15 
    17 use strict;
    16 use strict;
    18 use warnings;
    17 use warnings;
    19 
    18 
    20 use File::Basename;
    19 use File::Basename;
    21 use File::Copy;
    20 use File::Copy;
    22 use FindBin;
    21 use FindBin;
    23 
    22 
    24 my @configs = ( "$FindBin::Bin/dnstools.conf", "/etc/dnstools.conf" );
    23 my @configs = ( "$FindBin::Bin/dnstools.conf", "/etc/dnstools.conf" );
    25 my @dnssec_signs = ( "$FindBin::Bin/dnssec-sign", "/usr/bin/dnstools/dnssec-sign");
    24 my @dnssec_signs
       
    25     = ( "$FindBin::Bin/dnssec-sign", "/usr/bin/dnstools/dnssec-sign" );
    26 my %config;
    26 my %config;
    27 my $dnssec_sign;
    27 my $dnssec_sign;
       
    28 my @change_names = ();
    28 
    29 
    29 foreach ( grep {-f} @configs ) {
    30 foreach ( grep {-f} @configs ) {
    30     open( CONFIG, $_ ) or die "Can't open $_: $!\n";
    31     open( CONFIG, $_ ) or die "Can't open $_: $!\n";
    31 }
    32 }
    32 
    33 
    33 unless ( seek( CONFIG, 0, 0 ) ) {
    34 unless ( seek( CONFIG, 0, 0 ) ) {
    34     die "Can't open config (searched: @configs)\n";
    35     die "Can't open config (searched: @configs)\n";
    35 }
    36 }
    36 foreach ( grep {-f} @dnssec_signs ) {
    37 foreach ( grep {-f} @dnssec_signs ) {
    37 	if (-x $_) {
    38     if ( -x $_ ) {
    38 		$dnssec_sign = $_;
    39         $dnssec_sign = $_;
    39 	}
    40     }
    40 	else {
    41     else {
    41 		die "Can't run $_\n"
    42         die "Can't run $_\n";
    42 	}
    43     }
    43 }
    44 }
    44 
       
    45 
    45 
    46 while (<CONFIG>) {
    46 while (<CONFIG>) {
    47     chomp;
    47     chomp;
    48     s/#.*//;
    48     s/#.*//;
    49     s/\t//g;
    49     s/\t//g;
    67 
    67 
    68 sub cleanup() { unlink @tmpfiles; }
    68 sub cleanup() { unlink @tmpfiles; }
    69 END { cleanup(); }
    69 END { cleanup(); }
    70 
    70 
    71 for (@ARGV) {
    71 for (@ARGV) {
    72 	if ($_ eq "-y") {
    72     if ( $_ eq "-y" ) {
    73 		$opt_yes = 1;
    73         $opt_yes = 1;
    74 		shift @ARGV;
    74         shift @ARGV;
    75 	}
    75     }
    76 }
    76 }
    77 
    77 
    78 @Zones = @ARGV ? @ARGV : glob("$master_dir/*");
    78 @Zones = @ARGV ? @ARGV : glob("$master_dir/*");
    79 
    79 
       
    80 MAIN: {
       
    81     my $changed;
       
    82     my ( $dd, $mm, $yy ) = ( localtime() )[ 3 .. 5 ];
       
    83     my $date;
       
    84     $mm++;
    80 
    85 
    81 MAIN: {
    86     foreach ( $dd, $mm ) { s/^\d$/0$&/; }
    82 	my $changed;
    87     $yy += 1900;
    83 	my ($dd, $mm, $yy) =(localtime())[3..5];
    88     $date = "$yy$mm$dd";
    84 	my $date;
       
    85 	$mm++;
       
    86 
    89 
    87 	foreach ($dd, $mm) { s/^\d$/0$&/; }
    90     while ( my $file = shift @Zones ) {
    88 	$yy += 1900;
       
    89 	$date = "$yy$mm$dd";
       
    90 
    91 
       
    92         my $file_basename = basename($file);
    91 
    93 
    92 	while (my $file = shift @Zones) {
    94         $file =~ s#($master_dir)(/.*)#$1$2$2#;
       
    95         local ( *I, *O );
       
    96         my $done = 0;
    93 
    97 
    94 		my $file_basename = basename($file);
    98         my $new   = "$file.$$.tmp";
       
    99         my $bak   = "$file.bak";
       
   100         my $stamp = $master_dir . "/.stamp/" . basename($file);
    95 
   101 
    96 		$file =~ s#($master_dir)(/.*)#$1$2$2#;
   102         $file =~ /(\.bak|~)$/ and next;
    97 		local (*I, *O);
   103         $file !~ /\./ and next;
    98 		my $done = 0;
       
    99 
   104 
   100 		my $new = "$file.$$.tmp";
   105         $verbose && print "$file:";
   101 		my $bak = "$file.bak";
       
   102 		my $stamp = $master_dir . "/.stamp/" . basename($file);	
       
   103 
   106 
   104 		$file =~ /(\.bak|~)$/ and next;
   107         if ( -f $stamp && ( ( stat($stamp) )[9] >= ( stat($file) )[9] ) ) {
   105 		$file !~ /\./ and next;
   108             $verbose && print " fresh, skipping.\n";
       
   109             next;
       
   110         }
   106 
   111 
   107 		$verbose && print "$file:";
   112         $done = 0;
       
   113         push @tmpfiles, $new;
       
   114         open( *I, "<$file" ) or die("Can't open < $file: $!\n");
       
   115         open( *O, ">$new" )  or die("Can't open > $new: $!\n");
   108 
   116 
       
   117         while (<I>) {
       
   118             /^\s+((\d+)(\d{2}))\s*;\s*serial/i and do {    # PATTERN
       
   119                 my ( $sdate, $scount, $serial ) = ( $2, $3, $1 );
       
   120                 $done = 1;
       
   121                 print " [$file] serial $sdate$scount";
   109 
   122 
   110 		if (-f $stamp && ((stat($stamp))[9] >= (stat($file))[9])) {
   123                 if   ( $date eq $sdate ) { $scount++; }
   111 			$verbose && print " fresh, skipping.\n";
   124                 else                     { $sdate = $date; $scount = "00"; }
   112 			next;
       
   113 		}
       
   114 
   125 
   115 		$done = 0;
   126                 print " bumping to $sdate$scount";
   116 		push @tmpfiles, $new;
   127                 s/$serial/$sdate$scount/;
   117 		open(*I, "<$file") or die("Can't open < $file: $!\n");
       
   118 		open(*O, ">$new") or die("Can't open > $new: $!\n");
       
   119 
   128 
   120 		while (<I>) {
   129             };
   121 			/^\s+((\d+)(\d{2}))\s*;\s*serial/i and do {		# PATTERN
   130             print O;
   122 				my ($sdate, $scount, $serial) = ($2, $3, $1);
   131         }
   123 				$done = 1;
       
   124 				print " [$file] serial $sdate$scount";
       
   125 
   132 
   126 				if ($date eq $sdate) { $scount++; }
   133         close(O);
   127 				else { $sdate = $date; $scount = "00"; }
   134         close(I);
   128 
   135 
   129 				print " bumping to $sdate$scount \n";
   136         if ($done) {
   130 				s/$serial/$sdate$scount/;
       
   131 
   137 
   132 			};
   138             # copy($file, $bak) or die("Can't copy $file -> $bak: $!\n");
   133 			print O;
       
   134 		}
       
   135 
   139 
   136 		close(O); close(I);
   140             open( I, "<$new" )  or die("Can't open <$new: $!\n");
       
   141             open( O, ">$file" ) or die("Can't open >$file: $!\n");
       
   142             while (<I>) { print O or die("Can't write to $file: $!\n"); }
       
   143             close(I) or die("Can't close $new: $!\n");
       
   144             close(O) or die("Can't close $file: $!\n");
   137 
   145 
   138 		if ($done) {
   146             unlink $new;
   139 			# copy($file, $bak) or die("Can't copy $file -> $bak: $!\n");
       
   140 
   147 
   141 			open(I, "<$new") or die("Can't open <$new: $!\n");
   148             open( O, ">$stamp" ) or die("Can't open >$stamp: $!\n");
   142 			open(O, ">$file") or die("Can't open >$file: $!\n");
   149             close(O);
   143 			while (<I>) { print O or die("Can't write to $file: $!\n"); }
   150             $changed++;
   144 			close(I) or die("Can't close $new: $!\n");
       
   145 			close(O) or die("Can't close $file: $!\n");
       
   146 
   151 
   147 			unlink $new;
   152             push @change_names, $file_basename;
   148 
   153 
   149 			open(O, ">$stamp") or die("Can't open >$stamp: $!\n");
   154         }
   150 			close(O);
   155         else {
   151 			$changed++;
   156             print " $file: no serial number found: no zone file?";
       
   157         }
       
   158         print "\n";
       
   159     }
   152 
   160 
   153 			# dnssec - new sign
   161     if ($changed) {
   154 			system "$dnssec_sign $file_basename";
   162         my $pidfile;
   155 			die "$dnssec_sign not found ($!)" if $? == -1;
       
   156 			exit 1 if $?;
       
   157 
   163 
   158 		} else {
   164         # dnssec - new sign
   159 			print " $file: no serial number found: no zone file?";
   165         system "$dnssec_sign @change_names";
   160 		}
   166         die "$dnssec_sign not found ($!)" if $? == -1;
   161 		print "\n";
   167         exit 1 if $?;
   162 	}
       
   163 
   168 
   164 	if ($changed) {
   169         print
   165 		my $pidfile;
   170             "** Changed $changed files, the nameserver needs to be reloaded!\n";
       
   171         foreach (
       
   172             qw(/var/run/bind/run/named.pid /var/run/named.pid /etc/named.pid))
       
   173         {
       
   174             -f $_ and $pidfile = $_ and last;
       
   175         }
   166 
   176 
   167 		print "** Changed $changed files, the nameserver needs to be reloaded!\n";
   177         if ($pidfile) {
   168 		foreach (qw(/var/run/bind/run/named.pid /var/run/named.pid /etc/named.pid)) { 
   178             if ($opt_yes) {
   169 			-f $_ and $pidfile = $_ and last; }
   179                 $_ = "y";
       
   180                 print "** Nameserver will be reloaded\n";
       
   181             }
       
   182             else { print "** Reload now? [Y/n]: "; $_ = <STDIN>; }
       
   183             /^y|^$/i and system "rndc reload";
       
   184         }
       
   185         else {
       
   186             print
       
   187                 "** No PID of a running named found.  Please reload manually.\n";
       
   188         }
   170 
   189 
   171 		if ($pidfile) {
   190     }
   172 			if ($opt_yes) { $_ = "y"; print "** Nameserver will be reloaded\n"; } 
       
   173 			else { print "** Reload now? [Y/n]: "; $_ = <STDIN>; }
       
   174 			/^y|^$/i and system "rndc reload";
       
   175 		} else {
       
   176 			print "** No PID of a running named found.  Please reload manually.\n";
       
   177 		}
       
   178 
       
   179 	}
       
   180 }
   191 }
   181 
   192 
   182 # vim:ts=4:sw=4:ai:aw:
   193 # vim:ts=4:sw=4:ai:aw: