📄 bind8-lib.pl
字号:
# directives that need their value to be quoted@need_quote = ( "file", "zone", "pid-file", "statistics-file", "dump-file", "named-xfer" );foreach $need (@need_quote) { $need_quote{$need}++; }1;# find_reverse(address)# Returns the zone and record structures for the PTR record for some addresssub find_reverse{local($conf, @zl, $rev, $z, $revconf, $revfile, $revrec, @revrecs, $addr, $rr);# find reverse domain$conf = &get_config();@zl = &find("zone", $conf);@octs = split(/\./, $_[0]);for($i=2; $i>=0; $i--) { $rev = &ip_to_arpa(join('.', @octs[0..$i])); $rev =~ s/\.$//g; foreach $z (@zl) { if (lc($z->{'value'}) eq $rev && ($typed = &find("type", $z->{'members'})) && $typed->{'value'} eq "master") { # found the reverse master domain $revconf = $z; last; } } }# find reverse recordif ($revconf) { $revfile = &find("file", $revconf->{'members'})->{'value'}; @revrecs = &read_zone_file($revfile, $revconf->{'value'}); $addr = &ip_to_arpa($_[0]); foreach $rr (@revrecs) { if ($rr->{'type'} eq "PTR" && lc($rr->{'name'}) eq lc($addr)) { # found the reverse record $revrec = $rr; last; } } }return ($revconf, $revfile, $revrec);}# can_edit_zone(&access, zone)sub can_edit_zone{local %zcan;return 1 if ($access{'zones'} eq '*');foreach (split(/\s+/, $access{'zones'})) { return 1 if ($_ eq $_[1]); }return 0;}# read_zone_file(file, origin)# Reads a DNS zone file and returns a data structure of records. The origin# must be a domain without the trailing dot, or just .sub read_zone_file{local($file, $lnum, $line, $t, @tok, @lnum, $i, @rv, $origin, $num, $j, @inc);$origin = $_[1];$file = &absolute_path($_[0]);open(FILE, $file);$lnum = 0;while($line = <FILE>) { # strip comments $line =~ s/\r|\n//g; $line =~ s/;.*$//g; $line =~ s/#.*$//g; # split line into tokens local $oset = 0; while(1) { if ($line =~ /^(\s*)"([^"]+)"(.*)/ || $line =~ /^(\s*)([A-z0-9\.\-_\$\/\*]+)(.*)/ || $line =~ /^(\s*)([^A-z0-9\.\-_\$\/\*\s])(.*)/) { $oset += length($1); push(@tok, $2); push(@lnum, $lnum); push(@oset, $oset); $line = $3; $oset += length($2); } else { last; } } $lnum++; }close(FILE);# parse into data structures$i = 0; $num = 0;while($i < @tok) { if ($tok[$i] =~ /^\$origin$/i) { # $ORIGIN directive (may be relative or absolute) if ($tok[$i+1] =~ /^(\S+)\.$/) { $origin = $1 ? $1 : "."; } elsif ($origin eq ".") { $origin = $tok[$i+1]; } else { $origin = "$tok[$i+1].$origin"; } $i += 2; } elsif ($tok[$i] =~ /^\$include$/i) { # including another file if ($lnum[$i+1] == $lnum[$i+2]) { # $INCLUDE zonefile origin local $inc_origin; if ($tok[$i+2] =~ /^(\S+)\.$/) { $inc_origin = $1 ? $1 : "."; } elsif ($origin eq ".") { $inc_origin = $tok[$i+2]; } else { $inc_origin = "$tok[$i+2].$origin"; } @inc = &read_zone_file($tok[$i+1], $inc_origin); $i += 3; } else { # $INCLUDE zonefile @inc = &read_zone_file($tok[$i+1], $origin); $i += 2; } foreach $j (@inc) { $j->{'num'} = $num++; } push(@rv, @inc); } elsif ($tok[$i] =~ /^\$(\S+)/i) { # some other special directive local $ln = $lnum[$i]; while($lnum[$i] == $ln) { $i++; } } else { # some other directive local(%dir, @values, $l); $dir{'line'} = $lnum[$i]; $dir{'file'} = $file; if ($tok[$i] =~ /^(in|hs)$/i) { # starting with a class $dir{'class'} = uc($tok[$i]); $i++; } elsif ($tok[$i] =~ /^\d/ && $tok[$i] !~ /in-addr/i && $oset[$i] > 0) { # starting with a TTL and class $dir{'ttl'} = $tok[$i]; $dir{'class'} = uc($tok[$i+1]); $i += 2; } elsif ($tok[$i+1] =~ /^(in|hs)$/i) { # starting with a name and class $dir{'name'} = $tok[$i]; $dir{'class'} = uc($tok[$i+1]); $i += 2; } elsif ($oset[$i] > 0) { # starting with nothing $dir{'class'} = "IN"; } elsif ($tok[$i+1] =~ /^\d/) { # starting with a name, ttl and class $dir{'name'} = $tok[$i]; $dir{'ttl'} = $tok[$i+1]; $dir{'class'} = uc($tok[$i+2]); $i += 3; } else { # starting with a name $dir{'name'} = $tok[$i]; $dir{'class'} = "IN"; $i++; } if (!$dir{'name'}) { $dir{'name'} = $rv[$#rv]->{'name'}; } $dir{'type'} = uc($tok[$i++]); # read values until end of line (unless a ( is found) $l = $lnum[$i]; while($lnum[$i] == $l && $i < @tok) { if ($tok[$i] eq "(") { while($tok[++$i] ne ")") { push(@values, $tok[$i]); } $i++; # skip ) last; } push(@values, $tok[$i++]); } $dir{'values'} = \@values; $dir{'eline'} = $lnum[$i-1]; if ($dir{'name'} eq "@") { $dir{'name'} = $origin eq "." ? "." : "$origin.";; } elsif ($dir{'name'} !~ /\.$/) { $dir{'name'} .= $origin eq "." ? "." : ".$origin."; } $dir{'num'} = $num++; push(@rv, \%dir); } }return @rv;}# record_input(zoneindex, type, file, origin, [num])# Display a form for editing or creating a DNS recordsub record_input{local(%rec, @recs);print "<form action=save_record.cgi>\n";print "<input type=hidden name=index value=$_[0]>\n";print "<input type=hidden name=file value=$_[2]>\n";print "<input type=hidden name=origin value=$_[3]>\n";if (@_ == 5) { print "<input type=hidden name=num value=$_[4]>\n"; @recs = &read_zone_file($_[2], $_[3]); %rec = %{$recs[$_[4]]}; }else { print "<input type=hidden name=new value=1>\n"; }print "<input type=hidden name=type value=$_[1]>\n";print "<table border>\n";print "<tr $tb><td><b>",&text(@_ == 5 ? 'edit_edit' : 'edit_add', $text{"type_$_[1]"}),"</b></td> </tr>\n";print "<tr $cb><td><table>\n";print "<tr> <td><b>",$_[1] eq "PTR" ? $text{'edit_addr'} : $text{'edit_name'}, "</b></td>\n";printf "<td><input name=name value=\"%s\" size=30></td>\n", $_[1] eq "PTR" ? &arpa_to_ip($rec{'name'}) : $rec{'name'};print "<td><b>$text{'edit_ttl'}</b></td>\n";printf "<td><input type=radio name=ttl_def value=1 %s> $text{'default'}\n", defined($rec{'ttl'}) ? "" : "checked";printf "<input type=radio name=ttl_def value=0 %s>\n", defined($rec{'ttl'}) ? "checked" : "";print "<input name=ttl size=8 value=\"$rec{'ttl'}\"></td> </tr>\n";@v = @{$rec{'values'}};if ($_[1] eq "A") { print "<tr> <td><b>$text{'value_A1'}</b></td>\n"; print "<td><input name=value0 size=20 value=\"$v[0]\"></td> </tr>\n"; if (@_ == 5) { print "<input type=hidden name=oldname ", "value=\"$rec{'name'}\">\n"; print "<input type=hidden name=oldvalue0 value=\"$v[0]\">\n"; } }elsif ($_[1] eq "NS") { print "<tr> <td><b>$text{'value_NS1'}</b></td>\n"; print "<td colspan=3><input name=value0 size=30 value=\"$v[0]\">\n"; print "($text{'edit_cnamemsg'})</td> </tr>\n"; }elsif ($_[1] eq "CNAME") { print "<tr> <td><b>$text{'value_CNAME1'}</b></td>\n"; print "<td colspan=3><input name=value0 size=30 value=\"$v[0]\">\n"; print "($text{'edit_cnamemsg'})</td> </tr>\n"; }elsif ($_[1] eq "MX") { print "<tr> <td><b>$text{'value_MX2'}</b></td>\n"; print "<td><input name=value1 size=30 value=\"$v[1]\"></td>\n"; print "<td><b>$text{'value_MX1'}</b></td>\n"; print "<td><input name=value0 size=8 value=\"$v[0]\"></td> </tr>\n"; }elsif ($_[1] eq "HINFO") { print "<tr> <td><b>$text{'value_HINFO1'}</b></td>\n"; print "<td><input name=value0 size=20 value=\"$v[0]\"></td>\n"; print "<td><b>$text{'value_HINFO2'}</b></td>\n"; print "<td><input name=value1 size=20 value=\"$v[1]\"></td> </tr>\n"; }elsif ($_[1] eq "TXT") { print "<tr> <td><b>$text{'value_TXT1'}</b></td>\n"; print "<td><input name=value0 size=30 value=\"$v[0]\"></td> </tr>\n"; }elsif ($_[1] eq "WKS") { print "<tr> <td><b>$text{'value_WKS1'}</b></td>\n"; print "<td><input name=value0 size=15 value=\"$v[0]\"></td>\n"; print "<td><b>$text{'value_WKS2'}</b></td>\n"; print "<td><select name=value1>\n"; printf "<option %s>TCP\n", $v[1] =~ /tcp/ ? "selected" : ""; printf "<option %s>UDP\n", $v[1] =~ /udp/ ? "selected" : ""; print "</select></td>\n"; print "<tr> <td valign=top><b>$text{'value_WKS3'}</b></td>\n"; print "<td><textarea name=value2 rows=3 cols=20 wrap>", join(' ', @v[2..$#v]),"</textarea></td> </tr>\n"; }elsif ($_[1] eq "RP") { print "<tr> <td><b>$text{'value_RP1'}</b></td>\n"; $v[0] =~ s/\./\@/; print "<td><input name=value0 size=20 value=\"$v[0]\"></td>\n"; print "<td><b>$text{'value_RP2'}</b></td>\n"; print "<td><input name=value1 size=30 value=\"$v[1]\"></td> </tr>\n"; }elsif ($_[1] eq "PTR") { print "<tr> <td><b>$text{'value_PTR1'}</b></td>\n"; print "<td><input name=value0 size=30 value=\"$v[0]\"></td> </tr>\n"; }if ($_[1] eq "A") { print "<tr> <td><b>$text{'edit_uprev'}</b></td>\n"; print "<td><input type=radio name=rev value=1 checked> $text{'yes'}\n"; print "<input type=radio name=rev value=0> $text{'no'}</td>\n"; }else { print "<tr> <td colspan=2></td>\n"; }print "<td colspan=2 align=right>\n";local %a = &get_module_acl();if (!$a{'ro'}) { if (@_ == 5) { print "<input type=submit value='$text{'save'}'>\n"; print "<input type=submit name=delete ", "value='$text{'delete'}'>\n"; } else { print "<input type=submit value='$text{'create'}'>\n"; } }print "</td></tr></table></td></tr></table></form>\n";}# create_record(file, name, ttl, class, type, values)# Add a new record of some type to some zone filesub create_record{open(ZONE, ">>".&absolute_path($_[0]));print ZONE &make_record(@_[1..$#_]);close(ZONE);}# modify_record(file, old, name, ttl, class, type, values)# Updates an existing record in some zone filesub modify_record{local(@zone, $lines, $file);$file = &absolute_path($_[0]);open(ZONE, $file);@zone = <ZONE>;close(ZONE);$lines = $_[1]->{'eline'} - $_[1]->{'line'} + 1;splice(@zone, $_[1]->{'line'}, $lines, &make_record(@_[2..$#_]));open(ZONE, "> $file");print ZONE @zone;close(ZONE);}# delete_record(file, old)# Deletes a record in some zone filesub delete_record{local(@zone, $lines, $file);$file = &absolute_path($_[0]);open(ZONE, $file);@zone = <ZONE>;close(ZONE);$lines = $_[1]->{'eline'} - $_[1]->{'line'} + 1;splice(@zone, $_[1]->{'line'}, $lines);open(ZONE, "> $file");print ZONE @zone;close(ZONE);}# make_record(name, ttl, class, type, values)# Returns a string for some zone recordsub make_record{return $_[0] . ($_[1] ? "\t$_[1]" : "") . "\t$_[2]\t$_[3]\t$_[4]\n";}# bump_soa_record(file, &records)# Increase the serial number in some SOA record by 1sub bump_soa_record{local($i, $r, $v, $vals);for($i=0; $i<@{$_[1]}; $i++) { $r = $_[1]->[$i]; if ($r->{'type'} eq "SOA") { $v = $r->{'values'}; if ($config{'soa_style'} == 1 && $v->[2] =~ /^(\d{8})(\d\d)$/) { if ($1 eq &date_serial()) { $serial = sprintf "%d%2.2d", $1, $2+1; } else { $serial = &date_serial()."00"; } } else { $serial = $v->[2]+1; } $vals = "$v->[0] $v->[1] (\n\t\t\t$serial\n\t\t\t$v->[3]\n". "\t\t\t$v->[4]\n\t\t\t$v->[5]\n\t\t\t$v->[6] )"; &modify_record($_[0], $r, $r->{'name'}, $r->{'ttl'}, $r->{'class'}, $r->{'type'}, $vals); } }}@cat_list = ( 'default', 'config', 'parser', 'queries', 'lame-servers', 'statistics', 'panic', 'update', 'ncache', 'xfer-in', 'xfer-out', 'db', 'eventlib', 'packet', 'notify', 'cname', 'security', 'os', 'insist', 'maintenance', 'load', 'response-checks' );@syslog_levels = ( 'kern', 'user', 'mail', 'daemon', 'auth', 'syslog', 'lpr', 'news', 'uucp', 'cron', 'authpriv', 'ftp', 'local0', 'local1', 'local2', 'local3', 'local4', 'local5', 'local6', 'local7' );@severities = ( 'critical', 'error', 'warning', 'notice', 'info', 'debug', 'dynamic' );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -