diff --git a/testing/tests/ldap/0003-sync-ldap.result b/testing/tests/ldap/0003-sync-ldap.result index 1bffbba9..9f77e25c 100644 --- a/testing/tests/ldap/0003-sync-ldap.result +++ b/testing/tests/ldap/0003-sync-ldap.result @@ -2,8 +2,8 @@ HTTP/1.1 207 Multi-Status Date: Dow, 01 Jan 2000 00:00:00 GMT DAV: 1, 2, 3, access-control, calendar-access, calendar-schedule DAV: extended-mkcol, bind, addressbook, calendar-auto-schedule, calendar-proxy -ETag: "ed58709591152964fd4a584af5b55d79" -Content-Length: 942 +ETag: "484a5b4172cb19240bad5a30bbcc9ab9" +Content-Length: 945 Content-Type: text/xml; charset="utf-8" @@ -44,7 +44,7 @@ Content-Type: text/xml; charset="utf-8" - /caldav.php/ldap1/ + /caldav.php/pg_ldap1/ @@ -58,62 +58,62 @@ Content-Type: text/xml; charset="utf-8" active: >1< - email: >ldap1@example.com< - fullname: >LDAP 1< + email: >pg_ldap1@example.com< + fullname: >pg LDAP 1< last_used: >NULL< password: >NULL< user_no: >1001< - username: >ldap1< + username: >pg_ldap1< active: >1< - email: >ldap2@example.com< - fullname: >LDAP 2< + email: >pg_ldap2@example.com< + fullname: >pg LDAP 2< last_used: >NULL< password: >NULL< user_no: >1002< - username: >ldap2< + username: >pg_ldap2< active: >1< email: >NULL< - fullname: >ldap_group1< + fullname: >pg LDAP Group 1< last_used: >NULL< password: >NULL< user_no: >1003< - username: >ldap_group1< + username: >pg_ldap_group1< active: >1< email: >NULL< - fullname: >ldap_group2< + fullname: >pg LDAP Group 2< last_used: >NULL< password: >NULL< user_no: >1004< - username: >ldap_group2< + username: >pg_ldap_group2< active: >1< email: >NULL< - fullname: >ldap_group3< + fullname: >pg LDAP Group 3< last_used: >NULL< password: >NULL< user_no: >1005< - username: >ldap_group3< + username: >pg_ldap_group3< active: >1< email: >NULL< - fullname: >ldap_group4< + fullname: >pg LDAP Group 4< last_used: >NULL< password: >NULL< user_no: >1006< - username: >ldap_group4< + username: >pg_ldap_group4< - group_name: >ldap_group1< - user_name: >ldap1< + group_name: >pg_ldap_group1< + user_name: >pg_ldap1< - group_name: >ldap_group2< - user_name: >ldap2< + group_name: >pg_ldap_group2< + user_name: >pg_ldap2< - group_name: >ldap_group3< + group_name: >pg_ldap_group3< user_name: >NULL< - group_name: >ldap_group4< + group_name: >pg_ldap_group4< user_name: >NULL< diff --git a/testing/tests/ldap/0003-sync-ldap.test b/testing/tests/ldap/0003-sync-ldap.test index 777eb789..6ddc171a 100644 --- a/testing/tests/ldap/0003-sync-ldap.test +++ b/testing/tests/ldap/0003-sync-ldap.test @@ -2,6 +2,12 @@ # Portions Copyright (c) Best Practical Solutions, LLC # , licensed under the GPL v2. # +# Test where the posixGroup with MemberUid as a plain UID is used. +# +# See: +# - https://ldapwiki.com/wiki/Wiki.jsp?page=PosixGroup +# - https://ldapwiki.com/wiki/Wiki.jsp?page=MemberUid +# BEGINPERL if ($debug) { $ENV{'LDAP_DEBUG'} = 1 }; @@ -27,47 +33,49 @@ my $users = "ou=users,$base"; my $groups = "ou=groups,$base"; $ldap->add( $base ); -for my $username (qw/ldap1 ldap2/) { +# pg = posixGroup +for my $username (qw/pg_ldap1 pg_ldap2/) { my $dn = "uid=$username,$users"; - (my $cn = $username) =~ s/ldap(\d+)/LDAP $1/; + (my $cn = $username) =~ s/_ldap(\d+)/ LDAP $1/; my $entry = { cn => $cn, mail => "$username\@example.com", uid => $username, - objectClass => 'User', + objectClass => 'person', userPassword => $username, modifyTimestamp => 20240203001020, }; $ldap->add( $dn, attr => [%$entry] ); } -for my $group (qw/ldap_group1 ldap_group2/) { - my $dn = "cn=$group,$groups"; - (my $member = $group) =~ s/_group//; - my $entry = { - cn => $group, - objectClass => 'groupofNames', - memberUid => $member, - modifyTimestamp => 20240203001020, - }; - $ldap->add( $dn, attr => [%$entry] ); -} - -# Create some empty groups. -for my $group (qw/ldap_group3 ldap_group4/) { - my $dn = "cn=$group,$groups"; - my $entry = { - cn => $group, - objectClass => 'groupofNames', - modifyTimestamp => 20240203001020, - }; - $ldap->add( $dn, attr => [%$entry] ); -} - +make_group($ldap, 'pg_ldap_group1', 'pg_ldap1'); +make_group($ldap, 'pg_ldap_group2', 'pg_ldap2'); +make_group($ldap, 'pg_ldap_group3'); +make_group($ldap, 'pg_ldap_group4'); # We need to keep the client around, otherwise the test server will exit. $evaled{'ldap_client'} = $ldap; -#sleep 60; +sleep 60; + +sub make_group { + my $ldap = shift; + my $name = shift; + my @users = @_; + + my $dn = "cn=$name,$groups"; + (my $desc = $name) =~ s/_ldap_group(\d+)/ LDAP Group $1/; + my $entry = { + cn => $name, + objectClass => 'posixGroup', + description => $desc, + (@users + ? (memberUid => [ @users ]) + : () + ), + modifyTimestamp => 20240203001020, + }; + $ldap->add( $dn, attr => [%$entry] ); +} ENDPERL SCRIPT=../scripts/cron-sync-ldap.php regression_ldap.host @@ -77,7 +85,7 @@ TYPE=PROPFIND URL=http://regression_ldap.host/caldav.php/ HEADER=Content-Type: text/xml HEADER=Depth: 1 -AUTH=ldap1:ldap1 +AUTH=pg_ldap1:pg_ldap1 HEAD BEGINDATA @@ -94,12 +102,11 @@ ENDDATA QUERY SELECT active, email, fullname, last_used, password, username, user_no FROM usr -WHERE username LIKE 'ldap%' +WHERE username LIKE 'pg_ldap%' ORDER BY username; ENDQUERY -# Check that ldap1 is a member of ldap_qroup1 and ldap2 is a member of -# ldap_group2, and that ldap_group3 is empty. +# Make sure that group membership matches above. QUERY SELECT grp_u.username AS group_name, usr_u.username AS user_name FROM principal AS grp_p @@ -107,6 +114,6 @@ FROM principal AS grp_p left join principal AS usr_p ON (group_member.member_id = usr_p.principal_id) left join usr AS usr_u ON (usr_p.user_no = usr_u.user_no) left join usr AS grp_u ON (grp_p.user_no = grp_u.user_no) -WHERE grp_u.username LIKE 'ldap_group%' +WHERE grp_u.username LIKE 'pg_ldap_group%' ORDER BY group_name, user_name; ENDQUERY diff --git a/testing/tests/ldap/0004-sync-ldap-changes.result b/testing/tests/ldap/0004-sync-ldap-changes.result index 46ee9b73..dc1ecd1d 100644 --- a/testing/tests/ldap/0004-sync-ldap-changes.result +++ b/testing/tests/ldap/0004-sync-ldap-changes.result @@ -2,8 +2,8 @@ HTTP/1.1 207 Multi-Status Date: Dow, 01 Jan 2000 00:00:00 GMT DAV: 1, 2, 3, access-control, calendar-access, calendar-schedule DAV: extended-mkcol, bind, addressbook, calendar-auto-schedule, calendar-proxy -ETag: "ed58709591152964fd4a584af5b55d79" -Content-Length: 942 +ETag: "484a5b4172cb19240bad5a30bbcc9ab9" +Content-Length: 945 Content-Type: text/xml; charset="utf-8" @@ -44,7 +44,7 @@ Content-Type: text/xml; charset="utf-8" - /caldav.php/ldap1/ + /caldav.php/pg_ldap1/ @@ -58,65 +58,59 @@ Content-Type: text/xml; charset="utf-8" active: >1< - email: >ldap1@example.com< - fullname: >LDAP 1< + email: >pg_ldap1@example.com< + fullname: >pg LDAP 1< last_used: >NULL< password: >NULL< - user_no: >1001< - username: >ldap1< + username: >pg_ldap1< active: >1< - email: >ldap2@example.com< - fullname: >LDAP 2< + email: >pg_ldap2@example.com< + fullname: >pg LDAP 2< last_used: >NULL< password: >NULL< - user_no: >1002< - username: >ldap2< + username: >pg_ldap2< active: >1< email: >NULL< - fullname: >ldap_group1< + fullname: >pg_ldap_group1< last_used: >NULL< password: >NULL< - user_no: >1003< - username: >ldap_group1< + username: >pg_ldap_group1< active: >1< email: >NULL< - fullname: >ldap_group2< + fullname: >pg_ldap_group2< last_used: >NULL< password: >NULL< - user_no: >1004< - username: >ldap_group2< + username: >pg_ldap_group2< active: >1< email: >NULL< - fullname: >ldap_group3< + fullname: >pg_ldap_group3< last_used: >NULL< password: >NULL< - user_no: >1005< - username: >ldap_group3< + username: >pg_ldap_group3< active: >1< email: >NULL< - fullname: >ldap_group4< + fullname: >pg_ldap_group4< last_used: >NULL< password: >NULL< - user_no: >1006< - username: >ldap_group4< + username: >pg_ldap_group4< - group_name: >ldap_group1< - user_name: >ldap2< + group_name: >pg_ldap_group1< + user_name: >pg_ldap2< - group_name: >ldap_group2< - user_name: >ldap1< + group_name: >pg_ldap_group2< + user_name: >pg_ldap1< - group_name: >ldap_group2< - user_name: >ldap2< + group_name: >pg_ldap_group2< + user_name: >pg_ldap2< - group_name: >ldap_group3< - user_name: >ldap1< + group_name: >pg_ldap_group3< + user_name: >pg_ldap1< - group_name: >ldap_group4< + group_name: >pg_ldap_group4< user_name: >NULL< diff --git a/testing/tests/ldap/0004-sync-ldap-changes.test b/testing/tests/ldap/0004-sync-ldap-changes.test index 51e4050f..8e6c0ec1 100644 --- a/testing/tests/ldap/0004-sync-ldap-changes.test +++ b/testing/tests/ldap/0004-sync-ldap-changes.test @@ -6,16 +6,19 @@ # the previous test to make sure that changes are reflected. # # Database will start with: -# ldap_group1: ldap1 -# ldap_group2: ldap2 -# ldap_group3: -# ldap_group4: ldap1 +# pg_ldap_group1: pg_ldap1 +# pg_ldap_group2: pg_ldap2 +# pg_ldap_group3: +# pg_ldap_group4: pg_ldap1 # # We will change that to: -# ldap_group1: ldap2 -# ldap_group2: ldap1, ldap2 -# ldap_group3: ldap1 -# ldap_group4: +# pg_ldap_group1: pg_ldap2 +# pg_ldap_group2: pg_ldap1, pg_ldap2 +# pg_ldap_group3: pg_ldap1 +# pg_ldap_group4: +# +# The fullanme for each group should change from "pg LDAP Group $n" to +# "pg_ldap_group_$n". # BEGINPERL if ($debug) { $ENV{'LDAP_DEBUG'} = 1 }; @@ -42,24 +45,25 @@ my $users = "ou=users,$base"; my $groups = "ou=groups,$base"; $ldap->add( $base ); -for my $username (qw/ldap1 ldap2/) { +# pg = posixGroup +for my $username (qw/pg_ldap1 pg_ldap2/) { my $dn = "uid=$username,$users"; - (my $cn = $username) =~ s/ldap(\d+)/LDAP $1/; + (my $cn = $username) =~ s/_ldap(\d+)/LDAP $1/; my $entry = { cn => $cn, mail => "$username\@example.com", uid => $username, - objectClass => 'User', + objectClass => 'person', userPassword => $username, modifyTimestamp => 20240203001020, }; $ldap->add( $dn, attr => [%$entry] ); } -make_group($ldap, 'ldap_group1', 'ldap2'); -make_group($ldap, 'ldap_group2', 'ldap1', 'ldap2'); -make_group($ldap, 'ldap_group3', 'ldap1'); -make_group($ldap, 'ldap_group4'); +make_group($ldap, 'pg_ldap_group1', 'pg_ldap2'); +make_group($ldap, 'pg_ldap_group2', 'pg_ldap1', 'pg_ldap2'); +make_group($ldap, 'pg_ldap_group3', 'pg_ldap1'); +make_group($ldap, 'pg_ldap_group4'); # We need to keep the client around, otherwise the test server will exit. $evaled{'ldap_client'} = $ldap; @@ -70,12 +74,13 @@ sub make_group { my $name = shift; my @users = @_; - my $dn = "cn=$name,$groups"; - my $entry = { + my $dn = "cn=$name,$groups"; + my $entry = { cn => $name, - objectClass => 'groupofNames', + objectClass => 'posixGroup', + description => $name, (@users - ? (memberUid => [ @users ]) + ? (memberUid => [ @users ]) : () ), modifyTimestamp => 20240203001020, @@ -91,7 +96,7 @@ TYPE=PROPFIND URL=http://regression_ldap.host/caldav.php/ HEADER=Content-Type: text/xml HEADER=Depth: 1 -AUTH=ldap1:ldap1 +AUTH=pg_ldap1:pg_ldap1 HEAD BEGINDATA @@ -105,14 +110,13 @@ ENDDATA # Check that a usr record has been created for all users and groups QUERY -SELECT active, email, fullname, last_used, password, username, user_no +SELECT active, email, fullname, last_used, password, username FROM usr -WHERE username LIKE 'ldap%' +WHERE username LIKE 'pg_ldap%' ORDER BY username; ENDQUERY -# Check that ldap1 is a member of ldap_qroup1 and ldap2 is a member of -# ldap_group2, and that ldap_group3 is empty. +# Check that group membership matches what was created above. QUERY SELECT grp_u.username AS group_name, usr_u.username AS user_name FROM principal AS grp_p @@ -120,6 +124,6 @@ FROM principal AS grp_p left join principal AS usr_p ON (group_member.member_id = usr_p.principal_id) left join usr AS usr_u ON (usr_p.user_no = usr_u.user_no) left join usr AS grp_u ON (grp_p.user_no = grp_u.user_no) -WHERE grp_u.username LIKE 'ldap_group%' +WHERE grp_u.username LIKE 'pg_ldap_group%' ORDER BY group_name, user_name; ENDQUERY diff --git a/testing/tests/ldap/0005-test-ldap.result b/testing/tests/ldap/0005-test-ldap.result index e8434050..85167726 100644 --- a/testing/tests/ldap/0005-test-ldap.result +++ b/testing/tests/ldap/0005-test-ldap.result @@ -62,6 +62,5 @@ Content-Type: text/xml; charset="utf-8" fullname: >ldap3< last_used: >NULL< password: >NULL< - user_no: >1007< username: >ldap3< diff --git a/testing/tests/ldap/0005-test-ldap.test b/testing/tests/ldap/0005-test-ldap.test index bf9c0dd3..3cceeb6d 100644 --- a/testing/tests/ldap/0005-test-ldap.test +++ b/testing/tests/ldap/0005-test-ldap.test @@ -64,7 +64,7 @@ ENDDATA # Check that a usr record has been created. QUERY -SELECT active, email, fullname, last_used, password, username, user_no +SELECT active, email, fullname, last_used, password, username FROM usr WHERE username = 'ldap3'; ENDQUERY diff --git a/testing/tests/ldap/0006-test-DN-in-Groups.result b/testing/tests/ldap/0006-test-DN-in-Groups.result new file mode 100644 index 00000000..353acdc3 --- /dev/null +++ b/testing/tests/ldap/0006-test-DN-in-Groups.result @@ -0,0 +1,127 @@ +HTTP/1.1 207 Multi-Status +Date: Dow, 01 Jan 2000 00:00:00 GMT +DAV: 1, 2, 3, access-control, calendar-access, calendar-schedule +DAV: extended-mkcol, bind, addressbook, calendar-auto-schedule, calendar-proxy +ETag: "da739b6b98d20b87833748d890466cde" +Content-Length: 946 +Content-Type: text/xml; charset="utf-8" + + + + + /caldav.php/ + + + + + + + HTTP/1.1 200 OK + + + + /caldav.php/resource1/ + + + + + + + + HTTP/1.1 200 OK + + + + /caldav.php/resource2/ + + + + + + + + HTTP/1.1 200 OK + + + + /caldav.php/gON_ldap1/ + + + + + + + + HTTP/1.1 200 OK + + + + + active: >1< + email: >gON_ldap1@example.com< + fullname: >gON LDAP 1< + last_used: >NULL< + password: >NULL< + username: >gON_ldap1< + + active: >1< + email: >gON_ldap2@example.com< + fullname: >gON LDAP 2< + last_used: >NULL< + password: >NULL< + username: >gON_ldap2< + + active: >1< + email: >gON_ldap3@example.com< + fullname: >gON LDAP 3< + last_used: >NULL< + password: >NULL< + username: >gON_ldap3< + + active: >1< + email: >gON_ldap4@example.com< + fullname: >gON LDAP 4< + last_used: >NULL< + password: >NULL< + username: >gON_ldap4< + + active: >1< + email: >NULL< + fullname: >gON_ldap_group1< + last_used: >NULL< + password: >NULL< + username: >gON_ldap_group1< + + active: >1< + email: >NULL< + fullname: >gON_ldap_group2< + last_used: >NULL< + password: >NULL< + username: >gON_ldap_group2< + + active: >1< + email: >NULL< + fullname: >gON_ldap_group3< + last_used: >NULL< + password: >NULL< + username: >gON_ldap_group3< + + active: >1< + email: >NULL< + fullname: >gON_ldap_group4< + last_used: >NULL< + password: >NULL< + username: >gON_ldap_group4< + + group_name: >gON_ldap_group1< + user_name: >NULL< + + group_name: >gON_ldap_group2< + user_name: >NULL< + + group_name: >gON_ldap_group3< + user_name: >NULL< + + group_name: >gON_ldap_group4< + user_name: >NULL< + diff --git a/testing/tests/ldap/0006-test-DN-in-Groups.test b/testing/tests/ldap/0006-test-DN-in-Groups.test new file mode 100644 index 00000000..85fd4078 --- /dev/null +++ b/testing/tests/ldap/0006-test-DN-in-Groups.test @@ -0,0 +1,147 @@ +# Copyright (c) 2021-2024 Andrew Ruthven +# Portions Copyright (c) Best Practical Solutions, LLC +# , licensed under the GPL v2. +# +# Test where the groupOfNames style of groups are used. In this case the +# DN of each member is stored, typically in a "member" attribute. +# +# See: +# - https://ldapwiki.com/wiki/Wiki.jsp?page=GroupOfNames +# - https://ldapwiki.com/wiki/Wiki.jsp?page=Member +# +BEGINPERL +if ($debug) { $ENV{'LDAP_DEBUG'} = 1 }; + +use Net::LDAP::Server::Test; +use Net::LDAP; +use IO::Socket::INET; + +my $ldap_port = 21394; +my $ldap_socket = IO::Socket::INET->new( + Listen => 5, + Proto => 'tcp', + Reuse => 1, + LocalPort => $ldap_port, +); + +# Keep it around after this block exits. +$evaled{'ldap_server'} + = Net::LDAP::Server::Test->new( $ldap_socket, auto_schema => 1 ); + +my $ldap = Net::LDAP->new("localhost:$ldap_port") + || die "Failed to instantiate Net::LDAP: $!"; +$ldap->bind(); + +my $base = "dc=example,dc=com"; +my $users = "ou=users,$base"; +my $groups = "ou=groups,$base"; +$ldap->add( $base ); + +my %users; + +# gON = groupOfNames test +for my $username (qw/gON_ldap1 gON_ldap2/) { + my $dn = "uid=$username,$users"; + (my $cn = $username) =~ s/_ldap(\d+)/ LDAP $1/; + $users{$username} = $dn; + + my $entry = { + cn => $cn, + mail => "$username\@example.com", + uid => $username, + objectClass => 'person', + userPassword => $username, + modifyTimestamp => 20240203001020, + }; + + $ldap->add( $dn, attr => [%$entry] ); +} + +# Users where the DN does not have uid as an RDN. +for my $username (qw/gON_ldap3 gON_ldap4/) { + (my $cn = $username) =~ s/_ldap(\d+)/ LDAP $1/; + my $dn = "cn=$cn,$users"; + $users{$username} = $dn; + + my $entry = { + cn => $cn, + mail => "$username\@example.com", + uid => $username, + objectClass => 'person', + userPassword => $username, + modifyTimestamp => 20240203001020, + }; + + $ldap->add( $dn, attr => [%$entry] ); +} + + +make_group($ldap, 'gON_ldap_group1', $users{gON_ldap1}); +make_group($ldap, 'gON_ldap_group2', $users{gON_ldap1}, $users{gON_ldap2}, + $users{gON_ldap4}); +make_group($ldap, 'gON_ldap_group3', $users{gON_ldap1}, $users{gON_ldap3}); +make_group($ldap, 'gON_ldap_group4'); + +# We need to keep the client around, otherwise the test server will exit. +$evaled{'ldap_client'} = $ldap; +#sleep 60; + +sub make_group { + my $ldap = shift; + my $name = shift; + my @users = @_; + + my $dn = "cn=$name,$groups"; + my $entry = { + cn => $name, + objectClass => 'groupOfNames', + (@users + ? (member => [ @users ]) + : () + ), + modifyTimestamp => 20240203001020, + }; + $ldap->add( $dn, attr => [%$entry] ); +} + +ENDPERL + +SCRIPT=../scripts/cron-sync-ldap.php regression_ldap.host + +# Testing logging in as one of the users - should work. +TYPE=PROPFIND +URL=http://regression_ldap.host/caldav.php/ +HEADER=Content-Type: text/xml +HEADER=Depth: 1 +AUTH=gON_ldap1:gON_ldap1 +HEAD + +BEGINDATA + + + + + + +ENDDATA + + +# Check that a usr record has been created for all users and groups +QUERY +SELECT active, email, fullname, last_used, password, username +FROM usr +WHERE username LIKE 'gON_ldap%' +ORDER BY username; +ENDQUERY + +# Check group membership matches above. +QUERY +SELECT grp_u.username AS group_name, usr_u.username AS user_name +FROM principal AS grp_p + left join group_member ON (grp_p.principal_id = group_member.group_id) + left join principal AS usr_p ON (group_member.member_id = usr_p.principal_id) + left join usr AS usr_u ON (usr_p.user_no = usr_u.user_no) + left join usr AS grp_u ON (grp_p.user_no = grp_u.user_no) +WHERE grp_u.username LIKE 'gON_ldap_group%' +ORDER BY group_name, user_name; +ENDQUERY