Overview of Filter Scripts

Introduction

When you want to find particular entries on a LDAP server, you are using a LDAP search filter. For example, you can find all users that have no mail attribute with the filter below:

(&(objectClass=inetOrgPerson)(!(mail=*)))

Although the LDAP search filter is a powerful tool, sometimes it is not possible or too complicated to get by only with it, without resorting to a procedural logic. For example, you make a request and, knowing that the result is incomplete, you issue another request based on the result of the first request. You can achieve this with a script.

How it works

The Data View contains the results of a LDAP search for a specified entry.

Searched entry and results

The View specifies the LDAP filter, which attributes are shown in the Data View, their order and sort order.

LDAP filter attributes

You can further control which results are shown in the Data View by enabling the script under the Script Filter tab.

LDAP script

The order of execution with the script enabled is as follows:

  1. The search defined under the LDAP Filter tab is performed.
  2. You can enumerate the entries returned from the server and perform some additional action, e.g. exclude some entries from the result set or extend the result set by querying the server.
  3. The result set is shown in the Data View.

Scripting Features

Here is the list of the most important features:

  • Procedural extension of the LDAP searches
  • Concise API for LDAP searches, emailing and working with the file system
  • Categorized logging
  • Colorized script editor
  • COM support
  • Easy C-Java-JavaScript-like syntax
  • Exception handling

Script features

Example: Descendant Members of a Group

Suppose you need to find and visualize all descendant members of a group, i.e. all members of the searched group, the members of each group that is the member of the searched group and so on.

On the below screenshot, group Main Group contains two groups, the later contains users.

LDAP groups

If we type in Main Group in the String to Search text box in the Quick Search panel, the list of entries in the grid is expectedly limited to one group.

LDAP groups with LDAP filter

Now let us create a script that uses the content of the String to Search text box as the input field. The script should find all members of group identified with cn, which we can specify in the text box, and then find all other member recursively. You can specify the script or open it directly from the file system under the Script Filter tab in the View Properties window.

LDAP script

NOTE: Several sample scripts come with the installer and available under the following path:

%appdata%\..\Local\Userbooster\FilterScripts\Samples

Here is the content of the script:

function main() {
    var searchedGroupCn = ub.SearchInputText;
   
    if(searchedGroupCn == ""){
    	UbLogWarning << "The \"String to Search is empty.  It should contain the cn of the searched group.\"";
    	return;
    }

    try{
   	    var groupEntry = ub.DefaultEnumeration.Next();
    	if(groupEntry.IsEmpty || groupEntry["cn"].size() == 0 || groupEntry["cn"][0] !=  searchedGroupCn){
    		UbLogWarning << "The group with cn=\"" + searchedGroupCn + "\" not found.";
    		return;
    	}
    	findDescendentMemebersOfGroup(groupEntry);
    }
    catch(e){
    	UbLogError << e;
    }    
 }

function findDescendentMemebersOfGroup(groupEntry){
    
    UbLogInformation << "Members of \"" + groupEntry["dn"][0] + "\"";
    var members = groupEntry["member"], i;
    for(i = 0; i < members.size(); i++){
    	var dn = members[i];
    	var entry = GetEntry(dn);
    	if(entry.IsEmpty){
    		UbLogWarning << "Dn not found. " + dn;
    		continue;
    	}
    		
    	entry.PushToResponse();

    	UbLogInformation << "===" + entry["dn"][0];
	    if(IsGroup(entry))
    		findDescendentMemebersOfGroup(entry);

    }
}

function IsGroup(entry) {
	var objectClasses = entry["objectClass"],i;
	for(i = 0; i < objectClasses.size(); i++){
		if(objectClasses[i] == "groupOfNames")
			return true;
	}
	return false;
}

function GetEntry(entryDn){
    var enumeration = ub.ConnectionManager.Query( entryDn, "(objectClass=*)", "Base" );
	return enumeration.Next();
}

The highlights of the script are as follows:

  • The script should always contains function main () as an entry point.
  • var groupEntry = ub.DefaultEnumeration.Next(); returns the next entry of the enumeration specified by the LDAP filter, which in our sample is (|(objectClass=group)(objectClass=groupOfNames)).
  • groupEntry.IsEmpty indicates that there is no more enumerated entries;
  • ub.ConnectionManager.Query( entryDn, “(objectClass=*)”, “Base” ); allows you to perform a LDAP search, with three parameters: dn, LDAP filter definition and search scope;
  • entry.PushToResponse() visualizes the enumerated entry.

As a result, all descendent members are listed in the Data View.

Results of the LDAP script