beb795
From 13d111faedfd5cbd0a7382e566edda7bd9ffc7ad Mon Sep 17 00:00:00 2001
beb795
From: Florence Blanc-Renaud <flo@redhat.com>
beb795
Date: Wed, 14 Mar 2018 16:13:17 +0100
beb795
Subject: [PATCH] ipa-replica-install: make sure that certmonger picks the
beb795
 right master
beb795
beb795
During ipa-replica-install, http installation first creates a service
beb795
principal for http/hostname (locally on the soon-to-be-replica), then
beb795
waits for this entry to be replicated on the master picked for the
beb795
install.
beb795
In a later step, the installer requests a certificate for HTTPd. The local
beb795
certmonger first tries the master defined in xmlrpc_uri (which is
beb795
pointing to the soon-to-be-replica), but fails because the service is not
beb795
up yet. Then certmonger tries to find a master by using the DNS and looking
beb795
for a ldap service. This step can pick a different master, where the
beb795
principal entry has not always be replicated yet.
beb795
As the certificate request adds the principal if it does not exist, we can
beb795
end by re-creating the principal and have a replication conflict.
beb795
beb795
The replication conflict later causes kerberos issues, preventing
beb795
from installing a new replica.
beb795
beb795
The proposed fix forces xmlrpc_uri to point to the same master as the one
beb795
picked for the installation, in order to make sure that the master already
beb795
contains the principal entry.
beb795
beb795
https://pagure.io/freeipa/issue/7041
beb795
beb795
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
beb795
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
beb795
---
beb795
 ipaserver/install/server/replicainstall.py | 42 +++++++++++++++++++++++++++---
beb795
 1 file changed, 39 insertions(+), 3 deletions(-)
beb795
beb795
diff --git a/ipaserver/install/server/replicainstall.py b/ipaserver/install/server/replicainstall.py
beb795
index 6aa1157133423e854514de61a69810433e436d2f..5a37aea0ac913d5c9cb88346345ba5760a9e923d 100644
beb795
--- a/ipaserver/install/server/replicainstall.py
beb795
+++ b/ipaserver/install/server/replicainstall.py
beb795
@@ -194,7 +194,16 @@ def install_dns_records(config, options, remote_api):
beb795
                          'on master: %s', str(e))
beb795
 
beb795
 
beb795
-def create_ipa_conf(fstore, config, ca_enabled):
beb795
+def create_ipa_conf(fstore, config, ca_enabled, master=None):
beb795
+    """
beb795
+    Create /etc/ipa/default.conf master configuration
beb795
+    :param fstore: sysrestore file store used for backup and restore of
beb795
+                   the server configuration
beb795
+    :param config: replica config
beb795
+    :param ca_enabled: True if the topology includes a CA
beb795
+    :param master: if set, the xmlrpc_uri parameter will use the provided
beb795
+                   master instead of this host
beb795
+    """
beb795
     # Save client file on Domain Level 1
beb795
     target_fname = paths.IPA_DEFAULT_CONF
beb795
     fstore.backup_file(target_fname)
beb795
@@ -203,8 +212,12 @@ def create_ipa_conf(fstore, config, ca_enabled):
beb795
     ipaconf.setOptionAssignment(" = ")
beb795
     ipaconf.setSectionNameDelimiters(("[", "]"))
beb795
 
beb795
-    xmlrpc_uri = 'https://{0}/ipa/xml'.format(
beb795
-                    ipautil.format_netloc(config.host_name))
beb795
+    if master:
beb795
+        xmlrpc_uri = 'https://{0}/ipa/xml'.format(
beb795
+            ipautil.format_netloc(master))
beb795
+    else:
beb795
+        xmlrpc_uri = 'https://{0}/ipa/xml'.format(
beb795
+                        ipautil.format_netloc(config.host_name))
beb795
     ldapi_uri = 'ldapi://%2fvar%2frun%2fslapd-{0}.socket\n'.format(
beb795
                     installutils.realm_to_serverid(config.realm_name))
beb795
 
beb795
@@ -1431,6 +1444,25 @@ def install(installer):
beb795
     # we now need to enable ssl on the ds
beb795
     ds.enable_ssl()
beb795
 
beb795
+    if promote:
beb795
+        # We need to point to the master when certmonger asks for
beb795
+        # HTTP certificate.
beb795
+        # During http installation, the HTTP/hostname principal is created
beb795
+        # locally then the installer waits for the entry to appear on the
beb795
+        # master selected for the installation.
beb795
+        # In a later step, the installer requests a SSL certificate through
beb795
+        # Certmonger (and the op adds the principal if it does not exist yet).
beb795
+        # If xmlrpc_uri points to the soon-to-be replica,
beb795
+        # the httpd service is not ready yet to handle certmonger requests
beb795
+        # and certmonger tries to find another master. The master can be
beb795
+        # different from the one selected for the installation, and it is
beb795
+        # possible that the principal has not been replicated yet. This
beb795
+        # may lead to a replication conflict.
beb795
+        # This is why we need to force the use of the same master by
beb795
+        # setting xmlrpc_uri
beb795
+        create_ipa_conf(fstore, config, ca_enabled,
beb795
+                        master=config.master_host_name)
beb795
+
beb795
     install_http(
beb795
         config,
beb795
         auto_redirect=not options.no_ui_redirect,
beb795
@@ -1439,6 +1471,10 @@ def install(installer):
beb795
         ca_is_configured=ca_enabled,
beb795
         ca_file=cafile)
beb795
 
beb795
+    if promote:
beb795
+        # Need to point back to ourself after the cert for HTTP is obtained
beb795
+        create_ipa_conf(fstore, config, ca_enabled)
beb795
+
beb795
     otpd = otpdinstance.OtpdInstance()
beb795
     otpd.create_instance('OTPD', config.host_name,
beb795
                          ipautil.realm_to_suffix(config.realm_name))
beb795
-- 
beb795
2.14.3
beb795