diff --git a/SOURCES/0205-Add-CommonNameToSANDefault-to-default-cert-profile.patch b/SOURCES/0205-Add-CommonNameToSANDefault-to-default-cert-profile.patch
new file mode 100644
index 0000000..73b0c6d
--- /dev/null
+++ b/SOURCES/0205-Add-CommonNameToSANDefault-to-default-cert-profile.patch
@@ -0,0 +1,62 @@
+From bf0a34b06e4a44b71b5a9b5f7b7537d3d99e0441 Mon Sep 17 00:00:00 2001
+From: Fraser Tweedale <ftweedal@redhat.com>
+Date: Wed, 7 Jun 2017 19:41:26 +1000
+Subject: [PATCH] Add CommonNameToSANDefault to default cert profile
+
+The CommonNameToSANDefault component was added to Dogtag 10.4.  When
+a profile is configured to use it, this profile copies the CN in the
+certificate to the Subject Alternative Name extension as a dNSName
+(if and only if it does look like a DNS name).
+
+It is desirable that the default service profile use this component.
+Add it to the default profile, for new installations only.  For
+existing installations, until a proper profile update mechanism is
+implemented, administrators who wish to use it must configure it via
+the 'certprofile-mod' command.
+
+Fixes: https://pagure.io/freeipa/issue/7007
+Reviewed-By: Jan Cholasta <jcholast@redhat.com>
+---
+ freeipa.spec.in                             | 4 ++--
+ install/share/profiles/caIPAserviceCert.cfg | 6 +++++-
+ 2 files changed, 7 insertions(+), 3 deletions(-)
+
+diff --git a/freeipa.spec.in b/freeipa.spec.in
+index d7f8d11ec553cfe299937e1e5f8cc27caed32b08..721e512039a4d7f9d2ed94d7620b083732c56304 100644
+--- a/freeipa.spec.in
++++ b/freeipa.spec.in
+@@ -291,8 +291,8 @@ Requires(post): systemd-units
+ Requires: selinux-policy >= %{selinux_policy_version}
+ Requires(post): selinux-policy-base >= %{selinux_policy_version}
+ Requires: slapi-nis >= %{slapi_nis_version}
+-Requires: pki-ca >= 10.3.5-11
+-Requires: pki-kra >= 10.3.5-11
++Requires: pki-ca >= 10.4.0-1
++Requires: pki-kra >= 10.4.0-1
+ Requires(preun): python systemd-units
+ Requires(postun): python systemd-units
+ Requires: policycoreutils >= 2.1.12-5
+diff --git a/install/share/profiles/caIPAserviceCert.cfg b/install/share/profiles/caIPAserviceCert.cfg
+index 6c5102f0dbd6bd6c6eaf2fa22e87ed4a5f34553c..3bec9ed10c7c053a67271de52dd95e71fe1fb6b8 100644
+--- a/install/share/profiles/caIPAserviceCert.cfg
++++ b/install/share/profiles/caIPAserviceCert.cfg
+@@ -12,7 +12,7 @@ input.i2.class_id=submitterInfoInputImpl
+ output.list=o1
+ output.o1.class_id=certOutputImpl
+ policyset.list=serverCertSet
+-policyset.serverCertSet.list=1,2,3,4,5,6,7,8,9,10,11
++policyset.serverCertSet.list=1,2,3,4,5,6,7,8,9,10,11,12
+ policyset.serverCertSet.1.constraint.class_id=subjectNameConstraintImpl
+ policyset.serverCertSet.1.constraint.name=Subject Name Constraint
+ policyset.serverCertSet.1.constraint.params.pattern=CN=[^,]+,.+
+@@ -107,3 +107,7 @@ policyset.serverCertSet.11.constraint.name=No Constraint
+ policyset.serverCertSet.11.default.class_id=userExtensionDefaultImpl
+ policyset.serverCertSet.11.default.name=User Supplied Extension Default
+ policyset.serverCertSet.11.default.params.userExtOID=2.5.29.17
++policyset.serverCertSet.12.constraint.class_id=noConstraintImpl
++policyset.serverCertSet.12.constraint.name=No Constraint
++policyset.serverCertSet.12.default.class_id=commonNameToSANDefaultImpl
++policyset.serverCertSet.12.default.name=Copy Common Name to Subject Alternative Name
+-- 
+2.9.4
+
diff --git a/SOURCES/0206-smart-card-advises-configure-systemwide-NSS-DB-also-.patch b/SOURCES/0206-smart-card-advises-configure-systemwide-NSS-DB-also-.patch
new file mode 100644
index 0000000..f83b0f2
--- /dev/null
+++ b/SOURCES/0206-smart-card-advises-configure-systemwide-NSS-DB-also-.patch
@@ -0,0 +1,131 @@
+From 57c93cb21d542e1d0eab52baa01ac60f30459dc7 Mon Sep 17 00:00:00 2001
+From: Martin Babinsky <mbabinsk@redhat.com>
+Date: Wed, 21 Jun 2017 18:28:50 +0200
+Subject: [PATCH] smart-card advises: configure systemwide NSS DB also on
+ master
+
+Previously the Smart card signing CA cert was uploaded to systemwide NSS
+DB only on the client, but it need to be added also to the server.
+Modify the advise plugins to allow for common configuration steps to
+occur in both cases.
+
+https://pagure.io/freeipa/issue/7036
+
+Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
+Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
+---
+ ipaserver/advise/plugins/smart_card_auth.py | 59 +++++++++++++++++------------
+ 1 file changed, 35 insertions(+), 24 deletions(-)
+
+diff --git a/ipaserver/advise/plugins/smart_card_auth.py b/ipaserver/advise/plugins/smart_card_auth.py
+index 5859e350939fdba0a8b258de5285dd10c7b3bc23..0ee4808d47aa87a4b1b838d427e9958d98075a4a 100644
+--- a/ipaserver/advise/plugins/smart_card_auth.py
++++ b/ipaserver/advise/plugins/smart_card_auth.py
+@@ -10,8 +10,39 @@ from ipaserver.install.httpinstance import NSS_OCSP_ENABLED
+ register = Registry()
+ 
+ 
++class common_smart_card_auth_config(Advice):
++    """
++    Common steps required to properly configure both server and client for
++    smart card auth
++    """
++
++    systemwide_nssdb = paths.NSS_DB_DIR
++    smart_card_ca_cert_variable_name = "SC_CA_CERT"
++
++    def check_and_set_ca_cert_path(self):
++        ca_path_variable = self.smart_card_ca_cert_variable_name
++        self.log.command("{}=$1".format(ca_path_variable))
++        self.log.exit_on_predicate(
++            '[ -z "${}" ]'.format(ca_path_variable),
++            ['You need to provide the path to the PEM file containing CA '
++             'signing the Smart Cards']
++        )
++        self.log.exit_on_predicate(
++            '[ ! -f "${}" ]'.format(ca_path_variable),
++            ['Invalid CA certificate filename: ${}'.format(ca_path_variable),
++             'Please check that the path exists and is a valid file']
++        )
++
++    def upload_smartcard_ca_certificate_to_systemwide_db(self):
++        self.log.command(
++            'certutil -d {} -A -i ${} -n "Smart Card CA" -t CT,C,C'.format(
++                self.systemwide_nssdb, self.smart_card_ca_cert_variable_name
++            )
++        )
++
++
+ @register()
+-class config_server_for_smart_card_auth(Advice):
++class config_server_for_smart_card_auth(common_smart_card_auth_config):
+     """
+     Configures smart card authentication via Kerberos (PKINIT) and for WebUI
+     """
+@@ -28,6 +59,7 @@ class config_server_for_smart_card_auth(Advice):
+ 
+     def get_info(self):
+         self.log.exit_on_nonroot_euid()
++        self.check_and_set_ca_cert_path()
+         self.check_ccache_not_empty()
+         self.check_hostname_is_in_masters()
+         self.resolve_ipaca_records()
+@@ -37,6 +69,7 @@ class config_server_for_smart_card_auth(Advice):
+         self.record_httpd_ocsp_status()
+         self.check_and_enable_pkinit()
+         self.enable_ok_to_auth_as_delegate_on_http_principal()
++        self.upload_smartcard_ca_certificate_to_systemwide_db()
+ 
+     def check_ccache_not_empty(self):
+         self.log.comment('Check whether the credential cache is not empty')
+@@ -162,11 +195,10 @@ class config_server_for_smart_card_auth(Advice):
+ 
+ 
+ @register()
+-class config_client_for_smart_card_auth(Advice):
++class config_client_for_smart_card_auth(common_smart_card_auth_config):
+     """
+     Configures smart card authentication on FreeIPA client
+     """
+-    smart_card_ca_cert_variable_name = "SC_CA_CERT"
+ 
+     description = ("Instructions for enabling Smart Card authentication on "
+                    " a single FreeIPA client. Configures Smart Card daemon, "
+@@ -190,20 +222,6 @@ class config_client_for_smart_card_auth(Advice):
+         self.run_authconfig_to_configure_smart_card_auth()
+         self.restart_sssd()
+ 
+-    def check_and_set_ca_cert_path(self):
+-        ca_path_variable = self.smart_card_ca_cert_variable_name
+-        self.log.command("{}=$1".format(ca_path_variable))
+-        self.log.exit_on_predicate(
+-            '[ -z "${}" ]'.format(ca_path_variable),
+-            ['You need to provide the path to the PEM file containing CA '
+-             'signing the Smart Cards']
+-        )
+-        self.log.exit_on_predicate(
+-            '[ ! -f "${}" ]'.format(ca_path_variable),
+-            ['Invalid CA certificate filename: ${}'.format(ca_path_variable),
+-             'Please check that the path exists and is a valid file']
+-        )
+-
+     def check_and_remove_pam_pkcs11(self):
+         self.log.command('rpm -qi pam_pkcs11 > /dev/null')
+         self.log.commands_on_predicate(
+@@ -247,13 +265,6 @@ class config_client_for_smart_card_auth(Advice):
+             ]
+         )
+ 
+-    def upload_smartcard_ca_certificate_to_systemwide_db(self):
+-        self.log.command(
+-            'certutil -d {} -A -i ${} -n "Smart Card CA" -t CT,C,C'.format(
+-                self.systemwide_nssdb, self.smart_card_ca_cert_variable_name
+-            )
+-        )
+-
+     def run_authconfig_to_configure_smart_card_auth(self):
+         self.log.exit_on_failed_command(
+             'authconfig --enablesmartcard --smartcardmodule=sssd --updateall',
+-- 
+2.9.4
+
diff --git a/SOURCES/0207-smart-card-advises-add-steps-to-store-smart-card-sig.patch b/SOURCES/0207-smart-card-advises-add-steps-to-store-smart-card-sig.patch
new file mode 100644
index 0000000..344a96c
--- /dev/null
+++ b/SOURCES/0207-smart-card-advises-add-steps-to-store-smart-card-sig.patch
@@ -0,0 +1,125 @@
+From 7bbf7dbc27d1bcde8bf3e4d0bb8fec65de2660c8 Mon Sep 17 00:00:00 2001
+From: Martin Babinsky <mbabinsk@redhat.com>
+Date: Wed, 21 Jun 2017 18:52:57 +0200
+Subject: [PATCH] smart-card advises: add steps to store smart card signing CA
+ cert
+
+On master, upload the CA certificate to IPA LDAP and NSS databases. On
+both master and client run ipa-certupdate to update client-side CA
+certificate bundles used as PKINIT anchors.
+
+https://pagure.io/freeipa/issue/7036
+
+Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
+Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
+---
+ ipaserver/advise/plugins/smart_card_auth.py | 46 +++++++++++++++++++++++------
+ 1 file changed, 37 insertions(+), 9 deletions(-)
+
+diff --git a/ipaserver/advise/plugins/smart_card_auth.py b/ipaserver/advise/plugins/smart_card_auth.py
+index 0ee4808d47aa87a4b1b838d427e9958d98075a4a..0217bd190778f1235981a49e7b0764b8b9cdf582 100644
+--- a/ipaserver/advise/plugins/smart_card_auth.py
++++ b/ipaserver/advise/plugins/smart_card_auth.py
+@@ -3,6 +3,7 @@
+ #
+ 
+ from ipalib.plugable import Registry
++from ipaplatform import services
+ from ipaplatform.paths import paths
+ from ipaserver.advise.base import Advice
+ from ipaserver.install.httpinstance import NSS_OCSP_ENABLED
+@@ -19,6 +20,16 @@ class common_smart_card_auth_config(Advice):
+     systemwide_nssdb = paths.NSS_DB_DIR
+     smart_card_ca_cert_variable_name = "SC_CA_CERT"
+ 
++    def check_ccache_not_empty(self):
++        self.log.comment('Check whether the credential cache is not empty')
++        self.log.exit_on_failed_command(
++            'klist',
++            [
++                "Credential cache is empty",
++                'Use kinit as privileged user to obtain Kerberos credentials'
++            ])
++
++
+     def check_and_set_ca_cert_path(self):
+         ca_path_variable = self.smart_card_ca_cert_variable_name
+         self.log.command("{}=$1".format(ca_path_variable))
+@@ -40,6 +51,20 @@ class common_smart_card_auth_config(Advice):
+             )
+         )
+ 
++    def install_smart_card_signing_ca_cert(self):
++        self.log.exit_on_failed_command(
++            'ipa-cacert-manage install ${} -t CT,C,C'.format(
++                self.smart_card_ca_cert_variable_name
++            ),
++            ['Failed to install external CA certificate to IPA']
++        )
++
++    def update_ipa_ca_certificate_store(self):
++        self.log.exit_on_failed_command(
++            'ipa-certupdate',
++            ['Failed to update IPA CA certificate database']
++        )
++
+ 
+ @register()
+ class config_server_for_smart_card_auth(common_smart_card_auth_config):
+@@ -56,6 +81,7 @@ class config_server_for_smart_card_auth(common_smart_card_auth_config):
+     nss_conf = paths.HTTPD_NSS_CONF
+     nss_ocsp_directive = 'NSSOCSP'
+     nss_nickname_directive = 'NSSNickname'
++    kdc_service_name = services.knownservices.krb5kdc.systemd_name
+ 
+     def get_info(self):
+         self.log.exit_on_nonroot_euid()
+@@ -70,15 +96,8 @@ class config_server_for_smart_card_auth(common_smart_card_auth_config):
+         self.check_and_enable_pkinit()
+         self.enable_ok_to_auth_as_delegate_on_http_principal()
+         self.upload_smartcard_ca_certificate_to_systemwide_db()
+-
+-    def check_ccache_not_empty(self):
+-        self.log.comment('Check whether the credential cache is not empty')
+-        self.log.exit_on_failed_command(
+-            'klist',
+-            [
+-                "Credential cache is empty",
+-                'Use kinit as privileged user to obtain Kerberos credentials'
+-            ])
++        self.update_ipa_ca_certificate_store()
++        self.restart_kdc()
+ 
+     def check_hostname_is_in_masters(self):
+         self.log.comment('Check whether the host is IPA master')
+@@ -193,6 +212,12 @@ class config_server_for_smart_card_auth(common_smart_card_auth_config):
+             ["Failed to set OK_AS_AUTH_AS_DELEGATE flag on HTTP principal"]
+         )
+ 
++    def restart_kdc(self):
++        self.log.exit_on_failed_command(
++            'systemctl restart {}'.format(self.kdc_service_name),
++            ['Failed to restart KDC. Please restart the service manually.']
++        )
++
+ 
+ @register()
+ class config_client_for_smart_card_auth(common_smart_card_auth_config):
+@@ -214,11 +239,14 @@ class config_client_for_smart_card_auth(common_smart_card_auth_config):
+     def get_info(self):
+         self.log.exit_on_nonroot_euid()
+         self.check_and_set_ca_cert_path()
++        self.check_ccache_not_empty()
+         self.check_and_remove_pam_pkcs11()
+         self.install_opensc_and_dconf_packages()
+         self.start_enable_smartcard_daemon()
+         self.add_pkcs11_module_to_systemwide_db()
+         self.upload_smartcard_ca_certificate_to_systemwide_db()
++        self.install_smart_card_signing_ca_cert()
++        self.update_ipa_ca_certificate_store()
+         self.run_authconfig_to_configure_smart_card_auth()
+         self.restart_sssd()
+ 
+-- 
+2.9.4
+
diff --git a/SOURCES/0208-Allow-to-pass-in-multiple-CA-cert-paths-to-the-smart.patch b/SOURCES/0208-Allow-to-pass-in-multiple-CA-cert-paths-to-the-smart.patch
new file mode 100644
index 0000000..612e334
--- /dev/null
+++ b/SOURCES/0208-Allow-to-pass-in-multiple-CA-cert-paths-to-the-smart.patch
@@ -0,0 +1,150 @@
+From 6bfb11f2110f5fbaecc2d6a27d89289c58edc171 Mon Sep 17 00:00:00 2001
+From: Martin Babinsky <mbabinsk@redhat.com>
+Date: Thu, 22 Jun 2017 10:06:21 +0200
+Subject: [PATCH] Allow to pass in multiple CA cert paths to the smart card
+ advises
+
+If the user has a series of CA certificates required to verify smart
+card certs (e.g. intermediary CAs and root CA) it is convenient to allow
+for passing them to the advise scripts as a series of PEM files.
+
+https://pagure.io/freeipa/issue/7036
+
+Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
+Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
+---
+ ipaserver/advise/plugins/smart_card_auth.py | 69 +++++++++++++++++++----------
+ 1 file changed, 46 insertions(+), 23 deletions(-)
+
+diff --git a/ipaserver/advise/plugins/smart_card_auth.py b/ipaserver/advise/plugins/smart_card_auth.py
+index 0217bd190778f1235981a49e7b0764b8b9cdf582..16c01204444883ed949db73b2314ba5c404124df 100644
+--- a/ipaserver/advise/plugins/smart_card_auth.py
++++ b/ipaserver/advise/plugins/smart_card_auth.py
+@@ -18,7 +18,8 @@ class common_smart_card_auth_config(Advice):
+     """
+ 
+     systemwide_nssdb = paths.NSS_DB_DIR
+-    smart_card_ca_cert_variable_name = "SC_CA_CERT"
++    smart_card_ca_certs_variable_name = "SC_CA_CERTS"
++    single_ca_cert_variable_name = 'ca_cert'
+ 
+     def check_ccache_not_empty(self):
+         self.log.comment('Check whether the credential cache is not empty')
+@@ -29,35 +30,58 @@ class common_smart_card_auth_config(Advice):
+                 'Use kinit as privileged user to obtain Kerberos credentials'
+             ])
+ 
++    def check_and_set_ca_cert_paths(self):
++        ca_paths_variable = self.smart_card_ca_certs_variable_name
++        single_ca_path_variable = self.single_ca_cert_variable_name
+ 
+-    def check_and_set_ca_cert_path(self):
+-        ca_path_variable = self.smart_card_ca_cert_variable_name
+-        self.log.command("{}=$1".format(ca_path_variable))
++        self.log.command("{}=$@".format(ca_paths_variable))
+         self.log.exit_on_predicate(
+-            '[ -z "${}" ]'.format(ca_path_variable),
+-            ['You need to provide the path to the PEM file containing CA '
+-             'signing the Smart Cards']
++            '[ -z "${}" ]'.format(ca_paths_variable),
++            ['You need to provide one or more paths to the PEM files '
++             'containing CAs signing the Smart Cards']
+         )
++        self.log.command(
++            "for {} in ${}".format(
++                single_ca_path_variable, ca_paths_variable))
++        self.log.command("do")
+         self.log.exit_on_predicate(
+-            '[ ! -f "${}" ]'.format(ca_path_variable),
+-            ['Invalid CA certificate filename: ${}'.format(ca_path_variable),
+-             'Please check that the path exists and is a valid file']
++            '[ ! -f "${}" ]'.format(single_ca_path_variable),
++            ['Invalid CA certificate filename: ${}'.format(
++                single_ca_path_variable),
++             'Please check that the path exists and is a valid file'],
++            indent_spaces=2
+         )
++        self.log.command("done")
+ 
+-    def upload_smartcard_ca_certificate_to_systemwide_db(self):
++    def upload_smartcard_ca_certificates_to_systemwide_db(self):
++        self.log.command(
++            "for {} in ${}".format(
++                self.single_ca_cert_variable_name,
++                self.smart_card_ca_certs_variable_name))
++        self.log.command("do")
+         self.log.command(
+-            'certutil -d {} -A -i ${} -n "Smart Card CA" -t CT,C,C'.format(
+-                self.systemwide_nssdb, self.smart_card_ca_cert_variable_name
+-            )
++            'certutil -d {} -A -i ${} -n "Smart Card CA $(uuidgen)" '
++            '-t CT,C,C'.format(
++                self.systemwide_nssdb, self.single_ca_cert_variable_name
++            ),
++            indent_spaces=2
+         )
++        self.log.command("done")
+ 
+-    def install_smart_card_signing_ca_cert(self):
++    def install_smart_card_signing_ca_certs(self):
++        self.log.command(
++            "for {} in ${}".format(
++                self.single_ca_cert_variable_name,
++                self.smart_card_ca_certs_variable_name))
++        self.log.command("do")
+         self.log.exit_on_failed_command(
+             'ipa-cacert-manage install ${} -t CT,C,C'.format(
+-                self.smart_card_ca_cert_variable_name
++                self.single_ca_cert_variable_name
+             ),
+-            ['Failed to install external CA certificate to IPA']
++            ['Failed to install external CA certificate to IPA'],
++            indent_spaces=2
+         )
++        self.log.command("done")
+ 
+     def update_ipa_ca_certificate_store(self):
+         self.log.exit_on_failed_command(
+@@ -85,7 +109,7 @@ class config_server_for_smart_card_auth(common_smart_card_auth_config):
+ 
+     def get_info(self):
+         self.log.exit_on_nonroot_euid()
+-        self.check_and_set_ca_cert_path()
++        self.check_and_set_ca_cert_paths()
+         self.check_ccache_not_empty()
+         self.check_hostname_is_in_masters()
+         self.resolve_ipaca_records()
+@@ -95,7 +119,8 @@ class config_server_for_smart_card_auth(common_smart_card_auth_config):
+         self.record_httpd_ocsp_status()
+         self.check_and_enable_pkinit()
+         self.enable_ok_to_auth_as_delegate_on_http_principal()
+-        self.upload_smartcard_ca_certificate_to_systemwide_db()
++        self.upload_smartcard_ca_certificates_to_systemwide_db()
++        self.install_smart_card_signing_ca_certs()
+         self.update_ipa_ca_certificate_store()
+         self.restart_kdc()
+ 
+@@ -234,18 +259,16 @@ class config_client_for_smart_card_auth(common_smart_card_auth_config):
+     pkcs11_shared_lib = '/usr/lib64/opensc-pkcs11.so'
+     smart_card_service_file = 'pcscd.service'
+     smart_card_socket = 'pcscd.socket'
+-    systemwide_nssdb = paths.NSS_DB_DIR
+ 
+     def get_info(self):
+         self.log.exit_on_nonroot_euid()
+-        self.check_and_set_ca_cert_path()
++        self.check_and_set_ca_cert_paths()
+         self.check_ccache_not_empty()
+         self.check_and_remove_pam_pkcs11()
+         self.install_opensc_and_dconf_packages()
+         self.start_enable_smartcard_daemon()
+         self.add_pkcs11_module_to_systemwide_db()
+-        self.upload_smartcard_ca_certificate_to_systemwide_db()
+-        self.install_smart_card_signing_ca_cert()
++        self.upload_smartcard_ca_certificates_to_systemwide_db()
+         self.update_ipa_ca_certificate_store()
+         self.run_authconfig_to_configure_smart_card_auth()
+         self.restart_sssd()
+-- 
+2.9.4
+
diff --git a/SOURCES/0209-add-a-class-that-tracks-the-indentation-in-the-gener.patch b/SOURCES/0209-add-a-class-that-tracks-the-indentation-in-the-gener.patch
new file mode 100644
index 0000000..e6ac4ed
--- /dev/null
+++ b/SOURCES/0209-add-a-class-that-tracks-the-indentation-in-the-gener.patch
@@ -0,0 +1,77 @@
+From bdf024c20213110306b2fcf3651f274c229aae29 Mon Sep 17 00:00:00 2001
+From: Martin Babinsky <mbabinsk@redhat.com>
+Date: Thu, 22 Jun 2017 13:18:54 +0200
+Subject: [PATCH] add a class that tracks the indentation in the generated
+ advises
+
+https://pagure.io/freeipa/issue/7036
+
+Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
+Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
+---
+ ipaserver/advise/base.py | 49 ++++++++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 49 insertions(+)
+
+diff --git a/ipaserver/advise/base.py b/ipaserver/advise/base.py
+index ba412b872472580cd32baf2a326a14edb951cab1..639fd1807f72f11f46136999c4ce4c6eec6b3698 100644
+--- a/ipaserver/advise/base.py
++++ b/ipaserver/advise/base.py
+@@ -76,6 +76,55 @@ As a result, you can redirect the advice's output directly to a script file.
+ """
+ 
+ 
++class _IndentationTracker(object):
++    """
++    A simple wrapper that tracks the indentation level of the generated bash
++    commands
++    """
++    def __init__(self, spaces_per_indent=0):
++        if spaces_per_indent <= 0:
++            raise ValueError(
++                "Indentation increments cannot be zero or negative")
++        self.spaces_per_indent = spaces_per_indent
++        self._indentation_stack = []
++        self._total_indentation_level = 0
++
++    @property
++    def indentation_string(self):
++        """
++        return a string containing number of spaces corresponding to
++        indentation level
++        """
++        return " " * self._total_indentation_level
++
++    def indent(self):
++        """
++        track a single indentation of the generated code
++        """
++        self._indentation_stack.append(self.spaces_per_indent)
++        self._recompute_indentation_level()
++
++    def _recompute_indentation_level(self):
++        """
++        Track total indentation level of the generated code
++        """
++        self._total_indentation_level = sum(self._indentation_stack)
++
++    def dedent(self):
++        """
++        track a single dedentation of the generated code
++        dedents that would result in zero or negative indentation level will be
++        ignored
++        """
++        try:
++            self._indentation_stack.pop()
++        except IndexError:
++            # can not dedent any further
++            pass
++
++        self._recompute_indentation_level()
++
++
+ class _AdviceOutput(object):
+ 
+     def __init__(self):
+-- 
+2.9.4
+
diff --git a/SOURCES/0210-delegate-the-indentation-handling-in-advises-to-dedi.patch b/SOURCES/0210-delegate-the-indentation-handling-in-advises-to-dedi.patch
new file mode 100644
index 0000000..901dd54
--- /dev/null
+++ b/SOURCES/0210-delegate-the-indentation-handling-in-advises-to-dedi.patch
@@ -0,0 +1,267 @@
+From 243f7ebf6a07fa54cbd5db6bf7f67fee04e4f14c Mon Sep 17 00:00:00 2001
+From: Martin Babinsky <mbabinsk@redhat.com>
+Date: Thu, 22 Jun 2017 13:20:05 +0200
+Subject: [PATCH] delegate the indentation handling in advises to dedicated
+ class
+
+Indentation levels are now handled transparently by a dedicated class
+and should not pollute the statement printing logic.
+
+https://pagure.io/freeipa/issue/7036
+
+Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
+Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
+---
+ ipaserver/advise/base.py                    | 106 +++++++++++++++++++---------
+ ipaserver/advise/plugins/smart_card_auth.py |  45 ++++++------
+ 2 files changed, 93 insertions(+), 58 deletions(-)
+
+diff --git a/ipaserver/advise/base.py b/ipaserver/advise/base.py
+index 639fd1807f72f11f46136999c4ce4c6eec6b3698..c320b002c83198cbb0fd73a5c158df07dd309242 100644
+--- a/ipaserver/advise/base.py
++++ b/ipaserver/advise/base.py
+@@ -19,6 +19,7 @@
+ 
+ from __future__ import print_function
+ 
++from contextlib import contextmanager
+ import os
+ from textwrap import wrap
+ 
+@@ -75,6 +76,8 @@ As a result, you can redirect the advice's output directly to a script file.
+ # ./script.sh
+ """
+ 
++DEFAULT_INDENTATION_INCREMENT = 2
++
+ 
+ class _IndentationTracker(object):
+     """
+@@ -131,39 +134,77 @@ class _AdviceOutput(object):
+         self.content = []
+         self.prefix = '# '
+         self.options = None
++        self._indentation_tracker = _IndentationTracker(
++            spaces_per_indent=DEFAULT_INDENTATION_INCREMENT)
++
++    def indent(self):
++        """
++        Indent the statements by one level
++        """
++        self._indentation_tracker.indent()
++
++    def dedent(self):
++        """
++        Dedent the statements by one level
++        """
++        self._indentation_tracker.dedent()
++
++    @contextmanager
++    def indented_block(self):
++        self.indent()
++        try:
++            yield
++        finally:
++            self.dedent()
+ 
+     def comment(self, line, wrapped=True):
+         if wrapped:
+-            for wrapped_line in wrap(line, 70):
+-                self.content.append(self.prefix + wrapped_line)
++            self.append_wrapped_and_indented_comment(line)
+         else:
+-            self.content.append(self.prefix + line)
++            self.append_comment(line)
++
++    def append_wrapped_and_indented_comment(self, line, character_limit=70):
++        """
++        append wrapped and indented comment to the output
++        """
++        for wrapped_indented_line in wrap(
++                self.indent_statement(line), character_limit):
++            self.append_comment(wrapped_indented_line)
++
++    def append_comment(self, line):
++        self.append_statement(self.prefix + line)
++
++    def append_statement(self, statement):
++        """
++        Append a line to the generated content indenting it by tracked number
++        of spaces
++        """
++        self.content.append(self.indent_statement(statement))
++
++    def indent_statement(self, statement):
++        return '{indent}{statement}'.format(
++            indent=self._indentation_tracker.indentation_string,
++            statement=statement)
+ 
+     def debug(self, line):
+         if self.options.verbose:
+             self.comment('DEBUG: ' + line)
+ 
+-    def command(self, line, indent_spaces=0):
+-        self.content.append(
+-            '{}{}'.format(self._format_indent(indent_spaces), line))
+-
+-    def _format_indent(self, num_spaces):
+-        return ' ' * num_spaces
++    def command(self, line):
++        self.append_statement(line)
+ 
+-    def echo_error(self, error_message, indent_spaces=0):
+-        self.command(
+-            self._format_error(error_message), indent_spaces=indent_spaces)
++    def echo_error(self, error_message):
++        self.command(self._format_error(error_message))
+ 
+     def _format_error(self, error_message):
+         return 'echo "{}" >&2'.format(error_message)
+ 
+     def exit_on_failed_command(self, command_to_run,
+-                               error_message_lines, indent_spaces=0):
+-        self.command(command_to_run, indent_spaces=indent_spaces)
++                               error_message_lines):
++        self.command(command_to_run)
+         self.exit_on_predicate(
+             '[ "$?" -ne "0" ]',
+-            error_message_lines,
+-            indent_spaces=indent_spaces)
++            error_message_lines)
+ 
+     def exit_on_nonroot_euid(self):
+         self.exit_on_predicate(
+@@ -171,8 +212,7 @@ class _AdviceOutput(object):
+             ["This script has to be run as root user"]
+         )
+ 
+-    def exit_on_predicate(self, predicate, error_message_lines,
+-                          indent_spaces=0):
++    def exit_on_predicate(self, predicate, error_message_lines):
+         commands_to_run = [
+             self._format_error(error_message_line)
+             for error_message_line in error_message_lines]
+@@ -180,30 +220,26 @@ class _AdviceOutput(object):
+         commands_to_run.append('exit 1')
+         self.commands_on_predicate(
+             predicate,
+-            commands_to_run,
+-            indent_spaces=indent_spaces)
++            commands_to_run)
+ 
+     def commands_on_predicate(self, predicate, commands_to_run_when_true,
+-                              commands_to_run_when_false=None,
+-                              indent_spaces=0):
++                              commands_to_run_when_false=None):
+         if_command = 'if {}'.format(predicate)
+-        self.command(if_command, indent_spaces=indent_spaces)
+-        self.command('then', indent_spaces=indent_spaces)
+-
+-        indented_block_spaces = indent_spaces + 2
++        self.command(if_command)
++        self.command('then')
+ 
+-        for command_to_run_when_true in commands_to_run_when_true:
+-            self.command(
+-                command_to_run_when_true, indent_spaces=indented_block_spaces)
++        with self.indented_block():
++            for command_to_run_when_true in commands_to_run_when_true:
++                self.command(
++                    command_to_run_when_true)
+ 
+         if commands_to_run_when_false is not None:
+-            self.command("else", indent_spaces=indent_spaces)
+-            for command_to_run_when_false in commands_to_run_when_false:
+-                self.command(
+-                    command_to_run_when_false,
+-                    indent_spaces=indented_block_spaces)
++            self.command("else")
++            with self.indented_block():
++                for command_to_run_when_false in commands_to_run_when_false:
++                    self.command(command_to_run_when_false)
+ 
+-        self.command('fi', indent_spaces=indent_spaces)
++        self.command('fi')
+ 
+ 
+ class Advice(Plugin):
+diff --git a/ipaserver/advise/plugins/smart_card_auth.py b/ipaserver/advise/plugins/smart_card_auth.py
+index 16c01204444883ed949db73b2314ba5c404124df..75efa6f854acd5f746111ea44957a538117381ae 100644
+--- a/ipaserver/advise/plugins/smart_card_auth.py
++++ b/ipaserver/advise/plugins/smart_card_auth.py
+@@ -44,13 +44,13 @@ class common_smart_card_auth_config(Advice):
+             "for {} in ${}".format(
+                 single_ca_path_variable, ca_paths_variable))
+         self.log.command("do")
+-        self.log.exit_on_predicate(
+-            '[ ! -f "${}" ]'.format(single_ca_path_variable),
+-            ['Invalid CA certificate filename: ${}'.format(
+-                single_ca_path_variable),
+-             'Please check that the path exists and is a valid file'],
+-            indent_spaces=2
+-        )
++        with self.log.indented_block():
++            self.log.exit_on_predicate(
++                '[ ! -f "${}" ]'.format(single_ca_path_variable),
++                ['Invalid CA certificate filename: ${}'.format(
++                    single_ca_path_variable),
++                 'Please check that the path exists and is a valid file']
++            )
+         self.log.command("done")
+ 
+     def upload_smartcard_ca_certificates_to_systemwide_db(self):
+@@ -59,13 +59,13 @@ class common_smart_card_auth_config(Advice):
+                 self.single_ca_cert_variable_name,
+                 self.smart_card_ca_certs_variable_name))
+         self.log.command("do")
+-        self.log.command(
+-            'certutil -d {} -A -i ${} -n "Smart Card CA $(uuidgen)" '
+-            '-t CT,C,C'.format(
+-                self.systemwide_nssdb, self.single_ca_cert_variable_name
+-            ),
+-            indent_spaces=2
+-        )
++        with self.log.indented_block():
++            self.log.command(
++                'certutil -d {} -A -i ${} -n "Smart Card CA $(uuidgen)" '
++                '-t CT,C,C'.format(
++                    self.systemwide_nssdb, self.single_ca_cert_variable_name
++                ),
++            )
+         self.log.command("done")
+ 
+     def install_smart_card_signing_ca_certs(self):
+@@ -74,13 +74,13 @@ class common_smart_card_auth_config(Advice):
+                 self.single_ca_cert_variable_name,
+                 self.smart_card_ca_certs_variable_name))
+         self.log.command("do")
+-        self.log.exit_on_failed_command(
+-            'ipa-cacert-manage install ${} -t CT,C,C'.format(
+-                self.single_ca_cert_variable_name
+-            ),
+-            ['Failed to install external CA certificate to IPA'],
+-            indent_spaces=2
+-        )
++        with self.log.indented_block():
++            self.log.exit_on_failed_command(
++                'ipa-cacert-manage install ${} -t CT,C,C'.format(
++                    self.single_ca_cert_variable_name
++                ),
++                ['Failed to install external CA certificate to IPA']
++            )
+         self.log.command("done")
+ 
+     def update_ipa_ca_certificate_store(self):
+@@ -221,8 +221,7 @@ class config_server_for_smart_card_auth(common_smart_card_auth_config):
+         self.log.command('else')
+         self.log.exit_on_failed_command(
+             'ipa-pkinit-manage enable',
+-            ['Failed to issue PKINIT certificates to local KDC'],
+-            indent_spaces=2)
++            ['Failed to issue PKINIT certificates to local KDC'])
+         self.log.command('fi')
+ 
+     def enable_ok_to_auth_as_delegate_on_http_principal(self):
+-- 
+2.9.4
+
diff --git a/SOURCES/0211-advise-add-an-infrastructure-for-formatting-Bash-com.patch b/SOURCES/0211-advise-add-an-infrastructure-for-formatting-Bash-com.patch
new file mode 100644
index 0000000..297b114
--- /dev/null
+++ b/SOURCES/0211-advise-add-an-infrastructure-for-formatting-Bash-com.patch
@@ -0,0 +1,104 @@
+From 7e2702164e28576dfa64c0c9bbc83dc7dcb30ba7 Mon Sep 17 00:00:00 2001
+From: Martin Babinsky <mbabinsk@redhat.com>
+Date: Thu, 22 Jun 2017 15:00:00 +0200
+Subject: [PATCH] advise: add an infrastructure for formatting Bash compound
+ statements
+
+A series of context managers simplify formatting of common compound
+statements such as `if`, `else if`, `else` blocks.
+
+https://pagure.io/freeipa/issue/7036
+
+Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
+Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
+---
+ ipaserver/advise/base.py | 73 ++++++++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 73 insertions(+)
+
+diff --git a/ipaserver/advise/base.py b/ipaserver/advise/base.py
+index c320b002c83198cbb0fd73a5c158df07dd309242..940d87ed4c1804326a46e2866381364e6f4f3f3e 100644
+--- a/ipaserver/advise/base.py
++++ b/ipaserver/advise/base.py
+@@ -128,6 +128,79 @@ class _IndentationTracker(object):
+         self._recompute_indentation_level()
+ 
+ 
++class CompoundStatement(object):
++    """
++    Wrapper around indented blocks of Bash statements.
++
++    Override `begin_statement` and `end_statement` methods to issue
++    opening/closing commands using the passed in _AdviceOutput instance
++    """
++
++    def __init__(self, advice_output):
++        self.advice_output = advice_output
++
++    def __enter__(self):
++        self.begin_statement()
++        self.advice_output.indent()
++
++    def begin_statement(self):
++        pass
++
++    def __exit__(self, exc_type, exc_value, traceback):
++        self.advice_output.dedent()
++        self.end_statement()
++
++    def end_statement(self):
++        pass
++
++
++class IfBranch(CompoundStatement):
++    """
++    Base wrapper around `if` branch. The closing statement is empty so it
++    leaves trailing block that can be closed off or continued by else branches
++    """
++    def __init__(self, advice_output, conditional):
++        super(IfBranch, self).__init__(advice_output)
++        self.conditional = conditional
++
++    def begin_statement(self):
++        self.advice_output.command('if {}'.format(self.conditional))
++        self.advice_output.command('then')
++
++
++class ElseIfBranch(CompoundStatement):
++    """
++    Wrapper for `else if <CONDITIONAL>`
++    """
++    def __init__(self, advice_output, alternative_conditional):
++        super(ElseIfBranch, self).__init__(advice_output)
++        self.alternative_conditional = alternative_conditional
++
++    def begin_statement(self):
++        command = 'else if {}'.format(self.alternative_conditional)
++
++        self.advice_output.command(command)
++
++
++class ElseBranch(CompoundStatement):
++    """
++    Wrapper for final `else` block
++    """
++    def begin_statement(self):
++        self.advice_output.command('else')
++
++    def end_statement(self):
++        self.advice_output.command('fi')
++
++
++class UnbranchedIfStatement(IfBranch):
++    """
++    Plain `if` without branches
++    """
++    def end_statement(self):
++        self.advice_output.command('fi')
++
++
+ class _AdviceOutput(object):
+ 
+     def __init__(self):
+-- 
+2.9.4
+
diff --git a/SOURCES/0212-delegate-formatting-of-compound-Bash-statements-to-d.patch b/SOURCES/0212-delegate-formatting-of-compound-Bash-statements-to-d.patch
new file mode 100644
index 0000000..59b6b5b
--- /dev/null
+++ b/SOURCES/0212-delegate-formatting-of-compound-Bash-statements-to-d.patch
@@ -0,0 +1,93 @@
+From d22e7953295f878950ca5be976d89bf9af8d36b1 Mon Sep 17 00:00:00 2001
+From: Martin Babinsky <mbabinsk@redhat.com>
+Date: Thu, 22 Jun 2017 15:02:25 +0200
+Subject: [PATCH] delegate formatting of compound Bash statements to dedicated
+ classes
+
+this simplifies handling compound statements using _AdviceOutput class.
+The necessary statements are exposed as context managers and API for
+most common constructs is provided.
+
+https://pagure.io/freeipa/issue/7036
+
+Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
+Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
+---
+ ipaserver/advise/base.py | 48 ++++++++++++++++++++++++++++++++++--------------
+ 1 file changed, 34 insertions(+), 14 deletions(-)
+
+diff --git a/ipaserver/advise/base.py b/ipaserver/advise/base.py
+index 940d87ed4c1804326a46e2866381364e6f4f3f3e..581478fb75bc4f50b6bffe2e4cf9b51de46fa095 100644
+--- a/ipaserver/advise/base.py
++++ b/ipaserver/advise/base.py
+@@ -286,33 +286,53 @@ class _AdviceOutput(object):
+         )
+ 
+     def exit_on_predicate(self, predicate, error_message_lines):
+-        commands_to_run = [
+-            self._format_error(error_message_line)
+-            for error_message_line in error_message_lines]
++        with self.unbranched_if(predicate):
++            for error_message_line in error_message_lines:
++                self.command(self._format_error(error_message_line))
+ 
+-        commands_to_run.append('exit 1')
+-        self.commands_on_predicate(
+-            predicate,
+-            commands_to_run)
++            self.command('exit 1')
++
++    @contextmanager
++    def unbranched_if(self, predicate):
++        with self._compound_statement(UnbranchedIfStatement, predicate):
++            yield
++
++    @contextmanager
++    def _compound_statement(self, statement_cls, *args):
++        with statement_cls(self, *args):
++            yield
+ 
+     def commands_on_predicate(self, predicate, commands_to_run_when_true,
+                               commands_to_run_when_false=None):
+-        if_command = 'if {}'.format(predicate)
+-        self.command(if_command)
+-        self.command('then')
++        if commands_to_run_when_false is not None:
++            if_statement = self.if_branch
++        else:
++            if_statement = self.unbranched_if
+ 
+-        with self.indented_block():
++        with if_statement(predicate):
+             for command_to_run_when_true in commands_to_run_when_true:
+                 self.command(
+                     command_to_run_when_true)
+ 
+         if commands_to_run_when_false is not None:
+-            self.command("else")
+-            with self.indented_block():
++            with self.else_branch():
+                 for command_to_run_when_false in commands_to_run_when_false:
+                     self.command(command_to_run_when_false)
+ 
+-        self.command('fi')
++    @contextmanager
++    def if_branch(self, predicate):
++        with self._compound_statement(IfBranch, predicate):
++            yield
++
++    @contextmanager
++    def else_branch(self):
++        with self._compound_statement(ElseBranch):
++            yield
++
++    @contextmanager
++    def else_if_branch(self, predicate):
++        with self._compound_statement(ElseIfBranch, predicate):
++            yield
+ 
+ 
+ class Advice(Plugin):
+-- 
+2.9.4
+
diff --git a/SOURCES/0213-Fix-indentation-of-statements-in-Smart-card-advises.patch b/SOURCES/0213-Fix-indentation-of-statements-in-Smart-card-advises.patch
new file mode 100644
index 0000000..452b7df
--- /dev/null
+++ b/SOURCES/0213-Fix-indentation-of-statements-in-Smart-card-advises.patch
@@ -0,0 +1,36 @@
+From 5bf0faed2a4692d5ce2747c5036d3fca8b0f7b04 Mon Sep 17 00:00:00 2001
+From: Martin Babinsky <mbabinsk@redhat.com>
+Date: Thu, 22 Jun 2017 15:03:45 +0200
+Subject: [PATCH] Fix indentation of statements in Smart card advises
+
+https://pagure.io/freeipa/issue/7036
+
+Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
+Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
+---
+ ipaserver/advise/plugins/smart_card_auth.py | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/ipaserver/advise/plugins/smart_card_auth.py b/ipaserver/advise/plugins/smart_card_auth.py
+index 75efa6f854acd5f746111ea44957a538117381ae..138a44316473f6b504a44a1b68d01fa4d5a58308 100644
+--- a/ipaserver/advise/plugins/smart_card_auth.py
++++ b/ipaserver/advise/plugins/smart_card_auth.py
+@@ -165,13 +165,13 @@ class config_server_for_smart_card_auth(common_smart_card_auth_config):
+             predicate,
+             [
+                 self._interpolate_ocsp_directive_file_into_command(
+-                    "  sed -i.ipabkp -r "
++                    "sed -i.ipabkp -r "
+                     "'s/^#*[[:space:]]*{directive}[[:space:]]+(on|off)$"
+                     "/{directive} on/' {filename}")
+             ],
+             commands_to_run_when_false=[
+                 self._interpolate_ocsp_directive_file_into_command(
+-                    "  sed -i.ipabkp '/<\/VirtualHost>/i {directive} on' "
++                    "sed -i.ipabkp '/<\/VirtualHost>/i {directive} on' "
+                     "{filename}")
+             ]
+         )
+-- 
+2.9.4
+
diff --git a/SOURCES/0214-Use-the-compound-statement-formatting-API-for-config.patch b/SOURCES/0214-Use-the-compound-statement-formatting-API-for-config.patch
new file mode 100644
index 0000000..6c24663
--- /dev/null
+++ b/SOURCES/0214-Use-the-compound-statement-formatting-API-for-config.patch
@@ -0,0 +1,48 @@
+From c702bb6ca3742cf7ea156e062840623f95a001b7 Mon Sep 17 00:00:00 2001
+From: Martin Babinsky <mbabinsk@redhat.com>
+Date: Thu, 22 Jun 2017 15:08:08 +0200
+Subject: [PATCH] Use the compound statement formatting API for configuring
+ PKINIT
+
+Use `if_branch` and `else_branch` context managers instead of raw
+`command` calls in the method that generates Bash snippet that
+configures PKINIT on the master.
+
+https://pagure.io/freeipa/issue/7036
+
+Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
+Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
+---
+ ipaserver/advise/plugins/smart_card_auth.py | 16 +++++++---------
+ 1 file changed, 7 insertions(+), 9 deletions(-)
+
+diff --git a/ipaserver/advise/plugins/smart_card_auth.py b/ipaserver/advise/plugins/smart_card_auth.py
+index 138a44316473f6b504a44a1b68d01fa4d5a58308..2dc9ddb25ce41a8c85aab827a92a1143784d9457 100644
+--- a/ipaserver/advise/plugins/smart_card_auth.py
++++ b/ipaserver/advise/plugins/smart_card_auth.py
+@@ -214,15 +214,13 @@ class config_server_for_smart_card_auth(common_smart_card_auth_config):
+ 
+     def check_and_enable_pkinit(self):
+         self.log.comment('check whether PKINIT is configured on the master')
+-        self.log.command(
+-            "if ipa-pkinit-manage status | grep -q 'enabled'")
+-        self.log.command('then')
+-        self.log.command('  echo "PKINIT already enabled"')
+-        self.log.command('else')
+-        self.log.exit_on_failed_command(
+-            'ipa-pkinit-manage enable',
+-            ['Failed to issue PKINIT certificates to local KDC'])
+-        self.log.command('fi')
++        with self.log.if_branch(
++                "ipa-pkinit-manage status | grep -q 'enabled'"):
++            self.log.command('echo "PKINIT already enabled"')
++        with self.log.else_branch():
++            self.log.exit_on_failed_command(
++                'ipa-pkinit-manage enable',
++                ['Failed to issue PKINIT certificates to local KDC'])
+ 
+     def enable_ok_to_auth_as_delegate_on_http_principal(self):
+         self.log.comment('Enable OK-AS-DELEGATE flag on the HTTP principal')
+-- 
+2.9.4
+
diff --git a/SOURCES/0215-smart-card-advises-use-a-wrapper-around-Bash-for-loo.patch b/SOURCES/0215-smart-card-advises-use-a-wrapper-around-Bash-for-loo.patch
new file mode 100644
index 0000000..7102db1
--- /dev/null
+++ b/SOURCES/0215-smart-card-advises-use-a-wrapper-around-Bash-for-loo.patch
@@ -0,0 +1,121 @@
+From 4e6992f985ebfb6e6c3fb4a6fa7a2959d84ca243 Mon Sep 17 00:00:00 2001
+From: Martin Babinsky <mbabinsk@redhat.com>
+Date: Thu, 22 Jun 2017 15:30:41 +0200
+Subject: [PATCH] smart card advises: use a wrapper around Bash `for` loops
+
+Replace the raw `command` calls constructing the for loops in some
+methods by a wrapper hiding this detail.
+
+https://pagure.io/freeipa/issue/7036
+
+Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
+Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
+---
+ ipaserver/advise/base.py                    | 23 +++++++++++++++++++++++
+ ipaserver/advise/plugins/smart_card_auth.py | 26 +++++++-------------------
+ 2 files changed, 30 insertions(+), 19 deletions(-)
+
+diff --git a/ipaserver/advise/base.py b/ipaserver/advise/base.py
+index 581478fb75bc4f50b6bffe2e4cf9b51de46fa095..be7274417042fca521039b56af60831563f6952b 100644
+--- a/ipaserver/advise/base.py
++++ b/ipaserver/advise/base.py
+@@ -201,6 +201,24 @@ class UnbranchedIfStatement(IfBranch):
+         self.advice_output.command('fi')
+ 
+ 
++class ForLoop(CompoundStatement):
++    """
++    Wrapper around the for loop
++    """
++    def __init__(self, advice_output, loop_variable, iterable):
++        super(ForLoop, self).__init__(advice_output)
++        self.loop_variable = loop_variable
++        self.iterable = iterable
++
++    def begin_statement(self):
++        self.advice_output.command(
++            'for {} in {}'.format(self.loop_variable, self.iterable))
++        self.advice_output.command('do')
++
++    def end_statement(self):
++        self.advice_output.command('done')
++
++
+ class _AdviceOutput(object):
+ 
+     def __init__(self):
+@@ -334,6 +352,11 @@ class _AdviceOutput(object):
+         with self._compound_statement(ElseIfBranch, predicate):
+             yield
+ 
++    @contextmanager
++    def for_loop(self, loop_variable, iterable):
++        with self._compound_statement(ForLoop, loop_variable, iterable):
++            yield
++
+ 
+ class Advice(Plugin):
+     """
+diff --git a/ipaserver/advise/plugins/smart_card_auth.py b/ipaserver/advise/plugins/smart_card_auth.py
+index 2dc9ddb25ce41a8c85aab827a92a1143784d9457..3ff94be1e8b108668989602b1b406a39d23ff501 100644
+--- a/ipaserver/advise/plugins/smart_card_auth.py
++++ b/ipaserver/advise/plugins/smart_card_auth.py
+@@ -40,48 +40,36 @@ class common_smart_card_auth_config(Advice):
+             ['You need to provide one or more paths to the PEM files '
+              'containing CAs signing the Smart Cards']
+         )
+-        self.log.command(
+-            "for {} in ${}".format(
+-                single_ca_path_variable, ca_paths_variable))
+-        self.log.command("do")
+-        with self.log.indented_block():
++        with self.log.for_loop(single_ca_path_variable,
++                               '${}'.format(ca_paths_variable)):
+             self.log.exit_on_predicate(
+                 '[ ! -f "${}" ]'.format(single_ca_path_variable),
+                 ['Invalid CA certificate filename: ${}'.format(
+                     single_ca_path_variable),
+                  'Please check that the path exists and is a valid file']
+             )
+-        self.log.command("done")
+ 
+     def upload_smartcard_ca_certificates_to_systemwide_db(self):
+-        self.log.command(
+-            "for {} in ${}".format(
++        with self.log.for_loop(
+                 self.single_ca_cert_variable_name,
+-                self.smart_card_ca_certs_variable_name))
+-        self.log.command("do")
+-        with self.log.indented_block():
++                '${}'.format(self.smart_card_ca_certs_variable_name)):
+             self.log.command(
+                 'certutil -d {} -A -i ${} -n "Smart Card CA $(uuidgen)" '
+                 '-t CT,C,C'.format(
+                     self.systemwide_nssdb, self.single_ca_cert_variable_name
+-                ),
++                )
+             )
+-        self.log.command("done")
+ 
+     def install_smart_card_signing_ca_certs(self):
+-        self.log.command(
+-            "for {} in ${}".format(
++        with self.log.for_loop(
+                 self.single_ca_cert_variable_name,
+-                self.smart_card_ca_certs_variable_name))
+-        self.log.command("do")
+-        with self.log.indented_block():
++                '${}'.format(self.smart_card_ca_certs_variable_name)):
+             self.log.exit_on_failed_command(
+                 'ipa-cacert-manage install ${} -t CT,C,C'.format(
+                     self.single_ca_cert_variable_name
+                 ),
+                 ['Failed to install external CA certificate to IPA']
+             )
+-        self.log.command("done")
+ 
+     def update_ipa_ca_certificate_store(self):
+         self.log.exit_on_failed_command(
+-- 
+2.9.4
+
diff --git a/SOURCES/0216-smart-card-advise-use-password-when-changing-trust-f.patch b/SOURCES/0216-smart-card-advise-use-password-when-changing-trust-f.patch
new file mode 100644
index 0000000..c49524c
--- /dev/null
+++ b/SOURCES/0216-smart-card-advise-use-password-when-changing-trust-f.patch
@@ -0,0 +1,54 @@
+From 4a9ff573f1c9c91e1e2e1e2d7de70951b7333fb4 Mon Sep 17 00:00:00 2001
+From: Martin Babinsky <mbabinsk@redhat.com>
+Date: Fri, 23 Jun 2017 15:47:48 +0200
+Subject: [PATCH] smart card advise: use password when changing trust flags on
+ HTTP cert
+
+This is to prevent NSS asking for database password when operating in
+FIPS 140 mode.
+
+https://pagure.io/freeipa/issue/7036
+
+Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
+Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
+---
+ ipaserver/advise/plugins/smart_card_auth.py | 9 +++++++--
+ 1 file changed, 7 insertions(+), 2 deletions(-)
+
+diff --git a/ipaserver/advise/plugins/smart_card_auth.py b/ipaserver/advise/plugins/smart_card_auth.py
+index 3ff94be1e8b108668989602b1b406a39d23ff501..5134db535e8f10e8cf850dbf0696b679aacec4f5 100644
+--- a/ipaserver/advise/plugins/smart_card_auth.py
++++ b/ipaserver/advise/plugins/smart_card_auth.py
+@@ -2,6 +2,8 @@
+ # Copyright (C) 2017 FreeIPA Contributors see COPYING for license
+ #
+ 
++import os
++
+ from ipalib.plugable import Registry
+ from ipaplatform import services
+ from ipaplatform.paths import paths
+@@ -172,6 +174,8 @@ class config_server_for_smart_card_auth(common_smart_card_auth_config):
+         return fmt_line.format(directive=directive, filename=filename)
+ 
+     def mark_httpd_cert_as_trusted(self):
++        httpd_nss_database_pwd_file = os.path.join(
++            paths.HTTPD_ALIAS_DIR, 'pwdfile.txt')
+         self.log.comment(
+             'mark the HTTP certificate as trusted peer to avoid '
+             'chicken-egg startup issue')
+@@ -181,8 +185,9 @@ class config_server_for_smart_card_auth(common_smart_card_auth_config):
+                 " cut -f 2 -d ' ')"))
+ 
+         self.log.exit_on_failed_command(
+-            'certutil -M -n $http_cert_nick -d "{}" -t "Pu,u,u"'.format(
+-                paths.HTTPD_ALIAS_DIR),
++            'certutil -M -n $http_cert_nick -d "{}" -f {} -t "Pu,u,u"'.format(
++                paths.HTTPD_ALIAS_DIR,
++                httpd_nss_database_pwd_file),
+             ['Can not set trust flags on HTTP certificate'])
+ 
+     def _interpolate_nssnickname_directive_file_into_command(self, fmt_line):
+-- 
+2.9.4
+
diff --git a/SOURCES/0217-smart-card-advises-ensure-that-krb5-pkinit-is-instal.patch b/SOURCES/0217-smart-card-advises-ensure-that-krb5-pkinit-is-instal.patch
new file mode 100644
index 0000000..66e090e
--- /dev/null
+++ b/SOURCES/0217-smart-card-advises-ensure-that-krb5-pkinit-is-instal.patch
@@ -0,0 +1,46 @@
+From aa123edfdab1836c0915bb75f3bf82e46083b17f Mon Sep 17 00:00:00 2001
+From: Martin Babinsky <mbabinsk@redhat.com>
+Date: Wed, 28 Jun 2017 09:49:18 +0200
+Subject: [PATCH] smart-card-advises: ensure that krb5-pkinit is installed on
+ client
+
+This library is a prerequisite for successful Smart Card authentication
+on the client. The client-side advise should make sure this dependency
+is present.
+
+https://pagure.io/freeipa/issue/7036
+
+Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
+Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
+---
+ ipaserver/advise/plugins/smart_card_auth.py | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/ipaserver/advise/plugins/smart_card_auth.py b/ipaserver/advise/plugins/smart_card_auth.py
+index 5134db535e8f10e8cf850dbf0696b679aacec4f5..fb328f29ca5051ad52c9c5e0000021ad5e8b94e8 100644
+--- a/ipaserver/advise/plugins/smart_card_auth.py
++++ b/ipaserver/advise/plugins/smart_card_auth.py
+@@ -256,6 +256,7 @@ class config_client_for_smart_card_auth(common_smart_card_auth_config):
+         self.check_ccache_not_empty()
+         self.check_and_remove_pam_pkcs11()
+         self.install_opensc_and_dconf_packages()
++        self.install_krb5_client_dependencies()
+         self.start_enable_smartcard_daemon()
+         self.add_pkcs11_module_to_systemwide_db()
+         self.upload_smartcard_ca_certificates_to_systemwide_db()
+@@ -281,6 +282,12 @@ class config_client_for_smart_card_auth(common_smart_card_auth_config):
+             ['Could not install OpenSC package']
+         )
+ 
++    def install_krb5_client_dependencies(self):
++        self.log.exit_on_failed_command(
++            'yum install -y krb5-pkinit-openssl',
++            ['Failed to install Kerberos client PKINIT extensions.']
++        )
++
+     def start_enable_smartcard_daemon(self):
+         self.log.command(
+             'systemctl start {service} {socket} '
+-- 
+2.9.4
+
diff --git a/SOURCES/0218-NULL-LDAP-context-in-call-to-ldap_search_ext_s-durin.patch b/SOURCES/0218-NULL-LDAP-context-in-call-to-ldap_search_ext_s-durin.patch
new file mode 100644
index 0000000..d4ac0c7
--- /dev/null
+++ b/SOURCES/0218-NULL-LDAP-context-in-call-to-ldap_search_ext_s-durin.patch
@@ -0,0 +1,33 @@
+From 0703a575b4e337e7ce41860956bd339c12cd44ea Mon Sep 17 00:00:00 2001
+From: Thierry Bordaz <tbordaz@redhat.com>
+Date: Tue, 20 Jun 2017 18:22:33 +0200
+Subject: [PATCH] NULL LDAP context in call to ldap_search_ext_s during search
+
+    KDC crashes on quite random interval while trying to reach LDAP
+    https://pagure.io/freeipa/issue/7017
+
+Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
+---
+ daemons/ipa-kdb/ipa_kdb.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/daemons/ipa-kdb/ipa_kdb.c b/daemons/ipa-kdb/ipa_kdb.c
+index 050bfc90cef1bce4c932f54bb6050438c60ca79f..c0f1e276ca32ecb318add3a0d36f57acc3d17d51 100644
+--- a/daemons/ipa-kdb/ipa_kdb.c
++++ b/daemons/ipa-kdb/ipa_kdb.c
+@@ -465,6 +465,12 @@ int ipadb_get_connection(struct ipadb_context *ipactx)
+     ret = ipadb_reinit_mspac(ipactx, false);
+     if (ret && ret != ENOENT) {
+         /* TODO: log that there is an issue with adtrust settings */
++        if (ipactx->lcontext == NULL) {
++            /* for some reason ldap connection was reset in ipadb_reinit_mspac
++             * and is no longer established => failure of ipadb_get_connection
++             */
++            goto done;
++        }
+     }
+ 
+     ret = 0;
+-- 
+2.9.4
+
diff --git a/SOURCES/0219-Restore-old-version-of-caIPAserviceCert-for-upgrade-.patch b/SOURCES/0219-Restore-old-version-of-caIPAserviceCert-for-upgrade-.patch
new file mode 100644
index 0000000..0c35b69
--- /dev/null
+++ b/SOURCES/0219-Restore-old-version-of-caIPAserviceCert-for-upgrade-.patch
@@ -0,0 +1,187 @@
+From 533f2539cbc8fe5b4bb748982a6cfee7d73416e6 Mon Sep 17 00:00:00 2001
+From: Fraser Tweedale <ftweedal@redhat.com>
+Date: Wed, 9 Aug 2017 12:55:57 +1000
+Subject: [PATCH] Restore old version of caIPAserviceCert for upgrade only
+
+The latest version of caIPAserviceCert profile includes a feature
+that is not available before Dogtag 10.4, and this version of the
+profile is intended for new installs only (otherwise, problems will
+arise in topologies containing CA replicas at an earlier version).
+But IPA versions before v4.2 did not use LDAP-based profiles, so the
+new version of the profile gets imported when upgrading from
+pre-v4.2 to v4.5 or later.
+
+We do not yet have a proper version- and topology-aware profile
+update mechanism, so to resolve this issue, ship the older version
+of the profile alongside the newer version, and make sure we use the
+older version when importing the profile in an upgrade context.
+
+https://pagure.io/freeipa/issue/7097
+
+Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
+---
+ install/share/profiles/Makefile.am                 |   1 +
+ .../share/profiles/caIPAserviceCert.UPGRADE.cfg    | 109 +++++++++++++++++++++
+ ipaserver/install/cainstance.py                    |  18 +++-
+ 3 files changed, 126 insertions(+), 2 deletions(-)
+ create mode 100644 install/share/profiles/caIPAserviceCert.UPGRADE.cfg
+
+diff --git a/install/share/profiles/Makefile.am b/install/share/profiles/Makefile.am
+index 640ca0a4a54c574da57b62b2b3c23f6db78df2fb..7f188e3fcac2ad80558399015d49216caa32c14b 100644
+--- a/install/share/profiles/Makefile.am
++++ b/install/share/profiles/Makefile.am
+@@ -3,6 +3,7 @@ NULL =
+ appdir = $(IPA_DATA_DIR)/profiles
+ app_DATA =				\
+ 	caIPAserviceCert.cfg		\
++	caIPAserviceCert.UPGRADE.cfg	\
+ 	IECUserRoles.cfg		\
+ 	KDCs_PKINIT_Certs.cfg		\
+ 	$(NULL)
+diff --git a/install/share/profiles/caIPAserviceCert.UPGRADE.cfg b/install/share/profiles/caIPAserviceCert.UPGRADE.cfg
+new file mode 100644
+index 0000000000000000000000000000000000000000..1efd2066b9f75b4e26c390932353f20141d800b9
+--- /dev/null
++++ b/install/share/profiles/caIPAserviceCert.UPGRADE.cfg
+@@ -0,0 +1,109 @@
++profileId=caIPAserviceCert
++classId=caEnrollImpl
++desc=This certificate profile is for enrolling server certificates with IPA-RA agent authentication.
++visible=false
++enable=true
++enableBy=admin
++auth.instance_id=raCertAuth
++name=IPA-RA Agent-Authenticated Server Certificate Enrollment
++input.list=i1,i2
++input.i1.class_id=certReqInputImpl
++input.i2.class_id=submitterInfoInputImpl
++output.list=o1
++output.o1.class_id=certOutputImpl
++policyset.list=serverCertSet
++policyset.serverCertSet.list=1,2,3,4,5,6,7,8,9,10,11
++policyset.serverCertSet.1.constraint.class_id=subjectNameConstraintImpl
++policyset.serverCertSet.1.constraint.name=Subject Name Constraint
++policyset.serverCertSet.1.constraint.params.pattern=CN=[^,]+,.+
++policyset.serverCertSet.1.constraint.params.accept=true
++policyset.serverCertSet.1.default.class_id=subjectNameDefaultImpl
++policyset.serverCertSet.1.default.name=Subject Name Default
++policyset.serverCertSet.1.default.params.name=CN=$$request.req_subject_name.cn$$, $SUBJECT_DN_O
++policyset.serverCertSet.2.constraint.class_id=validityConstraintImpl
++policyset.serverCertSet.2.constraint.name=Validity Constraint
++policyset.serverCertSet.2.constraint.params.range=740
++policyset.serverCertSet.2.constraint.params.notBeforeCheck=false
++policyset.serverCertSet.2.constraint.params.notAfterCheck=false
++policyset.serverCertSet.2.default.class_id=validityDefaultImpl
++policyset.serverCertSet.2.default.name=Validity Default
++policyset.serverCertSet.2.default.params.range=731
++policyset.serverCertSet.2.default.params.startTime=0
++policyset.serverCertSet.3.constraint.class_id=keyConstraintImpl
++policyset.serverCertSet.3.constraint.name=Key Constraint
++policyset.serverCertSet.3.constraint.params.keyType=RSA
++policyset.serverCertSet.3.constraint.params.keyParameters=1024,2048,3072,4096,8192
++policyset.serverCertSet.3.default.class_id=userKeyDefaultImpl
++policyset.serverCertSet.3.default.name=Key Default
++policyset.serverCertSet.4.constraint.class_id=noConstraintImpl
++policyset.serverCertSet.4.constraint.name=No Constraint
++policyset.serverCertSet.4.default.class_id=authorityKeyIdentifierExtDefaultImpl
++policyset.serverCertSet.4.default.name=Authority Key Identifier Default
++policyset.serverCertSet.5.constraint.class_id=noConstraintImpl
++policyset.serverCertSet.5.constraint.name=No Constraint
++policyset.serverCertSet.5.default.class_id=authInfoAccessExtDefaultImpl
++policyset.serverCertSet.5.default.name=AIA Extension Default
++policyset.serverCertSet.5.default.params.authInfoAccessADEnable_0=true
++policyset.serverCertSet.5.default.params.authInfoAccessADLocationType_0=URIName
++policyset.serverCertSet.5.default.params.authInfoAccessADLocation_0=http://$IPA_CA_RECORD.$DOMAIN/ca/ocsp
++policyset.serverCertSet.5.default.params.authInfoAccessADMethod_0=1.3.6.1.5.5.7.48.1
++policyset.serverCertSet.5.default.params.authInfoAccessCritical=false
++policyset.serverCertSet.5.default.params.authInfoAccessNumADs=1
++policyset.serverCertSet.6.constraint.class_id=keyUsageExtConstraintImpl
++policyset.serverCertSet.6.constraint.name=Key Usage Extension Constraint
++policyset.serverCertSet.6.constraint.params.keyUsageCritical=true
++policyset.serverCertSet.6.constraint.params.keyUsageDigitalSignature=true
++policyset.serverCertSet.6.constraint.params.keyUsageNonRepudiation=true
++policyset.serverCertSet.6.constraint.params.keyUsageDataEncipherment=true
++policyset.serverCertSet.6.constraint.params.keyUsageKeyEncipherment=true
++policyset.serverCertSet.6.constraint.params.keyUsageKeyAgreement=false
++policyset.serverCertSet.6.constraint.params.keyUsageKeyCertSign=false
++policyset.serverCertSet.6.constraint.params.keyUsageCrlSign=false
++policyset.serverCertSet.6.constraint.params.keyUsageEncipherOnly=false
++policyset.serverCertSet.6.constraint.params.keyUsageDecipherOnly=false
++policyset.serverCertSet.6.default.class_id=keyUsageExtDefaultImpl
++policyset.serverCertSet.6.default.name=Key Usage Default
++policyset.serverCertSet.6.default.params.keyUsageCritical=true
++policyset.serverCertSet.6.default.params.keyUsageDigitalSignature=true
++policyset.serverCertSet.6.default.params.keyUsageNonRepudiation=true
++policyset.serverCertSet.6.default.params.keyUsageDataEncipherment=true
++policyset.serverCertSet.6.default.params.keyUsageKeyEncipherment=true
++policyset.serverCertSet.6.default.params.keyUsageKeyAgreement=false
++policyset.serverCertSet.6.default.params.keyUsageKeyCertSign=false
++policyset.serverCertSet.6.default.params.keyUsageCrlSign=false
++policyset.serverCertSet.6.default.params.keyUsageEncipherOnly=false
++policyset.serverCertSet.6.default.params.keyUsageDecipherOnly=false
++policyset.serverCertSet.7.constraint.class_id=noConstraintImpl
++policyset.serverCertSet.7.constraint.name=No Constraint
++policyset.serverCertSet.7.default.class_id=extendedKeyUsageExtDefaultImpl
++policyset.serverCertSet.7.default.name=Extended Key Usage Extension Default
++policyset.serverCertSet.7.default.params.exKeyUsageCritical=false
++policyset.serverCertSet.7.default.params.exKeyUsageOIDs=1.3.6.1.5.5.7.3.1,1.3.6.1.5.5.7.3.2
++policyset.serverCertSet.8.constraint.class_id=signingAlgConstraintImpl
++policyset.serverCertSet.8.constraint.name=No Constraint
++policyset.serverCertSet.8.constraint.params.signingAlgsAllowed=SHA1withRSA,SHA256withRSA,SHA512withRSA,MD5withRSA,MD2withRSA,SHA1withDSA,SHA1withEC,SHA256withEC,SHA384withEC,SHA512withEC
++policyset.serverCertSet.8.default.class_id=signingAlgDefaultImpl
++policyset.serverCertSet.8.default.name=Signing Alg
++policyset.serverCertSet.8.default.params.signingAlg=-
++policyset.serverCertSet.9.constraint.class_id=noConstraintImpl
++policyset.serverCertSet.9.constraint.name=No Constraint
++policyset.serverCertSet.9.default.class_id=crlDistributionPointsExtDefaultImpl
++policyset.serverCertSet.9.default.name=CRL Distribution Points Extension Default
++policyset.serverCertSet.9.default.params.crlDistPointsCritical=false
++policyset.serverCertSet.9.default.params.crlDistPointsNum=1
++policyset.serverCertSet.9.default.params.crlDistPointsEnable_0=true
++policyset.serverCertSet.9.default.params.crlDistPointsIssuerName_0=$CRL_ISSUER
++policyset.serverCertSet.9.default.params.crlDistPointsIssuerType_0=DirectoryName
++policyset.serverCertSet.9.default.params.crlDistPointsPointName_0=http://$IPA_CA_RECORD.$DOMAIN/ipa/crl/MasterCRL.bin
++policyset.serverCertSet.9.default.params.crlDistPointsPointType_0=URIName
++policyset.serverCertSet.9.default.params.crlDistPointsReasons_0=
++policyset.serverCertSet.10.constraint.class_id=noConstraintImpl
++policyset.serverCertSet.10.constraint.name=No Constraint
++policyset.serverCertSet.10.default.class_id=subjectKeyIdentifierExtDefaultImpl
++policyset.serverCertSet.10.default.name=Subject Key Identifier Extension Default
++policyset.serverCertSet.10.default.params.critical=false
++policyset.serverCertSet.11.constraint.class_id=noConstraintImpl
++policyset.serverCertSet.11.constraint.name=No Constraint
++policyset.serverCertSet.11.default.class_id=userExtensionDefaultImpl
++policyset.serverCertSet.11.default.name=User Supplied Extension Default
++policyset.serverCertSet.11.default.params.userExtOID=2.5.29.17
+diff --git a/ipaserver/install/cainstance.py b/ipaserver/install/cainstance.py
+index b0e9e8757ec3e3c0d03ed930743ef5a1253b864a..62f79b28000b015edb66f4c39a270097ab3ed666 100644
+--- a/ipaserver/install/cainstance.py
++++ b/ipaserver/install/cainstance.py
+@@ -1568,8 +1568,22 @@ def __get_profile_config(profile_id):
+         CRL_ISSUER='CN=Certificate Authority,o=ipaca',
+         SUBJECT_DN_O=dsinstance.DsInstance().find_subject_base(),
+     )
+-    return ipautil.template_file(
+-        '/usr/share/ipa/profiles/{}.cfg'.format(profile_id), sub_dict)
++
++    # To work around lack of proper profile upgrade system, we ship
++    # two versions of some profiles - one for new installs only, and
++    # the other for upgrading to LDAP-based profiles in an existing
++    # deployment.
++    #
++    # Select UPGRADE version if we are in the 'updates' API context
++    # and an upgrade-specific version of the profile exists.
++    #
++    profile_filename = '/usr/share/ipa/profiles/{}.cfg'.format(profile_id)
++    profile_upg_filename = \
++        '/usr/share/ipa/profiles/{}.UPGRADE.cfg'.format(profile_id)
++    if api.env.context == 'updates' and os.path.isfile(profile_upg_filename):
++        profile_filename = profile_upg_filename
++
++    return ipautil.template_file(profile_filename, sub_dict)
+ 
+ def import_included_profiles():
+     server_id = installutils.realm_to_serverid(api.env.realm)
+-- 
+2.9.4
+
diff --git a/SOURCES/1001-Change-branding-to-IPA-and-Identity-Management.patch b/SOURCES/1001-Change-branding-to-IPA-and-Identity-Management.patch
index f44dd1f..3eb1df2 100644
--- a/SOURCES/1001-Change-branding-to-IPA-and-Identity-Management.patch
+++ b/SOURCES/1001-Change-branding-to-IPA-and-Identity-Management.patch
@@ -1,4 +1,4 @@
-From f7b0cbd43590be6255d61b55cf6b06ffa3904e79 Mon Sep 17 00:00:00 2001
+From 27b4f549af4f55b95ff44b9c5a59b9174ab7ad2e Mon Sep 17 00:00:00 2001
 From: Jan Cholasta <jcholast@redhat.com>
 Date: Tue, 14 Mar 2017 15:48:07 +0000
 Subject: [PATCH] Change branding to IPA and Identity Management
diff --git a/SOURCES/1002-Package-copy-schema-to-ca.py.patch b/SOURCES/1002-Package-copy-schema-to-ca.py.patch
index b6534aa..3972454 100644
--- a/SOURCES/1002-Package-copy-schema-to-ca.py.patch
+++ b/SOURCES/1002-Package-copy-schema-to-ca.py.patch
@@ -1,4 +1,4 @@
-From 9800e6fcc16455635e2d774a33009d6fb02646db Mon Sep 17 00:00:00 2001
+From 85ac8d7f55b26f7d783844acbf942f5db99d0a37 Mon Sep 17 00:00:00 2001
 From: Jan Cholasta <jcholast@redhat.com>
 Date: Tue, 14 Mar 2017 16:07:15 +0000
 Subject: [PATCH] Package copy-schema-to-ca.py
@@ -10,7 +10,7 @@ This reverts commit f4c7f1dd8a9ce530a8291219a904686ee47e59c7.
  2 files changed, 5 insertions(+), 2 deletions(-)
 
 diff --git a/freeipa.spec.in b/freeipa.spec.in
-index d7f8d11ec553cfe299937e1e5f8cc27caed32b08..a075cbb4e2bd6fb0fecfca96a1568c07a27080af 100644
+index 721e512039a4d7f9d2ed94d7620b083732c56304..99e69d81dd4104063ac68a9429eeb53ee1d36245 100644
 --- a/freeipa.spec.in
 +++ b/freeipa.spec.in
 @@ -1285,6 +1285,7 @@ fi
@@ -22,7 +22,7 @@ index d7f8d11ec553cfe299937e1e5f8cc27caed32b08..a075cbb4e2bd6fb0fecfca96a1568c07
  %{_usr}/share/ipa/*.uldif
  %{_usr}/share/ipa/*.template
 diff --git a/ipaserver/install/cainstance.py b/ipaserver/install/cainstance.py
-index b0e9e8757ec3e3c0d03ed930743ef5a1253b864a..b0d8208cc05b94f697b7b8c81caee9d311e2d0f0 100644
+index 62f79b28000b015edb66f4c39a270097ab3ed666..d876c5b385a250f3bd9c2689f9794ef7f89720a6 100644
 --- a/ipaserver/install/cainstance.py
 +++ b/ipaserver/install/cainstance.py
 @@ -1311,9 +1311,11 @@ def replica_ca_install_check(config, promote):
diff --git a/SOURCES/1003-Revert-Increased-mod_wsgi-socket-timeout.patch b/SOURCES/1003-Revert-Increased-mod_wsgi-socket-timeout.patch
index 2ec7313..8f4863a 100644
--- a/SOURCES/1003-Revert-Increased-mod_wsgi-socket-timeout.patch
+++ b/SOURCES/1003-Revert-Increased-mod_wsgi-socket-timeout.patch
@@ -1,4 +1,4 @@
-From 1c88c60dd72621e77fc2605e6bd4d670a3d65b1d Mon Sep 17 00:00:00 2001
+From e419842024b0fc9a774988972fadcbaf4650c395 Mon Sep 17 00:00:00 2001
 From: Jan Cholasta <jcholast@redhat.com>
 Date: Wed, 22 Jun 2016 13:53:46 +0200
 Subject: [PATCH] Revert "Increased mod_wsgi socket-timeout"
diff --git a/SOURCES/1004-Remove-csrgen.patch b/SOURCES/1004-Remove-csrgen.patch
index b917a5a..a532876 100644
--- a/SOURCES/1004-Remove-csrgen.patch
+++ b/SOURCES/1004-Remove-csrgen.patch
@@ -1,4 +1,4 @@
-From c211f36d3cc765379ff0ae324dfb052d7ce13b99 Mon Sep 17 00:00:00 2001
+From 12d2356795d64089ce2578031a1297d56c8048ce Mon Sep 17 00:00:00 2001
 From: Jan Cholasta <jcholast@redhat.com>
 Date: Thu, 16 Mar 2017 09:44:21 +0000
 Subject: [PATCH] Remove csrgen
@@ -75,7 +75,7 @@ https://bugzilla.redhat.com/show_bug.cgi?id=1432630
  delete mode 100644 ipatests/test_ipaclient/test_csrgen.py
 
 diff --git a/freeipa.spec.in b/freeipa.spec.in
-index a075cbb4e2bd6fb0fecfca96a1568c07a27080af..f4576927c9be3d7c7b7f971f0184cad3166083b7 100644
+index 99e69d81dd4104063ac68a9429eeb53ee1d36245..3892e502c0c64cca25e2e50a0ff53a15a556d2f3 100644
 --- a/freeipa.spec.in
 +++ b/freeipa.spec.in
 @@ -194,7 +194,6 @@ BuildRequires:  python-sssdconfig
diff --git a/SOURCES/ipa-centos-branding.patch b/SOURCES/ipa-centos-branding.patch
deleted file mode 100644
index 673cd2f..0000000
--- a/SOURCES/ipa-centos-branding.patch
+++ /dev/null
@@ -1,38 +0,0 @@
-From 99efecaf87dc1fc9517efaff441a6a7ce46444eb Mon Sep 17 00:00:00 2001
-From: Jim Perrin <jperrin@centos.org>
-Date: Wed, 11 Mar 2015 10:37:03 -0500
-Subject: [PATCH] update for new ntp server method
-
----
- ipaplatform/base/paths.py        | 1 +
- ipaserver/install/ntpinstance.py | 2 ++
- 2 files changed, 3 insertions(+)
-
-diff --git a/ipaplatform/base/paths.py b/ipaplatform/base/paths.py
-index af50262..5090062 100644
---- a/ipaplatform/base/paths.py
-+++ b/ipaplatform/base/paths.py
-@@ -99,6 +99,7 @@ class BasePathNamespace(object):
-     PKI_TOMCAT_ALIAS_DIR = "/etc/pki/pki-tomcat/alias/"
-     PKI_TOMCAT_PASSWORD_CONF = "/etc/pki/pki-tomcat/password.conf"
-     ETC_REDHAT_RELEASE = "/etc/redhat-release"
-+    ETC_CENTOS_RELEASE = "/etc/centos-release"
-     RESOLV_CONF = "/etc/resolv.conf"
-     SAMBA_KEYTAB = "/etc/samba/samba.keytab"
-     SMB_CONF = "/etc/samba/smb.conf"
-diff --git a/ipaserver/install/ntpinstance.py b/ipaserver/install/ntpinstance.py
-index c653525..4b0578b 100644
---- a/ipaserver/install/ntpinstance.py
-+++ b/ipaserver/install/ntpinstance.py
-@@ -44,6 +44,8 @@ class NTPInstance(service.Service):
-         os = ""
-         if ipautil.file_exists(paths.ETC_FEDORA_RELEASE):
-             os = "fedora"
-+        elif ipautil.file_exists(paths.ETC_CENTOS_RELEASE):
-+            os = "centos"
-         elif ipautil.file_exists(paths.ETC_REDHAT_RELEASE):
-             os = "rhel"
- 
--- 
-1.8.3.1
-
diff --git a/SPECS/ipa.spec b/SPECS/ipa.spec
index 5c7b789..183b97d 100644
--- a/SPECS/ipa.spec
+++ b/SPECS/ipa.spec
@@ -68,7 +68,7 @@
 
 Name:           ipa
 Version:        %{IPA_VERSION}
-Release:        21%{?dist}
+Release:        21%{?dist}.1.2
 Summary:        The Identity, Policy and Audit system
 
 Group:          System Environment/Base
@@ -76,10 +76,10 @@ License:        GPLv3+
 URL:            http://www.freeipa.org/
 Source0:        https://releases.pagure.org/freeipa/freeipa-%{version}.tar.gz
 # RHEL spec file only: START: Change branding to IPA and Identity Management
-#Source1:        header-logo.png
-#Source2:        login-screen-background.jpg
-#Source3:        login-screen-logo.png
-#Source4:        product-name.png
+Source1:        header-logo.png
+Source2:        login-screen-background.jpg
+Source3:        login-screen-logo.png
+Source4:        product-name.png
 # RHEL spec file only: END: Change branding to IPA and Identity Management
 BuildRoot:      %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
 
@@ -288,6 +288,21 @@ Patch0201:      0201-ipa-sam-replace-encode_nt_key-with-E_md4hash.patch
 Patch0202:      0202-ipa_pwd_extop-do-not-generate-NT-hashes-in-FIPS-mode.patch
 Patch0203:      0203-Make-sure-we-check-ccaches-in-all-rpcserver-paths.patch
 Patch0204:      0204-replica-install-drop-in-IPA-specific-config-to-tmpfi.patch
+Patch0205:      0205-Add-CommonNameToSANDefault-to-default-cert-profile.patch
+Patch0206:      0206-smart-card-advises-configure-systemwide-NSS-DB-also-.patch
+Patch0207:      0207-smart-card-advises-add-steps-to-store-smart-card-sig.patch
+Patch0208:      0208-Allow-to-pass-in-multiple-CA-cert-paths-to-the-smart.patch
+Patch0209:      0209-add-a-class-that-tracks-the-indentation-in-the-gener.patch
+Patch0210:      0210-delegate-the-indentation-handling-in-advises-to-dedi.patch
+Patch0211:      0211-advise-add-an-infrastructure-for-formatting-Bash-com.patch
+Patch0212:      0212-delegate-formatting-of-compound-Bash-statements-to-d.patch
+Patch0213:      0213-Fix-indentation-of-statements-in-Smart-card-advises.patch
+Patch0214:      0214-Use-the-compound-statement-formatting-API-for-config.patch
+Patch0215:      0215-smart-card-advises-use-a-wrapper-around-Bash-for-loo.patch
+Patch0216:      0216-smart-card-advise-use-password-when-changing-trust-f.patch
+Patch0217:      0217-smart-card-advises-ensure-that-krb5-pkinit-is-instal.patch
+Patch0218:      0218-NULL-LDAP-context-in-call-to-ldap_search_ext_s-durin.patch
+Patch0219:      0219-Restore-old-version-of-caIPAserviceCert-for-upgrade-.patch
 
 Patch1001:      1001-Change-branding-to-IPA-and-Identity-Management.patch
 Patch1002:      1002-Package-copy-schema-to-ca.py.patch
@@ -514,8 +529,10 @@ Requires(post): systemd-units
 Requires: selinux-policy >= %{selinux_policy_version}
 Requires(post): selinux-policy-base >= %{selinux_policy_version}
 Requires: slapi-nis >= %{slapi_nis_version}
-Requires: pki-ca >= 10.3.5-11
-Requires: pki-kra >= 10.3.5-11
+# Required because of: https://bugzilla.redhat.com/show_bug.cgi?id=1475238
+# related pki-core update: https://bugzilla.redhat.com/show_bug.cgi?id=1305993
+Requires: pki-ca >= 10.4.0-1
+Requires: pki-kra >= 10.4.0-1
 Requires(preun): python systemd-units
 Requires(postun): python systemd-units
 Requires: policycoreutils >= 2.1.14-37
@@ -1087,10 +1104,10 @@ cp -r %{_builddir}/freeipa-%{version} %{_builddir}/freeipa-%{version}-python3
 %endif # with_python3
 
 # RHEL spec file only: START: Change branding to IPA and Identity Management
-#cp %SOURCE1 install/ui/images/header-logo.png
-#cp %SOURCE2 install/ui/images/login-screen-background.jpg
-#cp %SOURCE3 install/ui/images/login-screen-logo.png
-#cp %SOURCE4 install/ui/images/product-name.png
+cp %SOURCE1 install/ui/images/header-logo.png
+cp %SOURCE2 install/ui/images/login-screen-background.jpg
+cp %SOURCE3 install/ui/images/login-screen-logo.png
+cp %SOURCE4 install/ui/images/product-name.png
 # RHEL spec file only: END: Change branding to IPA and Identity Management
 
 
@@ -1114,8 +1131,7 @@ find \
 %configure --with-vendor-suffix=-%{release} \
            %{enable_server_option} \
            %{with_ipatests_option} \
-           %{linter_options} \
-           --with-ipaplatform=rhel
+           %{linter_options}
 
 %make_build
 
@@ -1839,9 +1855,35 @@ fi
 
 
 %changelog
-* Mon Jul 31 2017 CentOS Sources <bugs@centos.org> - 4.5.0-21.el7.centos
-- Roll in CentOS Branding
-- set ipaplatform to rhel for compatibilty for updates
+* Wed Aug 16 2017 Pavel Vomacka <pvomacka@redhat.com> - 4.5.0-21.el7.1.2
+- Fixing issues reported by Errata tool
+
+* Tue Aug 15 2017 Pavel Vomacka <pvomacka@redhat.com> - 4.5.0-21.el7.1.1
+- Resolves: #1477046 Use CommonNameToSANDefault in default profile
+  (new installs only)
+  - Restore old version of caIPAserviceCert for upgrade only
+
+* Tue Aug 1 2017 Pavel Vomacka <pvomacka@redhat.com> - 4.5.0-21.el7.1
+- Resolves: #1473272 Provide a tooling automating the configuration
+  of Smart Card authentication on a FreeIPA master
+  - smart-card advises: configure systemwide NSS DB also on master
+  - smart-card advises: add steps to store smart card signing CA cert
+  - Allow to pass in multiple CA cert paths to the smart card advises
+  - add a class that tracks the indentation in the generated advises
+  - delegate the indentation handling in advises to dedicated class
+  - advise: add an infrastructure for formatting Bash compound statements
+  - delegate formatting of compound Bash statements to dedicated classes
+  - Fix indentation of statements in Smart card advises
+  - Use the compound statement formatting API for configuring PKINIT
+  - smart card advises: use a wrapper around Bash `for` loops
+  - smart card advise: use password when changing trust flags on HTTP cert
+  - smart-card-advises: ensure that krb5-pkinit is installed on client
+- Resolves: #1477046 Use CommonNameToSANDefault in default profile 
+  (new installs only)
+  - Add CommonNameToSANDefault to default cert profile
+- Resolves: #1475664 NULL LDAP context in call to ldap_search_ext_s
+  during search in cn=ad,cn=trusts,dc=example,dc=com
+  - NULL LDAP context in call to ldap_search_ext_s during search
 
 * Wed Jul 12 2017 Pavel Vomacka <pvomacka@redhat.com> - 4.5.0-21.el7
 - Resolves: #1470125 Replica install fails to configure IPA-specific