From a926a002d65d5980df8b6f6f5fe6a4aa811ec41e Mon Sep 17 00:00:00 2001 From: Christian Heimes Date: Nov 15 2017 10:12:10 +0000 Subject: Backup ipa-custodia conf and keys https://pagure.io/freeipa/issue/7247 Signed-off-by: Christian Heimes Reviewed-By: Simo Sorce --- diff --git a/install/share/custodia.conf.template b/install/share/custodia.conf.template index 855a1b3..ee3c43c 100644 --- a/install/share/custodia.conf.template +++ b/install/share/custodia.conf.template @@ -16,7 +16,7 @@ header = GSS_NAME handler = ipaserver.secrets.kem.IPAKEMKeys paths = /keys store = ipa -server_keys = $IPA_CUSTODIA_CONF_DIR/server.keys +server_keys = $IPA_CUSTODIA_KEYS [store:ipa] handler = ipaserver.secrets.store.IPASecStore diff --git a/ipaplatform/base/paths.py b/ipaplatform/base/paths.py index 1a085b7..9837247 100644 --- a/ipaplatform/base/paths.py +++ b/ipaplatform/base/paths.py @@ -347,6 +347,7 @@ class BasePathNamespace(object): NETWORK_MANAGER_CONFIG_DIR = '/etc/NetworkManager/conf.d' IPA_CUSTODIA_CONF_DIR = '/etc/ipa/custodia' IPA_CUSTODIA_CONF = '/etc/ipa/custodia/custodia.conf' + IPA_CUSTODIA_KEYS = '/etc/ipa/custodia/server.keys' IPA_CUSTODIA_SOCKET = '/run/httpd/ipa-custodia.sock' IPA_CUSTODIA_AUDIT_LOG = '/var/log/ipa-custodia.audit.log' IPA_GETKEYTAB = '/usr/sbin/ipa-getkeytab' diff --git a/ipapython/ipautil.py b/ipapython/ipautil.py index c4149a1..bb91ad2 100644 --- a/ipapython/ipautil.py +++ b/ipapython/ipautil.py @@ -326,6 +326,25 @@ def write_tmp_file(txt): return fd + +def flush_sync(f): + """Flush and fsync file to disk + + :param f: a file object with fileno and name + """ + # flush file buffer to file descriptor + f.flush() + # flush Kernel buffer to disk + os.fsync(f.fileno()) + # sync metadata in directory + dirname = os.path.dirname(os.path.abspath(f.name)) + dirfd = os.open(dirname, os.O_RDONLY | os.O_DIRECTORY) + try: + os.fsync(dirfd) + finally: + os.close(dirfd) + + def shell_quote(string): if isinstance(string, str): return "'" + string.replace("'", "'\\''") + "'" diff --git a/ipaserver/install/custodiainstance.py b/ipaserver/install/custodiainstance.py index aa5261d..7ca23b4 100644 --- a/ipaserver/install/custodiainstance.py +++ b/ipaserver/install/custodiainstance.py @@ -30,8 +30,7 @@ class CustodiaInstance(SimpleServiceInstance): def __init__(self, host_name=None, realm=None): super(CustodiaInstance, self).__init__("ipa-custodia") self.config_file = paths.IPA_CUSTODIA_CONF - self.server_keys = os.path.join(paths.IPA_CUSTODIA_CONF_DIR, - 'server.keys') + self.server_keys = paths.IPA_CUSTODIA_KEYS self.ldap_uri = None self.fqdn = host_name self.realm = realm @@ -40,16 +39,19 @@ class CustodiaInstance(SimpleServiceInstance): template_file = os.path.basename(self.config_file) + '.template' template = os.path.join(paths.USR_SHARE_IPA_DIR, template_file) httpd_info = pwd.getpwnam(constants.HTTPD_USER) - sub_dict = dict(IPA_CUSTODIA_CONF_DIR=paths.IPA_CUSTODIA_CONF_DIR, - IPA_CUSTODIA_SOCKET=paths.IPA_CUSTODIA_SOCKET, - IPA_CUSTODIA_AUDIT_LOG=paths.IPA_CUSTODIA_AUDIT_LOG, - LDAP_URI=installutils.realm_to_ldapi_uri(self.realm), - UID=httpd_info.pw_uid, GID=httpd_info.pw_gid) + sub_dict = dict( + IPA_CUSTODIA_CONF_DIR=paths.IPA_CUSTODIA_CONF_DIR, + IPA_CUSTODIA_KEYS=paths.IPA_CUSTODIA_KEYS, + IPA_CUSTODIA_SOCKET=paths.IPA_CUSTODIA_SOCKET, + IPA_CUSTODIA_AUDIT_LOG=paths.IPA_CUSTODIA_AUDIT_LOG, + LDAP_URI=installutils.realm_to_ldapi_uri(self.realm), + UID=httpd_info.pw_uid, + GID=httpd_info.pw_gid + ) conf = ipautil.template_file(template, sub_dict) - fd = open(self.config_file, "w+") - fd.write(conf) - fd.flush() - fd.close() + with open(self.config_file, "w") as f: + f.write(conf) + ipautil.flush_sync(f) def create_instance(self): suffix = ipautil.realm_to_suffix(self.realm) diff --git a/ipaserver/install/ipa_backup.py b/ipaserver/install/ipa_backup.py index ac9b0fc..d8ff395 100644 --- a/ipaserver/install/ipa_backup.py +++ b/ipaserver/install/ipa_backup.py @@ -189,6 +189,8 @@ class Backup(admintool.AdminTool): paths.DNSSEC_SOFTHSM_PIN_SO, paths.IPA_ODS_EXPORTER_KEYTAB, paths.IPA_DNSKEYSYNCD_KEYTAB, + paths.IPA_CUSTODIA_KEYS, + paths.IPA_CUSTODIA_CONF, paths.HOSTS, ) + tuple( os.path.join(paths.IPA_NSSDB_DIR, file) diff --git a/ipatests/test_ipapython/test_ipautil.py b/ipatests/test_ipapython/test_ipautil.py index 75011d5..ec9a3c9 100644 --- a/ipatests/test_ipapython/test_ipautil.py +++ b/ipatests/test_ipapython/test_ipautil.py @@ -25,6 +25,7 @@ Test the `ipapython/ipautil.py` module. import nose import pytest import six +import tempfile from ipapython import ipautil @@ -470,3 +471,9 @@ def test_backcompat(): assert rc is result.returncode assert out is result.output assert err is result.error_output + + +def test_flush_sync(): + with tempfile.NamedTemporaryFile('wb+') as f: + f.write(b'data') + ipautil.flush_sync(f)