Changeset 838


Ignore:
Timestamp:
04/21/22 17:50:04 (2 years ago)
Author:
Kris Deugau
Message:

/trunk

Remove some copy-pasta by factoring the Postgres-CIDR-operator voodoo out
of getRecList() and getRecCount() so it can also be used for recSearchCount()
and recSearch()

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/DNSDB.pm

    r834 r838  
    561561
    562562} # end _updateserial()
     563
     564
     565## DNSDB::_recfilter()
     566# Utility sub to construct an SQL fragment for host/value filtering based on a filter argument
     567# Deconstructs the argument to apply Postgres CIDR operators or Postgres string-matching operators as appropriate
     568# Used by recSearchCount(), recSearch(), getRecList(), and getRecCount()
     569# Takes a hash of:
     570#   filter - string to create SQL fragment from
     571#   sql - reference to SQL string.  SQL fragment will be appended to this string
     572#   bindvars - reference to list of DBI bind variable scalars to be fed to DBI on execute
     573sub _recfilter {
     574  my %args = @_;
     575
     576  # flag for "was this an IPish filter argument?", since we want to fall through
     577  # to the second top-level if() if *any* of the ones in the first block fail
     578  my $ipfilt = 0;
     579
     580  if ($args{filter} =~ /^\s*(<|<=|=|>=|>|<>|<<|<<=|>>|>>=)\s*([\da-fA-F].+)\s*$/) {
     581    # filter argument starts with a Postgres CIDR operator, followed by something that could be a CIDR value
     582    my $filt_op = $1;
     583    my $filt_val = $2;
     584    # do we have an IP-ish value?
     585    if ($filt_val =~ m,^(?:[\d.]+|[0-9a-f]+)(?:/\d+)?$,) {
     586      # now make sure
     587      my $tmp = new NetAddr::IP $filt_val;
     588      if ($tmp) {
     589        ${$args{sql}} .= " AND inetlazy(r.val) $filt_op ?";
     590        push @{$args{bindvars}}, $filt_val;
     591        $ipfilt = 1;
     592      } # really looks like a valid IP/CIDR
     593    } # looks IPish
     594  } # has CIDR operator
     595
     596  if (!$ipfilt) {
     597    # simple text matching, with a bit of mix-n-match to account for .arpa names
     598    ${$args{sql}} .= " AND (r.host ~* ? OR r.val ~* ? OR r.host ~* ? OR r.val ~* ?)";
     599    my $tmp = join('.',reverse(split(/\./,$args{filter})));
     600    push @{$args{bindvars}}, ($args{filter},$args{filter});
     601    push @{$args{bindvars}}, ($tmp, $tmp);
     602  }
     603
     604} # _recfilter
    563605
    564606
     
    44664508  # Filtering on host/val (mainly normal record list)
    44674509  if ($args{filter}) {
    4468     # not much use to end users, but internal callers may want more fine-grained restriction on CIDR ranges
    4469     # we'll only support the value-comparison operators;  bitwise/add/subtract don't make much sense in this context
    4470     my $ipfilt = 0;
    4471     if ($args{filter} =~ /^\s*(<|<=|=|>=|>|<>|<<|<<=|>>|>>=)\s*([\da-fA-F].+)\s*$/) {
    4472       my $filt_op = $1;
    4473       my $filt_val = $2;
    4474       # do we have an IP-ish value?
    4475       if ($filt_val =~ m,^(?:[\d.]+|[0-9a-f]+)(?:/\d+)?$,) {
    4476         # now make sure
    4477         my $tmp = new NetAddr::IP $filt_val;
    4478         if ($tmp) {
    4479           $sql .= " AND inetlazy(r.val) $filt_op ?";
    4480           push @bindvars, $filt_val;
    4481           $ipfilt = 1;
    4482         } # really looks like a valid IP/CIDR
    4483       } # looks IPish
    4484     } # has CIDR operator
    4485     if (!$ipfilt) {
    4486       # simple text matching, with a bit of mix-n-match to account for .arpa names
    4487       $sql .= " AND (r.host ~* ? OR r.val ~* ? OR r.host ~* ? OR r.val ~* ?)";
    4488       my $tmp = join('.',reverse(split(/\./,$args{filter})));
    4489       push @bindvars, ($args{filter},$args{filter});
    4490       push @bindvars, ($tmp, $tmp);
    4491     }
     4510    _recfilter(filter => $args{filter}, sql => \$sql, bindvars => \@bindvars);
    44924511  }
    44934512
     
    45634582  # Filtering on host/val (mainly normal record list)
    45644583  if ($args{filter}) {
    4565     # not much use to end users, but internal callers may want more fine-grained restriction on CIDR ranges
    4566     # we'll only support the value-comparison operators;  bitwise/add/subtract don't make much sense in this context
    4567     my $ipfilt = 0;
    4568     if ($args{filter} =~ /^\s*(<|<=|=|>=|>|<>|<<|<<=|>>|>>=)\s*([\da-fA-F].+)\s*$/) {
    4569       my $filt_op = $1;
    4570       my $filt_val = $2;
    4571       # do we have an IP-ish value?
    4572       if ($filt_val =~ m,^(?:[\d.]+|[0-9a-f]+)(?:/\d+)?$,) {
    4573         # now make sure
    4574         my $tmp = new NetAddr::IP $filt_val;
    4575         if ($tmp) {
    4576           $sql .= " AND inetlazy(r.val) $filt_op ?";
    4577           push @bindvars, $filt_val;
    4578           $ipfilt = 1;
    4579         } # really looks like a valid IP/CIDR
    4580       } # looks IPish
    4581     } # has CIDR operator
    4582     if (!$ipfilt) {
    4583       # simple text matching, with a bit of mix-n-match to account for .arpa names
    4584       $sql .= " AND (r.host ~* ? OR r.val ~* ? OR r.host ~* ? OR r.val ~* ?)";
    4585       my $tmp = join('.',reverse(split(/\./,$args{filter})));
    4586       push @bindvars, ($args{filter},$args{filter});
    4587       push @bindvars, ($tmp, $tmp);
    4588     }
     4584    _recfilter(filter => $args{filter}, sql => \$sql, bindvars => \@bindvars);
    45894585  }
    45904586
     
    51955191JOIN rectypes t ON r.type = t.val
    51965192LEFT JOIN locations l ON r.location = l.location
    5197 WHERE r.type <> 6 AND (r.host ~* ? OR r.val ~* ?)
    5198 );
     5193WHERE r.type <> 6);
    51995194
    52005195
     
    52085203
    52095204  my $sql = "SELECT count(*)".$recsearchsqlbase;
     5205
     5206  my @bindargs;
     5207  _recfilter(filter => $args{searchfor}, sql => \$sql, bindvars => \@bindargs);
    52105208
    52115209  # Limit scope based on group
     
    52235221  }
    52245222
    5225   my $count = $dbh->selectrow_array($sql, undef, $args{searchfor}, $args{searchfor});
     5223  my $count = $dbh->selectrow_array($sql, undef, @bindargs);
    52265224  $errstr = $dbh->errstr if !$count;
    52275225  return $count;
     
    52455243    r.host, t.name AS rectype, r.val, l.description AS location, r.record_id).
    52465244    $recsearchsqlbase;
     5245
     5246  my @bindargs;
     5247  _recfilter(filter => $args{searchfor}, sql => \$sql, bindvars => \@bindargs);
    52475248
    52485249  # Limit scope based on group
     
    52825283
    52835284##fixme: should probably sent the warning somewhere else
    5284   my $ret = $dbh->selectall_arrayref($sql, { Slice => {} }, $args{searchfor}, $args{searchfor})
     5285  my $ret = $dbh->selectall_arrayref($sql, { Slice => {} }, @bindargs)
    52855286    or warn $dbh->errstr;
    52865287  return $ret;
Note: See TracChangeset for help on using the changeset viewer.