|
| 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 | +planskip_all=>'LDAP not supported by this build'; |
| 20 | +} |
| 21 | +elsif ($ENV{PG_TEST_EXTRA} !~/\bldap\b/) |
| 22 | +{ |
| 23 | +planskip_all=> |
| 24 | +'Potentially unsafe test LDAP not enabled in PG_TEST_EXTRA'; |
| 25 | +} |
| 26 | +elsif (!$LdapServer::setup) |
| 27 | +{ |
| 28 | +planskip_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 | +subtest_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_reseq 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(); |