Remove LDAP schema extensions

Abstract

Several apps include their own LDAP schema extensions. They are automatically registered with the UCS LDAP servers on installation. On de-installation they are not removed automatically. They can be only removed if no LDAP objects use definitions from the schema extensions any longer.

Warning

The following procedure should be done by experienced administrators only. An error may severely damage your domain. The procedure should be performed in a test environment before working in the productive environment. Make sure to have a recent and working backup!

Preparation

1. Make a backup of the current directory service:

slapcat -l ldap-backup.ldif
tar -c -f ldap-backup.tar /etc/ldap/schema /usr/share/univention-ldap/schema

In case of problems the schema files may be re-installed using (Note: only do this in case of trouble and if you know what you are doing. Better solutions may be found in the next section below):
tar -x -f ldap-backup.tar -C /

Usually that should be enough to be able to start the LDAP server again on an individual DC. In case of more severe issues the backup of the LDAP directory data may be re-installed into an empty LDAP using (Note: only do this in case of trouble and if you know what you are doing. Better solutions may be found in the next section below):
slapadd -l ldap-backup.ldif

2. Stop the UCS replication mechanism by stopping the UCS notifier service:
/etc/init.d/univention-directory-notifier stop
or
systemctl stop univention-directory-notifier.service

After the whole procedure it needs to be re-started again using:
/etc/init.d/univention-directory-notifier start
or
systemctl start univention-directory-notifier.service

Procedure

The following steps may be performed on the UCS DC Master to remove no-longer required LDAP schema extensions:

1. Identify .schema file. There are two cases:

  1. Before UCS-3.2 schema extensions were installed mainly through separate packages, normally ending on ‘-schema’. You can use:
    dpkg-query -W *-schema

to list all such packages. As soon as you know the package name, use the following command to list all files belonging that package:
dpkg-query -L "$package_name_schema"

Look for the location of the schema file (normally using the file name extension ‘.schema’), which is normally located in one of the following directories:

  • /etc/ldap/schema/
  • /usr/share/univention-ldap/schema/
  1. Since UCS-3.2 schema extensions can be registered and distributed via the Univention directory service. These extensions can be listed using the following command:
    udm settings/ldapschema list | grep filename:

The name of the schema file will be referenced as "$schema_filename_ldif" in step 7. The schema files are stored locally on DC Master and DC Backup systems in the following directory:

  • /var/lib/univention-ldap/local-schema/

The complete file name will be referenced as "$path_to_schema_file_ldif" in the following steps.

2. Make a backup of that schema file, so you can re-insert it in case an error occurs.
cp "$path_to_schema_file_ldif" schema-extension-backup.ldif

3. Identify all object classes and attribute types defined in the schema file (note: this writes two files “attributes” and “objectclasses” into the current working directory):

ldapsearch-wrapper < "$path_to_schema_file_ldif" |
  sed -r -n \
  -e "s/^attributetype .* NAME +(\( *)?'([^']+).*/\2/iw attributes" \
  -e "s/^objectclass .* NAME +(\( *)?'([^']+).*/\2/iw objectclasses"

4. Perform a LDAP search using ‘univention-ldapsearch’ to find any entry using elements of the schema:

univention-ldapsearch -LLLo ldif-wrap=no -f attributes '(%s=*)' dn $(cat attributes)
univention-ldapsearch -LLLo ldif-wrap=no -f objectclasses '(objectClass=%s)' dn

5. For all entries decide on a case-by-case basis if

  • the complete entry should be removed by

ldapdelete -D "cn=admin,$(ucr get ldap/base)" -y /etc/ldap.secret "$dn_of_object"

  • or only the relevant attributes should be deleted:
ldapmodify -D "cn=admin,$(ucr get ldap/base)" -y /etc/ldap.secret <<__LDIF__
dn: $dn_of_object
changetype: modify
delete: $attribute_name
-
__LDIF__

6. After deleting the entries re-do the search from step 4 to guarantee that the schema is now no longer used.
No more entries should be found. If you still find entries, repeat the steps from 4 onwards again.

6a. Note: If you have more ldap DCs (Backup and Slaves) in your domain, the changes in the ldap should be replicated first to the other DCs. Otherwise if the new schema is replicated first, the old attributes and objectclasses cannot be deleted from the ldap.

7. Remove the LDAP schema extensions by either purging the package using
dpkg -P "$package_name_schema"

or by deleting the schema extension object in LDAP using
udm settings/ldapschema remove --filter filename="$schema_filename_ldif"

8. Check the LDAP database for consistency by running the following command:
slapschema

If any error about “UNKNOWN attributeDescription” or “Object class violation: unrecognized objectClass” are found:

  • Write down the distinguished names of the failed objects, so you can fix them in the next iteration.
  • Copy the backup file from step 3 into ‘/var/lib/univention-ldap/local-schema/’:
    cp schema-extension-backup.ldif /var/lib/univention-ldap/local-schema/

Don’t forget to delete this temporary file next time in step 7 using this command:
rm /var/lib/univention-ldap/local-schema/schema.ldif

  • Re-generate the slapd.conf file by running the following command:
    ucr commit /etc/ldap/slapd.conf

  • Check the schema again:
    slapschema

  • Restart the LDAP server by running the following command:
    /etc/init.d/slapd restart

  • Go back to step 5 and fix all failed entries noted in step 8.1.

9. If no errors were found, finally restart the services again by running the following commands:

/etc/init.d/slapd restart
/etc/init.d/univention-directory-notifier restart

10. Cleanup all temporary files:

rm ldap-backup.ldif
rm ldap-backup.tar
rm schema-extension-backup.ldif
rm attributes
rm objectclasses

Additional way to identify orphaned entries if LDAP service does not start finally

Please check this article.

3 Likes

Steps 4 and 5 are really important as the OpenLDAP server seems to return former regular attributes as operational attributes if the attributes are left behind but the schema file is deleted. They are then returned when asking about all operational attributes (ldapsearch +), which breaks replication via UDN/UDL: joining a DC Backup/Replica will no longer be possible as UDL replication.py just does such a query for all operation attributes and will try to feed them to the local OpenLDAP server, which rejects them as there is no schema for them.
Searching explicitly for entries with these attributes after the schema is removed will not return those entries as the schema definition contained the SYNTAX type and EQUALITY comparison specification, which are then missing and will prevent the search from working.
The simplest solution is to do something like this then:

systemctl stop slapd.service
slapcat -n 1 -l ./backup.ldif
sed -e '/^ATTRIBUTE:/d' -i.bak ./backup.ldif  # change this
rm -f /var/lib/univention-ldap/ldap/*.mdb
slapadd -n 1 -l ./backup.ldif
chown openldap:openldap /var/lib/univention-ldap/ldap/*.mdb
systemctl start slapd.service
# when everything works:
rm -f ./backup.ldif*
Mastodon