Forums / Developer / contrib : ldap group mappings

contrib : ldap group mappings

Author Message

Artturi Markko

Saturday 13 May 2006 6:26:03 am

Hello,

I have set up EzPublish with ldap authentication and I had to map existing ldap groups to the groups I have created in Ez.
From what I've read in the forums, mappings can only be achieved by retrieving an attribute on the ldap user object (employeetype is mentionned).

In consequence, I have written a small piece of code in kernel/classes/datatypes/ezuser/ezldapuser.php in order to retrieve the group memberships of the user who logs in.
<b>With the mappings defined in ldap.ini, this code fills the $extraNodeAssignments variable</b>.

<i>The contrib is in three parts</i> :
- additionnal settings in ldap.ini
- a recursive function that looks for groups (it's recursive to handle the case of nested groups). This function is placed outside of the "eZLDAPUser" class.
- a call to this function in the "loginUser" method of "eZLDAPUser" class

First, here is what I've added in ldap.ini :

LDAPUserGroupAM[]
LDAPUserGroupAM[]=ldapgroup1--ezgroup1
LDAPUserGroupAM[]=ldapgroup2--ezgrp2

Here's the function :

function mapInEzGroups($filter, $LDAPBaseDN, &$ds, &$db, &$ldap2ez, &$extraNodeAssignments, $depth = 0)
{
    $retrieve = array("cn");  // that's the groups name
    $sr2 = ldap_search( $ds, $LDAPBaseDN, $filter, $retrieve );
    $info2 = ldap_get_entries( $ds, $sr2 );       
                           
    $newfilter = '(&(objectClass=group)(|'; 
    $max = count($info2);

    // I loop on the found groups and check if I have a mapping defined for it
    for ( $i = 0; $i < $max; $i++ )
    {
        if ( is_null( $info2[ $i ] ) ) continue;
        $ldapGroupName = $info2[$i]['cn'][0];
        if ( array_key_exists($ldapGroupName, $ldap2ez) ) // is there a mapping ? --> ldap2ez holds the mappings
        {
            $groupName = $ldap2ez[$ldapGroupName];
            $groupQuery = "SELECT ezcontentobject_tree.node_id
                             FROM ezcontentobject, ezcontentobject_tree
                            WHERE ezcontentobject.name like '$groupName'
                              AND ezcontentobject.id=ezcontentobject_tree.contentobject_id
                              AND ezcontentobject.contentclass_id=3";
            $groupObject = $db->arrayQuery( $groupQuery );

            if ( count( $groupObject ) > 0 )
            {
                $extraNodeAssignments[] = $groupObject[0]['node_id'];
            }
        }        
        $newfilter .= '(member=' . $info2[$i]['dn']  . ')';                        
    }

    // If groups are found, I also check if they are nested in other groups, limited to a depth of 30
    if ( $depth < 30 && $max > 0 )
    {    
        $newfilter .= '))';
        mapInEzGroups($newfilter, $LDAPBaseDN, $ds, $db, $ldap2ez, $extraNodeAssignments, ( $depth + 1));
    }    
}

And in the "eZLDAPUser" class :

$LDAPUserGroupAML = $LDAPIni->variable( 'LDAPSettings', 'LDAPUserGroupAML' );

// ...

// ** existing code, just to show where it happens ***//
                // authenticated user
                if  ( !@ldap_bind( $ds, $info[0]['dn'], $password ) )
                {
                    $user = false;
                    return $user;
                }

// ** added code follows :            
                if ( $LDAPUserGroupAM != null )
                {
                    foreach ( $LDAPUserGroupAM as $value)
                    {
                        $r = explode("--", $value);
                        $ldap2ez[$r[0]] = $r[1];                        
                    }
                    // filter looking for groups the user is member of
                    $filter = "(&(objectClass=group)(member=" . $info[0]['dn'] . "))";

                    // this function fills the $extraNodeAssignments variable
                    mapInEzGroups($filter, $LDAPBaseDN, $ds, $db, $ldap2ez, $extraNodeAssignments);
                }

Artturi

Artturi Markko

Saturday 13 May 2006 6:37:56 am

Just a note to mention that while I've tested this code, I would welcome some critics about it.

There's also a catch about how it works in this form :
- upon user creation, mappings are done as I expect
- <b>if user exists in EZ before a mapping is created</b>, this mapping won't apply

This is due to the fact that $extraNodeAssignments is not used when user is updated. It is only used when user is created.
Would somebody know how to improve that because I'm a total newbie in Ez developpment and can't see how to do that ?

Best regards,

Artturi

Artturi Markko

Sunday 14 May 2006 3:38:47 am

Reply to myself : I've found that an existing cronjob script is in charge of the update :

cronjobs/ldapusermanage.php

However, things are not 100% ok for me as group removal does not work as I expect.
If interested, see this post :
http://ez.no/community/forum/developer/node_group_assignment_how_to_remove_correctly

Regards,

Artturi