Latest Release
- Release candidate 2.0rc2 (07/03/12)
- Release candidate 2.0rc1 (23/12/11)
- Stable version 1.2.2 (09/02/12)
- Nightly builds available to test
Events
- 10/10/2011 - LDAPCon 2011 (Heidelberg, Germany)
- 13/06/2011 - RMLL (Strasbourg, France)
- 9/07/2010 - RMLL (Bordeaux, France)
Community
Get help, contribute or find professional services ...
Find out more!
Search
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:
- Set and export the CA certificate used in AD (see http://confluence.atlassian.com/display/CROWD/Configuring+an+SSL+Certificate+for+Microsoft+Active+Directory)
- Import the certificate in the JVM or in your own SSL truststore (see SSL and TLS activation)
- Use ldaps in the AD URI in lsc.properties (dst.java.naming.provider.url)
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.


