The LDAP functions allow you to connect to an LDAP, using anonymous or simple authentication, and modify and delete entries or perform searches based on names, and filters, and explicitly define what attributes to be returned. The LDAP functions use connection pooling for best performance.
Note
title
Note!
Due to the nature of LDAP, the following functions are not transaction safe and should therefore be used mainly for realtime workflows.
All functions except ldapCreate are asynchronous in nature. The ldapCreate function is recommended to be called from the initialized block and the returned value to be stored in a global variable.
LDAP Related UDR Type
The UDR type created by default in the LDAP agent can be viewed in the UDR Internal Format Browser. To open the browser open an APL Editor, in the editing area right-click and select UDR Assistance...; the browser opens.
...
If this is not desired behavior, it is possible to set these LDAP functions to suppress all communication errors and instead return null in error situations. In this case, the error will be made available through the ldapGetLastError function.
...
Set the property in the cell.conf or the relevant Execution Context <pico>.conf, depending on where where where the workflow is executed.
Idle Connection Timeout
By default a connection remains within a pool in an idle state for five minutes before it is closed. To set the amount of time in milliseconds, set the property com.sun.jndi.ldap.connect.pool.timeout in the cell.conf or the relevant Execution Context <pico>.conf, depending on where the workflow is executed.
ldapCreate
Creates a connection towards an LDAP server, using either anonymous or simple authentication. This function is usually invoked in the initialize block.
...
Info
title
Example - LDAP APL Plugins
Code Block
// Demonstration of LDAP APL plugin functions
// The following code shows the following:
//
// 1) How to open a LDAP connection
// 2) How to add/delete an object to/from LDAP
// 3) How to change objects properties
// 4) How to perform different type of searches
void runDemoCode() {
any ctx;
string name = "DEMOUSER";
string distinguisedName = "cn="+name;
string error;
list<string> attributes;
list<ldapResult> result;
// ==============================================
// Opens a connection to a LDAP Server
// ==============================================
ctx = ldapCreate("127.0.0.1", 389, "dc=nodomain",
"cn=admin,dc=nodomain", "demo");
// ==============================================
// Adding/Deleting/Modifying an LDAP Object
// ==============================================
//
//Adds a new person object to the LDAP Server
//
attributes = listCreate(string);
listAdd(attributes, "cn: "+name);
listAdd(attributes, "objectClass: top");
listAdd(attributes, "objectClass: person");
listAdd(attributes, "sn: Test");
listAdd(attributes, "description: Test Record");
listAdd(attributes, "userPassword: {crypt}rkM1sTbxrERtE");
error = ldapAdd(ctx, distinguisedName, attributes);
if( error != null ) {
debug("Error creating user: "+error);
}
//
//Changes description for the created person object
//
attributes = listCreate(string);
listAdd(attributes, "description: A demo user");
error = ldapModify(ctx, distinguisedName, "REPLACE",
attributes);
if( error != null ) {
debug("Error changing user description: "+error);
}
//
//Removes user description from our person object
//
attributes = listCreate(string);
listAdd(attributes, "description: A demo user");
error = ldapModify(ctx, distinguisedName, "REMOVE",
attributes);
if( error != null ) {
debug("Error removing user description: "+error);
}
//
//Adds user description to our person object
//
attributes = listCreate(string);
listAdd(attributes, "description: a description line");
error = ldapModify(ctx, distinguisedName, "ADD",
attributes);
if( error != null ) {
debug("Error adding user description: "+error);
}
//
// Deletes our person object from the LDAP Server
//
error = ldapDelete(ctx, distinguisedName);
if( error != null ) {
debug("Error deleting user: "+error);
}
// ==============================================
// Executing different searches against the LDAP
// ==============================================
// For demo purposes the LDAP tree should contain
// two admin objects (a tree containing a backup
// admin object).
// Setup a filter for the search tests.
// We are interested only in the attribute 'cn'.
//
list<string> attrFilter = listCreate(string);
listAdd(attrFilter, "cn");
//
//Executes a normal search, should return size=1
//
result = ldapSearch(ctx, "dc=test", "cn=admin", attrFilter);
debug("* Normal search");
debug("result size="+listSize(result));
printResultEntries(result);
//
//Scoped Search Types
//
//This search uses OBJECT scope, and should return size=1
// Explanation:
// The search only searches for a specific object, and the
// 'cn' attribute is returned for that object.
//
result = ldapScopeSearch(ctx, "OBJECT_SCOPE", "dc=test",
"cn=admin", attrFilter);
debug("* Object Scope");
debug("result size="+listSize(result));
printResultEntries(result);
//
//This search uses ONELEVEL scope, and should return size=1.
//
// Explanation:
// The search executes a search on a unique level. Two objects
// with the same name can not exists on the same level.
//
result = ldapScopeSearch(ctx, "ONELEVEL_SCOPE", "dc=test",
"cn=admin", attrFilter);
debug("* Onelevel Scope");
debug("result size="+listSize(result));
printResultEntries(result);
//
//This search uses SUBTREE scope, and should return size=2.
//
// Explanation:
// The search execute a search on sublevels, and return a
// match for every admin object found (and we had two).
//
result = ldapScopeSearch(ctx, "SUBTREE_SCOPE", "dc=test",
"cn=admin", attrFilter);
debug("* Subtree Scope");
debug("result size="+listSize(result));
printResultEntries(result);
}
//
// Help method that prints out the result of a ldapSearch
//
void printResultEntries(list <ldapResult> result)
{
int resultIdx = 0;
int resultCount = 0;
int resultSize = listSize(result);
while (resultCount < resultSize) {
ldapResult entry = listGet(result, resultCount);
debug("Name: " + entry.name);
debug("Attribute: " + entry.attribute);
int valueCount = 0;
int valueSize = listSize(entry.values);
while (valueCount < valueSize){
debug("Value: " + listGet(entry.values, valueCount));
valueCount = valueCount + 1;
}
resultCount = resultCount + 1;
}
}