ac7d03
From 07469b2cc7bd1478836a1c755b301dbf9234d61a Mon Sep 17 00:00:00 2001
ac7d03
From: Jan Cholasta <jcholast@redhat.com>
ac7d03
Date: Mon, 22 May 2017 08:15:14 +0000
ac7d03
Subject: [PATCH] httpinstance: wait until the service entry is replicated
ac7d03
ac7d03
Wait until the local HTTP service entry is replicated to the remote master
ac7d03
before requesting the server certificate.
ac7d03
ac7d03
This prevents a replication conflict between the service entry added
ac7d03
locally and service entry added remotely when requesting the certificate.
ac7d03
ac7d03
https://pagure.io/freeipa/issue/6867
ac7d03
ac7d03
Reviewed-By: Martin Babinsky <mbabinsk@redhat.com>
ac7d03
Reviewed-By: Martin Basti <mbasti@redhat.com>
ac7d03
---
ac7d03
 ipaserver/install/httpinstance.py          | 29 +++++++++++++++++++++++++++--
ac7d03
 ipaserver/install/server/install.py        |  4 ++--
ac7d03
 ipaserver/install/server/replicainstall.py |  5 +++--
ac7d03
 3 files changed, 32 insertions(+), 6 deletions(-)
ac7d03
ac7d03
diff --git a/ipaserver/install/httpinstance.py b/ipaserver/install/httpinstance.py
ac7d03
index c76a1a4e484c5777ced92761916c1c586e8b2d5d..12fdddccc26b0c1132bcdca7fe2249a85997892e 100644
ac7d03
--- a/ipaserver/install/httpinstance.py
ac7d03
+++ b/ipaserver/install/httpinstance.py
ac7d03
@@ -32,9 +32,11 @@ import six
ac7d03
 from augeas import Augeas
ac7d03
 
ac7d03
 from ipalib.install import certmonger
ac7d03
+from ipapython import ipaldap
ac7d03
 from ipapython.certdb import (IPA_CA_TRUST_FLAGS,
ac7d03
                               EXTERNAL_CA_TRUST_FLAGS,
ac7d03
                               TRUSTED_PEER_TRUST_FLAGS)
ac7d03
+from ipaserver.install import replication
ac7d03
 from ipaserver.install import service
ac7d03
 from ipaserver.install import certs
ac7d03
 from ipaserver.install import installutils
ac7d03
@@ -127,12 +129,15 @@ class HTTPInstance(service.Service):
ac7d03
 
ac7d03
     subject_base = ipautil.dn_attribute_property('_subject_base')
ac7d03
 
ac7d03
-    def create_instance(self, realm, fqdn, domain_name, pkcs12_info=None,
ac7d03
+    def create_instance(self, realm, fqdn, domain_name, dm_password=None,
ac7d03
+                        pkcs12_info=None,
ac7d03
                         subject_base=None, auto_redirect=True, ca_file=None,
ac7d03
-                        ca_is_configured=None, promote=False):
ac7d03
+                        ca_is_configured=None, promote=False,
ac7d03
+                        master_fqdn=None):
ac7d03
         self.fqdn = fqdn
ac7d03
         self.realm = realm
ac7d03
         self.domain = domain_name
ac7d03
+        self.dm_password = dm_password
ac7d03
         self.suffix = ipautil.realm_to_suffix(self.realm)
ac7d03
         self.pkcs12_info = pkcs12_info
ac7d03
         self.dercert = None
ac7d03
@@ -148,6 +153,7 @@ class HTTPInstance(service.Service):
ac7d03
         if ca_is_configured is not None:
ac7d03
             self.ca_is_configured = ca_is_configured
ac7d03
         self.promote = promote
ac7d03
+        self.master_fqdn = master_fqdn
ac7d03
 
ac7d03
         self.step("stopping httpd", self.__stop)
ac7d03
         self.step("setting mod_nss port to 443", self.__set_mod_nss_port)
