How to use the new Zend_Ldap functionality

December 7, 2008 at 20:57 5 comments

Zend Framework Logo (small)The following post should demonstrate some of the new features that come along with the extended Zend_Ldap component that is now available in the Zend Framework Standard Incubator. The component was originally designed to augment the current Zend_Ldap component with methods to do all those operations on a LDAP server which everybody is used to when dealing with databases: searching, retrieving, updating, adding and deleting items on the directory server. The component has recently been accepted for Standard Incubator development with the notice to explore the possibility of a migration of all new features directly into the existing Zend_Ldap class. This has been achieved and the component can be considered an all out solution for working with LDAP directory servers which naturally means that there is still a lot of room for improvement. The transition from the authentication-only Zend_Ldap to a fully featured data-access component flowed smoothly and backwards-compatibility could be maintained (at least when connecting to OpenLDAP servers as I don’t have any other LDAP server at hand to run regression tests against). Enough of that blah, let’s have a look at the new features…

Connecting to a LDAP server

There is no change from the old Zend_Ldap – provide the options to connect to the server and call bind().

$options = array(
    'host'     => 'localhost',
    'port'     => 389,
    'username' => 'uid=php,ou=People,dc=zend,dc=com',
    'password' => 'password',
    'baseDn'   => 'dc=zend,dc=com'
);
$ldap=new Zend_Ldap($options);
$ldap->bind();

Retrieving a single entry

To retrieve a single entry from the server you use the getEntry() method.

$carl = $ldap->getEntry('cn=Carl Baker,ou=People,dc=zend,dc=com');
/*
 * $carl is an array containing
 * array(
 *    'dn'          => 'cn=Carl Baker,ou=People,dc=zend,dc=com',
 *    'cn'          => array('Carl Baker'),
 *    'givenname'   => array('Carl'),
 *    'objectclass' => array('account', 'inetOrgPerson', 'top'),
 *    'sn'          => array('Baker'),
 *    'title'       => array('PR Manager'),
 *    'uid'         => array('cbaker'),
 *    ...);
 */

Searching entries

You can retrieve a list of entries that match a given LDAP filter by using the search() method.

$items=$ldap()->search('(objectClass=account)', 'ou=People,dc=zend,dc=com',
    Zend_Ldap::SEARCH_SCOPE_ONE);
// $items is an object of type Zend_Ldap_Collection
$count=count($items); // the returned object implements Countable
foreach ($items as $item) { // the returned object also implements Iterator
    /*
     * $item is an array containing
     * array(
     *    'dn'          => '...',
     *    'cn'          => array('...'),
     *    'givenname'   => array('...'),
     *    'objectclass' => array('account', 'inetOrgPerson', 'top'),
     *    'sn'          => array('...'),
     *    'title'       => array('...'),
     *    'uid'         => array('...'),
     *    ...);
     */
}
// alternatively you can use searchEntries() to get back an array of entries
$items=$ldap()->searchEntries('(objectClass=account)', 'ou=People,dc=zend,dc=com',
    Zend_Ldap::SEARCH_SCOPE_ONE);
// $items is an object of type array

Searching entries with filter objects

Instead of using a filter string you can create your filter with the object-oriented interface of Zend_Ldap_Filter.

$filter=Zend_Ldap_Filter::equals('objectClass', 'account')
    ->addAnd(Zend_Ldap_Filter::greater('salary', 10000));
$items=$ldap()->search($filter, 'ou=People,dc=zend,dc=com',
    Zend_Ldap::SEARCH_SCOPE_ONE);

Manipulating DN string

DN strings can be parsed into Zend_Ldap_DN objects which allow for easy modifiation of the DN.

