URL: https://github.com/freeipa/freeipa/pull/437 Author: tomaskrizek Title: #437: FIPS: replica install check Action: synchronized
To pull the PR as Git branch: git remote add ghfreeipa https://github.com/freeipa/freeipa git fetch ghfreeipa pull/437/head:pr437 git checkout pr437
From f6c35fff584e2d980b693c4de8f1fc96f34e5805 Mon Sep 17 00:00:00 2001 From: Tomas Krizek <tkri...@redhat.com> Date: Mon, 6 Feb 2017 13:08:11 +0100 Subject: [PATCH 1/4] Add fips_mode variable to env Variable fips_mode indicating whether machine is running in FIPS-enabled mode was added to env. https://fedorahosted.org/freeipa/ticket/5695 --- ipalib/config.py | 8 ++++++++ ipalib/constants.py | 1 + 2 files changed, 9 insertions(+) diff --git a/ipalib/config.py b/ipalib/config.py index 20591db..c7caeef 100644 --- a/ipalib/config.py +++ b/ipalib/config.py @@ -44,6 +44,10 @@ from ipalib.constants import CONFIG_SECTION from ipalib.constants import OVERRIDE_ERROR, SET_ERROR, DEL_ERROR from ipalib import errors +try: + from ipaplatform.tasks import tasks +except ImportError: + tasks = None if six.PY3: unicode = str @@ -440,6 +444,10 @@ def _bootstrap(self, **overrides): self.bin = path.dirname(self.script) self.home = os.environ.get('HOME', None) + # Set fips_mode only if ipaplatform module was loaded + if tasks is not None: + self.fips_mode = tasks.is_fips_enabled() + # Merge in overrides: self._merge(**overrides) diff --git a/ipalib/constants.py b/ipalib/constants.py index 81643da..10433e1 100644 --- a/ipalib/constants.py +++ b/ipalib/constants.py @@ -215,6 +215,7 @@ ('script', object), # sys.argv[0] ('bin', object), # The directory containing the script ('home', object), # $HOME + ('fips_mode', object), # FIPS-mode of the server # Vars set in Env._bootstrap(): ('in_tree', object), # Whether or not running in-tree (bool) From cc1411d4cb3c81c2fe5c9180c1646872c96c5c37 Mon Sep 17 00:00:00 2001 From: Tomas Krizek <tkri...@redhat.com> Date: Mon, 6 Feb 2017 17:17:49 +0100 Subject: [PATCH 2/4] check_remote_version: update exception and docstring Refactor function to use ScriptError exception and provide docstring. --- ipaserver/install/server/replicainstall.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/ipaserver/install/server/replicainstall.py b/ipaserver/install/server/replicainstall.py index 18222c8..c766f4b 100644 --- a/ipaserver/install/server/replicainstall.py +++ b/ipaserver/install/server/replicainstall.py @@ -509,6 +509,13 @@ def promote_openldap_conf(hostname, master): def check_remote_version(api): + """ + Perform a check to verify remote server's version + + :param api: remote API + + :raises: ``ScriptError`` if the checks fails + """ client = rpc.jsonclient(api) client.finalize() @@ -521,7 +528,7 @@ def check_remote_version(api): remote_version = parse_version(env['version']) api_version = parse_version(api.env.version) if remote_version > api_version: - raise RuntimeError( + raise ScriptError( "Cannot install replica of a server of higher version ({}) than" "the local version ({})".format(remote_version, api_version)) From 7c305086c8e48d3370f94fd138caab2ec1060b16 Mon Sep 17 00:00:00 2001 From: Tomas Krizek <tkri...@redhat.com> Date: Tue, 7 Feb 2017 10:42:54 +0100 Subject: [PATCH 3/4] replicainstall: add context manager for rpc client Abstract creating rpc client into a context manager to allow re-use. --- ipaserver/install/server/replicainstall.py | 33 ++++++++++++++++++++---------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/ipaserver/install/server/replicainstall.py b/ipaserver/install/server/replicainstall.py index c766f4b..352641f 100644 --- a/ipaserver/install/server/replicainstall.py +++ b/ipaserver/install/server/replicainstall.py @@ -4,6 +4,7 @@ from __future__ import print_function +import contextlib import dns.exception as dnsexception import dns.name as dnsname import dns.resolver as dnsresolver @@ -508,29 +509,37 @@ def promote_openldap_conf(hostname, master): root_logger.info("Failed to update {}: {}".format(ldap_conf, e)) -def check_remote_version(api): +@contextlib.contextmanager +def rpc_client(api): """ - Perform a check to verify remote server's version + Context manager for JSON RPC client. - :param api: remote API - - :raises: ``ScriptError`` if the checks fails + :param api: api to initiate the RPC client """ client = rpc.jsonclient(api) client.finalize() - client.connect() + try: - env = client.forward(u'env', u'version')['result'] + yield client finally: client.disconnect() + +def check_remote_version(client, local_version): + """ + Verify remote server's version is not higher than this server's version + + :param client: RPC client + :param local_version: API version of local server + :raises: ScriptError: if the checks fails + """ + env = client.forward(u'env', u'version')['result'] remote_version = parse_version(env['version']) - api_version = parse_version(api.env.version) - if remote_version > api_version: + if remote_version > local_version: raise ScriptError( "Cannot install replica of a server of higher version ({}) than" - "the local version ({})".format(remote_version, api_version)) + "the local version ({})".format(remote_version, local_version)) def common_check(no_ntp): @@ -754,6 +763,7 @@ def install_check(installer): ldap_uri=ldapuri) remote_api.finalize() installer._remote_api = remote_api + conn = remote_api.Backend.ldap2 replman = None try: @@ -1084,7 +1094,8 @@ def promote_check(installer): remote_api.finalize() installer._remote_api = remote_api - check_remote_version(remote_api) + with rpc_client(remote_api) as client: + check_remote_version(client, api.env.version) conn = remote_api.Backend.ldap2 replman = None From 88f6d90136a14edf5b6d686bd5a7d2415e18b3e9 Mon Sep 17 00:00:00 2001 From: Tomas Krizek <tkri...@redhat.com> Date: Tue, 7 Feb 2017 12:00:09 +0100 Subject: [PATCH 4/4] FIPS: perform replica installation check Check status of remote server's FIPS mode and proceed with installation only if it matches the current replica's FIPS mode. https://fedorahosted.org/freeipa/ticket/5695 --- ipaserver/install/server/replicainstall.py | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/ipaserver/install/server/replicainstall.py b/ipaserver/install/server/replicainstall.py index 352641f..87bc26c 100644 --- a/ipaserver/install/server/replicainstall.py +++ b/ipaserver/install/server/replicainstall.py @@ -526,6 +526,27 @@ def rpc_client(api): client.disconnect() +def check_remote_fips_mode(client, local_fips_mode): + """ + Verify remote server's fips-mode is the same as this server's fips-mode + + :param client: RPC client + :param local_fips_mode: boolean indicating whether FIPS mode is turned on + :raises: ScriptError: if the checks fails + """ + env = client.forward(u'env', u'fips_mode')['result'] + remote_fips_mode = env.get('fips_mode', False) + if local_fips_mode != remote_fips_mode: + if local_fips_mode: + raise ScriptError( + "Cannot join FIPS-enabled replica into existing topology: " + "FIPS is not enabled on the master server.") + else: + raise ScriptError( + "Cannot join replica into existing FIPS-enabled topology: " + "FIPS has to be enabled locally first.") + + def check_remote_version(client, local_version): """ Verify remote server's version is not higher than this server's version @@ -675,6 +696,9 @@ def install_check(installer): filename = installer.replica_file installer._enrollment_performed = False + if api.env.fips_mode: + raise ScriptError("FIPS is not supported in domain level 0") + # check FIPS, selinux status, http and DS ports, NTP conflicting services common_check(options.no_ntp) @@ -1096,6 +1120,7 @@ def promote_check(installer): with rpc_client(remote_api) as client: check_remote_version(client, api.env.version) + check_remote_fips_mode(client, api.env.fips_mode) conn = remote_api.Backend.ldap2 replman = None
-- Manage your subscription for the Freeipa-devel mailing list: https://www.redhat.com/mailman/listinfo/freeipa-devel Contribute to FreeIPA: http://www.freeipa.org/page/Contribute/Code