#!/usr/bin/env python3 """ This is a script which converts each user record in CSC LDAP from the 'account' to the 'inetOrgPerson' objectClass. It pulls first/last name information from UWLDAP. GSSAPI is used for LDAP authentication, so make sure to run `kinit` first. Also, make sure to run this script from the top-level of the git directory (see the sys.path hack below). """ import sys import traceback import ldap3 # modify as necessary LDAP_URI = "ldap://auth1.csclub.uwaterloo.ca" LDAP_MEMBERS_BASE = "ou=People,dc=csclub,dc=uwaterloo,dc=ca" UWLDAP_URI = "ldap://auth1.csclub.uwaterloo.ca" UWLDAP_MEMBERS_BASE = "ou=UWLDAP,dc=csclub,dc=uwaterloo,dc=ca" csc_conn = ldap3.Connection( LDAP_URI, authentication=ldap3.SASL, sasl_mechanism=ldap3.KERBEROS, auto_bind=True, raise_exceptions=True) uw_conn = ldap3.Connection(UWLDAP_URI, auto_bind=True, raise_exceptions=True) csc_conn.search(LDAP_MEMBERS_BASE, '(&(objectClass=member)(objectClass=account))', attributes=ldap3.ALL_ATTRIBUTES) total_records_updated = 0 for csc_entry in csc_conn.entries: uid = csc_entry.uid.value cn = csc_entry.cn.value sn = None given_name = None try: uw_conn.search( f'uid={uid},{UWLDAP_MEMBERS_BASE}', '(objectClass=*)', attributes=ldap3.ALL_ATTRIBUTES, search_scope=ldap3.BASE) uw_entry = uw_conn.entries[0] sn = uw_entry.sn.value given_name = uw_entry.givenName.value except ldap3.core.exceptions.LDAPNoSuchObjectResult: pass if given_name is None or sn is None: print(f'WARNING: could not retrieve first and last names for {uid}; inferring from whitespace instead') words = cn.split() given_name, sn = words[0], words[-1] old_object_classes = csc_entry.objectClass.values.copy() old_object_classes.remove('account') new_object_classes = old_object_classes + [ 'person', 'organizationalPerson', 'inetOrgPerson', ] attrs = csc_entry.entry_attributes_as_dict.copy() attrs['objectClass'] = new_object_classes attrs['givenName'] = [given_name] attrs['sn'] = [sn] csc_conn.delete(csc_entry.entry_dn) try: csc_conn.add(csc_entry.entry_dn, attributes=attrs) except Exception: print(traceback.format_exc()) print(f"!!! ERROR !!! We weren't able to create a new record for {uid}.") print('You need to add the old record back in. Here it is:') print(csc_entry) sys.exit(1) print(f'Created new record for {uid}') total_records_updated += 1 print(f'Total records updated: {total_records_updated}')