Changeset 725 for branches/stable/dns-rpc.cgi
- Timestamp:
- 06/20/16 13:18:07 (9 years ago)
- Location:
- branches/stable
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/stable
-
branches/stable/dns-rpc.cgi
r690 r725 137 137 ## 138 138 139 ## 140 ## Internal utility subs 141 ## 142 139 143 # Check RPC ACL 140 144 sub _aclcheck { … … 174 178 } 175 179 176 # set ttl to zone defa ilt minttl if none is specified180 # set ttl to zone default minttl if none is specified 177 181 sub _ttlcheck { 178 182 my $argref = shift; … … 182 186 } 183 187 } 188 189 # Check if the hashrefs passed in refer to identical record data, so we can skip 190 # the actual update if nothing has actually changed. This is mainly useful for 191 # reducing log noise due to chained calls orginating with updateRevSet() since 192 # "many" records could be sent for update but only one or two have actually changed. 193 sub _checkRecMod { 194 my $oldrec = shift; 195 my $newrec = shift; 196 197 # Because we don't know which fields we've even been passed 198 no warnings qw(uninitialized); 199 200 my $modflag = 0; 201 # order by most common change. host should be first, due to rDNS RPC calls 202 for my $field qw(host type val) { 203 return 1 if ( 204 defined($newrec->{$field}) && 205 $oldrec->{$field} ne $newrec->{$field} ); 206 } 207 208 return 0; 209 } # _checRecMod 210 211 212 ## 213 ## Shims for DNSDB core subs 214 ## 184 215 185 216 #sub connectDB { … … 215 246 ($code,$msg) = $dnsdb->delZone($args{zone}, $args{revrec}); 216 247 } else { 248 die "Need zone location\n" if !defined($args{location}); 217 249 my $zoneid; 218 $zoneid = $dnsdb->domainID($args{zone} ) if $args{revrec} eq 'n';219 $zoneid = $dnsdb->revID($args{zone} ) if $args{revrec} eq 'y';250 $zoneid = $dnsdb->domainID($args{zone}, $args{location}) if $args{revrec} eq 'n'; 251 $zoneid = $dnsdb->revID($args{zone}, $args{location}) if $args{revrec} eq 'y'; 220 252 die "Can't find zone: ".$dnsdb->errstr."\n" if !$zoneid; 221 253 ($code,$msg) = $dnsdb->delZone($zoneid, $args{revrec}); … … 233 265 _commoncheck(\%args, 'y'); 234 266 235 my $domid = $dnsdb->domainID($args{domain} );267 my $domid = $dnsdb->domainID($args{domain}, $args{location}); 236 268 die $dnsdb->errstr."\n" if !$domid; 237 269 return $domid; … … 419 451 die "Missing zone ID\n" if !$args{id}; 420 452 453 # caller may not know about zone IDs. accept the zone name, but require a location if so 454 if ($args{id} !~ /^\d+$/) { 455 die "Location required to use the zone name\n" if !defined($args{location}); 456 } 457 421 458 # set some optional args 422 459 $args{offset} = 0 if !$args{offset}; … … 430 467 if ($args{defrec} eq 'n') { 431 468 if ($args{revrec} eq 'n') { 432 $args{id} = $dnsdb->domainID($args{id} ) if $args{id} !~ /^\d+$/;469 $args{id} = $dnsdb->domainID($args{id}, $args{location}) if $args{id} !~ /^\d+$/; 433 470 } else { 434 $args{id} = $dnsdb->revID($args{id} ) if $args{id} !~ /^\d+$/471 $args{id} = $dnsdb->revID($args{id}, $args{location}) if $args{id} !~ /^\d+$/ 435 472 } 436 473 } … … 454 491 455 492 _reccheck(\%args); 493 494 # caller may not know about zone IDs. accept the zone name, but require a location if so 495 if ($args{id} !~ /^\d+$/) { 496 die "Location required to use the zone name\n" if !defined($args{location}); 497 } 456 498 457 499 # set some optional args … … 462 504 $args{direction} = 'ASC' if !$args{direction}; 463 505 506 # convert zone name to zone ID, if needed 507 if ($args{defrec} eq 'n') { 508 if ($args{revrec} eq 'n') { 509 $args{id} = $dnsdb->domainID($args{id}, $args{location}) if $args{id} !~ /^\d+$/; 510 } else { 511 $args{id} = $dnsdb->revID($args{id}, $args{location}) if $args{id} !~ /^\d+$/ 512 } 513 } 514 515 # fail if we *still* don't have a valid zone ID 516 die $dnsdb->errstr."\n" if !$args{id}; 517 464 518 my $ret = $dnsdb->getRecCount(defrec => $args{defrec}, revrec => $args{revrec}, 465 519 id => $args{id}, filter => $args{filter}); … … 468 522 469 523 return $ret; 470 } 524 } # getRecCount() 471 525 472 526 # The core sub uses references for some arguments to allow limited modification for … … 534 588 } # rpc_updateRec 535 589 590 536 591 # Takes a passed CIDR block and DNS pattern; adds a new record or updates the record(s) affected 537 592 sub addOrUpdateRevRec { … … 541 596 my $cidr = new NetAddr::IP $args{cidr}; 542 597 543 ##fixme: Minor edge case; if we receive calls one after the other to update 544 # to the same thing, we bulk out the log with useless notices. Leaving this 545 # for future development since this should be rare in practice. 598 # Location required so we don't turn up unrelated zones in getZonesByCIDR(). 599 # Caller should generally have some knowledge of this. 600 die "Need location\n" if !defined($args{location}); 546 601 547 602 my $zonelist = $dnsdb->getZonesByCIDR(%args); … … 552 607 my $zone = new NetAddr::IP $zonelist->[0]->{revnet}; 553 608 if ($zone->contains($cidr)) { 554 # We need to strip the CIDR mask on IPv4 /32 assignments, or we just add a new record all the time. 555 my $filt = ($cidr->{isv6} || $cidr->masklen != 32 ? "$cidr" : $cidr->addr); 556 my $reclist = $dnsdb->getRecList(defrec => 'n', revrec => 'y', 609 # We need to strip the CIDR mask on IPv4 /32 or v6 /128 assignments, or we just add a new record all the time. 610 my $filt = ( $cidr->{isv6} ? ($cidr->masklen != 128 ? "$cidr" : $cidr->addr) : 611 ($cidr->masklen != 32 ? "$cidr" : $cidr->addr) ); 612 my $reclist = $dnsdb->getRecList(rpc => 1, defrec => 'n', revrec => 'y', 557 613 id => $zonelist->[0]->{rdns_id}, filter => $filt); 558 614 ##fixme: Figure some new magic to automerge new incoming A(AAA)+PTR requests … … 570 626 || $rec->{type} == 65282 || $rec->{type} == 65283 || $rec->{type} == 65284; 571 627 next unless $rec->{val} eq $filt; # make sure we really update the record we want to update. 628 # canonicalize the IP values so funny IPv6 short forms don't 629 # cause non-updates by not being literally string-equal 630 $rec->{val} = new NetAddr::IP $rec->{val}; 631 my $tmpcidr = new NetAddr::IP $args{cidr}; 632 my %newrec = (host => $args{name}, val => $tmpcidr, type => $args{type}); 572 633 rpc_updateRec(defrec =>'n', revrec => 'y', id => $rec->{record_id}, 573 parent_id => $zonelist->[0]->{rdns_id}, address => "$cidr", %args); 634 parent_id => $zonelist->[0]->{rdns_id}, address => "$cidr", %args) 635 if _checkRecMod($rec, \%newrec); # and only do the update if there really is something to change 574 636 $flag = 1; 575 637 last; # only do one record. … … 590 652 # that spans multiple reverse zones (eg, /23 CIDR -> 2 /24 rzones) 591 653 foreach my $zdata (@$zonelist) { 592 my $reclist = $dnsdb->getRecList( defrec => 'n', revrec => 'y',654 my $reclist = $dnsdb->getRecList(rpc => 1, defrec => 'n', revrec => 'y', 593 655 id => $zdata->{rdns_id}, filter => $zdata->{revnet}); 594 656 if (scalar(@$reclist) == 0) { … … 597 659 address => "$args{cidr}", %args); 598 660 } else { 661 my $updflag = 0; 599 662 foreach my $rec (@$reclist) { 600 663 # only the composite and/or template types; pure PTR or nontemplate composite 601 664 # types are nominally impossible here. 602 665 next unless $rec->{type} == 65282 || $rec->{type} == 65283 || $rec->{type} == 65284; 666 my %newrec = (host => $args{name}, val => $zdata->{revnet}, type => $args{type}); 603 667 rpc_updateRec(defrec => 'n', revrec => 'y', id => $rec->{record_id}, 604 parent_id => $zdata->{rdns_id}, %args); 668 parent_id => $zdata->{rdns_id}, %args) 669 if _checkRecMod($rec, \%newrec); # and only do the update if there really is something to change 670 $updflag = 1; 605 671 last; # only do one record. 606 672 } 607 } 673 # catch the case of "oops, no zone-sized template record and need to add a new one", 674 # because the SOA and NS records will be returned from the getRecList() call above 675 unless ($updflag) { 676 my $type = ($cidr->{isv6} ? 65284 : 65283); 677 rpc_addRec(defrec => 'n', revrec => 'y', parent_id => $zdata->{rdns_id}, type => $type, 678 address => $zdata->{revnet}, %args); 679 } 680 } # scalar(@$reclist) != 0 608 681 } # iterate zones within $cidr 609 682 } # done $cidr-contains-zones … … 623 696 next unless $key =~ m{^host_((?:[\d.]+|[\da-f:]+)(?:/\d+)?)$}; 624 697 my $ip = $1; 625 push @ret, addOrUpdateRevRec(cidr => $ip, name => $args{$key}, %args); 626 } 698 push @ret, addOrUpdateRevRec(%args, cidr => $ip, name => $args{$key}); 699 } 700 701 # now we check the parts of the block that didn't get passed to see if they should be deleted 702 my $block = new NetAddr::IP $args{cidr}; 703 if (!$block->{isv6}) { 704 foreach my $ip (@{$block->splitref(32)}) { 705 my $bare = $ip->addr; 706 next if $args{"host_$bare"}; 707 delByCIDR(delforward => 1, delsubs => 0, cidr => $bare, location => $args{location}, 708 rpcuser => $args{rpcuser}, rpcsystem => $args{rpcsystem}); 709 } 710 } 711 627 712 ##fixme: what about errors? what about warnings? 628 713 return \@ret; … … 637 722 638 723 my $cidr = new NetAddr::IP $args{cidr}; 724 725 # Location required so we don't turn up unrelated zones in getZonesByCIDR(). 726 # Caller should generally have some knowledge of this. 727 die "Need location\n" if !defined($args{location}); 639 728 640 729 my $zonelist = $dnsdb->getZonesByCIDR(%args); … … 647 736 if ($zone->contains($cidr)) { 648 737 # Find the first record in the reverse zone that matches the CIDR we're splitting... 649 my $reclist = $dnsdb->getRecList( defrec => 'n', revrec => 'y',738 my $reclist = $dnsdb->getRecList(rpc => 1, defrec => 'n', revrec => 'y', 650 739 id => $zonelist->[0]->{rdns_id}, filter => $cidr, sortby => 'val', sortorder => 'DESC'); 651 740 my $oldrec; … … 706 795 707 796 my $up_res; 797 798 # Location required so we don't turn up unrelated zones in getZonesByCIDR(). 799 # Caller should generally have some knowledge of this. 800 die "Need location\n" if !defined($args{location}); 708 801 709 802 my $zonelist = $dnsdb->getZonesByCIDR(%args); … … 769 862 my @retlist; 770 863 771 my $zsth = $dnsdb->{dbh}->prepare("SELECT rdns_id,group_id FROM revzones WHERE revnet >>= ?"); 864 # Location required so we don't turn up unrelated zones 865 die "Need location\n" if !defined($args{location}); 866 867 my $zsth = $dnsdb->{dbh}->prepare("SELECT rdns_id,group_id FROM revzones WHERE revnet >>= ? AND location = ?"); 772 868 # Going to assume template records with no expiry 773 869 # Also note IPv6 template records don't expand sanely the way v4 records do … … 792 888 eval { 793 889 foreach my $template (@{$args{templates}}) { 794 $zsth->execute($template );890 $zsth->execute($template, $args{location}); 795 891 my ($zid,$zgrp) = $zsth->fetchrow_array; 796 892 if (!$zid) { … … 851 947 # Caller may pass 'n' in delsubs. Assume it should be false/undefined 852 948 # unless the caller explicitly requested 'yes' 853 $args{delsubs} = 0 if $args{delsubs} ne 'y';949 $args{delsubs} = 0 if !$args{delsubs} || $args{delsubs} ne 'y'; 854 950 855 951 # Don't delete the A component of an A+PTR by default 856 952 $args{delforward} = 0 if !$args{delforward}; 953 954 # Location required so we don't turn up unrelated zones in getZonesByCIDR(). 955 die "Need location\n" if !defined($args{location}); 857 956 858 957 # much like addOrUpdateRevRec() … … 869 968 if ($args{delsubs}) { 870 969 # Delete ALL EVARYTHING!!one11!! in $args{cidr} 871 my $reclist = $dnsdb->getRecList( defrec => 'n', revrec => 'y', id => $zonelist->[0]->{rdns_id});970 my $reclist = $dnsdb->getRecList(rpc => 1, defrec => 'n', revrec => 'y', id => $zonelist->[0]->{rdns_id}); 872 971 foreach my $rec (@$reclist) { 873 972 my $reccidr = new NetAddr::IP $rec->{val}; … … 895 994 # Selectively delete only exact matches on $args{cidr} 896 995 # We need to strip the CIDR mask on IPv4 /32 assignments, or we can't find single-IP records 897 my $filt = ($cidr->{isv6} || $cidr->masklen != 32 ? "$cidr" : $cidr->addr); 898 my $reclist = $dnsdb->getRecList(defrec => 'n', revrec => 'y', 996 my $filt = ( $cidr->{isv6} ? ($cidr->masklen != 128 ? "$cidr" : $cidr->addr) : 997 ($cidr->masklen != 32 ? "$cidr" : $cidr->addr) ); 998 my $reclist = $dnsdb->getRecList(rpc => 1, defrec => 'n', revrec => 'y', location => $args{location}, 899 999 id => $zonelist->[0]->{rdns_id}, filter => $filt, sortby => 'val', sortorder => 'DESC'); 900 1000 foreach my $rec (@$reclist) { … … 924 1024 # that spans multiple reverse zones (eg, /23 CIDR -> 2 /24 rzones) 925 1025 foreach my $zdata (@$zonelist) { 926 my $reclist = $dnsdb->getRecList( defrec => 'n', revrec => 'y', id => $zdata->{rdns_id});1026 my $reclist = $dnsdb->getRecList(rpc => 1, defrec => 'n', revrec => 'y', id => $zdata->{rdns_id}); 927 1027 if (scalar(@$reclist) == 0) { 928 1028 # nothing to do? or do we (re)add a record based on the parent? … … 981 1081 _commoncheck(\%args, 'y'); 982 1082 983 return $dnsdb->getRevPattern($args{cidr}, $args{group});1083 return $dnsdb->getRevPattern($args{cidr}, location => $args{location}, group => $args{group}); 984 1084 } 985 1085 … … 989 1089 _commoncheck(\%args, 'y'); 990 1090 991 return $dnsdb->getRevSet($args{cidr}, $args{group});1091 return $dnsdb->getRevSet($args{cidr}, location => $args{location}, group => $args{group}); 992 1092 } 993 1093
Note:
See TracChangeset
for help on using the changeset viewer.