Project

General

Profile

LSC configuration

Description

Synchronization can be done with source or target any arbitrary [OU|DC|CN].

There are 3 types of synchronization (synchronization tasks):
  1. Users : User synchronization is split in two tasks:
    1. User Account: just the basic object (simply a dn). Authentication should work with just that.
    2. User Attributes: all the attributes
  2. LSC_config
  3. LSC_config

You can download the full template LSC configuration file lsc.properties
The wscript file lsc.properties.vbs generates an lsc.properties file given the right parameters.

Source and target

We can synchronize from any arbitrary [OU|DC|CN] to any other [OU|DC|CN].
In order for this to work there are three settings for each task that need to be configured properly.
Suppose we are synchronizing entries under DN %SRC_BASEDN% at the source, to DN %DST_BASEDN% at the destination.
Then the following lsc options should be configured:
  • source LDAP: src.java.naming.provider.url = ldap://src_ldapurl/%SRC_BASEDN%
  • destination LDAP: dst.java.naming.provider.url = ldap://dst_ldapurl/%DST_BASEDN%
For a specific task named TASKNAME we want to synchronize only the entries beneath %SRC_OU% at the source, to entries under %DST_OU% at the destination. For this task the following options are necessary:
  • lsc.tasks.TASKNAME.srcService.baseDn = %SRC_OU%
  • lsc.tasks.TASKNAME.dstService.baseDn = %DST_OU%
    And we must specify the following DN transformation rule:
  • lsc.tasks.TASKNAME.dn = srcBean.getAttributeValueById("distinguishedName").replace(",%SRC_OU%,%SRC_BASEDN%",",%DST_OU%")

Example 1:

We want to syncrhronize entries from dc=ipsyp,dc=dom to dc=imis,dc=athena-innovation,dc=gr, that means:
  • %SRC_BASEDN% = dc=ipsyp,dc=dom
  • %DST_BASEDN% = dc=imis,dc=athena-innovation,dc=gr
  • %SRC_OU% =
  • %DST_OU% =
In this case the following options need to be set:
  • src.java.naming.provider.url = ldap://src_ldapurl/dc=ipsyp,dc=dom
  • dst.java.naming.provider.url = ldap://dst_ldapurl/dc=imis,dc=athena-innovation,dc=gr
  • lsc.tasks.TASKNAME.dn = srcBean.getAttributeValueById("distinguishedName").replace(",dc=ipsyp,dc=dom","")
Note:
  1. The ',' in front of dc=ipsyp,dc=dom in the tranformation rule, but not on the replacement term
  2. No lsc.tasks.task1.srcService.baseDn or lsc.tasks.task1.dstService.baseDn should be spesified.

Example 2:

We want to syncrhronize entries from ou=Accounts,dc=ipsyp,dc=dom to ou=People,dc=imis,dc=athena-innovation,dc=gr, that means:
  • %SRC_BASEDN% = ou=Accounts,dc=ipsyp,dc=dom
  • %DST_BASEDN% = ou=People,dc=imis,dc=athena-innovation,dc=gr
  • %SRC_OU% =
  • %DST_OU% =
In this case the following options need to be set:
  • src.java.naming.provider.url = ldap://src_ldapurl/ou=Accounts,dc=ipsyp,dc=dom
  • dst.java.naming.provider.url = ldap://dst_ldapurl/ou=People,dc=imis,dc=athena-innovation,dc=gr
  • lsc.tasks.TASKNAME.dn = srcBean.getAttributeValueById("distinguishedName").replace(",ou=Accounts,dc=ipsyp,dc=dom","")
Note:
  1. The ',' in front of dc=ipsyp,dc=dom in the tranformation rule, but not on the replacement term
  2. No lsc.tasks.task1.srcService.baseDn or lsc.tasks.task1.dstService.baseDn should be spesified.

Example 3:

We want to syncrhronize entries from ou=Accounts,dc=ipsyp,dc=dom to ou=People,dc=imis,dc=athena-innovation,dc=gr, and for a specific task only the entriers below ou=Sales to ou=Accounting that means:
  • %SRC_BASEDN% = ou=Accounts,dc=ipsyp,dc=dom
  • %DST_BASEDN% = ou=People,dc=imis,dc=athena-innovation,dc=gr
  • %SRC_OU% = ou=Sales
  • %DST_OU% = ou=Accounting
In this case the following options need to be set:
  • src.java.naming.provider.url = ldap://src_ldapurl/ou=Accounts,dc=ipsyp,dc=dom
  • dst.java.naming.provider.url = ldap://dst_ldapurl/ou=People,dc=imis,dc=athena-innovation,dc=gr
  • lsc.tasks.task1.srcService.baseDn = Sales
  • lsc.tasks.task1.srcService.baseDn = Accounting
  • lsc.tasks.TASKNAME.dn = srcBean.getAttributeValueById("distinguishedName").replace(",ou=Sales,ou=Accounts,dc=ipsyp,dc=dom",",ou=Accounting")
