Configuring OpenIDM for Synchronization Between OpenLDAP and OpenDJ
| This example uses the Bitnami OpenLDAP image and its original configuration. Check image availability and compatibility before using it. |
Introduction
This guide describes how to set up two-way synchronization between OpenLDAP and OpenDJ. Changes made in OpenLDAP will be reflected in OpenDJ, and vice versa.
OpenIDM Setup
OpenIDM deployment is described in documentation. It is assumed that OpenIDM is already installed and ready to be configured.
Data Sources Setup
OpenLDAP Setup
If you do not already have OpenLDAP installed, install it as described in documentation. Or you can use the Docker image. This is the approach we will use in this article.
Download the test data file openldap-data.ldif from GitHub and place it in the ./ldifs directory that will be mounted into the OpenLDAP container.
docker run --name openldap \ -p 2389:1389 -p 2636:1636 \ --env LDAP_ADMIN_USERNAME=admin \ --env LDAP_ADMIN_PASSWORD=adminpassword \ --env LDAP_ROOT=dc=example,dc=com \ --env LDAP_ADMIN_DN=cn=admin,dc=example,dc=com \ -v ./ldifs:/ldifs \ bitnami/openldap:latest
After OpenLDAP starts, verify that the data is loaded by running the command
ldapsearch -x -H ldap://localhost:2389 -D "cn=admin,dc=example,dc=com" \ -w adminpassword -b "dc=example,dc=com" "(objectClass=inetOrgPerson)" | grep dn dn: cn=user01,ou=users,dc=example,dc=com dn: cn=user02,ou=users,dc=example,dc=com
Download the OpenLDAP connection configuration file provisioner.openicf-openldap.json from GitHub and copy it to the conf directory of OpenIDM.
The file is already configured according to the OpenLDAP connection settings in the Docker container and requires no changes.
OpenDJ Setup
If you do not have OpenDJ installed, install it as described in documentation.
Download the test data file Example.ldif from GitHub.
Perform the initial OpenDJ setup and import the data with the following command:
cd /path/to/opendj ./setup --cli \ --hostname localhost \ --ldapPort 1389 \ --rootUserDN "cn=Directory Manager" \ --rootUserPassword password \ --adminConnectorPort 4444 \ --baseDN dc=com \ --ldifFile /path/to/Example.ldif \ --acceptLicense \ --no-prompt ... Configuring Directory Server ..... Done. Creating Base Entry dc=com ..... Done. Starting Directory Server ....... Done. ...
Download from GitHub the OpenDJ connection configuration file provisioner.openicf-ldap.json and copy it to the conf directory of OpenIDM.
The file can be left unchanged, it is already configured according to the default OpenDJ connection parameters.
Configuring OpenLDAP → OpenDJ Synchronization
Open the OpenIDM administrator console at http://localhost:8080/admin. Enter the value openidm-admin in the login and password fields.
In the top menu, open Configure → Mappings and create the mapping openldap → user as shown in the image below.

Open the created mapping systemOpenldapAccount_managedUser and on the Properties tab customize the field matches as shown in the table below
| Source | Target |
|---|---|
uid |
userName |
cn |
cn |
sn |
sn |
givenName |
givenName |
telephoneNumber |
telephoneNumber |
On the Behaviors tab, configure the behavior for different synchronization situations.
| Situation | Action |
|---|---|
Ambiguous |
Ignore |
Source Missing |
Delete |
Missing |
Ignore |
Found Already Linked |
Exception |
Unqualified |
Delete |
Unassigned |
Ignore |
Link Only |
Exception |
Target Ignored |
Ignore |
Source Ignored |
Ignore |
All Gone |
Ignore |
Confirmed |
Update |
Found |
Ignore |
Absent |
Create |
Save the changes.
On the Mappings tab, create another mapping as shown in the figure below

