I’m working for a large corporate who has a large user account store in Oracle Unified Directory (LDAP).   They want to use these existing accounts and synchronise them to Azure Active Directory for Azure application services (such as future Office 365 services).
Microsoft state here that Azure Active Directory Connect (AAD Connect) will, in a ‘Future Release’ version, provide native LDAP support (“Connect to single on-premises LDAP directory”), so timing wise I’m in a tricky position – do I guide my customer to attempt to use the current version? (at the time of writing is: v1.1.649.0) or wait for this ‘future release version’?.
This blog may not have a very large lifespan – indeed a new version of AAD Connect might be released at any time with native LDAP tree support, so be sure to research AAD Connect prior to providing a design or implementation.
My customer doesn’t have any requirement for ‘write back’ services (where data is written back from Azure Active Directory to the local directory user store) so this blog post covers just a straight export from the on-premises LDAP into Azure Active Directory.
I contacted Microsoft and they stated it’s supported ‘today’ to provide connectivity from AAD Connect to LDAP, so I’ve spun up a Proof of Concept (PoC) lab to determine how to get it working in this current version of AAD Connect.
Good news first, it works!  Bad news, it’s not very well documented so I’ve created this blog just to outline my learnings in getting it working for my PoC lab.
I don’t have access to the Oracle Unified Directory in my PoC lab, so I substituted in Active Directory Lightweight Directory Services (AD LDS) so my configuration reflects the use of AD LDS.

Tip #1 – You still need an Active Directory Domain Service (AD DS) for installation purposes

During the AAD connect installation wizard (specifically the ‘Connect your directories’ page), it expects to connect to an AD DS forest to progress the installation.  In this version of AAD Connect, the ‘Directory Type’ listbox only shows ‘Active Directory’ – which I’m expecting to include more options when the ‘Future Release’ version is available.
I created a single Domain Controller (forest root domain) and used the local HOST file of my AAD Connect Windows Server to point the forest root domain FQDN e.g. ‘forestAD.internal’ to the IP address of that Domain Controller.
I did not need to ‘join’ my AAD Connect Windows Server to that domain to complete the installation, which will make it easier to decommission this AD DS (if it’s put into Production) if Microsoft releases an AAD Connect version that does not require AD DS.
Screen Shot 2017-10-25 at 10.39.34 am

Tip #2 – Your LDAP Connector service account needs to be a part of the LDAP tree

After getting AAD Connect installed with mostly the default options, I then went into the “Synchronization Engine” to install the ‘Generic LDAP’ connector that is available by clicking on the ‘Connector’ tab and clicking ‘Create’ under the ‘Actions’ heading on the right hand side:
Screen Shot 2017-11-01 at 11.50.41 am
For the ‘User Name’ field, I created and used an account (in this example: ‘CN=FIMLDSAdmin,DC=domain,DC=internal) that was part of the LDAP tree itself instead of the installation account created by AD LDS which is part of the local Windows Server user store.
If I tried use a local Windows Server ie. ‘Server\username’ user, it would just give me generic connection errors and not bind to the LDAP tree, even if that user had full administrative rights to the AD LDS tree.  I gave up troubleshooting this – so I’ve resigned myself to needing a service account in the LDAP tree itself.
Screen Shot 2017-11-03 at 9.50.55 am

Tip #3 – Copy (and modify) the existing Inbound Rules for AD

When you create a custom Connector, the data mapping rules for that Connector are taken from the ‘Sychronization Rules Editor’ program and are not located in the Synchronization Engine.  There’s basically two choices at the moment for a custom connector: copy existing rules from another Connector, or create a brand new (blank) rule set for that connector (per object type e.g. ‘User’).
I chose the first option – I copied the three existing ‘Inbound’ Rules from the AD DS connector:

  • In from AD – User Join
  • In from AD – User AccountEnabled
  • In from AD – User Common

If you ‘edit’ each of these existing AD DS rules, you’ll get a choice to create a copy of that rule set and disable the original.  Select ‘Yes’ will create a copy of that rule, and you can then modify the ‘Connected Systen’ to use the LDAP Connector instead of the AD DS Connector:
Screen Shot 2017-11-03 at 10.10.51 am
I also modified the priority numbering of each of the rules from ‘201’ to ‘203’ to have these new rules applied last in my Synchronization Engine.
I ended up with the configuration of these three new ‘cloned’ rules for my LDAP Connector:
Screen Shot 2017-11-03 at 10.04.27 am
I found I had to edit or remove any rules that required the following:

  • Any rule looking for ‘sAMAccountName’, I modified the text of the rule to look for ‘UID’ instead (which is the schema attribute name most closely resembling that account name field in my custom LDAP)
  • I deleted the following rule from the Transformation section of the ‘In from AD – User Join’ cloned rule.  I found that it was preventing any of my LDAP accounts reaching Azure AD:

