Thursday, July 10, 2014

Sync between LDAP directories with LSC

Currently I am working on a Forefront Identity Manager IdM project. The client has a test environment what is a mirror of the production environment to a certain point. This includes AD LDS and multiple Active Directories. Because of bindproxy objects we cannot just export and import user objects because those rely on the objectSID in their environment and after the account creation we can only update entries unless we have too much time waiting to get tens of thousands of accounts recreated. So when we run management agents in the test environment we changed a lot of data in AD LDS. I was looking for a way to turn back changes and also to get fresh data from production and also to get data from production we do not handle with our management agents in test. For example street address, location and zip code of users, just to keep it simple for this post.
While exporting data from the production system into CSV and then reimprting was my first approach I really had a hard time to find tools for the import. Some great tools are just working for AD user objects, so no luck with my objects in AD LDS (http://www.wisesoft.co.uk/software/bulkadusers/default.aspx). For others I had first to find out if I want add a new attribute or change an existing attribute value. I considered that as too much effort to implement (ADfind/ADmod). I spent also some time with PowerShell but I was not really successful either. So finally I asked around in our team and I got a recommendation for LSC (http://tools.lsc-project.org/news/49). I installed it on Windows 2008 R2 and even all documentation guides to Linux it is working well on Windows because of Java. The developer website has an article describing how to run it on Windows but I guess it is outdated. I did not needed Maven or Ant to get version 2.10 running.
Just in case I need it again I post here the configuration file I use to sync from prod to test (AD LDS to AD LDS). In my example I sync only accounts for user with the last name Mueller. You can change that of course. ;-)

Many thanks to the LSC team ! And thanks to Kevin pointing me into the right direction!

Install steps:

- Install Java
- set JAVA_HOME
- Create a new folder and copy the logback.xml from the examples there
- Create the lsc.xml (feel free to be a copy cat)
- Run from the bin directory: lsc.bat -f <folderwherelsc.xmlis>-s all -c all -n

(with -n it will start a dry-run)


lsc.xml

<?xml version="1.0" ?>
<lsc xmlns="http://lsc-project.org/XSD/lsc-core-2.1.xsd" revision="0">
  <connections>
    <ldapConnection>
      <name>LDAPsource</name>
      <url>ldap://source.mydomain.com:389/o=mydomain.com</url>
      <username>username@mydomain.com</username>
      <password>password</password>
      <authentication>SIMPLE</authentication>
      <referral>IGNORE</referral>
      <derefAliases>NEVER</derefAliases>
      <version>VERSION_3</version>
      <pageSize>1000</pageSize>
      <factory>com.sun.jndi.ldap.LdapCtxFactory</factory>
      <tlsActivated>false</tlsActivated>
    </ldapConnection>
    <ldapConnection>
      <name>LDAPdestination</name>
      <url>ldap://destination.mydomain.com:389/o=mydomain.com</url>
      <username>uid=svc_acct,OU=admins,O=mydomain.com</username>
      <password>password</password>
      <authentication>SIMPLE</authentication>
      <referral>IGNORE</referral>
      <derefAliases>NEVER</derefAliases>
      <version>VERSION_3</version>
      <pageSize>1000</pageSize>
      <factory>com.sun.jndi.ldap.LdapCtxFactory</factory>
      <tlsActivated>false</tlsActivated>
    </ldapConnection>
  </connections>
  <tasks>
    <task>
      <name>People</name>
      <bean>org.lsc.beans.SimpleBean</bean>
      <ldapSourceService>
        <name>LDAPsource-service</name>
        <connection reference="LDAPsource" />
        <baseDn>ou=users,o=mydomain.com</baseDn>
        <pivotAttributes>
          <string>uid</string>
        </pivotAttributes>
        <fetchedAttributes>
          <string>uid</string>
          <string>street</string>
          <string>l</string>
          <string>postalCode</string>
          <string>C</string>
          <string>mobile</string>
 <string>userCertificate</string>
        </fetchedAttributes>
        <getAllFilter>(sn=mueller)</getAllFilter>
        <getOneFilter>(&amp;(objectClass=person)(uid={uid}))</getOneFilter>
        <cleanFilter>(&amp;(objectClass=person)(uid={uid}))</cleanFilter>
      </ldapSourceService>
      <ldapDestinationService>
        <name>LDAPdestination-service</name>
        <connection reference="LDAPdestination" />
        <baseDn>ou=users,o=mydomain.com</baseDn>
        <pivotAttributes>
          <string>uid</string>
        </pivotAttributes>
        <fetchedAttributes>
          <string>uid</string>
          <string>street</string>
          <string>l</string>
          <string>postalCode</string>
          <string>c</string>
          <string>mobile</string>
 <string>userCertificate</string>
         </fetchedAttributes>
        <getAllFilter><![CDATA[(objectClass=person)]]></getAllFilter>
        <getOneFilter><![CDATA[(&(objectClass=person)(uid={uid}))]]></getOneFilter>
      </ldapDestinationService>
 <propertiesBasedSyncOptions>
        <mainIdentifier>"uid="+srcBean.getDatasetFirstValueById("uid") + ",ou=users,o=mydomain.com"</mainIdentifier>
        <defaultDelimiter>;</defaultDelimiter>
        <defaultPolicy>FORCE</defaultPolicy>
<conditions>
          <create>false</create>
          <update>true</update>
          <delete>false</delete>
          <changeId>false</changeId>
        </conditions>
<dataset>
<name>uid</name>
<policy>KEEP</policy>
<createValues>
 <string>srcBean.getDatasetFirstValueById("uid")</string>
</createValues>
</dataset>
      </propertiesBasedSyncOptions>
    </task>
  </tasks>
</lsc>







No comments: