Synchronizing users from LDAP to Active Directory

Since we decided to implement Active Directory in our company to take control of user’s desktops there rose up the idea of synchronizing users between LDAP and AD. The optimal solution would be two-way synchronization between our LDAP server and Active Directory server including user login, email, full name and his password.

After we had made some evaluation what projects are capable of this task with our configuration, we ended up only with LSP project which we finally found sort of clumsy and troublesome to configure besides there would be another issue regarding password synchronization anyway. Password synchronization turned up to be a big problem in general and is also mentioned by LSC project:

Synchronizing passwords with Active Directory is a common requirement, but generally a tricky subject. LSC does not solve this problem for you, but can help you achieve your goal. In particular:

  • LSC can write a password to Active Directory, given the original password in clear text (there is no way to update a password in AD if you only have a hashed password, in MD5 or SHA, for example).
  • LSC cannot read passwords from Active Directory

We also came to conclusion it would be easier task for us to synchronize users from/to 386 Directory which has some build-in AD synchronization feature (don’t know how much would it helped us) but we actually didn’t want to migrate from OpenLDAP to 386 Directory server also given the fact we already had complex master-slave synchronizations setup.

At this point we abandoned the idea of two-way synchronization between LDAP and AD and tried to find the easiest way to synchronize user’s data from LDAP to AD. This would help us in way that once we would create a new user in LDAP the user’s name, email, login and other data would be created in AD as well. We decided to create new AD accounts with preset passwords which is the only think user would have to change after logging in.

After few days spent by trying to find out what’s the optimal way to manage this task we ended up with pretty simple solution.

  1. Fist thing is to export user’s data from LDAP and prepare a .bat file which can further be run on Windows server to import users to AD. It actually just uses “dsadd” command to import user into AD with appropriate parameters. At the end the character encoding is changed to CP852 to preserve non-ASCII characters in user’s names. This script can be placed to cron and be run regularly so the generated data is still up-to-date
  2. users=`ldapsearch -x -LLL -h 127.0.0.1 "(objectClass=InetOrgPerson)" -b "ou=users,dc=example,dc=com" cn | grep ^cn | awk {'print $2'} `
    TEMPFILE=$(mktemp) || { echo "Failed to create temp file"; exit 1; }
    
    for user in ${users}; do
    
            displayname=`ldapsearch -x -LLL -s base -h 127.0.0.1 "(objectClass=InetOrgPerson)" -b "cn=$user,ou=users,dc=example,dc=com" displayName | grep displayName: | awk '{ if ($1 == "displayName::") {command = "base64 -d -i";print $2 | command } else  {FS=":";result=$0;sub(/displayName: /, "", $result);print $result } }'`
    
            sn=`ldapsearch -x -LLL -s base -h 127.0.0.1 "(objectClass=InetOrgPerson)" -b "cn=$user,ou=users,dc=example,dc=com" sn | grep sn: | awk '{ if ($1 == "sn::") {command = "base64 -d -i";print $2 | command } else  {FS=":";result=$0;sub(/sn: /, "", $result);print $result } }'`
    
            givenname=`ldapsearch -x -LLL -s base -h 127.0.0.1 "(objectClass=InetOrgPerson)" -b "cn=$user,ou=users,dc=example,dc=com" givenName | grep givenName: | awk '{ if ($1 == "givenName::") {command = "base64 -d -i";print $2 | command } else  {FS=":";result=$0;sub(/givenName: /, "", $result);print $result } }'`
    
            telephonenumber=`ldapsearch -x -LLL -s base -h 127.0.0.1 "(objectClass=InetOrgPerson)" -b "cn=$user,ou=users,dc=example,dc=com" telephoneNumber | grep telephoneNumber: | awk {'print $2'}`
    
            mail=`ldapsearch -x -LLL -s base -h 127.0.0.1 "(objectClass=InetOrgPerson)" -b "cn=$user,ou=users,dc=example,dc=com" mail | grep mail | awk {'print $2'}`
            telephonenumber=`ldapsearch -x -LLL -s base -h 127.0.0.1 "(objectClass=InetOrgPerson)" -b "cn=$user,ou=users,dc=example,dc=com" telephoneNumber | grep telephoneNumber: | awk {'print $2'}`
    
            mail=`ldapsearch -x -LLL -s base -h 127.0.0.1 "(objectClass=InetOrgPerson)" -b "cn=$user,ou=users,dc=example,dc=com" mail | grep mail | awk {'print $2'}`
    
            sn_formated=`echo ${user:1}`
    
            echo "dsadd user \"cn=$displayname,OU=user,OU=example,DC=com\" -disabled no -pwd defaultPassword01 -mustchpwd no -upn [email protected] -samid $user -fn $givenname -ln $sn -display \"$displayname\" -email [email protected] -pwdneverexpires yes" >> ${TEMPFILE}
    
            echo "" >> ${TEMPFILE}
    
    done
    
    iconv -f UTF-8 -t CP852 ${TEMPFILE} > /home/winpdc/pdc_ldap_data.bat
    chown winpdc. /home/winpdc/pdc_ldap_data.bat
    rm -f "${TEMPFILE}"

     

     

  3. This script is located on Windows server running AD. It’s supposed to be run regularly to import new users automatically
  4. @echo off
    
    REM ;;;;;Download the pregenerated script from Linux server for further processing;;;;;
    
    C:\batch\LDAP\pscp.exe -scp -P 22 -i private_key.ppk [email protected]:/home/winpdc/pdc_ldap_data.bat C:\batch\LDAP\pdc_ldap_data.bat
    
    REM ;;;;;Change the character coding of imported file to UTF8;;;;;
    
    chcp 852
    
    REM ;;;;;Execute the script to import the users;;;;;
    
    c:\batch\LDAP\pdc_ldap_data.bat >C:\batch\LDAP\log\import.log

     

  5. This script checks whether there were some new users imported and sends an information email about the changes
  6. @echo off                                                                                                                                                                                                                           
    @find /c /i "dsadd" "C:\batch\LDAP\log\import.log" > NUL                                                                                                                                                                                     
    IF %errorlevel% EQU 0 (                                                                                                                                                                                                                      
            C:\batch\LDAP\bmail.exe -s example.com -t [email protected] -f [email protected] -h -a "AD import" -m C:\batch\LDAP\log\import.log                                                                                                   
    
    ) else (                                                                                                                                                                  
    exit

 

Posted in Server administration


Leave a Reply