|
| 1 | + |
| 2 | +# Copyright (c) 2023, PostgreSQL Global Development Group |
| 3 | + |
| 4 | +use strict; |
| 5 | +use warnings; |
| 6 | + |
| 7 | +use FindBin; |
| 8 | +use lib "$FindBin::RealBin/.."; |
| 9 | + |
| 10 | +use File::Copy; |
| 11 | +use File::Basename; |
| 12 | +use LdapServer; |
| 13 | +use PostgreSQL::Test::Utils; |
| 14 | +use PostgreSQL::Test::Cluster; |
| 15 | +use Test::More; |
| 16 | + |
| 17 | +if ($ENV{with_ldap} ne 'yes') |
| 18 | +{ |
| 19 | + plan skip_all => 'LDAP not supported by this build'; |
| 20 | +} |
| 21 | +elsif ($ENV{PG_TEST_EXTRA} !~ /\bldap\b/) |
| 22 | +{ |
| 23 | + plan skip_all => |
| 24 | + 'Potentially unsafe test LDAP not enabled in PG_TEST_EXTRA'; |
| 25 | +} |
| 26 | +elsif (!$LdapServer::setup) |
| 27 | +{ |
| 28 | + plan skip_all => |
| 29 | + "ldap tests not supported on $^O or dependencies not installed"; |
| 30 | +} |
| 31 | + |
| 32 | +note "setting up LDAP server"; |
| 33 | + |
| 34 | +my $ldap_rootpw = 'secret'; |
| 35 | +my $ldap = LdapServer->new($ldap_rootpw, 'users'); # no anonymous auth |
| 36 | +$ldap->ldapadd_file('authdata.ldif'); |
| 37 | +$ldap->ldapsetpw('uid=test1,dc=example,dc=net', 'secret1'); |
| 38 | +$ldap->ldapsetpw('uid=test2,dc=example,dc=net', 'secret2'); |
| 39 | + |
| 40 | +my ($ldap_server, $ldap_port, $ldap_basedn, $ldap_rootdn) = |
| 41 | + $ldap->prop(qw(server port basedn rootdn)); |
| 42 | + |
| 43 | +note "setting up PostgreSQL instance"; |
| 44 | + |
| 45 | +my $node = PostgreSQL::Test::Cluster->new('node'); |
| 46 | +$node->init; |
| 47 | +$node->append_conf('postgresql.conf', "log_connections = on\n"); |
| 48 | +$node->start; |
| 49 | + |
| 50 | +$node->safe_psql('postgres', 'CREATE USER test0;'); |
| 51 | +$node->safe_psql('postgres', 'CREATE USER test1;'); |
| 52 | +$node->safe_psql('postgres', 'CREATE USER "test2@example.net";'); |
| 53 | + |
| 54 | +note "running tests"; |
| 55 | + |
| 56 | +sub test_access |
| 57 | +{ |
| 58 | + local $Test::Builder::Level = $Test::Builder::Level + 1; |
| 59 | + |
| 60 | + my ($node, $role, $expected_res, $test_name, %params) = @_; |
| 61 | + my $connstr = "user=$role"; |
| 62 | + |
| 63 | + if ($expected_res eq 0) |
| 64 | + { |
| 65 | + $node->connect_ok($connstr, $test_name, %params); |
| 66 | + } |
| 67 | + else |
| 68 | + { |
| 69 | + # No checks of the error message, only the status code. |
| 70 | + $node->connect_fails($connstr, $test_name, %params); |
| 71 | + } |
| 72 | +} |
| 73 | + |
| 74 | +note "use ldapbindpasswd"; |
| 75 | + |
| 76 | +unlink($node->data_dir . '/pg_hba.conf'); |
| 77 | +$node->append_conf('pg_hba.conf', |
| 78 | + qq{local all all ldap ldapserver=$ldap_server ldapport=$ldap_port ldapbasedn="$ldap_basedn" ldapbinddn="$ldap_rootdn ldapbindpasswd=wrong} |
| 79 | +); |
| 80 | +$node->restart; |
| 81 | + |
| 82 | +$ENV{"PGPASSWORD"} = 'secret1'; |
| 83 | +test_access($node, 'test1', 2, |
| 84 | + 'search+bind authentication fails with wrong ldapbindpasswd'); |
| 85 | + |
| 86 | +unlink($node->data_dir . '/pg_hba.conf'); |
| 87 | +$node->append_conf('pg_hba.conf', |
| 88 | + qq{local all all ldap ldapserver=$ldap_server ldapport=$ldap_port ldapbasedn="$ldap_basedn" ldapbinddn="$ldap_rootdn" ldapbindpasswd="$ldap_rootpw"} |
| 89 | +); |
| 90 | +$node->restart; |
| 91 | + |
| 92 | +test_access($node, 'test1', 0, |
| 93 | + 'search+bind authentication succeeds with ldapbindpasswd'); |
| 94 | + |
| 95 | +done_testing(); |
0 commit comments