X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ian/git?p=chiark-utils.git;a=blobdiff_plain;f=scripts%2Fnamed-conf;h=6d1777550253a274eea2dc3440a30587f0e8f61b;hp=f4e5323f1bc231b3cab844154563486b4ea1c0af;hb=750246f8aec98db8252f896b25e3a3bb64f2e1fb;hpb=c7f42647afa257d7f49a91b9ce85c4c31e9efcf3 diff --git a/scripts/named-conf b/scripts/named-conf index f4e5323..6d17775 100755 --- a/scripts/named-conf +++ b/scripts/named-conf @@ -65,22 +65,29 @@ usageerr("must specify either -f|-y|-n or zones (and not both)") if !!$mode == !!@ARGV; sub usageerr ($) { - die -"$_[0] -usage: named-conf-regen [options] -f|-y|-n|...\n". -"operation modes:\n". -" -f --force install without checking\n". -" -y --yes check and install\n". -" -n --no check only\n". -"additional options:\n". -" -A --all report on zones marked ? (ones we know are broken)\n". -" -D debug $quis (does not help debug your DNS config)\n". -" -g --glueless do not warn about any glueless referrals (not recommended)\n". -" -l --localonly full checks only on zones which we primary\n". -" -q --quiet no output for OK zones\n". -" -r --repeat repeat warnings for all sources of imperfect data\n". -" -v --verbose extra verbose info about each zone\n". -" -C|--config ... +operation modes: + -f --force install without checking + -y --yes check and install + -n --no check only (configured zones) + ... check only (specified zones, even unconfigured ones) +additional options: + -A --all report on zones marked ? (ones we know are broken) + -D debug $quis (does not help debug your DNS config) + -g --glueless do not warn about any glueless referrals (not recommended) + -l --localonly full checks only on zones which we primary + -q --quiet no output for OK zones + -r --repeat repeat warnings for all sources of imperfect data + -v --verbose extra verbose info about each zone + -C|--config {'s'} =~ m/f/) { zone_warning("foreign zone specified with -l",''); - } elsif ($cfg->{'s'} =~ m/\*/ || - ($localonly && $cfg->{'s'} !~ m/p/)) { + } elsif ($localonly && $cfg->{'s'} !~ m/p/) { zone_check_local(); } else { zone_check_full(); @@ -345,28 +351,32 @@ sub zone_reset() { } sub zone_investigate() { - my ($super_zone, @super_nsnames, - $super_ns, @super_ns_addrs, $s, $wa, $name_if_auth, + my ($super_zone, @start_nsnames, $start_ww, + $start_ns, @start_ns_addrs, $s, $wa, $name_if_auth, %nsrrset_checked, %soa_checked, $addr, $glueless_ok, $rcode, $name, $is_ns); - $super_zone= $zone; - for (;;) { - debug_trace("zone $zone superzone $super_zone"); - $super_zone =~ s/^[^.]+\.// or die "no superzone ? ($super_zone)\n"; - ($rcode,@super_nsnames)= - lookup($super_zone,'ns-','06',"superzone search"); - last if !$rcode; + if ($cfg->{'s'} !~ m/\*/) { + $super_zone= $zone; + for (;;) { + debug_trace("zone $zone superzone $super_zone"); + $super_zone =~ s/^[^.]+\.// + or die "no superzone ? ($super_zone)\n"; + ($rcode,@start_nsnames)= + lookup($super_zone,'ns-','06',"superzone search"); + last if !$rcode; + } + $start_ww= "server for $super_zone"; + } else { + ($rcode,@start_nsnames)= + lookup($zone,'ns-','0',"initial nameserver search"); + $start_ww= "nameserver for $zone"; } - for $super_ns (@super_nsnames) { - $super_ns= lc $super_ns; - ($rcode,@super_ns_addrs)= - lookup($super_ns,'a','0',"published nameserver"); - foreach $addr (@super_ns_addrs) { - push @to_check, - $addr, - "$super_ns, server for $super_zone", - undef, 0; + for $start_ns (@start_nsnames) { + $start_ns= lc $start_ns; + ($rcode,@start_ns_addrs)= lookup($start_ns,'a','0',"$start_ww"); + foreach $addr (@start_ns_addrs) { + push @to_check, $addr, "$start_ns, $start_ww", undef, 0; } } for (;;) { @@ -391,7 +401,7 @@ sub zone_investigate() { sub zone_check_nsrrset ($$$$) { my ($uaddr,$wa, $name_if_auth, $glueless_ok) = @_; - my (@s, $s, %s2g, @glue, $glue, $delgs_or_auths, $wwn, $ww); + my (@s, $s, $a, %s2g, @glue, $glue, $delgs_or_auths, $wwn, $ww); my ($rcode); $ww= "[$uaddr] $wa"; verbose("checking delegation by $ww"); @@ -400,8 +410,7 @@ sub zone_check_nsrrset ($$$$) { $s2g{lc $dig_rdata} = [ ]; } elsif ($dig_type eq 'a' && exists $s2g{$dig_owner}) { $wwn= "in glue from $ww"; - push @to_check, $dig_rdata, "$dig_owner, $wwn", $dig_owner, 0; - zone_server_addr($dig_rdata,$dig_owner,$wwn,"NS [$uaddr]",0); + zone_server_queue($dig_rdata,$dig_owner,$wwn,"NS [$uaddr]",0); push @{ $s2g{$dig_owner} }, $dig_rdata; } }, @@ -423,6 +432,10 @@ sub zone_check_nsrrset ($$$$) { grep { has_suffix_of($s,".$_"); } @{ $cfg->{'conv_glueless'} }; ($rcode,@glue)= lookup($s,'a','0',"glueless NS from $ww"); + foreach $a (@glue) { + $wwn= "glueless NS from $ww"; + zone_server_queue($a,$s,$wwn,"NS [$uaddr]",0); + } } $glue= join ' ', sort @glue; push @{ $glue{$s}{$glue} }, $ww; @@ -449,6 +462,12 @@ sub zone_ns_name ($$) { @{ $cfg->{'self_ns'} }, @{ $cfg->{'self_soa'} }; } +sub zone_server_queue ($$$$$) { + my ($addr,$name,$wwn,$wwq,$is_soa) = @_; + zone_server_addr($addr,$name,$wwn,$wwq,$is_soa); + push @to_check, $addr, "$name, $wwn", $name, $is_soa; +} + sub zone_server_addr ($$$$$) { my ($addr,$name,$ww,$wwq,$is_soa) = @_; debug_trace("zone_server_addr ".join '|',@_); @@ -498,14 +517,13 @@ sub zone_check_soa ($$$$) { $zone,'soa',$uaddr); $lame= 'broken' if !$lame && !defined $origin; if ($lame) { zone_warning("$lame server [$uaddr]",$wa); return; } - progress(2, sprintf "%-22s %40s has %s%s", - $zone, $name, $serial, $is_ns ? '' : '*'); + progress(2, sprintf "%-16s %46s has %s%s", + $zone, "$name [$uaddr]", $serial, $is_ns ? '' : '*'); push @{ $soas{$got} }, $ww; ($rcode,@soa_addrs)= lookup($origin,'a','0',"SOA ORIGIN"); $wwn= "SOA ORIGIN from $ww"; foreach $soa_addr (@soa_addrs) { - zone_server_addr($soa_addr,$origin,$wwn,"SOA [$uaddr]",1); - push @to_check, $soa_addr, "$origin, $wwn", $origin, 1; + zone_server_queue($soa_addr,$origin,$wwn,"SOA [$uaddr]",1); } } @@ -568,6 +586,7 @@ sub zone_servers_simplefind () { zone_ns_name($ns,"NS"); zone_server_simple($ns,'NS',0); } + $delgs{join ' ', sort @nsnames} = [ "zone's servers" ]; ($rcode,@soas)= lookup($zone,'soa','0',"SOA ORIGIN"); die "multiple SOA RRs in set! @soas ?" if @soas!=1;