diff --git a/check_postgres.pl b/check_postgres.pl index 37d334a..bbb9531 100755 --- a/check_postgres.pl +++ b/check_postgres.pl @@ -6931,7 +6931,7 @@ sub check_query_time { msg('queries'), msg('query-time'), 'query_start', - q{query_start IS NOT NULL AND current_query NOT LIKE '%'}); + q{current_query NOT LIKE '%'}); return; @@ -8703,7 +8703,7 @@ sub check_txn_idle { $SQL3 =~ s/query_start/state_change/g; ## For Pg 10 and above, consider only client backends - ($SQL4 = $SQL3) =~ s/ WHERE / WHERE backend_type = 'client backend' AND /; + ($SQL4 = $SQL3) =~ s/ WHERE / WHERE (backend_type = 'client backend' OR backend_type IS NULL) AND /; my $info = run_command($SQL, { emptyok => 1 , version => [ "<8.3 $SQL2", ">9.6 $SQL4", ">9.1 $SQL3" ] } ); @@ -8737,7 +8737,7 @@ sub check_txn_idle { my $st = defined($r->{state}) ? $r->{state} : ''; ## Return unknown if we cannot see because we are a non-superuser - if ($cq =~ /insufficient/) { + if ($cq eq '') { add_unknown msg('psa-nosuper'); return; } diff --git a/t/02_query_time.t b/t/02_query_time.t index cff23c7..6c43507 100644 --- a/t/02_query_time.t +++ b/t/02_query_time.t @@ -6,7 +6,7 @@ use 5.008; use strict; use warnings; use Data::Dumper; -use Test::More tests => 13; +use Test::More tests => 15; use lib 't','.'; use CP_Testing; @@ -75,4 +75,53 @@ like ($cp->run(q{-w 1 -vv}), qr{$label WARNING:}, $t); $dbh->rollback(); $dbh->disconnect(); +waitpid $child, 0; + +## Tests for non-superuser + +my $cp_nosuper = CP_Testing->new( {default_action => 'query_time', testuser => 'non_superuser', testuser_is_nosuper => 1 } ); + +# Test that a non-superuser shows the unknown data alert. +$child = fork(); +if (0 == $child) { + my $kiddbh = $cp->test_database_handle(); + $cp->database_sleep($kiddbh, 3); + $kiddbh->rollback(); + $kiddbh->disconnect(); + exit; +} + +my $dbh_nosuper = $cp_nosuper->test_database_handle(); +sleep 1; +$t = qq{$S detects non-superuser access}; +like ($cp_nosuper->run(q{-w 1 -vv}), qr{$label UNKNOWN.+superuser}, $t); +$dbh_nosuper->rollback(); +$dbh_nosuper->disconnect(); + +$dbh->disconnect(); + +waitpid $child, 0; + +# Test that a query using the word insufficient doesn't trigger the unknown data alert. + +$child = fork(); +if (0 == $child) { + my $kiddbh = $cp->test_database_handle(); + $kiddbh->do(qq{SELECT pg_sleep(3) AS insufficient}); + $kiddbh->rollback(); + $kiddbh->disconnect(); + exit; +} + +my $dbh = $cp->test_database_handle(); +sleep 1; +$t = qq{$S non-superuser access isn't fooled by the word insufficient}; +like ($cp->run(q{-w 1 -vv}), qr{$label WARNING}, $t); +$dbh->rollback(); +$dbh->disconnect(); + +$dbh->disconnect(); + +waitpid $child, 0; + exit; diff --git a/t/CP_Testing.pm b/t/CP_Testing.pm index e15a4f7..4260349 100644 --- a/t/CP_Testing.pm +++ b/t/CP_Testing.pm @@ -25,6 +25,7 @@ sub new { started => time(), dbdir => $arg->{dbdir} || 'test_database_check_postgres', testuser => $arg->{testuser} || 'check_postgres_testing', + testuser_is_nosuper => $arg->{testuser_is_nosuper}, testuser2 => $arg->{testuser2} || 'powerless_pete', }; if (exists $arg->{default_action}) { @@ -285,7 +286,11 @@ sub _test_database_handle { if ($res !~ /$newuser/) { $COM = qq{psql -d template1 -q -h "$host" -c "CREATE USER $newuser"}; system $COM; - $SQL = qq{UPDATE pg_shadow SET usesuper='t' WHERE usename = '$newuser'}; + if ($self->{testuser_is_nosuper}) { + $SQL = qq{UPDATE pg_shadow SET usesuper='f' WHERE usename = '$newuser'}; + } else { + $SQL = qq{UPDATE pg_shadow SET usesuper='t' WHERE usename = '$newuser'}; + } $COM = qq{psql -d postgres -q -h "$host" -c "$SQL"}; system $COM; } @@ -347,7 +352,11 @@ sub _test_database_handle { delete $ENV{PGUSER}; @tempdsn = ($dsn, '', '', {AutoCommit=>1,RaiseError=>1,PrintError=>0}); $tempdbh = DBI->connect(@tempdsn); - $tempdbh->do("CREATE USER $dbuser SUPERUSER"); + if ($self->{testuser_is_nosuper}) { + $tempdbh->do("CREATE USER $dbuser"); + } else { + $tempdbh->do("CREATE USER $dbuser SUPERUSER"); + } $tempdbh->disconnect(); $dbh = DBI->connect(@superdsn); } @@ -376,7 +385,11 @@ sub _test_database_handle { $sth->execute($dbuser); $count = $sth->fetchall_arrayref()->[0][0]; if (!$count) { - $dbh->do("CREATE USER $dbuser SUPERUSER"); + if ($self->{testuser_is_nosuper}) { + $dbh->do("CREATE USER $dbuser"); + } else { + $dbh->do("CREATE USER $dbuser SUPERUSER"); + } } my $user2 = $self->{testuser2}; $sth->execute($user2);