- Timestamp:
- 04/21/22 17:50:04 (3 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/DNSDB.pm
r834 r838 561 561 562 562 } # 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 573 sub _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 563 605 564 606 … … 4466 4508 # Filtering on host/val (mainly normal record list) 4467 4509 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); 4492 4511 } 4493 4512 … … 4563 4582 # Filtering on host/val (mainly normal record list) 4564 4583 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); 4589 4585 } 4590 4586 … … 5195 5191 JOIN rectypes t ON r.type = t.val 5196 5192 LEFT JOIN locations l ON r.location = l.location 5197 WHERE r.type <> 6 AND (r.host ~* ? OR r.val ~* ?) 5198 ); 5193 WHERE r.type <> 6); 5199 5194 5200 5195 … … 5208 5203 5209 5204 my $sql = "SELECT count(*)".$recsearchsqlbase; 5205 5206 my @bindargs; 5207 _recfilter(filter => $args{searchfor}, sql => \$sql, bindvars => \@bindargs); 5210 5208 5211 5209 # Limit scope based on group … … 5223 5221 } 5224 5222 5225 my $count = $dbh->selectrow_array($sql, undef, $args{searchfor}, $args{searchfor});5223 my $count = $dbh->selectrow_array($sql, undef, @bindargs); 5226 5224 $errstr = $dbh->errstr if !$count; 5227 5225 return $count; … … 5245 5243 r.host, t.name AS rectype, r.val, l.description AS location, r.record_id). 5246 5244 $recsearchsqlbase; 5245 5246 my @bindargs; 5247 _recfilter(filter => $args{searchfor}, sql => \$sql, bindvars => \@bindargs); 5247 5248 5248 5249 # Limit scope based on group … … 5282 5283 5283 5284 ##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) 5285 5286 or warn $dbh->errstr; 5286 5287 return $ret;
Note:
See TracChangeset
for help on using the changeset viewer.