Posts tagged ‘Zend_Ldap’

Zend_Ldap promoted to standard trunk

After some last modifications to make the original Zend_Ldap tests pass with the new extended Zend_Ldap classes, the ZF teams has promoted the component to the standard trunk.

I assume that we’ll have a public release of the code with the 1.9 version of Zend Framework.

July 10, 2009 at 09:46 5 comments

Extended Zend_Ldap passes penultimate hurdle

After Ralph Schindler (member of the Zend Technologies Zend Framework team) reviewed my Zend_Ldap extensions and successfully ran all unit tests, the last hurdle the component has to pass is the documentation. Currently the documentation is somewhat rudimentary but I think we’ll get the docs ready until the 1.9-release.

It’s been a long way for this component but at last I think we can have a GO for moving the component to trunk shortly.

July 9, 2009 at 12:08 Leave a comment

How to use the new Zend_Ldap functionality

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.

December 7, 2008 at 20:57 5 comments

Extended Zend_Ldap is in Standard Incubator

Zend Framework Logo (small)

After beeing accepted for Standard Incubator development by the Zend Framework team on November, 1st 2008, the extended Zend_Ldap component (formerly known as Zend_Ldap_Ext) has been moved into the Zend Framework Standard Incubator and can be checked out from there.

This is what the component is all about (from the proposal page):

The existing Zend_Ldap component currently just responds to authentication use cases in all their varieties. There is no posibility to query a LDAP directory service in a unified and consistent way. The current component also lacks core CRUD (Create, Retrieve, Update and Delete) functionality – operations that are crucial to for example database abstraction layers.
This proposals tries to resolve these deficiencies in that it provides a simple two-ply object oriented model to connect to, query and perfom CRUD operations on an LDAP server. The first layer is a wrapper around the ext/ldap functions, spiced up with extended functionality such as copying and moving (renaming in a LDAP context) nodes and subtrees.
The second layer (Zend_Ldap_Node) provides an active-record-like interface to LDAP entries and stresses the tree-structure of LDAP data in providing (recursive) tree traversal methods.
To simplify the usage of the unfamiliar LDAP filter syntax this components proposes an object oriented approach to LDAP filter string generation, which can loosely be compared to Zend_Db_Select.
Usefull helper classes for creating and modifying LDAP DNs and converting attribute values complete this component.
Furthermore it is possible to do some LDAP schema browsing and to read and write LDIF files.
It is important to note, that this proposal is a complete replacement for the current Zend_Ldap component and does not break backwards-compatibility.

Later today I’ll try to publish a short tutorial on the usage of the (hopefully) new Zend_Ldap component.

December 7, 2008 at 16:50 1 comment

Zend_Ldap_Ext proposal updated

Yesterday I updated the proposal wiki page for my Zend_Ldap_Ext proposal to be compliant with the current source. Currently there seems to be not that much interest in an extended Zend_Ldap component but in my opinion the framework should include such a component to allow for simple data exchange with LDAP servers the same way it provides means to talk to databases and webservices.

The proposals originates from my need for a unified data access layer to an LDAP server in my current project. The proposal features:

  • querying the LDAP server
  • retrieving LDAP entries
  • creating LDAP entries
  • updating LDAP entries
  • deleting LDAP entries
  • LDAP filter string creation
  • tree traversal methods
  • other stuff like attribute en- and decoding

Some parts of the proposal are inspired by the brilliant PEAR:Net_LDAP2 package.

I think LDAP usage should be as easy as querying a database and the current ext/ldap with its three different resource types is predestined for beeing wrapped up in an object oriented interface. Just take the following examples:

ext/ldap

$ds=ldap_connect("localhost");
ldap_bind($ds);
$sr=ldap_search($ds, "o=My Company, c=US", "sn=S*");
$info=ldap_get_entries($ds, $sr); // result is buffered on the machine
for ($i=0; $i<$info["count"]; $i++) {
    echo "dn is: " . $info[$i]["dn"] . "<br />";
    echo "first cn entry is: " . $info[$i]["cn"][0] . "<br />";
    echo "first email entry is: " . $info[$i]["mail"][0] . "<br /><hr />";
}
ldap_free_result($sr);
ldap_close($ds);

Zend_Ldap with ext/ldap

$ldap=new Zend_Ldap(array(/* options */));
$ldap->bind();
$sr=ldap_search($ldap->getResource(), "o=My Company, c=US", "sn=S*");
$info=ldap_get_entries($ldap->getResource(), $sr); // result is buffered on the machine
for ($i=0; $i<$info["count"]; $i++) {
    echo "dn is: " . $info[$i]["dn"] . "<br />";
    echo "first cn entry is: " . $info[$i]["cn"][0] . "<br />";
    echo "first email entry is: " . $info[$i]["mail"][0] . "<br /><hr />";
}
ldap_free_result($sr);
$ldap->disconnect();

Zend_Ldap_Ext

$ldap=new Zend_Ldap_Ext(array(/* options */));
$ldap->bind();
foreach ($ldap->search("sn=S*") as $item) { // items will be fetched from the LDAP when needed
    echo "dn is: " . $item["dn"] . "<br />";
    echo "first cn entry is: " . $item["cn"][0] . "<br />";
    echo "first email entry is: " . $item["mail"][0] . "<br /><hr />";
}
$ldap->disconnect();

This is just a simple example… But think of moving or copying complete subtrees, renaming entries, traversing the tree recursively and so on. Furthermore there are some common pitfalls with escaping values in filter strings and escaping DN values. My aim is to develop Zend_Ldap_Ext so that it addresses the most common workflows when dealing with LDAP servers.

August 11, 2008 at 11:18 2 comments


Twitter

  • Docker for Mac 17.04 adds flags that speed up file sharing 3x or more on common workloads. blog.docker.com/2017/05/user-g… via @docker 2 weeks ago
  • RT @t73fde: "Premature optimization is the root of all evil (after shared memory and mutable state)" 2 weeks ago
  • RT @mathiasverraes: How to interview a domain expert? - Is this always true? - Yes - Always? - Yes - Always? - Yes - Always? - Yes - Always… 1 month ago
  • RT @nikita_ppv: Some graphs comparing memory usage of arrays and objects (with declared properties) in PHP 7. Arrays need between 2x and 6x… 1 month ago
  • @dsci_ Sehr historisches Datenbankschema 🙄Damals gab's noch nicht so viele Spieler und schon gar keine mit dem selben Name. 😉 2 months ago

del.icio.us

Certification