- Timestamp:
- 12/23/13 17:23:41 (11 years ago)
- Location:
- branches/stable
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/stable
-
branches/stable/DNSDB.pm
r563 r568 36 36 use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS); 37 37 38 $VERSION = "1.2. 1"; ##VERSION##38 $VERSION = "1.2.2"; ##VERSION## 39 39 @ISA = qw(Exporter); 40 40 @EXPORT_OK = qw( … … 3498 3498 3499 3499 eval { 3500 my $sql = "UPDATE "._rectable($defrec, $revrec)." SET host=?, val=?, ttl=? WHERE record_id=? AND type=6"; 3501 $dbh->do($sql, undef, ("$soa{contact}:$soa{prins}", "$soa{refresh}:$soa{retry}:$soa{expire}:$soa{minttl}", 3500 if (!$oldsoa) { 3501 # old SOA record is missing for some reason. create a new one. 3502 my $sql = "INSERT INTO "._rectable($defrec, $revrec)." (group_id, host, type, val, ttl) VALUES (?,?,6,?,?)"; 3503 $dbh->do($sql, undef, ($soa{id}, "$soa{contact}:$soa{prins}", 3504 "$soa{refresh}:$soa{retry}:$soa{expire}:$soa{minttl}", $soa{ttl}) ); 3505 $msg = ($defrec eq 'y' ? ($revrec eq 'y' ? 'Default reverse ' : 'Default ') : ''). 3506 "SOA missing for $parname; added (ns $soa{prins}, contact $soa{contact}, refresh $soa{refresh},". 3507 " retry $soa{retry}, expire $soa{expire}, minTTL $soa{minttl}, TTL $soa{ttl})"; 3508 } else { 3509 my $sql = "UPDATE "._rectable($defrec, $revrec)." SET host=?, val=?, ttl=? WHERE record_id=? AND type=6"; 3510 $dbh->do($sql, undef, ("$soa{contact}:$soa{prins}", "$soa{refresh}:$soa{retry}:$soa{expire}:$soa{minttl}", 3502 3511 $soa{ttl}, $oldsoa->{record_id}) ); 3503 $msg = "Updated ".($defrec eq 'y' ? ($revrec eq 'y' ? 'default reverse ' : 'default ') : '').3512 $msg = "Updated ".($defrec eq 'y' ? ($revrec eq 'y' ? 'default reverse ' : 'default ') : ''). 3504 3513 "SOA for $parname: ". 3505 3514 "(ns $oldsoa->{prins}, contact $oldsoa->{contact}, refresh $oldsoa->{refresh},". … … 3507 3516 "(ns $soa{prins}, contact $soa{contact}, refresh $soa{refresh},". 3508 3517 " retry $soa{retry}, expire $soa{expire}, minTTL $soa{minttl}, TTL $soa{ttl})"; 3509 3518 } 3510 3519 $logdata{entry} = $msg; 3511 3520 $self->_log(%logdata); … … 4934 4943 4935 4944 if ($target eq 'tiny') { 4936 $self->__export_tiny(@_); 4945 eval { 4946 $self->__export_tiny(@_); 4947 }; 4948 if ($@) { 4949 $errstr = $@; 4950 return undef; 4951 } 4937 4952 } 4938 4953 # elsif ($target eq 'foo') { … … 4941 4956 # etc 4942 4957 4958 return 1; 4943 4959 } # end export() 4944 4960 … … 4958 4974 ##fixme: fail if $datafile isn't an open, writable file 4959 4975 4976 # Error check - does the cache dir exist, if we're using one? 4977 if ($self->{usecache}) { 4978 die "Cache directory does not exist\n" if !-e $self->{exportcache}; 4979 die "$self->{exportcache} is not a directory\n" if !-d $self->{exportcache}; 4980 die "$self->{exportcache} must be both readable and writable\n" 4981 if !-r $self->{exportcache} || !-w $self->{exportcache}; 4982 } 4983 4960 4984 # easy case - export all evarything 4961 4985 # not-so-easy case - export item(s) specified … … 4965 4989 # of remaining data, allows up to 255 raw bytes 4966 4990 4967 # Locations/views - worth including in the caching setup? 4968 my $lochash = $dbh->selectall_hashref("SELECT location,iplist FROM locations", 'location'); 4969 foreach my $location (keys %$lochash) { 4970 foreach my $ipprefix (split /[,\s]+/, $lochash->{$location}{iplist}) { 4971 $ipprefix =~ s/\s+//g; 4972 $ipprefix = new NetAddr::IP $ipprefix; 4991 # note: the only I/O failures we seem to be able to actually catch 4992 # here are "closed filehandle" errors. we're probably not writing 4993 # enough data at this point to properly trigger an "out of space" 4994 # error. :/ 4995 eval { 4996 use warnings FATAL => ('io'); 4997 # Locations/views - worth including in the caching setup? 4998 my $lochash = $dbh->selectall_hashref("SELECT location,iplist FROM locations", 'location'); 4999 foreach my $location (keys %$lochash) { 5000 foreach my $ipprefix (split /[,\s]+/, $lochash->{$location}{iplist}) { 5001 $ipprefix =~ s/\s+//g; 5002 $ipprefix = new NetAddr::IP $ipprefix; 4973 5003 ##fixme: how to handle IPv6? 4974 5004 next if $ipprefix->{isv6}; 4975 # have to account for /nn CIDR entries. tinydns only speaks octet-sliced prefix. 4976 if ($ipprefix->masklen <= 8) { 4977 foreach ($ipprefix->split(8)) { 4978 my $tmp = $_->addr; 4979 $tmp =~ s/\.\d+\.\d+\.\d+$//; 4980 print $datafile "%$location:$tmp\n"; 4981 } 4982 } elsif ($ipprefix->masklen <= 16) { 4983 foreach ($ipprefix->split(16)) { 4984 my $tmp = $_->addr; 4985 $tmp =~ s/\.\d+\.\d+$//; 4986 print $datafile "%$location:$tmp\n"; 4987 } 4988 } elsif ($ipprefix->masklen <= 24) { 4989 foreach ($ipprefix->split(24)) { 4990 my $tmp = $_->addr; 4991 $tmp =~ s/\.\d+$//; 4992 print $datafile "%$location:$tmp\n"; 4993 } 4994 } else { 4995 foreach ($ipprefix->split(32)) { 4996 print $datafile "%$location:".$_->addr."\n"; 5005 # have to account for /nn CIDR entries. tinydns only speaks octet-sliced prefix. 5006 if ($ipprefix->masklen <= 8) { 5007 foreach ($ipprefix->split(8)) { 5008 my $tmp = $_->addr; 5009 $tmp =~ s/\.\d+\.\d+\.\d+$//; 5010 print $datafile "%$location:$tmp\n"; 5011 } 5012 } elsif ($ipprefix->masklen <= 16) { 5013 foreach ($ipprefix->split(16)) { 5014 my $tmp = $_->addr; 5015 $tmp =~ s/\.\d+\.\d+$//; 5016 print $datafile "%$location:$tmp\n"; 5017 } 5018 } elsif ($ipprefix->masklen <= 24) { 5019 foreach ($ipprefix->split(24)) { 5020 my $tmp = $_->addr; 5021 $tmp =~ s/\.\d+$//; 5022 print $datafile "%$location:$tmp\n"; 5023 } 5024 } else { 5025 foreach ($ipprefix->split(32)) { 5026 print $datafile "%$location:".$_->addr."\n"; 5027 } 4997 5028 } 4998 5029 } 4999 } 5000 print $datafile "%$location\n" if !$lochash->{$location}{iplist}; 5030 print $datafile "%$location\n" if !$lochash->{$location}{iplist}; 5031 } 5032 }; 5033 if ($@) { 5034 die "Error writing locations to master file: $@, $!\n"; 5001 5035 } 5002 5036 … … 5022 5056 "ORDER BY masklen(CAST(val AS inet)) DESC, CAST(val AS inet)"); 5023 5057 my $revsth = $dbh->prepare("SELECT rdns_id,revnet,status,changed FROM revzones WHERE status=1 ". 5024 "ORDER BY masklen(revnet) DESC ");5058 "ORDER BY masklen(revnet) DESC, rdns_id"); 5025 5059 my $zonesth = $dbh->prepare("UPDATE revzones SET changed='n' WHERE rdns_id=?"); 5026 5060 $revsth->execute(); … … 5092 5126 }; 5093 5127 if ($@) { 5094 print "error writing new data for$revzone: $@\n";5128 die "error writing ".($self->{usecache} ? 'new data for ' : '')."$revzone: $@\n"; 5095 5129 # error! something borked, and we should be able to fall back on the old cache file 5096 5130 # report the error, somehow. … … 5104 5138 # We've already made as sure as we can that a cached zone file is "good", 5105 5139 # although possibly stale/obsolete due to errors creating a new one. 5106 open CACHE, "<$cachefile"; 5107 print $datafile $_ while <CACHE>; 5108 close CACHE; 5140 eval { 5141 open CACHE, "<$cachefile" or die $!; 5142 print $datafile $_ or die "error copying cached $revzone to master file: $!" while <CACHE>; 5143 close CACHE; 5144 }; 5145 die $@ if $@; 5109 5146 } 5110 5147 5111 5148 } # while ($revsth) 5112 5149 5113 my $domsth = $dbh->prepare("SELECT domain_id,domain,status,changed FROM domains WHERE status=1 ");5150 my $domsth = $dbh->prepare("SELECT domain_id,domain,status,changed FROM domains WHERE status=1 ORDER BY domain_id"); 5114 5151 $recsth = $dbh->prepare("SELECT host,type,val,distance,weight,port,ttl,record_id,location,extract(epoch from stamp),expires,stampactive ". 5115 5152 "FROM records WHERE domain_id=?"); # Just exclude all types relating to rDNS … … 5174 5211 }; 5175 5212 if ($@) { 5176 print "error writing new data for$dom: $@\n";5213 die "error writing ".($self->{usecache} ? 'new data for ' : '')."$dom: $@\n"; 5177 5214 # error! something borked, and we should be able to fall back on the old cache file 5178 5215 # report the error, somehow. … … 5186 5223 # We've already made as sure as we can that a cached zone file is "good", 5187 5224 # although possibly stale/obsolete due to errors creating a new one. 5188 open CACHE, "<$cachefile"; 5189 print $datafile $_ while <CACHE>; 5190 close CACHE; 5225 eval { 5226 open CACHE, "<$cachefile" or die $!; 5227 print $datafile $_ or die "error copying cached $dom to master file: $!" while <CACHE>; 5228 close CACHE; 5229 }; 5230 die $@ if $@; 5191 5231 } 5192 5232 5193 5233 } # while ($domsth) 5194 5234 5235 return 1; 5195 5236 } # end __export_tiny() 5196 5237 … … 5310 5351 _template4_expand(\$rec, $ip); 5311 5352 print $fh ($ptronly ? "^"._ZONE($_, 'ZONE.in-addr.arpa', 'r', '.').":$rec" : "=$rec:$ip"). 5312 ":$ttl:$stamp:$loc\n" ;5353 ":$ttl:$stamp:$loc\n" or die $!; 5313 5354 } 5314 5355 } … … 5332 5373 foreach my $szone ($zone->split($zone->masklen + (8 - $zone->masklen % 8))) { 5333 5374 $szone = _ZONE($szone, 'ZONE.in-addr.arpa', 'r', '.'); 5334 print $datafile "Z$szone:$primary:$email"."::$refresh:$retry:$expire:$min_ttl:$ttl:$stamp:$loc\n"; 5375 print $datafile "Z$szone:$primary:$email"."::$refresh:$retry:$expire:$min_ttl:$ttl:$stamp:$loc\n" 5376 or die $!; 5335 5377 } 5336 5378 return; # skips "default" bits just below … … 5338 5380 $zone = _ZONE($zone, 'ZONE', 'r', '.').($zone->{isv6} ? '.ip6.arpa' : '.in-addr.arpa'); 5339 5381 } 5340 print $datafile "Z$zone:$primary:$email"."::$refresh:$retry:$expire:$min_ttl:$ttl:$stamp:$loc\n"; 5382 print $datafile "Z$zone:$primary:$email"."::$refresh:$retry:$expire:$min_ttl:$ttl:$stamp:$loc\n" 5383 or die $!; 5341 5384 5342 5385 } elsif ($typemap{$type} eq 'A') { 5343 5386 5344 print $datafile "+$host:$val:$ttl:$stamp:$loc\n" ;5387 print $datafile "+$host:$val:$ttl:$stamp:$loc\n" or die $!; 5345 5388 5346 5389 } elsif ($typemap{$type} eq 'NS') { … … 5353 5396 my $szone2 = _ZONE($szone, 'ZONE.in-addr.arpa', 'r', '.'); 5354 5397 next if $$recflags{$szone2} && $$recflags{$szone2} > $val->masklen; 5355 print $datafile "\&$szone2"."::$host:$ttl:$stamp:$loc\n" ;5398 print $datafile "\&$szone2"."::$host:$ttl:$stamp:$loc\n" or die $!; 5356 5399 $$recflags{$szone2} = $val->masklen; 5357 5400 } … … 5360 5403 my $szone2 = _ZONE($szone, 'ZONE.ip6.arpa', 'r', '.'); 5361 5404 next if $$recflags{$szone2} && $$recflags{$szone2} > $val->masklen; 5362 print $datafile "\&$szone2"."::$host:$ttl:$stamp:$loc\n" ;5405 print $datafile "\&$szone2"."::$host:$ttl:$stamp:$loc\n" or die $!; 5363 5406 $$recflags{$szone2} = $val->masklen; 5364 5407 } 5365 5408 } else { 5366 5409 my $val2 = _ZONE($val, 'ZONE', 'r', '.').($val->{isv6} ? '.ip6.arpa' : '.in-addr.arpa'); 5367 print $datafile "\&$val2"."::$host:$ttl:$stamp:$loc\n" ;5410 print $datafile "\&$val2"."::$host:$ttl:$stamp:$loc\n" or die $!; 5368 5411 $$recflags{$val2} = $val->masklen; 5369 5412 } 5370 5413 } else { 5371 print $datafile "\&$host"."::$val:$ttl:$stamp:$loc\n" ;5414 print $datafile "\&$host"."::$val:$ttl:$stamp:$loc\n" or die $!; 5372 5415 } 5373 5416 5374 5417 } elsif ($typemap{$type} eq 'AAAA') { 5375 5418 5376 print $datafile ":$host:28:";5419 # print $datafile ":$host:28:"; 5377 5420 my $altgrp = 0; 5378 5421 my @altconv; … … 5387 5430 } 5388 5431 } 5432 my $prefix = ":$host:28:"; 5389 5433 foreach my $octet (@altconv) { 5390 5434 # if not 's', output 5391 print $datafile$octet unless $octet =~ /^s$/;5435 $prefix .= $octet unless $octet =~ /^s$/; 5392 5436 # if 's', output (9-array length)x literal '\000\000' 5393 print $datafile'\000\000'x(9-$altgrp) if $octet =~ /^s$/;5437 $prefix .= '\000\000'x(9-$altgrp) if $octet =~ /^s$/; 5394 5438 } 5395 print $datafile " :$ttl:$stamp:$loc\n";5439 print $datafile "$prefix:$ttl:$stamp:$loc\n" or die $!; 5396 5440 5397 5441 } elsif ($typemap{$type} eq 'MX') { 5398 5442 5399 print $datafile "\@$host"."::$val:$dist:$ttl:$stamp:$loc\n"; 5443 ##fixme: what if we get an MX AXFRed into a reverse zone? 5444 print $datafile "\@$host"."::$val:$dist:$ttl:$stamp:$loc\n" or die $!; 5400 5445 5401 5446 } elsif ($typemap{$type} eq 'TXT') { … … 5404 5449 if ($revrec eq 'n') { 5405 5450 $val =~ s/:/\\072/g; # may need to replace other symbols 5406 print $datafile "'$host:$val:$ttl:$stamp:$loc\n" ;5451 print $datafile "'$host:$val:$ttl:$stamp:$loc\n" or die $!; 5407 5452 } else { 5408 5453 $host =~ s/:/\\072/g; # may need to replace other symbols 5409 5454 my $val2 = NetAddr::IP->new($val); 5410 5455 print $datafile "'"._ZONE($val2, 'ZONE', 'r', '.').($val2->{isv6} ? '.ip6.arpa' : '.in-addr.arpa'). 5411 ":$host:$ttl:$stamp:$loc\n" ;5456 ":$host:$ttl:$stamp:$loc\n" or die $!; 5412 5457 } 5413 5458 … … 5432 5477 5433 5478 if ($revrec eq 'n') { 5434 print $datafile "C$host:$val:$ttl:$stamp:$loc\n" ;5479 print $datafile "C$host:$val:$ttl:$stamp:$loc\n" or die $!; 5435 5480 } else { 5436 5481 my $val2 = NetAddr::IP->new($val); 5437 5482 print $datafile "C"._ZONE($val2, 'ZONE', 'r', '.').($val2->{isv6} ? '.ip6.arpa' : '.in-addr.arpa'). 5438 ":$host:$ttl:$stamp:$loc\n" ;5483 ":$host:$ttl:$stamp:$loc\n" or die $!; 5439 5484 } 5440 5485 … … 5444 5489 # followed by length/string data 5445 5490 5446 print $datafile ":$host:33:".octalize($dist,'d').octalize($weight,'d').octalize($port,'d') ;5491 print $datafile ":$host:33:".octalize($dist,'d').octalize($weight,'d').octalize($port,'d') or die $!; 5447 5492 5448 5493 $val .= '.' if $val !~ /\.$/; 5449 5494 foreach (split /\./, $val) { 5450 printf $datafile "\\%0.3o%s", length($_), $_ ;5495 printf $datafile "\\%0.3o%s", length($_), $_ or die $!; 5451 5496 } 5452 print $datafile "\\000:$ttl:$stamp:$loc\n" ;5497 print $datafile "\\000:$ttl:$stamp:$loc\n" or die $!; 5453 5498 5454 5499 } elsif ($typemap{$type} eq 'RP') { … … 5457 5502 # The first is supposed to be an email address with @ replaced by . (as with the SOA contact) 5458 5503 # The second is the "hostname" of a TXT record with more info. 5459 print $datafile":$host:17:";5504 my $prefix = ":$host:17:"; 5460 5505 my ($who,$what) = split /\s/, $val; 5461 5506 foreach (split /\./, $who) { 5462 printf $datafile"\\%0.3o%s", length($_), $_;5507 $prefix .= sprintf "\\%0.3o%s", length($_), $_; 5463 5508 } 5464 print $datafile'\000';5509 $prefix .= '\000'; 5465 5510 foreach (split /\./, $what) { 5466 printf $datafile"\\%0.3o%s", length($_), $_;5511 $prefix .= sprintf "\\%0.3o%s", length($_), $_; 5467 5512 } 5468 print $datafile " \\000:$ttl:$stamp:$loc\n";5513 print $datafile "$prefix\\000:$ttl:$stamp:$loc\n" or die $!; 5469 5514 5470 5515 } elsif ($typemap{$type} eq 'PTR') { … … 5475 5520 ($val) = ($val =~ /\.(\d+)$/); 5476 5521 print $datafile "^$val."._ZONE($zone, 'ZONE', 'r', '.').'.in-addr.arpa'. 5477 ":$host:ttl:$stamp:$loc\n" ;5522 ":$host:ttl:$stamp:$loc\n" or die $!; 5478 5523 } else { 5479 5524 $val = NetAddr::IP->new($val); 5480 5525 print $datafile "^". 5481 5526 _ZONE($val, 'ZONE', 'r', '.').($val->{isv6} ? '.ip6.arpa' : '.in-addr.arpa'). 5482 ":$host:$ttl:$stamp:$loc\n" ;5527 ":$host:$ttl:$stamp:$loc\n" or die $!; 5483 5528 } 5484 5529 … … 5486 5531 5487 5532 $$recflags{$val}++; 5488 print $datafile "=$host:$val:$ttl:$stamp:$loc\n" ;5533 print $datafile "=$host:$val:$ttl:$stamp:$loc\n" or die $!; 5489 5534 5490 5535 } elsif ($type == 65281) { # AAAA+PTR … … 5552 5597 my ($oct) = ($_->addr =~ /(\d+)$/); 5553 5598 print $datafile "C"._ZONE($_, 'ZONE.in-addr.arpa', 'r', '.').":$oct.". 5554 _ZONE($dblock, 'ZONE.in-addr.arpa', 'r', '.').":$ttl:$stamp:$loc\n" ;5599 _ZONE($dblock, 'ZONE.in-addr.arpa', 'r', '.').":$ttl:$stamp:$loc\n" or die $!; 5555 5600 $$recflags{"$_"}++; 5556 5601 } … … 5570 5615 $fp =~ s/^..//; 5571 5616 } 5572 print $datafile "$rec:$ttl:$stamp:$loc\n" ;5617 print $datafile "$rec:$ttl:$stamp:$loc\n" or die $!; 5573 5618 5574 5619 } else { -
branches/stable/Makefile
r563 r568 3 3 4 4 PKGNAME=dnsadmin 5 VERSION=1.2. 15 VERSION=1.2.2 6 6 RELEASE=1 7 7
Note:
See TracChangeset
for help on using the changeset viewer.