pyceo/one_time_scripts/inetorgperson.py

68 lines
2.6 KiB
Python

#!/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}')