|
| 1 | +use strict; |
| 2 | +use warnings; |
| 3 | +use TestLib; |
| 4 | +use PostgresNode; |
| 5 | +use Test::Moretests=> 14; |
| 6 | + |
| 7 | +my ($slapd,$ldap_bin_dir,$ldap_schema_dir); |
| 8 | + |
| 9 | +$ldap_bin_dir =undef;# usually in PATH |
| 10 | + |
| 11 | +if ($^Oeq'darwin') |
| 12 | +{ |
| 13 | +$slapd ='/usr/local/opt/openldap/libexec/slapd'; |
| 14 | +$ldap_schema_dir ='/usr/local/etc/openldap/schema'; |
| 15 | +} |
| 16 | +elsif ($^Oeq'linux') |
| 17 | +{ |
| 18 | +$slapd ='/usr/sbin/slapd'; |
| 19 | +$ldap_schema_dir ='/etc/ldap/schema'if-f'/etc/ldap/schema'; |
| 20 | +$ldap_schema_dir ='/etc/openldap/schema'if-f'/etc/openldap/schema'; |
| 21 | +} |
| 22 | +elsif ($^Oeq'freebsd') |
| 23 | +{ |
| 24 | +$slapd ='/usr/local/libexec/slapd'; |
| 25 | +$ldap_schema_dir ='/usr/local/etc/openldap/schema'; |
| 26 | +} |
| 27 | + |
| 28 | +# make your own edits here |
| 29 | +#$slapd = ''; |
| 30 | +#$ldap_bin_dir = ''; |
| 31 | +#$ldap_schema_dir = ''; |
| 32 | + |
| 33 | +$ENV{PATH} ="$ldap_bin_dir:$ENV{PATH}"if$ldap_bin_dir; |
| 34 | + |
| 35 | +my$ldap_datadir ="${TestLib::tmp_check}/openldap-data"; |
| 36 | +my$slapd_conf ="${TestLib::tmp_check}/slapd.conf"; |
| 37 | +my$slapd_pidfile ="${TestLib::tmp_check}/slapd.pid"; |
| 38 | +my$slapd_logfile ="${TestLib::tmp_check}/slapd.log"; |
| 39 | +my$ldap_conf ="${TestLib::tmp_check}/ldap.conf"; |
| 40 | +my$ldap_server ='localhost'; |
| 41 | +my$ldap_port =int(rand() * 16384) + 49152; |
| 42 | +my$ldap_url ="ldap://$ldap_server:$ldap_port"; |
| 43 | +my$ldap_basedn ='dc=example,dc=net'; |
| 44 | +my$ldap_rootdn ='cn=Manager,dc=example,dc=net'; |
| 45 | +my$ldap_rootpw ='secret'; |
| 46 | +my$ldap_pwfile ="${TestLib::tmp_check}/ldappassword"; |
| 47 | + |
| 48 | +note"setting up slapd"; |
| 49 | + |
| 50 | +append_to_file($slapd_conf, |
| 51 | +qq{include$ldap_schema_dir/core.schema |
| 52 | +include$ldap_schema_dir/cosine.schema |
| 53 | +include$ldap_schema_dir/nis.schema |
| 54 | +include$ldap_schema_dir/inetorgperson.schema |
| 55 | +
|
| 56 | +pidfile$slapd_pidfile |
| 57 | +logfile$slapd_logfile |
| 58 | +
|
| 59 | +access to * |
| 60 | + by * read |
| 61 | + by anonymous auth |
| 62 | +
|
| 63 | +database ldif |
| 64 | +directory$ldap_datadir |
| 65 | +
|
| 66 | +suffix "dc=example,dc=net" |
| 67 | +rootdn "$ldap_rootdn" |
| 68 | +rootpw$ldap_rootpw}); |
| 69 | + |
| 70 | +mkdir$ldap_datadirordie; |
| 71 | + |
| 72 | +system_or_bail$slapd,'-f',$slapd_conf,'-h',$ldap_url; |
| 73 | + |
| 74 | +END |
| 75 | +{ |
| 76 | +kill'INT',`cat$slapd_pidfile`if-f$slapd_pidfile; |
| 77 | +} |
| 78 | + |
| 79 | +append_to_file($ldap_pwfile,$ldap_rootpw); |
| 80 | +chmod 0600,$ldap_pwfileordie; |
| 81 | + |
| 82 | +$ENV{'LDAPURI'} =$ldap_url; |
| 83 | +$ENV{'LDAPBINDDN'} =$ldap_rootdn; |
| 84 | + |
| 85 | +note"loading LDAP data"; |
| 86 | + |
| 87 | +system_or_bail'ldapadd','-x','-y',$ldap_pwfile,'-f','authdata.ldif'; |
| 88 | +system_or_bail'ldappasswd','-x','-y',$ldap_pwfile,'-s','secret1','uid=test1,dc=example,dc=net'; |
| 89 | +system_or_bail'ldappasswd','-x','-y',$ldap_pwfile,'-s','secret2','uid=test2,dc=example,dc=net'; |
| 90 | + |
| 91 | +note"setting up PostgreSQL instance"; |
| 92 | + |
| 93 | +my$node = get_new_node('node'); |
| 94 | +$node->init; |
| 95 | +$node->start; |
| 96 | + |
| 97 | +$node->safe_psql('postgres','CREATE USER test0;'); |
| 98 | +$node->safe_psql('postgres','CREATE USER test1;'); |
| 99 | +$node->safe_psql('postgres','CREATE USER "test2@example.net";'); |
| 100 | + |
| 101 | +note"running tests"; |
| 102 | + |
| 103 | +subtest_access |
| 104 | +{ |
| 105 | +my ($node,$role,$expected_res,$test_name) =@_; |
| 106 | + |
| 107 | +my$res =$node->psql('postgres','SELECT 1',extra_params=> ['-U',$role ]); |
| 108 | + is($res,$expected_res,$test_name); |
| 109 | +} |
| 110 | + |
| 111 | +note"simple bind"; |
| 112 | + |
| 113 | +unlink($node->data_dir .'/pg_hba.conf'); |
| 114 | +$node->append_conf('pg_hba.conf',qq{local all all ldap ldapserver=$ldap_server ldapport=$ldap_port ldapprefix="uid=" ldapsuffix=",dc=example,dc=net"}); |
| 115 | +$node->reload; |
| 116 | + |
| 117 | +$ENV{"PGPASSWORD"} ='wrong'; |
| 118 | +test_access($node,'test0', 2,'simple bind authentication fails if user not found in LDAP'); |
| 119 | +test_access($node,'test1', 2,'simple bind authentication fails with wrong password'); |
| 120 | +$ENV{"PGPASSWORD"} ='secret1'; |
| 121 | +test_access($node,'test1', 0,'simple bind authentication succeeds'); |
| 122 | + |
| 123 | +note"search+bind"; |
| 124 | + |
| 125 | +unlink($node->data_dir .'/pg_hba.conf'); |
| 126 | +$node->append_conf('pg_hba.conf',qq{local all all ldap ldapserver=$ldap_server ldapport=$ldap_port ldapbasedn="$ldap_basedn"}); |
| 127 | +$node->reload; |
| 128 | + |
| 129 | +$ENV{"PGPASSWORD"} ='wrong'; |
| 130 | +test_access($node,'test0', 2,'search+bind authentication fails if user not found in LDAP'); |
| 131 | +test_access($node,'test1', 2,'search+bind authentication fails with wrong password'); |
| 132 | +$ENV{"PGPASSWORD"} ='secret1'; |
| 133 | +test_access($node,'test1', 0,'search+bind authentication succeeds'); |
| 134 | + |
| 135 | +note"LDAP URLs"; |
| 136 | + |
| 137 | +unlink($node->data_dir .'/pg_hba.conf'); |
| 138 | +$node->append_conf('pg_hba.conf',qq{local all all ldap ldapurl="$ldap_url/$ldap_basedn?uid?sub"}); |
| 139 | +$node->reload; |
| 140 | + |
| 141 | +$ENV{"PGPASSWORD"} ='wrong'; |
| 142 | +test_access($node,'test0', 2,'search+bind with LDAP URL authentication fails if user not found in LDAP'); |
| 143 | +test_access($node,'test1', 2,'search+bind with LDAP URL authentication fails with wrong password'); |
| 144 | +$ENV{"PGPASSWORD"} ='secret1'; |
| 145 | +test_access($node,'test1', 0,'search+bind with LDAP URL authentication succeeds'); |
| 146 | + |
| 147 | +note"search filters"; |
| 148 | + |
| 149 | +unlink($node->data_dir .'/pg_hba.conf'); |
| 150 | +$node->append_conf('pg_hba.conf',qq{local all all ldap ldapserver=$ldap_server ldapport=$ldap_port ldapbasedn="$ldap_basedn" ldapsearchfilter="(|(uid=\$username)(mail=\$username))"}); |
| 151 | +$node->reload; |
| 152 | + |
| 153 | +$ENV{"PGPASSWORD"} ='secret1'; |
| 154 | +test_access($node,'test1', 0,'search filter finds by uid'); |
| 155 | +$ENV{"PGPASSWORD"} ='secret2'; |
| 156 | +test_access($node,'test2@example.net', 0,'search filter finds by mail'); |
| 157 | + |
| 158 | +note"search filters in LDAP URLs"; |
| 159 | + |
| 160 | +unlink($node->data_dir .'/pg_hba.conf'); |
| 161 | +$node->append_conf('pg_hba.conf',qq{local all all ldap ldapurl="$ldap_url/$ldap_basedn??sub?(|(uid=\$username)(mail=\$username))"}); |
| 162 | +$node->reload; |
| 163 | + |
| 164 | +$ENV{"PGPASSWORD"} ='secret1'; |
| 165 | +test_access($node,'test1', 0,'search filter finds by uid'); |
| 166 | +$ENV{"PGPASSWORD"} ='secret2'; |
| 167 | +test_access($node,'test2@example.net', 0,'search filter finds by mail'); |
| 168 | + |
| 169 | +# This is not documented: You can combine ldapurl and other ldap* |
| 170 | +# settings. ldapurl is always parsed first, then the other settings |
| 171 | +# override. It might be useful in a case like this. |
| 172 | +unlink($node->data_dir .'/pg_hba.conf'); |
| 173 | +$node->append_conf('pg_hba.conf',qq{local all all ldap ldapurl="$ldap_url/$ldap_basedn??sub" ldapsearchfilter="(|(uid=\$username)(mail=\$username))"}); |
| 174 | +$node->reload; |
| 175 | + |
| 176 | +$ENV{"PGPASSWORD"} ='secret1'; |
| 177 | +test_access($node,'test1', 0,'combined LDAP URL and search filter'); |