Home Contact Download
LSC logo
Open source connector to synchronize identities to a LDAP directory from any data source including any database with a JDBC connector, another LDAP server or flat files ...
Download  |  Read more...  |  Get started!

Populating Active Directory from OpenLDAP

Presentation

This article describes the creation of a connector which synchronizes data from OpenLDAP to Active Directory.

It has been done under Linux Ubuntu 9.10, with LSC v1.2. Everything will be done through the console.

Prepare your environment

Java tools

As described in Requirements, you need a Java virtual machine to run LSC. For this tutorial, we downloaded Sun JRE 1.6+.

Connector directory

To start a new connector, you have to download the LSC distribution, as a starting point. Get the latest LSC archive from here.

Decompress the archive and rename it for your project:

$ tar xjf lsc-1.2.0-dist.tar.gz
$ mv lsc-1.2.0 lsc-openldap2ad

Start LDAP directories

Make sure you have started OpenLDAP and Active Directory, and be sure to have LDAP access to them.

Connection to Active Directory requires a user account, with read rights on the schema. This user account can be used next for synchronization, with read and write access to data.

Configure your connector

All configuration is done through the configuration file etc/lsc.properties. A sample file is provided, so copy it and edit it:

$ cp etc/lsc.properties-sample etc/lsc.properties
$ vi etc/lsc.properties

All configuration parameters are described in LSC Configuration.

This file is made up of the following sections:

  • Destination LDAP directory
  • Source LDAP directory
  • Source database
  • Tasks configuration
  • Synchronization options

Destination LDAP directory (Active Directory)

Target directory properties:

  • Destination directory authentication mode: we choose simple.
  • LDAP server URL: a standard LDAP URI. Do not forget the trailing slash. We choose ldap://lng-pdc.linagora.lan:389/.
  • Naming context root DN: the data suffix. We choose dc=linagora,dc=lan.
dst.java.naming.security.authentication = simple
dst.java.naming.provider.url = ldap://lng-pdc.linagora.lan:389/dc=linagora,dc=lan

Pprovide information on the identity used to bind to the target directory:

  • Principal DN: for example cn=LSC,dc=linagora,dc=lan.
  • Password: for example linagora.
dst.java.naming.security.principal = cn=LSC,dc=linagora,dc=lan
dst.java.naming.security.credentials = linagora

To manage Active Directory Paged Results Control (which enables to return more than 1000 entries), add:

dst.java.naming.ldap.pageSize = 1000

As we want to act on the password (the attribute unicodePwd), we must use an SSL connection to Active Directory (password modification is not allowed on a clear connection).

The steps are:

Source LDAP directory

Source directory properties:

  • Source directory authentication mode: we choose Simple bind.
  • LDAP server URL: a standard LDAP URI for our OpenLDAP server. Do not forget the trailing slash. We choose ldap://localhost:389/.
  • Naming context root DN: the data suffix. We choose dc=lsc-project,dc=org.
  • Principal DN: for example cn=Directory Manager,dc=lsc-project,dc=org.
  • Password: for example secret.
src.java.naming.security.authentication = simple
src.java.naming.provider.url = ldap://localhost:389/dc=lsc-project,dc=org
src.java.naming.security.principal = cn=Directory Manager,dc=lsc-project,dc=org
src.java.naming.security.credentials = secret

Source database

Since we're not using a database for this connector, you can ignore or delete this section from the configuration file.

Task

You can have multiple tasks in your connector (identified by the lsc.taskname value). In this tutorial, we have only one task, named ADuser.

You have to update the configuration to define basic searches on source and destination, list all source and destination attributes you want to synchronize, set the destination DN creation rule and select the pivot attributes that will link a source entry to a destination entry.

If we want to read from the source all Active Directory users with a sAMAccountName, and from the destination all inetOrgPerson entries from ou=People with a uid, we could do this:

lsc.tasks.ADuser.srcService.baseDn = cn=Users
lsc.tasks.ADuser.srcService.filterAll = (&(sAMAccountName=*)(objectClass=user))

