We're in the home stretch getting the OpenLDAP Management Agent prepped and ready for our Milestone 1 release this Friday. The release should contain an installable MSI (remember you need to have MIIS/ILM installed on the same machine) and a zip with the project documentation. Of course if you want to build the project we've already got an SVN repository with the source and the docs checked in so give it a whirl. I personally like Tortoise SVN as my client for keeping code in sync.

We're in full test mode this week and we've found a few bugs so far but the more testers the better.

In terms of features you can expect on Friday we're supporting the following:

  • FullImport from OpenLDAP (IMAExtensibleFileImport)
    • Ability to skip DSML generation for improved performance
  • DeltaImport from OpenLDAP (IMAExtensibleFileImport)
    • Based on attribute tracking
    • Based on changelogs (this is to support additional directories but hasn't been tested thoroughly)
    • Ability to skip deletes for improved performance
  • Call-based export to OpenLDAP (IMAExtensibleCallExport)
  • Password Management (IMAPasswordManagement)
  • Support for multiple naming contexts
  • Paged Searches (if supported by target directory)
  • Support for SSL
  • Support for multiple authentication types (Basic, Digest, and Kerberos)*

*Our goal is to support SASL's EXTERNAL mechanism as well however we ran into some difficulty with the underlying support in System.DirectoryServices.Protocols in .Net 2.0 and have alerted the team at Microsoft to the issue.  In the meantime, we've commented out the code in the project for EXTERNAL support however one of the developers on the project did come up with a little workaround by calling into the underlying native wldap.dll directly (thanks, Franck!).  We haven't tested this so use at your own risk, but I thought it was clever so I thought I would share it here. If the lack of support for EXTERNAL impacts your ability to use the adapter send me a note and let me know – I'm interested to hear about your scenarios. I will certainly keep you up to date as we move forward in coming to a resolution.

public class Class1


[DllImport("wldap32.dll", EntryPoint = "ldap_bind_sW", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode)]

    public static extern int ldap_bind_s(IntPtr ldapHandle, string dn, string credentials, uint method);



    static void Main(string[] args)


        LdapConnection cxn = new LdapConnection("ServerName:636"); //SSL port



            cxn.AuthType = AuthType.External;

            cxn.Timeout = System.TimeSpan.FromHours(1000);

            cxn.SessionOptions.ProtocolVersion = 3;

            cxn.SessionOptions.SecureSocketLayer = true;


            FieldInfo fildaphandle = cxn.GetType().GetField("ldapHandle", BindingFlags.Instance | BindingFlags.NonPublic);

            IntPtr ldaphandle = (IntPtr)fildaphandle.GetValue(cxn);


            uint LDAP_AUTH_EXTERNAL = 0xa6;

            int res = ldap_bind_s(ldaphandle, null, null, LDAP_AUTH_EXTERNAL);


            if (res == 0)


FieldInfo ficonnected = cxn.GetType().GetField("connected", BindingFlags.Instance | BindingFlags.NonPublic);

FieldInfo fibounded = cxn.GetType().GetField("bounded", BindingFlags.Instance | BindingFlags.NonPublic);

FieldInfo fineedRebind = cxn.GetType().GetField("needRebind", vBindingFlags.Instance | BindingFlags.NonPublic);


                ficonnected.SetValue(cxn, true);

                fibounded.SetValue(cxn, true);

                fineedRebind.SetValue(cxn, false);



       ��    {

                throw new LdapException(res, string.Format("External bind failed with error code {0}", res));



        catch (Exception e)


            throw e;