Changeset 35 for trunk/DNSDB.pm


Ignore:
Timestamp:
11/13/09 18:05:34 (15 years ago)
Author:
Kris Deugau
Message:

/trunk

checkpoint - my Net::DNS vs DBD::Pg weirdness went away

  • clean up return-message handling for AXFR
  • check AXFR host to remove taint flag so IO::Socket doesn't whine
  • rearrange statement handles in DNSDB::importAXFR
  • add some flags to fail on no records at all, no SOA, or no NS records
  • tweak template to put error in a row at the top of the import form vs an uncontrolled div
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/DNSDB.pm

    r34 r35  
    816816sub importAXFR {
    817817  my $dbh = shift;
    818   my $ifrom = shift;
     818  my $ifrom_in = shift;
    819819  my $domain = shift;
    820820  my $group = shift;
     
    824824##fixme:  add mode to delete&replace, merge+overwrite, merge new?
    825825
    826 
    827826my $nrecs = 0;
    828 my $flags = 0;
    829 my $warnmsg;
     827my $soaflag = 0;
     828my $nsflag = 0;
     829my $warnmsg = '';
     830my $ifrom;
     831
     832  # choke on possible bad setting in ifrom
     833  # IPv4 and v6!
     834  ($ifrom) = ($ifrom_in =~ /^([0-9a-f\:.]+|[0-9a-z_.-]+)$/i);
     835  return ('FAIL', "Bad AXFR source host $ifrom")
     836        unless ($ifrom) = ($ifrom_in =~ /^([0-9a-f\:.]+|[0-9a-z_.-]+)$/i);
    830837
    831838  # Allow transactions, and raise an exception on errors so we can catch it later.
     
    834841  local $dbh->{RaiseError} = 1;
    835842
     843  my $sth_domin = $dbh->prepare("INSERT INTO domains (domain,group_id,status) VALUES (?,?,?)");
     844  my $sth_getid = $dbh->prepare("SELECT domain_id FROM domains WHERE domain=?");
    836845  my $dom_id;
     846
     847# quick check to start to see if we've already got one
     848  $sth_getid->execute($domain);
     849  ($dom_id) = $sth_getid->fetchrow_array;
     850
     851  return ('FAIL', "Domain already exists") if $dom_id;
    837852
    838853  eval {
    839854    # can't do this, can't nest transactions.  sigh.
    840     #my ($dcode, $dmsg) = addDomain($dbh, $domain, $group, $status);
     855    #my ($dcode, $dmsg) = addDomain(dbh, domain, group, status);
    841856
    842857##fixme:  serial
    843     my $sth = $dbh->prepare("INSERT INTO domains (domain,group_id,status) VALUES (?,?,?)");
    844 $warnmsg = "trying lokido... (".$dbh->{AutoCommit}."), (".$dbh->{RaiseError}.")" if $domain eq 'waslokido.com';
    845     $sth->execute($domain,$group,$status);
     858    $sth_domin->execute($domain,$group,$status);
     859
     860## bizarre DBI<->Net::DNS interaction bug:
     861## sometimes a zone will cause an immediate commit-and-exit (sort of) of the while()
    846862
    847863    # get domain id so we can do the records
    848     $sth = $dbh->prepare("select domain_id from domains where domain='$domain'");
    849     $sth->execute;
    850     ($dom_id) = $sth->fetchrow_array();
    851 $warnmsg .= " [domid $dom_id]";
     864    $sth_getid->execute($domain);
     865    ($dom_id) = $sth_getid->fetchrow_array();
    852866
    853867    my $res = Net::DNS::Resolver->new;
    854     unless ($res->axfr_start($domain)) {
    855       $dbh->rollback;
    856       die "Couldn't begin AXFR\n";
    857     }
    858 
    859 #die "just started AXFR\n";
    860 
    861     while (my $rr = $res->axfr_next) {
    862 $warnmsg = $rr->string;
     868    $res->nameservers($ifrom);
     869    $res->axfr_start($domain)
     870        or die "Couldn't begin AXFR\n";
     871
     872#my $foobar = $res->axfr_next() if $domain =~ /loki/;
     873#die "outside the loop with ".$foobar->type."\n" if $domain =~ /loki/;
     874
     875    while (my $rr = $res->axfr_next()) {
    863876      my $type = $rr->type;
    864 # nasty big ugly case-like thing here, since we have to do *some* different
    865 # processing depending on the record.  le sigh.
     877
     878#die "first record! $type\n" if $domain =~ /lok/;
     879
    866880      my $sql = "INSERT INTO records (domain_id,host,type,ttl,val";
    867881      my $vallen = "?,?,?,?,?";
     
    870884#      my $val;
    871885
     886$soaflag = 1 if $type eq 'SOA';
     887$nsflag = 1 if $type eq 'NS';
     888
    872889##work
    873 # gnnnnnh.  going to need to (rr->string)  ->  split  ->  <localvars>  ?
    874 my @vallist = ($dom_id, $rr->name, $reverse_typemap{$type}, $rr->ttl);
     890      my @vallist = ($dom_id, $rr->name, $reverse_typemap{$type}, $rr->ttl);
    875891
    876892# "Primary" types:
    877893# A, NS, CNAME, SOA, PTR(warn in forward), MX, TXT, AAAA, SRV, A6(ob), SPF
    878894# maybe KEY
     895
     896# nasty big ugly case-like thing here, since we have to do *some* different
     897# processing depending on the record.  le sigh.
    879898
    880899      if ($type eq 'A') {
     
    882901      } elsif ($type eq 'NS') {
    883902        push @vallist, $rr->nsdname;
     903        $nsflag = 1;
    884904      } elsif ($type eq 'CNAME') {
    885905        push @vallist, $rr->cname;
     
    887907        $vallist[1] = $rr->mname.":".$rr->rname;
    888908        push @vallist, ($rr->refresh.":".$rr->retry.":".$rr->expire.":".$rr->minimum);
     909        $soaflag = 1;
    889910      } elsif ($type eq 'PTR') {
    890911        # hmm.  PTR records should not be in forward zones.
     
    910931        push @vallist, $rr->port;
    911932      } elsif ($type eq 'KEY') {
     933        # we don't actually know what to do with these...
    912934        push @vallist, ($rr->flags.":".$rr->protocol.":".$rr->algorithm.":".$rr->key.":".$rr->keytag.":".$rr->privatekeyname);
     935      } else {
     936        # Finding a different record type is not fatal.... just problematic.
     937        $warnmsg .= "Unusual record ".$rr->name." ($type) found\n";
    913938      }
    914 
    915 $warnmsg = $rr->string;
    916 $dbh->rollback if $domain eq 'waslokido.com';
    917 die "first record: ".$rr->string."\n" if $domain eq 'waslokido.com';
    918939
    919940# BIND supports:
     
    934955      }
    935956
    936       $sth = $dbh->prepare($sql.") VALUES (".$vallen.")");
    937       $sth->execute(@vallist) or die "failed to insert ".$rr->string.": ".$sth->errstr."\n" if $sth->err;
     957      my $sth_rr = $dbh->prepare($sql.") VALUES (".$vallen.")");
     958      $sth_rr->execute(@vallist) or die "failed to insert ".$rr->string.": ".$sth_rr->errstr."\n" if $sth_rr->err;
    938959
    939960      if ($type eq 'SOA') {
    940961      }
    941962
     963#die "die.die.die!\n";
     964
     965      $nrecs++;
     966
     967    } # while axfr_next
     968
     969    die "No records found;  either $ifrom is not authoritative or doesn't allow transfers\n" if !$nrecs;
     970    die "Bad zone:  No SOA record!\n" if !$soaflag;
     971    die "Bad zone:  No NS records!\n" if !$nsflag;
     972
    942973$dbh->rollback;
    943 #die "die.die.die!\n";
    944 
    945       #print $rr->rdata."\n";
    946     }
     974#    $dbh->commit;
     975
     976#    die "Bad zone.  BAD zone!  No cookie!\n";
     977#die "don't insert me!  I'm nasty, I am!\n";
    947978  };
    948979
     
    950981    my $msg = $@;
    951982    eval { $dbh->rollback; };
     983#    $dbh->do("delete from domains where domain='$domain'");
    952984    return ('FAIL',$msg." $warnmsg");
    953985  } else {
    954     return ('WARN', "OOOK!  Ooooook.  Ook. ($warnmsg)") if $domain eq 'deepnet.cx';
    955     return ('WARN', "Funky Things Happened: $warnmsg") if $domain eq 'waslokido.com';
     986#    $dbh->do("delete from domains where domain='$domain'");
     987    return ('WARN', $warnmsg) if $warnmsg;
    956988    return ('OK',"ook");
    957989  }
Note: See TracChangeset for help on using the changeset viewer.