Changeset 1032 for branches/stable


Ignore:
Timestamp:
02/10/26 13:30:58 (3 days ago)
Author:
Kris Deugau
Message:

/branches/stable

Start merging changes from /trunk forward based on changes actually applied
in production

Location:
branches/stable
Files:
10 edited
2 copied

Legend:

Unmodified
Added
Removed
  • branches/stable

  • branches/stable/DNSDB.pm

    r756 r1032  
    33##
    44# $Id$
    5 # Copyright 2008-2016 Kris Deugau <kdeugau@deepnet.cx>
     5# Copyright 2008-2017 Kris Deugau <kdeugau@deepnet.cx>
    66#
    77#    This program is free software: you can redistribute it and/or modify
     
    983983  ${$args{weight}} =~ s/\s*//g;
    984984  ${$args{port}} =~ s/\s*//g;
    985   return ('FAIL',"Distance, port and weight are required, and must be numeric")
    986         unless ${$args{weight}} =~ /^\d+$/ && ${$args{port}} =~ /^\d+$/;
     985  my @ferr;
     986  push @ferr, "distance" unless ${$args{dist}} =~ /^\d+$/;
     987  push @ferr, "weight" unless ${$args{weight}} =~ /^\d+$/;
     988  push @ferr, "port" unless ${$args{port}} =~ /^\d+$/;
     989  return ('FAIL',"Distance, port and weight are required, and must be numeric (check ".join(",", @ferr).")")
     990        unless ${$args{dist}} =~ /^\d+$/ && ${$args{weight}} =~ /^\d+$/ && ${$args{port}} =~ /^\d+$/;
    987991
    988992  ${$args{fields}} = "distance,weight,port,";
     
    13691373  }
    13701374  return ('OK','OK');
    1371 }
     1375} # done delegation record
     1376
     1377# ALIAS record
     1378# A specialized variant of the CNAME, which retrieves the A record list on each
     1379# export and publishes the A records instead.  Primarily for "root CNAME" or "apex
     1380# alias" records.  See https://secure.deepnet.cx/trac/dnsadmin/ticket/55.
     1381# Not allowed in reverse zones because this is already a hack, and reverse zones
     1382# don't get pointed to CNAMEed CDNs the way domains do.
     1383sub _validate_65300 {
     1384  my $self = shift;
     1385  my $dbh = $self->{dbh};
     1386
     1387  my %args = @_;
     1388
     1389  return ('FAIL',"ALIAS records are not permitted in reverse zones") if $args{revrec} eq 'y';
     1390
     1391  # Make sure target is a well-formed hostname
     1392  return ('FAIL', $errstr) if ! _check_hostname_form(${$args{val}}, ${$args{rectype}}, $args{defrec}, $args{revrec});
     1393
     1394  # Coerce all hostnames to end in ".DOMAIN" for group/default records,
     1395  # or the intended parent domain for live records.
     1396  my $pname = ($args{defrec} eq 'y' ? 'DOMAIN' : $self->domainName($args{id}));
     1397  ${$args{host}} =~ s/\.*$/\.$pname/ if (${$args{host}} ne '@' && ${$args{host}} !~ /$pname$/i);
     1398
     1399  # Only do the cache thing on live/active records
     1400  return ('OK','OK') unless $args{defrec} eq 'n';
     1401
     1402  # now we check/update the cached target address info
     1403  my ($iplist) = $self->{dbh}->selectrow_array("SELECT auxdata FROM records WHERE record_id = ?", undef, $args{recid});
     1404  my $warnmsg;
     1405  $iplist = '' if !$iplist;
     1406
     1407  # shared target-name-to-IP converter
     1408  my $liveips = $self->_grab_65300($args{recid}, ${$args{val}});
     1409  $liveips = '' if !$liveips;
     1410
     1411  # check to see if there was an OOOOPS checking for updated A records on the target.  also make sure we have something cached.
     1412  if (!$liveips) {
     1413    if (!$iplist) {
     1414      # not fatal since we do the lookup on export as well
     1415      $warnmsg = "No cached data and no live DNS data for ALIAS target ${$args{val}};  record may be SKIPPED on export!";
     1416    }
     1417  }
     1418
     1419  # munge the insert/update fieldlist and data array
     1420  # note we always force this;  if the target has changed the cached data is almost certainly invalid anyway
     1421  if ($liveips && ($iplist ne $liveips)) {
     1422    ${$args{fields}} .= "auxdata,";
     1423    push @{$args{vallist}}, $liveips;
     1424  }
     1425
     1426  return ('WARN', join("\n", $errstr, $warnmsg) ) if $warnmsg;
     1427 
     1428  return ('OK','OK');
     1429} # done ALIAS record
     1430
     1431# this segment used multiple places to update ALIAS target details
     1432sub _grab_65300 {
     1433  my $self = shift;
     1434  my $dbh = $self->{dbh};
     1435
     1436  my $recid = shift;
     1437  my $target = shift;
     1438
     1439  my $res = Net::DNS::Resolver->new;
     1440  $res->tcp_timeout(2);
     1441  $res->udp_timeout(2);
     1442  my $reply = $res->query($target);
     1443
     1444  my $liveips = '';
     1445  if ($reply) {
     1446    # default to a one-hour TTL, which should be variously modified down the chain.  Arguably this could
     1447    # default even lower, since "The Cloud" often uses sub-1-minute TTLs on the final A records.
     1448    my $minttl = 3600;
     1449    my @newlist;
     1450    foreach my $rr ($reply->answer) {  #@alist) {
     1451      next unless $rr->type eq "A";
     1452      push @newlist, $rr->address;
     1453      $minttl = $rr->ttl if $rr->ttl < $minttl;
     1454    }
     1455    # safety limit.  could arguably take this lower, or for extra
     1456    # complexity, reference off the zone SOA minTTL
     1457    $minttl = 60 if $minttl < 60;
     1458    # we don't need this to be perfectly correct IP address order, just consistent.
     1459    $liveips = "$minttl:".join(':', sort(@newlist)) if @newlist;
     1460#fixme:  should it be a formal error case if there are no A records returned?
     1461  } else {
     1462    $errstr = "Lookup failure retrieving ALIAS IP list: ".$res->errorstring;
     1463  }
     1464
     1465  return $liveips;
     1466} # _grab_65300()
     1467
    13721468
    13731469# Subs not specific to a particular record type
     
    44164512
    44174513  # do simple validation first
     4514  $ttl = '' if !$ttl;
     4515  $ttl =~ s/\s*//g;
    44184516  return ('FAIL', "TTL must be numeric") unless $ttl =~ /^-?\d+$/;
    44194517
     
    45664664
    45674665  # do simple validation first
     4666  $ttl = '' if !$ttl;
     4667  $ttl =~ s/\s*//g;
    45684668  return ('FAIL', "TTL must be numeric") unless $ttl =~ /^-?\d+$/;
    45694669
     
    59246024  # Error check - does the cache dir exist, if we're using one?
    59256025  if ($self->{usecache}) {
    5926     die "Cache directory does not exist\n" if !-e $self->{exportcache};
     6026    die "Cache directory $self->{exportcache} does not exist\n" if !-e $self->{exportcache};
    59276027    die "$self->{exportcache} is not a directory\n" if !-d $self->{exportcache};
    59286028    die "$self->{exportcache} must be both readable and writable\n"
     
    61386238      #  - the cache file does not exist
    61396239      #  - the cache file is empty
     6240      #  - the zone contains ALIAS pseudorecords, which need to cascade changes from the upstream CNAME farm at every opportunity
     6241      if ( ($dbh->selectrow_array("SELECT count(*) FROM records WHERE domain_id = ? AND type=65300", undef, $domid))[0] ) {
     6242        $changed = 1;  # abuse this flag for zones with ALIAS records
     6243      }
    61406244      if (!$self->{usecache} || $self->{force_refresh} || $changed || !-e $cachefile || -z $cachefile) {
    61416245        if ($self->{usecache}) {
     
    63986502    print $datafile "Z$zone:$primary:$email"."::$refresh:$retry:$expire:$min_ttl:$ttl:$stamp:$loc\n"
    63996503      or die $!;
    6400 
    6401   } elsif ($typemap{$type} eq 'A') {
    6402 
     6504  } # SOA
     6505
     6506  elsif ($typemap{$type} eq 'A') {
    64036507    ($host,$val) = __revswap($host,$val) if $revrec eq 'y';
    64046508    print $datafile "+$host:$val:$ttl:$stamp:$loc\n" or die $!;
    6405 
    6406   } elsif ($typemap{$type} eq 'NS') {
    6407 
     6509  } # A
     6510
     6511  elsif ($typemap{$type} eq 'NS') {
    64086512    if ($revrec eq 'y') {
    64096513      $val = NetAddr::IP->new($val);
     
    64316535      print $datafile "\&$host"."::$val:$ttl:$stamp:$loc\n" or die $!;
    64326536    }
    6433 
    6434   } elsif ($typemap{$type} eq 'AAAA') {
    6435 
     6537  } # NS
     6538
     6539  elsif ($typemap{$type} eq 'AAAA') {
    64366540    ($host,$val) = __revswap($host,$val) if $revrec eq 'y';
    64376541    my $altgrp = 0;
     
    64556559    }
    64566560    print $datafile "$prefix:$ttl:$stamp:$loc\n" or die $!;
    6457 
    6458   } elsif ($typemap{$type} eq 'MX') {
    6459 
     6561  } # AAAA
     6562
     6563  elsif ($typemap{$type} eq 'MX') {
    64606564    ($host,$val) = __revswap($host,$val) if $revrec eq 'y';
    64616565    print $datafile "\@$host"."::$val:$dist:$ttl:$stamp:$loc\n" or die $!;
    6462 
    6463   } elsif ($typemap{$type} eq 'TXT') {
    6464 
     6566  } # MX
     6567
     6568  elsif ($typemap{$type} eq 'TXT') {
    64656569    ($host,$val) = __revswap($host,$val) if $revrec eq 'y';
    64666570# le sigh.  Some idiot DNS implementations don't seem to like tinydns autosplitting
     
    65066610#:3600
    65076611
    6508   } elsif ($typemap{$type} eq 'CNAME') {
    6509 
     6612  } # TXT
     6613
     6614  elsif ($typemap{$type} eq 'CNAME') {
    65106615    ($host,$val) = __revswap($host,$val) if $revrec eq 'y';
    65116616    print $datafile "C$host:$val:$ttl:$stamp:$loc\n" or die $!;
    6512 
    6513   } elsif ($typemap{$type} eq 'SRV') {
    6514 
     6617  } # CNAME
     6618
     6619  elsif ($typemap{$type} eq 'SRV') {
    65156620    ($host,$val) = __revswap($host,$val) if $revrec eq 'y';
    65166621
     
    65256630    }
    65266631    print $datafile "$prefix\\000:$ttl:$stamp:$loc\n" or die $!;
    6527 
    6528   } elsif ($typemap{$type} eq 'RP') {
    6529 
     6632  } # SRV
     6633
     6634  elsif ($typemap{$type} eq 'RP') {
    65306635    ($host,$val) = __revswap($host,$val) if $revrec eq 'y';
    65316636    # RP consists of two mostly free-form strings.
     
    65426647    }
    65436648    print $datafile "$prefix\\000:$ttl:$stamp:$loc\n" or die $!;
    6544 
    6545   } elsif ($typemap{$type} eq 'PTR') {
    6546 
     6649  } # RP
     6650
     6651  elsif ($typemap{$type} eq 'PTR') {
    65476652    $$recflags{$val}++;
    65486653    if ($revrec eq 'y') {
     
    65736678      print $datafile "^$host:$val:$ttl:$stamp:$loc\n" or die $!;
    65746679    }
    6575 
    6576   } elsif ($type == 65280) { # A+PTR
    6577 
     6680  } # PTR
     6681
     6682  elsif ($type == 65280) { # A+PTR
    65786683    $$recflags{$val}++;
    65796684    print $datafile "=$host:$val:$ttl:$stamp:$loc\n" or die $!;
    6580 
    6581   } elsif ($type == 65281) { # AAAA+PTR
    6582 
     6685  } # A+PTR
     6686
     6687  elsif ($type == 65281) { # AAAA+PTR
    65836688    $$recflags{$val}++;
    65846689    # treat these as two separate records.  since tinydns doesn't have
     
    65936698##fixme: add a config flag to indicate use of the patch from http://www.fefe.de/dns/
    65946699# type 6 is for AAAA+PTR, type 3 is for AAAA
    6595 
    6596   } elsif ($type == 65282) { # PTR template
    6597 
     6700  } # AAAA+PTR
     6701
     6702  elsif ($type == 65282) { # PTR template
    65986703    # only useful for v4 with standard DNS software, since this expands all
    65996704    # IPs in $zone (or possibly $val?) with autogenerated records
     
    66086713      $self->__publish_subnet($val, $recflags, $host, $datafile, $ttl, $stamp, $loc, $zone, 1);
    66096714    }
    6610 
    6611   } elsif ($type == 65283) { # A+PTR template
    6612 
     6715  } # PTR template
     6716
     6717  elsif ($type == 65283) { # A+PTR template
    66136718    $val = NetAddr::IP->new($val);
    66146719    # Just In Case.  An A+PTR should be impossible to add to a v6 revzone via API.
     
    66226727      $self->__publish_subnet($val, $recflags, $host, $datafile, $ttl, $stamp, $loc, $zone, 0);
    66236728    }
    6624 
    6625   } elsif ($type == 65284) { # AAAA+PTR template
     6729  } # A+PTR template
     6730
     6731  elsif ($type == 65284) { # AAAA+PTR template
    66266732    # Stub for completeness.  Could be exported to DNS software that supports
    66276733    # some degree of internal automagic in generic-record-creation
    66286734    # (eg http://search.cpan.org/dist/AllKnowingDNS/ )
    6629 
    6630   } elsif ($type == 65285) { # Delegation
     6735  } # AAAA+PTR template
     6736
     6737  elsif ($type == 65285) { # Delegation
    66316738    # This is intended for reverse zones, but may prove useful in forward zones.
    66326739
     
    66536760      }
    66546761    }
     6762  } # Delegation
     6763
     6764  elsif ($type == 65300) { # ALIAS
     6765    # Implemented as a unique record in parallel with many other
     6766    # management tools, for clarity VS formal behviour around CNAME
     6767    # Mainly for "root CNAME" or "apex alias";  limited value for any
     6768    # other use case since CNAME can generally be used elsewhere.
     6769
     6770    # .arpa zones don't need this hack.  shouldn't be allowed into
     6771    # the DB in the first place, but Just In Case...
     6772    return if $revrec eq 'y';
     6773
     6774    my ($iplist) = $self->{dbh}->selectrow_array("SELECT auxdata FROM records WHERE record_id = ?", undef, $recid);
     6775    $iplist = '' if !$iplist;
     6776
     6777    # shared target-name-to-IP converter
     6778    my $liveips = $self->_grab_65300($recid, $val);
     6779    # only update the cache if the live lookup actually returned data
     6780    if ($liveips && ($iplist ne $liveips)) {
     6781      $self->{dbh}->do("UPDATE records SET auxdata = ? WHERE record_id = ?", undef, $liveips, $recid);
     6782      $iplist = $liveips;
     6783    }
     6784
     6785    # slice the TTL we'll actually publish off the front
     6786    my @asubs = split ':', $iplist;
     6787    my $attl = shift @asubs;
     6788
     6789    # output a plain old A record for each IP the target name really points to.
     6790    # in the event that, for whatever reason, no A records are available for $val, nothing will be output.
     6791    foreach my $subip (@asubs) {
     6792      print $datafile "+$host:$subip:$attl:$stamp:$loc\n" or die $!;
     6793    }
     6794  } # ALIAS
    66556795
    66566796##
     
    66586798##
    66596799
    6660   } elsif ($type == 44) { # SSHFP
    6661 
     6800  elsif ($type == 44) { # SSHFP
    66626801    ($host,$val) = __revswap($host,$val) if $revrec eq 'y';
    66636802
     
    66716810    print $datafile "$rec:$ttl:$stamp:$loc\n" or die $!;
    66726811
    6673   } else {
     6812  } # SSHFP
     6813
     6814  else {
    66746815    # raw record.  we don't know what's in here, so we ASS-U-ME the user has
    66756816    # put it in correctly, since either the user is messing directly with the
     
    66826823    #print $datafile ":$host:$type:$val:$ttl:$stamp:$loc\n";
    66836824
    6684   } # record type if-else
     6825  } # "other"
    66856826
    66866827} # end _printrec_tiny()
  • branches/stable/Makefile

    r756 r1032  
    4646        INSTALL COPYING TODO Makefile dnsadmin.spec \
    4747        \
    48         dns.sql dns-1.0-1.2.sql dns-1.2.3-1.2.4.sql dns-upd-1.2.6.sql dns-upd-1.4.0.sql \
     48        dns.sql dns-1.0-1.2.sql dns-1.2.3-1.2.4.sql dns-upd-1.2.6.sql dns-upd-1.4.0.sql dns-upd-1.4.1.sql \
    4949        \
    5050        $(SCRIPTS) $(MODULES) \
     
    6868
    6969SCRIPTS = \
    70         compact-recs.pl dns.cgi dns-rpc.cgi dns-rpc.fcgi export.pl mergerecs textrecs.cgi tiny-import.pl \
    71         vega-import.pl
     70        bulk-add-domain compact-recs.pl dns.cgi dns-rpc.cgi dns-rpc.fcgi export.pl mergerecs textrecs.cgi \
     71        tiny-import.pl vega-import.pl
    7272
    7373MODULES = DNSDB.pm
  • branches/stable/compact-recs.pl

    r756 r1032  
    5353# get userdata for log
    5454($dnsdb->{logusername}, undef, undef, undef, undef, undef, $dnsdb->{logfullname}) = getpwuid($<);
     55$dnsdb->{logfullname} =~ s/,//g;
    5556$dnsdb->{loguserid} = 0;        # not worth setting up a pseudouser the way the RPC system does
    5657$dnsdb->{logusername} = $dnsdb->{logusername}."/compact-recs.pl";
  • branches/stable/dns-rpc.cgi

    r756 r1032  
    134134exit;
    135135
     136
     137=head1 dns-rpc.cgi
     138
     139The RPC API for DeepNet DNS Administrator.
     140
     141=head2 Common required arguments
     142
     143A few arguments for primitive authorization are required on all calls.
     144
     145=over 4
     146
     147=item rpcuser
     148
     149A string identifying the remote user in some way.  Used to generate a hidden local user for logging.
     150
     151=item rpcsystem
     152
     153A string identifying the remote system doing the RPC call.  This is checked against a list of IPs allowed to
     154claim this system identifier.
     155
     156=back
     157
     158=cut
     159
    136160##
    137161## Subs below here
     
    214238## Shims for DNSDB core subs
    215239##
     240
     241
     242=head2 Exposed RPC subs
     243
     244=cut
     245#over 4
     246
    216247
    217248#sub connectDB {
     
    225256#sub _log {
    226257
     258
     259=head3 addDomain
     260
     261Add a domain.  Note that while this should accept a formal .arpa reverse zone name, doing so will disrupt
     262several features that ease management of bulk reverse records.  Use C<addRDNS> to add reverse zones.
     263
     264=over 4
     265
     266=item domain
     267
     268The domain to add.
     269
     270=item group
     271
     272The group ID to add the domain to.  Group ID 1 is expected to exist;  otherwise a list of groups should be
     273retrieved with C<getGroupList> for selection.  The group defines which template records will be used to create
     274the initial record set in the domain.
     275
     276=item state
     277
     278Active/inactive flag.  Send C<active>, C<on>, or C<1> for domains that should be published;  C<inactive>,
     279C<off>, or C<0> for domains that should be added but not currently published.
     280
     281=item defloc
     282
     283Optional argument for the default location/view the domain's records should be published in.  Leave blank, or a
     284list of locations can be retrieved with C<getLocList> or C<getLocDropdown> for selection.
     285
     286=back
     287
     288Returns the ID of the domain.
     289
     290=cut
    227291sub addDomain {
    228292  my %args = @_;
     
    235299}
    236300
     301
     302=head3 delZone
     303
     304Delete a domain or reverse zone
     305
     306=over 4
     307
     308=item zone
     309
     310The domain name, domain ID, .arpa zone name, or logical CIDR range to remove
     311
     312=item revrec
     313
     314Flag to indicate whether to go looking for a domain or a reverse zone to delete.  Accepts "y" or "n".
     315
     316=back
     317
     318Returns an informational confirmation message on success.
     319
     320=cut
    237321sub delZone {
    238322  my %args = @_;
     
    258342} # delZone()
    259343
     344
    260345#sub domainName {}
    261346#sub revName {}
    262347
     348
     349=head3 domainID
     350
     351Retrieve the ID for a domain
     352
     353=over 4
     354
     355=item domain
     356
     357The domain name to find the ID for
     358
     359=back
     360
     361Returns the integer ID of the domain if found.
     362
     363=cut
    263364sub domainID {
    264365  my %args = @_;
     
    273374#sub revID {}
    274375
     376
     377=head3 addRDNS
     378
     379Add a reverse zone
     380
     381=over 4
     382
     383=item revzone
     384
     385The logical reverse zone to be added.  Can be specified as either formal .arpa notation or a valid CIDR
     386netblock.  Using a CIDR netblock allows logical aggregation of related records even if the CIDR range covers
     387multiple formal .arpa zone boundaries.  For example, the logical zone 192.168.4.0/22 covers
     3884.168.192.in-addr.arpa, 5.168.192.in-addr.arpa, 6.168.192.in-addr.arpa, and 7.168.192.in-addr.arpa, and will be
     389correctly published as such.
     390
     391=item revpatt
     392
     393A string representing the pattern to use for an initial template record.
     394
     395=item group
     396
     397The group ID to add the zone to.
     398
     399=item state
     400
     401Active/inactive flag.  Send C<active>, C<on>, or 1 for zones that should be published;  C<inactive>,
     402C<off>, or C<0> for zones that should be added but not currently published.
     403
     404=item defloc
     405
     406Optional argument for the default location/view the zone's records should be published in.  Leave blank, or a
     407list of locations can be retrieved with C<getLocList> or C<getLocDropdown> for selection.
     408
     409=back
     410
     411Returns the zone ID on success.
     412
     413=cut
    275414sub addRDNS {
    276415  my %args = @_;
     
    287426#sub getZoneLocation {}
    288427
     428
     429=head3 addGroup
     430
     431Add a group
     432
     433=over 4
     434
     435=item groupname
     436
     437The name for the new group
     438
     439=item parent_id
     440
     441The ID of the group to put the new group in
     442
     443=back
     444
     445Note that the RPC API does not currently expose the full DNSDB::addGroup interface;  the permissions hashref is
     446substituted with a reasonable standard default user permissions allowing users to add/edit/delete zones and
     447records.
     448
     449Returns literal 'OK' on success.
     450
     451=cut
    289452sub addGroup {
    290453  my %args = @_;
     
    305468}
    306469
     470
     471=head3 delGroup
     472
     473Delete a group.  The group must be empty of users, zones, or subgroups.
     474
     475=over 4
     476
     477=item group
     478
     479The group name or group ID to delete
     480
     481=back
     482
     483Returns an informational message on success.
     484
     485=cut
    307486sub delGroup {
    308487  my %args = @_;
     
    330509#sub groupID {}
    331510
     511
     512=head3 addUser
     513
     514Add a user.
     515
     516=over 4
     517
     518=item username
     519
     520The username to add
     521
     522=item group
     523
     524The group ID to add the user in.  Users in subgroups only have access to data in that group and its subgroups.
     525
     526=item pass
     527
     528The password for the account
     529
     530=item state
     531
     532Flag to indicate if the account should be active on creation or set to inactive.  Accepts the same values as
     533domains and reverse zones - C<active>, C<on>, or C<1> for an active user, C<inactive>, C<off>, or C<0> for an
     534inactive one.
     535
     536=back
     537
     538B<Optional arguments>
     539
     540=over 4
     541
     542=item type
     543
     544Type of user account to add.  Current types are C<u> (normal user) and C<s> (superuser).  Defaults to C<u>.
     545
     546=item permstring
     547
     548A string encoding the permissions a normal user receives.  By default this is set to C<i> indicating
     549permissions are inherited from the group.
     550
     551C<c:[digits]> clones permissions from user with id [digits]
     552
     553C<C:,[string]> sets the exact permissions indicated by [string].  It is currently up to the caller to ensure
     554that related/cascading permissions are set correctly;  see C<%DNSDB::permchains> for the current set.  Current
     555valid permission identifiers match
     556C<(group|user|domain|record|location|self)_(edit|create|delete|locchg|view)>, however see C<@DNSDB::permtypes>
     557for the exact list.
     558
     559The comma after the colon is not a typo.
     560
     561=item fname
     562
     563First name
     564
     565=item lname
     566
     567Last name
     568
     569=item phone
     570
     571Phone number
     572
     573=back
     574
     575Note that some user properties originate in DNS Administrator's inspiration, VegaDNS.
     576
     577=cut
    332578sub addUser {
    333579  my %args = @_;
     
    355601#sub checkUser {}
    356602
     603
     604=head3 updateUser
     605
     606Update a user's username, password, state, type, first/last names, and/or phone number
     607
     608Most arguments are the same as for addUser.
     609
     610=over 4
     611
     612=item uid
     613
     614The ID of the user record
     615
     616=item username
     617
     618The username
     619
     620=item group
     621
     622The group ID the user is in (for logging).  Users cannot currently be moved to a different group.
     623
     624=item pass
     625
     626An updated password, if provided.  Leave blank to keep the existing password.
     627
     628=item state
     629
     630The account state (active/inactive).  Takes the same values as addUser.
     631
     632=item type
     633
     634The account type (user [C<u>] or superuser [C<S>])
     635
     636=item fname
     637
     638First name (optional)
     639
     640=item lname
     641
     642Last name (optional)
     643
     644=item phone
     645
     646Phone contact (optional)
     647
     648=back
     649
     650=cut
    357651sub updateUser {
    358652  my %args = @_;
     
    376670}
    377671
     672
     673=head3 delUser
     674
     675Delete a user
     676
     677=over 4
     678
     679=item uid
     680
     681The ID of the user record to delete
     682
     683=back
     684
     685=cut
    378686sub delUser {
    379687  my %args = @_;
     
    398706#sub getLocList {}
    399707
     708
     709=head3 getLocDropdown
     710
     711Retrieve a list of locations for display in a dropdown.
     712
     713=over 4
     714
     715=item group
     716
     717The group ID to select locations from
     718
     719=item defloc
     720
     721Optional argument to flag the "default" location in the list
     722
     723=back
     724
     725Returns an arrayref to a list of hashrefs with elements C<locname>, C<loc> and C<selected>.  C<selected> will
     726be 0 for all entries unless the C<loc> value matches C<defloc>, where it will be set to 1.
     727
     728=cut
    400729sub getLocDropdown {
    401730  my %args = @_;
     
    408737}
    409738
     739
     740=head3 getSOA
     741
     742Retrieve the SOA record for a zone
     743
     744=over 4
     745
     746=item defrec
     747
     748Default/live records flag.  Accepts C<y> and C<n>.
     749
     750=item revrec
     751
     752Forward/reverse flag.  Accepts C<y> and C<n>.
     753
     754=item id
     755
     756The zone ID (if C<defrec> is C<y>) or the group ID (if C<defrec> is C<n>) to retrieve the SOA from
     757
     758=back
     759
     760=cut
    410761sub getSOA {
    411762  my %args = @_;
     
    428779#sub updateSOA {}
    429780
     781
     782=head3 getRecLine
     783
     784Retrieve all fields for a specific record
     785
     786=over 4
     787
     788=item defrec
     789
     790Default/live records flag.  Accepts C<y> and C<n>.
     791
     792=item revrec
     793
     794Forward/reverse flag.  Accepts C<y> and C<n>.  Mildly abused to determine whether to include C<distance>,
     795C<weight>, and C<port> fields, since MX and SRV records don't make much sense in reverse zones.
     796
     797=item id
     798
     799The record ID (if C<defrec> is C<y>) or default record ID (if C<defrec> is C<n>) to retrieve
     800
     801=back
     802
     803=cut
    430804sub getRecLine {
    431805  my %args = @_;
     
    442816}
    443817
     818
     819=head3 getRecList
     820
     821Retrieve a list of records for a zone.
     822
     823=over 4
     824
     825=item id
     826
     827The zone ID (if C<defrec> is C<n>) or group ID (if C<defrec> is C<y>) to retrieve records from
     828
     829=item defrec
     830
     831Default/live records flag.  Accepts C<y> and C<n>.
     832
     833=item revrec
     834
     835Forward/reverse flag.  Accepts C<y> and C<n>.
     836
     837=back
     838
     839Optional arguments
     840
     841=over 4
     842
     843=item offset
     844
     845Offset from the start of the raw record list.  Mainly for pagination.  Defaults 0.
     846
     847=item nrecs
     848
     849Number of records to return.  Defaults to C<$DNSDB::perpage>
     850
     851=item sortby
     852
     853Sort field.  Defaults to host for domain zones, val for reverse zones.  Supports multifield sorts;  pass the
     854fields in order separated by commas.
     855
     856=item sortorder
     857
     858SQL sort order.  Defaults to C<ASC>.
     859
     860=item filter
     861
     862Return only records whose host or val fields match this string.
     863
     864=item type, distance, weight, port, ttl, description
     865
     866If these arguments are present, use the value to filter on that field.
     867
     868=back
     869
     870=cut
    444871sub getRecList {
    445872  my %args = @_;
     
    486913}
    487914
     915
     916=head3 getRecCount
     917
     918Return count of non-SOA records in zone (or default records in a group).
     919
     920Uses the same arguments as getRecList, except for C<offset>, C<nrecs>, C<sortby>, and C<sortorder>.
     921
     922=cut
    488923sub getRecCount {
    489924  my %args = @_;
     
    525960} # getRecCount()
    526961
     962
     963=head3 addRec
     964
     965Add a record to a zone or add a default record to a group.
     966
     967Note that the name, type, and address arguments may be modified for normalization or to match available zones
     968for A+PTR and related metatypes.
     969
     970=over 4
     971
     972=item defrec
     973
     974Default/live records flag. Accepts C<y> and C<n>.
     975
     976=item revrec
     977
     978Forward/reverse flag. Accepts C<y> and C<n>.
     979
     980=item parent_id
     981
     982The ID of the parent zone or group.
     983
     984=item name
     985
     986The fully-qualified hostname for the record.  Trailing periods will automatically be stripped for storage, and
     987added on export as needed.  Note that for reverse zone records, this is the nominal record target.
     988
     989=item type
     990
     991The record type.  Both the nominal text identifiers and the bare integer types are accepted.
     992
     993=item address
     994
     995The record data or target.  Note that for reverse zones this is the nominal .arpa name for the record.
     996
     997=item ttl
     998
     999The record TTL.
     1000
     1001=item location
     1002
     1003The location identifier for the record.
     1004
     1005=item expires
     1006
     1007Flag to indicate the record will either expire at a certain time or become active at a certain time.
     1008
     1009=item stamp
     1010
     1011The timestamp a record will expire or become active at.  Note that depending on the DNS system in use this may
     1012not result in an exact expiry or activation time.
     1013
     1014=back
     1015
     1016B<Optional arguments>
     1017
     1018=over 4
     1019
     1020=item distance
     1021
     1022MX and SRV distance or priority
     1023
     1024=item weight
     1025
     1026SRV weight
     1027
     1028=item port
     1029
     1030SRV port number
     1031
     1032=back
     1033
     1034=cut
    5271035# The core sub uses references for some arguments to allow limited modification for
    5281036# normalization or type+zone matching/mapping/availability.
     
    5561064} # rpc_addRec
    5571065
     1066
     1067=head3 updateRec
     1068
     1069Update a record.
     1070
     1071Takes the same arguments as C<addRec> except that C<id> is the record to update, not the primary parent zone ID.
     1072
     1073If C<stamp> is blank or undefined, any timestamp will be removed.
     1074
     1075=cut
    5581076sub rpc_updateRec {
    5591077  my %args = @_;
     
    5901108
    5911109
     1110
     1111=head3 addOrUpdateRevRec
     1112
     1113Add or update a reverse DNS record (usually A+PTR template) as appropriate based on a passed CIDR address and
     1114hostname pattern.  The record will automatically be downconverted to a PTR template if the forward zone
     1115referenced by the hostname pattern is not managed in this DNSAdmin instance.
     1116
     1117=over 4
     1118
     1119=item cidr
     1120
     1121The CIDR address or IP for the record
     1122
     1123=item name
     1124
     1125The hostname pattern for template records, or the hostname for single IP records
     1126
     1127=back
     1128
     1129=cut
    5921130# Takes a passed CIDR block and DNS pattern;  adds a new record or updates the record(s) affected
    5931131sub addOrUpdateRevRec {
     
    6851223} # done addOrUpdateRevRec()
    6861224
     1225
     1226=head3 updateRevSet
     1227
     1228Update reverse DNS entries for a set of IP addresses all at once.  Calls addOrUpdateRevRec internally.
     1229
     1230=over 4
     1231
     1232=item host_[ip.add.re.ss] (Multiple entries)
     1233
     1234One or more identifiers for one or more IP addresses to update reverse DNS on.  The value of the argument is the
     1235hostname to set on that IP.
     1236
     1237=back
     1238
     1239=cut
    6871240# Update rDNS on a whole batch of IP addresses.  Presented as a separate sub via RPC
    6881241# since RPC calls can be s...l...o...w....
     
    7151268} # done updateRevSet()
    7161269
     1270
     1271=head3 splitTemplate
     1272
     1273Split a PTR template record into multiple records.
     1274
     1275=over 4
     1276
     1277=item cidr
     1278
     1279The CIDR address for the record to split
     1280
     1281=item newmask
     1282
     1283The new masklength for the new records. 
     1284
     1285=back
     1286
     1287=cut
    7171288# Split a template record as per a passed CIDR.
    7181289# Requires the CIDR and the new mask length
     
    7821353} # done splitTemplate()
    7831354
     1355
     1356=head3 resizeTemplate
     1357
     1358Resize a template record based on a pair of passed CIDR addresses.
     1359
     1360=over 4
     1361
     1362=item oldcidr
     1363
     1364The old CIDR to look for in the existing records
     1365
     1366=item newcidr
     1367
     1368The new CIDR
     1369
     1370=back
     1371
     1372=cut
    7841373# Resize a template according to an old/new CIDR pair
    7851374# Takes the old cidr in $args{oldcidr} and the new in $args{newcidr}
     
    8501439} # done resizeTemplate()
    8511440
     1441
     1442=head3 templatesToRecords
     1443
     1444Convert one or more template records to individual IP records, expanding the template as would be done on
     1445export.
     1446
     1447=over 4
     1448
     1449=item templates
     1450
     1451A list/array of CIDR addresses to search for for conversion.
     1452
     1453=back
     1454
     1455=cut
    8521456# Convert one or more template records to a set of individual IP records.  Expands the template.
    8531457# Handle the case of nested templates, although the primary caller (IPDB) should not be
     
    9281532} # done templatesToRecords()
    9291533
     1534
     1535=head3 delRec
     1536
     1537Delete a record.
     1538
     1539=over 4
     1540
     1541=item defrec
     1542
     1543Default/live records flag. Accepts C<y> and C<n>.
     1544
     1545=item revrec
     1546
     1547Forward/reverse flag. Accepts C<y> and C<n>.  Used for logging to pick the "primary" zone of the record.
     1548
     1549=item id
     1550
     1551The record to delete.
     1552
     1553=back
     1554
     1555=cut
    9301556sub delRec {
    9311557  my %args = @_;
     
    9411567}
    9421568
     1569
     1570=head3 delByCIDR
     1571
     1572Delete a record by CIDR address.
     1573
     1574=over 4
     1575
     1576=item cidr
     1577
     1578The CIDR address for the record or record group to delete.
     1579
     1580=back
     1581
     1582B<Optional arguments>
     1583
     1584=over 4
     1585
     1586=item delforward (default 0/off)
     1587
     1588Delete the matching A record on A+PTR and similar metarecords.
     1589
     1590=item delsubs (default 0/off)
     1591
     1592Delete all records within C<cidr>.  Send C<y> if desired, otherwise it reverts to default even for other
     1593otherwise "true" values.
     1594
     1595=item parpatt
     1596
     1597Template pattern to add a replacement record if the delete removes all records from a reverse zone.
     1598
     1599=back
     1600
     1601=cut
    9431602sub delByCIDR {
    9441603  my %args = @_;
     
    10591718} # end delByCIDR()
    10601719
     1720
     1721=head3 delRevSet
     1722
     1723Delete a set of single-IP records similar to updateRevSet
     1724
     1725=over 4
     1726
     1727=item cidrlist
     1728
     1729Simple comma-separated string containing the IP addresses that should be removed.
     1730
     1731=back
     1732
     1733=cut
    10611734# Batch-delete a set of reverse entries similar to updateRevSet
    10621735sub delRevSet {
     
    10771750#sub getLogEntries {}
    10781751
     1752
     1753=head3 getRevPattern
     1754
     1755Get the pattern that would be applied to IPs in a CIDR range that do not have narrower patterns or separate
     1756individual reverse entries.
     1757
     1758=over 4
     1759
     1760=item cidr
     1761
     1762The CIDR address range to find a pattern for.
     1763
     1764=item group
     1765
     1766The group to restrict reverse zone matches to.
     1767
     1768=item location
     1769
     1770The DNS view/location to restrict record matches to.
     1771
     1772=back
     1773
     1774=cut
    10791775sub getRevPattern {
    10801776  my %args = @_;
     
    10851781}
    10861782
     1783
     1784=head3 getRevSet
     1785
     1786Retrieve the set of per-IP reverse records within a CIDR range, if any.
     1787
     1788Returns a list of hashes.
     1789
     1790=over 4
     1791
     1792=item cidr
     1793
     1794The CIDR address range to find a pattern for.
     1795
     1796=item group
     1797
     1798The group to restrict reverse zone matches to.
     1799
     1800=item location
     1801
     1802The DNS view/location to restrict record matches to.
     1803
     1804=back
     1805
     1806=cut
    10871807sub getRevSet {
    10881808  my %args = @_;
     
    10931813}
    10941814
     1815
     1816=head3 getTypelist
     1817
     1818Retrieve a list of record types suitable for a dropdown form field.  Returns only record types currently
     1819supported by DNSAdmin.
     1820
     1821Returns a list of hashes.
     1822
     1823=over 4
     1824
     1825=item recgroup
     1826
     1827Flag argument to determine which record types will be returned.  Values not listed fall back to C<f>.
     1828
     1829=over 4
     1830
     1831=item r
     1832
     1833Logical records commonly found in reverse zones (includes A+PTR and related metatypes)
     1834
     1835=item l
     1836
     1837Records that can actually be looked up in the DNS.
     1838
     1839=item f
     1840
     1841Logical records commonly found in forward zones (includes A+PTR and similar metatypes that include a forward
     1842record component).  Append C<o> to exclude the metatypes.
     1843
     1844=back
     1845
     1846=item selected
     1847
     1848Optional flag argument if a particular type should be "selected".  Sets the C<tselect> key on that entry.  Note
     1849that the passed type will always be present in the returned list, even if it wouldn't be otherwise - eg, PTR
     1850template if C<recgroup> is set to C<fo>, or SRV if C<recgroup> is set to C<r>.
     1851
     1852=back
     1853
     1854=cut
    10951855sub getTypelist {
    10961856  my %args = @_;
     
    11021862}
    11031863
     1864
     1865=head3 getTypemap
     1866
     1867Return DNS record type hash mapping DNS integer type values to text names
     1868
     1869=cut
    11041870sub getTypemap {
    11051871  my %args = @_;
     
    11081874}
    11091875
     1876
     1877=head3 getReverse_typemap
     1878
     1879Return DNS record type hash mapping text names to integer type values
     1880
     1881=cut
    11101882sub getReverse_typemap {
    11111883  my %args = @_;
     
    11171889#sub isParent {}
    11181890
     1891
     1892=head3 zoneStatus
     1893
     1894Get or set the status of a zone.  Returns the status of the zone.
     1895
     1896=over 4
     1897
     1898=item zoneid
     1899
     1900The ID of the zone to get or set status on
     1901
     1902=back
     1903
     1904B<Optional arguments>
     1905
     1906=over 4
     1907
     1908=item reverse
     1909
     1910Set to C<y> if you want to get/set the status for a reverse zone
     1911
     1912=item status
     1913
     1914Pass C<0> or C<domoff> to set the zone to inactive;  C<1> or C<domon> to set it to active
     1915
     1916=back
     1917
     1918=cut
    11191919sub zoneStatus {
    11201920  my %args = @_;
     
    11281928  my $status = $dnsdb->zoneStatus(@arglist);
    11291929}
     1930
     1931
     1932=head3 getZonesByCIDR
     1933
     1934Get a list of reverse zones within a passed CIDR block.  Returns a list of hashes.
     1935
     1936=over 4
     1937
     1938=item cidr
     1939
     1940The CIDR range to look for reverse zones in
     1941
     1942=back
     1943
     1944=cut
    11301945
    11311946# Get a list of hashes referencing the reverse zone(s) for a passed CIDR block
     
    11501965  return \@methods;
    11511966}
     1967
     1968
     1969# and we're done.  close the POD
     1970
     1971#back
  • branches/stable/dns.cgi

    r756 r1032  
    17341734    my @results;
    17351735    foreach my $domain (@domlist) {
     1736##fixme: Net::DNS has made changes somewhere between 0.66something (~~ Debian wheezy) and
     1737# 0.81 (~~ Debian jessie) that cause taint failures when providing a hostname as a nameserver
     1738# for AXFR.  A proper fix may boil down to "split AXFR into its own script".  Feh.
     1739# For now, we'll just convert the requested AXFR host to an IP, and pass that down the chain instead.
     1740      my $nsip = gethostbyname($webvar{ifrom});
     1741      use Socket;
     1742      $nsip = inet_ntoa($nsip);
     1743      # strangely enough we don't seem to need to detaint:
     1744      #($nsip) = ($nsip =~ /^([a-fA-F0-9:.]+)$/);
    17361745      my %row;
    1737       my ($code,$msg) = $dnsdb->importAXFR($webvar{ifrom}, $domain, $webvar{group},
     1746      my ($code,$msg) = $dnsdb->importAXFR($nsip, $domain, $webvar{group},
    17381747        status => $webvar{domactive}, rwsoa => $webvar{rwsoa}, rwns => $webvar{rwns},
    17391748        newttl => ($webvar{forcettl} ? $webvar{newttl} : 0),
     
    19681977# fill in general URL-to-self
    19691978  $page->param(script_self => "$ENV{SCRIPT_NAME}?");
     1979# fill in the generalized path-to-instance
     1980  $page->param(webpath => ($ENV{SCRIPT_NAME} =~ m|(/.+)/[^/]+$|)[0]);
    19701981}
    19711982
     
    21532164
    21542165  foreach my $rec (@$foo2) {
    2155     $rec->{type} = $typemap{$rec->{type}};
     2166    if ($typemap{$rec->{type}}) {
     2167      $rec->{type} = $typemap{$rec->{type}};
     2168    } else {
     2169      $rec->{type} = "TYPE$rec->{type}";
     2170    }
    21562171    $rec->{fwdzone} = $rev eq 'n';
    21572172    $rec->{ttl} = '(auto)' if $rec->{ttl} == -1;
  • branches/stable/dns.sql

    r756 r1032  
    191191    stamp TIMESTAMP WITH TIME ZONE DEFAULT 'epoch' NOT NULL,
    192192    expires boolean DEFAULT 'n' NOT NULL,
    193     stampactive boolean DEFAULT 'n' NOT NULL
     193    stampactive boolean DEFAULT 'n' NOT NULL,
     194    auxdata text
    194195);
    195196CREATE INDEX rec_domain_index ON records USING btree (domain_id);
     
    206207
    207208-- Types are required.  NB:  these are vaguely read-only too
    208 -- data from http://www.iana.org/assignments/dns-parameters
     209-- data from https://www.iana.org/assignments/dns-parameters
    209210COPY rectypes (val, name, stdflag, listorder, alphaorder) FROM stdin;
    2102111       A       1       1       1
     
    25926050      NSEC3   5       255     41
    26026151      NSEC3PARAM      5       255     42
     26252      TLSA    5       255     255
     26353      SMIMEA  5       255     255
    26126455      HIP     5       255     19
     26556      NINFO   5       255     255
     26657      RKEY    5       255     255
     26758      TALINK  5       255     255
     26859      CDS     5       255     255
     26960      CDNSKEY 5       255     255
     27061      OPENPGPKEY      5       255     255
     27162      CSYNC   5       255     255
    26227299      SPF     5       255     54
    263273100     UINFO   5       255     62
     
    265275102     GID     5       255     16
    266276103     UNSPEC  5       255     63
     277104     NID     5       255     255
     278105     L32     5       255     255
     279106     L64     5       255     255
     280107     LP      5       255     255
     281108     EUI48   5       255     255
     282109     EUI64   5       255     255
    267283249     TKEY    5       255     58
    268284250     TSIG    5       255     59
     
    271287253     MAILB   5       255     27
    272288254     MAILA   5       255     26
     289255     *       5       255     255
     290256     URI     5       255     255
     291257     CAA     5       255     255
     292258     AVC     5       255     255
    27329332768   TA      5       255     57
    27429432769   DLV     5       255     11
     
    28330365284   AAAA+PTR template       2       8       2
    28430465285   Delegation      2       9       2
     30565300   ALIAS   2       16      255
    285306\.
    286307
  • branches/stable/mergerecs

    r756 r1032  
    6363# get userdata for log
    6464($dnsdb->{logusername}, undef, undef, undef, undef, undef, $dnsdb->{logfullname}) = getpwuid($<);
     65$dnsdb->{logfullname} =~ s/,//g;
    6566$dnsdb->{loguserid} = 0;        # not worth setting up a pseudouser the way the RPC system does
    6667$dnsdb->{logusername} = $dnsdb->{logusername}."/mergerecs";
  • branches/stable/templates/menu.tmpl

    r756 r1032  
     1<TMPL_IF 0><TMPL_VAR NAME=webpath></TMPL_IF>
    12<td class="menu">
    23<TMPL_VAR NAME=username> logged in<br />
  • branches/stable/tiny-import.pl

    r756 r1032  
    118118# collect some things for logging
    119119($dnsdb->{logusername}, undef, undef, undef, undef, undef, $dnsdb->{logfullname}) = getpwuid($<);
     120$dnsdb->{logfullname} =~ s/,//g;
    120121$dnsdb->{loguserid} = 0;        # not worth setting up a pseudouser the way the RPC system does
    121122$dnsdb->{logusername} = $dnsdb->{logusername}."/tiny-import.pl";
Note: See TracChangeset for help on using the changeset viewer.