Screen Shot 2017-11-03 at 10.32.39 am

  • In the ‘In from AD – User AccountEnabled’ Rule, I modified the existing Scoping Filter to not look at the ‘userAccountControl’ bit and instead used the AD LDS attribute name:  msDS-UserAccountDisabled = FALSE’ value instead:

Screen Shot 2017-11-03 at 10.35.36 am
There are obviously many, many ways of configuring the rules for your LDAP tree but I thought I’d share how I did it with AD LDS.  The reasoning why I ‘cloned’ existing rules was that I wanted to protect the data integrity of Azure AD primarily.  There are many, many default data mapping rules for Azure AD that come with the AD DS rule set – a lot of them use ‘TRIM’ and ‘LEFT’ functions to ensure the data reaches Azure AD with the correct formatting.
It will be interesting to see how Microsoft tackles these rules sets in a more ‘wizard’ driven approach – particularly since LDAP trees can be highly customised with unique attribute names and data approaches.
Before closing the ‘Synchronization Rules Editor’, don’t forgot to ‘re-enable’ each of the (e.g AD DS) Connector rules you’ve previously cloned because the Synchronization Rules Editor assumes you’re not modifying the Connector they’re using.  Select the original rule cloned, and uncheck the ‘Disabled’ box.

Tip #4 – Create ‘Delta’ and ‘Full’ Run Profiles

Lastly, you might be wondering: how does the AAD Connector Scheduler (the one based entirely in PowerShell with seemingly no customisation commands) pickup the new LDAP Connector?
Well, it’s simply a matter of naming your ‘Run Profiles’ in the Synchronization Engine with the text: ‘Delta’ and ‘Full’ where required.  Select ‘Configure Run Profiles’ in the Engine for your LDAP Connector:
Screen Shot 2017-11-03 at 10.16.29 am.png
I then created ‘Run Profiles’ with the same naming convention as the ones created for AD DS and Azure AD:
Screen Shot 2017-11-03 at 10.17.58 am
Next time I ran an ‘Initial’ (which executes ‘Full Import’ and ‘Full Sync.’ jobs) or a ‘Delta’ AD Scheduler job (I’ve previously blogged about the AD Scheduler, but you can find the official Microsoft doc on it here), my new LDAP Connector Run Profiles were executed automatically along with the AD DS and AAD Connector Run Profiles:
Screen Shot 2017-11-03 at 10.19.57 am
Before I finish up, my colleague David Minnelli has found IDAMPundit’s blog post about a current bug upgrading to AAD Connect v1.1.649.0 version if you already have an LDAP Connector.  In a nutshell, just open up the existing LDAP Connector and step through each page and re-save it to clear the issue.
** Edit: I have had someone query how I’m authenticating with these accounts, well I’m leveraging an existing SecureAuth service that uses the WS-Federation protocol to communicate with Azure AD.  So ‘Federation’ basically – I’m not extracting passwords out of this LDAP or doing any kind of password hash synchronization.  Thanks for the question though!
Hope this helped, good luck!

Azure Infrastructure, Azure Platform, Identity and Access Management

Join the conversation! 7 Comments

  1. awesome and brave move 🙂

  2. hi
    I’m trying to export data from AD to openLDAP, but it doesn’t work.
    I looked ldap log and checked connection was succeed, but nothing added.
    I think this cause of not exporting is sync rules.
    If you know how to config, please tell me.
    This problem plagues me for three weeks…

  3. this article is awesome!
    please tell me how to export users from Active Directory to ldap.
    There is no article about it

  4. I’m trying to set up OpenLDAP – Azure AD Sync via ADConnect Generic LDAP Connector following your guidelines, but so far only managed to perform “Full Import”, and not even past “Full Synchronization” (All entries got skipped as “Disconnectors”). I’ve tried modifying the Synchronization rules and transformations but so far haven’t managed to get any entry synced. Would appreciate any pointers. Thanks.

  5. Any update on whether this is still the method you would recommend using? I haven’t found any evidence yet that Azure AD Connect will directly connect to LDAP yet.

  6. https://docs.microsoft.com/en-us/azure/active-directory/hybrid/plan-hybrid-identity-design-considerations-tools-comparison

    * Currently there are two supported options for this. They are:

    You can use the generic LDAP connector and enable it outside of Azure AD Connect. This is complex and requires a partner for on-boarding and a premier support agreement to maintain. This option can handle both single and multiple LDAP directories.

    You can develop your own solution for moving objects from LDAP to Active Directory. Then synchronize the objects with Azure AD Connect. MIM or FIM could be used as a possible solution for moving the objects.

  7. I am trying to configure azure ad connect with generic ldap connector but it does not work, you know how it is done in the current version

Comments are closed.