From fcc0a58742ff834af52a02de184f356a340b11d2 Mon Sep 17 00:00:00 2001 From: Christian Heimes Date: Jan 04 2018 15:21:23 +0000 Subject: NSSDB: use preferred convert command After further testing, Kai Engert proposed to use -N with -f -@ to convert a NSSDB from DBM to SQL format. https://fedoraproject.org/wiki/Changes/NSSDefaultFileFormatSql#Upgrade.2Fcompatibility_impact https://pagure.io/freeipa/issue/7049 Signed-off-by: Christian Heimes Reviewed-By: Rob Crittenden --- diff --git a/ipapython/certdb.py b/ipapython/certdb.py index b9d8984..2346a83 100644 --- a/ipapython/certdb.py +++ b/ipapython/certdb.py @@ -293,6 +293,56 @@ class NSSDatabase(object): new_mode = filemode os.chmod(path, new_mode) + def convert_db(self, rename_old=True): + """Convert DBM database format to SQL database format + + **WARNING** **WARNING** **WARNING** **WARNING** **WARNING** + + The caller must ensure that no other process or service is + accessing the NSSDB during migration. The DBM format does not support + multiple processes. If more than one process opens a DBM NSSDB for + writing, the database will become **irreparably corrupted**. + + **WARNING** **WARNING** **WARNING** **WARNING** **WARNING** + """ + if (self.dbtype == 'sql' or + os.path.isfile(os.path.join(self.secdir, "cert9.db"))): + raise ValueError( + 'NSS DB {} has been migrated already.'.format(self.secdir) + ) + + # use certutil to migrate db to new format + # see https://bugzilla.mozilla.org/show_bug.cgi?id=1415912 + # https://fedoraproject.org/wiki/Changes/NSSDefaultFileFormatSql + args = [ + paths.CERTUTIL, + '-d', 'sql:{}'.format(self.secdir), '-N', + '-f', self.pwd_file, '-@', self.pwd_file + ] + ipautil.run(args) + + # retain file ownership and permission, backup old files + migration = ( + ('cert8.db', 'cert9.db'), + ('key3.db', 'key4.db'), + ('secmod.db', 'pkcs11.txt'), + ) + for oldname, newname in migration: + oldname = os.path.join(self.secdir, oldname) + newname = os.path.join(self.secdir, newname) + oldstat = os.stat(oldname) + os.chmod(newname, stat.S_IMODE(oldstat.st_mode)) + os.chown(newname, oldstat.st_uid, oldstat.st_gid) + # XXX also retain SELinux context? + + self._set_filenames('sql') + self.list_certs() # self-test + + if rename_old: + for oldname, _ in migration: # pylint: disable=unused-variable + oldname = os.path.join(self.secdir, oldname) + os.rename(oldname, oldname + '.migrated') + def restore(self): for filename in NSS_FILES: path = os.path.join(self.secdir, filename)