$dnString='cn=Baker\\, Alice,cn=Users+ou=Lab,ou=People,dc=zend,dc=com';
$dn=Zend_Ldap_Dn::fromString($dnString);
unset($dn[2];
$dn[1]=array('cn' => 'Users', 'ou' => 'PR');
$dn->insert(1, array('ou' => 'Dismissed'));
$dnString=(string)$dn;
// cn=Baker\\, Alice,cn=Users+ou=PR,ou=Dismissed,dc=zend,dc=com

Adding new entries

Zend_Ldap provides an add() method to add entries to the directory.

$ldap->add('uid=created,ou=People,dc=zend,dc=com', array(
    'uid'         => 'created',
    'objectClass' => 'account'));

Updating existing entries

The update() method can be used to update existing entries in the directory.

$ldap->update('cn=Carl Baker,ou=People,dc=zend,dc=com', array(
    'title' => array('Barkeeper'),
    'uid'   => 'cabaker');
// it's enough to provide those attributes that will be changed

Deleting entries

Deletions can be done recursively when providing true as the second parameter.

// this will throw an exception if the given entry has subordinates
$ldap->delete('cn=Baker\\, Alice,cn=Users+ou=Lab,ou=People,dc=zend,dc=com', false);
// this will delete the complete subtree
$ldap->delete('ou=Dismissed,dc=zend,dc=com', true);

Copying and moving entries and subtrees

Zend_Ldap provides methods to move and copy entries and subtrees to other locations within the directory tree. The third parameter specifies if the operation will be carried ou recursively.

// this will throw an exception if the given entry has subordinates
$ldap->copy('cn=Baker\\, Alice,cn=Users+ou=Lab,ou=People,dc=zend,dc=com',
    'cn=Baker\\, Charlie,ou=Lab,ou=People,dc=zend,dc=com', false);
// the operation will be done recursively
$ldap->move('ou=Dismissed,dc=zend,dc=com', 'ou=Fired,dc=zend,dc=com', true);

There is a lot more to be discovered in Zend_Ldap such as checking server capabilities via the RootDSE, browsing the schema using the subSchemaSubentry, LDIF im- and exporting and especially the active-record like interface to LDAP entries Zend_Ldap_Node which we’ll cover in the next post.

I hope this post has provided some insight into the features of Zend_Ldap and you’re invited to try and test the new features and give your feedback to further improve the component and get it into production, which means into the standard trunk, as soon as possible. Especially I’m in search for testers who can verify the working of this component against the different LDAP servers available: e.g. ActiveDirectory, ADAM, Siemens, Novell, Sun, and so on.

About these ads

Entry filed under: Zend Framework. Tags: , .

Extended Zend_Ldap is in Standard Incubator Update on strcoll() UTF-8 issue

5 Comments Add your own

  • 1. brad lackey  |  May 22, 2009 at 00:55

    I am currently attempting to use the ldap->add() method and i am providing all of the required options, now i am receiving a “Message: 0×32 (Insufficient access; no write access to parent): adding: cn=slackey,ou=People,dc=nodomain ” error message, has anyone experienced this, fixed this?

    Reply
    • 2. Stefan Gehrig  |  May 22, 2009 at 08:27

      This actually looks like an ACL-restriction on the server. Please make sure, that the user you’re binding has the required rights to add the entry. Adding an entry requires write-access to the parent node.

      Reply
      • 3. bradley lackey  |  May 22, 2009 at 23:02

        Any idea how to enable write permissions on the parent node? im using ubuntu 9.04 and the slapd.conf file is now gone. i have two posix groups and many posix accounts and depending upon which group the user is assigned to i (Admin group or Limited group) should determine their write permissions… ideas?

      • 4. Stefan Gehrig  |  May 26, 2009 at 10:30

        Please see http://www.openldap.org/doc/admin24/slapdconf2.html for information about the new configuration system of OpenLDAP (configuration settings are now stored in the LDAP tree itself which allows for runtime modification of some settings). Access control is documented in http://www.openldap.org/doc/admin24/access-control.html – please see especially http://www.openldap.org/doc/admin24/access-control.html#Access Control via Dynamic Configuration

  • 5. brad lackey  |  May 22, 2009 at 03:17

    wanted to comment and say, MAKE SURE YOUR BIND IS WITH A USER THAT HAS RIGHTS! ;)

    Reply

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Trackback this post  |  Subscribe to the comments via RSS Feed


Current articles

Twitter

  • RT @_md: Symfony is such an asset for the PHP community. Thank you Symfony developers for your amazing contribution! 3 weeks ago
  • RT @CompSciFact: 'The purpose of abstraction is not to be vague, but to create a new semantic level in which one can be absolutely precise'… 1 month ago
  • @DB_Bahn Gibt es dafür ein Formular oder wie funktioniert das? 1 month ago
  • @DB_Bahn Auch dann, wenn ich mit dem Privat-PKW fahren muss? 1 month ago
  • @DB_Bahn und wer bezahlt mit jetzt das Taxi nach Heilbronn? 1 month ago

del.icio.us

Certification


Follow

Get every new post delivered to your Inbox.

%d bloggers like this: