From 6c5e72aee4dffb353b79b99324858bf2a1ec7314 Mon Sep 17 00:00:00 2001 From: Florence Blanc-Renaud Date: Sep 23 2019 17:51:44 +0000 Subject: replica install: enforce --server arg When the --server option is provided to ipa-replica-install (1-step install), make sure that the server offers all the required roles (CA, KRA). If it's not the case, refuse the installation. Note that the --server option is ignored when promoting from client to replica (2-step install with ipa-client-install and ipa-replica-install), meaning that the existing behavior is not changed in this use case: by default the host specified in default.conf as server is used for enrollment, but if it does not provide a required role, another host can be picked for CA or KRA setup. Fixes: https://pagure.io/freeipa/issue/7566 Signed-off-by: Florence Blanc-Renaud Reviewed-By: Rob Crittenden Reviewed-By: Mohammad Rizwan Yusuf --- diff --git a/install/tools/man/ipa-replica-install.1 b/install/tools/man/ipa-replica-install.1 index c63107d..7f6cd26 100644 --- a/install/tools/man/ipa-replica-install.1 +++ b/install/tools/man/ipa-replica-install.1 @@ -47,7 +47,7 @@ One Time Password for joining a machine to the IPA realm. Path to host keytab. .TP \fB\-\-server\fR -The fully qualified domain name of the IPA server to enroll to. +The fully qualified domain name of the IPA server to enroll to. The IPA server must provide the CA role if \fB\-\-setup-ca\fR option is specified, and the KRA role if \fB\-\-setup-kra\fR option is specified. .TP \fB\-n\fR, \fB\-\-domain\fR=\fIDOMAIN\fR The primary DNS domain of an existing IPA deployment, e.g. example.com. @@ -275,3 +275,5 @@ path. 1 if an error occurred 3 if the host exists in the IPA server or a replication agreement to the remote master already exists + +4 if the remote master specified for enrollment does not provide required services such as CA or KRA diff --git a/ipaserver/install/server/replicainstall.py b/ipaserver/install/server/replicainstall.py index 4d8eedb..6e3b23a 100644 --- a/ipaserver/install/server/replicainstall.py +++ b/ipaserver/install/server/replicainstall.py @@ -790,6 +790,8 @@ def promote_check(installer): print("IPA client is already configured on this system, ignoring " "the --domain, --server, --realm, --hostname, --password " "and --keytab options.") + # Make sure options.server is not used + options.server = None # The NTP configuration can not be touched on pre-installed client: if options.no_ntp or options.ntp_servers or options.ntp_pool: @@ -1044,8 +1046,15 @@ def promote_check(installer): config.subject_base = DN(subject_base) # Find any server with a CA + # The order of preference is + # 1. the first server specified in --server, if any + # 2. the server specified in the config file + # 3. any other + preferred_cas = [config.ca_host_name] + if options.server: + preferred_cas.insert(0, options.server) ca_host = find_providing_server( - 'CA', conn, [config.ca_host_name] + 'CA', conn, preferred_cas ) if ca_host is not None: config.ca_host_name = ca_host @@ -1054,6 +1063,14 @@ def promote_check(installer): logger.error("Certificates could not be provided when " "CA is present on some master.") raise ScriptError(rval=3) + if options.setup_ca and options.server and \ + ca_host != options.server: + # Installer was provided with a specific master + # but this one doesn't provide CA + logger.error("The specified --server %s does not provide CA, " + "please provide a server with the CA role", + options.server) + raise ScriptError(rval=4) else: if options.setup_ca: logger.error("The remote master does not have a CA " @@ -1068,12 +1085,27 @@ def promote_check(installer): raise ScriptError(rval=3) # Find any server with a KRA + # The order of preference is + # 1. the first server specified in --server, if any + # 2. the server specified in the config file + # 3. any other + preferred_kras = [config.kra_host_name] + if options.server: + preferred_kras.insert(0, options.server) kra_host = find_providing_server( - 'KRA', conn, [config.kra_host_name] + 'KRA', conn, preferred_kras ) if kra_host is not None: config.kra_host_name = kra_host kra_enabled = True + if options.setup_kra and options.server and \ + kra_host != options.server: + # Installer was provided with a specific master + # but this one doesn't provide KRA + logger.error("The specified --server %s does not provide KRA, " + "please provide a server with the KRA role", + options.server) + raise ScriptError(rval=4) else: if options.setup_kra: logger.error("There is no active KRA server in the domain, "