httpinstance: wait until the service entry is replicated

Wait until the local HTTP service entry is replicated to the remote master
before requesting the server certificate.

This prevents a replication conflict between the service entry added
locally and service entry added remotely when requesting the certificate.

https://pagure.io/freeipa/issue/6867

Reviewed-By: Martin Babinsky <mbabinsk@redhat.com>
Reviewed-By: Martin Basti <mbasti@redhat.com>
This commit is contained in:
Jan Cholasta 2017-05-22 08:15:14 +00:00 committed by Martin Babinsky
parent bc6d499514
commit ab71cd5a16
3 changed files with 32 additions and 6 deletions

View File

@ -32,9 +32,11 @@ import six
from augeas import Augeas
from ipalib.install import certmonger
from ipapython import ipaldap
from ipapython.certdb import (IPA_CA_TRUST_FLAGS,
EXTERNAL_CA_TRUST_FLAGS,
TRUSTED_PEER_TRUST_FLAGS)
from ipaserver.install import replication
from ipaserver.install import service
from ipaserver.install import certs
from ipaserver.install import installutils
@ -120,12 +122,15 @@ class HTTPInstance(service.Service):
subject_base = ipautil.dn_attribute_property('_subject_base')
def create_instance(self, realm, fqdn, domain_name, pkcs12_info=None,
def create_instance(self, realm, fqdn, domain_name, dm_password=None,
pkcs12_info=None,
subject_base=None, auto_redirect=True, ca_file=None,
ca_is_configured=None, promote=False):
ca_is_configured=None, promote=False,
master_fqdn=None):
self.fqdn = fqdn
self.realm = realm
self.domain = domain_name
self.dm_password = dm_password
self.suffix = ipautil.realm_to_suffix(self.realm)
self.pkcs12_info = pkcs12_info
self.dercert = None
@ -141,6 +146,7 @@ class HTTPInstance(service.Service):
if ca_is_configured is not None:
self.ca_is_configured = ca_is_configured
self.promote = promote
self.master_fqdn = master_fqdn
self.step("stopping httpd", self.__stop)
self.step("setting mod_nss port to 443", self.__set_mod_nss_port)
@ -570,3 +576,22 @@ class HTTPInstance(service.Service):
db = certs.CertDB(self.realm, nssdir=paths.HTTPD_ALIAS_DIR)
db.track_server_cert(self.cert_nickname, self.principal,
db.passwd_fname, 'restart_httpd')
def request_service_keytab(self):
super(HTTPInstance, self).request_service_keytab()
if self.master_fqdn is not None:
service_dn = DN(('krbprincipalname', self.principal),
api.env.container_service,
self.suffix)
ldap_uri = ipaldap.get_ldap_uri(self.master_fqdn)
with ipaldap.LDAPClient(ldap_uri,
start_tls=not self.promote,
cacert=paths.IPA_CA_CRT) as remote_ldap:
if self.promote:
remote_ldap.gssapi_bind()
else:
remote_ldap.simple_bind(ipaldap.DIRMAN_DN,
self.dm_password)
replication.wait_for_entry(remote_ldap, service_dn, timeout=60)

View File

@ -830,13 +830,13 @@ def install(installer):
http = httpinstance.HTTPInstance(fstore)
if options.http_cert_files:
http.create_instance(
realm_name, host_name, domain_name,
realm_name, host_name, domain_name, dm_password,
pkcs12_info=http_pkcs12_info, subject_base=options.subject_base,
auto_redirect=not options.no_ui_redirect,
ca_is_configured=setup_ca)
else:
http.create_instance(
realm_name, host_name, domain_name,
realm_name, host_name, domain_name, dm_password,
subject_base=options.subject_base,
auto_redirect=not options.no_ui_redirect,
ca_is_configured=setup_ca)

View File

@ -163,9 +163,10 @@ def install_http(config, auto_redirect, ca_is_configured, ca_file,
http = httpinstance.HTTPInstance()
http.create_instance(
config.realm_name, config.host_name, config.domain_name,
pkcs12_info, auto_redirect=auto_redirect, ca_file=ca_file,
config.dirman_password, pkcs12_info,
auto_redirect=auto_redirect, ca_file=ca_file,
ca_is_configured=ca_is_configured, promote=promote,
subject_base=config.subject_base)
subject_base=config.subject_base, master_fqdn=config.master_host_name)
return http