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.

OpenLDAP -> Managed User Mapping

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

mail

mail

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

Managed User -> OpenDJ Mapping

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

source.cn || (source.givenName + ' ' + source.sn)

givenName

givenName

mail

mail

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

mail

mail

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

Managed User -> OpenLDAP Mapping

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

'cn=' + source + ',ou=users,dc=example,dc=com'

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

Managed User List from OpenLDAP

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

OpenLDAP + OpenDJ managed 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