From a102cfe5faf28b801d2ad3570477ef9dd5c0d5f1 Mon Sep 17 00:00:00 2001 From: Stanislav Levin Date: Thu, 27 Aug 2020 12:07:40 +0300 Subject: [PATCH] nss: Raise exception earlier on unsupported DB type For now FreeIPA handles explicit migration of NSS DB (dbm->sql). But Mozilla's NSS can be built without the support of legacy database (DBM). This implies that neither implicit nor explicit DB migration to SQL will work. So, eventually, this support will be removed from FreeIPA. With this patch, the instantiation of NSS with legacy db(if not supported by NSS) is forbidden. Fixes: https://pagure.io/freeipa/issue/8474 Signed-off-by: Stanislav Levin Reviewed-By: Alexander Bokovoy --- ipapython/certdb.py | 23 ++++++++++++++----- ipatests/test_ipapython/test_certdb.py | 31 +++++++++++++++++++++++++- 2 files changed, 47 insertions(+), 7 deletions(-) diff --git a/ipapython/certdb.py b/ipapython/certdb.py index 43245cd29..8e0faffdd 100644 --- a/ipapython/certdb.py +++ b/ipapython/certdb.py @@ -26,10 +26,11 @@ import io import pwd import grp import re +import shutil import stat import tempfile +from ctypes.util import find_library from tempfile import NamedTemporaryFile -import shutil import cryptography.x509 @@ -73,6 +74,10 @@ TRUSTED_PEER_TRUST_FLAGS = TrustFlags( ) +def nss_supports_dbm(): + return bool(find_library("nssdbm3")) + + def get_ca_nickname(realm, format=CA_NICKNAME_FMT): return format % realm @@ -252,14 +257,20 @@ class NSSDatabase: # Generic NSS DB code should be moved here. def __init__(self, nssdir=None, dbtype='auto'): + if nssdir is not None: + self.secdir = nssdir + self._is_temporary = False + if dbtype == "auto": + dbtype = self._detect_dbtype() + + if dbtype == "dbm" and not nss_supports_dbm(): + raise ValueError( + "NSS is built without support of the legacy database(DBM)" + ) + if nssdir is None: self.secdir = tempfile.mkdtemp() self._is_temporary = True - else: - self.secdir = nssdir - self._is_temporary = False - if dbtype == 'auto': - dbtype = self._detect_dbtype() self.pwd_file = os.path.join(self.secdir, 'pwdfile.txt') self.dbtype = None diff --git a/ipatests/test_ipapython/test_certdb.py b/ipatests/test_ipapython/test_certdb.py index e4366de6d..7c0558da8 100644 --- a/ipatests/test_ipapython/test_certdb.py +++ b/ipatests/test_ipapython/test_certdb.py @@ -4,7 +4,11 @@ import os import pytest -from ipapython.certdb import NSSDatabase, TRUSTED_PEER_TRUST_FLAGS +from ipapython.certdb import ( + NSSDatabase, + TRUSTED_PEER_TRUST_FLAGS, + nss_supports_dbm, +) from ipapython import ipautil from ipaplatform.osinfo import osinfo @@ -40,6 +44,10 @@ def create_selfsigned(nssdb): os.unlink(noisefile) +@pytest.mark.skipif( + not nss_supports_dbm(), + reason="NSS is built without support of the legacy database(DBM)", +) def test_dbm_tmp(): with NSSDatabase(dbtype='dbm') as nssdb: assert nssdb.dbtype == 'dbm' @@ -60,6 +68,19 @@ def test_dbm_tmp(): assert os.path.basename(nssdb.secmod) == 'secmod.db' +@pytest.mark.skipif( + nss_supports_dbm(), + reason="NSS is built with support of the legacy database(DBM)", +) +def test_dbm_raise(): + with pytest.raises(ValueError) as e: + NSSDatabase(dbtype="dbm") + assert ( + str(e.value) == "NSS is built without support of the legacy " + "database(DBM)" + ) + + def test_sql_tmp(): with NSSDatabase(dbtype='sql') as nssdb: assert nssdb.dbtype == 'sql' @@ -80,6 +101,10 @@ def test_sql_tmp(): assert os.path.basename(nssdb.secmod) == 'pkcs11.txt' +@pytest.mark.skipif( + not nss_supports_dbm(), + reason="NSS is built without support of the legacy database(DBM)", +) def test_convert_db(): with NSSDatabase(dbtype='dbm') as nssdb: assert nssdb.dbtype == 'dbm' @@ -115,6 +140,10 @@ def test_convert_db(): assert os.path.basename(nssdb.secmod) == 'pkcs11.txt' +@pytest.mark.skipif( + not nss_supports_dbm(), + reason="NSS is built without support of the legacy database(DBM)", +) def test_convert_db_nokey(): with NSSDatabase(dbtype='dbm') as nssdb: assert nssdb.dbtype == 'dbm'