Question

I'm using InMemoryDirectoryServer from UnboundID SDK. How do I process ldap requests from ldap client?

Here's code I found (at How to get DN and password with UnboundID):

public class MyLDAPListenerRequestHandler extends LDAPListenerRequestHandler {

@Override
public LDAPListenerRequestHandler newInstance(
        LDAPListenerClientConnection arg0) throws LDAPException {
        System.out.println("New Instance.");
        LDAPConnectionOptions option = new LDAPConnectionOptions();
        LDAPConnection connection = new LDAPConnection(option, "yourIPadress", yourport);
        System.out.println("Connected to : " + connection.getConnectedAddress()+ " " + connection.getConnectedPort());

    return this;
}

@Override
public LDAPMessage processBindRequest(int arg0, BindRequestProtocolOp arg1,
        List<Control> arg2) {
    System.out.println(arg1.getBindDN());
    System.out.println(arg1.getSimplePassword());
    return null;
}

Is this a proper way to capture bind reqest and process it under

public LDAPMessage processBindRequest(int arg0, BindRequestProtocolOp arg1,
        List<Control> arg2) {

function? After processing, do I have to manually send bind to InMemoryDirectoryServer instance?

Hi again,

based on: http://sourceforge.net/p/ldap-sdk/discussion/1001257/thread/796c129d

it looks to me that it is possible to modify InMemoryRequestHandler source and change how it replies ldap requests (search,modify,...).

For alias dereferencing, I modified

for (final SearchResultEntry e : entryList)

loop in function:

public synchronized LDAPMessage processSearchRequest(final int messageID, final SearchRequestProtocolOp request, final List controls) {

with this code:

for (final SearchResultEntry e : entryList)
{

    // flag which is set if for loop finds an alias entry.
    boolean aliasEntryFound = false;
    // aliasedObjectName reference to real entry.
    String aliasedObjectName = null;

    // Check that dereferencing is turned on.
    if (aliasDeref)
    {            
        // check if entry is an alias entry. 
        for (String objectClass : e.getAttributeValues("objectClass"))
        {
            if (objectClass.equalsIgnoreCase("alias"))
            {
                // Put on flag.
                aliasEntryFound = true;                    
                // Get real entry path. 
                aliasedObjectName = e.getAttributeValue("aliasedObjectName");

            }
        }

    }

    // If entry e is actually alias entry, then ...
    if (aliasEntryFound && aliasedObjectName != null)
    {
        // Build new SearchRequest query with aliasedObjectName as real DN.
        final SearchRequestProtocolOp newRequest = new SearchRequestProtocolOp(
                aliasedObjectName, request.getScope(), request.getDerefPolicy(),
                request.getSizeLimit(), request.getTimeLimit(),
                false, request.getFilter(), request.getAttributes());
        // Call recursively processSearchRequest() with new request value.
        processSearchRequest(messageID, newRequest, controls);

    }
    else
    {
            try {
                connection.sendSearchResultEntry(messageID, e, e.getControls());
            } catch (final LDAPException le) {
                Debug.debugException(le);
                return new LDAPMessage(messageID, new SearchResultDoneProtocolOp(le.getResultCode().intValue(), le.getMatchedDN(),
                        le.getDiagnosticMessage(), StaticUtils.toList(le.getReferralURLs())), le.getResponseControls());
            }
    }
}
...
}

Somewhere at the beginning of InMemoryRequestHandler class, I added:

private boolean aliasDeref = true;

which I just use as a flag to control if I want alias dereferencing or not.

My code is just an example how to do alias dereferencing on search request. With custom request handler, it is possible only to alert ldap requests, not ldap replies or results.

Let me know if there is a better way of doing this. thanks

Was it helpful?

Solution

The UnboundID LDAP SDK for Java provides an LDAPListener framework that allows you to create your own code that accepts LDAP requests from clients and can provide responses back to them. When the LDAPListener receives a request, it uses an LDAPListenerRequestHandler to process the request and generate the result.

The in-memory directory server uses the InMemoryRequestHandler to perform this processing, but you can create your own request handler implementation that does whatever you want (e.g., the CannedResponseRequestHandler bindly returns a fixed response to any request), and you can have a request handler that does some processing before delegating to another request handler (e.g., the AccessLogRequestHandler and LDAPDebuggerRequestHandler implementations intercept requests and write information about them to a log file before forwarding them on to another request handler, and then intercepts and logs information about the response before returning it back to the client; conversely, the ProxyRequestHandler does the processing to another directory server over LDAP).

If you want to provide custom processing, then you should create your own LDAPListenerRequestHandler subclass (and as you assumed, the processBindRequest method can be used to perform the processing for a bind operation). If that request handler does all the processing for the operation, then you can create and return the response yourself. If you just need to intercept the request and capture information about it before forwarding it on to something else that will really perform the processing, then you should delegate to another request handler. There are examples of both of those already in the LDAP SDK, so you can use them as a model to create what you need.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top