LDAP Pike objects


This document discusses the following topics:

© Honza Petrous, v1.3



Description

This module allows Pike programmers to access and manipulate an LDAP based Directory. Module enables two new objects Protocols.LDAP.client and Protocols.LDAP.client.result for using it in LDAP-related calculatings.

Current version 1.5 supports the main subset of client operations version 2 LDAP protocol with one exception in search filter - parser don't understand escaped characters. This will be corrected in the next version.


Initial conection

All connection to the LDAP server are started by creating a new object in the Protocols.LDAP.client class. This can be done quite easily by the following type of statement:
	> object ld = Protocols.LDAP.client("ldap.company.com");
	
Where argument is the name of your LDAP server. If you are not using the standard LDAP port (389), you will also need to suply the portnumber:
	> object ld = Protocols.LDAP.client("ldap.company.com:9999");
	


Binding

After creating a connection to the LDAP server, you will always need to bind to the server(1) prior to performing any LDAP related operations. This can be done with the bind method.

As anonymous bind can be performed without arguments:

	> int status = ld->bind();
	
A simple bind can be performed by specifying the distingished name (DN) and password of the user you are authenticating as:
	> status = ld->bind("cn=Directory Admin, o=UniBASE Ltd., c=CZ", "password");
	
Note that if "password" above was "", you would be doing a reference bind, which would return success even if the password in the directory was not empty. Thus if you were using the bind to check a password entered with one in the directory, you should first check to see if password was null.

SECURITY ALERT: Current version supported only simple bind operation with clear text password.

(1) - This is true for version 2 LDAP protocol.

Delete operation

The delete operation is used to delete DN.
	> status = ld->delete("cn=Honza Petrous, o=UniBASE Ltd., c=CZ");
	


Compare operation

The compare operation is used to compare single attribute value for DN.
	> status = ld->compare("cn=Honza Petrous, o=UniBASE Ltd., c=CZ",
			       ({"mail", "hop@unibase.cz"}));
	
Status value returned by this method is LDAP_COMPARE_TRUE (5) or LDAP_COMPARE_FALSE (6).


Search operation

The search operation is used for retrieving attribute and its values for entries specified in search filter.
	> object rv = ld->search("(|(objectclass=person)(mail))");
	
Statesment above performs LDAP search. Returns an object, if operations ended successfully otherwise negative integer value. Argument is a string containing an LDAP search filter.
You can restrict attributes returned by search:
	> rv = ld->search("(|(objectclass=person)(mail))",
			  ({"mail", "telephonenumber", "sn"}));
	
Second argument is array of attribute names you need.
You also can restrict returned attributes name only:
	> rv = ld->search("(|(objectclass=person)(mail))",
			  ({"mail", "telephonenumber", "sn"}), 1);
	
Third argument can be '1' if you can returned attributes name only.


Add operation

The add operation is used to insert new entry to the LDAP server.
	> status = ld->add("cn=Akos Varga, o=UniBASE Ltd., c=CZ",
			   (["objectclass":({"top", "person"}),
			     "mail":({"Akos.Varga@unibase.cz"})]);
	
First argument is DN of new entry. Second argument is an attribute values of entry. This is mapping(string:array(string)) object.

Note that in most cases, you will need to be bound to the LDAP server as an administrator in order to add entries.


Error values

Most methods returns integer value as status of operation. There are three groups of values:
  1. greater or equal to 0
    This values are regular LDAP code errors. You can access error code and its aproppriate string representations anytime you want by the following methods:
    	    > status = ld->error_code();
    	    > string strstat = ld->error_string();
    	    
  2. less then 0
    This codes are returned on internal error.

Session options

The methods get_option and set_option can be used to get and set LDAP session options.

The following LDAP options can be set or gotten whith these methods:

	LDAP_OPT_DEREF (1)	- Dereference
	LDAP_OPT_SIZELIMIT (2)	- Maximum number of entries to return
	LDAP_OPT_TIMELIMIT (3)	- Timeout for LDAP operations
	LDAP_OPT_REFERRALS (4)	- Follow referrals (unimplemented)
	
For both get and set operations, the first argument is the relevant option. In set, the second argument is the value at which to set this option. Examples:
	> status = ld->set_option(LDAP_OPT_SIZELIMIT, 20);
	> int size = ld->get_option(LDAP_OPT_SIZELIMIT);
	


Obtaining results

Search operation returns object of type Protocols.LDAP.client.result if successful. This object contains all LDAP messages returned from LDAP server (i.e. entries and result). All entries in object are linked to the chain. You can access entries sequencelly or directly.

Example:

Walking through all entries sequencelly:

	object rv = search("(objectclass=person)");
	do {
	  print(sprintf("%d. %s <%s>\n", rv->num_entries() - rv->count_entries(),
					 rv->fetch()["dn"][0],
					 rv->fetch()["mail"][0]));
	} while (rv->next());
	
The same but with direct access:
	object rv = search("(objectclass=person)");
	for(int ix=1; ixnum_entries(); ix++) {
	  print(sprintf("%d. %s <%s>\n", ix,
					 rv->fetch(ix)["dn"][0],
					 rv->fetch(ix)["mail"][0]));
	}
	
As you can see, method fetch is used for getting entry. This method returns mapping(string:array(string)) for entry.