ac7d03
@@ -577,3 +583,22 @@ class HTTPInstance(service.Service):
ac7d03
         db = certs.CertDB(self.realm, nssdir=paths.HTTPD_ALIAS_DIR)
ac7d03
         db.track_server_cert(self.cert_nickname, self.principal,
ac7d03
                              db.passwd_fname, 'restart_httpd')
ac7d03
+
ac7d03
+    def request_service_keytab(self):
ac7d03
+        super(HTTPInstance, self).request_service_keytab()
ac7d03
+
ac7d03
+        if self.master_fqdn is not None:
ac7d03
+            service_dn = DN(('krbprincipalname', self.principal),
ac7d03
+                            api.env.container_service,
ac7d03
+                            self.suffix)
ac7d03
+
ac7d03
+            ldap_uri = ipaldap.get_ldap_uri(self.master_fqdn)
ac7d03
+            with ipaldap.LDAPClient(ldap_uri,
ac7d03
+                                    start_tls=not self.promote,
ac7d03
+                                    cacert=paths.IPA_CA_CRT) as remote_ldap:
ac7d03
+                if self.promote:
ac7d03
+                    remote_ldap.gssapi_bind()
ac7d03
+                else:
ac7d03
+                    remote_ldap.simple_bind(ipaldap.DIRMAN_DN,
ac7d03
+                                            self.dm_password)
ac7d03
+                replication.wait_for_entry(remote_ldap, service_dn, timeout=60)
ac7d03
diff --git a/ipaserver/install/server/install.py b/ipaserver/install/server/install.py
ac7d03
index 03380b8d0e9150224b014a1a174d7ea81ccdcf00..9dcf903f4582740f007c049fae3ec247ddf52aef 100644
ac7d03
--- a/ipaserver/install/server/install.py
ac7d03
+++ b/ipaserver/install/server/install.py
ac7d03
@@ -830,13 +830,13 @@ def install(installer):
ac7d03
     http = httpinstance.HTTPInstance(fstore)
ac7d03
     if options.http_cert_files:
ac7d03
         http.create_instance(
ac7d03
-            realm_name, host_name, domain_name,
ac7d03
+            realm_name, host_name, domain_name, dm_password,
ac7d03
             pkcs12_info=http_pkcs12_info, subject_base=options.subject_base,
ac7d03
             auto_redirect=not options.no_ui_redirect,
ac7d03
             ca_is_configured=setup_ca)
ac7d03
     else:
ac7d03
         http.create_instance(
ac7d03
-            realm_name, host_name, domain_name,
ac7d03
+            realm_name, host_name, domain_name, dm_password,
ac7d03
             subject_base=options.subject_base,
ac7d03
             auto_redirect=not options.no_ui_redirect,
ac7d03
             ca_is_configured=setup_ca)
ac7d03
diff --git a/ipaserver/install/server/replicainstall.py b/ipaserver/install/server/replicainstall.py
ac7d03
index b30133ffa22d410452ae04624d49db209175bed9..20eaf98397101b49c751c325afc0591e0babcc18 100644
ac7d03
--- a/ipaserver/install/server/replicainstall.py
ac7d03
+++ b/ipaserver/install/server/replicainstall.py
ac7d03
@@ -163,9 +163,10 @@ def install_http(config, auto_redirect, ca_is_configured, ca_file,
ac7d03
     http = httpinstance.HTTPInstance()
ac7d03
     http.create_instance(
ac7d03
         config.realm_name, config.host_name, config.domain_name,
ac7d03
-        pkcs12_info, auto_redirect=auto_redirect, ca_file=ca_file,
ac7d03
+        config.dirman_password, pkcs12_info,
ac7d03
+        auto_redirect=auto_redirect, ca_file=ca_file,
ac7d03
         ca_is_configured=ca_is_configured, promote=promote,
ac7d03
-        subject_base=config.subject_base)
ac7d03
+        subject_base=config.subject_base, master_fqdn=config.master_host_name)
ac7d03
 
ac7d03
     return http
ac7d03
 
ac7d03
-- 
ac7d03
2.9.4
ac7d03