From: ianmdlvl Date: Sun, 30 Dec 2001 18:08:53 +0000 (+0000) Subject: /usr/local/sbin/named-conf-regen 5737 Nov 23 18:54 broken and found - checkin to cvs X-Git-Tag: debian_version_2_2_0~53 X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ian/git?p=chiark-utils.git;a=commitdiff_plain;h=4f4c11add419e120b2800a350f23091f47e7e03f /usr/local/sbin/named-conf-regen 5737 Nov 23 18:54 broken and found - checkin to cvs --- diff --git a/scripts/named-conf b/scripts/named-conf index 4bba39c..e788f07 100755 --- a/scripts/named-conf +++ b/scripts/named-conf @@ -1,198 +1,141 @@ -#!/bin/bash -set -e -base=/var/named -conf=$base/conf -etcfile=/etc/named/zones-rgc - -check=true -install=false -hostdelg=false -hostzone=false -progress=true -usage=true - -while [ $# -gt 0 ] -do - case "$1" in - -f) usage=false; check=false; install=true ;; - -y) usage=false; check=true; install=true ;; - -n) usage=false; check=true; install=false ;; - -h) hostdelg=true; hostzone=false ;; - -z) hostdelg=true; hostzone=true ;; - -q) progress=false ;; - *) echo >&2 "$0: usage: $0 [-y|-f] [-h|-z] [-q]"; exit 3 ;; - esac - shift -done - -if $usage -then - cat <&2 -usage: named-conf-regen -f|-y|-n [-h|-z] -operation modes: - -f install without checking } but you must then - -y check and install } ndc reload - -n check only -additional options: - -h check output from host -C - -z check output from host -C and host -val -END - exit 1 -fi +#!/usr/bin/perl -beginfile () { - if $install - then - exec >$conf/$1.new - else - exec >/dev/null - fi - currentfile=$1 -} +$base= "/var/named"; +$conf= "$base/conf"; +$etcfile= "/etc/named/zones-rgc"; -endfile () { - exec >/dev/null - files="$files $currentfile" -} +$check= 1; +$progress= 1; -installfiles () { - if $install - then - cd $conf - for f in $files - do - mv -f $f.new $f - done - fi +while ($ARGV[0] =~ m/^\-/) { + $_= shift @ARGV; + last if m/^\-\-?$/; + while (m/^\-./) { + if (s/^\-f/-/) { $usage=0; $check=0; $install++; } + elsif (s/^\-y/-/) { $usage=0; $check=1; $install++; } + elsif (s/^\-n/-/) { $usage=0; $check=1; $install=0; } + elsif (s/^\-h/-/) { $hostdelg=1; $hostzone=0; } + elsif (s/^\-z/-/) { $hostdelg=1; $hostzone=1; } + elsif (s/^\-q/-/) { $progress=0; } + else { $usage=1; break; } + } } -warnings=0 +die +"usage: named-conf-regen -f|-y|-n [-h|-z]\n". +"operation modes:\n". +" -f install without checking -ff and then ndc reload\n". +" -y check and install -yy and then ndc reload\n". +" -n check only\n". +"additional options:\n". +" -h check output from host -C\n". +" -z check output from host -C and host -val\n". + if $usage; -warning () { - echo >&2 "$zone $style: $*" - warnings=$[$warnings+1] +beginfile('secondary.zones'); +open E, "< $etcfile" or die "$0: open $etcfile: $!\n"; +for (;;) { + $!=0; defined $_= or die "$0: read $etcfile $!\n"; + s/^\s+//; chomp; s/\s+$//; + next if m/^\#/; + last if m/^end$/; + if (m/^myname\s+(\S.*\S)/) { + @mynames= split /\s+/, $1; + } elsif (m/^(secondary|backup|unoff)\s+(\S+)\s+([0-9. \t]+)$/) { + $style= $1; + $zone= $2; + @servers= split /\s+/, $3; + $file= "slave/$zone"; + progress(); + check(); + } else { + die "$0: $etcfile:$.: syntax error in \`$_'\n"; + } } -equlines () { - if [ "x`echo \" $2\" | wc -l`" != "x`echo \" $3\" | wc -l`" ] - then - warning "$1 >$2|$3<" - fi +sub lookup ($$) { + my ($type,$domain) = @_; + my ($c,@result); + defined($c=open ADH, "-|") or die "$0: fork adnshost: $!\n"; + if (!$c) { + exec 'adnshost','+Do','+Dt','+Dc','-Cf',"-t$type", + '-',"$domain."; + die "$0: exec adnshost: $!\n"; + } + @result= ; + chomp @result; + $!=0; close ADH; + die "$0: lookup -t$type $domain failed $? $!\n" if $? or $!; + return @result; } -checkhostout () { - set +e - hostout="`host $1 \"$zone\" 2>&1 >/dev/null $2 | egrep -v \ -'^ \!\!\! .* SOA primary .* is not advertised via NS$'`" - set -e - if [ "x$hostout" = x ]; then return; fi - if $hostfirstwarn - then - warning "warnings from host:" - hostfirstwarn=false - fi - echo >&2 "$hostout" +sub lookup1 ($$) { + my ($type,$domain) = @_; + my (@result)= lookup($type,$domain); + @result==1 or die "$0: lookup -t$type $domain gave more than one RR\n"; + return $result[0]; } -progress () { - if $progress - then - echo -n "$zone $style " >&2 - echo -ne '\r' >&2 - fi -} +sub check () { + return unless $check; + eval { + $soa= lookup1('soa',$zone); + $soa_origin=$soa; $soa_origin =~ s/ .*//; + $soa_origin_addr= lookup1('a',$soa_origin); -cd $base/primary -zones="*_db" + @zone_ns= lookup('ns-',$zone); -beginfile primary.zones -for f in $zones -do - zone="`echo $f | sed -e 's/_db$//'`" - cat <&2 "$etcfile: $style" - exit 3 - esac - - if $check - then - set -e; ns="`host -t ns $zone.`"; set +e - nsnames="`echo \" $ns\" | expand | tr A-Z a-z | sed -n ' - 1s/^ // - s/^[^ ][^ ]* *ns *\([0-9a-z][-.0-9a-z]*\)$/\1/p - '`" - equlines NS "$nsnames" "$ns" - nsnames="`echo $nsnames | tr ' -' ' '`" - - if [ "x$myname" != x ] - then - meadvert=false - for ns in $nsnames - do - if [ "x$myname" = "x$ns" ] - then - meadvert=true - fi - done - fi + for $server (@servers) { + grep { $server eq $_ } @ok_sources + or warn "secondarying from $server which is not ". + "$ok_sources_desc\n"; + } - case "$style" in - secondary) names="$soaname" ;; - unoff|backup) names="$nsnames" ;; - esac + if ($style eq 'secondary') { + grep { $zone_ns=$_, grep { $myname eq $_ } @mynames } @zone_n + or warn "supposedly published secondary but we ". + "(@mynames) are not published ($@zone_ns)\n"; + } + } + check_after_eval(); + + + +# $superzone= $zone; $superzone =~ s/^[^\.]+\.//; +# @super_ns= lookup('ns-',$zone); + } + eval { + + for $super_ns (@super_ns) { + @deleg_ns= (); + open DIG, "dig @$super_ns. -t ns +norecurse $zone." + or die "$0: fork for dig: $!\n"; + while () { + + + split /\n/, lookup(" + case "$style" in secondary|backup) - if [ $meadvert = false ] + if [ $meadvert = 0 ] then warning "$myname unlisted NS $nsnames" fi ;; unoff) - if $meadvert = false + if $meadvert = 0 then warning "$myname advertised NS $nsnames" fi @@ -223,12 +166,12 @@ END echo " $server;" if $check then - notfound=true + notfound=1 for addr in $addrs do if [ "x$addr" = "x$server" ] then - notfound=false + notfound=0 fi done if $notfound @@ -241,7 +184,7 @@ END }; }; END - hostfirstwarn=true + hostfirstwarn=1 if $hostdelg then checkhostout -C @@ -253,6 +196,83 @@ END done endfile + +chdir "$base/primary" or die "$0: chdir $base/primary: $!"; +beginfile('primary.zones'); + +for $f (<*_db>) { + $zone= $f; $zone =~ s/_db$//; + + +for f in $zones +do + zone="`echo $f | sed -e 's/_db$//'`" + cat < $toopen" or die "$0: begin $currentfile_opened: $!\n"; +} + +endfile () { + close CFF or die "$0: close $currentfile_opened: $!\n"; + push @files, $currentfile; +} + +sub installfiles () { + return unless $install; + chdir $conf or die "$0: chdir $conf: $!\n"; + for $f (@files) { + rename "$f.new", $f or die "$0: install new $f: $!\n"; + } +} + +warning () { + echo >&2 "$zone $style: $*" + warnings=$[$warnings+1] +} + +equlines () { + if [ "x`echo \" $2\" | wc -l`" != "x`echo \" $3\" | wc -l`" ] + then + warning "$1 >$2|$3<" + fi +} + +checkhostout () { + set +e + hostout="`host $1 \"$zone\" 2>&1 >/dev/null $2 | egrep -v \ +'^ \!\!\! .* SOA primary .* is not advertised via NS$'`" + set -e + if [ "x$hostout" = x ]; then return; fi + if $hostfirstwarn + then + warning "warnings from host:" + hostfirstwarn=0 + fi + echo >&2 "$hostout" +} + +progress () { + if $progress + then + echo -n "$zone $style " >&2 + echo -ne '\r' >&2 + fi +} + +myname='' + if [ $warnings != 0 ] then echo >&2 "$warnings warnings "