- Timestamp:
- 06/08/12 18:14:05 (13 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/DNSDB.pm
r339 r340 268 268 return 0 if $parnet->addr =~ /:/ && $$val =~ /\./; 269 269 270 if ($$addr && $$val =~ /^[\da-fA-F][\da-fA-F:]+[\da-fA-F]$/) { 271 # the only case where NetAddr::IP's acceptance of legitimate IPs is "correct" is for a proper IPv6 address. 270 if ($$addr && ($$val =~ /^[\da-fA-F][\da-fA-F:]+[\da-fA-F]$/ || $$val =~ m|/\d+$|)) { 271 # the only case where NetAddr::IP's acceptance of legitimate IPs is "correct" is for a proper IPv6 address, 272 # or a netblock (only expected on templates) 272 273 # the rest we have to restructure before fiddling. *sigh* 273 274 return 1 if $$addr->within($parnet); 274 275 } else { 275 # We don't have a complete IP in $$val (yet) 276 # We don't have a complete IP in $$val (yet)... unless we have a netblock 276 277 if ($parnet->addr =~ /:/) { 277 278 $$val =~ s/^:+//; # gotta strip'em all... … … 734 735 # PTR template record 735 736 sub _validate_65282 { 737 my $dbh = shift; 738 739 my %args = @_; 740 741 # we're *this* >.< close to being able to just call _validate_12... unfortunately we can't, quite. 742 if ($args{revrec} eq 'y') { 743 if ($args{defrec} eq 'n') { 744 return ('FAIL', "Template block ${$args{val}} is not within ".revName($dbh, $args{id})) 745 unless _ipparent($dbh, $args{defrec}, $args{revrec}, $args{val}, $args{id}, \$args{addr}); 746 ##fixme: warn if $args{val} is not /31 or larger block? 747 ${$args{val}} = "$args{addr}"; 748 } else { 749 if (${$args{val}} =~ /\./) { 750 # looks like a v4 or fragment 751 if (${$args{val}} =~ m|^\d+\.\d+\.\d+\.\d+(?:/\d+)?$|) { 752 # woo! a complete IP! validate it and normalize, or fail. 753 $args{addr} = NetAddr::IP->new(${$args{val}}) 754 or return ('FAIL', "IP/value looks like IPv4 but isn't valid"); 755 ${$args{val}} = "$args{addr}"; 756 } else { 757 ${$args{val}} =~ s/^\.*/ZONE./ unless ${$args{val}} =~ /^ZONE/; 758 } 759 } elsif (${$args{val}} =~ /[a-f:]/) { 760 # looks like a v6 or fragment 761 ${$args{val}} =~ s/^:*/ZONE::/ if !$args{addr} && ${$args{val}} !~ /^ZONE/; 762 if ($args{addr}) { 763 if ($args{addr}->addr =~ /^0/) { 764 ${$args{val}} =~ s/^:*/ZONE::/ unless ${$args{val}} =~ /^ZONE/; 765 } else { 766 ${$args{val}} = "$args{addr}"; 767 } 768 } 769 } else { 770 # bare number (probably). These could be v4 or v6, so we'll 771 # expand on these on creation of a reverse zone. 772 ${$args{val}} = "ZONE,${$args{val}}" unless ${$args{val}} =~ /^ZONE/; 773 } 774 } 775 ##fixme: validate %-patterns? 776 777 # Unlike single PTR records, there is absolutely no way to sanely support multiple 778 # PTR templates for the same block, since they expect to expand to all the individual 779 # IPs on export. Nested templates should be supported though. 780 781 my @checkvals = (${$args{val}}); 782 if (${$args{val}} =~ /,/) { 783 # push . and :: variants into checkvals if val has , 784 my $tmp; 785 ($tmp = ${$args{val}}) =~ s/,/./; 786 push @checkvals, $tmp; 787 ($tmp = ${$args{val}}) =~ s/,/::/; 788 push @checkvals, $tmp; 789 } 790 ##fixme: this feels wrong still - need to restrict template pseudorecords to One Of Each 791 # Per Netblock such that they don't conflict on export 792 my $typeck; 793 # type 65282 -> ptr template -> look for any of 65282, 65283, 65284 794 $typeck = 'type=65283 OR type=65284' if ${$args{rectype}} == 65282; 795 # type 65283 -> a+ptr template -> v4 -> look for 65282 or 65283 796 $typeck = 'type=65283' if ${$args{rectype}} == 65282; 797 # type 65284 -> aaaa+ptr template -> v6 -> look for 65282 or 65284 798 $typeck = 'type=65284' if ${$args{rectype}} == 65282; 799 my $pcsth = $dbh->prepare("SELECT count(*) FROM "._rectable($args{defrec},$args{revrec})." WHERE val = ? ". 800 "AND (type=65282 OR $typeck)"); 801 foreach my $checkme (@checkvals) { 802 $pcsth->execute($checkme); 803 my ($rc) = $pcsth->fetchrow_array; 804 return ('FAIL', "Only one template pseudorecord may exist for a given IP block") if $rc; 805 } 806 807 } else { 808 return ('FAIL', "Forward zones cannot contain PTR records"); 809 } 810 736 811 return ('OK','OK'); 737 812 } # done PTR template record … … 739 814 # A+PTR template record 740 815 sub _validate_65283 { 816 my $dbh = shift; 817 818 my %args = @_; 819 820 my ($code,$msg) = ('OK','OK'); 821 822 ##fixme: need to fiddle things since A+PTR templates are acceptable in live 823 # forward zones but not default records 824 if ($args{defrec} eq 'n') { 825 if ($args{revrec} eq 'n') { 826 ($code,$msg) = _validate_1($dbh, %args) if ${$args{rectype}} == 65280; 827 ($code,$msg) = _validate_28($dbh, %args) if ${$args{rectype}} == 65281; 828 return ($code,$msg) if $code eq 'FAIL'; 829 830 # Check if the requested reverse zone exists - note, an IP fragment won't 831 # work here since we don't *know* which parent to put it in. 832 # ${$args{val}} has been validated as a valid IP by now, in one of the above calls. 833 my ($revid) = $dbh->selectrow_array("SELECT rdns_id FROM revzones WHERE revnet >> ?". 834 " ORDER BY masklen(revnet) DESC", undef, (${$args{val}})); 835 # Fail if no match; we can't coerce a PTR-template type down to not include the PTR bit currently. 836 if (!$revid) { 837 $msg = "Can't ".($args{update} ? 'update' : 'add')." ${$args{host}}/${$args{val}} as ". 838 "$typemap{${$args{rectype}}}: reverse zone not found for ${$args{val}}"; 839 ##fixme: add A template, AAAA template types? 840 # ${$args{rectype}} = (${$args{rectype}} == 65280 ? $reverse_typemap{A} : $reverse_typemap{AAAA}); 841 return ('FAIL', $msg); 842 } 843 844 # Add reverse zone ID to field list and values 845 ${$args{fields}} .= "rdns_id,"; 846 push @{$args{vallist}}, $revid; 847 848 } else { 849 return ('FAIL', "IP or IP fragment ${$args{val}} is not within ".revName($dbh, $args{id})) 850 unless _ipparent($dbh, $args{defrec}, $args{revrec}, $args{val}, $args{id}, \$args{addr}); 851 ${$args{val}} = "$args{addr}"; 852 853 if (!(${$args{domid}} = _hostparent($dbh, ${$args{host}}))) { 854 my $addmsg = "Record ".($args{update} ? 'updated' : 'added'). 855 " as PTR template instead of $typemap{${$args{rectype}}}; domain not found for ${$args{host}}"; 856 $msg .= "\n$addmsg" if $code eq 'WARN'; 857 $msg = $addmsg if $code eq 'OK'; 858 ${$args{rectype}} = 65282; 859 return ('WARN', $msg); 860 } 861 862 # Add domain ID to field list and values 863 ${$args{fields}} .= "domain_id,"; 864 push @{$args{vallist}}, ${$args{domid}}; 865 } 866 867 } else { 868 my ($code,$msg) = _validate_65282($dbh, %args); 869 return ($code, $msg) if $code eq 'FAIL'; 870 # get domain, check against ${$args{name}} 871 } 872 873 # check domain, if nonexistent coerce down to PTR template 741 874 return ('OK','OK'); 742 875 } # done AAAA+PTR template record
Note:
See TracChangeset
for help on using the changeset viewer.