From 2b3eb5c567e1e5d4fe7d945e36615cef3dd4d144 Mon Sep 17 00:00:00 2001 From: Rob Crittenden Date: Tue, 29 May 2018 14:19:16 -0400 Subject: [PATCH] Disable Schema Compat plugin during server upgrade If this is enabled it can cause a deadlock with SSSD trying to look up entries and it trying to get data on AD users from SSSD. When reading the entry from LDIF try to get the camel-case nsslapd-pluginEnabled and fall back to the all lower-case nsslapd-pluginenabled if that is not found. It would be nice if the fetch function was case sensitive but this is likely overkill as it is, but better safe than blowing up. Upon restoring it will always write the camel-case version. https://pagure.io/freeipa/issue/6721 Signed-off-by: Rob Crittenden Reviewed-By: Stanislav Laznicka --- ipaserver/install/upgradeinstance.py | 36 ++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/ipaserver/install/upgradeinstance.py b/ipaserver/install/upgradeinstance.py index df0777ec5..301ff5b42 100644 --- a/ipaserver/install/upgradeinstance.py +++ b/ipaserver/install/upgradeinstance.py @@ -37,6 +37,7 @@ from ipaserver.install import service logger = logging.getLogger(__name__) DSE = 'dse.ldif' +COMPAT_DN = "cn=Schema Compatibility,cn=plugins,cn=config" class GetEntryFromLDIF(ldif.LDIFParser): @@ -113,6 +114,7 @@ class IPAUpgrade(service.Service): self.step("saving configuration", self.__save_config) self.step("disabling listeners", self.__disable_listeners) self.step("enabling DS global lock", self.__enable_ds_global_write_lock) + self.step("disabling Schema Compat", self.__disable_schema_compat) self.step("starting directory server", self.__start) if self.schema_files: self.step("updating schema", self.__update_schema) @@ -161,6 +163,22 @@ class IPAUpgrade(service.Service): else: self.backup_state('nsslapd-global-backend-lock', global_lock) + with open(self.filename, "r") as in_file: + parser = GetEntryFromLDIF(in_file, entries_dn=[COMPAT_DN]) + parser.parse() + + try: + compat_entry = parser.get_results()[COMPAT_DN] + except KeyError: + return + + schema_compat_enabled = compat_entry.get('nsslapd-pluginEnabled') + if schema_compat_enabled is None: + schema_compat_enabled = compat_entry.get('nsslapd-pluginenabled') + if schema_compat_enabled: + self.backup_state('schema_compat_enabled', + schema_compat_enabled[0].decode('utf-8')) + def __enable_ds_global_write_lock(self): ldif_outfile = "%s.modified.out" % self.filename with open(ldif_outfile, "w") as out_file: @@ -177,6 +195,7 @@ class IPAUpgrade(service.Service): port = self.restore_state('nsslapd-port') security = self.restore_state('nsslapd-security') global_lock = self.restore_state('nsslapd-global-backend-lock') + schema_compat_enabled = self.restore_state('schema_compat_enabled') ldif_outfile = "%s.modified.out" % self.filename with open(ldif_outfile, "w") as out_file: @@ -195,6 +214,10 @@ class IPAUpgrade(service.Service): if global_lock is not None: parser.add_value("cn=config", "nsslapd-global-backend-lock", [global_lock.encode('utf-8')]) + if schema_compat_enabled is not None: + parser.replace_value( + COMPAT_DN, "nsslapd-pluginEnabled", + [schema_compat_enabled.encode('utf-8')]) parser.parse() @@ -212,6 +235,19 @@ class IPAUpgrade(service.Service): shutil.copy2(ldif_outfile, self.filename) + def __disable_schema_compat(self): + ldif_outfile = "%s.modified.out" % self.filename + with open(ldif_outfile, "w") as out_file: + with open(self.filename, "r") as in_file: + parser = installutils.ModifyLDIF(in_file, out_file) + parser.remove_value(COMPAT_DN, "nsslapd-pluginEnabled") + parser.remove_value(COMPAT_DN, "nsslapd-pluginenabled") + parser.add_value(COMPAT_DN, "nsslapd-pluginEnabled", + [b"off"]) + parser.parse() + + shutil.copy2(ldif_outfile, self.filename) + def __update_schema(self): self.modified = schemaupdate.update_schema( self.schema_files,