lib/DNStools/UpdateSerial.pm
changeset 150 3db363880766
parent 138 046d8e631700
equal deleted inserted replaced
146:a3860111db49 150:3db363880766
    30 use File::Temp;
    30 use File::Temp;
    31 use IO::File;
    31 use IO::File;
    32 use POSIX qw(strftime);
    32 use POSIX qw(strftime);
    33 use if $ENV{DEBUG} => "Smart::Comments";
    33 use if $ENV{DEBUG} => "Smart::Comments";
    34 
    34 
    35 
       
    36 BEGIN {
    35 BEGIN {
    37 
    36 
    38     our ($VERSION, @ISA, @EXPORT);
    37     our ($VERSION, @ISA, @EXPORT);
    39     use Exporter;
    38     use Exporter;
    40 
    39 
    41     # set the version for version checking
    40     # set the version for version checking
    42     $VERSION     = 1.00;
    41     $VERSION = 1.00;
       
    42 
    43     # if using RCS/CVS, this may be preferred
    43     # if using RCS/CVS, this may be preferred
    44     $VERSION = sprintf "%d.%03d", q$Revision: 1.1 $ =~ /(\d+)/g;
    44     $VERSION = sprintf "%d.%03d", q$Revision: 1.1 $ =~ /(\d+)/g;
    45 
    45 
    46     @ISA         = qw(Exporter);
    46     @ISA    = qw(Exporter);
    47     @EXPORT      = qw(&uniq &zones &changed_zones &update_index
    47     @EXPORT = qw(&uniq &zones &changed_zones &update_index
    48     &signature_expired &need_rollover &done_rollover &begin_rollover
    48       &signature_expired &need_rollover &done_rollover &begin_rollover
    49     &end_rollover &unlink_unused_keys &include_keys &sign &update_serial
    49       &end_rollover &unlink_unused_keys &include_keys &sign &update_serial
    50     &mk_zone_conf &file_entry &server_reload &dnssec_enabled %config);
    50       &mk_zone_conf &file_entry &server_reload &dnssec_enabled %config);
    51 }
    51 }
    52 
    52 
    53 our %config;
    53 our %config;
    54 
    54 
    55 sub uniq(@);
    55 sub uniq(@);
   109             say " * $zone: no .stamp file found";    # NOCH IN NEW_SERIAL PUSHEN
   109             say " * $zone: no .stamp file found";    # NOCH IN NEW_SERIAL PUSHEN
   110             push @r, $zone;
   110             push @r, $zone;
   111             next;
   111             next;
   112         }
   112         }
   113 
   113 
   114         my $stamp_mtime = (stat _)[9];
   114         my $stamp_mtime     = (stat _)[9];
   115         my $zone_file_mtime  = (stat "$_/$zone")[9] or die "Can't stat '$_/$zone': $!";
   115         my $zone_file_mtime = (stat "$_/$zone")[9]
       
   116           or die "Can't stat '$_/$zone': $!";
   116 
   117 
   117         # stamp age 'wins' if mtimes are equal because update_serial will both
   118         # stamp age 'wins' if mtimes are equal because update_serial will both
   118         # modify the zonefile and update the stamp which both is likely to
   119         # modify the zonefile and update the stamp which both is likely to
   119         # happen at the 'same' time unless you have very very high precision
   120         # happen at the 'same' time unless you have very very high precision
   120         # mtimes
   121         # mtimes
   180 }
   181 }
   181 
   182 
   182 sub update_serial($) {
   183 sub update_serial($) {
   183 
   184 
   184     my $zone = shift;
   185     my $zone = shift;
   185 #    say "XXX: $zone: updating serial number";
   186 
       
   187     #    say "XXX: $zone: updating serial number";
   186 
   188 
   187     my $file = "$config{master_dir}/$zone/$zone";
   189     my $file = "$config{master_dir}/$zone/$zone";
   188     my $in   = IO::File->new($file) or die "Can't open $file: $!\n";
   190     my $in   = IO::File->new($file) or die "Can't open $file: $!\n";
   189     my $out  = File::Temp->new(DIR => dirname $file)
   191     my $out  = File::Temp->new(DIR => dirname $file)
   190       or die "Can't open tmpfile: $!\n";
   192       or die "Can't open tmpfile: $!\n";
   201 
   203 
   202     rename($out->filename => $file)
   204     rename($out->filename => $file)
   203       or die "Can't rename tmp to $file: $!\n";
   205       or die "Can't rename tmp to $file: $!\n";
   204 
   206 
   205     my $perms = (stat $file)[2] & 07777 | 040
   207     my $perms = (stat $file)[2] & 07777 | 040
   206         or die "Can't stat '$file': $!";
   208       or die "Can't stat '$file': $!";
   207     chmod $perms, $file
   209     chmod $perms, $file
   208         or die "Can't 'chmod $perms, $file': $!";
   210       or die "Can't 'chmod $perms, $file': $!";
   209 
   211 
   210     $serial =~ s/\s*//g;
   212     $serial =~ s/\s*//g;
   211     say " * $zone: serial incremented to $serial";
   213     say " * $zone: serial incremented to $serial";
   212 
   214 
   213     open(my $stamp, ">", dirname($file) . "/.stamp");
   215     open(my $stamp, ">", dirname($file) . "/.stamp");
   214 
   216 
   215     say " * $zone: stamp aktualisiert";
   217     say " * $zone: stamp aktualisiert";
   216 #    say " XXX $zone: stamp '$s' aktualisiert";
   218 
       
   219     #    say " XXX $zone: stamp '$s' aktualisiert";
   217 }
   220 }
   218 
   221 
   219 sub new_serial($) {
   222 sub new_serial($) {
   220 
   223 
   221     my ($date, $cnt) = $_[0] =~ /(\d{8})(\d\d)/;
   224     my ($date, $cnt) = $_[0] =~ /(\d{8})(\d\d)/;
   272           or die "Can't rename ", $fh->filename, " to $izf: $!\n";
   275           or die "Can't rename ", $fh->filename, " to $izf: $!\n";
   273         $fh->unlink_on_destroy(0);
   276         $fh->unlink_on_destroy(0);
   274     }
   277     }
   275 
   278 
   276     my $perms = (stat _)[2] & 07777 | 040
   279     my $perms = (stat _)[2] & 07777 | 040
   277         or die "Can't stat '$izf': $!";
   280       or die "Can't stat '$izf': $!";
   278     chmod $perms, $izf
   281     chmod $perms, $izf
   279         or die "Can't 'chmod $perms, $izf': $!";
   282       or die "Can't 'chmod $perms, $izf': $!";
   280 
   283 
   281     say "** index-zone aktualisiert";
   284     say "** index-zone aktualisiert";
   282     return $indexzone;
   285     return $indexzone;
   283 }
   286 }
   284 
   287 
   294         m#($md/)(.*)#;
   297         m#($md/)(.*)#;
   295         my $z  = $2;
   298         my $z  = $2;
   296         my $cf = "$cd/$z";
   299         my $cf = "$cd/$z";
   297         my $de = dnssec_enabled $z, "$md/$config{indexzone}/$config{indexzone}";
   300         my $de = dnssec_enabled $z, "$md/$config{indexzone}/$config{indexzone}";
   298         my $suf = $de ? '.signed' : '';
   301         my $suf = $de ? '.signed' : '';
   299         # TODO: assuming that paths in $md and in zone config snippets match somehow
   302 
       
   303     # TODO: assuming that paths in $md and in zone config snippets match somehow
   300         my $zr = qr{\Q$z/$z$suf\E$};
   304         my $zr = qr{\Q$z/$z$suf\E$};
   301         my $zf = "$md/$z/$z$suf";
   305         my $zf = "$md/$z/$z$suf";
   302 
   306 
   303         my ($files, $changed) = (0, 0);
   307         my ($files, $changed) = (0, 0);
   304         my $czf;
   308         my $czf;
   305         open C, "+<$cf" or die "Cant't open '$cf': $!";
   309         open C, "+<$cf" or die "Cant't open '$cf': $!";
   306         my @lines = <C>; # TODO: deal with race condition?
   310         my @lines = <C>;    # TODO: deal with race condition?
   307         my @oldlines;
   311         my @oldlines;
   308         my ($mode, $uid, $gid, $atime, $mtime) = (stat C)[2, 4, 5, 8, 9] or die "Can't stat: $!";
   312         my ($mode, $uid, $gid, $atime, $mtime) = (stat C)[2, 4, 5, 8, 9]
       
   313           or die "Can't stat: $!";
   309         $mode &= 07777;
   314         $mode &= 07777;
   310         for (@lines) {
   315         for (@lines) {
   311             next unless /^\s*file\s+"([^"]*)"\s*;\s*$/;
   316             next unless /^\s*file\s+"([^"]*)"\s*;\s*$/;
   312             $czf = $1;
   317             $czf = $1;
   313             $files++;
   318             $files++;
   316                 @oldlines or @oldlines = @lines;
   321                 @oldlines or @oldlines = @lines;
   317                 $_ = qq(\tfile "$zf";\n);
   322                 $_ = qq(\tfile "$zf";\n);
   318             }
   323             }
   319         }
   324         }
   320 
   325 
   321         die "Multiple file statements found in '$cf' (maybe inside multiline comments)" if $files > 1;
   326         die
       
   327 "Multiple file statements found in '$cf' (maybe inside multiline comments)"
       
   328           if $files > 1;
   322         next unless $changed;
   329         next unless $changed;
   323 
   330 
   324         # file statement in config snippet doesnt match, so we make a backup first and write a new config
   331 # file statement in config snippet doesnt match, so we make a backup first and write a new config
   325         my $cb = "$cf.bak";
   332         my $cb = "$cf.bak";
   326         open B, ">$cb" or die "Can't open '$cb': $!";
   333         open B, ">$cb" or die "Can't open '$cb': $!";
   327         print B @oldlines;
   334         print B @oldlines;
   328         close B;
   335         close B;
   329         chown $uid, $gid, $cb or die "Can't 'chown $uid, $gid, $cb': $!";
   336         chown $uid, $gid, $cb or die "Can't 'chown $uid, $gid, $cb': $!";
   330         chmod $mode, $cb or die "Can't 'chmod $mode, $cb': $!";
   337         chmod $mode, $cb or die "Can't 'chmod $mode, $cb': $!";
   331         utime $atime, $mtime, $cb or die "Can't 'utime $atime, $mtime, $cb': $!";
   338         utime $atime, $mtime, $cb
       
   339           or die "Can't 'utime $atime, $mtime, $cb': $!";
   332 
   340 
   333         truncate C, 0 or die "Can't truncate C, 0: $!";
   341         truncate C, 0 or die "Can't truncate C, 0: $!";
   334         seek C, 0, 0 or die "Can't seek C, 0, 0: $!";
   342         seek C, 0, 0 or die "Can't seek C, 0, 0: $!";
       
   343 
   335         # write back @lines we modified earlier
   344         # write back @lines we modified earlier
   336         print C @lines;
   345         print C @lines;
   337         close C;
   346         close C;
   338 
   347 
   339         print " * zonekonfiguration aktualisiert ($czf ==> $zf)\n";
   348         print " * zonekonfiguration aktualisiert ($czf ==> $zf)\n";
   366     return @r;
   375     return @r;
   367 }
   376 }
   368 
   377 
   369 sub done_rollover() {
   378 sub done_rollover() {
   370 
   379 
   371     # funktion ueberprueft ob ein keyrollover fertig ist
   380 # funktion ueberprueft ob ein keyrollover fertig ist
   372     # die bedingung dafuer ist das:
   381 # die bedingung dafuer ist das:
   373     # - eine datei .index.zsk vorhanden ist
   382 # - eine datei .index.zsk vorhanden ist
   374     # - die letzte änderung an der datei .index.zsk länger her ist als die abl_zeit
   383 # - die letzte änderung an der datei .index.zsk länger her ist als die abl_zeit
   375     # - die datei .index.zsk ueber mehr als eine zeile gross ist
   384 # - die datei .index.zsk ueber mehr als eine zeile gross ist
   376     #   (also mehr als einen Schlüssel enthält)
   385 #   (also mehr als einen Schlüssel enthält)
   377     my @r;
   386     my @r;
   378     my $now = time;
   387     my $now = time;
   379 
   388 
   380     while (my $dir = glob "$config{master_dir}/*") {
   389     while (my $dir = glob "$config{master_dir}/*") {
   381         my $zone = basename $dir;
   390         my $zone = basename $dir;
   535     my $re = qr/^[^;]*IN\s+TXT\s+"ZONE::\Q$z\E::sec-(on|off)"/;
   544     my $re = qr/^[^;]*IN\s+TXT\s+"ZONE::\Q$z\E::sec-(on|off)"/;
   536     my $r;
   545     my $r;
   537 
   546 
   538     open I, "<$if" or die "Can't open index zone file '<$if': $!";
   547     open I, "<$if" or die "Can't open index zone file '<$if': $!";
   539     while (<I>) {
   548     while (<I>) {
   540 #        say "XXX: match: $_" if /$re/;
   549 
       
   550         #        say "XXX: match: $_" if /$re/;
   541         $r = $1 eq 'on' and last if /$re/;
   551         $r = $1 eq 'on' and last if /$re/;
   542     }
   552     }
   543     close I;
   553     close I;
   544 
   554 
   545     return $r;
   555     return $r;