Select Page

I’ve been working on a project that required a migration from an OpenLDAP Directory Server to Active Directory which was a very big challenge because there was no Samba server in order to do any work with ADMT or any other procedure. The options were to find a way to synchronize OpenLDAP with Active Directory and cut it off once everything was in order or to export the entire directory in a CSV file and then prepare it to be consumed by Active Directory.

We were considering both options at the time but the first one that tickled our fancy was to find the miracle tool that would help us the pain of constructing the CSV file. Lo and behold that we found the worthy open source candidate that could do exactly what we wanted. The tool is called “LDAP Synchronization Connector” and you can find out more about it here: LSC Project

If you stopped for a moment to check their website, you would have noticed that there is a guide for populating Active Directory from an OpenLDAP Directory server but the problem is that things changed and that tutorial can be treated as a guide line.

Parts of the tutorial helped me construct the XML file that’s required for the connector to actually do something but following it by the heart won’t get you anywhere and you will pull your hair out (like me) trying to get it working.

First of all; You will need to configure the Active Directory Domain Controller to use secure LDAP (LDAPS) otherwise this will never work. In this case you have two options, either you have PKI or you buy a third party SSL certificate. By using Active Directory Certificate Services, a Server Authentication certificate gets installed on the domain controllers which they use for enabling LDAPS.

Once you got that done, you will need to export the certificate that’s used for LDAPS without the private key. You need to do this task because you will have to import it on the machine where the LSC connector is installed.

The next step is to install the LSC tool, preferably on your OpenLDAP machine because it’s less hassle and you skip a few pain points.

The guys at LSC-Project have YUM and APT repositories so we don’t need to manually install anything. Basically we run the lines posted above and we’re good to go.

The next step in getting everything set up is to import the certificate that you previously exported in the JVM Keystore. For this part you can use your favorite way of putting files on a Linux machine. Once that’s done, import the certificate in the JVM Keystore.

The next step is to the necessary directories on the server the connector is installed.

For this I used the example in the LSC tutorial.

When you get to this part, you’re done with the Linux and Windows servers. This is the part where you open your favorite xml editor and start working on the actual file that will tell the connector what to do. I used Visual Studio Code for this task.

Let’s start with the config.

The first part of the configuration is pretty straight forward. You define the connection node for the OpenLDAP Server and Active Directory server. For this project I chose to create a domain admin that I delete after one complete sync so from my point of view that wasn’t a problem with having plain text credentials. The thing that you may notice is that I used ldap:// for the OpenLDAP server and ldaps:// for the domain controller. This is because I installed the connector directly on the OpenLDAP server.

Next up we have the tasks that the connector will actually perform.

This is the most complex and hard part of the XML. In the tasks phase, you need to define everything that you need to copy over to the domain controller. The snippet from above is just a basic example. The XML file that I created for the client had 40 fields that were required to be synchronized.

So let’s get it simple. We have a source service and a destination service.

In our case the source service is the OpenLDAP Server and the destination service is the AD Domain Controller:

As you can see we’re defining a pivot attribute (unique attribute) and we’re defining attributes that need to be fetched. Those attributes can be as many as you want but my advice to you is to start small and get it right.

On both the nodes we’re defining a pivot and fetching some attributes because if we’re doing multiple syncs or something changes, the connector won’t need to recreate the user in the destination service, it will just update it.

The next part of the config is the get filters which basically runs a query in the source and destination directories and loos for something specific. In this case we’re querying for users.

The snippet above tells the connector how to build the destination object. In the example above we’re building the object by using the CN= attribute and we’re appending an Organization Unit and the domain. You can simply remove the OU= part and put something else like CN=Users

The conditions node tells the connector what to do:

Create = Creates the object
Update = Updates the object
Delete = Deletes the object if non-existent in source service
ChangeID = Modifies the object identifier

Datasets are synchronization rules where you can define how to do the synchronization. You can have mirror rules or transformation rules.

Mirror rules simply take the value in the source service and does a 1:1 copy in the destination service while the transformation rule takes the values from the source and modifies it to look different.

Transform rules look like this:

As you can see we have two types of transform rules. One has a KEEP Policy with a node and the other one has a FORCE Policy with a node.

The main difference being that one is used to create the value and the other one to force the value.

One very important thing to mention is that you cannot synchronize passwords from OpenLDAP to AD or vice-versa. Unless you have the passwords in plain text (which is a very bad idea), passwords won’t be synchronized. Two of the datasets from above perform two operations on the newly created object. The first one is to force the user to change his password when he logs in the first time and second one is to set a password.

These are the datasets that do the operations:

This pretty much covers almost everything when it comes to migrating users. You can however go even deeper in the rabbit hole and start writing .js code that can be referenced inside the configuration file.

Our next tasks job will be to create the groups that are in the OpenLDAP server on the Active Directory server and of course populate those groups.

To do this, we create a new task that will handle group migration.

Once you understand how to build the user migration task then the group migration task will not be so hard to do. The task above basically takes the groups it find in the base DN and creates them in the destination directory. For actually populating the groups with members, we need to have some JavaScript code that does a LDAP search and populates the groups with the results from the query.

The only problem here is that the LSC connector doesn’t support OU migrations so if you don’t have a flat directory then the solution would be to write some JavaScript code or do it like me and create a task for each OU. I’m not that savvy in JavaScript so doing multiple copy paste operations with subtle changes was worth it.

Now that we understand how the tool works. All we need to do is piece together everything, paste it in the lsc.xml file that was created on the Linux machine and execute the sync job and see what happens 🙂

Here’s the command for the sync job:

In the end, the connector can do a lot of nice stuff and this is only one part of it. The problem I had was that they have a very poor documentation and you need to do a lot of digging to actually get stuff done.

Well that’s it folks!

Have a good one!

Pin It on Pinterest