|
|
e3ffab |
From 9037c4d84bcf9cde48beb83d69f05c3733106c2d Mon Sep 17 00:00:00 2001
|
|
|
e3ffab |
From: Jan Cholasta <jcholast@redhat.com>
|
|
|
e3ffab |
Date: Mon, 10 Nov 2014 16:24:22 +0000
|
|
|
e3ffab |
Subject: [PATCH] Fix CA certificate backup and restore
|
|
|
e3ffab |
|
|
|
e3ffab |
Backup and restore /etc/pki/ca-trust/source/ipa.p11-kit.
|
|
|
e3ffab |
|
|
|
e3ffab |
Create /etc/ipa/nssdb after restore if necessary.
|
|
|
e3ffab |
|
|
|
e3ffab |
https://fedorahosted.org/freeipa/ticket/4711
|
|
|
e3ffab |
|
|
|
e3ffab |
Reviewed-By: Petr Viktorin <pviktori@redhat.com>
|
|
|
e3ffab |
---
|
|
|
e3ffab |
ipaplatform/base/paths.py | 2 +-
|
|
|
e3ffab |
ipaplatform/base/tasks.py | 9 +++++++++
|
|
|
e3ffab |
ipaplatform/redhat/tasks.py | 43 ++++++++++++++++++++--------------------
|
|
|
e3ffab |
ipaserver/install/ipa_backup.py | 2 ++
|
|
|
e3ffab |
ipaserver/install/ipa_restore.py | 35 +++++++++++++++++++++++++++++++-
|
|
|
e3ffab |
5 files changed, 67 insertions(+), 24 deletions(-)
|
|
|
e3ffab |
|
|
|
e3ffab |
diff --git a/ipaplatform/base/paths.py b/ipaplatform/base/paths.py
|
|
|
e3ffab |
index af502628e493ad7b4d8d30ed1acb98bba8cb39e4..e28147ab4aa1faa3859c38665a83f57fb67e96b2 100644
|
|
|
e3ffab |
--- a/ipaplatform/base/paths.py
|
|
|
e3ffab |
+++ b/ipaplatform/base/paths.py
|
|
|
e3ffab |
@@ -92,7 +92,7 @@ class BasePathNamespace(object):
|
|
|
e3ffab |
PAM_LDAP_CONF = "/etc/pam_ldap.conf"
|
|
|
e3ffab |
PASSWD = "/etc/passwd"
|
|
|
e3ffab |
ETC_PKI_CA_DIR = "/etc/pki-ca"
|
|
|
e3ffab |
- SYSTEMWIDE_CA_STORE = "/etc/pki/ca-trust/source/anchors/"
|
|
|
e3ffab |
+ SYSTEMWIDE_IPA_CA_CRT = "/etc/pki/ca-trust/source/anchors/ipa-ca.crt"
|
|
|
e3ffab |
IPA_P11_KIT = "/etc/pki/ca-trust/source/ipa.p11-kit"
|
|
|
e3ffab |
NSS_DB_DIR = "/etc/pki/nssdb"
|
|
|
e3ffab |
PKI_TOMCAT = "/etc/pki/pki-tomcat"
|
|
|
e3ffab |
diff --git a/ipaplatform/base/tasks.py b/ipaplatform/base/tasks.py
|
|
|
e3ffab |
index 408447e43cd36d0cdf11a1877b3bc9880c4785de..a6684d7653d6de8202a489edb1f7a38f4b344bbc 100644
|
|
|
e3ffab |
--- a/ipaplatform/base/tasks.py
|
|
|
e3ffab |
+++ b/ipaplatform/base/tasks.py
|
|
|
e3ffab |
@@ -49,6 +49,15 @@ class BaseTaskNamespace(object):
|
|
|
e3ffab |
|
|
|
e3ffab |
return
|
|
|
e3ffab |
|
|
|
e3ffab |
+ def reload_systemwide_ca_store(self):
|
|
|
e3ffab |
+ """
|
|
|
e3ffab |
+ Reloads the systemwide CA store.
|
|
|
e3ffab |
+
|
|
|
e3ffab |
+ Returns True if the operation succeeded, False otherwise.
|
|
|
e3ffab |
+ """
|
|
|
e3ffab |
+
|
|
|
e3ffab |
+ return True
|
|
|
e3ffab |
+
|
|
|
e3ffab |
def insert_ca_certs_into_systemwide_ca_store(self, ca_certs):
|
|
|
e3ffab |
"""
|
|
|
e3ffab |
Adds CA certificates from 'ca_certs' to the systemwide CA store
|
|
|
e3ffab |
diff --git a/ipaplatform/redhat/tasks.py b/ipaplatform/redhat/tasks.py
|
|
|
e3ffab |
index 555516d90a6d1a7d3d9aced5de82a5c1efe6b8c2..4977e1c7c496e36d56110bcdf040ab5c932d31a2 100644
|
|
|
e3ffab |
--- a/ipaplatform/redhat/tasks.py
|
|
|
e3ffab |
+++ b/ipaplatform/redhat/tasks.py
|
|
|
e3ffab |
@@ -158,8 +158,19 @@ class RedHatTaskNamespace(BaseTaskNamespace):
|
|
|
e3ffab |
auth_config.add_option("nostart")
|
|
|
e3ffab |
auth_config.execute()
|
|
|
e3ffab |
|
|
|
e3ffab |
+ def reload_systemwide_ca_store(self):
|
|
|
e3ffab |
+ try:
|
|
|
e3ffab |
+ ipautil.run([paths.UPDATE_CA_TRUST])
|
|
|
e3ffab |
+ except CalledProcessError, e:
|
|
|
e3ffab |
+ root_logger.error(
|
|
|
e3ffab |
+ "Could not update systemwide CA trust database: %s", e)
|
|
|
e3ffab |
+ return False
|
|
|
e3ffab |
+ else:
|
|
|
e3ffab |
+ root_logger.info("Systemwide CA database updated.")
|
|
|
e3ffab |
+ return True
|
|
|
e3ffab |
+
|
|
|
e3ffab |
def insert_ca_certs_into_systemwide_ca_store(self, ca_certs):
|
|
|
e3ffab |
- new_cacert_path = os.path.join(paths.SYSTEMWIDE_CA_STORE, 'ipa-ca.crt')
|
|
|
e3ffab |
+ new_cacert_path = paths.SYSTEMWIDE_IPA_CA_CRT
|
|
|
e3ffab |
|
|
|
e3ffab |
if os.path.exists(new_cacert_path):
|
|
|
e3ffab |
try:
|
|
|
e3ffab |
@@ -248,24 +259,18 @@ class RedHatTaskNamespace(BaseTaskNamespace):
|
|
|
e3ffab |
f.close()
|
|
|
e3ffab |
|
|
|
e3ffab |
# Add the CA to the systemwide CA trust database
|
|
|
e3ffab |
- try:
|
|
|
e3ffab |
- ipautil.run([paths.UPDATE_CA_TRUST])
|
|
|
e3ffab |
- except CalledProcessError, e:
|
|
|
e3ffab |
- root_logger.info("Failed to add CA to the systemwide "
|
|
|
e3ffab |
- "CA trust database: %s" % str(e))
|
|
|
e3ffab |
- else:
|
|
|
e3ffab |
- root_logger.info('Added the CA to the systemwide CA trust '
|
|
|
e3ffab |
- 'database.')
|
|
|
e3ffab |
- return True
|
|
|
e3ffab |
+ if not self.reload_systemwide_ca_store():
|
|
|
e3ffab |
+ return False
|
|
|
e3ffab |
|
|
|
e3ffab |
- return False
|
|
|
e3ffab |
+ return True
|
|
|
e3ffab |
|
|
|
e3ffab |
def remove_ca_certs_from_systemwide_ca_store(self):
|
|
|
e3ffab |
- ipa_ca_crt = os.path.join(paths.SYSTEMWIDE_CA_STORE, 'ipa-ca.crt')
|
|
|
e3ffab |
+ result = True
|
|
|
e3ffab |
update = False
|
|
|
e3ffab |
|
|
|
e3ffab |
# Remove CA cert from systemwide store
|
|
|
e3ffab |
- for new_cacert_path in (paths.IPA_P11_KIT, ipa_ca_crt):
|
|
|
e3ffab |
+ for new_cacert_path in (paths.IPA_P11_KIT,
|
|
|
e3ffab |
+ paths.SYSTEMWIDE_IPA_CA_CRT):
|
|
|
e3ffab |
if not os.path.exists(new_cacert_path):
|
|
|
e3ffab |
continue
|
|
|
e3ffab |
try:
|
|
|
e3ffab |
@@ -273,21 +278,15 @@ class RedHatTaskNamespace(BaseTaskNamespace):
|
|
|
e3ffab |
except OSError, e:
|
|
|
e3ffab |
root_logger.error(
|
|
|
e3ffab |
"Could not remove %s: %s", new_cacert_path, e)
|
|
|
e3ffab |
+ result = False
|
|
|
e3ffab |
else:
|
|
|
e3ffab |
update = True
|
|
|
e3ffab |
|
|
|
e3ffab |
if update:
|
|
|
e3ffab |
- try:
|
|
|
e3ffab |
- ipautil.run([paths.UPDATE_CA_TRUST])
|
|
|
e3ffab |
- except CalledProcessError, e:
|
|
|
e3ffab |
- root_logger.error(
|
|
|
e3ffab |
- "Could not update systemwide CA trust database: %s", e)
|
|
|
e3ffab |
+ if not self.reload_systemwide_ca_store():
|
|
|
e3ffab |
return False
|
|
|
e3ffab |
- else:
|
|
|
e3ffab |
- root_logger.info("Systemwide CA database updated.")
|
|
|
e3ffab |
- return True
|
|
|
e3ffab |
|
|
|
e3ffab |
- return False
|
|
|
e3ffab |
+ return result
|
|
|
e3ffab |
|
|
|
e3ffab |
def backup_and_replace_hostname(self, fstore, statestore, hostname):
|
|
|
e3ffab |
old_hostname = socket.gethostname()
|
|
|
e3ffab |
diff --git a/ipaserver/install/ipa_backup.py b/ipaserver/install/ipa_backup.py
|
|
|
e3ffab |
index 75ee243d1c8deb6f8452744df4c040fd0794250c..5d583f7e9186f20ebe8187ba70db28de0c255ae7 100644
|
|
|
e3ffab |
--- a/ipaserver/install/ipa_backup.py
|
|
|
e3ffab |
+++ b/ipaserver/install/ipa_backup.py
|
|
|
e3ffab |
@@ -138,6 +138,8 @@ class Backup(admintool.AdminTool):
|
|
|
e3ffab |
paths.SYSCONFIG_ODS,
|
|
|
e3ffab |
paths.ETC_SYSCONFIG_AUTHCONFIG,
|
|
|
e3ffab |
paths.IPA_NSSDB_PWDFILE_TXT,
|
|
|
e3ffab |
+ paths.IPA_P11_KIT,
|
|
|
e3ffab |
+ paths.SYSTEMWIDE_IPA_CA_CRT,
|
|
|
e3ffab |
paths.NSSWITCH_CONF,
|
|
|
e3ffab |
paths.KRB5_KEYTAB,
|
|
|
e3ffab |
paths.SSSD_CONF,
|
|
|
e3ffab |
diff --git a/ipaserver/install/ipa_restore.py b/ipaserver/install/ipa_restore.py
|
|
|
e3ffab |
index 352a1ca2bf283c0beb8c95925c6eb9c9984b3338..8b1e80f5ed5e140ccb17ea0b63d92b6049507b74 100644
|
|
|
e3ffab |
--- a/ipaserver/install/ipa_restore.py
|
|
|
e3ffab |
+++ b/ipaserver/install/ipa_restore.py
|
|
|
e3ffab |
@@ -26,7 +26,7 @@ import pwd
|
|
|
e3ffab |
from ConfigParser import SafeConfigParser
|
|
|
e3ffab |
|
|
|
e3ffab |
from ipalib import api, errors
|
|
|
e3ffab |
-from ipapython import version
|
|
|
e3ffab |
+from ipapython import version, ipautil, certdb
|
|
|
e3ffab |
from ipapython.ipautil import run, user_input
|
|
|
e3ffab |
from ipapython import admintool
|
|
|
e3ffab |
from ipapython.dn import DN
|
|
|
e3ffab |
@@ -278,7 +278,9 @@ class Restore(admintool.AdminTool):
|
|
|
e3ffab |
create_ca_user()
|
|
|
e3ffab |
if options.online:
|
|
|
e3ffab |
raise admintool.ScriptError('File restoration cannot be done online.')
|
|
|
e3ffab |
+ self.cert_restore_prepare()
|
|
|
e3ffab |
self.file_restore(options.no_logs)
|
|
|
e3ffab |
+ self.cert_restore()
|
|
|
e3ffab |
if 'CA' in self.backup_services:
|
|
|
e3ffab |
self.__create_dogtag_log_dirs()
|
|
|
e3ffab |
|
|
|
e3ffab |
@@ -660,3 +662,34 @@ class Restore(admintool.AdminTool):
|
|
|
e3ffab |
tasks.set_selinux_booleans(bools)
|
|
|
e3ffab |
except ipapython.errors.SetseboolError as e:
|
|
|
e3ffab |
self.log.error('%s', e)
|
|
|
e3ffab |
+
|
|
|
e3ffab |
+ def cert_restore_prepare(self):
|
|
|
e3ffab |
+ for basename in ('cert8.db', 'key3.db', 'secmod.db', 'pwdfile.txt'):
|
|
|
e3ffab |
+ filename = os.path.join(paths.IPA_NSSDB_DIR, basename)
|
|
|
e3ffab |
+ try:
|
|
|
e3ffab |
+ ipautil.backup_file(filename)
|
|
|
e3ffab |
+ except OSError as e:
|
|
|
e3ffab |
+ self.log.error("Failed to backup %s: %s" % (filename, e))
|
|
|
e3ffab |
+
|
|
|
e3ffab |
+ tasks.remove_ca_certs_from_systemwide_ca_store()
|
|
|
e3ffab |
+
|
|
|
e3ffab |
+ def cert_restore(self):
|
|
|
e3ffab |
+ if not os.path.exists(os.path.join(paths.IPA_NSSDB_DIR, 'cert8.db')):
|
|
|
e3ffab |
+ certdb.create_ipa_nssdb()
|
|
|
e3ffab |
+ ipa_db = certdb.NSSDatabase(paths.IPA_NSSDB_DIR)
|
|
|
e3ffab |
+ sys_db = certdb.NSSDatabase(paths.NSS_DB_DIR)
|
|
|
e3ffab |
+ for nickname, trust_flags in (('IPA CA', 'CT,C,C'),
|
|
|
e3ffab |
+ ('External CA cert', 'C,,')):
|
|
|
e3ffab |
+ try:
|
|
|
e3ffab |
+ cert = sys_db.get_cert(nickname)
|
|
|
e3ffab |
+ except RuntimeError:
|
|
|
e3ffab |
+ pass
|
|
|
e3ffab |
+ else:
|
|
|
e3ffab |
+ try:
|
|
|
e3ffab |
+ ipa_db.add_cert(cert, nickname, trust_flags)
|
|
|
e3ffab |
+ except ipautil.CalledProcessError as e:
|
|
|
e3ffab |
+ self.log.error(
|
|
|
e3ffab |
+ "Failed to add %s to %s: %s" %
|
|
|
e3ffab |
+ (nickname, paths.IPA_NSSDB_DIR, e))
|
|
|
e3ffab |
+
|
|
|
e3ffab |
+ tasks.reload_systemwide_ca_store()
|
|
|
e3ffab |
--
|
|
|
e3ffab |
2.1.0
|
|
|
e3ffab |
|