lsc.tasks.ADuser.dstService.baseDn = ou=People
lsc.tasks.ADuser.dstService.filterAll = (&(uid=*)(objectClass=inetOrgPerson))

For example, we want to link the source entry to the destination entry saying that source uid value is equal to the sAMAccountName in the destination:

lsc.tasks.ADuser.srcService.filterId = (&(objectClass=inetOrgPerson)(uid={uid}))
lsc.tasks.ADuser.srcService.pivotAttrs = uid

lsc.tasks.ADuser.dstService.filterId = (&(objectClass=user)(sAMAccountName={uid}))
lsc.tasks.ADuser.dstService.pivotAttrs = uid

Warning: you have to put objectClass in lsc.tasks.user.dstService.attrs but be sure to remove it from lsc.tasks.user.srcService.attrs.

We will also define how the target DN is built. Let's choose that the target DN is composed from the source's attribute cn and the destination branch ou=users,dc=linagora,dc=lan.

The suffix dc=linagora,dc=lan is already configured in dst.java.naming.provider.url, so we only have to set up this configuration to build the relative DN:

lsc.tasks.ADuser.dn = "cn=" + srcBean.getAttributeValueById("cn") + ",ou=users"

If not successful, check the Requirements, read the configuration documentation or ask for help on the mailing lists.

Synchronization options

This is the last configuration part, but not the least, because we will now describe all our synchronization rules.

In this tutorial, we plan to use these rules:

Source attribute Destination attribute Rule
cn cn =
sn sn =
uid uid =
- objectClass user/person/organizationalPerson/top
uid sAMAccountName =
uid userPrincipalName uid + ”@linagora.lan”
- userAccountControl Set as “Normal account”
- pwdLastSet Force password change on creation
- unicodePwd “changeit”

These rules are applied through syncoptions:

# Synchronization options
lsc.syncoptions.ADuser = org.lsc.beans.syncoptions.PropertiesBasedSyncOptions
lsc.syncoptions.ADuser.default.action = F

# Direct link - no need to specify syncoptions
# uid <- uid
# cn <- cn (done with DN generation)
# sn <- sn

# objectClass <- top/user/person/organizationalperson
lsc.syncoptions.ADuser.objectClass.action = F
lsc.syncoptions.ADuser.objectClass.force_value = \
"top";"user";"person";"organizationalPerson"

# sAMAccountName <- uid
lsc.syncoptions.ADuser.sAMAccountName.create_value = \
srcBean.getAttributeValueById("uid")

# userPrincipalName <- uid + "@linagora.lan"
lsc.syncoptions.ADuser.userPrincipalName.force_value = \
srcBean.getAttributeValueById("uid") + "@linagora.lan"

# userAccountControl
lsc.syncoptions.ADuser.userAccountControl.create_value = \
AD.userAccountControlSet( "0", [AD.UAC_SET_NORMAL_ACCOUNT])

# pwdLastSet <- 0 to force user to change password on next connection
lsc.syncoptions.ADuser.pwdLastset.create_value = "0"

# unicodePwd <- "changeit" at creation (requires SSL connection to AD)
lsc.syncoptions.ADuser.unicodePwd.create_value = AD.getUnicodePwd("changeit")

Note: There should be no line breaks after ”=” signs. Any you see here are due to the formatting of this web page, and are marked with a “\” character you should remove.

You can test your synchronization in “dry-run” mode (-n), which means no modification is done on the target directory:

$ bin/lsc -f etc -c all -s all -n

Setup and run

Install the lsc-openldap2ad directory in /usr/local on the target server.

Install cronjob and logrotate scripts:

$ sudo cp /usr/local/lsc-openldap2ad/etc/cron.d/lsc-openldap2ad /etc/cron.d
$ sudo cp /usr/local/lsc-openldap2ad/etc/logrotate.d/lsc-openldap2ad /etc/logrotate.d

Now your connector will run every hour, but you can also launch it manually:

$ sudo /usr/local/lsc-openldap2ad/bin/lsc -s all -c all

A Nagios script is also installed in /usr/local/lsc-openldap2ad/bin/check-lsc.sh, that you can call with a check_ssh service.