Note:
  1. The ',' in front of both parts of the tranformation rule
  2. lsc.tasks.task1.srcService.baseDn or lsc.tasks.task1.dstService.baseDn should be spesified.

Syncrhonization Tasks

For all the tasks lsc.tasks.TASKNAME.dn must be set according to the above, as well as lsc.tasks.task1.srcService.baseDn, lsc.tasks.task1.srcService.baseDn if they are required

Users

  • Targets:
    • Synchronizes only the necessary to create a user LDAP entry.
  • Synchronization ID:
    • Active Directory's sAMAccountName (it is also added to openldap for easier sync)
  • Remarks:
    • The + "my.domain" in *@lsc.syncoptions.users.userPrincipalName.force_value* should be changed to the correct value, or removed if the source value is OK.
  • LSC configuration:
##########################################################
#USERS
lsc.tasks.users.srcService = org.lsc.jndi.SimpleJndiSrcService
lsc.tasks.users.srcService.baseDn = %SRC_OU%
lsc.tasks.users.srcService.filterAll = (&(objectClass=person)(sAMAccountName=*)(!(sAMAccountName=*$)))
lsc.tasks.users.srcService.filterId = (&(sAMAccountName={sAMAccountName})(objectClass=person))
lsc.tasks.users.srcService.pivotAttrs = sAMAccountName
lsc.tasks.users.srcService.attrs = cn sAMAccountName sn distinguishedName dn

lsc.tasks.users.dstService = org.lsc.jndi.SimpleJndiDstService
lsc.tasks.users.dstService.baseDn = %DST_OU%
lsc.tasks.users.dstService.filterAll = (&(objectClass=inetOrgPerson)(sAMAccountName=*)(!(sAMAccountName=*$)))
lsc.tasks.users.dstService.filterId = (&(sAMAccountName={sAMAccountName})(objectClass=inetOrgPerson))
lsc.tasks.users.dstService.pivotAttrs = sAMAccountName
lsc.tasks.users.dstService.attrs = cn sAMAccountName sn uid objectClass userPrincipalName

lsc.tasks.users.bean = org.lsc.beans.SimpleBean
lsc.tasks.users.dn = srcBean.getAttributeValueById("distinguishedName").replace(",%SRC_OU%,%SRC_BASEDN%",",%DST_OU%")
#############################
# Syncoptions configuration #
lsc.syncoptions.users = org.lsc.beans.syncoptions.PropertiesBasedSyncOptions
lsc.syncoptions.users.default.action = F
lsc.syncoptions.users.default.delimiter = $

lsc.syncoptions.users.objectClass.create_value = "top"$"synchronizedUser"$"inetOrgPerson" 
lsc.syncoptions.users.uid.create_value = srcBean.getAttributeValueById("sAMAccountName")
lsc.syncoptions.users.sn.default_value = "-" 
lsc.syncoptions.users.userPrincipalName.force_value = srcBean.getAttributeValueById("sAMAccountName") + "@mydomain.com" 

