github linkedin
Keystone. Synchronize users from AD to OpenLDAP [python script]
With OpenStack i need to sync users from corporate Microsoft Active Directory to OpenLDAP managed by Keystone.

As input i have list of user DNs. Script syncs only particular user parameters, such as

  • objectclass
  • mail
  • cn
  • givenName
  • sn
  • uid
  • userPassword
  • carLicense

These parameters a minimum enough for Keystone.

1) Make sure you have “python-ldap” installed
2) Prepare “users” file with list of DNs in source AD



3) Start script below

./ –users_file users

                –src_ldap_uri ldap://

                –src_ldap_user ‘DOMAINadministrator’

                –src_ldap_pass ‘xxx’

                –dst_ldap_uri ‘ldap://’

                –dst_ldap_user ‘cn=admin,dc=domain,dc=tld’

                –dst_ldap_pass xxx

                –dst_ldap_tree ‘ou=Users,dc=domain,dc=tld’


import ldap

import ldap.modlist as modlist

import argparse



parser = argparse.ArgumentParser()

parser.add_argument(‘–users_file’, default=’users’)

parser.add_argument(‘–src_ldap_uri’, required=True)

parser.add_argument(‘–src_ldap_user’, required=True)

parser.add_argument(‘–src_ldap_pass’, required=True)

parser.add_argument(‘–dst_ldap_uri’, required=True)

parser.add_argument(‘–dst_ldap_user’, required=True)

parser.add_argument(‘–dst_ldap_pass’, required=True)

parser.add_argument(‘–dst_ldap_tree’, required=True)

args = parser.parse_args()



USERS_FILE = args.users_file

SRC_LDAP_URI = args.src_ldap_uri

SRC_LDAP_USER = args.src_ldap_user

SRC_LDAP_PASS = args.src_ldap_pass

DST_LDAP_URI = args.dst_ldap_uri

DST_LDAP_USER = args.dst_ldap_user

DST_LDAP_PASS = args.dst_ldap_pass

DST_LDAP_USER_TREE = args.dst_ldap_tree



def prepare_attrs(src_attrs):

    attrs = {}

    attrs[‘objectclass’] = [‘top’,’inetOrgPerson’,’organizationalPerson’,’person’]

    attrs[‘mail’] = src_attrs[“mail”]

    attrs[‘cn’] =  src_attrs[“cn”]

    attrs[‘givenName’] = src_attrs[“givenName”]

    attrs[‘sn’] = src_attrs[“sAMAccountName”]

    attrs[‘uid’] = src_attrs[“sAMAccountName”]

    attrs[‘userPassword’] = ‘{SASL}%s’ % src_attrs[“mail”]

    attrs[‘carLicense’] = ‘TRUE’

    return attrs


src_ldap = ldap.initialize(SRC_LDAP_URI)

src_ldap.simple_bind_s(SRC_LDAP_USER, SRC_LDAP_PASS)



dst_ldap = ldap.initialize(DST_LDAP_URI)

dst_ldap.simple_bind_s(DST_LDAP_USER, DST_LDAP_PASS)



with open(USERS_FILE) as f:

    users_to_sync =



for user_dn in users_to_sync:

    user_cn = user_dn.split(‘,’)[0]

    user_tree = user_dn.split(‘,’, 1)[1]

    user = src_ldap.search_s(user_tree, ldap.SCOPE_ONELEVEL, user_cn)

    if user:

        dn = “cn=%s,%s” % (user_cn, DST_LDAP_USER_TREE)

        ldif = modlist.addModlist(prepare_attrs(user[0][1]))



            print “Synced user %s” % user[0][0]

        except ldap.ALREADY_EXISTS:

            print “User %s already exists” % user[0][0]