0

I'm trying to use the .net System.DirectoryServices.Protocols libraries to sync against an ApacheDS Ldap server using the LDAP Content Synchronization Control (RFC) so that only changes since the last sync are returned.

My first search request, with no cookie value works fine, and I can get a cookie value out of the search response. But when I make a subsequent search request and try to pass the previous sync cookie, I get a Server Unavailable exception when trying to send the request.

Here are some snippets of the code I'm working with:

static void Main(string[] args)
{
    //LdapConnection, binding, etc removed for brevity

    string contentSynchronizationControlOID = "1.3.6.1.4.1.4203.1.9.1.1";
    string syncDoneControlOID = "1.3.6.1.4.1.4203.1.9.1.3";
    byte[] value = GetSyncControlValue();
    DirectoryControl syncRequestControl = new DirectoryControl(contentSynchronizationControlOID, value, true, true);
    syncRequest.Controls.Add(syncRequestControl);

    SearchResponse syncResponse = (SearchResponse)connection.SendRequest(syncRequest);
    foreach (var responseControl in syncResponse.Controls)
    {
        if (responseControl.Type == syncDoneControlOID)
        {
            SaveSyncControlCookie(responseControl.GetValue());
        }
    }
}


private static byte[] GetSyncControlValue()
{
    byte[] value = null;
    try
    {
        value = File.ReadAllBytes("cookie.bin");
    }
    catch { }

    if (value == null)
    {
        return value; 
    }
    else
    {
        object[] controlParts = new object[] { 1, value, false };
        value = BerConverter.Encode("{iob}", controlParts);
    }

    return value;
}

private static void SaveSyncControlCookie(byte[] value)
{
    byte[] result = null;
    object[] controlParts = BerConverter.Decode("{B}", value);

    result = (byte[])controlParts[0];

    if (result != null)
    {
        File.WriteAllBytes("cookie.bin", result);
    }

}

I've tried with different formats for the BerConverter Encode/Decode methods but haven't had any luck with other combinations.

Community
  • 1
  • 1
Adam
  • 168
  • 5

1 Answers1

0

My issue ended up being the format string when using BerConverter.Encode to create the sync control value which is sent to the ldap server with the search request.

Switching it from "{iob}" to "{eob}" solved the issue. My guess is that "i" is used to represent regular integer values, and "e" should used when the int value is a value of an enumeration? Not really sure, but it's working for me now =]

Adam
  • 168
  • 5