URL: https://github.com/freeipa/freeipa/pull/698
Author: HonzaCholasta
 Title: #698: install: request service certs after host keytab is set up
Action: opened

PR body:
"""
**dsinstance: reconnect ldap2 after DS is restarted by certmonger**

DS is restarted by certmonger in the restart_dirsrv script after the DS
certificate is saved. This breaks the ldap2 backend and makes any operation
fail with NetworkError until it is reconnected.

Reconnect ldap2 after the DS certificate request is finished to fix the
issue. Make sure restart_dirsrv waits for the ldapi socket so that the
reconnect does not fail.

**httpinstance: avoid httpd restart during certificate request**

httpd is restarted by certmonger in the restart_httpd script after the
httpd certificate is saved if it was previously running. The restart will
fail because httpd is not properly configured at this point.

Stop httpd at the beginning of httpd install to avoid the restart.

**dsinstance, httpinstance: consolidate certificate request code**

A different code path is used for DS and httpd certificate requests in
replica promotion. This is rather unnecessary and makes the certificate
request code not easy to follow.

Consolidate the non-promotion and promotion code paths into one.

**install: request service certs after host keytab is set up**

The certmonger renew agent and restart scripts use host keytab for
authentication. When they are executed during a certmonger request before
the host keytab is set up, the authentication will fail.

Make sure all certmonger requests in the installer are done after the host
keytab is set up.

**renew agent: revert to host keytab authentication**

Fixes an issue where the renew agent uses GSSAPI for LDAP connection but
fails because it is not authenticated.

This reverts commit 7462adec13c5b25b6868d2863dc38062c97d0ff7.

**renew agent, restart scripts: connect to LDAP after kinit**

Connect to LDAP after kinit is done, otherwise GSSAPI authentication will
fail.

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

"""

To pull the PR as Git branch:
git remote add ghfreeipa https://github.com/freeipa/freeipa
git fetch ghfreeipa pull/698/head:pr698
git checkout pr698
From a177247344479e1e5636df5f27875d2c5b76fa5e Mon Sep 17 00:00:00 2001
From: Jan Cholasta <jchol...@redhat.com>
Date: Fri, 7 Apr 2017 07:40:19 +0200
Subject: [PATCH 1/6] dsinstance: reconnect ldap2 after DS is restarted by
 certmonger

DS is restarted by certmonger in the restart_dirsrv script after the DS
certificate is saved. This breaks the ldap2 backend and makes any operation
fail with NetworkError until it is reconnected.

Reconnect ldap2 after the DS certificate request is finished to fix the
issue. Make sure restart_dirsrv waits for the ldapi socket so that the
reconnect does not fail.

https://pagure.io/freeipa/issue/6757
---
 install/restart_scripts/restart_dirsrv | 2 +-
 ipaserver/install/dsinstance.py        | 4 ++++
 2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/install/restart_scripts/restart_dirsrv b/install/restart_scripts/restart_dirsrv
index b4c9490..ff476ca 100644
--- a/install/restart_scripts/restart_dirsrv
+++ b/install/restart_scripts/restart_dirsrv
@@ -41,7 +41,7 @@ def _main():
 
     try:
         if services.knownservices.dirsrv.is_running():
-            services.knownservices.dirsrv.restart(instance)
+            services.knownservices.dirsrv.restart(instance, ldapi=True)
     except Exception as e:
         syslog.syslog(syslog.LOG_ERR, "Cannot restart dirsrv (instance: '%s'): %s" % (instance, str(e)))
 
diff --git a/ipaserver/install/dsinstance.py b/ipaserver/install/dsinstance.py
index 79dc90e..fb5f925 100644
--- a/ipaserver/install/dsinstance.py
+++ b/ipaserver/install/dsinstance.py
@@ -837,6 +837,10 @@ def __enable_ssl(self):
             finally:
                 certmonger.modify_ca_helper('IPA', prev_helper)
 
+            # restart_dirsrv in the request above restarts DS, reconnect ldap2
+            api.Backend.ldap2.disconnect()
+            api.Backend.ldap2.connect()
+
             self.dercert = dsdb.get_cert_from_db(self.nickname, pem=False)
 
         dsdb.create_pin_file()

From 1477aff4e733b52f305e466e71e11a2f5730892b Mon Sep 17 00:00:00 2001
From: Jan Cholasta <jchol...@redhat.com>
Date: Fri, 7 Apr 2017 07:40:41 +0200
Subject: [PATCH 2/6] httpinstance: avoid httpd restart during certificate
 request

httpd is restarted by certmonger in the restart_httpd script after the
httpd certificate is saved if it was previously running. The restart will
fail because httpd is not properly configured at this point.

Stop httpd at the beginning of httpd install to avoid the restart.

https://pagure.io/freeipa/issue/6757
---
 ipaserver/install/httpinstance.py | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/ipaserver/install/httpinstance.py b/ipaserver/install/httpinstance.py
index 079ea92..d7cd776 100644
--- a/ipaserver/install/httpinstance.py
+++ b/ipaserver/install/httpinstance.py
@@ -160,6 +160,7 @@ def create_instance(self, realm, fqdn, domain_name, pkcs12_info=None,
             self.ca_is_configured = ca_is_configured
         self.promote = promote
 
+        self.step("stopping httpd", self.__stop)
         self.step("setting mod_nss port to 443", self.__set_mod_nss_port)
         self.step("setting mod_nss cipher suite",
                   self.set_mod_nss_cipher_suite)
@@ -185,15 +186,15 @@ def create_instance(self, realm, fqdn, domain_name, pkcs12_info=None,
             self.step("create KDC proxy user", create_kdcproxy_user)
             self.step("create KDC proxy config", self.create_kdcproxy_conf)
             self.step("enable KDC proxy", self.enable_kdcproxy)
-        self.step("restarting httpd", self.__start)
+        self.step("starting httpd", self.start)
         self.step("configuring httpd to start on boot", self.__enable)
         self.step("enabling oddjobd", self.enable_and_start_oddjobd)
 
         self.start_creation()
 
-    def __start(self):
+    def __stop(self):
         self.backup_state("running", self.is_running())
-        self.restart()
+        self.stop()
 
     def __enable(self):
         self.backup_state("enabled", self.is_enabled())

From 9ab8df834513cac096d5954f162fa84bff255ba7 Mon Sep 17 00:00:00 2001
From: Jan Cholasta <jchol...@redhat.com>
Date: Fri, 7 Apr 2017 07:43:09 +0200
Subject: [PATCH 3/6] dsinstance, httpinstance: consolidate certificate request
 code

A different code path is used for DS and httpd certificate requests in
replica promotion. This is rather unnecessary and makes the certificate
request code not easy to follow.

Consolidate the non-promotion and promotion code paths into one.

https://pagure.io/freeipa/issue/6757
---
 ipaserver/install/dsinstance.py            | 76 +++++++++---------------------
 ipaserver/install/httpinstance.py          | 40 ++++++++--------
 ipaserver/install/server/install.py        |  4 --
 ipaserver/install/server/replicainstall.py | 22 +--------
 4 files changed, 43 insertions(+), 99 deletions(-)

diff --git a/ipaserver/install/dsinstance.py b/ipaserver/install/dsinstance.py
index fb5f925..31dbd4ec 100644
--- a/ipaserver/install/dsinstance.py
+++ b/ipaserver/install/dsinstance.py
@@ -396,10 +396,7 @@ def create_replica(self, realm_name, master_fqdn, fqdn,
 
         self.step("creating DS keytab", self.request_service_keytab)
         if self.promote:
-            if self.pkcs12_info:
-                self.step("configuring TLS for DS instance", self.__enable_ssl)
-            else:
-                self.step("retrieving DS Certificate", self.__get_ds_cert)
+            self.step("configuring TLS for DS instance", self.__enable_ssl)
             self.step("restarting directory server", self.__restart_instance)
 
         self.step("setting up initial replication", self.__setup_replica)
@@ -810,18 +807,23 @@ def __enable_ssl(self):
                 dsdb.track_server_cert(
                     self.nickname, self.principal, dsdb.passwd_fname,
                     'restart_dirsrv %s' % self.serverid)
+
+            self.add_cert_to_service()
         else:
             dsdb.create_from_cacert()
-            ca_args = [
-                paths.CERTMONGER_DOGTAG_SUBMIT,
-                '--ee-url', 'https://%s:8443/ca/ee/ca' % self.fqdn,
-                '--certfile', paths.RA_AGENT_PEM,
-                '--keyfile', paths.RA_AGENT_KEY,
-                '--cafile', paths.IPA_CA_CRT,
-                '--agent-submit'
-            ]
-            helper = " ".join(ca_args)
-            prev_helper = certmonger.modify_ca_helper('IPA', helper)
+            if self.master_fqdn is None:
+                ca_args = [
+                    paths.CERTMONGER_DOGTAG_SUBMIT,
+                    '--ee-url', 'https://%s:8443/ca/ee/ca' % self.fqdn,
+                    '--certfile', paths.RA_AGENT_PEM,
+                    '--keyfile', paths.RA_AGENT_KEY,
+                    '--cafile', paths.IPA_CA_CRT,
+                    '--agent-submit'
+                ]
+                helper = " ".join(ca_args)
+                prev_helper = certmonger.modify_ca_helper('IPA', helper)
+            else:
+                prev_helper = None
             try:
                 cmd = 'restart_dirsrv %s' % self.serverid
                 certmonger.request_and_wait_for_cert(
@@ -835,7 +837,8 @@ def __enable_ssl(self):
                     dns=[self.fqdn],
                     post_command=cmd)
             finally:
-                certmonger.modify_ca_helper('IPA', prev_helper)
+                if prev_helper is not None:
+                    certmonger.modify_ca_helper('IPA', prev_helper)
 
             # restart_dirsrv in the request above restarts DS, reconnect ldap2
             api.Backend.ldap2.disconnect()
@@ -843,6 +846,9 @@ def __enable_ssl(self):
 
             self.dercert = dsdb.get_cert_from_db(self.nickname, pem=False)
 
+            if prev_helper is not None:
+                self.add_cert_to_service()
+
         dsdb.create_pin_file()
 
         self.cacert_name = dsdb.cacert_name
@@ -1236,46 +1242,6 @@ def request_service_keytab(self):
         ipautil.config_replace_variables(paths.SYSCONFIG_DIRSRV,
                                          replacevars=vardict)
 
-    def __get_ds_cert(self):
-        nssdb_dir = config_dirname(self.serverid)
-        db = certs.CertDB(
-            self.realm,
-            nssdir=nssdb_dir,
-            subject_base=self.subject_base,
-            ca_subject=self.ca_subject,
-        )
-        db.create_from_cacert()
-        db.request_service_cert(self.nickname, self.principal, self.fqdn)
-        db.create_pin_file()
-
-        # Connect to self over ldapi as Directory Manager and configure SSL
-        ldap_uri = ipaldap.get_ldap_uri(protocol='ldapi', realm=self.realm)
-        conn = ipaldap.LDAPClient(ldap_uri)
-        conn.external_bind()
-
-        mod = [(ldap.MOD_REPLACE, "nsSSLClientAuth", "allowed"),
-               (ldap.MOD_REPLACE, "nsSSL3Ciphers", "default"),
-               (ldap.MOD_REPLACE, "allowWeakCipher", "off")]
-        conn.modify_s(DN(('cn', 'encryption'), ('cn', 'config')), mod)
-
-        mod = [(ldap.MOD_ADD, "nsslapd-security", "on")]
-        conn.modify_s(DN(('cn', 'config')), mod)
-
-        entry = conn.make_entry(
-            DN(('cn', 'RSA'), ('cn', 'encryption'), ('cn', 'config')),
-            objectclass=["top", "nsEncryptionModule"],
-            cn=["RSA"],
-            nsSSLPersonalitySSL=[self.nickname],
-            nsSSLToken=["internal (software)"],
-            nsSSLActivation=["on"],
-        )
-        conn.add_entry(entry)
-
-        conn.unbind()
-
-        # check for open secure port 636 from now on
-        self.open_ports.append(636)
-
 
 def write_certmap_conf(realm, ca_subject):
     """(Re)write certmap.conf with given CA subject DN."""
diff --git a/ipaserver/install/httpinstance.py b/ipaserver/install/httpinstance.py
index d7cd776..45bf479 100644
--- a/ipaserver/install/httpinstance.py
+++ b/ipaserver/install/httpinstance.py
@@ -376,12 +376,12 @@ def disable_system_trust(self):
         return False
 
     def __setup_ssl(self):
-        truncate = not self.promote or not self.ca_is_configured
         db = certs.CertDB(self.realm, nssdir=paths.HTTPD_ALIAS_DIR,
                           subject_base=self.subject_base, user="root",
                           group=constants.HTTPD_GROUP,
-                          truncate=truncate)
+                          truncate=True)
         self.disable_system_trust()
+        self.create_password_conf()
         if self.pkcs12_info:
             if self.ca_is_configured:
                 trust_flags = 'CT,C,C'
@@ -394,8 +394,6 @@ def __setup_ssl(self):
             if len(server_certs) == 0:
                 raise RuntimeError("Could not find a suitable server cert in import in %s" % self.pkcs12_info[0])
 
-            self.create_password_conf()
-
             # We only handle one server cert
             nickname = server_certs[0][0]
             if nickname == 'ipaCert':
@@ -410,7 +408,6 @@ def __setup_ssl(self):
 
         else:
             if not self.promote:
-                self.create_password_conf()
                 ca_args = [
                     paths.CERTMONGER_DOGTAG_SUBMIT,
                     '--ee-url', 'https://%s:8443/ca/ee/ca' % self.fqdn,
@@ -421,23 +418,26 @@ def __setup_ssl(self):
                 ]
                 helper = " ".join(ca_args)
                 prev_helper = certmonger.modify_ca_helper('IPA', helper)
-
-                try:
-                    certmonger.request_and_wait_for_cert(
-                        certpath=db.secdir,
-                        nickname=self.cert_nickname,
-                        principal=self.principal,
-                        passwd_fname=db.passwd_fname,
-                        subject=str(DN(('CN', self.fqdn), self.subject_base)),
-                        ca='IPA',
-                        profile=dogtag.DEFAULT_PROFILE,
-                        dns=[self.fqdn],
-                        post_command='restart_httpd')
-                    self.dercert = db.get_cert_from_db(
-                        self.cert_nickname, pem=False)
-                finally:
+            else:
+                prev_helper = None
+            try:
+                certmonger.request_and_wait_for_cert(
+                    certpath=db.secdir,
+                    nickname=self.cert_nickname,
+                    principal=self.principal,
+                    passwd_fname=db.passwd_fname,
+                    subject=str(DN(('CN', self.fqdn), self.subject_base)),
+                    ca='IPA',
+                    profile=dogtag.DEFAULT_PROFILE,
+                    dns=[self.fqdn],
+                    post_command='restart_httpd')
+            finally:
+                if prev_helper is not None:
                     certmonger.modify_ca_helper('IPA', prev_helper)
 
+            self.dercert = db.get_cert_from_db(self.cert_nickname, pem=False)
+
+            if prev_helper is not None:
                 self.add_cert_to_service()
 
             # Verify we have a valid server cert
diff --git a/ipaserver/install/server/install.py b/ipaserver/install/server/install.py
index d7eb0bf..f8e64ec 100644
--- a/ipaserver/install/server/install.py
+++ b/ipaserver/install/server/install.py
@@ -807,10 +807,6 @@ def install(installer):
     if setup_ca:
         ca.install_step_1(False, None, options)
 
-    # The DS instance is created before the keytab, add the SSL cert we
-    # generated
-    ds.add_cert_to_service()
-
     otpd = otpdinstance.OtpdInstance()
     otpd.create_instance('OTPD', host_name,
                          ipautil.realm_to_suffix(realm_name))
diff --git a/ipaserver/install/server/replicainstall.py b/ipaserver/install/server/replicainstall.py
index f489e69..cd6a62f 100644
--- a/ipaserver/install/server/replicainstall.py
+++ b/ipaserver/install/server/replicainstall.py
@@ -27,7 +27,6 @@
 from ipapython.ipa_log_manager import root_logger
 from ipapython.admintool import ScriptError
 from ipaplatform import services
-from ipaplatform.constants import constants as pconstants
 from ipaplatform.tasks import tasks
 from ipaplatform.paths import paths
 from ipalib import api, constants, create_api, errors, rpc, x509
@@ -77,18 +76,6 @@ def make_pkcs12_info(directory, cert_name, password_name):
         return None
 
 
-def install_http_certs(host_name, realm_name, subject_base):
-    principal = 'HTTP/%s@%s' % (host_name, realm_name)
-    subject = subject_base or DN(('O', realm_name))
-    db = certs.CertDB(realm_name, nssdir=paths.HTTPD_ALIAS_DIR,
-                      subject_base=subject, user="root",
-                      group=pconstants.HTTPD_GROUP, truncate=True)
-    db.request_service_cert('Server-Cert', principal, host_name)
-    # Obtain certificate for the HTTP service
-    http = httpinstance.HTTPInstance()
-    http.create_password_conf()
-
-
 def install_replica_ds(config, options, ca_is_configured, remote_api,
                        ca_file, promote=False, pkcs12_info=None):
     dsinstance.check_ports()
@@ -175,7 +162,8 @@ def install_http(config, auto_redirect, ca_is_configured, ca_file,
     http.create_instance(
         config.realm_name, config.host_name, config.domain_name,
         pkcs12_info, auto_redirect=auto_redirect, ca_file=ca_file,
-        ca_is_configured=ca_is_configured, promote=promote)
+        ca_is_configured=ca_is_configured, promote=promote,
+        subject_base=config.subject_base)
 
     return http
 
@@ -1414,12 +1402,6 @@ def install(installer):
         # Always try to install DNS records
         install_dns_records(config, options, remote_api)
 
-        if promote and ca_enabled:
-            # we need to install http certs to setup ssl for httpd
-            install_http_certs(config.host_name,
-                               config.realm_name,
-                               config.subject_base)
-
         ntpinstance.ntp_ldap_enable(config.host_name, ds.suffix,
                                     remote_api.env.realm)
     finally:

From 4b129ae7fecbed978d1b5809a093016cefd267a7 Mon Sep 17 00:00:00 2001
From: Jan Cholasta <jchol...@redhat.com>
Date: Fri, 7 Apr 2017 07:44:21 +0200
Subject: [PATCH 4/6] install: request service certs after host keytab is set
 up

The certmonger renew agent and restart scripts use host keytab for
authentication. When they are executed during a certmonger request before
the host keytab is set up, the authentication will fail.

Make sure all certmonger requests in the installer are done after the host
keytab is set up.

https://pagure.io/freeipa/issue/6757
---
 ipaserver/install/dsinstance.py            | 17 +++++++----------
 ipaserver/install/server/install.py        | 18 +++++++-----------
 ipaserver/install/server/replicainstall.py |  5 ++---
 3 files changed, 16 insertions(+), 24 deletions(-)

diff --git a/ipaserver/install/dsinstance.py b/ipaserver/install/dsinstance.py
index 31dbd4ec..72fcb65 100644
--- a/ipaserver/install/dsinstance.py
+++ b/ipaserver/install/dsinstance.py
@@ -256,7 +256,7 @@ def __init__(self, realm_name=None, domain_name=None, fstore=None,
 
     subject_base = ipautil.dn_attribute_property('_subject_base')
 
-    def __common_setup(self, enable_ssl=False):
+    def __common_setup(self):
 
         self.step("creating directory server user", create_ds_user)
         self.step("creating directory server instance", self.__create_instance)
@@ -279,8 +279,6 @@ def __common_setup(self, enable_ssl=False):
         self.step("configuring topology plugin", self.__config_topology_module)
         self.step("creating indices", self.__create_indices)
         self.step("enabling referential integrity plugin", self.__add_referint_module)
-        if enable_ssl:
-            self.step("configuring TLS for DS instance", self.__enable_ssl)
         self.step("configuring certmap.conf", self.__certmap_conf)
         self.step("configure new location for managed entries", self.__repoint_managed_entries)
         self.step("configure dirsrv ccache", self.configure_dirsrv_ccache)
@@ -356,8 +354,12 @@ def enable_ssl(self):
         self.steps = []
 
         self.step("configuring TLS for DS instance", self.__enable_ssl)
+        if self.master_fqdn is None:
+            self.step("adding CA certificate entry", self.__upload_ca_cert)
+        else:
+            self.step("importing CA certificates from LDAP",
+                      self.__import_ca_certs)
         self.step("restarting directory server", self.__restart_instance)
-        self.step("adding CA certificate entry", self.__upload_ca_cert)
 
         self.start_creation()
 
@@ -391,21 +393,16 @@ def create_replica(self, realm_name, master_fqdn, fqdn,
         self.promote = promote
         self.api = api
 
-        self.__common_setup(enable_ssl=(not self.promote))
+        self.__common_setup()
         self.step("restarting directory server", self.__restart_instance)
 
         self.step("creating DS keytab", self.request_service_keytab)
-        if self.promote:
-            self.step("configuring TLS for DS instance", self.__enable_ssl)
-            self.step("restarting directory server", self.__restart_instance)
-
         self.step("setting up initial replication", self.__setup_replica)
         self.step("adding sasl mappings to the directory", self.__configure_sasl_mappings)
         self.step("updating schema", self.__update_schema)
         # See LDIFs for automember configuration during replica install
         self.step("setting Auto Member configuration", self.__add_replica_automember_config)
         self.step("enabling S4U2Proxy delegation", self.__setup_s4u2proxy)
-        self.step("importing CA certificates from LDAP", self.__import_ca_certs)
 
         self.__common_post_setup()
 
diff --git a/ipaserver/install/server/install.py b/ipaserver/install/server/install.py
index f8e64ec..bf2e248 100644
--- a/ipaserver/install/server/install.py
+++ b/ipaserver/install/server/install.py
@@ -770,6 +770,13 @@ def install(installer):
             realm_name, host_name, domain_name, dm_password,
             options.subject_base, options.ca_subject, 1101, 1100, None)
 
+    krb = krbinstance.KrbInstance(fstore)
+    krb.create_instance(realm_name, host_name, domain_name,
+                        dm_password, master_password,
+                        setup_pkinit=not options.no_pkinit,
+                        pkcs12_info=pkinit_pkcs12_info,
+                        subject_base=options.subject_base)
+
     if setup_ca:
         if not options.external_cert_files and options.external_ca:
             # stage 1 of external CA installation
@@ -793,17 +800,6 @@ def install(installer):
     # we now need to enable ssl on the ds
     ds.enable_ssl()
 
-    krb = krbinstance.KrbInstance(fstore)
-    krb.create_instance(realm_name, host_name, domain_name,
-                        dm_password, master_password,
-                        setup_pkinit=not options.no_pkinit,
-                        pkcs12_info=pkinit_pkcs12_info,
-                        subject_base=options.subject_base)
-
-    # restart DS to enable ipa-pwd-extop plugin
-    print("Restarting directory server to enable password extension plugin")
-    ds.restart()
-
     if setup_ca:
         ca.install_step_1(False, None, options)
 
diff --git a/ipaserver/install/server/replicainstall.py b/ipaserver/install/server/replicainstall.py
index cd6a62f..6f1a0d6 100644
--- a/ipaserver/install/server/replicainstall.py
+++ b/ipaserver/install/server/replicainstall.py
@@ -1422,9 +1422,8 @@ def install(installer):
         setup_pkinit=not options.no_pkinit,
         promote=promote)
 
-    # restart DS to enable ipa-pwd-extop plugin
-    print("Restarting directory server to enable password extension plugin")
-    ds.restart()
+    # we now need to enable ssl on the ds
+    ds.enable_ssl()
 
     install_http(
         config,

From 8f68dfd3d7211db024a54cd92f4dbcdf9bfacbd8 Mon Sep 17 00:00:00 2001
From: Jan Cholasta <jchol...@redhat.com>
Date: Fri, 7 Apr 2017 07:46:58 +0200
Subject: [PATCH 5/6] renew agent: revert to host keytab authentication

Fixes an issue where the renew agent uses GSSAPI for LDAP connection but
fails because it is not authenticated.

This reverts commit 7462adec13c5b25b6868d2863dc38062c97d0ff7.

https://pagure.io/freeipa/issue/6757
---
 install/certmonger/dogtag-ipa-ca-renew-agent-submit | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/install/certmonger/dogtag-ipa-ca-renew-agent-submit b/install/certmonger/dogtag-ipa-ca-renew-agent-submit
index 5782db7..3389447 100755
--- a/install/certmonger/dogtag-ipa-ca-renew-agent-submit
+++ b/install/certmonger/dogtag-ipa-ca-renew-agent-submit
@@ -40,6 +40,7 @@ from cryptography.hazmat.backends import default_backend
 
 import six
 
+from ipalib.install.kinit import kinit_keytab
 from ipapython import ipautil
 from ipapython.dn import DN
 from ipalib import api, errors, x509
@@ -132,7 +133,7 @@ def ldap_connect():
     conn = None
     try:
         conn = ldap2(api)
-        conn.connect(autobind=True)
+        conn.connect(ccache=os.environ['KRB5CCNAME'])
         yield conn
     finally:
         if conn is not None and conn.isconnected():
@@ -526,6 +527,11 @@ def main():
     tmpdir = tempfile.mkdtemp(prefix="tmp-")
     certs.renewal_lock.acquire()
     try:
+        principal = str('host/%s@%s' % (api.env.host, api.env.realm))
+        ccache_filename = os.path.join(tmpdir, 'ccache')
+        os.environ['KRB5CCNAME'] = ccache_filename
+        kinit_keytab(principal, paths.KRB5_KEYTAB, ccache_filename)
+
         profile = os.environ.get('CERTMONGER_CA_PROFILE')
         if is_replicated():
             if profile or is_renewal_master():

From f5a175a8ae985eea4e0325d0324ef71882990a18 Mon Sep 17 00:00:00 2001
From: Jan Cholasta <jchol...@redhat.com>
Date: Fri, 7 Apr 2017 07:51:01 +0200
Subject: [PATCH 6/6] renew agent, restart scripts: connect to LDAP after kinit

Connect to LDAP after kinit is done, otherwise GSSAPI authentication will
fail.

https://pagure.io/freeipa/issue/6757
---
 install/certmonger/dogtag-ipa-ca-renew-agent-submit | 6 ++++--
 install/restart_scripts/renew_ca_cert               | 6 ++++--
 install/restart_scripts/renew_ra_cert               | 6 ++++--
 3 files changed, 12 insertions(+), 6 deletions(-)

diff --git a/install/certmonger/dogtag-ipa-ca-renew-agent-submit b/install/certmonger/dogtag-ipa-ca-renew-agent-submit
index 3389447..7a3d955 100755
--- a/install/certmonger/dogtag-ipa-ca-renew-agent-submit
+++ b/install/certmonger/dogtag-ipa-ca-renew-agent-submit
@@ -518,7 +518,6 @@ def main():
 
     api.bootstrap(in_server=True, context='renew', confdir=paths.ETC_IPA)
     api.finalize()
-    api.Backend.ldap2.connect()
 
     operation = os.environ.get('CERTMONGER_OPERATION')
     if operation not in ('SUBMIT', 'POLL'):
@@ -532,6 +531,8 @@ def main():
         os.environ['KRB5CCNAME'] = ccache_filename
         kinit_keytab(principal, paths.KRB5_KEYTAB, ccache_filename)
 
+        api.Backend.ldap2.connect()
+
         profile = os.environ.get('CERTMONGER_CA_PROFILE')
         if is_replicated():
             if profile or is_renewal_master():
@@ -547,9 +548,10 @@ def main():
             print(item)
         return res[0]
     finally:
+        if api.Backend.ldap2.isconnected():
+            api.Backend.ldap2.disconnect()
         certs.renewal_lock.release()
         shutil.rmtree(tmpdir)
-        api.Backend.ldap2.disconnect()
 
 
 try:
diff --git a/install/restart_scripts/renew_ca_cert b/install/restart_scripts/renew_ca_cert
index bbeae1a..7a54b4c 100644
--- a/install/restart_scripts/renew_ca_cert
+++ b/install/restart_scripts/renew_ca_cert
@@ -42,7 +42,6 @@ def _main():
 
     api.bootstrap(in_server=True, context='restart', confdir=paths.ETC_IPA)
     api.finalize()
-    api.Backend.ldap2.connect()
 
     dogtag_service = services.knownservices['pki_tomcatd']
 
@@ -77,6 +76,8 @@ def _main():
         kinit_keytab(principal, paths.KRB5_KEYTAB, ccache_filename)
         os.environ['KRB5CCNAME'] = ccache_filename
 
+        api.Backend.ldap2.connect()
+
         ca = cainstance.CAInstance(host_name=api.env.host)
         ca.update_cert_config(nickname, cert)
         if ca.is_renewal_master():
@@ -184,8 +185,9 @@ def _main():
                 if conn is not None and conn.isconnected():
                     conn.disconnect()
     finally:
+        if api.Backend.ldap2.isconnected():
+            api.Backend.ldap2.disconnect()
         shutil.rmtree(tmpdir)
-        api.Backend.ldap2.disconnect()
 
     # Now we can start the CA. Using the services start should fire
     # off the servlet to verify that the CA is actually up and responding so
diff --git a/install/restart_scripts/renew_ra_cert b/install/restart_scripts/renew_ra_cert
index 5c71d57..486ee78 100644
--- a/install/restart_scripts/renew_ra_cert
+++ b/install/restart_scripts/renew_ra_cert
@@ -38,7 +38,6 @@ from ipaplatform.paths import paths
 def _main():
     api.bootstrap(in_server=True, context='restart', confdir=paths.ETC_IPA)
     api.finalize()
-    api.Backend.ldap2.connect()
 
     tmpdir = tempfile.mkdtemp(prefix="tmp-")
     try:
@@ -47,6 +46,8 @@ def _main():
         kinit_keytab(principal, paths.KRB5_KEYTAB, ccache_filename)
         os.environ['KRB5CCNAME'] = ccache_filename
 
+        api.Backend.ldap2.connect()
+
         ca = cainstance.CAInstance(host_name=api.env.host)
         ra_certpath = paths.RA_AGENT_PEM
         if ca.is_renewal_master():
@@ -71,8 +72,9 @@ def _main():
             # Load it into dogtag
             cainstance.update_people_entry(dercert)
     finally:
+        if api.Backend.ldap2.isconnected():
+            api.Backend.ldap2.disconnect()
         shutil.rmtree(tmpdir)
-        api.Backend.ldap2.disconnect()
 
 
 def main():
-- 
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

Reply via email to