Add checks for regexes with user name map in test for peer authentication
authorMichael Paquier <[email protected]>
Mon, 17 Oct 2022 02:06:00 +0000 (11:06 +0900)
committerMichael Paquier <[email protected]>
Mon, 17 Oct 2022 02:06:00 +0000 (11:06 +0900)
There is already some coverage for that in the kerberos test suite,
though it requires PG_TEST_EXTRA to be set as per its insecure nature.
This provides coverage in a default setup, as long as peer is supported
on the platform where its test is run.

Author: Bertrand Drouvot
Discussion: https://postgr.es/m/7f87ca27-e184-29da-15d6-8be4325ad02e@gmail.com

src/test/authentication/t/003_peer.pl

index fc951dea0648cb5643209d137b7e055f1b2778ff..ce8408a4f8c97ac7d4df48765d2ffdb7178f3725 100644 (file)
@@ -23,18 +23,34 @@ sub reset_pg_hba
    return;
 }
 
+# Delete pg_ident.conf from the given node, add a new entry to it
+# and then execute a reload to refresh it.
+sub reset_pg_ident
+{
+   my $node        = shift;
+   my $map_name    = shift;
+   my $system_user = shift;
+   my $pg_user     = shift;
+
+   unlink($node->data_dir . '/pg_ident.conf');
+   $node->append_conf('pg_ident.conf', "$map_name $system_user $pg_user");
+   $node->reload;
+   return;
+}
+
 # Test access for a single role, useful to wrap all tests into one.
 sub test_role
 {
    local $Test::Builder::Level = $Test::Builder::Level + 1;
 
-   my ($node, $role, $method, $expected_res, %params) = @_;
+   my ($node, $role, $method, $expected_res, $test_details, %params) = @_;
    my $status_string = 'failed';
    $status_string = 'success' if ($expected_res eq 0);
 
    my $connstr = "user=$role";
    my $testname =
-     "authentication $status_string for method $method, role $role";
+     "authentication $status_string for method $method, role $role "
+     . $test_details;
 
    if ($expected_res eq 0)
    {
@@ -87,16 +103,50 @@ my $system_user =
 # Tests without the user name map.
 # Failure as connection is attempted with a database role not mapping
 # to an authorized system user.
-test_role($node, qq{testmapuser}, 'peer', 2,
+test_role(
+   $node, qq{testmapuser}, 'peer', 2,
+   'without user name map',
    log_like => [qr/Peer authentication failed for user "testmapuser"/]);
 
 # Tests with a user name map.
-$node->append_conf('pg_ident.conf', qq{mypeermap $system_user testmapuser});
+reset_pg_ident($node, 'mypeermap', $system_user, 'testmapuser');
 reset_pg_hba($node, 'peer map=mypeermap');
 
 # Success as the database role matches with the system user in the map.
-test_role($node, qq{testmapuser}, 'peer', 0,
+test_role($node, qq{testmapuser}, 'peer', 0, 'with user name map',
    log_like =>
      [qr/connection authenticated: identity="$system_user" method=peer/]);
 
+# Test with regular expression in user name map.
+# Extract the last 3 characters from the system_user
+# or the entire system_user (if its length is <= -3).
+my $regex_test_string = substr($system_user, -3);
+
+# Success as the regular expression matches.
+reset_pg_ident($node, 'mypeermap', qq{/^.*$regex_test_string\$},
+   'testmapuser');
+test_role(
+   $node,
+   qq{testmapuser},
+   'peer',
+   0,
+   'with regular expression in user name map',
+   log_like =>
+     [qr/connection authenticated: identity="$system_user" method=peer/]);
+
+
+# Concatenate system_user to system_user.
+$regex_test_string = $system_user . $system_user;
+
+# Failure as the regular expression does not match.
+reset_pg_ident($node, 'mypeermap', qq{/^.*$regex_test_string\$},
+   'testmapuser');
+test_role(
+   $node,
+   qq{testmapuser},
+   'peer',
+   2,
+   'with regular expression in user name map',
+   log_like => [qr/no match in usermap "mypeermap" for user "testmapuser"/]);
+
 done_testing();