Changeset 459
- Timestamp:
- 01/22/13 17:24:43 (12 years ago)
- Location:
- trunk
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/DNSDB.pm
r457 r459 3796 3796 return ($retcode, $retmsg); 3797 3797 } # end updateRec() 3798 3799 3800 ## DNSDB::downconvert() 3801 # A mostly internal (not exported) semiutilty sub to downconvert from pseudotype <x> 3802 # to a compatible component type. Only a handful of operations are valid, anything 3803 # else is a null-op. 3804 # Takes the record ID and the new type. Returns boolean. 3805 sub downconvert { 3806 my $dbh = shift; 3807 my $recid = shift; 3808 my $newtype = shift; 3809 3810 # also, only work on live records; little to no value trying to do this on default records. 3811 my $rec = getRecLine($dbh, 'n', 'y', $recid); 3812 3813 # hm? 3814 #return 1 if !$rec; 3815 3816 return 1 if $rec->{type} < 65000; # Only the reverse-record pseudotypes can be downconverted 3817 return 1 if $rec->{type} == 65282; # Nowhere to go 3818 3819 my $delpar; 3820 my @sqlargs; 3821 if ($rec->{type} == 65280) { 3822 return 1 if $newtype != 1 && $newtype != 12; 3823 $delpar = ($newtype == 1 ? 'rdns_id' : 'domain_id'); 3824 push @sqlargs, 0, $newtype, $recid; 3825 } elsif ($rec->{type} == 65281) { 3826 return 1 if $newtype != 28 && $newtype != 12; 3827 $delpar = ($newtype == 28 ? 'rdns_id' : 'domain_id'); 3828 push @sqlargs, 0, $newtype, $recid; 3829 } elsif ($rec->{type} == 65283) { 3830 return 1 if $newtype != 65282; 3831 $delpar = 'rdns_id'; 3832 } elsif ($rec->{type} == 65284) { 3833 return 1 if $newtype != 65282; 3834 $delpar = 'rdns_id'; 3835 } else { 3836 # Your llama is on fire. 3837 } 3838 3839 local $dbh->{AutoCommit} = 0; 3840 local $dbh->{RaiseError} = 1; 3841 3842 eval { 3843 $dbh->do("UPDATE records SET $delpar = ?, type = ? WHERE record_id = ?", undef, @sqlargs); 3844 $dbh->commit; 3845 }; 3846 if ($@) { 3847 $errstr = $@; 3848 eval { $dbh->rollback; }; 3849 return 0; 3850 } 3851 return 1; 3852 } # end downconvert() 3798 3853 3799 3854 -
trunk/dns-rpc.cgi
r454 r459 65 65 'dnsdb.addOrUpdateRevRec' => \&addOrUpdateRevRec, 66 66 'dnsdb.delRec' => \&delRec, 67 'dnsdb.delByCIDR' => \&delByCIDR, 67 68 #sub getLogCount {} 68 69 #sub getLogEntries {} … … 434 435 435 436 _commoncheck(\%args, 'y'); 436 $args{cidr}= new NetAddr::IP $args{cidr};437 my $cidr = new NetAddr::IP $args{cidr}; 437 438 438 439 my $zonelist = DNSDB::getZonesByCIDR($dbh, %args); … … 442 443 # check if the single zone returned is bigger than the CIDR. if so, we can just add a record 443 444 my $zone = new NetAddr::IP $zonelist->[0]->{revnet}; 444 if ($zone->contains($ args{cidr})) {445 if ($zone->contains($cidr)) { 445 446 # We need to strip the CIDR mask on IPv4 /32 assignments, or we just add a new record all the time. 446 my $filt = ($ args{cidr}->{isv6} || $args{cidr}->masklen != 32 ? "$args{cidr}" : $args{cidr}->addr);447 my $filt = ($cidr->{isv6} || $cidr->masklen != 32 ? "$cidr" : $cidr->addr); 447 448 my $reclist = DNSDB::getDomRecs($dbh, defrec => 'n', revrec => 'y', 448 449 id => $zonelist->[0]->{rdns_id}, filter => $filt); 449 450 if (scalar(@$reclist) == 0) { 450 451 # Aren't Magic Numbers Fun? See pseudotype list in dnsadmin. 451 my $type = ($ args{cidr}->{isv6} ? 65282 : ($args{cidr}->masklen == 32 ? 65280 : 65283) );452 my $type = ($cidr->{isv6} ? 65282 : ($cidr->masklen == 32 ? 65280 : 65283) ); 452 453 addRec(defrec =>'n', revrec => 'y', parent_id => $zonelist->[0]->{rdns_id}, type => $type, 453 address => "$ args{cidr}", %args);454 address => "$cidr", %args); 454 455 } else { 456 my $flag = 0; 455 457 foreach my $rec (@$reclist) { 456 458 # pure PTR plus composite types … … 460 462 updateRec(defrec =>'n', revrec => 'y', id => $rec->{record_id}, 461 463 parent_id => $zonelist->[0]->{rdns_id}, %args); 464 $flag = 1; 462 465 last; # only do one record. 466 } 467 unless ($flag) { 468 # Nothing was updated, so we didn't really have a match. Add as per @$reclist==0 469 # Aren't Magic Numbers Fun? See pseudotype list in dnsadmin. 470 my $type = ($cidr->{isv6} ? 65282 : ($cidr->masklen == 32 ? 65280 : 65283) ); 471 addRec(defrec =>'n', revrec => 'y', parent_id => $zonelist->[0]->{rdns_id}, type => $type, 472 address => "$cidr", %args); 463 473 } 464 474 } … … 501 511 } 502 512 513 sub delByCIDR { 514 my %args = @_; 515 516 _commoncheck(\%args, 'y'); 517 518 # much like addOrUpdateRevRec() 519 my $zonelist = DNSDB::getZonesByCIDR($dbh, %args); 520 my $cidr = new NetAddr::IP $args{cidr}; 521 522 if (scalar(@$zonelist) == 0) { 523 # enhh.... WTF? 524 } elsif (scalar(@$zonelist) == 1) { 525 526 # check if the single zone returned is bigger than the CIDR 527 my $zone = new NetAddr::IP $zonelist->[0]->{revnet}; 528 if ($zone->contains($cidr)) { 529 530 if ($args{delsubs}) { 531 # Delete ALL EVARYTHING!!one11!! in $args{cidr} 532 my $reclist = DNSDB::getDomRecs($dbh, defrec => 'n', revrec => 'y', id => $zonelist->[0]->{rdns_id}); 533 foreach my $rec (@$reclist) { 534 my $reccidr = new NetAddr::IP $rec->{val}; 535 next unless $cidr->contains($reccidr); 536 ##fixme: multiple records, wanna wax'em all, how to report errors? 537 if ($args{delforward} || 538 $rec->{type} == 12 || $rec->{type} == 65282 || 539 $rec->{type} == 65283 || $rec->{type} == 65284) { 540 my ($code,$msg) = DNSDB::delRec($dbh, 'n', 'y', $rec->{record_id}); 541 } else { 542 my $ret = DNSDB::downconvert($dbh, $rec->{record_id}, $DNSDB::reverse_typemap{A}); 543 } 544 } 545 546 } else { 547 # Selectively delete only exact matches on $args{cidr} 548 549 # We need to strip the CIDR mask on IPv4 /32 assignments, or we can't find single-IP records 550 my $filt = ($cidr->{isv6} || $cidr->masklen != 32 ? "$cidr" : $cidr->addr); 551 my $reclist = DNSDB::getDomRecs($dbh, defrec => 'n', revrec => 'y', 552 id => $zonelist->[0]->{rdns_id}, filter => $filt, sortby => 'val', sortorder => 'DESC'); 553 foreach my $rec (@$reclist) { 554 my $reccidr = new NetAddr::IP $rec->{val}; 555 next unless $cidr == $reccidr; 556 if ($args{delforward} || $rec->{type} == 12) { 557 my ($code,$msg) = DNSDB::delRec($dbh, 'n', 'y', $rec->{record_id}); 558 die $msg if $code eq 'FAIL'; 559 return $msg; 560 } else { 561 my $ret = DNSDB::downconvert($dbh, $rec->{record_id}, $DNSDB::reverse_typemap{A}); 562 die $DNSDB::errstr if !$ret; 563 return "A+PTR for $args{cidr} split and PTR removed"; 564 } 565 } # foreach @$reclist 566 } 567 568 } else { # $cidr > $zone but we only have one zone 569 # ebbeh? CIDR is only partly represented in DNS. This needs manual intervention. 570 return "Warning: $args{cidr} is only partly represented in DNS. Check and remove DNS records manually."; 571 } # done single-zone-contains-$cidr 572 573 } else { # multiple zones nominally "contain" $cidr 574 # Overlapping reverse zones shouldn't be possible, so if we're here we've got a CIDR 575 # that spans multiple reverse zones (eg, /23 CIDR -> 2 /24 rzones) 576 foreach my $zdata (@$zonelist) { 577 my $reclist = DNSDB::getDomRecs($dbh, defrec => 'n', revrec => 'y', 578 id => $zdata->{rdns_id}, filter => $zdata->{revnet}); 579 if (scalar(@$reclist) == 0) { 580 my $type = ($args{cidr}->{isv6} ? 65282 : ($args{cidr}->masklen == 32 ? 65280 : 65283) ); 581 addRec(defrec =>'n', revrec => 'y', parent_id => $zdata->{rdns_id}, type => $type, 582 address => "$args{cidr}", %args); 583 } else { 584 foreach my $rec (@$reclist) { 585 # only the composite and/or template types; pure PTR or nontemplate composite 586 # types are nominally impossible here. 587 next unless $rec->{type} == 65282 || $rec->{type} == 65283 || $rec->{type} == 65284; 588 updateRec(defrec =>'n', revrec => 'y', id => $rec->{record_id}, 589 parent_id => $zdata->{rdns_id}, %args); 590 last; # only do one record. 591 } # foreach @$reclist 592 } 593 } # iterate zones within $cidr 594 } # done $cidr-contains-zones 595 596 } # end delByCIDR() 597 503 598 #sub getLogCount {} 504 599 #sub getLogEntries {}
Note:
See TracChangeset
for help on using the changeset viewer.