Open the settings of the created mapping managedUser_systemLdapAccounts and on the Properties tab configure the field mappings as shown in the table below:
| Source | Target | Transformation script |
|---|---|---|
userName |
uid |
|
sn |
sn |
|
cn |
|
|
givenName |
givenName |
|
description |
description |
|
telephoneNumber |
telephoneNumber |
For the description field, specify the default value Created in OpenIDM
On the Behaviors tab configure the behavior for different synchronization situations:
| Situation | Action |
|---|---|
Ambiguous |
Ignore |
Source Missing |
Delete |
Missing |
Ignore |
Found Already Linked |
Exception |
Unqualified |
Delete |
Unassigned |
Ignore |
Link Only |
Exception |
Target Ignored |
Ignore |
Source Ignored |
Ignore |
All Gone |
Ignore |
Confirmed |
Update |
Found |
Update |
Absent |
Create |
On the same tab, under Situational Event Scripts, add a script for the onCreate event.
target.dn = 'uid=' + source.userName + ',ou=People,dc=example,dc=com';
Configuring OpenDJ → OpenLDAP Synchronization
Create synchronization OpenDJ → Managed User
In the Linked Mapping field, select managedUser_systemLdapAccounts.
Open the created mapping systemLdapAccount_managedUser and on the Properties tab customize the field mappings as shown in the tables below.
| Source | Target |
|---|---|
uid |
userName |
sn |
sn |
givenName |
givenName |
telephoneNumber |
telephoneNumber |
On the Behaviors tab, configure the behavior.
| Situation | Action |
|---|---|
Ambiguous |
Ignore |
Source Missing |
Delete |
Missing |
Ignore |
Found Already Linked |
Exception |
Unqualified |
Delete |
Unassigned |
Ignore |
Link Only |
Exception |
Target Ignored |
Ignore |
Source Ignored |
Ignore |
All Gone |
Ignore |
Confirmed |
Update |
Found |
Ignore |
Absent |
Create |
Create a mapping Managed User → OpenLDAP

When creating the Linked Mapping setting, set it to systemOpenldapAccount_managedUser.
In the created mapping managedUser_systemOpenldapAccount, set it to match:
| Source | Target | Transformation Script |
|---|---|---|
userName |
dn |
|
givenName |
givenName |
|
sn |
sn |
|
userName |
cn |
|
description |
description |
|
telephoneNumber |
telephoneNumber |
|
userName |
uid |
Map userName directly to cn so the attribute keeps the RDN value used by dn. Replacing it with a display name or a given name and surname would remove that RDN value and cause updates of existing OpenLDAP entries to fail.
On the Behaviors tab, configure behavior similar to mapping managedUser_systemLdapAccounts.
Test the Solution
OpenLDAP → OpenDJ Synchronization
In the admin console, select Mapping systemOpenldapAccount_managedUser and click Reconcile.
In the admin console, navigate to the Manage → User list. Accounts from OpenLDAP will appear in the user list

In the admin console, select Mapping managedUser_systemLdapAccounts and click Reconcile. After successful synchronization, the OpenLDAP entries created in Managed Users will appear in OpenDJ.
Check if the account exists with the command
./opendj/bin/ldapsearch -p 1389 -b dc=example,dc=com "(uid=user01)" uid dn: uid=user01,ou=People,dc=example,dc=com uid: user01
OpenDJ → OpenLDAP Synchronization
In the admin console, under Configure → Mappings, select the mapping systemLdapAccount_managedUser. And click Reconcile.
Go to Manage → User.
Accounts from OpenDJ will appear in the user list

Next, select mapping managedUser_systemOpenldapAccount and click Reconcile.
After successful synchronization, accounts from OpenDJ will appear in OpenLDAP.
Check for them with the command
ldapsearch -x -H ldap://localhost:2389 -D "cn=admin,dc=example,dc=com" \ -w adminpassword -b "dc=example,dc=com" "(objectClass=inetOrgPerson)" | grep cn=bjensen dn: cn=bjensen,ou=users,dc=example,dc=com
Also verify the existing user01 and user02 entries. Reconcile systemLdapAccount_managedUser and then managedUser_systemOpenldapAccount again. Both runs should complete without naming violations. Run the following search after the repeated synchronization:
ldapsearch -x -H ldap://localhost:2389 -D "cn=admin,dc=example,dc=com" \
-w adminpassword -b "dc=example,dc=com" \
"(|(uid=user01)(uid=user02)(uid=bjensen))" cn | grep -E '^(dn|cn):'
The three entries must retain the cn value used in their RDN. The order of the results may differ:
dn: cn=user01,ou=users,dc=example,dc=com cn: user01 dn: cn=user02,ou=users,dc=example,dc=com cn: user02 dn: cn=bjensen,ou=users,dc=example,dc=com cn: bjensen