Changeset 340 for trunk


Ignore:
Timestamp:
06/08/12 18:14:05 (13 years ago)
Author:
Kris Deugau
Message:

/trunk

Fill in validation stubs for type 65282 (PTR template) and
65283 (A+PTR template). See #26.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/DNSDB.pm

    r339 r340  
    268268  return 0 if $parnet->addr =~ /:/ && $$val =~ /\./;
    269269
    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)
    272273    # the rest we have to restructure before fiddling.  *sigh*
    273274    return 1 if $$addr->within($parnet);
    274275  } 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
    276277    if ($parnet->addr =~ /:/) {
    277278      $$val =~ s/^:+//;  # gotta strip'em all...
     
    734735# PTR template record
    735736sub _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
    736811  return ('OK','OK');
    737812} # done PTR template record
     
    739814# A+PTR template record
    740815sub _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
    741874  return ('OK','OK');
    742875} # done AAAA+PTR template record
Note: See TracChangeset for help on using the changeset viewer.