OUs

  • Targets:
    • Synchronizes the OU structure.
  • Synchronization ID:
    • OU attribute (ou name) combined with Active Directory's uSNCreated (creation serial number).
  • Remarks:
    • The chosen ID (ou+uSNCreated) could lead to duplicates in case of OUs from different Active Directories wich have the same name and uSNCreated. It is highly unlikely though, and there no other "good" ids to choose from. (would not work with objectGUID :-( )
    • In filterAll, both at the source and the destination, an expression to exclude the top OU is added (!(ou=%TOP_OU_RDN%)) (top OU is considered the top most OU in our current search path, that is from task BaseDN if it exists or from the ldap basedn). Note that this is required only if the RDN of the search path is an OU. This is because a subtree search for ou=* in OU=ouname,dc=my,dc=domain returns OU=ouname as well, so we will try to modify this as well. That might be OK in the case only one AD syncs entries into that particular, but could lead to problems if there more than one AD sources (each one would try to set its own uSNCreated, the other one would not be able to do the ID match .... Unfortunately LSC does not work well with multivalued IDs). Adding this extra term could be avoided if:
      1. We know that only one AD syncs here.
      2. Before synchronization we add to the destination top OU the attribute uSNCreated with the correct value from the source, so that the synchronization process will find it and will not try to create it.
  • LSC configuration:
##########################################################
#OUs
lsc.tasks.OUs.srcService = org.lsc.jndi.SimpleJndiSrcService
lsc.tasks.OUs.srcService.baseDn = %SRC_OU%
lsc.tasks.OUs.srcService.filterAll = (&(objectClass=organizationalUnit))
lsc.tasks.OUs.srcService.filterId = (&(uSNCreated={uSNCreated})(ou={ou})(objectClass=organizationalUnit))
lsc.tasks.OUs.srcService.pivotAttrs = uSNCreated ou
lsc.tasks.OUs.srcService.attrs = ou description distinguishedName uSNCreated

lsc.tasks.OUs.dstService = org.lsc.jndi.SimpleJndiDstService
lsc.tasks.OUs.dstService.baseDn = %DST_OU%
lsc.tasks.OUs.dstService.filterAll = (&(objectClass=synchronizedOU))
lsc.tasks.OUs.dstService.filterId = (&(uSNCreated={uSNCreated})(ou={ou})(objectClass=synchronizedOU))
lsc.tasks.OUs.dstService.pivotAttrs = uSNCreated ou
lsc.tasks.OUs.dstService.attrs = dn ou description objectClass uSNCreated

lsc.tasks.OUs.bean = org.lsc.beans.SimpleBean
lsc.tasks.OUs.dn = srcBean.getAttributeValueById("distinguishedName").replace(",%SRC_OU%,%SRC_BASEDN%",",%DST_OU%")

#############################
# Syncoptions configuration 
lsc.syncoptions.OUs = org.lsc.beans.syncoptions.PropertiesBasedSyncOptions
lsc.syncoptions.OUs.default.action = F
lsc.syncoptions.OUs.default.delimiter = $

lsc.syncoptions.OUs.objectClass.force_value = "organizationalUnit"$"synchronizedOU" 

UserInfo

  • Targets:
    • Synchronizes the users' attributes.
  • Synchronization ID:
    • Active Directory's sAMAccountName (it is also added to openldap for easier sync)
  • Remarks:
    • The userPassword attribute is modifies to "[disabled]" + userPassword if the account is disabled. Account locking does not synchronize.
    • The eduPerson schema's attribute wich are DNs are "auto calculated" from the Active Directory. That causes the values to be reupdated at every sync. This could change if we modify the eduPerson schema and declare the appropriate attributes as strings and not DNs. This way we loose in validation, but gain in a)freedom to specify any arbitrary DN, b)less modifications during sync.
  • LSC configuration:
##########################################################
#userInfo
lsc.tasks.userInfo.srcService = org.lsc.jndi.SimpleJndiSrcService
lsc.tasks.userInfo.srcService.baseDn = %SRC_OU%
lsc.tasks.userInfo.srcService.filterAll = (&(objectClass=person)(sAMAccountName=*)(!(sAMAccountName=*$)))
lsc.tasks.userInfo.srcService.filterId = (&(sAMAccountName={sAMAccountName})(objectClass=person))
lsc.tasks.userInfo.srcService.pivotAttrs = sAMAccountName
lsc.tasks.userInfo.srcService.attrs = userAccountControl distinguishedName sAMAccountName description givenName initials displayName l st postalCode telephoneNumber streetAddress wWWHomePage mail uidNumber gidNumber loginShell unixHomeDirectory eduPersonAffiliation eduPersonNickname eduPersonOrgDN eduPersonOrgUnitDN eduPersonPrimaryAffiliation eduPersonPrincipalName eduPersonEntitlement eduPersonPrimaryOrgUnitDN eduPersonScopedAffiliation eduPersonTargetedID eduPersonAssurance

lsc.tasks.userInfo.dstService = org.lsc.jndi.SimpleJndiDstService
lsc.tasks.userInfo.dstService.baseDn = %DST_OU%
lsc.tasks.userInfo.dstService.filterAll = (&(objectClass=inetOrgPerson)(sAMAccountName=*)(!(sAMAccountName=*$)))
lsc.tasks.userInfo.dstService.filterId = (&(sAMAccountName={sAMAccountName})(objectClass=inetOrgPerson))
lsc.tasks.userInfo.dstService.pivotAttrs = sAMAccountName
lsc.tasks.userInfo.dstService.attrs = userPassword objectClass sAMAccountName description givenName initials displayName l st postalCode telephoneNumber streetAddress o labeledURI mail uidNumber gidNumber loginShell homeDirectory eduPersonAffiliation eduPersonNickname eduPersonOrgDN eduPersonOrgUnitDN eduPersonPrimaryAffiliation eduPersonPrincipalName eduPersonEntitlement eduPersonPrimaryOrgUnitDN eduPersonScopedAffiliation eduPersonTargetedID eduPersonAssurance

lsc.tasks.userInfo.bean = org.lsc.beans.SimpleBean
lsc.tasks.userInfo.dn = srcBean.getAttributeValueById("distinguishedName").replace(",%SRC_OU%,%SRC_BASEDN%",",%DST_OU%")
#############################
# Syncoptions configuration 
lsc.syncoptions.userInfo = org.lsc.beans.syncoptions.PropertiesBasedSyncOptions
lsc.syncoptions.userInfo.default.action = F
lsc.syncoptions.userInfo.default.delimiter = $

lsc.syncoptions.userInfo.objectClass.action = M
lsc.syncoptions.userInfo.objectClass.force_value = "posixAccount"$"shadowAccount"$"eduPerson" 
lsc.syncoptions.userInfo.uidNumber.default_value = 65535
lsc.syncoptions.userInfo.gidNumber.default_value = 65535
lsc.syncoptions.userInfo.homeDirectory.force_value = var home; if (srcBean.getAttributeValueById('unixHomeDirector')=="") {home='/nohome'} else {home=srcBean.getAttributeValueById('unixHomeDirectory')} home
lsc.syncoptions.userInfo.labeledURI.force_value = srcBean.getAttributeValueById("wWWHomePage")

lsc.syncoptions.userInfo.userPassword.force_value = var passwd; if (AD.userAccountControlCheck(srcBean.getAttributeValueById('userAccountControl'),AD.UAC_ACCOUNTDISABLE)) {if (dstBean.getAttributeValueById("userPassword")!="") {passwd="[disabled]"+dstBean.getAttributeValueById("userPassword").replace("[disabled]","")}} else {passwd=dstBean.getAttributeValueById("userPassword").replace("[disabled]","")} passwd

Groups

  • Targets:
    • Synchronizes the users' attributes.
  • Synchronization ID:
    • Active Directory's sAMAccountName (it is also added to openldap for easier sync)
  • Remarks:
    • The + "my.domain" in *@lsc.syncoptions.groups.userPrincipalName.force_value* should be changed to the correct value, or removed if the source value is OK.
    • The memberOf member msSFU30PosixMember attributes "auto calculated" from the Active Directory. That causes the values to be reupdated at every sync. The are not necessary since unix group memberships are stored also in memberUid so consider removing them.
  • LSC configuration:
##########################################################
#Groups
lsc.tasks.groups.srcService = org.lsc.jndi.SimpleJndiSrcService
lsc.tasks.groups.srcService.baseDn = %SRC_OU%
lsc.tasks.groups.srcService.filterAll = (&(objectClass=group)(sAMAccountName=*))
lsc.tasks.groups.srcService.filterId = (&(sAMAccountName={sAMAccountName})(objectClass=group))
lsc.tasks.groups.srcService.pivotAttrs = sAMAccountName
lsc.tasks.groups.srcService.attrs = distinguishedName sAMAccountName cn gidNumber memberUid description memberOf member msSFU30PosixMember

lsc.tasks.groups.dstService = org.lsc.jndi.SimpleJndiDstService
lsc.tasks.groups.dstService.baseDn = %DST_OU%
lsc.tasks.groups.dstService.filterAll = (&(objectClass=posixGroup)(sAMAccountName=*))
lsc.tasks.groups.dstService.filterId = (&(sAMAccountName={sAMAccountName})(objectClass=posixGroup))
lsc.tasks.groups.dstService.pivotAttrs = sAMAccountName
lsc.tasks.groups.dstService.attrs = objectClass sAMAccountName msADmemberOf msADmember msSFU30PosixMember cn gidNumber memberUid description 

lsc.tasks.groups.bean = org.lsc.beans.SimpleBean
lsc.tasks.groups.dn = srcBean.getAttributeValueById("distinguishedName").replace(",%SRC_OU%,%SRC_BASEDN%",",%DST_OU%")
#############################
# Syncoptions configuration #
lsc.syncoptions.groups = org.lsc.beans.syncoptions.PropertiesBasedSyncOptions
lsc.syncoptions.groups.default.action = F
lsc.syncoptions.groups.default.delimiter = $

lsc.syncoptions.groups.objectClass.force_value = "top"$"synchronizedGroup"$"msADGroup"$"posixGroup" 
lsc.syncoptions.groups.cn.force_value = srcBean.getAttributeValueById("sAMAccountName")
lsc.syncoptions.groups.userPrincipalName.force_value = srcBean.getAttributeValueById("sAMAccountName") + "@mydomain.com" 
lsc.syncoptions.groups.gidNumber.default_value = 65535
lsc.syncoptions.groups.msADmemberOf.force_value = srcBean.getAttributeValuesById("memberOf")
lsc.syncoptions.groups.msADmember.force_value = srcBean.getAttributeValuesById("member")

lsc.properties View - LSC config example (9.28 KB) Panos Georgantas, 05/17/2010 05:58 AM

lsc.properties.vbs - LSC config generator (12.2 KB) Panos Georgantas, 05/17/2010 05:58 AM