Problem: ID-Connector - verify.py workgroups AttributeError

Problem

When executing the verify.py script of the ucsschool-id-connector app with the workgroups subcommand, the script aborts with an AttributeError:

root@ucs:/var/lib/univention-appcenter/apps/ucsschool-id-connector/conf/plugins/packages/idbroker# ./verify.py workgroups -a bremen --fix
2026-03-10 08:19:51.519134 Searching LDAP with filter '(ucsschoolRole=workgroup:*)'...
2026-03-10 08:19:56.956869 Found 1431 objects in 5.44 seconds.
Traceback (most recent call last):
  File "/var/lib/univention-appcenter/apps/ucsschool-id-connector/conf/plugins/packages/idbroker/./verify.py", line 664, in <module>
    cli()
  ...
  File "/var/lib/univention-appcenter/apps/ucsschool-id-connector/conf/plugins/packages/idbroker/./verify.py", line 376, in ldap_object_to_workgroup
    school = WORKGROUP_DN_PATTERN.match(ldap_object.entry_dn).groupdict()["ou"]
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AttributeError: 'NoneType' object has no attribute 'groupdict'

Root Cause

The verify.py script expects all work groups to reside inside the standard UCS@school container structure, for example:

cn=<workgroup-name>,cn=schueler,cn=groups,ou=<SCHOOL>,<base-dn>

For each work group object found in LDAP, the script extracts the school OU from the DN by applying a regular expression (WORKGROUP_DN_PATTERN):

school = WORKGROUP_DN_PATTERN.match(ldap_object.entry_dn).groupdict()["ou"]

If a work group is located outside the expected container hierarchy, the regular expression does not match. In that case WORKGROUP_DN_PATTERN.match(...) returns None, and calling .groupdict() on None raises the AttributeError shown above.

In short: at least one work group object in the LDAP directory has a DN that does not conform to the UCS@school DN pattern expected by verify.py.


Investigation

To identify the offending work group, list all DNs of objects marked as work groups in LDAP:

univention-ldapsearch -LLL "(ucsschoolRole=workgroup:school:*)" dn

Compare the returned DNs against the expected pattern. A valid DN looks like this:

dn: cn=Heisenberg-Test-Workgroup,cn=schueler,cn=groups,ou=Heisenberg,dc=example,dc=intranet

An invalid DN, one that triggers the error, is located outside the school OU structure, for example directly under the base DN:

dn: cn=Heisenberg-Test-Workgroup,cn=groups,dc=example,dc=intranet

Solution

Move the misplaced work group object into the correct UCS@school container structure.

  1. Identify the work group(s) with an invalid DN using the LDAP search above.

  2. Open the UMC module LDAP directory.

  3. Navigate to the misplaced work group object.

  4. Move the object to the correct container, for example:

    ou=<SCHOOL>/cn=groups/cn=schueler/
    
  5. Verify that the DN now matches the expected pattern:

    univention-ldapsearch -LLL "(ucsschoolRole=workgroup:school:*)" dn
    

    Example after correction:

    dn: cn=Heisenberg-Test-Workgroup,cn=schueler,cn=groups,ou=Heisenberg,dc=example,dc=intranet
    
  6. Re-run the verification:

    ./verify.py workgroups -a <authority> --fix
    

The script should now process all work groups without raising the AttributeError.


Additional Notes

  • Work group objects must always be created and managed via the UCS@school tools (UMC modules, ucsschool CLI, or the import framework) to ensure they end up in the correct container.
  • Manually created group objects with ucsschoolRole=workgroup:school:* outside the UCS@school structure are not supported and will break consistency checks such as verify.py.