modify CSC schema instead of using inetOrgPerson
continuous-integration/drone/push Build is passing Details

This commit is contained in:
Max Erenberg 2021-10-28 21:33:32 -04:00
parent 02aff43e7f
commit 2493bb1a6b
5 changed files with 22 additions and 42 deletions

View File

@ -27,7 +27,8 @@ attributetype ( 1.3.6.1.4.1.27934.1.1.6 NAME 'isClubRep'
objectclass ( 1.3.6.1.4.1.27934.1.2.1 NAME 'member'
SUP top AUXILIARY
MUST ( cn $ uid )
MAY ( studentid $ program $ term $ nonMemberTerm $ description $ position $ isClubRep ) )
MAY ( studentid $ program $ term $ nonMemberTerm $ description $ position $
isClubRep $ sn $ givenName ) )
objectclass ( 1.3.6.1.4.1.27934.1.2.2 NAME 'club'
SUP top AUXILIARY

View File

@ -89,9 +89,7 @@ uid: ctdalek
uidNumber: 20001
gidNumber: 20001
objectClass: top
objectClass: person
objectClass: organizationalPerson
objectClass: inetOrgPerson
objectClass: account
objectClass: posixAccount
objectClass: shadowAccount
objectClass: member
@ -116,9 +114,7 @@ uid: regular1
uidNumber: 20002
gidNumber: 20002
objectClass: top
objectClass: person
objectClass: organizationalPerson
objectClass: inetOrgPerson
objectClass: account
objectClass: posixAccount
objectClass: shadowAccount
objectClass: member
@ -143,9 +139,7 @@ uid: exec1
uidNumber: 20003
gidNumber: 20003
objectClass: top
objectClass: person
objectClass: organizationalPerson
objectClass: inetOrgPerson
objectClass: account
objectClass: posixAccount
objectClass: shadowAccount
objectClass: member

1
.gitignore vendored
View File

@ -14,6 +14,7 @@ __pycache__/
/docs/*.5
/debian/ceo/
/debian/ceod/
/debian/ceo-common/
/debian/tmp/
/debian/ceo.substvars
/debian/files

View File

@ -164,19 +164,15 @@ class LDAPService:
conn.delete(dn)
def add_user(self, user: IUser):
object_classes = ['top', 'account', 'posixAccount', 'shadowAccount']
if user.is_club():
min_id, max_id = self.club_min_id, self.club_max_id
object_classes = [
'top', 'account', 'posixAccount', 'shadowAccount', 'club',
]
object_classes.append('club')
else:
assert user.given_name and user.sn, \
'First name and last name must be specified for new members'
min_id, max_id = self.member_min_id, self.member_max_id
object_classes = [
'top', 'person', 'organizationalPerson', 'inetOrgPerson',
'posixAccount', 'shadowAccount', 'member',
]
object_classes.append('member')
if user.mail_local_addresses:
object_classes.append('inetLocalMailRecipient')
conn = self._get_ldap_conn()

View File

@ -1,8 +1,7 @@
#!/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.
This is a script which adds 'sn' and 'givenName' attributes to each user record.
It pulls first/last name information from UWLDAP.
GSSAPI is used for LDAP authentication, so make sure to run `kinit` first.
"""
@ -21,8 +20,10 @@ 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)
csc_conn.search(
LDAP_MEMBERS_BASE,
'(&(objectClass=member)(!(|(sn=*)(givenName=*))))',
attributes=['uid', 'cn'])
total_records_updated = 0
for csc_entry in csc_conn.entries:
uid = csc_entry.uid.value
@ -32,7 +33,7 @@ for csc_entry in csc_conn.entries:
try:
uw_conn.search(
f'uid={uid},{UWLDAP_MEMBERS_BASE}', '(objectClass=*)',
attributes=ldap3.ALL_ATTRIBUTES, search_scope=ldap3.BASE)
attributes=['sn', 'givenName'], search_scope=ldap3.BASE)
uw_entry = uw_conn.entries[0]
sn = uw_entry.sn.value
given_name = uw_entry.givenName.value
@ -42,24 +43,11 @@ for csc_entry in csc_conn.entries:
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}')
changes = {
'givenName': [(ldap3.MODIFY_ADD, [given_name])],
'sn': [(ldap3.MODIFY_ADD, [sn])],
}
csc_conn.modify(csc_entry.entry_dn, changes)
print(f'Updated record for {uid}')
total_records_updated += 1
print(f'Total records updated: {total_records_updated}')