Fix CA certificate backup and restore

Backup and restore /etc/pki/ca-trust/source/ipa.p11-kit.

Create /etc/ipa/nssdb after restore if necessary.

https://fedorahosted.org/freeipa/ticket/4711

Reviewed-By: Petr Viktorin <pviktori@redhat.com>
This commit is contained in:
Jan Cholasta 2014-11-10 16:24:22 +00:00 committed by Petr Viktorin
parent 8248f69627
commit 2639997dfe
5 changed files with 67 additions and 24 deletions

View File

@ -92,7 +92,7 @@ class BasePathNamespace(object):
PAM_LDAP_CONF = "/etc/pam_ldap.conf"
PASSWD = "/etc/passwd"
ETC_PKI_CA_DIR = "/etc/pki-ca"
SYSTEMWIDE_CA_STORE = "/etc/pki/ca-trust/source/anchors/"
SYSTEMWIDE_IPA_CA_CRT = "/etc/pki/ca-trust/source/anchors/ipa-ca.crt"
IPA_P11_KIT = "/etc/pki/ca-trust/source/ipa.p11-kit"
NSS_DB_DIR = "/etc/pki/nssdb"
PKI_TOMCAT = "/etc/pki/pki-tomcat"

View File

@ -55,6 +55,15 @@ class BaseTaskNamespace(object):
return
def reload_systemwide_ca_store(self):
"""
Reloads the systemwide CA store.
Returns True if the operation succeeded, False otherwise.
"""
return True
def insert_ca_certs_into_systemwide_ca_store(self, ca_certs):
"""
Adds CA certificates from 'ca_certs' to the systemwide CA store

View File

@ -161,8 +161,19 @@ class RedHatTaskNamespace(BaseTaskNamespace):
auth_config.add_option("nostart")
auth_config.execute()
def reload_systemwide_ca_store(self):
try:
ipautil.run([paths.UPDATE_CA_TRUST])
except CalledProcessError, e:
root_logger.error(
"Could not update systemwide CA trust database: %s", e)
return False
else:
root_logger.info("Systemwide CA database updated.")
return True
def insert_ca_certs_into_systemwide_ca_store(self, ca_certs):
new_cacert_path = os.path.join(paths.SYSTEMWIDE_CA_STORE, 'ipa-ca.crt')
new_cacert_path = paths.SYSTEMWIDE_IPA_CA_CRT
if os.path.exists(new_cacert_path):
try:
@ -251,24 +262,18 @@ class RedHatTaskNamespace(BaseTaskNamespace):
f.close()
# Add the CA to the systemwide CA trust database
try:
ipautil.run([paths.UPDATE_CA_TRUST])
except CalledProcessError, e:
root_logger.info("Failed to add CA to the systemwide "
"CA trust database: %s" % str(e))
else:
root_logger.info('Added the CA to the systemwide CA trust '
'database.')
return True
if not self.reload_systemwide_ca_store():
return False
return False
return True
def remove_ca_certs_from_systemwide_ca_store(self):
ipa_ca_crt = os.path.join(paths.SYSTEMWIDE_CA_STORE, 'ipa-ca.crt')
result = True
update = False
# Remove CA cert from systemwide store
for new_cacert_path in (paths.IPA_P11_KIT, ipa_ca_crt):
for new_cacert_path in (paths.IPA_P11_KIT,
paths.SYSTEMWIDE_IPA_CA_CRT):
if not os.path.exists(new_cacert_path):
continue
try:
@ -276,21 +281,15 @@ class RedHatTaskNamespace(BaseTaskNamespace):
except OSError, e:
root_logger.error(
"Could not remove %s: %s", new_cacert_path, e)
result = False
else:
update = True
if update:
try:
ipautil.run([paths.UPDATE_CA_TRUST])
except CalledProcessError, e:
root_logger.error(
"Could not update systemwide CA trust database: %s", e)
if not self.reload_systemwide_ca_store():
return False
else:
root_logger.info("Systemwide CA database updated.")
return True
return False
return result
def backup_and_replace_hostname(self, fstore, statestore, hostname):
old_hostname = socket.gethostname()

View File

@ -137,6 +137,8 @@ class Backup(admintool.AdminTool):
paths.SYSCONFIG_ODS,
paths.ETC_SYSCONFIG_AUTHCONFIG,
paths.IPA_NSSDB_PWDFILE_TXT,
paths.IPA_P11_KIT,
paths.SYSTEMWIDE_IPA_CA_CRT,
paths.NSSWITCH_CONF,
paths.KRB5_KEYTAB,
paths.SSSD_CONF,

View File

@ -26,7 +26,7 @@ import pwd
from ConfigParser import SafeConfigParser
from ipalib import api, errors
from ipapython import version
from ipapython import version, ipautil, certdb
from ipapython.ipautil import run, user_input
from ipapython import admintool
from ipapython.dn import DN
@ -277,7 +277,9 @@ class Restore(admintool.AdminTool):
create_ca_user()
if options.online:
raise admintool.ScriptError('File restoration cannot be done online.')
self.cert_restore_prepare()
self.file_restore(options.no_logs)
self.cert_restore()
if 'CA' in self.backup_services:
self.__create_dogtag_log_dirs()
@ -659,3 +661,34 @@ class Restore(admintool.AdminTool):
tasks.set_selinux_booleans(bools)
except ipapython.errors.SetseboolError as e:
self.log.error('%s', e)
def cert_restore_prepare(self):
for basename in ('cert8.db', 'key3.db', 'secmod.db', 'pwdfile.txt'):
filename = os.path.join(paths.IPA_NSSDB_DIR, basename)
try:
ipautil.backup_file(filename)
except OSError as e:
self.log.error("Failed to backup %s: %s" % (filename, e))
tasks.remove_ca_certs_from_systemwide_ca_store()
def cert_restore(self):
if not os.path.exists(os.path.join(paths.IPA_NSSDB_DIR, 'cert8.db')):
certdb.create_ipa_nssdb()
ipa_db = certdb.NSSDatabase(paths.IPA_NSSDB_DIR)
sys_db = certdb.NSSDatabase(paths.NSS_DB_DIR)
for nickname, trust_flags in (('IPA CA', 'CT,C,C'),
('External CA cert', 'C,,')):
try:
cert = sys_db.get_cert(nickname)
except RuntimeError:
pass
else:
try:
ipa_db.add_cert(cert, nickname, trust_flags)
except ipautil.CalledProcessError as e:
self.log.error(
"Failed to add %s to %s: %s" %
(nickname, paths.IPA_NSSDB_DIR, e))
tasks.reload_systemwide_ca_store()