Rather than look for a flag, if a member is a DN, modify/fetch the record.

This changes 48c6512a70740c403027b66e9d609e9b871d29c0, in Eric's commit it
needs a flag to go fetch the record and apply the mapping to find the
username field. This approach looks for a telltale that this is DN (naively
an "=") and then either grabs the first element from the DN if the username
attr matches or fetches the entry from LDAP.

There have also been attempts in the past to special case uniqueMember and
to add a group_member_dnfix config option.

This should handle the cases where people use uid/cn/whatever for the
username.
This commit is contained in:
Andrew Ruthven 2024-02-03 23:37:04 +13:00
parent 03d0e66b39
commit 8a6274e6cf
2 changed files with 37 additions and 24 deletions

View File

@ -726,10 +726,6 @@ $c->admin_email = 'calendar-admin@example.com';
// "members" => "member"
// ),
/* if your "members" field contains the full DN and needs to be
* truncated to just the uid */
// 'group_member_dnfix' => true,
/** used to set default value for all users, will be overcharged by
* ldap if defined also in mapping_field **/
// 'default_value' => array(

View File

@ -650,6 +650,11 @@ function sync_LDAP_groups(){
$user_mapping = $c->authenticate_hook['config']['mapping_field'];
}
// Used if the group members are DNs and we need to do LDAP lookups.
$query = $ldapDriver->ldap_query_one;
$username_ldap_attribute = $user_mapping['username'];
$filter = $ldapDriver->filterUsers;
foreach ( $groups_to_sync_members as $group ) {
$db_members = isset($db_group_members[$group])
&& is_array($db_group_members[$group])
@ -659,31 +664,43 @@ function sync_LDAP_groups(){
? array_values ( $ldap_groups_info[$group][$member_field] )
: array();
if (isset($c->authenticate_hook['config']['group_match_username_attr'])
&& isset($user_mapping['username'])) {
$query = $ldapDriver->ldap_query_one;
$username_ldap_attribute = $user_mapping['username'];
$ldap_members_tmp = array();
$filter = $ldapDriver->filterUsers();
foreach ( $ldap_members as $member ) {
if (isset($user_mapping['username'])
&& preg_match('/=/', $member)) {
// The member from LDAP has an = in it, assume it is a DN.
$ldap_members_tmp = array();
if (preg_match("/^$username_ldap_attribute=/", $member)) {
// If the member record starts with the mapping field, we
// don't need to fetch from LDAP. Win.
foreach ( $ldap_members as $member ){
$entry = ldap_read($ldapDriver->connect, $member, $filter,
array($username_ldap_attribute));
$ldap_user_entry
= ldap_first_entry($ldapDriver->connect,$entry);
$ldap_user_attributes
= ldap_get_attributes($ldapDriver->connect, $ldap_user_entry);
$ldap_members_tmp[] = ldap_explode_dn($member,1)[0];
array_push($ldap_members_tmp,
$ldap_user_attributes[$username_ldap_attribute][0]);
}
} else {
// The attribute isn't at the start of the member name,
// off to LDAP we go.
// NOTE: We could cache all the person records fetched
// in sync_LDAP and use more memory but not need
// anymore trips to LDAP.
$ldap_members = $ldap_members_tmp;
}
else if ( $member_field == 'uniqueMember' || $dnfix ) {
$ldap_members = fix_unique_member( $ldap_members );
$entry = ldap_read($ldapDriver->connect, $member, $filter,
array($username_ldap_attribute));
$ldap_user_entry
= ldap_first_entry($ldapDriver->connect, $entry);
$ldap_user_attributes
= ldap_get_attributes($ldapDriver->connect,
$ldap_user_entry);
$ldap_members_tmp[]
= $ldap_user_attributes[$username_ldap_attribute][0];
}
} else {
// No need to rewrite.
$ldap_members_tmp[] = $member;
}
$ldap_members = $ldap_members_tmp;
}
$add_users = array_diff ( $ldap_members, $db_members );