diff --git a/.gitignore b/.gitignore
index a43c0f8..6174b45 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,4 @@
-SOURCES/freeipa-4.5.0.tar.gz
+SOURCES/freeipa-4.5.4.tar.gz
 SOURCES/header-logo.png
 SOURCES/login-screen-background.jpg
 SOURCES/login-screen-logo.png
diff --git a/.ipa.metadata b/.ipa.metadata
index 61ded07..7ed498a 100644
--- a/.ipa.metadata
+++ b/.ipa.metadata
@@ -1,4 +1,4 @@
-686e9b1375659524de83e1b78df66b355715438e SOURCES/freeipa-4.5.0.tar.gz
+2707c6f6de4ab05e1cbd741297b655e1d1ef1c24 SOURCES/freeipa-4.5.4.tar.gz
 77c318cf1f4fc25cf847de0692a77859a767c0e3 SOURCES/header-logo.png
 8727245558422bf966d60677568925f081b8e299 SOURCES/login-screen-background.jpg
 24a29d79efbd0906777be4639957abda111fca4b SOURCES/login-screen-logo.png
diff --git a/SOURCES/0001-Add-options-to-allow-ticket-caching.patch b/SOURCES/0001-Add-options-to-allow-ticket-caching.patch
deleted file mode 100644
index 1c3b8e0..0000000
--- a/SOURCES/0001-Add-options-to-allow-ticket-caching.patch
+++ /dev/null
@@ -1,39 +0,0 @@
-From 6c4d53f843575d5e69a0c310cdb2e5026751faa4 Mon Sep 17 00:00:00 2001
-From: Simo Sorce <simo@redhat.com>
-Date: Mon, 6 Mar 2017 13:46:44 -0500
-Subject: [PATCH] Add options to allow ticket caching
-
-This new option (planned to land in gssproxy 0.7) we cache the ldap
-ticket properly and avoid a ticket lookup to the KDC on each and every
-ldap connection. (Also requires krb5 libs 1.15.1 to benefit from caching).
-
-Ticket: https://pagure.io/freeipa/issue/6771
-
-Signed-off-by: Simo Sorce <simo@redhat.com>
-Reviewed-By: Martin Babinsky <mbabinsk@redhat.com>
----
- install/share/gssproxy.conf.template | 2 ++
- 1 file changed, 2 insertions(+)
-
-diff --git a/install/share/gssproxy.conf.template b/install/share/gssproxy.conf.template
-index fbb158a689a430168ea9841d59cb558755371968..9d111009f5a5ba24dd474be336bf0cb27ab59aab 100644
---- a/install/share/gssproxy.conf.template
-+++ b/install/share/gssproxy.conf.template
-@@ -4,6 +4,7 @@
-   cred_store = keytab:$HTTP_KEYTAB
-   cred_store = client_keytab:$HTTP_KEYTAB
-   allow_protocol_transition = true
-+  allow_client_ccache_sync = true
-   cred_usage = both
-   euid = $HTTPD_USER
- 
-@@ -12,5 +13,6 @@
-   cred_store = keytab:$HTTP_KEYTAB
-   cred_store = client_keytab:$HTTP_KEYTAB
-   allow_constrained_delegation = true
-+  allow_client_ccache_sync = true
-   cred_usage = initiate
-   euid = $IPAAPI_USER
--- 
-2.12.0
-
diff --git a/SOURCES/0001-ds-ignore-time-skew-during-initial-replication-step.patch b/SOURCES/0001-ds-ignore-time-skew-during-initial-replication-step.patch
new file mode 100644
index 0000000..d641eb3
--- /dev/null
+++ b/SOURCES/0001-ds-ignore-time-skew-during-initial-replication-step.patch
@@ -0,0 +1,86 @@
+From a3bcb05ce1c554aa98af9343bec7335521db3a3e Mon Sep 17 00:00:00 2001
+From: Alexander Bokovoy <abokovoy@redhat.com>
+Date: Mon, 16 Oct 2017 13:32:38 +0300
+Subject: [PATCH] ds: ignore time skew during initial replication step
+
+Initial replica creation can go with ignoring time skew checks.
+We should, however, force time skew checks during normal operation.
+
+Fixes https://pagure.io/freeipa/issue/7211
+
+Reviewed-By: Rob Crittenden <rcritten@redhat.com>
+---
+ install/share/Makefile.am                    |  1 +
+ install/share/replica-prevent-time-skew.ldif |  4 ++++
+ ipaserver/install/dsinstance.py              | 24 ++++++++++++++++++++++++
+ 3 files changed, 29 insertions(+)
+ create mode 100644 install/share/replica-prevent-time-skew.ldif
+
+diff --git a/install/share/Makefile.am b/install/share/Makefile.am
+index 85a061c6976dcc55b0ba2250423a344e14f2ce97..46b3d77663113f770765c8bd1d8a916791d628f4 100644
+--- a/install/share/Makefile.am
++++ b/install/share/Makefile.am
+@@ -38,6 +38,7 @@ dist_app_DATA =				\
+ 	default-trust-view.ldif		\
+ 	delegation.ldif			\
+ 	replica-acis.ldif		\
++	replica-prevent-time-skew.ldif  \
+ 	ds-nfiles.ldif			\
+ 	dns.ldif			\
+ 	dnssec.ldif			\
+diff --git a/install/share/replica-prevent-time-skew.ldif b/install/share/replica-prevent-time-skew.ldif
+new file mode 100644
+index 0000000000000000000000000000000000000000..5d301feddb56347f3b35be89edaae1a7d91e07de
+--- /dev/null
++++ b/install/share/replica-prevent-time-skew.ldif
+@@ -0,0 +1,4 @@
++dn: cn=config
++changetype: modify
++replace: nsslapd-ignore-time-skew
++nsslapd-ignore-time-skew: $SKEWVALUE
+diff --git a/ipaserver/install/dsinstance.py b/ipaserver/install/dsinstance.py
+index c9db8ac28c3ca10539b745ca09f4d8aaece02e0c..7a88612997a3fa96cf394852401fb01e5e4501d5 100644
+--- a/ipaserver/install/dsinstance.py
++++ b/ipaserver/install/dsinstance.py
+@@ -392,7 +392,21 @@ class DsInstance(service.Service):
+         self.step("restarting directory server", self.__restart_instance)
+ 
+         self.step("creating DS keytab", self.request_service_keytab)
++
++        # 389-ds allows to ignore time skew during replication. It is disabled
++        # by default to avoid issues with non-contiguous CSN values which
++        # derived from a time stamp when the change occurs. However, there are
++        # cases when we are interested only in the changes coming from the
++        # other side and should therefore allow ignoring the time skew.
++        #
++        # This helps with initial replication or force-sync because
++        # the receiving side has no valuable changes itself yet.
++        self.step("ignore time skew for initial replication",
++                  self.__replica_ignore_initial_time_skew)
++
+         self.step("setting up initial replication", self.__setup_replica)
++        self.step("prevent time skew after initial replication",
++                  self.replica_manage_time_skew)
+         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
+@@ -929,6 +943,16 @@ class DsInstance(service.Service):
+     def __add_replication_acis(self):
+         self._ldap_mod("replica-acis.ldif", self.sub_dict)
+ 
++    def __replica_ignore_initial_time_skew(self):
++        self.replica_manage_time_skew(prevent=False)
++
++    def replica_manage_time_skew(self, prevent=True):
++        if prevent:
++            self.sub_dict['SKEWVALUE'] = 'off'
++        else:
++            self.sub_dict['SKEWVALUE'] = 'on'
++        self._ldap_mod("replica-prevent-time-skew.ldif", self.sub_dict)
++
+     def __setup_s4u2proxy(self):
+         self._ldap_mod("replica-s4u2proxy.ldif", self.sub_dict)
+ 
+-- 
+2.9.5
+
diff --git a/SOURCES/0002-Use-connection-keep-alive.patch b/SOURCES/0002-Use-connection-keep-alive.patch
deleted file mode 100644
index c7320ea..0000000
--- a/SOURCES/0002-Use-connection-keep-alive.patch
+++ /dev/null
@@ -1,35 +0,0 @@
-From 1216aaa3c5f5e3dc3a81de81633eaade15df1129 Mon Sep 17 00:00:00 2001
-From: Christian Heimes <cheimes@redhat.com>
-Date: Mon, 20 Mar 2017 08:47:41 +0100
-Subject: [PATCH] Use connection keep-alive
-
-Do not forcefully close the connection after every request. This enables
-HTTP connection keep-alive, also known as persistent TCP and TLS/SSL
-connection. Keep-alive speed up consecutive HTTP requests by 15% (for
-local, low-latency network connections to a fast server) to multiple
-times (high latency connections or remote peers).
-
-https://pagure.io/freeipa/issue/6641
-
-Signed-off-by: Christian Heimes <cheimes@redhat.com>
-Reviewed-By: Tomas Krizek <tkrizek@redhat.com>
----
- ipalib/rpc.py | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/ipalib/rpc.py b/ipalib/rpc.py
-index 16ffb8b541107e3ce1a84d143db007a1105b49b5..8d587180a65bd06b644c6df23ac9fb26eb7e97dd 100644
---- a/ipalib/rpc.py
-+++ b/ipalib/rpc.py
-@@ -686,7 +686,7 @@ class KerbTransport(SSLTransport):
-                 return self.parse_response(response)
-         except gssapi.exceptions.GSSError as e:
-             self._handle_exception(e)
--        finally:
-+        except BaseException:
-             self.close()
- 
-     if six.PY3:
--- 
-2.12.1
-
diff --git a/SOURCES/0002-ipa-replica-manage-implicitly-ignore-initial-time-sk.patch b/SOURCES/0002-ipa-replica-manage-implicitly-ignore-initial-time-sk.patch
new file mode 100644
index 0000000..ecde808
--- /dev/null
+++ b/SOURCES/0002-ipa-replica-manage-implicitly-ignore-initial-time-sk.patch
@@ -0,0 +1,41 @@
+From 469f8ba59eb369267a9d404291ce7794f996d9f4 Mon Sep 17 00:00:00 2001
+From: Alexander Bokovoy <abokovoy@redhat.com>
+Date: Mon, 16 Oct 2017 13:46:38 +0300
+Subject: [PATCH] ipa-replica-manage: implicitly ignore initial time skew in
+ force-sync
+
+When performing force synchronization, implicitly ignore initial
+time skew (if any) and restore it afterwards.
+
+This also changes semantics of force-sync by waiting until the end of
+the initial replication.
+
+Fixes https://pagure.io/freeipa/issue/7211
+
+Reviewed-By: Rob Crittenden <rcritten@redhat.com>
+---
+ install/tools/ipa-replica-manage | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/install/tools/ipa-replica-manage b/install/tools/ipa-replica-manage
+index f802201b7f93facb1e78463aa02eab66a1ae23ea..c00d8ca3a0fa8228c5aa782a270991f14ee16974 100755
+--- a/install/tools/ipa-replica-manage
++++ b/install/tools/ipa-replica-manage
+@@ -1231,8 +1231,14 @@ def force_sync(realm, thishost, fromhost, dirman_passwd, nolookup=False):
+         repl = replication.ReplicationManager(realm, thishost, dirman_passwd)
+         repl.force_sync(repl.conn, fromhost)
+     else:
++        ds = dsinstance.DsInstance(realm_name=realm)
++        ds.ldapi = os.getegid() == 0
++        ds.replica_manage_time_skew(prevent=False)
+         repl = replication.ReplicationManager(realm, fromhost, dirman_passwd)
+         repl.force_sync(repl.conn, thishost)
++        agreement = repl.get_replication_agreement(thishost)
++        repl.wait_for_repl_init(repl.conn, agreement.dn)
++        ds.replica_manage_time_skew(prevent=True)
+ 
+ def show_DNA_ranges(hostname, master, realm, dirman_passwd, nextrange=False,
+                     nolookup=False):
+-- 
+2.9.5
+
diff --git a/SOURCES/0003-Add-debug-logging-for-keep-alive.patch b/SOURCES/0003-Add-debug-logging-for-keep-alive.patch
deleted file mode 100644
index 4fc4f1d..0000000
--- a/SOURCES/0003-Add-debug-logging-for-keep-alive.patch
+++ /dev/null
@@ -1,68 +0,0 @@
-From bdaf584ef5ebcae08e86142ceb80ebe56ac11fa3 Mon Sep 17 00:00:00 2001
-From: Christian Heimes <cheimes@redhat.com>
-Date: Mon, 20 Mar 2017 08:47:51 +0100
-Subject: [PATCH] Add debug logging for keep-alive
-
-Signed-off-by: Christian Heimes <cheimes@redhat.com>
-Reviewed-By: Tomas Krizek <tkrizek@redhat.com>
----
- ipalib/rpc.py | 21 ++++++++++++++++++++-
- 1 file changed, 20 insertions(+), 1 deletion(-)
-
-diff --git a/ipalib/rpc.py b/ipalib/rpc.py
-index 8d587180a65bd06b644c6df23ac9fb26eb7e97dd..38321d17cf2c9529738aa45cc44bbd38b08b032b 100644
---- a/ipalib/rpc.py
-+++ b/ipalib/rpc.py
-@@ -79,6 +79,13 @@ except ImportError:
-     from xmlrpc.client import (Binary, Fault, DateTime, dumps, loads, ServerProxy,
-             Transport, ProtocolError, MININT, MAXINT)
- 
-+# pylint: disable=import-error
-+if six.PY3:
-+    from http.client import RemoteDisconnected
-+else:
-+    from httplib import BadStatusLine as RemoteDisconnected
-+# pylint: enable=import-error
-+
- 
- if six.PY3:
-     unicode = str
-@@ -531,6 +538,7 @@ class SSLTransport(LanguageAwareTransport):
-         host, self._extra_headers, _x509 = self.get_host_info(host)
- 
-         if self._connection and host == self._connection[0]:
-+            root_logger.debug("HTTP connection keep-alive (%s)", host)
-             return self._connection[1]
- 
-         conn = create_https_connection(
-@@ -540,6 +548,7 @@ class SSLTransport(LanguageAwareTransport):
-             tls_version_max=api.env.tls_version_max)
- 
-         conn.connect()
-+        root_logger.debug("New HTTP connection (%s)", host)
- 
-         self._connection = host, conn
-         return self._connection[1]
-@@ -686,8 +695,18 @@ class KerbTransport(SSLTransport):
-                 return self.parse_response(response)
-         except gssapi.exceptions.GSSError as e:
-             self._handle_exception(e)
--        except BaseException:
-+        except RemoteDisconnected:
-+            # keep-alive connection was terminated by remote peer, close
-+            # connection and let transport handle reconnect for us.
-+            self.close()
-+            root_logger.debug("HTTP server has closed connection (%s)", host)
-+            raise
-+        except BaseException as e:
-+            # Unexpected exception may leave connections in a bad state.
-             self.close()
-+            root_logger.debug("HTTP connection destroyed (%s)",
-+                              host, exc_info=True)
-+            raise
- 
-     if six.PY3:
-         def __send_request(self, connection, host, handler, request_body, debug):
--- 
-2.12.1
-
diff --git a/SOURCES/0003-Checks-if-replica-s4u2proxy.ldif-should-be-applied.patch b/SOURCES/0003-Checks-if-replica-s4u2proxy.ldif-should-be-applied.patch
new file mode 100644
index 0000000..475d399
--- /dev/null
+++ b/SOURCES/0003-Checks-if-replica-s4u2proxy.ldif-should-be-applied.patch
@@ -0,0 +1,51 @@
+From 17fab4982fcb8b8af6c20130907dd3d4bad7f699 Mon Sep 17 00:00:00 2001
+From: Felipe Barreto <fbarreto@redhat.com>
+Date: Fri, 13 Oct 2017 09:19:43 +0200
+Subject: [PATCH] Checks if replica-s4u2proxy.ldif should be applied
+
+Before applying replica-s3u2proxy.ldif, we check
+if the values are already there. The values can be
+there if a replica installation was done in the past
+and some info was left behind. Also, the code checks
+the values independently.
+
+https://pagure.io/freeipa/issue/7174
+
+Reviewed-By: Rob Crittenden <rcritten@redhat.com>
+---
+ ipaserver/install/dsinstance.py | 19 ++++++++++++++++++-
+ 1 file changed, 18 insertions(+), 1 deletion(-)
+
+diff --git a/ipaserver/install/dsinstance.py b/ipaserver/install/dsinstance.py
+index 7a88612997a3fa96cf394852401fb01e5e4501d5..923f483340a26a614001701ce6c235dd73501501 100644
+--- a/ipaserver/install/dsinstance.py
++++ b/ipaserver/install/dsinstance.py
+@@ -954,7 +954,24 @@ class DsInstance(service.Service):
+         self._ldap_mod("replica-prevent-time-skew.ldif", self.sub_dict)
+ 
+     def __setup_s4u2proxy(self):
+-        self._ldap_mod("replica-s4u2proxy.ldif", self.sub_dict)
++
++        def __add_principal(last_cn, principal, self):
++            dn = DN(('cn', last_cn), ('cn', 's4u2proxy'),
++                    ('cn', 'etc'), self.suffix)
++
++            value = '{principal}/{fqdn}@{realm}'.format(fqdn=self.fqdn,
++                                                        realm=self.realm,
++                                                        principal=principal)
++
++            entry = api.Backend.ldap2.get_entry(dn, ['memberPrincipal'])
++            try:
++                entry['memberPrincipal'].append(value)
++                api.Backend.ldap2.update_entry(entry)
++            except errors.EmptyModlist:
++                pass
++
++        __add_principal('ipa-http-delegation', 'HTTP', self)
++        __add_principal('ipa-ldap-delegation-targets', 'ldap', self)
+ 
+     def __create_indices(self):
+         self._ldap_mod("indices.ldif")
+-- 
+2.9.5
+
diff --git a/SOURCES/0004-Increase-Apache-HTTPD-s-default-keep-alive-timeout.patch b/SOURCES/0004-Increase-Apache-HTTPD-s-default-keep-alive-timeout.patch
deleted file mode 100644
index 4750bad..0000000
--- a/SOURCES/0004-Increase-Apache-HTTPD-s-default-keep-alive-timeout.patch
+++ /dev/null
@@ -1,41 +0,0 @@
-From 2905ebdb1a6c668da1a12d79824c6710e3f0eb94 Mon Sep 17 00:00:00 2001
-From: Christian Heimes <cheimes@redhat.com>
-Date: Mon, 20 Mar 2017 08:47:56 +0100
-Subject: [PATCH] Increase Apache HTTPD's default keep alive timeout
-
-Apache has a default keep alive timeout of 5 seconds. That's too low for
-interactive commands, e.g. password prompts. 30 seconds sounds like a
-good compromise.
-
-Signed-off-by: Christian Heimes <cheimes@redhat.com>
-Reviewed-By: Tomas Krizek <tkrizek@redhat.com>
----
- install/conf/ipa.conf | 7 ++++++-
- 1 file changed, 6 insertions(+), 1 deletion(-)
-
-diff --git a/install/conf/ipa.conf b/install/conf/ipa.conf
-index 164231c729a8b3d64982ea0d9592e949635d7418..e1f1a581b4e8a91b899bcf165ca81f266fa9e516 100644
---- a/install/conf/ipa.conf
-+++ b/install/conf/ipa.conf
-@@ -1,5 +1,5 @@
- #
--# VERSION 24 - DO NOT REMOVE THIS LINE
-+# VERSION 25 - DO NOT REMOVE THIS LINE
- #
- # This file may be overwritten on upgrades.
- #
-@@ -20,6 +20,11 @@ DirectoryIndex index.html
- # requests, ticket #2767. This should easily support a 64KiB PAC.
- LimitRequestFieldSize 100000
- 
-+# Increase connection keep alive time. Default value is 5 seconds, which is too
-+# short for interactive ipa commands. 30 seconds is a good compromise.
-+KeepAlive On
-+KeepAliveTimeout 30
-+
- # ipa-rewrite.conf is loaded separately
- 
- # This is required so the auto-configuration works with Firefox 2+
--- 
-2.12.1
-
diff --git a/SOURCES/0004-ldap-limit-the-retro-changelog-to-dns-subtree.patch b/SOURCES/0004-ldap-limit-the-retro-changelog-to-dns-subtree.patch
new file mode 100644
index 0000000..5fa10b1
--- /dev/null
+++ b/SOURCES/0004-ldap-limit-the-retro-changelog-to-dns-subtree.patch
@@ -0,0 +1,32 @@
+From d3c36fb83314c3fd1b87572a1c80687f06d7e2d5 Mon Sep 17 00:00:00 2001
+From: Tomas Krizek <tkrizek@redhat.com>
+Date: Mon, 23 Oct 2017 14:06:20 +0200
+Subject: [PATCH] ldap: limit the retro changelog to dns subtree
+
+The content synchronization plugin can be limited to the dns subtree in
+Directory Server. This increases performance and helps to prevent some
+potential issues.
+
+Fixes: https://pagure.io/freeipa/issue/6515
+Signed-off-by: Tomas Krizek <tkrizek@redhat.com>
+Reviewed-By: Rob Crittenden <rcritten@redhat.com>
+---
+ install/updates/20-syncrepl.update | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/install/updates/20-syncrepl.update b/install/updates/20-syncrepl.update
+index faa13f645f492ea35824fe57632b56d52afa8a6e..318eda16870afa06d6c6d9098cbffdc085f2dba2 100644
+--- a/install/updates/20-syncrepl.update
++++ b/install/updates/20-syncrepl.update
+@@ -4,7 +4,7 @@ only:nsslapd-pluginEnabled: on
+ # Remember original nsuniqueid for objects referenced from cn=changelog
+ add:nsslapd-attribute: nsuniqueid:targetUniqueId
+ add:nsslapd-changelogmaxage: 2d
+-add:nsslapd-exclude-suffix: o=ipaca
++add:nsslapd-include-suffix: cn=dns,$SUFFIX
+ 
+ # Keep memberOf and referential integrity plugins away from cn=changelog.
+ # It is necessary for performance reasons because we don't have appropriate
+-- 
+2.9.5
+
diff --git a/SOURCES/0005-Fix-ipa-replica-conncheck-when-called-with-principal.patch b/SOURCES/0005-Fix-ipa-replica-conncheck-when-called-with-principal.patch
new file mode 100644
index 0000000..f3f0bd7
--- /dev/null
+++ b/SOURCES/0005-Fix-ipa-replica-conncheck-when-called-with-principal.patch
@@ -0,0 +1,45 @@
+From 20f2650a8a23d288571fde552ed1c242cd972d88 Mon Sep 17 00:00:00 2001
+From: Florence Blanc-Renaud <flo@redhat.com>
+Date: Fri, 27 Oct 2017 09:05:20 +0200
+Subject: [PATCH] Fix ipa-replica-conncheck when called with --principal
+
+ipa-replica-conncheck can be called with --principal / --password or
+with an existing Kerberos credential cache in order to supply the
+authorized identity logging in to the master machine (in
+auto-master-check mode).
+
+In domain-level 0, the tool is called with --principal and password
+and tries to obtain a TGT by performing kinit, but does not set the
+env var KRB5CCNAME. Subsequent calls to IPA API do not use the
+credential cache and fail. In this case, ipa-replica-conncheck falls
+back to using SSH to check master connectivity instead of IPA API,
+and the ssh check is less robust.
+
+The code should set the KRB5CCNAME env var for IPA API to use the
+credential cache.
+
+Fixes:
+https://pagure.io/freeipa/issue/7221
+
+Reviewed-By: Rob Crittenden <rcritten@redhat.com>
+---
+ install/tools/ipa-replica-conncheck | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/install/tools/ipa-replica-conncheck b/install/tools/ipa-replica-conncheck
+index 03281d1c7b6ee9f1d4cabebceb0c7e64b09601c0..545cdf00ca74289e6532a40de4c9abad5af4cee0 100755
+--- a/install/tools/ipa-replica-conncheck
++++ b/install/tools/ipa-replica-conncheck
+@@ -534,6 +534,9 @@ def main():
+                 if result.returncode != 0:
+                     raise RuntimeError("Could not get ticket for master server: %s" %
+                                         result.error_output)
++                # Now that the cred cache file is initialized,
++                # use it for the IPA API calls
++                os.environ['KRB5CCNAME'] = CCACHE_FILE
+ 
+             try:
+                 root_logger.info("Check RPC connection to remote master")
+-- 
+2.9.5
+
diff --git a/SOURCES/0005-ipapython.ipautil.nolog_replace-Do-not-replace-empty.patch b/SOURCES/0005-ipapython.ipautil.nolog_replace-Do-not-replace-empty.patch
deleted file mode 100644
index 188c635..0000000
--- a/SOURCES/0005-ipapython.ipautil.nolog_replace-Do-not-replace-empty.patch
+++ /dev/null
@@ -1,32 +0,0 @@
-From fef78a011c148f63a08014bbe7ed2d63fe3380bd Mon Sep 17 00:00:00 2001
-From: David Kupka <dkupka@redhat.com>
-Date: Mon, 20 Mar 2017 12:48:14 +0100
-Subject: [PATCH] ipapython.ipautil.nolog_replace: Do not replace empty value
-
-When provided empty value in nolog parameter nolog_replace added 'XXXXXXXX'
-three (once for plain value, once for http quoted value and last time for shell
-quoted value) times before every character (including terminating '\0') in the string.
-
-https://pagure.io/freeipa/issue/6738
-
-Reviewed-By: Pavel Vomacka <pvomacka@redhat.com>
----
- ipapython/ipautil.py | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/ipapython/ipautil.py b/ipapython/ipautil.py
-index 60b4a37fe247624e826d0f6516cb9a25d30ae75d..cd66328e6c9a0f69e6f83582a9d288ac239c5be3 100644
---- a/ipapython/ipautil.py
-+++ b/ipapython/ipautil.py
-@@ -505,7 +505,7 @@ def run(args, stdin=None, raiseonerr=True, nolog=(), env=None,
- def nolog_replace(string, nolog):
-     """Replace occurences of strings given in `nolog` with XXXXXXXX"""
-     for value in nolog:
--        if not isinstance(value, six.string_types):
-+        if not value or not isinstance(value, six.string_types):
-             continue
- 
-         quoted = urllib.parse.quote(value)
--- 
-2.12.1
-
diff --git a/SOURCES/0006-Include-the-CA-basic-constraint-in-CSRs-when-renewin.patch b/SOURCES/0006-Include-the-CA-basic-constraint-in-CSRs-when-renewin.patch
new file mode 100644
index 0000000..794cb5f
--- /dev/null
+++ b/SOURCES/0006-Include-the-CA-basic-constraint-in-CSRs-when-renewin.patch
@@ -0,0 +1,75 @@
+From 148e78d74206730c31dd7bc87eece5c5bd1440ac Mon Sep 17 00:00:00 2001
+From: Rob Crittenden <rcritten@redhat.com>
+Date: Wed, 9 Aug 2017 17:28:35 -0400
+Subject: [PATCH] Include the CA basic constraint in CSRs when renewing a CA
+
+The CSR generated by `ipa-cacert-manage renew --external-ca` did
+not include the CA basic constraint:
+
+  X509v3 Basic Constraints: critical
+      CA:TRUE
+
+Add a flag to certmonger::resubmit_request to specify that a
+CA is being requested.
+
+Note that this also sets pathlen to -1 which means an unlimited
+pathlen. Leave it up to the issuing CA to set this.
+
+https://pagure.io/freeipa/issue/7088
+
+Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
+Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
+---
+ ipalib/install/certmonger.py           | 13 +++++++++++--
+ ipaserver/install/ipa_cacert_manage.py |  3 ++-
+ 2 files changed, 13 insertions(+), 3 deletions(-)
+
+diff --git a/ipalib/install/certmonger.py b/ipalib/install/certmonger.py
+index c286996ee2318e241b4af190d1a01f42e28aa9f3..d2b782ddb0c746a3dfd96d0222bb31c6a960fdff 100644
+--- a/ipalib/install/certmonger.py
++++ b/ipalib/install/certmonger.py
+@@ -519,16 +519,25 @@ def modify(request_id, ca=None, profile=None):
+         request.obj_if.modify(update)
+ 
+ 
+-def resubmit_request(request_id, ca=None, profile=None):
++def resubmit_request(request_id, ca=None, profile=None, is_ca=False):
++    """
++    :param request_id: the certmonger numeric request ID
++    :param ca: the nickname for the certmonger CA, e.g. IPA or SelfSign
++    :param profile: the dogtag template profile to use, e.g. SubCA
++    :param is_ca: boolean that if True adds the CA basic constraint
++    """
+     request = _get_request({'nickname': request_id})
+     if request:
+-        if ca or profile:
++        if ca or profile or is_ca:
+             update = {}
+             if ca is not None:
+                 cm = _certmonger()
+                 update['CA'] = cm.obj_if.find_ca_by_nickname(ca)
+             if profile is not None:
+                 update['template-profile'] = profile
++            if is_ca:
++                update['template-is-ca'] = True
++                update['template-ca-path-length'] = -1  # no path length
+             request.obj_if.modify(update)
+         request.obj_if.resubmit()
+ 
+diff --git a/ipaserver/install/ipa_cacert_manage.py b/ipaserver/install/ipa_cacert_manage.py
+index fcbf09155a3abc9ce9481aa2519ed39aaa6aa9bb..9607620d6c3e63b70b9e586f94282bf478c8c53e 100644
+--- a/ipaserver/install/ipa_cacert_manage.py
++++ b/ipaserver/install/ipa_cacert_manage.py
+@@ -310,7 +310,8 @@ class CACertManage(admintool.AdminTool):
+         timeout = api.env.startup_timeout + 60
+ 
+         self.log.debug("resubmitting certmonger request '%s'", self.request_id)
+-        certmonger.resubmit_request(self.request_id, ca=ca, profile=profile)
++        certmonger.resubmit_request(self.request_id, ca=ca, profile=profile,
++                                    is_ca=True)
+         try:
+             state = certmonger.wait_for_request(self.request_id, timeout)
+         except RuntimeError:
+-- 
+2.9.5
+
diff --git a/SOURCES/0006-tasks-run-systemctl-daemon-reload-after-httpd.servic.patch b/SOURCES/0006-tasks-run-systemctl-daemon-reload-after-httpd.servic.patch
deleted file mode 100644
index 15450ff..0000000
--- a/SOURCES/0006-tasks-run-systemctl-daemon-reload-after-httpd.servic.patch
+++ /dev/null
@@ -1,49 +0,0 @@
-From d8a9ed4e2fc164962d76773b57277f97bca84270 Mon Sep 17 00:00:00 2001
-From: Jan Cholasta <jcholast@redhat.com>
-Date: Thu, 16 Mar 2017 12:51:29 +0000
-Subject: [PATCH] tasks: run `systemctl daemon-reload` after httpd.service.d
- updates
-
-Run `systemctl daemon-reload` after
-`/etc/systemd/system/httpd.service.d/ipa.conf` is created or deleted,
-otherwise systemd will not merge the file into httpd.service and therefore
-required environment variables will not be set for httpd.
-
-This fixes authentication failures ("No valid Negotiate header in server
-response") due to missing `GSS_USE_PROXY=yes` in httpd environment.
-
-https://pagure.io/freeipa/issue/6773
-
-Reviewed-By: Martin Babinsky <mbabinsk@redhat.com>
----
- ipaplatform/redhat/tasks.py | 7 +++++++
- 1 file changed, 7 insertions(+)
-
-diff --git a/ipaplatform/redhat/tasks.py b/ipaplatform/redhat/tasks.py
-index c1b574e06fc52839b684cbe96587365fa107b2eb..d0ef5fbd1ceb8110dd417dda44a74dc63898456a 100644
---- a/ipaplatform/redhat/tasks.py
-+++ b/ipaplatform/redhat/tasks.py
-@@ -483,6 +483,9 @@ class RedHatTaskNamespace(BaseTaskNamespace):
-         os.chmod(paths.SYSTEMD_SYSTEM_HTTPD_IPA_CONF, 0o644)
-         self.restore_context(paths.SYSTEMD_SYSTEM_HTTPD_IPA_CONF)
- 
-+        ipautil.run([paths.SYSTEMCTL, "--system", "daemon-reload"],
-+                    raiseonerr=False)
-+
-     def configure_http_gssproxy_conf(self):
-         ipautil.copy_template_file(
-             os.path.join(paths.USR_SHARE_IPA_DIR, 'gssproxy.conf.template'),
-@@ -513,6 +516,10 @@ class RedHatTaskNamespace(BaseTaskNamespace):
-                     'Error removing %s: %s',
-                     paths.SYSTEMD_SYSTEM_HTTPD_IPA_CONF, e
-                 )
-+            return
-+
-+        ipautil.run([paths.SYSTEMCTL, "--system", "daemon-reload"],
-+                    raiseonerr=False)
- 
-     def set_hostname(self, hostname):
-         ipautil.run([paths.BIN_HOSTNAMECTL, 'set-hostname', hostname])
--- 
-2.12.1
-
diff --git a/SOURCES/0007-ipa-extdom-extop-refactor-nsswitch-operations.patch b/SOURCES/0007-ipa-extdom-extop-refactor-nsswitch-operations.patch
new file mode 100644
index 0000000..b98db3e
--- /dev/null
+++ b/SOURCES/0007-ipa-extdom-extop-refactor-nsswitch-operations.patch
@@ -0,0 +1,1728 @@
+From 8a80363e07b5c9309d785bf3b41f506f32a750a5 Mon Sep 17 00:00:00 2001
+From: Alexander Bokovoy <abokovoy@redhat.com>
+Date: Tue, 14 Nov 2017 12:44:02 +0200
+Subject: [PATCH] ipa-extdom-extop: refactor nsswitch operations
+
+Refactor nsswitch operations in ipa-extdom-extop plugin to allow use
+of timeout-enabled nsswitch calls provided by libsss_nss_idmap.
+
+Standard POSIX nsswitch API has no way to cancel requests which may
+cause ipa-extdom-extop requests to hang far too long and potentially
+exhaust LDAP server workers. In addition, glibc nsswitch API iterates
+through all nsswitch modules one by one and with multiple parallel
+requests a lock up may happen in an unrelated nsswitch module like
+nss_files.so.2.
+
+A solution to the latter issue is to directly load nss_sss.so.2 plugin
+and utilize it. This, however, does not solve a problem with lack of
+cancellable API.
+
+With SSSD 1.16.1, libsss_nss_idmap provides a timeout-enabled variant of
+nsswitch API that is directly integrated with SSSD client side machinery
+used by nss_sss.so.2. As result, this API can be used instead of loading
+nss_sss.so.2 directly.
+
+To support older SSSD version, both direct loading of nss_sss.so.2 and
+new timeout-enabled API are supported by this changeset. An API to
+abstract both is designed to be a mix between internal glibc nsswitch
+API and external nsswitch API that libsss_nss_idmap mimics. API does not
+expose per-call timeout. Instead, it allows to set a timeout per
+nsswitch operation context to reduce requirements on information
+a caller has to maintain.
+
+A choice which API to use is made at configure time.
+
+In order to test the API, a cmocka test is updated to explicitly load
+nss_files.so.2 as a backend. Since use of nss_sss.so.2 would always
+depend on availablility of SSSD, predictable testing would not be
+possible without it otherwise. Also, cmocka test does not use
+nss_wrapper anymore because nss_wrapper overrides higher level glibc
+nsswitch API while we are loading an individual nsswitch module
+directly.
+
+As result, cmocka test overrides fopen() call used by nss_files.so.2 to
+load /etc/passwd and /etc/group. An overridden version changes paths to
+/etc/passwd and /etc/group to a local test_data/passwd and
+test_data/group. This way we can continue testing a backend API for
+ipa-extdom-extop with the same data as with nss_wrapper.
+
+Fixes https://pagure.io/freeipa/issue/5464
+
+Reviewed-By: Christian Heimes <cheimes@redhat.com>
+Reviewed-By: Simo Sorce <ssorce@redhat.com>
+Reviewed-By: Robbie Harwood <rharwood@redhat.com>
+---
+ configure.ac                                       |  25 +-
+ .../ipa-slapi-plugins/ipa-extdom-extop/Makefile.am |  17 +-
+ .../ipa-extdom-extop/back_extdom.h                 |  79 ++++++
+ .../ipa-extdom-extop/back_extdom_nss_sss.c         | 276 +++++++++++++++++++++
+ .../ipa-extdom-extop/back_extdom_sss_idmap.c       | 260 +++++++++++++++++++
+ .../ipa-extdom-extop/ipa_extdom.h                  |  13 +-
+ .../ipa-extdom-extop/ipa_extdom_cmocka_tests.c     | 241 +++++++++++++++---
+ .../ipa-extdom-extop/ipa_extdom_common.c           | 242 +++++++++---------
+ .../ipa-extdom-extop/ipa_extdom_extop.c            |  17 ++
+ .../ipa-extdom-extop/test_data/test_setup.sh       |   3 -
+ freeipa.spec.in                                    |   1 -
+ server.m4                                          |  10 +
+ 12 files changed, 994 insertions(+), 190 deletions(-)
+ create mode 100644 daemons/ipa-slapi-plugins/ipa-extdom-extop/back_extdom.h
+ create mode 100644 daemons/ipa-slapi-plugins/ipa-extdom-extop/back_extdom_nss_sss.c
+ create mode 100644 daemons/ipa-slapi-plugins/ipa-extdom-extop/back_extdom_sss_idmap.c
+ delete mode 100644 daemons/ipa-slapi-plugins/ipa-extdom-extop/test_data/test_setup.sh
+
+diff --git a/configure.ac b/configure.ac
+index e7a8b11153209fdfb4903cd3876e21a871a92f03..8a99b028886790aca211ddf164772920221f3ec7 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -140,30 +140,6 @@ PKG_CHECK_EXISTS(cmocka,
+ )
+ AM_CONDITIONAL([HAVE_CMOCKA], [test x$have_cmocka = xyes])
+ 
+-dnl A macro to check presence of a cwrap (http://cwrap.org) wrapper on the system
+-dnl Usage:
+-dnl     AM_CHECK_WRAPPER(name, conditional)
+-dnl If the cwrap library is found, sets the HAVE_$name conditional
+-AC_DEFUN([AM_CHECK_WRAPPER],
+-[
+-    FOUND_WRAPPER=0
+-
+-    AC_MSG_CHECKING([for $1])
+-    PKG_CHECK_EXISTS([$1],
+-                     [
+-                        AC_MSG_RESULT([yes])
+-                        FOUND_WRAPPER=1
+-                     ],
+-                     [
+-                        AC_MSG_RESULT([no])
+-                        AC_MSG_WARN([cwrap library $1 not found, some tests will not run])
+-                     ])
+-
+-    AM_CONDITIONAL($2, [ test x$FOUND_WRAPPER = x1])
+-])
+-
+-AM_CHECK_WRAPPER(nss_wrapper, HAVE_NSS_WRAPPER)
+-
+ dnl ---------------------------------------------------------------------------
+ dnl - Check for POPT
+ dnl ---------------------------------------------------------------------------
+@@ -235,6 +211,7 @@ dnl ---------------------------------------------------------------------------
+ AM_COND_IF([ENABLE_SERVER], [
+     m4_include(server.m4)
+ ])
++AM_CONDITIONAL([USE_SSS_NSS_TIMEOUT], [test "x$ac_cv_have_decl_sss_nss_getpwnam_timeout" = xyes])
+ 
+ dnl ---------------------------------------------------------------------------
+ dnl - Check if IPA certauth plugin can be build
+diff --git a/daemons/ipa-slapi-plugins/ipa-extdom-extop/Makefile.am b/daemons/ipa-slapi-plugins/ipa-extdom-extop/Makefile.am
+index 1213965c96607bf14c6c92ce592585aed1a125db..cbdd570eabeb12b95fdc26213a64749f9ba9fdde 100644
+--- a/daemons/ipa-slapi-plugins/ipa-extdom-extop/Makefile.am
++++ b/daemons/ipa-slapi-plugins/ipa-extdom-extop/Makefile.am
+@@ -25,6 +25,7 @@ libipa_extdom_extop_la_SOURCES = 	\
+ 	ipa_extdom.h			\
+ 	ipa_extdom_extop.c		\
+ 	ipa_extdom_common.c		\
++	back_extdom.h			\
+ 	$(NULL)
+ 
+ libipa_extdom_extop_la_LDFLAGS = -avoid-version
+@@ -34,20 +35,29 @@ libipa_extdom_extop_la_LIBADD = 	\
+ 	$(SSSNSSIDMAP_LIBS)		\
+ 	$(NULL)
+ 
++# We have two backends for nss operations:
++# (1) directly loading nss_sss.so.2
++# (2) using timeout-enabled API from libsss_nss_idmap
++# We prefer (2) if available
++if USE_SSS_NSS_TIMEOUT
++libipa_extdom_extop_la_SOURCES += back_extdom_sss_idmap.c
++else
++libipa_extdom_extop_la_SOURCES += back_extdom_nss_sss.c
++endif
++
++
+ TESTS =
+ check_PROGRAMS =
+ 
+ if HAVE_CMOCKA
+-if HAVE_NSS_WRAPPER
+-TESTS_ENVIRONMENT = . ./test_data/test_setup.sh;
+ TESTS += extdom_cmocka_tests
+ check_PROGRAMS += extdom_cmocka_tests
+ endif
+-endif
+ 
+ extdom_cmocka_tests_SOURCES = 		\
+ 	ipa_extdom_cmocka_tests.c	\
+ 	ipa_extdom_common.c		\
++	back_extdom_nss_sss.c		\
+ 	$(NULL)
+ extdom_cmocka_tests_CFLAGS = $(CMOCKA_CFLAGS)
+ extdom_cmocka_tests_LDFLAGS = 	\
+@@ -58,6 +68,7 @@ extdom_cmocka_tests_LDADD = 	\
+ 	$(LDAP_LIBS)		\
+ 	$(DIRSRV_LIBS)		\
+ 	$(SSSNSSIDMAP_LIBS)	\
++	-ldl			\
+ 	$(NULL)
+ 
+ 
+diff --git a/daemons/ipa-slapi-plugins/ipa-extdom-extop/back_extdom.h b/daemons/ipa-slapi-plugins/ipa-extdom-extop/back_extdom.h
+new file mode 100644
+index 0000000000000000000000000000000000000000..d2937c8c8ecf8b960b5b31e9449c719bfda86de4
+--- /dev/null
++++ b/daemons/ipa-slapi-plugins/ipa-extdom-extop/back_extdom.h
+@@ -0,0 +1,79 @@
++/*
++ * Copyright 2017 Red Hat, Inc.
++ *
++ * This Program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; version 2 of the License.
++ *
++ * This Program is distributed in the hope that it will be useful, but
++ * WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this Program; if not, write to the
++ *
++ *   Free Software Foundation, Inc.
++ *   59 Temple Place, Suite 330
++ *   Boston, MA 02111-1307 USA
++ *
++ */
++
++#ifndef BACK_EXTDOM_H
++#define BACK_EXTDOM_H
++#include <unistd.h>
++#include <pwd.h>
++#include <grp.h>
++
++/* Possible results of lookup using a nss_* function.
++ * Note: don't include nss.h as its path gets overriden by NSS library */
++enum nss_status {
++    NSS_STATUS_TRYAGAIN = -2,
++    NSS_STATUS_UNAVAIL,
++    NSS_STATUS_NOTFOUND,
++    NSS_STATUS_SUCCESS,
++    NSS_STATUS_RETURN
++};
++
++/* NSS backend operations implemented using either nss_sss.so.2 or libsss_nss_idmap API */
++struct nss_ops_ctx;
++
++int back_extdom_init_context(struct nss_ops_ctx **nss_context);
++void back_extdom_free_context(struct nss_ops_ctx **nss_context);
++void back_extdom_set_timeout(struct nss_ops_ctx *nss_context,
++                             unsigned int timeout);
++void back_extdom_evict_user(struct nss_ops_ctx *nss_context,
++                            const char *name);
++void back_extdom_evict_group(struct nss_ops_ctx *nss_context,
++                             const char *name);
++
++enum nss_status back_extdom_getpwnam(struct nss_ops_ctx *nss_context,
++                                     const char *name, struct passwd *pwd,
++                                     char *buffer, size_t buflen,
++                                     struct passwd **result,
++                                     int *lerrno);
++
++enum nss_status back_extdom_getpwuid(struct nss_ops_ctx *nss_context,
++                                     uid_t uid, struct passwd *pwd,
++                                     char *buffer, size_t buflen,
++                                     struct passwd **result,
++                                     int *lerrno);
++
++enum nss_status back_extdom_getgrnam(struct nss_ops_ctx *nss_context,
++                                     const char *name, struct group *grp,
++                                     char *buffer, size_t buflen,
++                                     struct group **result,
++                                     int *lerrno);
++
++enum nss_status back_extdom_getgrgid(struct nss_ops_ctx *nss_context,
++                                     gid_t gid, struct group *grp,
++                                     char *buffer, size_t buflen,
++                                     struct group **result,
++                                     int *lerrno);
++
++enum nss_status back_extdom_getgrouplist(struct nss_ops_ctx *nss_context,
++                                         const char *name, gid_t group,
++                                         gid_t *groups, int *ngroups,
++                                         int *lerrno);
++
++#endif /* BACK_EXTDOM_H */
+diff --git a/daemons/ipa-slapi-plugins/ipa-extdom-extop/back_extdom_nss_sss.c b/daemons/ipa-slapi-plugins/ipa-extdom-extop/back_extdom_nss_sss.c
+new file mode 100644
+index 0000000000000000000000000000000000000000..346c7d4301a607c7bc07ca5a9c53fe84618ac8ad
+--- /dev/null
++++ b/daemons/ipa-slapi-plugins/ipa-extdom-extop/back_extdom_nss_sss.c
+@@ -0,0 +1,276 @@
++/*
++ * Copyright 2013-2017 Red Hat, Inc.
++ *
++ * This Program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; version 2 of the License.
++ *
++ * This Program is distributed in the hope that it will be useful, but
++ * WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this Program; if not, write to the
++ *
++ *   Free Software Foundation, Inc.
++ *   59 Temple Place, Suite 330
++ *   Boston, MA 02111-1307 USA
++ *
++ */
++
++#ifdef HAVE_CONFIG_H
++#include "config.h"
++#endif
++
++#include <sys/types.h>
++#include <stdlib.h>
++#include <string.h>
++#include <time.h>
++#include <unistd.h>
++#include <dlfcn.h>
++#include <errno.h>
++#include <pwd.h>
++#include <grp.h>
++#include <sys/param.h>
++#include "back_extdom.h"
++
++struct nss_ops_ctx {
++    void *dl_handle;
++    long int initgroups_start;
++
++    enum nss_status (*getpwnam_r)(const char *name, struct passwd *result,
++                                  char *buffer, size_t buflen, int *errnop);
++    enum nss_status (*getpwuid_r)(uid_t uid, struct passwd *result,
++                                  char *buffer, size_t buflen, int *errnop);
++    enum nss_status (*getgrnam_r)(const char *name, struct group *result,
++                                  char *buffer, size_t buflen, int *errnop);
++    enum nss_status (*getgrgid_r)(gid_t gid, struct group *result,
++                                  char *buffer, size_t buflen, int *errnop);
++    enum nss_status (*initgroups_dyn)(const char *user, gid_t group,
++                                      long int *start, long int *size,
++                                      gid_t **groups, long int limit,
++                                      int *errnop);
++};
++
++void back_extdom_free_context(struct nss_ops_ctx **nss_context)
++{
++    if ((nss_context == NULL) || (*nss_context == NULL)) {
++        return;
++    }
++
++    if ((*nss_context)->dl_handle != NULL) {
++        dlclose((*nss_context)->dl_handle);
++    }
++
++    free((*nss_context));
++    *nss_context = NULL;
++}
++
++int back_extdom_init_context(struct nss_ops_ctx **nss_context)
++{
++    struct nss_ops_ctx *ctx = NULL;
++
++    if (nss_context == NULL) {
++        return EINVAL;
++    }
++
++    ctx = calloc(1, sizeof(struct nss_ops_ctx));
++    if (ctx == NULL) {
++        return ENOMEM;
++    }
++    *nss_context = ctx;
++
++    ctx->dl_handle = dlopen("libnss_sss.so.2", RTLD_NOW);
++    if (ctx->dl_handle == NULL) {
++        goto fail;
++    }
++
++    ctx->getpwnam_r = dlsym(ctx->dl_handle, "_nss_sss_getpwnam_r");
++    if (ctx->getpwnam_r == NULL) {
++        goto fail;
++    }
++
++    ctx->getpwuid_r = dlsym(ctx->dl_handle, "_nss_sss_getpwuid_r");
++    if (ctx->getpwuid_r == NULL) {
++        goto fail;
++    }
++
++    ctx->getgrnam_r = dlsym(ctx->dl_handle, "_nss_sss_getgrnam_r");
++    if (ctx->getgrnam_r == NULL) {
++        goto fail;
++    }
++
++    ctx->getgrgid_r = dlsym(ctx->dl_handle, "_nss_sss_getgrgid_r");
++    if (ctx->getgrgid_r == NULL) {
++        goto fail;
++    }
++
++    ctx->initgroups_dyn = dlsym(ctx->dl_handle, "_nss_sss_initgroups_dyn");
++    if (ctx->initgroups_dyn == NULL) {
++        goto fail;
++    }
++
++    return 0;
++
++fail:
++    back_extdom_free_context(nss_context);
++
++    return EINVAL;
++}
++
++
++/* Following three functions cannot be implemented with nss_sss.so.2
++ * As result, we simply do nothing here */
++
++void back_extdom_set_timeout(struct nss_ops_ctx *nss_context,
++                             unsigned int timeout) {
++        /* no operation */
++}
++
++void back_extdom_evict_user(struct nss_ops_ctx *nss_context,
++                            const char *name) {
++        /* no operation */
++}
++
++void back_extdom_evict_group(struct nss_ops_ctx *nss_context,
++                             const char *name) {
++        /* no operation */
++}
++
++enum nss_status back_extdom_getpwnam(struct nss_ops_ctx *nss_context,
++                                     const char *name, struct passwd *pwd,
++                                     char *buffer, size_t buflen,
++                                     struct passwd **result,
++                                     int *lerrno) {
++    enum nss_status ret;
++
++    if (nss_context == NULL) {
++        return NSS_STATUS_UNAVAIL;
++    }
++
++    ret = nss_context->getpwnam_r(name, pwd,
++                                  buffer, buflen,
++                                  lerrno);
++
++    if ((ret == NSS_STATUS_SUCCESS) && (result != NULL)) {
++        *result = pwd;
++        *lerrno = 0;
++    }
++
++    return ret;
++}
++
++enum nss_status back_extdom_getpwuid(struct nss_ops_ctx *nss_context,
++                                     uid_t uid, struct passwd *pwd,
++                                     char *buffer, size_t buflen,
++                                     struct passwd **result,
++                                     int *lerrno) {
++    enum nss_status ret;
++
++    if (nss_context == NULL) {
++        return NSS_STATUS_UNAVAIL;
++    }
++
++    ret = nss_context->getpwuid_r(uid, pwd,
++                                  buffer, buflen,
++                                  lerrno);
++
++    if ((ret == NSS_STATUS_SUCCESS) && (result != NULL)) {
++        *result = pwd;
++        *lerrno = 0;
++    }
++
++    return ret;
++}
++
++enum nss_status back_extdom_getgrnam(struct nss_ops_ctx *nss_context,
++                                     const char *name, struct group *grp,
++                                     char *buffer, size_t buflen,
++                                     struct group **result,
++                                     int *lerrno) {
++    enum nss_status ret;
++
++    if (nss_context == NULL) {
++        return NSS_STATUS_UNAVAIL;
++    }
++
++    ret = nss_context->getgrnam_r(name, grp,
++                                  buffer, buflen,
++                                  lerrno);
++
++    if ((ret == NSS_STATUS_SUCCESS) && (result != NULL)) {
++        *result = grp;
++        *lerrno = 0;
++    }
++
++    return ret;
++}
++
++enum nss_status back_extdom_getgrgid(struct nss_ops_ctx *nss_context,
++                                     gid_t gid, struct group *grp,
++                                     char *buffer, size_t buflen,
++                                     struct group **result,
++                                     int *lerrno) {
++
++    enum nss_status ret;
++
++    if (nss_context == NULL) {
++        return NSS_STATUS_UNAVAIL;
++    }
++
++    ret = nss_context->getgrgid_r(gid, grp,
++                                  buffer, buflen,
++                                  lerrno);
++
++    if ((ret == NSS_STATUS_SUCCESS) && (result != NULL)) {
++        *result = grp;
++        *lerrno = 0;
++    }
++
++    return ret;
++}
++
++enum nss_status back_extdom_getgrouplist(struct nss_ops_ctx *nss_context,
++                                         const char *name, gid_t group,
++                                         gid_t *groups, int *ngroups,
++                                         int *lerrno) {
++
++    enum nss_status ret = NSS_STATUS_UNAVAIL;
++    long int tsize = MAX (1, *ngroups);
++    gid_t *newgroups = NULL;
++
++    if (nss_context == NULL) {
++        return NSS_STATUS_UNAVAIL;
++    }
++
++    newgroups = (gid_t *) calloc (tsize, sizeof (gid_t));
++    if (newgroups == NULL) {
++        *lerrno = ENOMEM;
++        return NSS_STATUS_TRYAGAIN;
++    }
++
++    newgroups[0] = group;
++    nss_context->initgroups_start = 1;
++
++    ret = nss_context->initgroups_dyn(name, group,
++                                      &nss_context->initgroups_start,
++                                      &tsize, &newgroups,
++                                      -1, lerrno);
++
++    (void) memcpy(groups, newgroups,
++                  MIN(*ngroups, nss_context->initgroups_start) * sizeof(gid_t));
++    free(newgroups);
++
++    if (*ngroups < nss_context->initgroups_start) {
++        ret = NSS_STATUS_TRYAGAIN;
++        *lerrno = ERANGE;
++    }
++
++    *ngroups = (int) nss_context->initgroups_start;
++
++    nss_context->initgroups_start = 0;
++
++    return ret;
++}
++
+diff --git a/daemons/ipa-slapi-plugins/ipa-extdom-extop/back_extdom_sss_idmap.c b/daemons/ipa-slapi-plugins/ipa-extdom-extop/back_extdom_sss_idmap.c
+new file mode 100644
+index 0000000000000000000000000000000000000000..89c58ca2de333b26954d916836b57aed5d7e18fb
+--- /dev/null
++++ b/daemons/ipa-slapi-plugins/ipa-extdom-extop/back_extdom_sss_idmap.c
+@@ -0,0 +1,260 @@
++/*
++ * Copyright 2013-2017 Red Hat, Inc.
++ *
++ * This Program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; version 2 of the License.
++ *
++ * This Program is distributed in the hope that it will be useful, but
++ * WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this Program; if not, write to the
++ *
++ *   Free Software Foundation, Inc.
++ *   59 Temple Place, Suite 330
++ *   Boston, MA 02111-1307 USA
++ *
++ */
++
++#ifdef HAVE_CONFIG_H
++#include "config.h"
++#endif
++
++#include <sys/types.h>
++#include <stdlib.h>
++#include <string.h>
++#include <time.h>
++#include <unistd.h>
++#include <errno.h>
++#include <pwd.h>
++#include <grp.h>
++#include "back_extdom.h"
++
++/* SSSD only exposes *_timeout() variants if the following symbol is defined */
++#define IPA_389DS_PLUGIN_HELPER_CALLS
++#include <sss_nss_idmap.h>
++
++struct nss_ops_ctx {
++    unsigned int timeout;
++};
++
++static enum nss_status __convert_sss_nss2nss_status(int errcode) {
++    switch(errcode) {
++    case 0:
++        return NSS_STATUS_SUCCESS;
++    case ENOENT:
++        return NSS_STATUS_NOTFOUND;
++    case ETIME:
++        /* fall-through */
++    case ERANGE:
++        return NSS_STATUS_TRYAGAIN;
++    case ETIMEDOUT:
++        /* fall-through */
++    default:
++        return NSS_STATUS_UNAVAIL;
++    }
++    return NSS_STATUS_UNAVAIL;
++}
++
++int back_extdom_init_context(struct nss_ops_ctx **nss_context)
++{
++    struct nss_ops_ctx *ctx = NULL;
++
++    if (nss_context == NULL) {
++        return EINVAL;
++    }
++
++    ctx = calloc(1, sizeof(struct nss_ops_ctx));
++
++    if (ctx == NULL) {
++        return ENOMEM;
++    }
++    *nss_context = ctx;
++    return 0;
++}
++
++void back_extdom_free_context(struct nss_ops_ctx **nss_context)
++{
++    if ((nss_context == NULL) || (*nss_context == NULL)) {
++        return;
++    }
++
++    free((*nss_context));
++    *nss_context = NULL;
++}
++
++
++void back_extdom_set_timeout(struct nss_ops_ctx *nss_context,
++                             unsigned int timeout) {
++    if (nss_context == NULL) {
++        return;
++    }
++
++    nss_context->timeout = timeout;
++}
++
++void back_extdom_evict_user(struct nss_ops_ctx *nss_context,
++                            const char *name) {
++    if (nss_context == NULL) {
++        return;
++    }
++
++    (void) sss_nss_getpwnam_timeout(name, NULL,
++                                    NULL, 0,
++                                    NULL,
++                                    SSS_NSS_EX_FLAG_INVALIDATE_CACHE,
++                                    nss_context->timeout);
++}
++
++void back_extdom_evict_group(struct nss_ops_ctx *nss_context,
++                             const char *name) {
++    if (nss_context == NULL) {
++            return;
++    }
++
++    (void) sss_nss_getgrnam_timeout(name, NULL,
++                                    NULL, 0,
++                                    NULL,
++                                    SSS_NSS_EX_FLAG_INVALIDATE_CACHE,
++                                    nss_context->timeout);
++}
++
++enum nss_status back_extdom_getpwnam(struct nss_ops_ctx *nss_context,
++                                     const char *name, struct passwd *pwd,
++                                     char *buffer, size_t buflen,
++                                     struct passwd **result,
++                                     int *lerrno) {
++    int ret = 0;
++
++    if (nss_context == NULL) {
++        return NSS_STATUS_UNAVAIL;
++    }
++
++    ret = sss_nss_getpwnam_timeout(name, pwd,
++                                   buffer, buflen,
++                                   result,
++                                   SSS_NSS_EX_FLAG_NO_FLAGS,
++                                   nss_context->timeout);
++
++    /* SSSD uses the same infrastructure to handle sss_nss_get* calls
++     * as nss_sss.so.2 module where 'int *errno' is passed to the helper
++     * but writes down errno into return code so we propagate it in case
++     * of error and translate the return code */
++    if (lerrno != NULL) {
++        *lerrno = ret;
++    }
++    return __convert_sss_nss2nss_status(ret);
++}
++
++enum nss_status back_extdom_getpwuid(struct nss_ops_ctx *nss_context,
++                                     uid_t uid, struct passwd *pwd,
++                                     char *buffer, size_t buflen,
++                                     struct passwd **result,
++                                     int *lerrno) {
++
++    int ret = 0;
++
++    if (nss_context == NULL) {
++        return NSS_STATUS_UNAVAIL;
++    }
++
++    ret = sss_nss_getpwuid_timeout(uid, pwd,
++                                   buffer, buflen,
++                                   result,
++                                   SSS_NSS_EX_FLAG_NO_FLAGS,
++                                   nss_context->timeout);
++
++    /* SSSD uses the same infrastructure to handle sss_nss_get* calls
++     * as nss_sss.so.2 module where 'int *errno' is passed to the helper
++     * but writes down errno into return code so we propagate it in case
++     * of error and translate the return code */
++    if (lerrno != NULL) {
++        *lerrno = ret;
++    }
++    return __convert_sss_nss2nss_status(ret);
++}
++
++enum nss_status back_extdom_getgrnam(struct nss_ops_ctx *nss_context,
++                                     const char *name, struct group *grp,
++                                     char *buffer, size_t buflen,
++                                     struct group **result,
++                                     int *lerrno) {
++
++    int ret = 0;
++
++    if (nss_context == NULL) {
++        return NSS_STATUS_UNAVAIL;
++    }
++
++    ret = sss_nss_getgrnam_timeout(name, grp,
++                                   buffer, buflen,
++                                   result,
++                                   SSS_NSS_EX_FLAG_NO_FLAGS,
++                                   nss_context->timeout);
++
++    /* SSSD uses the same infrastructure to handle sss_nss_get* calls
++     * as nss_sss.so.2 module where 'int *errno' is passed to the helper
++     * but writes down errno into return code so we propagate it in case
++     * of error and translate the return code */
++    if (lerrno != NULL) {
++        *lerrno = ret;
++    }
++    return __convert_sss_nss2nss_status(ret);
++}
++
++enum nss_status back_extdom_getgrgid(struct nss_ops_ctx *nss_context,
++                                     gid_t gid, struct group *grp,
++                                     char *buffer, size_t buflen,
++                                     struct group **result,
++                                     int *lerrno) {
++
++    int ret = 0;
++
++    if (nss_context == NULL) {
++        return NSS_STATUS_UNAVAIL;
++    }
++
++    ret = sss_nss_getgrgid_timeout(gid, grp,
++                                   buffer, buflen,
++                                   result,
++                                   SSS_NSS_EX_FLAG_NO_FLAGS,
++                                   nss_context->timeout);
++
++    /* SSSD uses the same infrastructure to handle sss_nss_get* calls
++     * as nss_sss.so.2 module where 'int *errno' is passed to the helper
++     * but writes down errno into return code so we propagate it in case
++     * of error and translate the return code */
++    if (lerrno != NULL) {
++        *lerrno = ret;
++    }
++    return __convert_sss_nss2nss_status(ret);
++}
++
++enum nss_status back_extdom_getgrouplist(struct nss_ops_ctx *nss_context,
++                                         const char *name, gid_t group,
++                                         gid_t *groups, int *ngroups,
++                                         int *lerrno) {
++    int ret = 0;
++
++    if (nss_context == NULL) {
++        return NSS_STATUS_UNAVAIL;
++    }
++
++    ret = sss_nss_getgrouplist_timeout(name, group,
++                                       groups, ngroups,
++                                       SSS_NSS_EX_FLAG_NO_FLAGS,
++                                       nss_context->timeout);
++
++    /* SSSD uses the same infrastructure to handle sss_nss_get* calls
++     * as nss_sss.so.2 module where 'int *errno' is passed to the helper
++     * but writes down errno into return code so we propagate it in case
++     * of error and translate the return code */
++    if (lerrno != NULL) {
++        *lerrno = ret;
++    }
++    return __convert_sss_nss2nss_status(ret);
++}
++
+diff --git a/daemons/ipa-slapi-plugins/ipa-extdom-extop/ipa_extdom.h b/daemons/ipa-slapi-plugins/ipa-extdom-extop/ipa_extdom.h
+index bc29f069816b0ce13578c9ae14c61edb832d44e4..bbc574747e8bbe045dfc9882198cb34b0bb8cab9 100644
+--- a/daemons/ipa-slapi-plugins/ipa-extdom-extop/ipa_extdom.h
++++ b/daemons/ipa-slapi-plugins/ipa-extdom-extop/ipa_extdom.h
+@@ -150,10 +150,13 @@ struct extdom_res {
+     } data;
+ };
+ 
++struct nss_ops_ctx;
++
+ struct ipa_extdom_ctx {
+     Slapi_ComponentId *plugin_id;
+     char *base_dn;
+     size_t max_nss_buf_size;
++    struct nss_ops_ctx *nss_ctx;
+ };
+ 
+ struct domain_info {
+@@ -179,15 +182,15 @@ int handle_request(struct ipa_extdom_ctx *ctx, struct extdom_req *req,
+                    struct berval **berval);
+ int pack_response(struct extdom_res *res, struct berval **ret_val);
+ int get_buffer(size_t *_buf_len, char **_buf);
+-int getpwnam_r_wrapper(size_t buf_max, const char *name,
++int getpwnam_r_wrapper(struct ipa_extdom_ctx *ctx, const char *name,
+                        struct passwd *pwd, char **_buf, size_t *_buf_len);
+-int getpwuid_r_wrapper(size_t buf_max, uid_t uid,
++int getpwuid_r_wrapper(struct ipa_extdom_ctx *ctx, uid_t uid,
+                        struct passwd *pwd, char **_buf, size_t *_buf_len);
+-int getgrnam_r_wrapper(size_t buf_max, const char *name,
++int getgrnam_r_wrapper(struct ipa_extdom_ctx *ctx, const char *name,
+                        struct group *grp, char **_buf, size_t *_buf_len);
+-int getgrgid_r_wrapper(size_t buf_max, gid_t gid,
++int getgrgid_r_wrapper(struct ipa_extdom_ctx *ctx, gid_t gid,
+                        struct group *grp, char **_buf, size_t *_buf_len);
+-int get_user_grouplist(const char *name, gid_t gid,
++int get_user_grouplist(struct ipa_extdom_ctx *ctx, const char *name, gid_t gid,
+                        size_t *_ngroups, gid_t **_groups);
+ int pack_ber_sid(const char *sid, struct berval **berval);
+ int pack_ber_name(const char *domain_name, const char *name,
+diff --git a/daemons/ipa-slapi-plugins/ipa-extdom-extop/ipa_extdom_cmocka_tests.c b/daemons/ipa-slapi-plugins/ipa-extdom-extop/ipa_extdom_cmocka_tests.c
+index 526f903d2416e62ee5781909c234bd5ee2d89183..29699cfa390f5469d7c009388b90e68616cbf984 100644
+--- a/daemons/ipa-slapi-plugins/ipa-extdom-extop/ipa_extdom_cmocka_tests.c
++++ b/daemons/ipa-slapi-plugins/ipa-extdom-extop/ipa_extdom_cmocka_tests.c
+@@ -19,6 +19,7 @@
+     You should have received a copy of the GNU General Public License
+     along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
++#define _GNU_SOURCE
+ 
+ #include <errno.h>
+ #include <stdarg.h>
+@@ -31,24 +32,166 @@
+ 
+ 
+ #include "ipa_extdom.h"
++#include "back_extdom.h"
++#include <stdio.h>
++#include <dlfcn.h>
+ 
+ #define MAX_BUF (1024*1024*1024)
++struct test_data {
++    struct extdom_req *req;
++    struct ipa_extdom_ctx *ctx;
++};
++
++/*
++ * redefine logging for mocks
++ */
++#ifdef __GNUC__
++    __attribute__((format(printf, 3, 4)))
++#endif
++int slapi_log_error(int loglevel, char *subsystem, char *fmt, ...)
++{
++    va_list ap;
++    va_start(ap, fmt);
++    vprint_error(fmt, ap);
++    va_end(ap);
++    return 0;
++}
++
++
++/*
++ * We cannot run cmocka tests against SSSD as that would require to set up SSSD
++ * and the rest of environment. Instead, we compile cmocka tests against
++ * back_extdom_nss_sss.c and re-define context initialization to use
++ * nsswrapper with our test data.
++ *
++ * This means we have to keep struct nss_ops_ctx definition in sync with tests!
++ */
++
++struct nss_ops_ctx {
++    void *dl_handle;
++    long int initgroups_start;
++
++    enum nss_status (*getpwnam_r)(const char *name, struct passwd *result,
++                                  char *buffer, size_t buflen, int *errnop);
++    enum nss_status (*getpwuid_r)(uid_t uid, struct passwd *result,
++                                  char *buffer, size_t buflen, int *errnop);
++    enum nss_status (*getgrnam_r)(const char *name, struct group *result,
++                                  char *buffer, size_t buflen, int *errnop);
++    enum nss_status (*getgrgid_r)(gid_t gid, struct group *result,
++                                  char *buffer, size_t buflen, int *errnop);
++    enum nss_status (*initgroups_dyn)(const char *user, gid_t group,
++                                      long int *start, long int *size,
++                                      gid_t **groups, long int limit,
++                                      int *errnop);
++};
++
++int cmocka_extdom_init_context(struct nss_ops_ctx **nss_context)
++{
++    struct nss_ops_ctx *ctx = NULL;
++
++    if (nss_context == NULL) {
++        return -1;
++    }
++
++    ctx = calloc(1, sizeof(struct nss_ops_ctx));
++
++    if (ctx == NULL) {
++        return ENOMEM;
++    }
++    *nss_context = ctx;
++
++    ctx->dl_handle = dlopen("libnss_files.so.2", RTLD_NOW);
++    if (ctx->dl_handle == NULL) {
++        goto fail;
++    }
++
++    ctx->getpwnam_r = dlsym(ctx->dl_handle, "_nss_files_getpwnam_r");
++    if (ctx->getpwnam_r == NULL) {
++        goto fail;
++    }
++
++    ctx->getpwuid_r = dlsym(ctx->dl_handle, "_nss_files_getpwuid_r");
++    if (ctx->getpwuid_r == NULL) {
++        goto fail;
++    }
++
++    ctx->getgrnam_r = dlsym(ctx->dl_handle, "_nss_files_getgrnam_r");
++    if (ctx->getgrnam_r == NULL) {
++        goto fail;
++    }
++
++    ctx->getgrgid_r = dlsym(ctx->dl_handle, "_nss_files_getgrgid_r");
++    if (ctx->getgrgid_r == NULL) {
++        goto fail;
++    }
++
++    ctx->initgroups_dyn = dlsym(ctx->dl_handle, "_nss_files_initgroups_dyn");
++    if (ctx->initgroups_dyn == NULL) {
++        goto fail;
++    }
++
++    return 0;
++
++fail:
++    back_extdom_free_context(nss_context);
++
++    return -1;
++}
++
++struct {
++    const char *o, *n;
++} path_table[] = {
++    { .o = "/etc/passwd", .n = "./test_data/passwd"},
++    { .o = "/etc/group",  .n = "./test_data/group"},
++    { .o = NULL, .n = NULL}};
++
++FILE *(*original_fopen)(const char*, const char*) = NULL;
++
++FILE *fopen(const char *path, const char *mode) {
++    const char *_path = NULL;
++
++    /* Do not handle before-main() cases */
++    if (original_fopen == NULL) {
++        return NULL;
++    }
++    for(int i=0; path_table[i].o != NULL; i++) {
++        if (strcmp(path, path_table[i].o) == 0) {
++                _path = path_table[i].n;
++                break;
++        }
++    }
++    return (*original_fopen)(_path ? _path : path, mode);
++}
++
++/* Attempt to initialize original_fopen before main()
++ * There is no explicit order when all initializers are called,
++ * so we might still be late here compared to a code in a shared
++ * library initializer, like libselinux */
++void redefined_fopen_ctor (void) __attribute__ ((constructor));
++void redefined_fopen_ctor(void) {
++    original_fopen = dlsym(RTLD_NEXT, "fopen");
++}
+ 
+ void test_getpwnam_r_wrapper(void **state)
+ {
+     int ret;
+     struct passwd pwd;
+     char *buf;
+-    size_t buf_len;
++    size_t buf_len, max_big_buf_len;
++    struct test_data *test_data;
++
++    test_data = (struct test_data *) *state;
+ 
+     ret = get_buffer(&buf_len, &buf);
+     assert_int_equal(ret, 0);
+ 
+-    ret = getpwnam_r_wrapper(MAX_BUF, "non_exisiting_user", &pwd, &buf,
+-                             &buf_len);
++    ret = getpwnam_r_wrapper(test_data->ctx,
++                             "non_exisiting_user", &pwd,
++                             &buf, &buf_len);
+     assert_int_equal(ret, ENOENT);
+ 
+-    ret = getpwnam_r_wrapper(MAX_BUF, "user", &pwd, &buf, &buf_len);
++    ret = getpwnam_r_wrapper(test_data->ctx,
++                             "user", &pwd, &buf, &buf_len);
+     assert_int_equal(ret, 0);
+     assert_string_equal(pwd.pw_name, "user");
+     assert_string_equal(pwd.pw_passwd, "x");
+@@ -62,7 +205,8 @@ void test_getpwnam_r_wrapper(void **state)
+     ret = get_buffer(&buf_len, &buf);
+     assert_int_equal(ret, 0);
+ 
+-    ret = getpwnam_r_wrapper(MAX_BUF, "user_big", &pwd, &buf, &buf_len);
++    ret = getpwnam_r_wrapper(test_data->ctx,
++                             "user_big", &pwd, &buf, &buf_len);
+     assert_int_equal(ret, 0);
+     assert_string_equal(pwd.pw_name, "user_big");
+     assert_string_equal(pwd.pw_passwd, "x");
+@@ -76,7 +220,11 @@ void test_getpwnam_r_wrapper(void **state)
+     ret = get_buffer(&buf_len, &buf);
+     assert_int_equal(ret, 0);
+ 
+-    ret = getpwnam_r_wrapper(1024, "user_big", &pwd, &buf, &buf_len);
++    max_big_buf_len = test_data->ctx->max_nss_buf_size;
++    test_data->ctx->max_nss_buf_size = 1024;
++    ret = getpwnam_r_wrapper(test_data->ctx,
++                             "user_big", &pwd, &buf, &buf_len);
++    test_data->ctx->max_nss_buf_size = max_big_buf_len;
+     assert_int_equal(ret, ERANGE);
+     free(buf);
+ }
+@@ -86,15 +234,18 @@ void test_getpwuid_r_wrapper(void **state)
+     int ret;
+     struct passwd pwd;
+     char *buf;
+-    size_t buf_len;
++    size_t buf_len, max_big_buf_len;
++    struct test_data *test_data;
++
++    test_data = (struct test_data *) *state;
+ 
+     ret = get_buffer(&buf_len, &buf);
+     assert_int_equal(ret, 0);
+ 
+-    ret = getpwuid_r_wrapper(MAX_BUF, 99999, &pwd, &buf, &buf_len);
++    ret = getpwuid_r_wrapper(test_data->ctx, 99999, &pwd, &buf, &buf_len);
+     assert_int_equal(ret, ENOENT);
+ 
+-    ret = getpwuid_r_wrapper(MAX_BUF, 12345, &pwd, &buf, &buf_len);
++    ret = getpwuid_r_wrapper(test_data->ctx, 12345, &pwd, &buf, &buf_len);
+     assert_int_equal(ret, 0);
+     assert_string_equal(pwd.pw_name, "user");
+     assert_string_equal(pwd.pw_passwd, "x");
+@@ -108,7 +259,7 @@ void test_getpwuid_r_wrapper(void **state)
+     ret = get_buffer(&buf_len, &buf);
+     assert_int_equal(ret, 0);
+ 
+-    ret = getpwuid_r_wrapper(MAX_BUF, 12346, &pwd, &buf, &buf_len);
++    ret = getpwuid_r_wrapper(test_data->ctx, 12346, &pwd, &buf, &buf_len);
+     assert_int_equal(ret, 0);
+     assert_string_equal(pwd.pw_name, "user_big");
+     assert_string_equal(pwd.pw_passwd, "x");
+@@ -122,7 +273,10 @@ void test_getpwuid_r_wrapper(void **state)
+     ret = get_buffer(&buf_len, &buf);
+     assert_int_equal(ret, 0);
+ 
+-    ret = getpwuid_r_wrapper(1024, 12346, &pwd, &buf, &buf_len);
++    max_big_buf_len = test_data->ctx->max_nss_buf_size;
++    test_data->ctx->max_nss_buf_size = 1024;
++    ret = getpwuid_r_wrapper(test_data->ctx, 12346, &pwd, &buf, &buf_len);
++    test_data->ctx->max_nss_buf_size = max_big_buf_len;
+     assert_int_equal(ret, ERANGE);
+     free(buf);
+ }
+@@ -132,15 +286,19 @@ void test_getgrnam_r_wrapper(void **state)
+     int ret;
+     struct group grp;
+     char *buf;
+-    size_t buf_len;
++    size_t buf_len, max_big_buf_len;
++    struct test_data *test_data;
++
++    test_data = (struct test_data *) *state;
+ 
+     ret = get_buffer(&buf_len, &buf);
+     assert_int_equal(ret, 0);
+ 
+-    ret = getgrnam_r_wrapper(MAX_BUF, "non_exisiting_group", &grp, &buf, &buf_len);
++    ret = getgrnam_r_wrapper(test_data->ctx,
++                             "non_exisiting_group", &grp, &buf, &buf_len);
+     assert_int_equal(ret, ENOENT);
+ 
+-    ret = getgrnam_r_wrapper(MAX_BUF, "group", &grp, &buf, &buf_len);
++    ret = getgrnam_r_wrapper(test_data->ctx, "group", &grp, &buf, &buf_len);
+     assert_int_equal(ret, 0);
+     assert_string_equal(grp.gr_name, "group");
+     assert_string_equal(grp.gr_passwd, "x");
+@@ -153,7 +311,7 @@ void test_getgrnam_r_wrapper(void **state)
+     ret = get_buffer(&buf_len, &buf);
+     assert_int_equal(ret, 0);
+ 
+-    ret = getgrnam_r_wrapper(MAX_BUF, "group_big", &grp, &buf, &buf_len);
++    ret = getgrnam_r_wrapper(test_data->ctx, "group_big", &grp, &buf, &buf_len);
+     assert_int_equal(ret, 0);
+     assert_string_equal(grp.gr_name, "group_big");
+     assert_string_equal(grp.gr_passwd, "x");
+@@ -165,7 +323,10 @@ void test_getgrnam_r_wrapper(void **state)
+     ret = get_buffer(&buf_len, &buf);
+     assert_int_equal(ret, 0);
+ 
+-    ret = getgrnam_r_wrapper(1024, "group_big", &grp, &buf, &buf_len);
++    max_big_buf_len = test_data->ctx->max_nss_buf_size;
++    test_data->ctx->max_nss_buf_size = 1024;
++    ret = getgrnam_r_wrapper(test_data->ctx, "group_big", &grp, &buf, &buf_len);
++    test_data->ctx->max_nss_buf_size = max_big_buf_len;
+     assert_int_equal(ret, ERANGE);
+     free(buf);
+ }
+@@ -175,15 +336,18 @@ void test_getgrgid_r_wrapper(void **state)
+     int ret;
+     struct group grp;
+     char *buf;
+-    size_t buf_len;
++    size_t buf_len, max_big_buf_len;
++    struct test_data *test_data;
++
++    test_data = (struct test_data *) *state;
+ 
+     ret = get_buffer(&buf_len, &buf);
+     assert_int_equal(ret, 0);
+ 
+-    ret = getgrgid_r_wrapper(MAX_BUF, 99999, &grp, &buf, &buf_len);
++    ret = getgrgid_r_wrapper(test_data->ctx, 99999, &grp, &buf, &buf_len);
+     assert_int_equal(ret, ENOENT);
+ 
+-    ret = getgrgid_r_wrapper(MAX_BUF, 11111, &grp, &buf, &buf_len);
++    ret = getgrgid_r_wrapper(test_data->ctx, 11111, &grp, &buf, &buf_len);
+     assert_int_equal(ret, 0);
+     assert_string_equal(grp.gr_name, "group");
+     assert_string_equal(grp.gr_passwd, "x");
+@@ -196,7 +360,7 @@ void test_getgrgid_r_wrapper(void **state)
+     ret = get_buffer(&buf_len, &buf);
+     assert_int_equal(ret, 0);
+ 
+-    ret = getgrgid_r_wrapper(MAX_BUF, 22222, &grp, &buf, &buf_len);
++    ret = getgrgid_r_wrapper(test_data->ctx, 22222, &grp, &buf, &buf_len);
+     assert_int_equal(ret, 0);
+     assert_string_equal(grp.gr_name, "group_big");
+     assert_string_equal(grp.gr_passwd, "x");
+@@ -208,7 +372,10 @@ void test_getgrgid_r_wrapper(void **state)
+     ret = get_buffer(&buf_len, &buf);
+     assert_int_equal(ret, 0);
+ 
+-    ret = getgrgid_r_wrapper(1024, 22222, &grp, &buf, &buf_len);
++    max_big_buf_len = test_data->ctx->max_nss_buf_size;
++    test_data->ctx->max_nss_buf_size = 1024;
++    ret = getgrgid_r_wrapper(test_data->ctx, 22222, &grp, &buf, &buf_len);
++    test_data->ctx->max_nss_buf_size = max_big_buf_len;
+     assert_int_equal(ret, ERANGE);
+     free(buf);
+ }
+@@ -219,16 +386,21 @@ void test_get_user_grouplist(void **state)
+     size_t ngroups;
+     gid_t *groups;
+     size_t c;
++    struct test_data *test_data;
++
++    test_data = (struct test_data *) *state;
+ 
+     /* This is a bit odd behaviour of getgrouplist() it does not check if the
+      * user exists, only if memberships of the user can be found. */
+-    ret = get_user_grouplist("non_exisiting_user", 23456, &ngroups, &groups);
++    ret = get_user_grouplist(test_data->ctx,
++                             "non_exisiting_user", 23456, &ngroups, &groups);
+     assert_int_equal(ret, LDAP_SUCCESS);
+     assert_int_equal(ngroups, 1);
+     assert_int_equal(groups[0], 23456);
+     free(groups);
+ 
+-    ret = get_user_grouplist("member0001", 23456, &ngroups, &groups);
++    ret = get_user_grouplist(test_data->ctx,
++                             "member0001", 23456, &ngroups, &groups);
+     assert_int_equal(ret, LDAP_SUCCESS);
+     assert_int_equal(ngroups, 3);
+     assert_int_equal(groups[0], 23456);
+@@ -236,14 +408,16 @@ void test_get_user_grouplist(void **state)
+     assert_int_equal(groups[2], 22222);
+     free(groups);
+ 
+-    ret = get_user_grouplist("member0003", 23456, &ngroups, &groups);
++    ret = get_user_grouplist(test_data->ctx,
++                             "member0003", 23456, &ngroups, &groups);
+     assert_int_equal(ret, LDAP_SUCCESS);
+     assert_int_equal(ngroups, 2);
+     assert_int_equal(groups[0], 23456);
+     assert_int_equal(groups[1], 22222);
+     free(groups);
+ 
+-    ret = get_user_grouplist("user_big", 23456, &ngroups, &groups);
++    ret = get_user_grouplist(test_data->ctx,
++                             "user_big", 23456, &ngroups, &groups);
+     assert_int_equal(ret, LDAP_SUCCESS);
+     assert_int_equal(ngroups, 1001);
+     assert_int_equal(groups[0], 23456);
+@@ -253,11 +427,6 @@ void test_get_user_grouplist(void **state)
+     free(groups);
+ }
+ 
+-struct test_data {
+-    struct extdom_req *req;
+-    struct ipa_extdom_ctx *ctx;
+-};
+-
+ static int  extdom_req_setup(void **state)
+ {
+     struct test_data *test_data;
+@@ -269,8 +438,14 @@ static int  extdom_req_setup(void **state)
+     assert_non_null(test_data->req);
+ 
+     test_data->ctx = calloc(sizeof(struct ipa_extdom_ctx), 1);
+-    assert_non_null(test_data->req);
++    assert_non_null(test_data->ctx);
++
++    test_data->ctx->max_nss_buf_size = MAX_BUF;
++
++    assert_int_equal(cmocka_extdom_init_context(&test_data->ctx->nss_ctx), 0);
++    assert_non_null(test_data->ctx->nss_ctx);
+ 
++    back_extdom_set_timeout(test_data->ctx->nss_ctx, 10000);
+     *state = test_data;
+ 
+     return 0;
+@@ -283,6 +458,7 @@ static int  extdom_req_teardown(void **state)
+     test_data = (struct test_data *) *state;
+ 
+     free_req_data(test_data->req);
++    back_extdom_free_context(&test_data->ctx->nss_ctx);
+     free(test_data->ctx);
+     free(test_data);
+ 
+@@ -450,5 +626,6 @@ int main(int argc, const char *argv[])
+         cmocka_unit_test(test_decode),
+     };
+ 
+-    return cmocka_run_group_tests(tests, NULL, NULL);
++    assert_non_null(original_fopen);
++    return cmocka_run_group_tests(tests, extdom_req_setup, extdom_req_teardown);
+ }
+diff --git a/daemons/ipa-slapi-plugins/ipa-extdom-extop/ipa_extdom_common.c b/daemons/ipa-slapi-plugins/ipa-extdom-extop/ipa_extdom_common.c
+index fe225fa86669a6728bec5014be41d80275f10717..86c6638ba73c2f59aff29191e3e68dc5c85d50fc 100644
+--- a/daemons/ipa-slapi-plugins/ipa-extdom-extop/ipa_extdom_common.c
++++ b/daemons/ipa-slapi-plugins/ipa-extdom-extop/ipa_extdom_common.c
+@@ -43,11 +43,12 @@
+ 
+ #include <errno.h>
+ #include <stdio.h>
++#include <sys/param.h>
+ 
+ #include "ipa_extdom.h"
++#include "back_extdom.h"
+ #include "util.h"
+ 
+-#define MAX(a,b) (((a)>(b))?(a):(b))
+ #define SSSD_DOMAIN_SEPARATOR '@'
+ 
+ int get_buffer(size_t *_buf_len, char **_buf)
+@@ -97,134 +98,137 @@ static int inc_buffer(size_t buf_max, size_t *_buf_len, char **_buf)
+     return 0;
+ }
+ 
+-int getpwnam_r_wrapper(size_t buf_max, const char *name,
+-                       struct passwd *pwd, char **_buf, size_t *_buf_len)
++int __nss_to_err(enum nss_status errcode)
+ {
+-    char *buf = NULL;
+-    size_t buf_len = 0;
+-    int ret;
+-    struct passwd *result = NULL;
++    switch(errcode) {
++    case NSS_STATUS_SUCCESS:
++        return 0;
++    case NSS_STATUS_NOTFOUND:
++        return ENOENT;
++    case NSS_STATUS_TRYAGAIN:
++        return ERANGE;
++    case NSS_STATUS_UNAVAIL:
++        return ETIMEDOUT;
++    }
+ 
+-    buf = *_buf;
+-    buf_len = *_buf_len;
++    return -1;
++}
+ 
+-    while (buf != NULL
+-            && (ret = getpwnam_r(name, pwd, buf, buf_len, &result)) == ERANGE) {
+-        ret = inc_buffer(buf_max, &buf_len, &buf);
+-        if (ret != 0) {
+-            if (ret == ERANGE) {
+-                LOG("Buffer too small, increase ipaExtdomMaxNssBufSize.\n");
+-            }
+-            goto done;
++int getpwnam_r_wrapper(struct ipa_extdom_ctx *ctx, const char *name,
++                       struct passwd *pwd, char **buf, size_t *buf_len)
++{
++    int ret, lerrno = 0;
++    struct passwd *result = NULL;
++    enum nss_status rc;
++
++    for(rc = NSS_STATUS_TRYAGAIN; rc == NSS_STATUS_TRYAGAIN;) {
++        rc = back_extdom_getpwnam(ctx->nss_ctx, name, pwd, *buf, *buf_len, &result, &lerrno);
++        ret = __nss_to_err(rc);
++        if (ret == ERANGE) {
++            ret = inc_buffer(ctx->max_nss_buf_size, buf_len, buf);
++            if (ret != 0) goto done;
+         }
+     }
+ 
+-    if (ret == 0 && result == NULL) {
+-        ret = ENOENT;
+-    }
+-
+ done:
+-    *_buf = buf;
+-    *_buf_len = buf_len;
+-
++    switch(ret) {
++    case 0:
++        if (result == NULL) ret = ENOENT;
++        break;
++    case ERANGE:
++        LOG("Buffer too small, increase ipaExtdomMaxNssBufSize.\n");
++    default:
++        break;
++    }
+     return ret;
+ }
+ 
+-int getpwuid_r_wrapper(size_t buf_max, uid_t uid,
+-                       struct passwd *pwd, char **_buf, size_t *_buf_len)
++int getpwuid_r_wrapper(struct ipa_extdom_ctx *ctx, uid_t uid,
++                       struct passwd *pwd, char **buf, size_t *buf_len)
+ {
+-    char *buf = NULL;
+-    size_t buf_len = 0;
+-    int ret;
++    int ret, lerrno;
+     struct passwd *result = NULL;
+-
+-    buf = *_buf;
+-    buf_len = *_buf_len;
+-
+-    while (buf != NULL
+-            && (ret = getpwuid_r(uid, pwd, buf, buf_len, &result)) == ERANGE) {
+-        ret = inc_buffer(buf_max, &buf_len, &buf);
+-        if (ret != 0) {
+-            if (ret == ERANGE) {
+-                LOG("Buffer too small, increase ipaExtdomMaxNssBufSize.\n");
+-            }
+-            goto done;
++    enum nss_status rc;
++
++    for(rc = NSS_STATUS_TRYAGAIN; rc == NSS_STATUS_TRYAGAIN;) {
++        rc = back_extdom_getpwuid(ctx->nss_ctx, uid, pwd, *buf, *buf_len, &result, &lerrno);
++        ret = __nss_to_err(rc);
++        if (ret == ERANGE) {
++            ret = inc_buffer(ctx->max_nss_buf_size, buf_len, buf);
++            if (ret != 0) goto done;
+         }
+     }
+ 
+-    if (ret == 0 && result == NULL) {
+-        ret = ENOENT;
+-    }
+-
+ done:
+-    *_buf = buf;
+-    *_buf_len = buf_len;
++    switch(ret) {
++    case 0:
++        if (result == NULL) ret = ENOENT;
++        break;
++    case ERANGE:
++        LOG("Buffer too small, increase ipaExtdomMaxNssBufSize.\n");
++    default:
++        break;
++    }
+ 
+     return ret;
+ }
+ 
+-int getgrnam_r_wrapper(size_t buf_max, const char *name,
+-                       struct group *grp, char **_buf, size_t *_buf_len)
++int getgrnam_r_wrapper(struct ipa_extdom_ctx *ctx, const char *name,
++                       struct group *grp, char **buf, size_t *buf_len)
+ {
+-    char *buf = NULL;
+-    size_t buf_len = 0;
+-    int ret;
++    int ret, lerrno;
+     struct group *result = NULL;
+-
+-    buf = *_buf;
+-    buf_len = *_buf_len;
+-
+-    while (buf != NULL
+-            && (ret = getgrnam_r(name, grp, buf, buf_len, &result)) == ERANGE) {
+-        ret = inc_buffer(buf_max, &buf_len, &buf);
+-        if (ret != 0) {
+-            if (ret == ERANGE) {
+-                LOG("Buffer too small, increase ipaExtdomMaxNssBufSize.\n");
+-            }
+-            goto done;
++    enum nss_status rc;
++
++    for(rc = NSS_STATUS_TRYAGAIN; rc == NSS_STATUS_TRYAGAIN;) {
++        rc = back_extdom_getgrnam(ctx->nss_ctx, name, grp, *buf, *buf_len, &result, &lerrno);
++        ret = __nss_to_err(rc);
++        if (ret == ERANGE) {
++            ret = inc_buffer(ctx->max_nss_buf_size, buf_len, buf);
++            if (ret != 0) goto done;
+         }
+     }
+ 
+-    if (ret == 0 && result == NULL) {
+-        ret = ENOENT;
+-    }
+-
+ done:
+-    *_buf = buf;
+-    *_buf_len = buf_len;
++    switch(ret) {
++    case 0:
++        if (result == NULL) ret = ENOENT;
++        break;
++    case ERANGE:
++        LOG("Buffer too small, increase ipaExtdomMaxNssBufSize.\n");
++    default:
++        break;
++    }
+ 
+     return ret;
+ }
+ 
+-int getgrgid_r_wrapper(size_t buf_max, gid_t gid,
+-                       struct group *grp, char **_buf, size_t *_buf_len)
++int getgrgid_r_wrapper(struct ipa_extdom_ctx *ctx, gid_t gid,
++                       struct group *grp, char **buf, size_t *buf_len)
+ {
+-    char *buf = NULL;
+-    size_t buf_len = 0;
+-    int ret;
++    int ret, lerrno;
+     struct group *result = NULL;
+-
+-    buf = *_buf;
+-    buf_len = *_buf_len;
+-
+-    while (buf != NULL
+-            && (ret = getgrgid_r(gid, grp, buf, buf_len, &result)) == ERANGE) {
+-        ret = inc_buffer(buf_max, &buf_len, &buf);
+-        if (ret != 0) {
+-            if (ret == ERANGE) {
+-                LOG("Buffer too small, increase ipaExtdomMaxNssBufSize.\n");
+-            }
+-            goto done;
++    enum nss_status rc;
++
++    for(rc = NSS_STATUS_TRYAGAIN; rc == NSS_STATUS_TRYAGAIN;) {
++        rc = back_extdom_getgrgid(ctx->nss_ctx, gid, grp, *buf, *buf_len, &result, &lerrno);
++        ret = __nss_to_err(rc);
++        if (ret == ERANGE) {
++            ret = inc_buffer(ctx->max_nss_buf_size, buf_len, buf);
++            if (ret != 0) goto done;
+         }
+     }
+ 
+-    if (ret == 0 && result == NULL) {
+-        ret = ENOENT;
+-    }
+-
+ done:
+-    *_buf = buf;
+-    *_buf_len = buf_len;
++    switch(ret) {
++    case 0:
++        if (result == NULL) ret = ENOENT;
++        break;
++    case ERANGE:
++        LOG("Buffer too small, increase ipaExtdomMaxNssBufSize.\n");
++    default:
++        break;
++    }
+ 
+     return ret;
+ }
+@@ -406,13 +410,14 @@ int check_request(struct extdom_req *req, enum extdom_version version)
+     return LDAP_SUCCESS;
+ }
+ 
+-int get_user_grouplist(const char *name, gid_t gid,
++int get_user_grouplist(struct ipa_extdom_ctx *ctx, const char *name, gid_t gid,
+                        size_t *_ngroups, gid_t **_groups)
+ {
+-    int ret;
++    int lerrno;
+     int ngroups;
+     gid_t *groups;
+     gid_t *new_groups;
++    enum nss_status rc;
+ 
+     ngroups = 128;
+     groups = malloc(ngroups * sizeof(gid_t));
+@@ -420,19 +425,18 @@ int get_user_grouplist(const char *name, gid_t gid,
+         return LDAP_OPERATIONS_ERROR;
+     }
+ 
+-    ret = getgrouplist(name, gid, groups, &ngroups);
+-    if (ret == -1) {
+-        new_groups = realloc(groups, ngroups * sizeof(gid_t));
+-        if (new_groups == NULL) {
+-            free(groups);
+-            return LDAP_OPERATIONS_ERROR;
+-        }
+-        groups = new_groups;
+-
+-        ret = getgrouplist(name, gid, groups, &ngroups);
+-        if (ret == -1) {
+-            free(groups);
+-            return LDAP_OPERATIONS_ERROR;
++    for(rc = NSS_STATUS_TRYAGAIN; rc == NSS_STATUS_TRYAGAIN;) {
++        rc = back_extdom_getgrouplist(ctx->nss_ctx, name, gid, groups, &ngroups, &lerrno);
++        if (rc == NSS_STATUS_TRYAGAIN) {
++            new_groups = NULL;
++            if (lerrno == ERANGE) {
++                new_groups = realloc(groups, ngroups * sizeof(gid_t));
++            }
++            if ((new_groups == NULL) || (lerrno == ENOMEM)) {
++                free(groups);
++                return LDAP_OPERATIONS_ERROR;
++            }
++            groups = new_groups;
+         }
+     }
+ 
+@@ -538,7 +542,7 @@ int pack_ber_user(struct ipa_extdom_ctx *ctx,
+     }
+ 
+     if (response_type == RESP_USER_GROUPLIST) {
+-        ret = get_user_grouplist(user_name, gid, &ngroups, &groups);
++        ret = get_user_grouplist(ctx, user_name, gid, &ngroups, &groups);
+         if (ret != LDAP_SUCCESS) {
+             goto done;
+         }
+@@ -561,7 +565,7 @@ int pack_ber_user(struct ipa_extdom_ctx *ctx,
+         }
+ 
+         for (c = 0; c < ngroups; c++) {
+-            ret = getgrgid_r_wrapper(ctx->max_nss_buf_size,
++            ret = getgrgid_r_wrapper(ctx,
+                                      groups[c], &grp, &buf, &buf_len);
+             if (ret != 0) {
+                 if (ret == ENOMEM || ret == ERANGE) {
+@@ -841,8 +845,7 @@ static int handle_uid_request(struct ipa_extdom_ctx *ctx,
+ 
+         ret = pack_ber_sid(sid_str, berval);
+     } else {
+-        ret = getpwuid_r_wrapper(ctx->max_nss_buf_size, uid, &pwd, &buf,
+-                                 &buf_len);
++        ret = getpwuid_r_wrapper(ctx, uid, &pwd, &buf, &buf_len);
+         if (ret != 0) {
+             if (ret == ENOMEM || ret == ERANGE) {
+                 ret = LDAP_OPERATIONS_ERROR;
+@@ -913,8 +916,7 @@ static int handle_gid_request(struct ipa_extdom_ctx *ctx,
+ 
+         ret = pack_ber_sid(sid_str, berval);
+     } else {
+-        ret = getgrgid_r_wrapper(ctx->max_nss_buf_size, gid, &grp, &buf,
+-                                 &buf_len);
++        ret = getgrgid_r_wrapper(ctx, gid, &grp, &buf, &buf_len);
+         if (ret != 0) {
+             if (ret == ENOMEM || ret == ERANGE) {
+                 ret = LDAP_OPERATIONS_ERROR;
+@@ -1053,8 +1055,7 @@ static int handle_sid_request(struct ipa_extdom_ctx *ctx,
+     switch(id_type) {
+     case SSS_ID_TYPE_UID:
+     case SSS_ID_TYPE_BOTH:
+-        ret = getpwnam_r_wrapper(ctx->max_nss_buf_size, fq_name, &pwd, &buf,
+-                                 &buf_len);
++        ret = getpwnam_r_wrapper(ctx, fq_name, &pwd, &buf, &buf_len);
+         if (ret != 0) {
+             if (ret == ENOMEM || ret == ERANGE) {
+                 ret = LDAP_OPERATIONS_ERROR;
+@@ -1086,8 +1087,7 @@ static int handle_sid_request(struct ipa_extdom_ctx *ctx,
+                             pwd.pw_shell, kv_list, berval);
+         break;
+     case SSS_ID_TYPE_GID:
+-        ret = getgrnam_r_wrapper(ctx->max_nss_buf_size, fq_name, &grp, &buf,
+-                                 &buf_len);
++        ret = getgrnam_r_wrapper(ctx, fq_name, &grp, &buf, &buf_len);
+         if (ret != 0) {
+             if (ret == ENOMEM || ret == ERANGE) {
+                 ret = LDAP_OPERATIONS_ERROR;
+@@ -1181,8 +1181,7 @@ static int handle_name_request(struct ipa_extdom_ctx *ctx,
+             goto done;
+         }
+ 
+-        ret = getpwnam_r_wrapper(ctx->max_nss_buf_size, fq_name, &pwd, &buf,
+-                                 &buf_len);
++        ret = getpwnam_r_wrapper(ctx, fq_name, &pwd, &buf, &buf_len);
+         if (ret == 0) {
+             if (request_type == REQ_FULL_WITH_GROUPS) {
+                 ret = sss_nss_getorigbyname(pwd.pw_name, &kv_list, &id_type);
+@@ -1211,8 +1210,7 @@ static int handle_name_request(struct ipa_extdom_ctx *ctx,
+              * error codes which can indicate that the user was not found. To
+              * be on the safe side we fail back to the group lookup on all
+              * errors. */
+-            ret = getgrnam_r_wrapper(ctx->max_nss_buf_size, fq_name, &grp, &buf,
+-                                     &buf_len);
++            ret = getgrnam_r_wrapper(ctx, fq_name, &grp, &buf, &buf_len);
+             if (ret != 0) {
+                 if (ret == ENOMEM || ret == ERANGE) {
+                     ret = LDAP_OPERATIONS_ERROR;
+diff --git a/daemons/ipa-slapi-plugins/ipa-extdom-extop/ipa_extdom_extop.c b/daemons/ipa-slapi-plugins/ipa-extdom-extop/ipa_extdom_extop.c
+index 5bc8c2f571e311c5ae4cc56e2e1ae7d4e2f77ee6..83c30e7e6aad72af603c0b4ed1c49b80fa57560f 100644
+--- a/daemons/ipa-slapi-plugins/ipa-extdom-extop/ipa_extdom_extop.c
++++ b/daemons/ipa-slapi-plugins/ipa-extdom-extop/ipa_extdom_extop.c
+@@ -38,9 +38,11 @@
+  * END COPYRIGHT BLOCK **/
+ 
+ #include "ipa_extdom.h"
++#include "back_extdom.h"
+ #include "util.h"
+ 
+ #define DEFAULT_MAX_NSS_BUFFER (128*1024*1024)
++#define DEFAULT_MAX_NSS_TIMEOUT (10*1000)
+ 
+ Slapi_PluginDesc ipa_extdom_plugin_desc = {
+     IPA_EXTDOM_FEATURE_DESC,
+@@ -166,6 +168,7 @@ static int ipa_extdom_init_ctx(Slapi_PBlock *pb, struct ipa_extdom_ctx **_ctx)
+     struct ipa_extdom_ctx *ctx;
+     Slapi_Entry *e;
+     int ret;
++    unsigned int timeout;
+ 
+     ctx = calloc(1, sizeof(struct ipa_extdom_ctx));
+     if (!ctx) {
+@@ -202,6 +205,20 @@ static int ipa_extdom_init_ctx(Slapi_PBlock *pb, struct ipa_extdom_ctx **_ctx)
+     }
+     LOG("Maximal nss buffer size set to [%zu]!\n", ctx->max_nss_buf_size);
+ 
++
++    ret = back_extdom_init_context(&ctx->nss_ctx);
++    if (ret != 0) {
++        LOG("Unable to initialize nss interface: returned [%d]!\n", ret);
++        goto done;
++    }
++
++    timeout = slapi_entry_attr_get_uint(e, "ipaExtdomMaxNssTimeout");
++    if (timeout == 0) {
++        timeout = DEFAULT_MAX_NSS_TIMEOUT;
++    }
++    back_extdom_set_timeout(ctx->nss_ctx, timeout);
++    LOG("Maximal nss timeout (in ms) set to [%u]!\n", timeout);
++
+     ret = 0;
+ 
+ done:
+diff --git a/daemons/ipa-slapi-plugins/ipa-extdom-extop/test_data/test_setup.sh b/daemons/ipa-slapi-plugins/ipa-extdom-extop/test_data/test_setup.sh
+deleted file mode 100644
+index ad839f340efe989a91cd6902f59c9a41483f68e0..0000000000000000000000000000000000000000
+--- a/daemons/ipa-slapi-plugins/ipa-extdom-extop/test_data/test_setup.sh
++++ /dev/null
+@@ -1,3 +0,0 @@
+-export LD_PRELOAD=$(pkg-config --libs nss_wrapper)
+-export NSS_WRAPPER_PASSWD=./test_data/passwd
+-export NSS_WRAPPER_GROUP=./test_data/group
+diff --git a/freeipa.spec.in b/freeipa.spec.in
+index a8b5ce81fcf9bdb61cd3707e6b68b6f2196e0776..80ae98c5515f64a8df8d981ad5e91b05c84e31c1 100644
+--- a/freeipa.spec.in
++++ b/freeipa.spec.in
+@@ -246,7 +246,6 @@ BuildRequires:  python3-augeas
+ #
+ %if ! %{ONLY_CLIENT}
+ BuildRequires:  libcmocka-devel
+-BuildRequires:  nss_wrapper
+ # Required by ipa_kdb_tests
+ BuildRequires:  %{_libdir}/krb5/plugins/kdb/db2.so
+ %endif # ONLY_CLIENT
+diff --git a/server.m4 b/server.m4
+index a9670c87372bb7b92d08dad634c0bda123a02597..f0a8bbcc778596dade89d9332abb2939b8a44143 100644
+--- a/server.m4
++++ b/server.m4
+@@ -35,6 +35,16 @@ AC_CHECK_LIB([sss_nss_idmap],
+              [AC_MSG_ERROR([Required sss_nss_getlistbycert symbol in sss_nss_idmap not found])],
+              [])
+ 
++dnl --- if sss_nss_idmap provides _timeout() API, use it
++bck_cflags="$CFLAGS"
++CFLAGS="$CFLAGS -DIPA_389DS_PLUGIN_HELPER_CALLS"
++AC_CHECK_DECLS([sss_nss_getpwnam_timeout], [], [], [[#include <sss_nss_idmap.h>]])
++CFLAGS="$bck_cflags"
++
++if test "x$ac_cv_have_decl_sss_nss_getpwnam_timeout" = xyes ; then
++    AC_DEFINE(USE_SSS_NSS_TIMEOUT,1,[Use extended NSS API provided by SSSD])
++fi
++
+ dnl -- sss_certmap and certauth.h are needed by the IPA KDB certauth plugin --
+ PKG_CHECK_EXISTS([sss_certmap],
+                  [PKG_CHECK_MODULES([SSSCERTMAP], [sss_certmap])],
+-- 
+2.14.3
+
diff --git a/SOURCES/0007-man-ipa-cacert-manage-install-needs-clarification.patch b/SOURCES/0007-man-ipa-cacert-manage-install-needs-clarification.patch
deleted file mode 100644
index def7c31..0000000
--- a/SOURCES/0007-man-ipa-cacert-manage-install-needs-clarification.patch
+++ /dev/null
@@ -1,31 +0,0 @@
-From 9d5e8f44210f661850ec67f92909534dd52c2ee8 Mon Sep 17 00:00:00 2001
-From: Florence Blanc-Renaud <flo@redhat.com>
-Date: Wed, 22 Mar 2017 08:49:39 +0100
-Subject: [PATCH] man ipa-cacert-manage install needs clarification
-
-The customers are often confused by ipa-cacert-manage install. The man page
-should make it clear that IPA CA is not modified in any way by this command.
-
-https://pagure.io/freeipa/issue/6795
-
-Reviewed-By: Tomas Krizek <tkrizek@redhat.com>
----
- install/tools/man/ipa-cacert-manage.1 | 2 ++
- 1 file changed, 2 insertions(+)
-
-diff --git a/install/tools/man/ipa-cacert-manage.1 b/install/tools/man/ipa-cacert-manage.1
-index 4515d7c404054139725fd47f366706cb1e222be5..128edd8bd2500a09f406da8dc01a53b269007ab0 100644
---- a/install/tools/man/ipa-cacert-manage.1
-+++ b/install/tools/man/ipa-cacert-manage.1
-@@ -46,6 +46,8 @@ When the IPA CA is not configured, this command is not available.
- .RS
- This command can be used to install the certificate contained in \fICERTFILE\fR as an additional CA certificate to IPA.
- .sp
-+Important: this does not replace IPA CA but adds the provided certificate as a known CA. This is useful for instance when using ipa-server-certinstall to replace HTTP/LDAP certificates with third-party certificates signed by this additional CA.
-+.sp
- Please do not forget to run ipa-certupdate on the master, all the replicas and all the clients after this command in order to update IPA certificates databases.
- .RE
- .SH "COMMON OPTIONS"
--- 
-2.12.1
-
diff --git a/SOURCES/0008-Add-the-sub-operation-for-fqdn-index-config.patch b/SOURCES/0008-Add-the-sub-operation-for-fqdn-index-config.patch
new file mode 100644
index 0000000..b7f8792
--- /dev/null
+++ b/SOURCES/0008-Add-the-sub-operation-for-fqdn-index-config.patch
@@ -0,0 +1,46 @@
+From 8a1e04abede4c0bd5730781ef8c42c8a2e1bbcf9 Mon Sep 17 00:00:00 2001
+From: Stanislav Laznicka <slaznick@redhat.com>
+Date: Fri, 3 Nov 2017 09:23:10 +0100
+Subject: [PATCH] Add the sub operation for fqdn index config
+
+This should improve performance of the host-find command.
+
+https://pagure.io/freeipa/issue/6371
+
+Reviewed-By: Rob Crittenden <rcritten@redhat.com>
+---
+ install/share/indices.ldif        | 1 +
+ install/updates/20-indices.update | 5 +++--
+ 2 files changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/install/share/indices.ldif b/install/share/indices.ldif
+index d853266025ae350dd7de83e11e463c6bb1ab9429..adb041d374d8fc48fff9d4b40208e7eda82857b3 100644
+--- a/install/share/indices.ldif
++++ b/install/share/indices.ldif
+@@ -108,6 +108,7 @@ cn: fqdn
+ nsSystemIndex: false
+ nsIndexType: eq
+ nsIndexType: pres
++nsIndexType: sub
+ 
+ dn: cn=macAddress,cn=index,cn=userRoot,cn=ldbm database,cn=plugins,cn=config
+ changetype: add
+diff --git a/install/updates/20-indices.update b/install/updates/20-indices.update
+index 74961d77875515d680f34af739c984a6533eb252..fb588b9ba8a2a89c9e7eab87ab5f224ca438645a 100644
+--- a/install/updates/20-indices.update
++++ b/install/updates/20-indices.update
+@@ -70,8 +70,9 @@ default:cn: fqdn
+ default:ObjectClass: top
+ default:ObjectClass: nsIndex
+ default:nsSystemIndex: false
+-default:nsIndexType: eq
+-default:nsIndexType: pres
++only:nsIndexType: eq
++only:nsIndexType: pres
++only:nsIndexType: sub
+ 
+ dn: cn=macAddress,cn=index,cn=userRoot,cn=ldbm database,cn=plugins,cn=config
+ default:cn: macAddress
+-- 
+2.14.3
+
diff --git a/SOURCES/0008-certs-do-not-implicitly-create-DS-pin.txt.patch b/SOURCES/0008-certs-do-not-implicitly-create-DS-pin.txt.patch
deleted file mode 100644
index caea419..0000000
--- a/SOURCES/0008-certs-do-not-implicitly-create-DS-pin.txt.patch
+++ /dev/null
@@ -1,48 +0,0 @@
-From 846b1c9b72f539cbe4b8d6e23de81e03b1afec9e Mon Sep 17 00:00:00 2001
-From: Jan Cholasta <jcholast@redhat.com>
-Date: Tue, 14 Mar 2017 09:32:17 +0100
-Subject: [PATCH] certs: do not implicitly create DS pin.txt
-
-Do not implicitly create DS pin.txt in `CertDB.init_from_pkcs12()`, create
-it explicitly in `DSInstance.__enable_ssl()`.
-
-This stops the file from being created in /etc/httpd/alias during classic
-replica install.
-
-https://pagure.io/freeipa/issue/4639
-
-Reviewed-By: Martin Babinsky <mbabinsk@redhat.com>
----
- ipaserver/install/certs.py      | 1 -
- ipaserver/install/dsinstance.py | 3 ++-
- 2 files changed, 2 insertions(+), 2 deletions(-)
-
-diff --git a/ipaserver/install/certs.py b/ipaserver/install/certs.py
-index 63e7887c4e73a8346d4eb5d865ddc89c07247573..9f340b8678c55cffe2872df97c643c34857cfaa9 100644
---- a/ipaserver/install/certs.py
-+++ b/ipaserver/install/certs.py
-@@ -635,7 +635,6 @@ class CertDB(object):
-         self.cacert_name = ca_names[-1]
-         self.trust_root_cert(self.cacert_name, trust_flags)
- 
--        self.create_pin_file()
-         self.export_ca_cert(nickname, False)
- 
-     def publish_ca_cert(self, location):
-diff --git a/ipaserver/install/dsinstance.py b/ipaserver/install/dsinstance.py
-index 91cc180e62b9532e716c07c493b359567b20c749..79dc90e92cac49a2b64ff6645f75dc3a8cbcc104 100644
---- a/ipaserver/install/dsinstance.py
-+++ b/ipaserver/install/dsinstance.py
-@@ -838,7 +838,8 @@ class DsInstance(service.Service):
-                 certmonger.modify_ca_helper('IPA', prev_helper)
- 
-             self.dercert = dsdb.get_cert_from_db(self.nickname, pem=False)
--            dsdb.create_pin_file()
-+
-+        dsdb.create_pin_file()
- 
-         self.cacert_name = dsdb.cacert_name
- 
--- 
-2.12.1
-
diff --git a/SOURCES/0009-Add-indexing-to-improve-host-find-performance.patch b/SOURCES/0009-Add-indexing-to-improve-host-find-performance.patch
new file mode 100644
index 0000000..8bc6e7f
--- /dev/null
+++ b/SOURCES/0009-Add-indexing-to-improve-host-find-performance.patch
@@ -0,0 +1,121 @@
+From ff597260ef2f5e953b55ae1a8511191853becca8 Mon Sep 17 00:00:00 2001
+From: Stanislav Laznicka <slaznick@redhat.com>
+Date: Fri, 27 Oct 2017 09:34:38 +0200
+Subject: [PATCH] Add indexing to improve host-find performance
+
+host-find <host_name> command performance gets deteriorated when
+there's way too many hosts in the LDAP tree. We're adding indices
+to try and mitigate this behavior.
+
+https://pagure.io/freeipa/issue/6371
+
+Reviewed-By: Rob Crittenden <rcritten@redhat.com>
+---
+ install/share/indices.ldif        | 45 +++++++++++++++++++++++++++++++++++++++
+ install/updates/20-indices.update | 40 ++++++++++++++++++++++++++++++++++
+ 2 files changed, 85 insertions(+)
+
+diff --git a/install/share/indices.ldif b/install/share/indices.ldif
+index adb041d374d8fc48fff9d4b40208e7eda82857b3..7bd59d2774df9bdf56f6b8034236aa2c5658b366 100644
+--- a/install/share/indices.ldif
++++ b/install/share/indices.ldif
+@@ -279,3 +279,48 @@ objectClass: nsIndex
+ nsSystemIndex: false
+ nsIndexType: eq
+ nsIndexType: sub
++
++dn: cn=description,cn=index,cn=userroot,cn=ldbm database,cn=plugins,cn=config
++changetype: add
++cn: description
++objectClass: top
++objectClass: nsindex
++nssystemindex: false
++nsindextype: eq
++nsindextype: sub
++
++dn: cn=l,cn=index,cn=userroot,cn=ldbm database,cn=plugins,cn=config
++changetype: add
++cn: l
++objectClass: top
++objectClass: nsindex
++nssystemindex: false
++nsindextype: eq
++nsindextype: sub
++
++dn: cn=nsOsVersion,cn=index,cn=userroot,cn=ldbm database,cn=plugins,cn=config
++changetype: add
++cn: nsOsVersion
++objectClass: top
++objectClass: nsindex
++nssystemindex: false
++nsindextype: eq
++nsindextype: sub
++
++dn: cn=nsHardwarePlatform,cn=index,cn=userroot,cn=ldbm database,cn=plugins,cn=config
++changetype: add
++cn: nsHardwarePlatform
++objectClass: top
++objectClass: nsindex
++nssystemindex: false
++nsindextype: eq
++nsindextype: sub
++
++dn: cn=nsHostLocation,cn=index,cn=userroot,cn=ldbm database,cn=plugins,cn=config
++changetype: add
++cn: nsHostLocation
++objectClass: top
++objectClass: nsindex
++nssystemindex: false
++nsindextype: eq
++nsindextype: sub
+diff --git a/install/updates/20-indices.update b/install/updates/20-indices.update
+index fb588b9ba8a2a89c9e7eab87ab5f224ca438645a..016fbb6bedb6af69fba0a8a84f8c1c6622d4368c 100644
+--- a/install/updates/20-indices.update
++++ b/install/updates/20-indices.update
+@@ -260,3 +260,43 @@ default: objectClass: nsIndex
+ only: nsSystemIndex: false
+ only: nsIndexType: eq
+ only: nsIndexType: sub
++
++dn: cn=description,cn=index,cn=userroot,cn=ldbm database,cn=plugins,cn=config
++default: cn: description
++default: objectclass: top
++default: objectclass: nsindex
++default: nssystemindex: false
++default: nsindextype: eq
++default: nsindextype: sub
++
++dn: cn=l,cn=index,cn=userroot,cn=ldbm database,cn=plugins,cn=config
++default: cn: l
++default: objectclass: top
++default: objectclass: nsindex
++default: nssystemindex: false
++default: nsindextype: eq
++default: nsindextype: sub
++
++dn: cn=nsOsVersion,cn=index,cn=userroot,cn=ldbm database,cn=plugins,cn=config
++default: cn: nsOsVersion
++default: objectclass: top
++default: objectclass: nsindex
++default: nssystemindex: false
++default: nsindextype: eq
++default: nsindextype: sub
++
++dn: cn=nsHardwarePlatform,cn=index,cn=userroot,cn=ldbm database,cn=plugins,cn=config
++default: cn: nsHardwarePlatform
++default: objectclass: top
++default: objectclass: nsindex
++default: nssystemindex: false
++default: nsindextype: eq
++default: nsindextype: sub
++
++dn: cn=nsHostLocation,cn=index,cn=userroot,cn=ldbm database,cn=plugins,cn=config
++default: cn: nsHostLocation
++default: objectclass: top
++default: objectclass: nsindex
++default: nssystemindex: false
++default: nsindextype: eq
++default: nsindextype: sub
+-- 
+2.14.3
+
diff --git a/SOURCES/0009-httpinstance-clean-up-etc-httpd-alias-on-uninstall.patch b/SOURCES/0009-httpinstance-clean-up-etc-httpd-alias-on-uninstall.patch
deleted file mode 100644
index c26e495..0000000
--- a/SOURCES/0009-httpinstance-clean-up-etc-httpd-alias-on-uninstall.patch
+++ /dev/null
@@ -1,74 +0,0 @@
-From 10e74165a827377ed3318d4d2b974fdbf0fab9db Mon Sep 17 00:00:00 2001
-From: Jan Cholasta <jcholast@redhat.com>
-Date: Wed, 8 Mar 2017 14:24:15 +0000
-Subject: [PATCH] httpinstance: clean up /etc/httpd/alias on uninstall
-
-Restore cert8.db, key3.db, pwdfile.txt and secmod.db in /etc/httpd/alias
-from backup on uninstall.
-
-Files modified by IPA are kept with .ipasave suffix.
-
-https://pagure.io/freeipa/issue/4639
-
-Reviewed-By: Martin Babinsky <mbabinsk@redhat.com>
----
- ipapython/certdb.py               | 13 +++++++++++++
- ipaserver/install/certs.py        |  3 +++
- ipaserver/install/httpinstance.py |  3 +++
- 3 files changed, 19 insertions(+)
-
-diff --git a/ipapython/certdb.py b/ipapython/certdb.py
-index 6c89e778068d9ed1e9939077f7114463776e3516..f1410e5ae4290263573e9554ab4e66873d4344a1 100644
---- a/ipapython/certdb.py
-+++ b/ipapython/certdb.py
-@@ -169,6 +169,19 @@ class NSSDatabase(object):
-                     new_mode = filemode
-                 os.chmod(path, new_mode)
- 
-+    def restore(self):
-+        for filename in NSS_FILES:
-+            path = os.path.join(self.secdir, filename)
-+            backup_path = path + '.orig'
-+            save_path = path + '.ipasave'
-+            try:
-+                if os.path.exists(path):
-+                    os.rename(path, save_path)
-+                if os.path.exists(backup_path):
-+                    os.rename(backup_path, path)
-+            except OSError as e:
-+                root_logger.debug(e)
-+
-     def list_certs(self):
-         """Return nicknames and cert flags for all certs in the database
- 
-diff --git a/ipaserver/install/certs.py b/ipaserver/install/certs.py
-index 9f340b8678c55cffe2872df97c643c34857cfaa9..0ca971358030db6a6e7e410e58a984675bcf53ac 100644
---- a/ipaserver/install/certs.py
-+++ b/ipaserver/install/certs.py
-@@ -234,6 +234,9 @@ class CertDB(object):
-                              backup=True)
-         self.set_perms(self.passwd_fname, write=True)
- 
-+    def restore(self):
-+        self.nssdb.restore()
-+
-     def list_certs(self):
-         """
-         Return a tuple of tuples containing (nickname, trust)
-diff --git a/ipaserver/install/httpinstance.py b/ipaserver/install/httpinstance.py
-index ca3bcc87eec2c93a664db517df3eddecaaf565c2..f6f0b0c4f6acd648aa9f6f5d7400617613245473 100644
---- a/ipaserver/install/httpinstance.py
-+++ b/ipaserver/install/httpinstance.py
-@@ -555,6 +555,9 @@ class HTTPInstance(service.Service):
-                 ca_iface.Set('org.fedorahosted.certmonger.ca',
-                              'external-helper', helper)
- 
-+        db = certs.CertDB(self.realm, paths.HTTPD_ALIAS_DIR)
-+        db.restore()
-+
-         for f in [paths.HTTPD_IPA_CONF, paths.HTTPD_SSL_CONF, paths.HTTPD_NSS_CONF]:
-             try:
-                 self.fstore.restore_file(f)
--- 
-2.12.1
-
diff --git a/SOURCES/0010-Fixing-replica-install-fix-ldap-connection-in-domlvl.patch b/SOURCES/0010-Fixing-replica-install-fix-ldap-connection-in-domlvl.patch
deleted file mode 100644
index 0664301..0000000
--- a/SOURCES/0010-Fixing-replica-install-fix-ldap-connection-in-domlvl.patch
+++ /dev/null
@@ -1,43 +0,0 @@
-From 175c29c7b57a0ab48d1371c199e70f3435a0ead7 Mon Sep 17 00:00:00 2001
-From: felipe <fbarreto@localhost.localdomain>
-Date: Tue, 21 Mar 2017 09:05:56 -0300
-Subject: [PATCH] Fixing replica install: fix ldap connection in domlvl 0
-
-Now, at the domain level 0, the replica install always uses
-Directory Manager credentials to create the LDAP connection.
-Since ACIs permitting hosts to manage their own services were
-added in 4.2 release,  the old master denies this operations.
-
-https://pagure.io/freeipa/issue/6549
-
-Reviewed-By: Martin Basti <mbasti@redhat.com>
-Reviewed-By: Jan Cholasta <jcholast@redhat.com>
----
- ipaserver/install/server/replicainstall.py | 11 ++++++++++-
- 1 file changed, 10 insertions(+), 1 deletion(-)
-
-diff --git a/ipaserver/install/server/replicainstall.py b/ipaserver/install/server/replicainstall.py
-index b4463fd4066efbc68f22e4f8f3175b59cb20b103..f489e691999fd9d6e82879341922510e56eac47d 100644
---- a/ipaserver/install/server/replicainstall.py
-+++ b/ipaserver/install/server/replicainstall.py
-@@ -1391,7 +1391,16 @@ def install(installer):
-     dsinstance.create_ds_user()
- 
-     try:
--        conn.connect(ccache=ccache)
-+        if promote:
-+            conn.connect(ccache=ccache)
-+        else:
-+            # dmlvl 0 replica install should always use DM credentials
-+            # to create remote LDAP connection. Since ACIs permitting hosts
-+            # to manage their own services were added in 4.2 release,
-+            # the master denies this operations.
-+            conn.connect(bind_dn=ipaldap.DIRMAN_DN, cacert=cafile,
-+                         bind_pw=config.dirman_password)
-+
-         # Update and istall updated CA file
-         cafile = install_ca_cert(conn, api.env.basedn, api.env.realm, cafile)
- 
--- 
-2.12.1
-
diff --git a/SOURCES/0010-ipa-getkeytab-man-page-add-more-details-about-the-r-.patch b/SOURCES/0010-ipa-getkeytab-man-page-add-more-details-about-the-r-.patch
new file mode 100644
index 0000000..f3509c2
--- /dev/null
+++ b/SOURCES/0010-ipa-getkeytab-man-page-add-more-details-about-the-r-.patch
@@ -0,0 +1,87 @@
+From 30e55883bd4822d4d3af061d646e7b1044880d52 Mon Sep 17 00:00:00 2001
+From: Florence Blanc-Renaud <flo@redhat.com>
+Date: Tue, 7 Nov 2017 09:31:19 +0100
+Subject: [PATCH] ipa-getkeytab man page: add more details about the -r option
+
+The man page does not provide enough information about replicated
+environments and the use of the -r option.
+This fix adds an example how to use the same keytab on 2 different
+hosts, and points to ipa {service/host}-allow-retrieve-keytab.
+
+Fixes:
+https://pagure.io/freeipa/issue/7237
+
+Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
+---
+ client/man/ipa-getkeytab.1 | 35 ++++++++++++++++++++++++++++++++++-
+ 1 file changed, 34 insertions(+), 1 deletion(-)
+
+diff --git a/client/man/ipa-getkeytab.1 b/client/man/ipa-getkeytab.1
+index 08f6ec40d362b88a974e6ec735ed37c271e01882..39ff0d5da85b5a641328a512feeb06bc9c1ab9d7 100644
+--- a/client/man/ipa-getkeytab.1
++++ b/client/man/ipa-getkeytab.1
+@@ -44,10 +44,15 @@ provided, so the principal name is just the service
+ name and hostname (ldap/foo.example.com from the
+ example above).
+ 
++ipa-getkeytab is used during IPA client enrollment to retrieve a host service principal and store it in /etc/krb5.keytab. It is possible to retrieve the keytab without Kerberos credentials if the host was pre\-created with a one\-time password. The keytab can be retrieved by binding as the host and authenticating with this one\-time password. The \fB\-D|\-\-binddn\fR and \fB\-w|\-\-bindpw\fR options are used for this authentication.
++
+ \fBWARNING:\fR retrieving the keytab resets the secret for the Kerberos principal.
+ This renders all other keytabs for that principal invalid.
++When multiple hosts or services need to share the same key (for instance in high availability or load balancing clusters), the \fB\-r\fR option must be used to retrieve the existing key instead of generating a new one (please refer to the EXAMPLES section).
++
++Note that the user or host calling \fBipa-getkeytab\fR needs to be allowed to generate the key with \fBipa host\-allow\-create\-keytab\fR or \fBipa service\-allow\-create\-keytab\fR,
++and the user or host calling \fBipa-getkeytab \-r\fR needs to be allowed to retrieve the keytab for the host or service with \fBipa host\-allow\-retrieve\-keytab\fR or \fBipa service\-allow\-retrieve\-keytab\fR.
+ 
+-This is used during IPA client enrollment to retrieve a host service principal and store it in /etc/krb5.keytab. It is possible to retrieve the keytab without Kerberos credentials if the host was pre\-created with a one\-time password. The keytab can be retrieved by binding as the host and authenticating with this one\-time password. The \fB\-D|\-\-binddn\fR and \fB\-w|\-\-bindpw\fR options are used for this authentication.
+ .SH "OPTIONS"
+ .TP
+ \fB\-p principal\-name\fR
+@@ -118,16 +123,44 @@ keytab must have access to the keys for this operation to succeed.
+ Add and retrieve a keytab for the NFS service principal on
+ the host foo.example.com and save it in the file /tmp/nfs.keytab and retrieve just the des\-cbc\-crc key.
+ 
++.nf
+    # ipa\-getkeytab \-p nfs/foo.example.com \-k /tmp/nfs.keytab \-e des\-cbc\-crc
++.fi
+ 
+ Add and retrieve a keytab for the ldap service principal on
+ the host foo.example.com and save it in the file /tmp/ldap.keytab.
+ 
++.nf
+    # ipa\-getkeytab \-s ipaserver.example.com \-p ldap/foo.example.com \-k /tmp/ldap.keytab
++.fi
+ 
+ Retrieve a keytab using LDAP credentials (this will typically be done by \fBipa\-join(1)\fR when enrolling a client using the \fBipa\-client\-install(1)\fR command:
+ 
++.nf
+    # ipa\-getkeytab \-s ipaserver.example.com \-p host/foo.example.com \-k /etc/krb5.keytab \-D fqdn=foo.example.com,cn=computers,cn=accounts,dc=example,dc=com \-w password
++.fi
++
++Add and retrieve a keytab for a clustered HTTP service deployed on client1.example.com and client2.example.com (already enrolled), using the client-frontend.example.com host name:
++
++.nf
++   # ipa host-add client-frontend.example.com --ip-address 10.1.2.3
++   # ipa service-add HTTP/client-frontend.example.com
++   # ipa service-allow-retrieve-keytab HTTP/client-frontend.example.com --hosts={client1.example.com,client2.example.com}
++   # ipa server-allow-create-keytab HTTP/client-frontend.example.com --hosts=client1.example.com
++.fi
++
++   On client1, generate and retrieve a new keytab for client-frontend.example.com:
++.nf
++   # kinit -k
++   # ipa-getkeytab -p HTTP/client-frontend.example.com -k /tmp/http.keytab
++
++.fi
++   On client2, retrieve the existing keytab for client-frontend.example.com:
++.nf
++   # kinit -k
++   # ipa-getkeytab -r -p HTTP/client-frontend.example.com -k /tmp/http.keytab
++.fi
++
+ .SH "EXIT STATUS"
+ The exit status is 0 on success, nonzero on error.
+ 
+-- 
+2.13.6
+
diff --git a/SOURCES/0011-Don-t-allow-OTP-or-RADIUS-in-FIPS-mode.patch b/SOURCES/0011-Don-t-allow-OTP-or-RADIUS-in-FIPS-mode.patch
new file mode 100644
index 0000000..74e0d92
--- /dev/null
+++ b/SOURCES/0011-Don-t-allow-OTP-or-RADIUS-in-FIPS-mode.patch
@@ -0,0 +1,83 @@
+From be18d6c15a2557e8f45e41efc81f1c005958c690 Mon Sep 17 00:00:00 2001
+From: Stanislav Laznicka <slaznick@redhat.com>
+Date: Tue, 7 Nov 2017 14:42:12 +0100
+Subject: [PATCH] Don't allow OTP or RADIUS in FIPS mode
+
+RADIUS, which is also internally used in the process of OTP
+authentication by ipa-otpd, requires MD5 checksums which
+makes it impossible to be used in FIPS mode. Don't allow users
+setting OTP or RADIUS authentication if in FIPS mode.
+
+https://pagure.io/freeipa/issue/7168
+
+Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
+---
+ ipaserver/plugins/baseuser.py |  3 +++
+ ipaserver/plugins/config.py   | 16 ++++++++++++++++
+ 2 files changed, 19 insertions(+)
+
+diff --git a/ipaserver/plugins/baseuser.py b/ipaserver/plugins/baseuser.py
+index bf24dbf542d3b481671dfe4e8cee14a2edcc26e0..bb8a73ded0fed135d5829ec0b0829a936f2196fb 100644
+--- a/ipaserver/plugins/baseuser.py
++++ b/ipaserver/plugins/baseuser.py
+@@ -32,6 +32,7 @@ from .baseldap import (
+     add_missing_object_class)
+ from ipaserver.plugins.service import (
+    validate_certificate, validate_realm, normalize_principal)
++from ipaserver.plugins.config import check_fips_auth_opts
+ from ipalib.request import context
+ from ipalib import _
+ from ipalib.constants import PATTERN_GROUPUSER_NAME
+@@ -477,6 +478,7 @@ class baseuser_add(LDAPCreate):
+                             **options):
+         assert isinstance(dn, DN)
+         set_krbcanonicalname(entry_attrs)
++        check_fips_auth_opts(fips_mode=self.api.env.fips_mode, **options)
+         self.obj.convert_usercertificate_pre(entry_attrs)
+ 
+     def post_common_callback(self, ldap, dn, entry_attrs, *keys, **options):
+@@ -600,6 +602,7 @@ class baseuser_mod(LDAPUpdate):
+         assert isinstance(dn, DN)
+         add_sshpubkey_to_attrs_pre(self.context, attrs_list)
+ 
++        check_fips_auth_opts(fips_mode=self.api.env.fips_mode, **options)
+         self.check_namelength(ldap, **options)
+ 
+         self.check_mail(entry_attrs)
+diff --git a/ipaserver/plugins/config.py b/ipaserver/plugins/config.py
+index ce15e6096f5b84dc45ee21d5aecc73ecf86eba07..c9033fa8e7a2a0bfe77464fa4f9c62278bd814f6 100644
+--- a/ipaserver/plugins/config.py
++++ b/ipaserver/plugins/config.py
+@@ -85,6 +85,20 @@ EXAMPLES:
+ 
+ register = Registry()
+ 
++
++def check_fips_auth_opts(fips_mode, **options):
++    """
++    OTP and RADIUS are not allowed in FIPS mode since they use MD5
++    checksums (OTP uses our RADIUS responder daemon ipa-otpd).
++    """
++    if 'ipauserauthtype' in options and fips_mode:
++        if ('otp' in options['ipauserauthtype'] or
++                'radius' in options['ipauserauthtype']):
++            raise errors.InvocationError(
++                'OTP and RADIUS authentication in FIPS is '
++                'not yet supported')
++
++
+ @register()
+ class config(LDAPObject):
+     """
+@@ -398,6 +412,8 @@ class config_mod(LDAPUpdate):
+ 
+     def pre_callback(self, ldap, dn, entry_attrs, attrs_list, *keys, **options):
+         assert isinstance(dn, DN)
++        check_fips_auth_opts(fips_mode=self.api.env.fips_mode, **options)
++
+         if 'ipadefaultprimarygroup' in entry_attrs:
+             group=entry_attrs['ipadefaultprimarygroup']
+             try:
+-- 
+2.13.6
+
diff --git a/SOURCES/0011-replica-prepare-fix-wrong-IPA-CA-nickname-in-replica.patch b/SOURCES/0011-replica-prepare-fix-wrong-IPA-CA-nickname-in-replica.patch
deleted file mode 100644
index 7b96d06..0000000
--- a/SOURCES/0011-replica-prepare-fix-wrong-IPA-CA-nickname-in-replica.patch
+++ /dev/null
@@ -1,51 +0,0 @@
-From c34fa1891b774e98de6a1787001f2215ea85c0f3 Mon Sep 17 00:00:00 2001
-From: Jan Cholasta <jcholast@redhat.com>
-Date: Fri, 17 Mar 2017 09:34:08 +0000
-Subject: [PATCH] replica prepare: fix wrong IPA CA nickname in replica file
-
-Lookup IPA CA subject and pass it to CertDB when creating dscert.p12 and
-httpcert.p12, otherwise a generic nickname will be used for the IPA CA
-certificate instead of "$REALM IPA CA".
-
-This fixes replica install on domain level 0 from a replica file created
-using ipa-replica-install on IPA 4.5.
-
-https://pagure.io/freeipa/issue/6777
-
-Reviewed-By: Martin Babinsky <mbabinsk@redhat.com>
----
- ipaserver/install/ipa_replica_prepare.py | 7 ++++---
- 1 file changed, 4 insertions(+), 3 deletions(-)
-
-diff --git a/ipaserver/install/ipa_replica_prepare.py b/ipaserver/install/ipa_replica_prepare.py
-index f4925a6c46b6714362545ee5e8194b7b02de5091..95c3818a9fc34c937f8b418e91a1bfc28352b02e 100644
---- a/ipaserver/install/ipa_replica_prepare.py
-+++ b/ipaserver/install/ipa_replica_prepare.py
-@@ -34,7 +34,7 @@ import dns.resolver
- from six.moves.configparser import SafeConfigParser
- # pylint: enable=import-error
- 
--from ipaserver.install import certs, installutils, bindinstance, dsinstance
-+from ipaserver.install import certs, installutils, bindinstance, dsinstance, ca
- from ipaserver.install.replication import enable_replication_version_checking
- from ipaserver.install.server.replicainstall import install_ca_cert
- from ipaserver.install.bindinstance import (
-@@ -537,12 +537,13 @@ class ReplicaPrepare(admintool.AdminTool):
-         """
-         hostname = self.replica_fqdn
-         subject_base = self.subject_base
-+        ca_subject = ca.lookup_ca_subject(api, subject_base)
-         nickname = "Server-Cert"
- 
-         try:
-             db = certs.CertDB(
--                api.env.realm, nssdir=self.dir, subject_base=subject_base,
--                host_name=api.env.host)
-+                api.env.realm, nssdir=self.dir, host_name=api.env.host,
-+                subject_base=subject_base, ca_subject=ca_subject)
-             db.create_passwd_file()
-             db.create_from_cacert()
-             db.create_server_cert(nickname, hostname)
--- 
-2.12.1
-
diff --git a/SOURCES/0012-Fix-cert-find-for-CA-less-installations.patch b/SOURCES/0012-Fix-cert-find-for-CA-less-installations.patch
new file mode 100644
index 0000000..106cea6
--- /dev/null
+++ b/SOURCES/0012-Fix-cert-find-for-CA-less-installations.patch
@@ -0,0 +1,88 @@
+From 6049b791567dad33be050b05bb08ef2040f473ee Mon Sep 17 00:00:00 2001
+From: Rob Crittenden <rcritten@redhat.com>
+Date: Tue, 24 Oct 2017 15:43:08 -0400
+Subject: [PATCH] Fix cert-find for CA-less installations
+
+Change 49f9d799c171c7ae2ac546a33a353c2c40b4719c deferred the
+detailed lookup until all certs were collected but introduced
+a bug where the ra backend was always retrieved. This generated a
+backtrace in a CA-less install because there is no ra backend in
+the CA-less case.
+
+The deferral also removes the certificate value from the LDAP
+search output resulting in only the serial number being displayed
+unless --all is provided. Add a new class variable,
+self.ca_enabled, to add an exception for the CA-less case.
+
+Fixes https://pagure.io/freeipa/issue/7202
+
+Signed-off-by: Rob Crittenden <rcritten@redhat.com>
+Reviewed-By: Stanislav Laznicka <slaznick@redhat.com>
+---
+ ipaserver/plugins/cert.py | 22 ++++++++++++++++++++--
+ 1 file changed, 20 insertions(+), 2 deletions(-)
+
+diff --git a/ipaserver/plugins/cert.py b/ipaserver/plugins/cert.py
+index bb11713317abad55577b1c280253ab5d6d68c508..c1d389217265f44e646ac27d9adc8d5524c74ce7 100644
+--- a/ipaserver/plugins/cert.py
++++ b/ipaserver/plugins/cert.py
+@@ -1453,6 +1453,7 @@ class cert_find(Search, CertMethod):
+ 
+             truncated = bool(truncated)
+ 
++        ca_enabled = getattr(context, 'ca_enabled')
+         for entry in entries:
+             for attr in ('usercertificate', 'usercertificate;binary'):
+                 for cert in entry.get(attr, []):
+@@ -1466,7 +1467,12 @@ class cert_find(Search, CertMethod):
+                         obj = result[issuer, serial_number]
+                     except KeyError:
+                         obj = {'serial_number': serial_number}
+-                        if not pkey_only and all:
++                        if not pkey_only and (all or not ca_enabled):
++                            # Retrieving certificate details is now deferred
++                            # until after all certificates are collected.
++                            # For the case of CA-less we need to keep
++                            # the certificate because getting it again later
++                            # would require unnecessary LDAP searches.
+                             obj['certificate'] = (
+                                 base64.b64encode(cert).decode('ascii'))
+                         result[issuer, serial_number] = obj
+@@ -1480,6 +1486,11 @@ class cert_find(Search, CertMethod):
+ 
+     def execute(self, criteria=None, all=False, raw=False, pkey_only=False,
+                 no_members=True, timelimit=None, sizelimit=None, **options):
++        # Store ca_enabled status in the context to save making the API
++        # call multiple times.
++        ca_enabled = self.api.Command.ca_is_enabled()['result']
++        setattr(context, 'ca_enabled', ca_enabled)
++
+         if 'cacn' in options:
+             ca_obj = api.Command.ca_show(options['cacn'])['result']
+             ca_sdn = unicode(ca_obj['ipacasubjectdn'][0])
+@@ -1534,7 +1545,8 @@ class cert_find(Search, CertMethod):
+ 
+         if not pkey_only:
+             ca_objs = {}
+-            ra = self.api.Backend.ra
++            if ca_enabled:
++                ra = self.api.Backend.ra
+ 
+             for key, obj in six.iteritems(result):
+                 if all and 'cacn' in obj:
+@@ -1561,6 +1573,12 @@ class cert_find(Search, CertMethod):
+ 
+                 if not raw:
+                     self.obj._parse(obj, all)
++                    if not ca_enabled and not all:
++                        # For the case of CA-less don't display the full
++                        # certificate unless requested. It is kept in the
++                        # entry from _ldap_search() so its attributes can
++                        # be retrieved.
++                        obj.pop('certificate', None)
+                     self.obj._fill_owners(obj)
+ 
+         result = list(six.itervalues(result))
+-- 
+2.13.6
+
diff --git a/SOURCES/0012-ldap2-use-LDAP-whoami-operation-to-retrieve-bind-DN-.patch b/SOURCES/0012-ldap2-use-LDAP-whoami-operation-to-retrieve-bind-DN-.patch
deleted file mode 100644
index 2b4be55..0000000
--- a/SOURCES/0012-ldap2-use-LDAP-whoami-operation-to-retrieve-bind-DN-.patch
+++ /dev/null
@@ -1,43 +0,0 @@
-From 1288763da61ba9e0c9bd345487a3e645c58284df Mon Sep 17 00:00:00 2001
-From: Alexander Bokovoy <abokovoy@redhat.com>
-Date: Wed, 22 Mar 2017 13:00:22 +0200
-Subject: [PATCH] ldap2: use LDAP whoami operation to retrieve bind DN for
- current connection
-
-For external users which are mapped to some DN in LDAP server, we
-wouldn't neccesary be able to find a kerberos data in their LDAP entry.
-Instead of searching for Kerberos principal use actual DN we are bound
-to because for get_effective_rights LDAP control we only need the DN
-itself.
-
-Fixes https://pagure.io/freeipa/issue/6797
-
-Reviewed-By: Martin Babinsky <mbabinsk@redhat.com>
-Reviewed-By: Pavel Vomacka <pvomacka@redhat.com>
----
- ipaserver/plugins/ldap2.py | 7 +++----
- 1 file changed, 3 insertions(+), 4 deletions(-)
-
-diff --git a/ipaserver/plugins/ldap2.py b/ipaserver/plugins/ldap2.py
-index def124530cc863e6924c7b6f1f48c236323019a9..3b1e4da57a8e16e3d9b27eea24025de2caa53216 100644
---- a/ipaserver/plugins/ldap2.py
-+++ b/ipaserver/plugins/ldap2.py
-@@ -286,12 +286,11 @@ class ldap2(CrudBackend, LDAPClient):
- 
-         assert isinstance(dn, DN)
- 
--        principal = getattr(context, 'principal')
--        entry = self.find_entry_by_attr("krbprincipalname", principal,
--            "krbPrincipalAux", base_dn=self.api.env.basedn)
-+        bind_dn = self.conn.whoami_s()[4:]
-+
-         sctrl = [
-             GetEffectiveRightsControl(
--                True, "dn: {0}".format(entry.dn).encode('utf-8'))
-+                True, "dn: {0}".format(bind_dn).encode('utf-8'))
-         ]
-         self.conn.set_option(_ldap.OPT_SERVER_CONTROLS, sctrl)
-         try:
--- 
-2.12.1
-
diff --git a/SOURCES/0013-Backup-ipa-specific-httpd-unit-file.patch b/SOURCES/0013-Backup-ipa-specific-httpd-unit-file.patch
deleted file mode 100644
index bf500ae..0000000
--- a/SOURCES/0013-Backup-ipa-specific-httpd-unit-file.patch
+++ /dev/null
@@ -1,47 +0,0 @@
-From 7b57dd770bbb4861f46805adaa9597445dff142c Mon Sep 17 00:00:00 2001
-From: Stanislav Laznicka <slaznick@redhat.com>
-Date: Thu, 16 Mar 2017 10:22:59 +0100
-Subject: [PATCH] Backup ipa-specific httpd unit-file
-
-On backup-restore, the ipa unit file for httpd was not backed up.
-This file however contains setting for httpd to communicate with
-gssproxy so not backing it up will result in httpd not knowing
-how to get credentials.
-
-https://pagure.io/freeipa/issue/6748
-
-Reviewed-By: Martin Basti <mbasti@redhat.com>
-Reviewed-By: Christian Heimes <cheimes@redhat.com>
----
- ipaserver/install/ipa_backup.py  | 1 +
- ipaserver/install/ipa_restore.py | 2 ++
- 2 files changed, 3 insertions(+)
-
-diff --git a/ipaserver/install/ipa_backup.py b/ipaserver/install/ipa_backup.py
-index 07c50c8364c313b9aeb6d73540b541f55d98a44d..56583c01b1677a48c103d79123e3fbe106222f38 100644
---- a/ipaserver/install/ipa_backup.py
-+++ b/ipaserver/install/ipa_backup.py
-@@ -166,6 +166,7 @@ class Backup(admintool.AdminTool):
-         paths.KDC_CERT,
-         paths.KDC_KEY,
-         paths.SYSTEMD_IPA_SERVICE,
-+        paths.SYSTEMD_SYSTEM_HTTPD_IPA_CONF,
-         paths.SYSTEMD_SSSD_SERVICE,
-         paths.SYSTEMD_CERTMONGER_SERVICE,
-         paths.SYSTEMD_PKI_TOMCAT_SERVICE,
-diff --git a/ipaserver/install/ipa_restore.py b/ipaserver/install/ipa_restore.py
-index d798654ea7464f66e461936e41e3747a16acb21d..2552bbdef36f653f1c377ea096ca227d09e5f3e6 100644
---- a/ipaserver/install/ipa_restore.py
-+++ b/ipaserver/install/ipa_restore.py
-@@ -414,6 +414,8 @@ class Restore(admintool.AdminTool):
-                 sssd = services.service('sssd', api)
-                 sssd.restart()
-                 http.remove_httpd_ccaches()
-+                # have the daemons pick up their restored configs
-+                run([paths.SYSTEMCTL, "--system", "daemon-reload"])
-         finally:
-             try:
-                 os.chdir(cwd)
--- 
-2.12.1
-
diff --git a/SOURCES/0013-Fix-ipa-restore-python2.patch b/SOURCES/0013-Fix-ipa-restore-python2.patch
new file mode 100644
index 0000000..573fb00
--- /dev/null
+++ b/SOURCES/0013-Fix-ipa-restore-python2.patch
@@ -0,0 +1,39 @@
+From 276a0dfa90be417a0ce37b15027f716baa97a453 Mon Sep 17 00:00:00 2001
+From: Florence Blanc-Renaud <flo@redhat.com>
+Date: Thu, 2 Nov 2017 09:34:43 +0100
+Subject: [PATCH] Fix ipa-restore (python2)
+
+In order to stop tracking LDAP server cert, ipa-restore is using
+dse.ldif to find the certificate name. But when ipa-server-install
+--uninstall has been called, the file does not exist, leading to a
+IOError exception (regression introduced by 87540fe).
+
+The ipa-restore code properly catches the exception in python3 because
+IOError is a subclass of OSError, but in python2 this is not the case.
+The fix catches IOError and OSError to work properly with both version.
+
+Fixes:
+https://pagure.io/freeipa/issue/7231
+
+Reviewed-By: Rob Crittenden <rcritten@redhat.com>
+Reviewed-By: Tomas Krizek <tkrizek@redhat.com>
+---
+ ipaserver/install/ipa_restore.py | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/ipaserver/install/ipa_restore.py b/ipaserver/install/ipa_restore.py
+index 96fc493c774f5de4c8149bf477cb66ec4960de4f..923b1d6696d33c0bb07ca018b53dd3dabcc191aa 100644
+--- a/ipaserver/install/ipa_restore.py
++++ b/ipaserver/install/ipa_restore.py
+@@ -815,7 +815,7 @@ class Restore(admintool.AdminTool):
+         try:
+             dsinstance.DsInstance().stop_tracking_certificates(
+                 installutils.realm_to_serverid(api.env.realm))
+-        except OSError:
++        except (OSError, IOError):
+             # When IPA is not installed, DS NSS DB does not exist
+             pass
+ 
+-- 
+2.13.6
+
diff --git a/SOURCES/0014-Backup-ipa-custodia-conf-and-keys.patch b/SOURCES/0014-Backup-ipa-custodia-conf-and-keys.patch
new file mode 100644
index 0000000..fb72527
--- /dev/null
+++ b/SOURCES/0014-Backup-ipa-custodia-conf-and-keys.patch
@@ -0,0 +1,154 @@
+From 0e1b5a65ed06b2213deebb0ea1e5fb8422223426 Mon Sep 17 00:00:00 2001
+From: Christian Heimes <cheimes@redhat.com>
+Date: Wed, 8 Nov 2017 15:15:30 +0100
+Subject: [PATCH] Backup ipa-custodia conf and keys
+
+https://pagure.io/freeipa/issue/7247
+
+Signed-off-by: Christian Heimes <cheimes@redhat.com>
+Reviewed-By: Simo Sorce <ssorce@redhat.com>
+---
+ install/share/custodia.conf.template    |  2 +-
+ ipaplatform/base/paths.py               |  1 +
+ ipapython/ipautil.py                    | 19 +++++++++++++++++++
+ ipaserver/install/custodiainstance.py   | 24 +++++++++++++-----------
+ ipaserver/install/ipa_backup.py         |  2 ++
+ ipatests/test_ipapython/test_ipautil.py |  7 +++++++
+ 6 files changed, 43 insertions(+), 12 deletions(-)
+
+diff --git a/install/share/custodia.conf.template b/install/share/custodia.conf.template
+index 855a1b3ba206e4ded8de80758b02473040096c7f..ee3c43ca7ec265aa09d250426bf4138bcfdf62b6 100644
+--- a/install/share/custodia.conf.template
++++ b/install/share/custodia.conf.template
+@@ -16,7 +16,7 @@ header = GSS_NAME
+ handler = ipaserver.secrets.kem.IPAKEMKeys
+ paths = /keys
+ store = ipa
+-server_keys = $IPA_CUSTODIA_CONF_DIR/server.keys
++server_keys = $IPA_CUSTODIA_KEYS
+ 
+ [store:ipa]
+ handler = ipaserver.secrets.store.IPASecStore
+diff --git a/ipaplatform/base/paths.py b/ipaplatform/base/paths.py
+index 804fddee60f787e161947bbe4b1914995257ceb4..42240a71066599ca8b36d10a9e5b23625f868977 100644
+--- a/ipaplatform/base/paths.py
++++ b/ipaplatform/base/paths.py
+@@ -349,6 +349,7 @@ class BasePathNamespace(object):
+     NETWORK_MANAGER_CONFIG_DIR = '/etc/NetworkManager/conf.d'
+     IPA_CUSTODIA_CONF_DIR = '/etc/ipa/custodia'
+     IPA_CUSTODIA_CONF = '/etc/ipa/custodia/custodia.conf'
++    IPA_CUSTODIA_KEYS = '/etc/ipa/custodia/server.keys'
+     IPA_CUSTODIA_SOCKET = '/run/httpd/ipa-custodia.sock'
+     IPA_CUSTODIA_AUDIT_LOG = '/var/log/ipa-custodia.audit.log'
+     IPA_GETKEYTAB = '/usr/sbin/ipa-getkeytab'
+diff --git a/ipapython/ipautil.py b/ipapython/ipautil.py
+index cc52af6d9235cfbd597679231f63667b81a200b4..426b32ef05ab00dcbf37b1e58b6390accee33cb1 100644
+--- a/ipapython/ipautil.py
++++ b/ipapython/ipautil.py
+@@ -307,6 +307,25 @@ def write_tmp_file(txt):
+ 
+     return fd
+ 
++
++def flush_sync(f):
++    """Flush and fsync file to disk
++
++    :param f: a file object with fileno and name
++    """
++    # flush file buffer to file descriptor
++    f.flush()
++    # flush Kernel buffer to disk
++    os.fsync(f.fileno())
++    # sync metadata in directory
++    dirname = os.path.dirname(os.path.abspath(f.name))
++    dirfd = os.open(dirname, os.O_RDONLY | os.O_DIRECTORY)
++    try:
++        os.fsync(dirfd)
++    finally:
++        os.close(dirfd)
++
++
+ def shell_quote(string):
+     if isinstance(string, str):
+         return "'" + string.replace("'", "'\\''") + "'"
+diff --git a/ipaserver/install/custodiainstance.py b/ipaserver/install/custodiainstance.py
+index bc3cea7063dff183c85b4f6e8ced7567f691001d..0a90bb3954486b9773e3553e9981d2a8d0d4e44a 100644
+--- a/ipaserver/install/custodiainstance.py
++++ b/ipaserver/install/custodiainstance.py
+@@ -25,8 +25,7 @@ class CustodiaInstance(SimpleServiceInstance):
+     def __init__(self, host_name=None, realm=None):
+         super(CustodiaInstance, self).__init__("ipa-custodia")
+         self.config_file = paths.IPA_CUSTODIA_CONF
+-        self.server_keys = os.path.join(paths.IPA_CUSTODIA_CONF_DIR,
+-                                        'server.keys')
++        self.server_keys = paths.IPA_CUSTODIA_KEYS
+         self.ldap_uri = None
+         self.fqdn = host_name
+         self.realm = realm
+@@ -35,16 +34,19 @@ class CustodiaInstance(SimpleServiceInstance):
+         template_file = os.path.basename(self.config_file) + '.template'
+         template = os.path.join(paths.USR_SHARE_IPA_DIR, template_file)
+         httpd_info = pwd.getpwnam(constants.HTTPD_USER)
+-        sub_dict = dict(IPA_CUSTODIA_CONF_DIR=paths.IPA_CUSTODIA_CONF_DIR,
+-                        IPA_CUSTODIA_SOCKET=paths.IPA_CUSTODIA_SOCKET,
+-                        IPA_CUSTODIA_AUDIT_LOG=paths.IPA_CUSTODIA_AUDIT_LOG,
+-                        LDAP_URI=installutils.realm_to_ldapi_uri(self.realm),
+-                        UID=httpd_info.pw_uid, GID=httpd_info.pw_gid)
++        sub_dict = dict(
++            IPA_CUSTODIA_CONF_DIR=paths.IPA_CUSTODIA_CONF_DIR,
++            IPA_CUSTODIA_KEYS=paths.IPA_CUSTODIA_KEYS,
++            IPA_CUSTODIA_SOCKET=paths.IPA_CUSTODIA_SOCKET,
++            IPA_CUSTODIA_AUDIT_LOG=paths.IPA_CUSTODIA_AUDIT_LOG,
++            LDAP_URI=installutils.realm_to_ldapi_uri(self.realm),
++            UID=httpd_info.pw_uid,
++            GID=httpd_info.pw_gid
++        )
+         conf = ipautil.template_file(template, sub_dict)
+-        fd = open(self.config_file, "w+")
+-        fd.write(conf)
+-        fd.flush()
+-        fd.close()
++        with open(self.config_file, "w") as f:
++            f.write(conf)
++            ipautil.flush_sync(f)
+ 
+     def create_instance(self):
+         suffix = ipautil.realm_to_suffix(self.realm)
+diff --git a/ipaserver/install/ipa_backup.py b/ipaserver/install/ipa_backup.py
+index f8cdd56d26636678279ba5afb423c5eef10c33d0..93b154330d3e6c8700c98860eb0c08f6841774bb 100644
+--- a/ipaserver/install/ipa_backup.py
++++ b/ipaserver/install/ipa_backup.py
+@@ -181,6 +181,8 @@ class Backup(admintool.AdminTool):
+         paths.DNSSEC_SOFTHSM_PIN_SO,
+         paths.IPA_ODS_EXPORTER_KEYTAB,
+         paths.IPA_DNSKEYSYNCD_KEYTAB,
++        paths.IPA_CUSTODIA_KEYS,
++        paths.IPA_CUSTODIA_CONF,
+         paths.HOSTS,
+     ) + tuple(
+         os.path.join(paths.IPA_NSSDB_DIR, file)
+diff --git a/ipatests/test_ipapython/test_ipautil.py b/ipatests/test_ipapython/test_ipautil.py
+index 9c351bd0ed9cd96488ac74deadf97996668a75d2..5e1f58003e9f3cae2f0819ecc348ade2c367548b 100644
+--- a/ipatests/test_ipapython/test_ipautil.py
++++ b/ipatests/test_ipapython/test_ipautil.py
+@@ -25,6 +25,7 @@ Test the `ipapython/ipautil.py` module.
+ import nose
+ import pytest
+ import six
++import tempfile
+ 
+ from ipapython import ipautil
+ 
+@@ -478,3 +479,9 @@ def test_backcompat():
+     assert rc is result.returncode
+     assert out is result.output
+     assert err is result.error_output
++
++
++def test_flush_sync():
++    with tempfile.NamedTemporaryFile('wb+') as f:
++        f.write(b'data')
++        ipautil.flush_sync(f)
+-- 
+2.13.6
+
diff --git a/SOURCES/0014-WebUI-check-principals-in-lowercase.patch b/SOURCES/0014-WebUI-check-principals-in-lowercase.patch
deleted file mode 100644
index ebaff11..0000000
--- a/SOURCES/0014-WebUI-check-principals-in-lowercase.patch
+++ /dev/null
@@ -1,36 +0,0 @@
-From 4ffc29d45ff1121f76b39ac7acaee824b4d04aaf Mon Sep 17 00:00:00 2001
-From: Pavel Vomacka <pvomacka@redhat.com>
-Date: Wed, 22 Mar 2017 16:39:21 +0100
-Subject: [PATCH] WebUI: check principals in lowercase
-
-WebUI checks whether principal name of logged user and principal name
-in each command is equal. As KDC for our principals is case insensitive
-- it does make sense to switch this check also into case insensitive.
-So both principals are reformated to lower case and then
-compared.
-
-Part of: https://pagure.io/freeipa/issue/3242
-
-Reviewed-By: Petr Vobornik <pvoborni@redhat.com>
-Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
----
- install/ui/src/freeipa/rpc.js | 3 ++-
- 1 file changed, 2 insertions(+), 1 deletion(-)
-
-diff --git a/install/ui/src/freeipa/rpc.js b/install/ui/src/freeipa/rpc.js
-index 7ae1b64291a4530137e0fb8d72ff5a8491cb10b4..1880f8d5732f982c25924b787b273c9e56636b20 100644
---- a/install/ui/src/freeipa/rpc.js
-+++ b/install/ui/src/freeipa/rpc.js
-@@ -389,7 +389,8 @@ rpc.command = function(spec) {
-             } else if (IPA.version && data.version && IPA.version !== data.version) {
-                 window.location.reload();
- 
--            } else if (IPA.principal && data.principal && IPA.principal !== data.principal) {
-+            } else if (IPA.principal && data.principal &&
-+                IPA.principal.toLowerCase() !== data.principal.toLowerCase()) {
-                 window.location.reload();
- 
-             } else if (data.error) {
--- 
-2.12.1
-
diff --git a/SOURCES/0015-WebUI-add-method-for-disabling-item-in-user-dropdown.patch b/SOURCES/0015-WebUI-add-method-for-disabling-item-in-user-dropdown.patch
deleted file mode 100644
index e8389c4..0000000
--- a/SOURCES/0015-WebUI-add-method-for-disabling-item-in-user-dropdown.patch
+++ /dev/null
@@ -1,105 +0,0 @@
-From 894fdd8c10552ef0b90363db985bb25e398d99e1 Mon Sep 17 00:00:00 2001
-From: Pavel Vomacka <pvomacka@redhat.com>
-Date: Wed, 22 Mar 2017 16:48:36 +0100
-Subject: [PATCH] WebUI: add method for disabling item in user dropdown menu
-
-AD user can do only several things. One of those which are not
-allowed is to reset password to itself. Therefore we need to be
-able to turn of a item in dropdown menu. In our case
-'Password reset' item. Function which disable menu item and detach
-the listener on click from the item specified by its name was added.
-
-Part of: https://pagure.io/freeipa/issue/3242
-
-Reviewed-By: Petr Vobornik <pvoborni@redhat.com>
-Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
----
- install/ui/src/freeipa/Application_controller.js | 42 ++++++++++++++++++++----
- install/ui/src/freeipa/widgets/App.js            |  4 +++
- 2 files changed, 40 insertions(+), 6 deletions(-)
-
-diff --git a/install/ui/src/freeipa/Application_controller.js b/install/ui/src/freeipa/Application_controller.js
-index 32add5f8f3d6874c1c555bf28d2b70cd54af5956..d809c1f2662609e390609270ef3ddc42f0727936 100644
---- a/install/ui/src/freeipa/Application_controller.js
-+++ b/install/ui/src/freeipa/Application_controller.js
-@@ -69,6 +69,16 @@ define([
-         facet_changing: false,
- 
-         /**
-+         * Listeners for user menu items
-+         */
-+         on_profile_listener: null,
-+         on_passwd_reset_listener: null,
-+         on_logout_listener: null,
-+         on_item_select_listener: null,
-+         on_configuration_listerer: null,
-+         on_about_listener: null,
-+
-+        /**
-          * Currently displayed facet
-          *
-          */
-@@ -109,12 +119,7 @@ define([
-                 }
-             };
- 
--            on(this.app_widget.menu_widget, 'item-select', this.on_menu_click.bind(this));
--            on(this.app_widget, 'profile-click', this.on_profile.bind(this));
--            on(this.app_widget, 'logout-click', this.on_logout.bind(this));
--            on(this.app_widget, 'password-reset-click', this.on_password_reset.bind(this));
--            on(this.app_widget, 'configuration-click', this.on_configuration.bind(this));
--            on(this.app_widget, 'about-click', this.on_about.bind(this));
-+            this.register_user_menu_listeners();
- 
-             on(this.router, 'facet-show', this.on_facet_show.bind(this));
-             on(this.router, 'facet-change', this.on_facet_change.bind(this));
-@@ -133,6 +138,31 @@ define([
-             IPA.opened_dialogs.start_handling(this);
-         },
- 
-+        register_user_menu_listeners: function() {
-+            this.on_profile_listener = on(this.app_widget, 'profile-click',
-+                    this.on_profile.bind(this));
-+            this.on_passwd_reset_listener = on(this.app_widget,
-+                    'password-reset-click', this.on_password_reset.bind(this));
-+            this.on_logout_listener = on(this.app_widget, 'logout-click',
-+                    this.on_logout.bind(this));
-+            this.on_item_select_listener = on(this.app_widget.menu_widget,
-+                    'item-select', this.on_menu_click.bind(this));
-+            this.on_configuration_listerer = on(this.app_widget,
-+                    'configuration-click', this.on_configuration.bind(this));
-+            this.on_about_listener = on(this.app_widget,
-+                    'about-click', this.on_about.bind(this));
-+        },
-+
-+        /**
-+         * Turns off one item in user dropdown menu and remove its listener.
-+         * @param {string} name of the user menu item which should be disabled
-+         * @param {Object} listener disable this listener
-+         */
-+        disable_user_menu_item: function(name, listener) {
-+            this.app_widget.disable_user_menu_item(name);
-+            listener.remove();
-+        },
-+
-         /**
-          * Gets:
-          *  * metadata
-diff --git a/install/ui/src/freeipa/widgets/App.js b/install/ui/src/freeipa/widgets/App.js
-index 68b78c7c4be44f5a1f658fed6b6b75d1beda22c5..95bc9b2cf3bcf40cd3a4cab47e9043e05331e019 100644
---- a/install/ui/src/freeipa/widgets/App.js
-+++ b/install/ui/src/freeipa/widgets/App.js
-@@ -222,6 +222,10 @@ define(['dojo/_base/declare',
-             }
-         },
- 
-+        disable_user_menu_item: function(name) {
-+            this.user_menu.disable_item(name);
-+        },
-+
-         on_menu_item_click: function(item) {
-             this.collapse_menu();
-         },
--- 
-2.12.1
-
diff --git a/SOURCES/0015-adtrust-filter-out-subdomains-when-defining-our-topo.patch b/SOURCES/0015-adtrust-filter-out-subdomains-when-defining-our-topo.patch
new file mode 100644
index 0000000..8e7bbe8
--- /dev/null
+++ b/SOURCES/0015-adtrust-filter-out-subdomains-when-defining-our-topo.patch
@@ -0,0 +1,66 @@
+From efdbea05f716700d8ed659430a6b501b41de0e54 Mon Sep 17 00:00:00 2001
+From: Alexander Bokovoy <abokovoy@redhat.com>
+Date: Thu, 19 Oct 2017 13:21:05 +0300
+Subject: [PATCH] adtrust: filter out subdomains when defining our topology to
+ AD
+
+When definining a topology of a forest to be visible over a cross-forest
+trust, we set *.<forest name> as all-catch top level name already.
+
+This means that all DNS subdomains of the forest will already be matched
+by this top level name (TLN). If we add more TLNs for subdomains, Active
+Directory will respond with NT_STATUS_INVALID_PARAMETER.
+
+Filter out all subdomains of the forest root domain. All other realm
+domains will be added with explicit TLN records.
+
+Also filter out single label domains. These aren't possible to add as
+TLNs to Windows Server 2016 as it considers them incorrect. Given that
+we do not allow single lable domains as part of freeIPA installs, this
+is another layer of protection here.
+
+Fixes https://pagure.io/freeipa/issue/6666
+
+Reviewed-By: Christian Heimes <cheimes@redhat.com>
+---
+ ipaserver/dcerpc.py | 16 ++++++++++++++++
+ 1 file changed, 16 insertions(+)
+
+diff --git a/ipaserver/dcerpc.py b/ipaserver/dcerpc.py
+index d684a17cabe43bbbd43d29f75f534b6e50fccd12..aa63cd9db0a1d47b5309cc6bed2ff7584760a39d 100644
+--- a/ipaserver/dcerpc.py
++++ b/ipaserver/dcerpc.py
+@@ -50,6 +50,7 @@ import samba
+ 
+ import ldap as _ldap
+ from ipapython import ipaldap
++from ipapython.dnsutil import DNSName
+ from dns import resolver, rdatatype
+ from dns.exception import DNSException
+ import pysss_nss_idmap
+@@ -1589,7 +1590,22 @@ class TrustDomainJoins(object):
+                      entry.single_value.get('modifytimestamp').timetuple()
+                 )*1e7+116444736000000000)
+ 
++        forest = DNSName(self.local_domain.info['dns_forest'])
++        # tforest is IPA forest. keep the line below for future checks
++        # tforest = DNSName(self.remote_domain.info['dns_forest'])
+         for dom in realm_domains['associateddomain']:
++            d = DNSName(dom)
++
++            # We should skip all DNS subdomains of our forest
++            # because we are going to add *.<forest> TLN anyway
++            if forest.is_superdomain(d) and forest != d:
++                continue
++
++            # We also should skip single label TLDs as they
++            # cannot be added as TLNs
++            if len(d.labels) == 1:
++                continue
++
+             ftinfo = dict()
+             ftinfo['rec_name'] = dom
+             ftinfo['rec_time'] = trust_timestamp
+-- 
+2.13.6
+
diff --git a/SOURCES/0016-Fix-ca-less-IPA-install-on-fips-mode.patch b/SOURCES/0016-Fix-ca-less-IPA-install-on-fips-mode.patch
new file mode 100644
index 0000000..1f8d3dc
--- /dev/null
+++ b/SOURCES/0016-Fix-ca-less-IPA-install-on-fips-mode.patch
@@ -0,0 +1,45 @@
+From 8f35c1c705a7584cdcc9ad5c6fb15ba940ec3f4a Mon Sep 17 00:00:00 2001
+From: Florence Blanc-Renaud <flo@redhat.com>
+Date: Thu, 23 Nov 2017 18:06:56 +0100
+Subject: [PATCH] Fix ca less IPA install on fips mode
+
+When ipa-server-install is run in fips mode and ca-less, the installer
+fails when the keys are provided with --{http|dirsrv|pkinit}-cert-file
+in a separate key file.
+
+The installer transforms the key into PKCS#8 format using
+openssl pkcs8 -topk8
+but this command fails on a fips-enabled server, unless the options
+-v2 aes256 -v2prf hmacWithSHA256
+are also provided.
+
+Fixes:
+https://pagure.io/freeipa/issue/7280
+
+Reviewed-By: Christian Heimes <cheimes@redhat.com>
+Reviewed-By: Christian Heimes <cheimes@redhat.com>
+---
+ ipapython/certdb.py | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/ipapython/certdb.py b/ipapython/certdb.py
+index 114c58340253141706afa461ecaf87797562ca1d..f198811e0fd02c8925f0dcfa8764535b35ed29ed 100644
+--- a/ipapython/certdb.py
++++ b/ipapython/certdb.py
+@@ -499,9 +499,13 @@ class NSSDatabase(object):
+                                 "Can't load private key from both %s and %s" %
+                                 (key_file, filename))
+ 
++                        # the args -v2 aes256 -v2prf hmacWithSHA256 are needed
++                        # on OpenSSL 1.0.2 (fips mode). As soon as FreeIPA
++                        # requires OpenSSL 1.1.0 we'll be able to drop them
+                         args = [
+                             OPENSSL, 'pkcs8',
+                             '-topk8',
++                            '-v2', 'aes256', '-v2prf', 'hmacWithSHA256',
+                             '-passout', 'file:' + self.pwd_file,
+                         ]
+                         if ((label != 'PRIVATE KEY' and key_password) or
+-- 
+2.13.6
+
diff --git a/SOURCES/0016-WebUI-Add-support-for-login-for-AD-users.patch b/SOURCES/0016-WebUI-Add-support-for-login-for-AD-users.patch
deleted file mode 100644
index 4912fd1..0000000
--- a/SOURCES/0016-WebUI-Add-support-for-login-for-AD-users.patch
+++ /dev/null
@@ -1,341 +0,0 @@
-From 18e9bc2399af788399e66c3f4b28e6a7f0378b78 Mon Sep 17 00:00:00 2001
-From: Pavel Vomacka <pvomacka@redhat.com>
-Date: Wed, 22 Mar 2017 16:54:33 +0100
-Subject: [PATCH] WebUI: Add support for login for AD users
-
-After login, method user-find --whoami was called which cannot be
-called for AD users. That method was replaced by ipa whoami command
-and sequential command according to result of ipa whoami. AD user
-can now be logged in.
-
-AD users have new menu definition which contains only list of IPA
-users and profile page of AD user - "User ID Override".
-
-This commit also fixes several places where IPA.whoami object was
-used, because its structure was also changed. It now contains two
-objects. First one is stored in 'metadata' property and stores
-result from ipa whoami (type of object, command which should be
-called for showing detailed data about currently logged entity, etc).
-The second one is stored in 'data' property which stores result of
-_show command for currently logged entity.
-
-https://pagure.io/freeipa/issue/3242
-
-Reviewed-By: Petr Vobornik <pvoborni@redhat.com>
-Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
----
- install/ui/src/freeipa/Application_controller.js | 52 +++++++++++++++++++-----
- install/ui/src/freeipa/idviews.js                | 21 +++++++++-
- install/ui/src/freeipa/ipa.js                    | 47 +++++++++++++--------
- install/ui/src/freeipa/navigation/menu_spec.js   | 10 +++++
- install/ui/src/freeipa/otptoken.js               |  2 +-
- install/ui/src/freeipa/user.js                   |  5 ++-
- ipaserver/plugins/internal.py                    |  1 +
- 7 files changed, 108 insertions(+), 30 deletions(-)
-
-diff --git a/install/ui/src/freeipa/Application_controller.js b/install/ui/src/freeipa/Application_controller.js
-index d809c1f2662609e390609270ef3ddc42f0727936..5eb4e7a5104b780761b9a5179dbfd1501a8d1478 100644
---- a/install/ui/src/freeipa/Application_controller.js
-+++ b/install/ui/src/freeipa/Application_controller.js
-@@ -31,6 +31,7 @@ define([
-         './widgets/App',
-         './widgets/FacetContainer',
-         './ipa',
-+        './rpc',
-         './reg',
-         './config',
-         './widget',
-@@ -41,7 +42,7 @@ define([
-         './plugins/load_page'
-        ],
-        function(declare, array, Deferred, on, topic, query, dom_class, auth,
--            JSON, App_widget, FacetContainer, IPA, reg, config, widget_mod,
-+            JSON, App_widget, FacetContainer, IPA, rpc, reg, config, widget_mod,
-             Menu, Router, routing, menu_spec) {
- 
-     /**
-@@ -156,7 +157,7 @@ define([
-         /**
-          * Turns off one item in user dropdown menu and remove its listener.
-          * @param {string} name of the user menu item which should be disabled
--         * @param {Object} listener disable this listener
-+         * @param {Object} listener disable di
-          */
-         disable_user_menu_item: function(name, listener) {
-             this.app_widget.disable_user_menu_item(name);
-@@ -179,16 +180,22 @@ define([
-          */
-         choose_profile: function() {
- 
--            // TODO: change IPA.whoami.cn[0] to something readable
--            this.update_logged_in(true, IPA.whoami.cn[0]);
-+            this.update_logged_in(true);
-             var selfservice = this.is_selfservice();
- 
- 
-             this.app_widget.menu_widget.ignore_changes = true;
- 
-             if (selfservice) {
--                this.menu.name = menu_spec.self_service.name;
--                this.menu.add_items(menu_spec.self_service.items);
-+                if (this.is_aduser_selfservice()) {
-+                    this.menu.name = menu_spec.ad_self_service.name;
-+                    this.menu.add_items(menu_spec.ad_self_service.items);
-+                    this.disable_user_menu_item('password_reset',
-+                            this.on_passwd_reset_listener);
-+                } else {
-+                    this.menu.name = menu_spec.self_service.name;
-+                    this.menu.add_items(menu_spec.self_service.items);
-+                }
-             } else {
-                 this.menu.name = menu_spec.admin.name;
-                 this.menu.add_items(menu_spec.admin.items);
-@@ -232,10 +239,9 @@ define([
-         },
- 
-         is_selfservice: function() {
--            var whoami = IPA.whoami;
-+            var whoami = IPA.whoami.data;
-             var self_service = true;
- 
--
-             if (whoami.hasOwnProperty('memberof_group') &&
-                 whoami.memberof_group.indexOf('admins') !== -1) {
-                 self_service = false;
-@@ -255,13 +261,39 @@ define([
-             return self_service;
-         },
- 
--        update_logged_in: function(logged_in, fullname) {
-+        is_aduser_selfservice: function() {
-+            var selfservice = IPA.whoami.metadata.object === 'idoverrideuser';
-+            // quite ugly, needed for users and iduseroverride to hide breadcrumb
-+            IPA.is_aduser_selfservice = selfservice;
-+
-+            return selfservice;
-+        },
-+
-+        update_logged_in: function(logged_in) {
-             this.app_widget.set('logged', logged_in);
-+
-+            var whoami = IPA.whoami;
-+            var fullname = '';
-+            var entity = whoami.metadata.object;
-+
-+            if (whoami.data.cn) {
-+                fullname = whoami.data.cn[0];
-+            } else if (whoami.data.displayname) {
-+                fullname = whoami.data.displayname[0];
-+            } else if (whoami.data.gecos) {
-+                fullname = whoami.data.gecos[0];
-+            } else if (whoami.data.krbprincipalname) {
-+                fullname = whoami.data.krbprincipalname[0];
-+            } else if (whoami.data.ipaoriginaluid) {
-+                fullname = whoami.data.ipaoriginaluid[0];
-+            }
-+
-             this.app_widget.set('fullname', fullname);
-         },
- 
-         on_profile: function() {
--            routing.navigate(['entity', 'user', 'details', [IPA.whoami.uid[0]]]);
-+            routing.navigate(['entity', IPA.whoami.metadata.object, 'details',
-+                 IPA.whoami.metadata.arguments]);
-         },
- 
-         on_logout: function(event) {
-diff --git a/install/ui/src/freeipa/idviews.js b/install/ui/src/freeipa/idviews.js
-index f383ab3be4c4ed997fb209da2da4d04835236d8a..d9133a13c2ed8970e7919bb28d06f818d832170a 100644
---- a/install/ui/src/freeipa/idviews.js
-+++ b/install/ui/src/freeipa/idviews.js
-@@ -452,6 +452,21 @@ idviews.id_override_user_details_facet = function(spec) {
-     return that;
- };
- 
-+
-+idviews.aduser_idoverrideuser_pre_op = function(spec, context) {
-+    spec = spec || [];
-+
-+    if (!IPA.is_aduser_selfservice) return spec;
-+
-+    var facet = spec.facets[0];
-+    facet.label = '@i18n:objects.idoverrideuser.profile';
-+    facet.actions = [];
-+    facet.header_actions = [];
-+    facet.disable_breadcrumb = true;
-+
-+    return spec;
-+};
-+
- /**
-  * @extends IPA.cert.certs_widget
-  */
-@@ -948,7 +963,11 @@ idviews.register = function() {
-     var w = reg.widget;
- 
-     e.register({type: 'idview', spec: idviews.spec});
--    e.register({type: 'idoverrideuser', spec: idviews.idoverrideuser_spec});
-+    e.register({
-+        type: 'idoverrideuser',
-+        spec: idviews.idoverrideuser_spec,
-+        pre_ops: [idviews.aduser_idoverrideuser_pre_op]
-+    });
-     e.register({type: 'idoverridegroup', spec: idviews.idoverridegroup_spec});
-     f.copy('attribute', 'idview_appliedtohosts', {
-         factory: idviews.appliedtohosts_facet
-diff --git a/install/ui/src/freeipa/ipa.js b/install/ui/src/freeipa/ipa.js
-index 0ddbd0744d699cacddb3970e5ec7cb72b9dbf4f4..2538001c94141b823d634ca63327a66fd148129f 100644
---- a/install/ui/src/freeipa/ipa.js
-+++ b/install/ui/src/freeipa/ipa.js
-@@ -86,7 +86,8 @@ var IPA = function () {
-     /**
-      * User information
-      *
--     * - output of ipa user-find --whoami
-+     * - output of ipa whoami in that.whoami.metadata and then object_show method
-+     * in that.whoami.data
-      */
-     that.whoami = {};
- 
-@@ -263,19 +264,33 @@ var IPA = function () {
-      */
-     that.get_whoami_command = function(batch) {
-         return rpc.command({
--            entity: 'user',
--            method: 'find',
--            options: {
--                whoami: true,
--                all: true
--            },
-+            method: 'whoami',
-             on_success: function(data, text_status, xhr) {
--                that.whoami = batch ? data.result[0] : data.result.result[0];
--                var cn = that.whoami.krbcanonicalname;
--                if (cn) that.principal = cn[0];
--                if (!that.principal) {
--                    that.principal = that.whoami.krbprincipalname[0];
--                }
-+                that.whoami.metadata = data;
-+
-+                rpc.command({
-+                    method: data.details || data.command,
-+                    args: data.arguments,
-+                    options: function() {
-+                        var options = data.options || [];
-+                        $.extend(options, {all: true});
-+                        return options;
-+                    }(),
-+                    on_success: function(data, text_status, xhr) {
-+                        that.whoami.data = false ? data.result[0] : data.result.result;
-+                        var entity = that.whoami.metadata.object;
-+
-+                        if (entity === 'user') {
-+                            var cn = that.whoami.data.krbcanonicalname;
-+                            if (cn) that.principal = cn[0];
-+                            if (!that.principal) {
-+                                that.principal = that.whoami.data.krbprincipalname[0];
-+                            }
-+                        } else if (entity === 'idoverrideuser') {
-+                            that.principal = that.whoami.data.ipaoriginaluid[0];
-+                        }
-+                    }
-+                }).execute();
-             }
-         });
-     };
-@@ -616,7 +631,7 @@ IPA.update_password_expiration = function() {
- 
-     var now, expires, notify_days, diff, message, container, notify;
- 
--    expires = rpc.extract_objects(IPA.whoami.krbpasswordexpiration);
-+    expires = rpc.extract_objects(IPA.whoami.data.krbpasswordexpiration);
-     expires = expires ? datetime.parse(expires[0]) : null;
- 
-     notify_days = IPA.server_config.ipapwdexpadvnotify;
-@@ -650,13 +665,13 @@ IPA.update_password_expiration = function() {
- IPA.password_selfservice = function() {
-     var reset_dialog = builder.build('dialog', {
-         $type: 'user_password',
--        args: [IPA.whoami.uid[0]]
-+        args: [IPA.whoami.data.uid[0]]
-     });
-     reset_dialog.succeeded.attach(function() {
-         var command = IPA.get_whoami_command();
-         var orig_on_success = command.on_success;
-         command.on_success = function(data, text_status, xhr) {
--            orig_on_success.call(this, data, text_status, xhr);
-+            orig_on_success.call(this, data.result, text_status, xhr);
-             IPA.update_password_expiration();
-         };
-         command.execute();
-diff --git a/install/ui/src/freeipa/navigation/menu_spec.js b/install/ui/src/freeipa/navigation/menu_spec.js
-index 4f78e4bf9ba25bf2f7585e38086b1cbc6db34026..9329694c14a47cbe1ec244554327b40743044d7b 100644
---- a/install/ui/src/freeipa/navigation/menu_spec.js
-+++ b/install/ui/src/freeipa/navigation/menu_spec.js
-@@ -353,5 +353,15 @@ nav.self_service = {
-     ]
- };
- 
-+nav.ad_self_service = {
-+    name: 'ad_self_service',
-+    items: [
-+        {
-+            entity: 'idoverrideuser',
-+            label: 'Profile'
-+        }
-+    ]
-+};
-+
- return nav;
- });
-diff --git a/install/ui/src/freeipa/otptoken.js b/install/ui/src/freeipa/otptoken.js
-index caa7a85523d6e63db629a3a518e8611d511f7952..1f6f20d801042a5424ecf5894658df9411723bcc 100644
---- a/install/ui/src/freeipa/otptoken.js
-+++ b/install/ui/src/freeipa/otptoken.js
-@@ -361,7 +361,7 @@ otptoken.adder_dialog = function(spec) {
- 
-         var command = that.entity_adder_dialog_create_add_command(record);
-         if (that.self_service) {
--            command.set_option('ipatokenowner', IPA.whoami.uid[0]);
-+            command.set_option('ipatokenowner', IPA.whoami.data.uid[0]);
-         }
-         return command;
-     };
-diff --git a/install/ui/src/freeipa/user.js b/install/ui/src/freeipa/user.js
-index 4bb04488b51dd43a437ab3759eb3f530afe62550..6b2bf196c31e7891d3389eb2e2774f56d88ac2ba 100644
---- a/install/ui/src/freeipa/user.js
-+++ b/install/ui/src/freeipa/user.js
-@@ -735,7 +735,7 @@ IPA.user.password_dialog = function(spec) {
-     var that = dialogs.command_dialog(spec);
- 
-     that.is_self_service = function() {
--        var self_service = that.args[0] === IPA.whoami.uid[0];
-+        var self_service = that.args[0] === IPA.whoami.data.uid[0];
-         return self_service;
-     };
- 
-@@ -895,7 +895,8 @@ IPA.user.self_service_other_user_evaluator = function(spec) {
-         that.state = [];
- 
-         var value = that.adapter.load(data);
--        if (IPA.is_selfservice && IPA.whoami.uid[0] !== value[0]) {
-+        if (IPA.is_aduser_selfservice ||
-+            (IPA.is_selfservice && IPA.whoami.data.uid[0] !== value[0])) {
-             that.state.push('self-service-other');
-         }
- 
-diff --git a/ipaserver/plugins/internal.py b/ipaserver/plugins/internal.py
-index 9fa1b6de857cf7e21210f557befabff32da0d4ff..6feefa5941506f38f01b8016a22cad14a831e3fc 100644
---- a/ipaserver/plugins/internal.py
-+++ b/ipaserver/plugins/internal.py
-@@ -625,6 +625,7 @@ class i18n_messages(Command):
-                 "anchor_label": _("User to override"),
-                 "anchor_tooltip": _("Enter trusted or IPA user login. Note: search doesn't list users from trusted domains."),
-                 "anchor_tooltip_ad": _("Enter trusted user login."),
-+                "profile": _("Profile"),
-             },
-             "idoverridegroup": {
-                 "anchor_label": _("Group to override"),
--- 
-2.12.1
-
diff --git a/SOURCES/0017-cert-do-not-limit-internal-searches-in-cert-find.patch b/SOURCES/0017-cert-do-not-limit-internal-searches-in-cert-find.patch
deleted file mode 100644
index 7166516..0000000
--- a/SOURCES/0017-cert-do-not-limit-internal-searches-in-cert-find.patch
+++ /dev/null
@@ -1,105 +0,0 @@
-From ca26e32beb77fbd8fcc66e6eea07c6eeeb9261c9 Mon Sep 17 00:00:00 2001
-From: Jan Cholasta <jcholast@redhat.com>
-Date: Wed, 22 Mar 2017 06:58:25 +0000
-Subject: [PATCH] cert: do not limit internal searches in cert-find
-
-Instead, apply the limits on the combined result.
-
-This fixes (absence of) `--sizelimit` leading to strange behavior, such as
-`cert-find --users user` returning a non-empty result only with
-`--sizelimit 0`.
-
-https://pagure.io/freeipa/issue/6716
-
-Reviewed-By: Stanislav Laznicka <slaznick@redhat.com>
----
- ipaserver/plugins/cert.py | 28 ++++++++++------------------
- 1 file changed, 10 insertions(+), 18 deletions(-)
-
-diff --git a/ipaserver/plugins/cert.py b/ipaserver/plugins/cert.py
-index 9f901076075809592ad5ddeec8d71c273d4853c9..1a6d04533cebb2eb00022981dae9ffe5b785ba8b 100644
---- a/ipaserver/plugins/cert.py
-+++ b/ipaserver/plugins/cert.py
-@@ -1324,7 +1324,7 @@ class cert_find(Search, CertMethod):
- 
-         return result, False, True
- 
--    def _ca_search(self, all, raw, pkey_only, sizelimit, exactly, **options):
-+    def _ca_search(self, all, raw, pkey_only, exactly, **options):
-         ra_options = {}
-         for name in ('revocation_reason',
-                      'issuer',
-@@ -1343,10 +1343,6 @@ class cert_find(Search, CertMethod):
-             elif isinstance(value, DN):
-                 value = unicode(value)
-             ra_options[name] = value
--        if sizelimit > 0:
--            # Dogtag doesn't tell that the size limit was exceeded
--            # search for one more entry so that we can tell ourselves
--            ra_options['sizelimit'] = sizelimit + 1
-         if exactly:
-             ra_options['exactly'] = True
- 
-@@ -1369,11 +1365,6 @@ class cert_find(Search, CertMethod):
- 
-         ra = self.api.Backend.ra
-         for ra_obj in ra.find(ra_options):
--            if sizelimit > 0 and len(result) >= sizelimit:
--                self.add_message(messages.SearchResultTruncated(
--                        reason=errors.SizeLimitExceeded()))
--                break
--
-             issuer = DN(ra_obj['issuer'])
-             serial_number = ra_obj['serial_number']
- 
-@@ -1411,8 +1402,7 @@ class cert_find(Search, CertMethod):
- 
-         return result, False, complete
- 
--    def _ldap_search(self, all, raw, pkey_only, no_members, timelimit,
--                     sizelimit, **options):
-+    def _ldap_search(self, all, raw, pkey_only, no_members, **options):
-         ldap = self.api.Backend.ldap2
- 
-         filters = []
-@@ -1453,8 +1443,8 @@ class cert_find(Search, CertMethod):
-                 base_dn=self.api.env.basedn,
-                 filter=filter,
-                 attrs_list=['usercertificate'],
--                time_limit=timelimit,
--                size_limit=sizelimit,
-+                time_limit=0,
-+                size_limit=0,
-             )
-         except errors.EmptyResult:
-             entries = []
-@@ -1527,13 +1517,9 @@ class cert_find(Search, CertMethod):
-                 raw=raw,
-                 pkey_only=pkey_only,
-                 no_members=no_members,
--                timelimit=timelimit,
--                sizelimit=sizelimit,
-                 **options)
- 
-             if sub_complete:
--                sizelimit = 0
--
-                 for key in tuple(result):
-                     if key not in sub_result:
-                         del result[key]
-@@ -1552,6 +1538,12 @@ class cert_find(Search, CertMethod):
-             complete = complete or sub_complete
- 
-         result = list(six.itervalues(result))
-+        if sizelimit > 0 and len(result) > sizelimit:
-+            if not truncated:
-+                self.add_message(messages.SearchResultTruncated(
-+                        reason=errors.SizeLimitExceeded()))
-+            result = result[:sizelimit]
-+            truncated = True
- 
-         ret = dict(
-             result=result
--- 
-2.12.1
-
diff --git a/SOURCES/0017-trust-detect-and-error-out-when-non-AD-trust-with-IP.patch b/SOURCES/0017-trust-detect-and-error-out-when-non-AD-trust-with-IP.patch
new file mode 100644
index 0000000..8cf7475
--- /dev/null
+++ b/SOURCES/0017-trust-detect-and-error-out-when-non-AD-trust-with-IP.patch
@@ -0,0 +1,281 @@
+From a4e9e8f368c8a61d539e9da26e4a16a6234c138f Mon Sep 17 00:00:00 2001
+From: Alexander Bokovoy <abokovoy@redhat.com>
+Date: Fri, 17 Nov 2017 17:19:25 +0200
+Subject: [PATCH] trust: detect and error out when non-AD trust with IPA domain
+ name exists
+
+Quite often users choose wrong type of trust on Active Directory side
+when setting up a trust to freeIPA. The trust type supported by freeIPA
+is just a normal forest trust to another Active Directory. However,
+some people follow old internet recipes that force using a trust to MIT
+Kerberos realm.
+
+This is a wrong type of trust. Unfortunately, when someone used MIT
+Kerberos realm trust, there is no way to programmatically remote the
+trust from freeIPA side. As result, we have to detect such situation and
+report an error.
+
+To do proper reporting, we need reuse some constants and trust type
+names we use in IPA CLI/Web UI. These common components were moved to
+a separate ipaserver/dcerpc_common.py module that is imported by both
+ipaserver/plugins/trust.py and ipaserver/dcerpc.py.
+
+Fixes https://pagure.io/freeipa/issue/7264
+
+Reviewed-By: Christian Heimes <cheimes@redhat.com>
+Reviewed-By: Thierry Bordaz <tbordaz@redhat.com>
+---
+ ipaserver/dcerpc.py        | 37 +++++++++++++++--------
+ ipaserver/dcerpc_common.py | 73 ++++++++++++++++++++++++++++++++++++++++++++++
+ ipaserver/plugins/trust.py | 65 ++++++++++-------------------------------
+ 3 files changed, 113 insertions(+), 62 deletions(-)
+ create mode 100644 ipaserver/dcerpc_common.py
+
+diff --git a/ipaserver/dcerpc.py b/ipaserver/dcerpc.py
+index aa63cd9db0a1d47b5309cc6bed2ff7584760a39d..ac1b2a34784df491a3851aa21bbadbec2297241c 100644
+--- a/ipaserver/dcerpc.py
++++ b/ipaserver/dcerpc.py
+@@ -31,6 +31,10 @@ from ipapython import ipautil
+ from ipapython.ipa_log_manager import root_logger
+ from ipapython.dn import DN
+ from ipaserver.install import installutils
++from ipaserver.dcerpc_common import (TRUST_BIDIRECTIONAL,
++                                     TRUST_JOIN_EXTERNAL,
++                                     trust_type_string)
++
+ from ipalib.util import normalize_name
+ 
+ import os
+@@ -77,15 +81,6 @@ The code in this module relies heavily on samba4-python package
+ and Samba4 python bindings.
+ """)
+ 
+-# Both constants can be used as masks against trust direction
+-# because bi-directional has two lower bits set.
+-TRUST_ONEWAY = 1
+-TRUST_BIDIRECTIONAL = 3
+-
+-# Trust join behavior
+-# External trust -- allow creating trust to a non-root domain in the forest
+-TRUST_JOIN_EXTERNAL = 1
+-
+ 
+ def is_sid_valid(sid):
+     try:
+@@ -151,6 +146,7 @@ pysss_type_key_translation_dict = {
+     pysss_nss_idmap.ID_BOTH: 'both',
+ }
+ 
++
+ class TrustTopologyConflictSolved(Exception):
+     """
+     Internal trust error: raised when previously detected
+@@ -1254,9 +1250,26 @@ class TrustDomainInstance(object):
+             dname = lsa.String()
+             dname.string = another_domain.info['dns_domain']
+             res = self._pipe.QueryTrustedDomainInfoByName(
+-                                self._policy_handle,
+-                                dname,
+-                                lsa.LSA_TRUSTED_DOMAIN_INFO_FULL_INFO)
++                self._policy_handle,
++                dname,
++                lsa.LSA_TRUSTED_DOMAIN_INFO_FULL_INFO
++            )
++            if res.info_ex.trust_type != lsa.LSA_TRUST_TYPE_UPLEVEL:
++                msg = _('There is already a trust to {ipa_domain} with '
++                        'unsupported type {trust_type}. Please remove '
++                        'it manually on AD DC side.')
++                ttype = trust_type_string(
++                    res.info_ex.trust_type, res.info_ex.trust_attributes
++                )
++                err = unicode(msg).format(
++                    ipa_domain=another_domain.info['dns_domain'],
++                    trust_type=ttype)
++
++                raise errors.ValidationError(
++                    name=_('AD domain controller'),
++                    error=err
++                )
++
+             self._pipe.DeleteTrustedDomain(self._policy_handle,
+                                            res.info_ex.sid)
+         except RuntimeError as e:
+diff --git a/ipaserver/dcerpc_common.py b/ipaserver/dcerpc_common.py
+new file mode 100644
+index 0000000000000000000000000000000000000000..526b025e3282c8a556088eb2ed1ba467b889b86c
+--- /dev/null
++++ b/ipaserver/dcerpc_common.py
+@@ -0,0 +1,73 @@
++import six
++from ipalib import _
++if six.PY3:
++    unicode = six.text_type
++
++# Both constants can be used as masks against trust direction
++# because bi-directional has two lower bits set.
++TRUST_ONEWAY = 1
++TRUST_BIDIRECTIONAL = 3
++
++# Trust join behavior
++# External trust -- allow creating trust to a non-root domain in the forest
++TRUST_JOIN_EXTERNAL = 1
++
++# We don't want to import any of Samba Python code here just for constants
++# Since these constants set in MS-ADTS, we can rely on their stability
++LSA_TRUST_ATTRIBUTE_NON_TRANSITIVE = 0x00000001
++
++_trust_direction_dict = {
++        1: _('Trusting forest'),
++        2: _('Trusted forest'),
++        3: _('Two-way trust')
++}
++
++_trust_status_dict = {
++        True: _('Established and verified'),
++        False: _('Waiting for confirmation by remote side')
++}
++
++_trust_type_dict_unknown = _('Unknown')
++
++# Trust type is a combination of ipanttrusttype and ipanttrustattributes
++# We shift trust attributes by 3 bits to left so bit 0 becomes bit 3 and
++# 2+(1 << 3) becomes 10.
++_trust_type_dict = {
++        1: _('Non-Active Directory domain'),
++        2: _('Active Directory domain'),
++        3: _('RFC4120-compliant Kerberos realm'),
++        10: _('Non-transitive external trust to a domain in '
++              'another Active Directory forest'),
++        11: _('Non-transitive external trust to an RFC4120-'
++              'compliant Kerberos realm')
++}
++
++
++def trust_type_string(level, attrs):
++    """
++    Returns a string representing a type of the trust.
++    The original field is an enum:
++      LSA_TRUST_TYPE_DOWNLEVEL  = 0x00000001,
++      LSA_TRUST_TYPE_UPLEVEL    = 0x00000002,
++      LSA_TRUST_TYPE_MIT        = 0x00000003
++    """
++    transitive = int(attrs) & LSA_TRUST_ATTRIBUTE_NON_TRANSITIVE
++    string = _trust_type_dict.get(int(level) | (transitive << 3),
++                                  _trust_type_dict_unknown)
++    return unicode(string)
++
++
++def trust_direction_string(level):
++    """
++    Returns a string representing a direction of the trust.
++    The original field is a bitmask taking two bits in use
++      LSA_TRUST_DIRECTION_INBOUND  = 0x00000001,
++      LSA_TRUST_DIRECTION_OUTBOUND = 0x00000002
++    """
++    string = _trust_direction_dict.get(int(level), _trust_type_dict_unknown)
++    return unicode(string)
++
++
++def trust_status_string(level):
++    string = _trust_status_dict.get(level, _trust_type_dict_unknown)
++    return unicode(string)
+diff --git a/ipaserver/plugins/trust.py b/ipaserver/plugins/trust.py
+index d0bbfbc47ca65c9c5229685fc9d202c293fe41cd..ecc5fa0b22f94de05cc5282758be093f0cfca13f 100644
+--- a/ipaserver/plugins/trust.py
++++ b/ipaserver/plugins/trust.py
+@@ -44,6 +44,13 @@ from ipalib import errors
+ from ipalib import output
+ from ldap import SCOPE_SUBTREE
+ from time import sleep
++from ipaserver.dcerpc_common import (TRUST_ONEWAY,
++                                     TRUST_BIDIRECTIONAL,
++                                     TRUST_JOIN_EXTERNAL,
++                                     LSA_TRUST_ATTRIBUTE_NON_TRANSITIVE,
++                                     trust_type_string,
++                                     trust_direction_string,
++                                     trust_status_string)
+ 
+ if six.PY3:
+     unicode = str
+@@ -63,9 +70,6 @@ except Exception as e:
+ if api.env.in_server and api.env.context in ['lite', 'server']:
+     try:
+         import ipaserver.dcerpc
+-        from ipaserver.dcerpc import (TRUST_ONEWAY,
+-                                      TRUST_BIDIRECTIONAL,
+-                                      TRUST_JOIN_EXTERNAL)
+         import dbus
+         import dbus.mainloop.glib
+         _bindings_installed = True
+@@ -157,28 +161,14 @@ particular type.
+ 
+ register = Registry()
+ 
+-# Trust type is a combination of ipanttrusttype and ipanttrustattributes
+-# We shift trust attributes by 3 bits to left so bit 0 becomes bit 3 and
+-# 2+(1 << 3) becomes 10.
+-_trust_type_dict = {1 : _('Non-Active Directory domain'),
+-                    2 : _('Active Directory domain'),
+-                    3 : _('RFC4120-compliant Kerberos realm'),
+-                    10: _('Non-transitive external trust to a domain in another Active Directory forest')}
+-
+-_trust_direction_dict = {1 : _('Trusting forest'),
+-                         2 : _('Trusted forest'),
+-                         3 : _('Two-way trust')}
+-_trust_status_dict = {True : _('Established and verified'),
+-                 False : _('Waiting for confirmation by remote side')}
+-_trust_type_dict_unknown = _('Unknown')
+-
+-_trust_type_option = StrEnum('trust_type',
+-                        cli_name='type',
+-                        label=_('Trust type (ad for Active Directory, default)'),
+-                        values=(u'ad',),
+-                        default=u'ad',
+-                        autofill=True,
+-                    )
++_trust_type_option = StrEnum(
++         'trust_type',
++         cli_name='type',
++         label=_('Trust type (ad for Active Directory, default)'),
++         values=(u'ad',),
++         default=u'ad',
++         autofill=True,
++        )
+ 
+ DEFAULT_RANGE_SIZE = 200000
+ 
+@@ -187,31 +177,6 @@ DBUS_IFACE_TRUST = 'com.redhat.idm.trust'
+ CRED_STYLE_SAMBA = 1
+ CRED_STYLE_KERBEROS = 2
+ 
+-LSA_TRUST_ATTRIBUTE_NON_TRANSITIVE = 0x00000001
+-
+-def trust_type_string(level, attrs):
+-    """
+-    Returns a string representing a type of the trust. The original field is an enum:
+-      LSA_TRUST_TYPE_DOWNLEVEL  = 0x00000001,
+-      LSA_TRUST_TYPE_UPLEVEL    = 0x00000002,
+-      LSA_TRUST_TYPE_MIT        = 0x00000003
+-    """
+-    transitive = int(attrs) & LSA_TRUST_ATTRIBUTE_NON_TRANSITIVE
+-    string = _trust_type_dict.get(int(level) | (transitive << 3), _trust_type_dict_unknown)
+-    return unicode(string)
+-
+-def trust_direction_string(level):
+-    """
+-    Returns a string representing a direction of the trust. The original field is a bitmask taking two bits in use
+-      LSA_TRUST_DIRECTION_INBOUND  = 0x00000001,
+-      LSA_TRUST_DIRECTION_OUTBOUND = 0x00000002
+-    """
+-    string = _trust_direction_dict.get(int(level), _trust_type_dict_unknown)
+-    return unicode(string)
+-
+-def trust_status_string(level):
+-    string = _trust_status_dict.get(level, _trust_type_dict_unknown)
+-    return unicode(string)
+ 
+ def make_trust_dn(env, trust_type, dn):
+     assert isinstance(dn, DN)
+-- 
+2.13.6
+
diff --git a/SOURCES/0018-ipa-kdb-add-ipadb_fetch_principals_with_extra_filter.patch b/SOURCES/0018-ipa-kdb-add-ipadb_fetch_principals_with_extra_filter.patch
deleted file mode 100644
index 3a5a47a..0000000
--- a/SOURCES/0018-ipa-kdb-add-ipadb_fetch_principals_with_extra_filter.patch
+++ /dev/null
@@ -1,132 +0,0 @@
-From 7a115884d370d8e9b2c7b110a0565fe5b78446a9 Mon Sep 17 00:00:00 2001
-From: Sumit Bose <sbose@redhat.com>
-Date: Wed, 15 Feb 2017 12:09:20 +0100
-Subject: [PATCH] ipa-kdb: add ipadb_fetch_principals_with_extra_filter()
-
-Additionally make ipadb_find_principal public.
-
-Related to https://pagure.io/freeipa/issue/4905
-
-Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
-Reviewed-By: David Kupka <dkupka@redhat.com>
----
- daemons/ipa-kdb/ipa_kdb.h            | 11 +++++++
- daemons/ipa-kdb/ipa_kdb_principals.c | 58 ++++++++++++++++++++++++++++--------
- 2 files changed, 56 insertions(+), 13 deletions(-)
-
-diff --git a/daemons/ipa-kdb/ipa_kdb.h b/daemons/ipa-kdb/ipa_kdb.h
-index 8a3f7d3c012186fd73b27abef09602b0d0e96e8d..72f2675809a3267cce30bc06c77335697c7287ad 100644
---- a/daemons/ipa-kdb/ipa_kdb.h
-+++ b/daemons/ipa-kdb/ipa_kdb.h
-@@ -198,6 +198,17 @@ krb5_error_code ipadb_put_principal(krb5_context kcontext,
-                                     char **db_args);
- krb5_error_code ipadb_delete_principal(krb5_context kcontext,
-                                        krb5_const_principal search_for);
-+krb5_error_code
-+ipadb_fetch_principals_with_extra_filter(struct ipadb_context *ipactx,
-+                                         unsigned int flags,
-+                                         const char *principal,
-+                                         const char *filter,
-+                                         LDAPMessage **result);
-+krb5_error_code ipadb_find_principal(krb5_context kcontext,
-+                                     unsigned int flags,
-+                                     LDAPMessage *res,
-+                                     char **principal,
-+                                     LDAPMessage **entry);
- #if KRB5_KDB_API_VERSION < 8
- krb5_error_code ipadb_iterate(krb5_context kcontext,
-                               char *match_entry,
-diff --git a/daemons/ipa-kdb/ipa_kdb_principals.c b/daemons/ipa-kdb/ipa_kdb_principals.c
-index 3bd8fb8c70c61b056a714bc0a8149bd8524beb1d..82c857430b11279b4029fa72a6d430610524ba43 100644
---- a/daemons/ipa-kdb/ipa_kdb_principals.c
-+++ b/daemons/ipa-kdb/ipa_kdb_principals.c
-@@ -37,6 +37,17 @@
-                                 "(objectclass=krbprincipal))" \
-                               "(krbprincipalname=%s))"
- 
-+#define PRINC_TGS_SEARCH_FILTER_EXTRA "(&(|(objectclass=krbprincipalaux)" \
-+                                          "(objectclass=krbprincipal)" \
-+                                          "(objectclass=ipakrbprincipal))" \
-+                                        "(|(ipakrbprincipalalias=%s)" \
-+                                          "(krbprincipalname:caseIgnoreIA5Match:=%s))" \
-+                                         "%s)"
-+
-+#define PRINC_SEARCH_FILTER_EXTRA "(&(|(objectclass=krbprincipalaux)" \
-+                                      "(objectclass=krbprincipal))" \
-+                                    "(krbprincipalname=%s)" \
-+                                    "%s)"
- static char *std_principal_attrs[] = {
-     "krbPrincipalName",
-     "krbCanonicalName",
-@@ -864,10 +875,12 @@ done:
-     return kerr;
- }
- 
--static krb5_error_code ipadb_fetch_principals(struct ipadb_context *ipactx,
--                                              unsigned int flags,
--                                              char *principal,
--                                              LDAPMessage **result)
-+krb5_error_code
-+ipadb_fetch_principals_with_extra_filter(struct ipadb_context *ipactx,
-+                                         unsigned int flags,
-+                                         const char *principal,
-+                                         const char *filter,
-+                                         LDAPMessage **result)
- {
-     krb5_error_code kerr;
-     char *src_filter = NULL;
-@@ -890,11 +903,21 @@ static krb5_error_code ipadb_fetch_principals(struct ipadb_context *ipactx,
-         goto done;
-     }
- 
--    if (flags & KRB5_KDB_FLAG_ALIAS_OK) {
--        ret = asprintf(&src_filter, PRINC_TGS_SEARCH_FILTER,
--                       esc_original_princ, esc_original_princ);
-+    if (filter == NULL) {
-+        if (flags & KRB5_KDB_FLAG_ALIAS_OK) {
-+            ret = asprintf(&src_filter, PRINC_TGS_SEARCH_FILTER,
-+                           esc_original_princ, esc_original_princ);
-+        } else {
-+            ret = asprintf(&src_filter, PRINC_SEARCH_FILTER, esc_original_princ);
-+        }
-     } else {
--        ret = asprintf(&src_filter, PRINC_SEARCH_FILTER, esc_original_princ);
-+        if (flags & KRB5_KDB_FLAG_ALIAS_OK) {
-+            ret = asprintf(&src_filter, PRINC_TGS_SEARCH_FILTER_EXTRA,
-+                           esc_original_princ, esc_original_princ, filter);
-+        } else {
-+            ret = asprintf(&src_filter, PRINC_SEARCH_FILTER_EXTRA,
-+                           esc_original_princ, filter);
-+        }
-     }
- 
-     if (ret == -1) {
-@@ -913,11 +936,20 @@ done:
-     return kerr;
- }
- 
--static krb5_error_code ipadb_find_principal(krb5_context kcontext,
--                                            unsigned int flags,
--                                            LDAPMessage *res,
--                                            char **principal,
--                                            LDAPMessage **entry)
-+static krb5_error_code ipadb_fetch_principals(struct ipadb_context *ipactx,
-+                                              unsigned int flags,
-+                                              char *principal,
-+                                              LDAPMessage **result)
-+{
-+    return ipadb_fetch_principals_with_extra_filter(ipactx, flags, principal,
-+                                                    NULL, result);
-+}
-+
-+krb5_error_code ipadb_find_principal(krb5_context kcontext,
-+                                     unsigned int flags,
-+                                     LDAPMessage *res,
-+                                     char **principal,
-+                                     LDAPMessage **entry)
- {
-     struct ipadb_context *ipactx;
-     bool found = false;
--- 
-2.12.1
-
diff --git a/SOURCES/0018-ipaserver-plugins-trust.py-fix-some-indenting-issues.patch b/SOURCES/0018-ipaserver-plugins-trust.py-fix-some-indenting-issues.patch
new file mode 100644
index 0000000..a93887e
--- /dev/null
+++ b/SOURCES/0018-ipaserver-plugins-trust.py-fix-some-indenting-issues.patch
@@ -0,0 +1,71 @@
+From e553b66e54af3bf981501bca57fb22caaa8e8305 Mon Sep 17 00:00:00 2001
+From: Alexander Bokovoy <abokovoy@redhat.com>
+Date: Thu, 9 Nov 2017 09:57:47 +0200
+Subject: [PATCH] ipaserver/plugins/trust.py; fix some indenting issues
+
+Reviewed-By: Christian Heimes <cheimes@redhat.com>
+Reviewed-By: Thierry Bordaz <tbordaz@redhat.com>
+---
+ ipaserver/plugins/trust.py | 17 +++++++++--------
+ 1 file changed, 9 insertions(+), 8 deletions(-)
+
+diff --git a/ipaserver/plugins/trust.py b/ipaserver/plugins/trust.py
+index ecc5fa0b22f94de05cc5282758be093f0cfca13f..d01529ee022d4a4f9b671a8f06156ed450326041 100644
+--- a/ipaserver/plugins/trust.py
++++ b/ipaserver/plugins/trust.py
+@@ -280,15 +280,17 @@ def generate_creds(trustinstance, style, **options):
+         elif style == CRED_STYLE_KERBEROS:
+             sp = admin_name.split('\\')
+             if len(sp) > 1:
+-               sp = [sp[1]]
++                sp = [sp[1]]
+             else:
+-               sp = admin_name.split(sep)
++                sp = admin_name.split(sep)
+             if len(sp) == 1:
+-                sp.append(trustinstance.remote_domain.info['dns_domain'].upper())
++                sp.append(trustinstance.remote_domain
++                          .info['dns_domain'].upper())
+         creds = u"{name}%{password}".format(name=sep.join(sp),
+                                             password=password)
+     return creds
+ 
++
+ def add_range(myapi, trustinstance, range_name, dom_sid, *keys, **options):
+     """
+     First, we try to derive the parameters of the ID range based on the
+@@ -319,7 +321,7 @@ def add_range(myapi, trustinstance, range_name, dom_sid, *keys, **options):
+         # CN=ypservers,CN=ypServ30,CN=RpcServices,CN=System
+         info_filter = '(objectClass=msSFU30DomainInfo)'
+         info_dn = DN('CN=ypservers,CN=ypServ30,CN=RpcServices,CN=System')\
+-                  + basedn
++            + basedn
+ 
+         # Get the domain validator
+         domain_validator = ipaserver.dcerpc.DomainValidator(myapi)
+@@ -367,7 +369,7 @@ def add_range(myapi, trustinstance, range_name, dom_sid, *keys, **options):
+ 
+                 base_id = int(info.get('msSFU30OrderNumber')[0])
+                 range_size = (1 + (max_id - base_id) // DEFAULT_RANGE_SIZE)\
+-                             * DEFAULT_RANGE_SIZE
++                    * DEFAULT_RANGE_SIZE
+ 
+     # Second, options given via the CLI options take precedence to discovery
+     if options.get('range_type', None):
+@@ -595,11 +597,10 @@ class trust(LDAPObject):
+             pass
+         else:
+             for entry in entries:
+-                 add_message(
++                add_message(
+                     options['version'],
+                     result,
+-                    BrokenTrust(domain=entry.single_value['cn'])
+-                 )
++                    BrokenTrust(domain=entry.single_value['cn']))
+ 
+ 
+ @register()
+-- 
+2.13.6
+
diff --git a/SOURCES/0019-IPA-certauth-plugin.patch b/SOURCES/0019-IPA-certauth-plugin.patch
deleted file mode 100644
index b600531..0000000
--- a/SOURCES/0019-IPA-certauth-plugin.patch
+++ /dev/null
@@ -1,609 +0,0 @@
-From 0956c8149f11921ed427d67b10bb9b6c4b97df48 Mon Sep 17 00:00:00 2001
-From: Sumit Bose <sbose@redhat.com>
-Date: Thu, 2 Feb 2017 12:32:13 +0100
-Subject: [PATCH] IPA certauth plugin
-
-This patch add a certauth plugin which allows the IPA server to support
-PKINIT for certificates which do not include a special SAN extension
-which contains a Kerberos principal but allow other mappings with the
-help of SSSD's certmap library.
-
-Related to https://pagure.io/freeipa/issue/4905
-
-Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
-Reviewed-By: David Kupka <dkupka@redhat.com>
----
- daemons/ipa-kdb/Makefile.am        |  24 ++-
- daemons/ipa-kdb/ipa-certauth.in    |   5 +
- daemons/ipa-kdb/ipa_kdb.c          |   2 +
- daemons/ipa-kdb/ipa_kdb.exports    |   1 +
- daemons/ipa-kdb/ipa_kdb.h          |   5 +
- daemons/ipa-kdb/ipa_kdb_certauth.c | 398 +++++++++++++++++++++++++++++++++++++
- freeipa.spec.in                    |   2 +
- server.m4                          |  13 ++
- 8 files changed, 449 insertions(+), 1 deletion(-)
- create mode 100644 daemons/ipa-kdb/ipa-certauth.in
- create mode 100644 daemons/ipa-kdb/ipa_kdb_certauth.c
-
-diff --git a/daemons/ipa-kdb/Makefile.am b/daemons/ipa-kdb/Makefile.am
-index 6a2caa0637bf076c796b50efc92412062524f35f..715666e779a4fa64c2c0f71767f09efb19b5f908 100644
---- a/daemons/ipa-kdb/Makefile.am
-+++ b/daemons/ipa-kdb/Makefile.am
-@@ -18,6 +18,7 @@ AM_CPPFLAGS =						\
- 	$(WARN_CFLAGS)					\
- 	$(NDRPAC_CFLAGS)				\
- 	$(NSS_CFLAGS)					\
-+	$(SSSCERTMAP_CFLAGS)				\
- 	$(NULL)
- 
- plugindir = $(libdir)/krb5/plugins/kdb
-@@ -39,6 +40,20 @@ ipadb_la_SOURCES = 		\
- 	ipa_kdb_audit_as.c	\
- 	$(NULL)
- 
-+if BUILD_IPA_CERTAUTH_PLUGIN
-+ipadb_la_SOURCES += ipa_kdb_certauth.c
-+
-+
-+%: %.in
-+	sed \
-+		-e 's|@plugindir@|$(plugindir)|g' \
-+		'$(srcdir)/$@.in' >$@
-+
-+krb5confdir = $(sysconfdir)/krb5.conf.d
-+krb5conf_DATA = ipa-certauth
-+CLEANFILES = $(krb5conf_DATA)
-+endif
-+
- ipadb_la_LDFLAGS = 		\
- 	-avoid-version 		\
- 	-module			\
-@@ -50,6 +65,7 @@ ipadb_la_LIBADD = 		\
- 	$(NDRPAC_LIBS)		\
- 	$(UNISTRING_LIBS)	\
- 	$(NSS_LIBS)             \
-+	$(SSSCERTMAP_LIBS)	\
- 	$(top_builddir)/util/libutil.la	\
- 	$(NULL)
- 
-@@ -70,6 +86,11 @@ ipa_kdb_tests_SOURCES =        \
-        ipa_kdb_delegation.c    \
-        ipa_kdb_audit_as.c      \
-        $(NULL)
-+
-+if BUILD_IPA_CERTAUTH_PLUGIN
-+ipa_kdb_tests_SOURCES += ipa_kdb_certauth.c
-+endif
-+
- ipa_kdb_tests_CFLAGS = $(CMOCKA_CFLAGS)
- ipa_kdb_tests_LDADD =          \
-        $(CMOCKA_LIBS)          \
-@@ -78,12 +99,13 @@ ipa_kdb_tests_LDADD =          \
-        $(NDRPAC_LIBS)          \
-        $(UNISTRING_LIBS)       \
-        $(NSS_LIBS)             \
-+       $(SSSCERTMAP_LIBS)      \
-        $(top_builddir)/util/libutil.la	\
-        -lkdb5                  \
-        -lsss_idmap             \
-        $(NULL)
- 
--dist_noinst_DATA = ipa_kdb.exports
-+dist_noinst_DATA = ipa_kdb.exports ipa-certauth.in
- 
- clean-local:
- 	rm -f tests/.dirstamp
-diff --git a/daemons/ipa-kdb/ipa-certauth.in b/daemons/ipa-kdb/ipa-certauth.in
-new file mode 100644
-index 0000000000000000000000000000000000000000..eda89a26f02fbea449eb754b232b8115904acd21
---- /dev/null
-+++ b/daemons/ipa-kdb/ipa-certauth.in
-@@ -0,0 +1,5 @@
-+[plugins]
-+ certauth = {
-+  module = ipakdb:@plugindir@/ipadb.so
-+  enable_only = ipakdb
-+ }
-diff --git a/daemons/ipa-kdb/ipa_kdb.c b/daemons/ipa-kdb/ipa_kdb.c
-index c19b7c40e2e88173ab8367a3ef1d7f46245fd174..a961e4e57cf5379eb237551d56e3bc8dc82d952d 100644
---- a/daemons/ipa-kdb/ipa_kdb.c
-+++ b/daemons/ipa-kdb/ipa_kdb.c
-@@ -67,6 +67,8 @@ static void ipadb_context_free(krb5_context kcontext,
-         }
-         free(cfg->authz_data);
- 
-+        ipa_certauth_free_moddata(&((*ctx)->certauth_moddata));
-+
-         free(*ctx);
-         *ctx = NULL;
-     }
-diff --git a/daemons/ipa-kdb/ipa_kdb.exports b/daemons/ipa-kdb/ipa_kdb.exports
-index d2c3f30246cc7ebcba02a9ec5d134e604fa0dbb9..27ce92d2edd741245061a5f4ee9275169440c932 100644
---- a/daemons/ipa-kdb/ipa_kdb.exports
-+++ b/daemons/ipa-kdb/ipa_kdb.exports
-@@ -3,6 +3,7 @@ EXPORTED {
- 	# public symbols
- 	global:
- 		kdb_function_table;
-+		certauth_ipakdb_initvt;
- 
- 	# everything else is local
- 	local:
-diff --git a/daemons/ipa-kdb/ipa_kdb.h b/daemons/ipa-kdb/ipa_kdb.h
-index 72f2675809a3267cce30bc06c77335697c7287ad..632c1979d15e88aec86d5e408ed6c7017d8362b8 100644
---- a/daemons/ipa-kdb/ipa_kdb.h
-+++ b/daemons/ipa-kdb/ipa_kdb.h
-@@ -40,6 +40,7 @@
- #include <arpa/inet.h>
- #include <endian.h>
- #include <unistd.h>
-+#include <krb5/certauth_plugin.h>
- 
- #include "ipa_krb5.h"
- #include "ipa_pwd.h"
-@@ -111,6 +112,7 @@ struct ipadb_context {
-     krb5_key_salt_tuple *def_encs;
-     int n_def_encs;
-     struct ipadb_mspac *mspac;
-+    krb5_certauth_moddata certauth_moddata;
- 
-     /* Don't access this directly, use ipadb_get_global_config(). */
-     struct ipadb_global_config config;
-@@ -331,3 +333,6 @@ ipadb_get_global_config(struct ipadb_context *ipactx);
- int ipadb_get_enc_salt_types(struct ipadb_context *ipactx, LDAPMessage *entry,
-                              char *attr, krb5_key_salt_tuple **enc_salt_types,
-                              int *n_enc_salt_types);
-+
-+/* CERTAUTH PLUGIN */
-+void ipa_certauth_free_moddata(krb5_certauth_moddata *moddata);
-diff --git a/daemons/ipa-kdb/ipa_kdb_certauth.c b/daemons/ipa-kdb/ipa_kdb_certauth.c
-new file mode 100644
-index 0000000000000000000000000000000000000000..a53a2ce4e7ceb06ec8de117cdbca2666fdb5a97a
---- /dev/null
-+++ b/daemons/ipa-kdb/ipa_kdb_certauth.c
-@@ -0,0 +1,398 @@
-+/** BEGIN COPYRIGHT BLOCK
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation, either version 3 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
-+ *
-+ * Additional permission under GPLv3 section 7:
-+ *
-+ * In the following paragraph, "GPL" means the GNU General Public
-+ * License, version 3 or any later version, and "Non-GPL Code" means
-+ * code that is governed neither by the GPL nor a license
-+ * compatible with the GPL.
-+ *
-+ * You may link the code of this Program with Non-GPL Code and convey
-+ * linked combinations including the two, provided that such Non-GPL
-+ * Code only links to the code of this Program through those well
-+ * defined interfaces identified in the file named EXCEPTION found in
-+ * the source code files (the "Approved Interfaces"). The files of
-+ * Non-GPL Code may instantiate templates or use macros or inline
-+ * functions from the Approved Interfaces without causing the resulting
-+ * work to be covered by the GPL. Only the copyright holders of this
-+ * Program may make changes or additions to the list of Approved
-+ * Interfaces.
-+ *
-+ * Authors:
-+ * Sumit Bose <sbose@redhat.com>
-+ *
-+ * Copyright (C) 2017 Red Hat, Inc.
-+ * All rights reserved.
-+ * END COPYRIGHT BLOCK **/
-+
-+#include <errno.h>
-+//#include <krb5/certauth_plugin.h>
-+#include <syslog.h>
-+#include <sss_certmap.h>
-+
-+#include "util/ipa_krb5.h"
-+#include "ipa_kdb.h"
-+
-+#define IPA_OC_CERTMAP_RULE "ipaCertMapRule"
-+#define IPA_CERTMAP_MAPRULE "ipaCertMapMapRule"
-+#define IPA_CERTMAP_MATCHRULE "ipaCertMapMatchRule"
-+#define IPA_CERTMAP_PRIORITY "ipaCertMapPriority"
-+#define IPA_ENABLED_FLAG "ipaEnabledFlag"
-+#define IPA_TRUE_VALUE "TRUE"
-+#define IPA_ASSOCIATED_DOMAIN "associatedDomain"
-+
-+#define OBJECTCLASS "objectClass"
-+
-+#define CERTMAP_FILTER "(&("OBJECTCLASS"="IPA_OC_CERTMAP_RULE")" \
-+                              "("IPA_ENABLED_FLAG"="IPA_TRUE_VALUE"))"
-+
-+#ifndef discard_const
-+#define discard_const(ptr) ((void *)((uintptr_t)(ptr)))
-+#endif
-+
-+
-+struct krb5_certauth_moddata_st {
-+    char *local_domain;
-+    struct sss_certmap_ctx *sss_certmap_ctx;
-+    struct ipadb_context *ipactx;
-+};
-+
-+void ipa_certmap_debug(void *private,
-+                       const char *file, long line,
-+                       const char *function,
-+                       const char *format, ...)
-+{
-+    va_list ap;
-+    char str[255] = { 0 };
-+
-+    va_start(ap, format);
-+    vsnprintf(str, sizeof(str)-1, format, ap);
-+    va_end(ap);
-+    krb5_klog_syslog(LOG_INFO, str);
-+}
-+
-+void ipa_certauth_free_moddata(krb5_certauth_moddata *moddata)
-+{
-+    if (moddata == NULL || *moddata == NULL) {
-+        return;
-+    }
-+
-+    free((*moddata)->local_domain);
-+    (*moddata)->local_domain = NULL;
-+    sss_certmap_free_ctx((*moddata)->sss_certmap_ctx);
-+    (*moddata)->sss_certmap_ctx = NULL;
-+
-+    free(*moddata);
-+
-+    return;
-+}
-+
-+static krb5_error_code ipa_get_init_data(krb5_context kcontext,
-+                                         krb5_certauth_moddata moddata_out)
-+{
-+    int ret;
-+    struct sss_certmap_ctx *ctx = NULL;
-+    struct ipadb_context *ipactx;
-+    krb5_error_code kerr;
-+    char *basedn = NULL;
-+    LDAPMessage *result = NULL;
-+    LDAPMessage *le;
-+    LDAP *lc;
-+    size_t c;
-+    uint32_t prio;
-+    char *map_rule = NULL;
-+    char *match_rule = NULL;
-+    char **domains = NULL;
-+
-+    const char *certmap_attrs[] = { OBJECTCLASS,
-+                                    IPA_CERTMAP_PRIORITY,
-+                                    IPA_CERTMAP_MATCHRULE,
-+                                    IPA_CERTMAP_MAPRULE,
-+                                    IPA_ASSOCIATED_DOMAIN,
-+                                    IPA_ENABLED_FLAG,
-+                                    NULL};
-+
-+
-+    krb5_klog_syslog(LOG_INFO, "Initializing IPA certauth plugin.");
-+
-+    ipactx = ipadb_get_context(kcontext);
-+    if (ipactx == NULL) {
-+        return KRB5_KDB_DBNOTINITED;
-+    }
-+
-+    if (ipactx->certauth_moddata == NULL) {
-+        ret = asprintf(&basedn, "cn=certmap,%s", ipactx->base);
-+        if (ret == -1) {
-+            return ENOMEM;
-+        }
-+
-+        kerr = ipadb_simple_search(ipactx,basedn, LDAP_SCOPE_SUBTREE,
-+                                   CERTMAP_FILTER, discard_const(certmap_attrs),
-+                                   &result);
-+        if (kerr != 0 && kerr != KRB5_KDB_NOENTRY) {
-+            goto done;
-+        }
-+
-+        ret = sss_certmap_init(NULL, ipa_certmap_debug, NULL, &ctx);
-+        if (ret != 0) {
-+            return ret;
-+        }
-+
-+        if (kerr == KRB5_KDB_NOENTRY) {
-+            ret = sss_certmap_add_rule(ctx, SSS_CERTMAP_MIN_PRIO,
-+                                       NULL, NULL, NULL);
-+            if (ret != 0) {
-+                goto done;
-+            }
-+        } else {
-+            lc = ipactx->lcontext;
-+
-+            for (le = ldap_first_entry(lc, result); le;
-+                                                 le = ldap_next_entry(lc, le)) {
-+                prio = SSS_CERTMAP_MIN_PRIO;
-+                ret = ipadb_ldap_attr_to_uint32(lc, le, IPA_CERTMAP_PRIORITY,
-+                                                &prio);
-+                if (ret != 0 && ret != ENOENT) {
-+                    goto done;
-+                }
-+
-+                free(map_rule);
-+                map_rule = NULL;
-+                ret = ipadb_ldap_attr_to_str(lc, le, IPA_CERTMAP_MAPRULE,
-+                                             &map_rule);
-+                if (ret != 0 && ret != ENOENT) {
-+                    goto done;
-+                }
-+
-+                free(match_rule);
-+                match_rule = NULL;
-+                ret = ipadb_ldap_attr_to_str(lc, le, IPA_CERTMAP_MATCHRULE,
-+                                             &match_rule);
-+                if (ret != 0 && ret != ENOENT) {
-+                    goto done;
-+                }
-+
-+                if (domains != NULL) {
-+                    for (c = 0; domains[c] != NULL; c++) {
-+                        free(domains[c]);
-+                    }
-+                    free(domains);
-+                    domains = NULL;
-+                }
-+                ret = ipadb_ldap_attr_to_strlist(lc, le, IPA_ASSOCIATED_DOMAIN,
-+                                                 &domains);
-+                if (ret != 0 && ret != ENOENT) {
-+                    goto done;
-+                }
-+
-+                ret = sss_certmap_add_rule(ctx, prio, match_rule, map_rule,
-+                                           (const char **) domains);
-+                if (ret != 0) {
-+                    goto done;
-+                }
-+            }
-+        }
-+
-+        ipactx->certauth_moddata = moddata_out;
-+
-+        if (ipactx->realm != NULL) {
-+            ipactx->certauth_moddata->local_domain = strdup(ipactx->realm);
-+            if (ipactx->certauth_moddata->local_domain == NULL) {
-+                free(ipactx->certauth_moddata);
-+                ipactx->certauth_moddata = NULL;
-+                ret = ENOMEM;
-+                goto done;
-+            }
-+        }
-+
-+        ipactx->certauth_moddata->sss_certmap_ctx = ctx;
-+        ipactx->certauth_moddata->ipactx = ipactx;
-+
-+    }
-+
-+    ret = 0;
-+
-+done:
-+    ldap_msgfree(result);
-+    free(basedn);
-+    free(map_rule);
-+    free(match_rule);
-+    if (domains != NULL) {
-+        for (c = 0; domains[c] != NULL; c++) {
-+            free(domains[c]);
-+        }
-+        free(domains);
-+        domains = NULL;
-+    }
-+
-+    if (ret != 0) {
-+        sss_certmap_free_ctx(ctx);
-+    }
-+
-+    return ret;
-+}
-+
-+static krb5_error_code ipa_certauth_authorize(krb5_context context,
-+                                              krb5_certauth_moddata moddata,
-+                                              const uint8_t *cert,
-+                                              size_t cert_len,
-+                                              krb5_const_principal princ,
-+                                              const void *opts,
-+                                              const krb5_db_entry *db_entry,
-+                                              char ***authinds_out)
-+{
-+    char *cert_filter = NULL;
-+    char **domains = NULL;
-+    int ret;
-+    size_t c;
-+    char *principal = NULL;
-+    LDAPMessage *res = NULL;
-+    krb5_error_code kerr;
-+    LDAPMessage *lentry;
-+
-+    if (moddata == NULL) {
-+        return KRB5_PLUGIN_NO_HANDLE;
-+    }
-+
-+    if (moddata->sss_certmap_ctx == NULL) {
-+        kerr = ipa_get_init_data(context, moddata);
-+        if (kerr != 0) {
-+            krb5_klog_syslog(LOG_ERR, "Failed to init certmapping data");
-+            return KRB5_PLUGIN_NO_HANDLE;
-+        }
-+    }
-+
-+    ret = krb5_unparse_name(context, princ, &principal);
-+    if (ret != 0) {
-+        ret = KRB5KDC_ERR_CERTIFICATE_MISMATCH;
-+        goto done;
-+    }
-+    krb5_klog_syslog(LOG_INFO, "Doing certauth authorize for [%s]", principal);
-+
-+    ret = sss_certmap_get_search_filter(moddata->sss_certmap_ctx,
-+                                        cert, cert_len,
-+                                        &cert_filter, &domains);
-+    if (ret != 0) {
-+        if (ret == ENOENT) {
-+            ret = KRB5KDC_ERR_CERTIFICATE_MISMATCH;
-+        }
-+        goto done;
-+    }
-+    krb5_klog_syslog(LOG_INFO, "Got cert filter [%s]", cert_filter);
-+
-+    /* If there are no domains assigned the rule will apply to the local
-+     * domain only. */
-+    if (domains != NULL) {
-+
-+        if (moddata->local_domain == NULL) {
-+        /* We don't know our own domain name, in general this should not
-+         * happen. But to be fault tolerant we allow matching rule which
-+         * do not have a domain assigned. */
-+
-+            ret = KRB5KDC_ERR_CERTIFICATE_MISMATCH;
-+            goto done;
-+        }
-+
-+        for (c = 0; domains[c] != NULL; c++) {
-+            if (strcasecmp(domains[c], moddata->local_domain) == 0) {
-+                break;
-+            }
-+        }
-+
-+        /* Our domain was not in the list */
-+        if (domains[c] == NULL) {
-+            ret = KRB5KDC_ERR_CERTIFICATE_MISMATCH;
-+            goto done;
-+        }
-+    }
-+
-+    kerr = ipadb_fetch_principals_with_extra_filter(moddata->ipactx,
-+                                                    KRB5_KDB_FLAG_ALIAS_OK,
-+                                                    principal,
-+                                                    cert_filter,
-+                                                    &res);
-+    if (kerr != 0) {
-+        krb5_klog_syslog(LOG_ERR, "Search failed [%d]", kerr);
-+        ret = KRB5KDC_ERR_CERTIFICATE_MISMATCH;
-+        goto done;
-+    }
-+
-+    kerr = ipadb_find_principal(context, KRB5_KDB_FLAG_ALIAS_OK, res,
-+                                &principal, &lentry);
-+    if (kerr == KRB5_KDB_NOENTRY) {
-+        krb5_klog_syslog(LOG_INFO, "No matching entry found");
-+        ret = KRB5KDC_ERR_CERTIFICATE_MISMATCH;
-+        goto done;
-+    } else if (kerr != 0) {
-+        krb5_klog_syslog(LOG_ERR, "ipadb_find_principal failed [%d]", kerr);
-+        ret = KRB5KDC_ERR_CERTIFICATE_MISMATCH;
-+        goto done;
-+    }
-+
-+    /* TODO: add more tests ? */
-+
-+    ret = 0;
-+
-+done:
-+    sss_certmap_free_filter_and_domains(cert_filter, domains);
-+    krb5_free_unparsed_name(context, principal);
-+    ldap_msgfree(res);
-+
-+    return ret;
-+}
-+
-+static krb5_error_code ipa_certauth_init(krb5_context kcontext,
-+                                         krb5_certauth_moddata *moddata_out)
-+{
-+    struct krb5_certauth_moddata_st *certauth_moddata;
-+
-+    certauth_moddata = calloc(1, sizeof(struct krb5_certauth_moddata_st));
-+    if (certauth_moddata == NULL) {
-+        return ENOMEM;
-+    }
-+
-+    *moddata_out = certauth_moddata;
-+
-+    return 0;
-+}
-+
-+static void ipa_certauth_fini(krb5_context context,
-+                              krb5_certauth_moddata moddata_out)
-+{
-+    krb5_klog_syslog(LOG_INFO, "IPA certauth plugin un-loaded.");
-+    return;
-+}
-+
-+
-+krb5_error_code certauth_ipakdb_initvt(krb5_context context,
-+                                          int maj_ver, int min_ver,
-+                                          krb5_plugin_vtable vtable)
-+{
-+    krb5_certauth_vtable vt;
-+
-+    if (maj_ver != 1) {
-+        return KRB5_PLUGIN_VER_NOTSUPP;
-+    }
-+
-+    vt = (krb5_certauth_vtable) vtable;
-+
-+    vt->name = "ipakdb";
-+    vt->authorize = ipa_certauth_authorize;
-+    vt->init = ipa_certauth_init;
-+    vt->fini = ipa_certauth_fini;
-+    /* currently we do not return authentication indicators */
-+    vt->free_ind = NULL;
-+    return 0;
-+}
-diff --git a/freeipa.spec.in b/freeipa.spec.in
-index f776b34af88cc8ccd02da0713cb6eaca161c99f5..18291a5793a6b69dcd719f42e80e1652169e5e1d 100644
---- a/freeipa.spec.in
-+++ b/freeipa.spec.in
-@@ -120,6 +120,7 @@ BuildRequires:  libtalloc-devel
- BuildRequires:  libtevent-devel
- BuildRequires:  libuuid-devel
- BuildRequires:  libsss_idmap-devel
-+BuildRequires:  libsss_certmap-devel
- # 1.14.0: sss_nss_getnamebycert (https://fedorahosted.org/sssd/ticket/2897)
- BuildRequires:  libsss_nss_idmap-devel >= 1.14.0
- BuildRequires:  rhino
-@@ -1164,6 +1165,7 @@ fi
- %attr(0755,root,root) %{_libexecdir}/ipa/oddjob/org.freeipa.server.conncheck
- %config(noreplace) %{_sysconfdir}/dbus-1/system.d/org.freeipa.server.conf
- %config(noreplace) %{_sysconfdir}/oddjobd.conf.d/ipa-server.conf
-+%config(noreplace) %{_sysconfdir}/krb5.conf.d/ipa-certauth
- %dir %{_libexecdir}/ipa/certmonger
- %attr(755,root,root) %{_libexecdir}/ipa/certmonger/*
- # NOTE: systemd specific section
-diff --git a/server.m4 b/server.m4
-index 92b5cdd3a6ff90b70a9002360ff3d3aec5053392..7b2e94df91a4803849e496142788a4ed87ef487d 100644
---- a/server.m4
-+++ b/server.m4
-@@ -30,6 +30,19 @@ dnl -- sss_idmap is needed by the extdom exop --
- PKG_CHECK_MODULES([SSSIDMAP], [sss_idmap])
- PKG_CHECK_MODULES([SSSNSSIDMAP], [sss_nss_idmap >= 1.13.90])
- 
-+dnl -- sss_certmap and certauth.h are needed by the IPA KDB certauth plugin --
-+PKG_CHECK_EXISTS([sss_certmap],
-+                 [PKG_CHECK_MODULES([SSSCERTMAP], [sss_certmap])],
-+                 [AC_MSG_NOTICE([sss_certmap not found])])
-+AC_CHECK_HEADER([krb5/certauth_plugin.h],
-+                [have_certauth_plugin=yes],
-+                [have_certauth_plugin=no])
-+AM_CONDITIONAL([BUILD_IPA_CERTAUTH_PLUGIN],
-+               [test x$have_certauth_plugin = xyes -a x"$SSSCERTMAP_LIBS" != x])
-+AM_COND_IF([BUILD_IPA_CERTAUTH_PLUGIN],
-+           [AC_MSG_NOTICE([Build IPA KDB certauth plugin])],
-+           [AC_MSG_WARN([Cannot build IPA KDB certauth plugin])])
-+
- dnl ---------------------------------------------------------------------------
- dnl - Check for KRB5 krad
- dnl ---------------------------------------------------------------------------
--- 
-2.12.1
-
diff --git a/SOURCES/0019-ipaserver-plugins-trust.py-pep8-compliance.patch b/SOURCES/0019-ipaserver-plugins-trust.py-pep8-compliance.patch
new file mode 100644
index 0000000..60c36be
--- /dev/null
+++ b/SOURCES/0019-ipaserver-plugins-trust.py-pep8-compliance.patch
@@ -0,0 +1,786 @@
+From aae0cc2fdaeead8ff33ade93e73d6aba25704659 Mon Sep 17 00:00:00 2001
+From: Alexander Bokovoy <abokovoy@redhat.com>
+Date: Fri, 17 Nov 2017 17:25:57 +0200
+Subject: [PATCH] ipaserver/plugins/trust.py: pep8 compliance
+
+Reviewed-By: Christian Heimes <cheimes@redhat.com>
+Reviewed-By: Thierry Bordaz <tbordaz@redhat.com>
+---
+ ipaserver/plugins/trust.py | 356 +++++++++++++++++++++++++++------------------
+ 1 file changed, 214 insertions(+), 142 deletions(-)
+
+diff --git a/ipaserver/plugins/trust.py b/ipaserver/plugins/trust.py
+index d01529ee022d4a4f9b671a8f06156ed450326041..73e137abcec9625997a619fe64d4f615743247b1 100644
+--- a/ipaserver/plugins/trust.py
++++ b/ipaserver/plugins/trust.py
+@@ -81,10 +81,10 @@ Cross-realm trusts
+ 
+ Manage trust relationship between IPA and Active Directory domains.
+ 
+-In order to allow users from a remote domain to access resources in IPA
+-domain, trust relationship needs to be established. Currently IPA supports
+-only trusts between IPA and Active Directory domains under control of Windows
+-Server 2008 or later, with functional level 2008 or later.
++In order to allow users from a remote domain to access resources in IPA domain,
++trust relationship needs to be established. Currently IPA supports only trusts
++between IPA and Active Directory domains under control of Windows Server 2008
++or later, with functional level 2008 or later.
+ 
+ Please note that DNS on both IPA and Active Directory domain sides should be
+ configured properly to discover each other. Trust relationship relies on
+@@ -95,7 +95,8 @@ Examples:
+ 1. Establish cross-realm trust with Active Directory using AD administrator
+    credentials:
+ 
+-   ipa trust-add --type=ad <ad.domain> --admin <AD domain administrator> --password
++   ipa trust-add --type=ad <ad.domain> --admin <AD domain administrator> \
++           --password
+ 
+ 2. List all existing trust relationships:
+ 
+@@ -110,35 +111,39 @@ Examples:
+    ipa trust-del <ad.domain>
+ 
+ Once trust relationship is established, remote users will need to be mapped
+-to local POSIX groups in order to actually use IPA resources. The mapping should
+-be done via use of external membership of non-POSIX group and then this group
+-should be included into one of local POSIX groups.
++to local POSIX groups in order to actually use IPA resources. The mapping
++should be done via use of external membership of non-POSIX group and then
++this group should be included into one of local POSIX groups.
+ 
+ Example:
+ 
+-1. Create group for the trusted domain admins' mapping and their local POSIX group:
++1. Create group for the trusted domain admins' mapping and their local POSIX
++group:
+ 
+-   ipa group-add --desc='<ad.domain> admins external map' ad_admins_external --external
++   ipa group-add --desc='<ad.domain> admins external map' \
++           ad_admins_external --external
+    ipa group-add --desc='<ad.domain> admins' ad_admins
+ 
+-2. Add security identifier of Domain Admins of the <ad.domain> to the ad_admins_external
+-   group:
++2. Add security identifier of Domain Admins of the <ad.domain> to the
++   ad_admins_external group:
+ 
+    ipa group-add-member ad_admins_external --external 'AD\\Domain Admins'
+ 
+-3. Allow members of ad_admins_external group to be associated with ad_admins POSIX group:
++3. Allow members of ad_admins_external group to be associated with
++   ad_admins POSIX group:
+ 
+    ipa group-add-member ad_admins --groups ad_admins_external
+ 
+-4. List members of external members of ad_admins_external group to see their SIDs:
++4. List members of external members of ad_admins_external group to see
++   their SIDs:
+ 
+    ipa group-show ad_admins_external
+ 
+ 
+ GLOBAL TRUST CONFIGURATION
+ 
+-When IPA AD trust subpackage is installed and ipa-adtrust-install is run,
+-a local domain configuration (SID, GUID, NetBIOS name) is generated. These
++When IPA AD trust subpackage is installed and ipa-adtrust-install is run, a
++local domain configuration (SID, GUID, NetBIOS name) is generated. These
+ identifiers are then used when communicating with a trusted domain of the
+ particular type.
+ 
+@@ -147,11 +152,11 @@ particular type.
+    ipa trustconfig-show --type ad
+ 
+ 2. Modify global configuration for all trusts of Active Directory type and set
+-   a different fallback primary group (fallback primary group GID is used as
+-   a primary user GID if user authenticating to IPA domain does not have any other
+-   primary GID already set):
++   a different fallback primary group (fallback primary group GID is used as a
++   primary user GID if user authenticating to IPA domain does not have any
++   other primary GID already set):
+ 
+-   ipa trustconfig-mod --type ad --fallback-primary-group "alternative AD group"
++   ipa trustconfig-mod --type ad --fallback-primary-group "another AD group"
+ 
+ 3. Change primary fallback group back to default hidden group (any group with
+    posixGroup object class is allowed):
+@@ -185,6 +190,7 @@ def make_trust_dn(env, trust_type, dn):
+         return DN(dn, container_dn)
+     return dn
+ 
++
+ def find_adtrust_masters(ldap, api):
+     """
+     Returns a list of names of IPA servers with ADTRUST component configured.
+@@ -200,6 +206,7 @@ def find_adtrust_masters(ldap, api):
+ 
+     return [entry.dn[1].value for entry in entries]
+ 
++
+ def verify_samba_component_presence(ldap, api):
+     """
+     Verifies that Samba is installed and configured on this particular master.
+@@ -233,7 +240,7 @@ def verify_samba_component_presence(ldap, api):
+ 
+     # First check for packages missing
+     elif not _bindings_installed:
+-        error_message=_(
++        error_message = _(
+             'Cannot perform the selected command without Samba 4 support '
+             'installed. Make sure you have installed server-trust-ad '
+             'sub-package of IPA.'
+@@ -243,7 +250,7 @@ def verify_samba_component_presence(ldap, api):
+ 
+     # Packages present, but ADTRUST instance is not configured
+     elif not adtrust_present:
+-        error_message=_(
++        error_message = _(
+             'Cannot perform the selected command without Samba 4 instance '
+             'configured on this machine. Make sure you have run '
+             'ipa-adtrust-install on this server.'
+@@ -263,7 +270,8 @@ def generate_creds(trustinstance, style, **options):
+        **options     -- options with realm_admin and realm_passwd keys
+ 
+     Result:
+-       a string representing credentials with first % separating username and password
++       a string representing credentials with first % separating
++       username and password
+        None is returned if realm_passwd key returns nothing from options
+     """
+     creds = None
+@@ -284,8 +292,9 @@ def generate_creds(trustinstance, style, **options):
+             else:
+                 sp = admin_name.split(sep)
+             if len(sp) == 1:
+-                sp.append(trustinstance.remote_domain
+-                          .info['dns_domain'].upper())
++                sp.append(
++                    trustinstance.remote_domain.info['dns_domain'].upper()
++                )
+         creds = u"{name}%{password}".format(name=sep.join(sp),
+                                             password=password)
+     return creds
+@@ -334,7 +343,8 @@ def add_range(myapi, trustinstance, range_name, dom_sid, *keys, **options):
+         creds = None
+         if trustinstance:
+             # Re-use AD administrator credentials if they were provided
+-            creds = generate_creds(trustinstance, style=CRED_STYLE_KERBEROS, **options)
++            creds = generate_creds(trustinstance,
++                                   style=CRED_STYLE_KERBEROS, **options)
+             if creds:
+                 domain_validator._admin_creds = creds
+         # KDC might not get refreshed data at the first time,
+@@ -417,21 +427,32 @@ def fetch_trusted_domains_over_dbus(myapi, log, forest_name):
+         _stdout = ''
+         _stderr = ''
+         bus = dbus.SystemBus()
+-        intf = bus.get_object(DBUS_IFACE_TRUST,"/", follow_name_owner_changes=True)
+-        fetch_domains_method = intf.get_dbus_method('fetch_domains', dbus_interface=DBUS_IFACE_TRUST)
++        intf = bus.get_object(DBUS_IFACE_TRUST, "/",
++                              follow_name_owner_changes=True)
++        fetch_domains_method = intf.get_dbus_method(
++                'fetch_domains',
++                dbus_interface=DBUS_IFACE_TRUST)
+         (_ret, _stdout, _stderr) = fetch_domains_method(forest_name)
+     except dbus.DBusException as e:
+-        log.error('Failed to call %(iface)s.fetch_domains helper.'
+-                       'DBus exception is %(exc)s.' % dict(iface=DBUS_IFACE_TRUST, exc=str(e)))
++        log.error(
++            'Failed to call %(iface)s.fetch_domains helper. '
++            'DBus exception is %(exc)s.' % dict(iface=DBUS_IFACE_TRUST, exc=str(e))
++        )
+         if _ret != 0:
+-            log.error('Helper was called for forest %(forest)s, return code is %(ret)d' % dict(forest=forest_name, ret=_ret))
+-            log.error('Standard output from the helper:\n%s---\n' % (_stdout))
+-            log.error('Error output from the helper:\n%s--\n' % (_stderr))
+-        raise errors.ServerCommandError(server=myapi.env.host,
+-                                        error=_('Fetching domains from trusted forest failed. '
+-                                                'See details in the error_log'))
++            log.error(
++                'Helper was called for forest %s, return code is %d',
++                forest_name, _ret
++            )
++            log.error('Standard output from the helper:\n%s---\n', _stdout)
++            log.error('Error output from the helper:\n%s--\n', _stderr)
++        raise errors.ServerCommandError(
++            server=myapi.env.host,
++            error=_('Fetching domains from trusted forest failed. '
++                    'See details in the error_log')
++        )
+     return
+ 
++
+ @register()
+ class trust(LDAPObject):
+     """
+@@ -538,8 +559,8 @@ class trust(LDAPObject):
+                 continue
+             for value in values:
+                 if not ipaserver.dcerpc.is_sid_valid(value):
+-                    raise errors.ValidationError(name=attr,
+-                            error=_("invalid SID: %(value)s") % dict(value=value))
++                    err = unicode(_("invalid SID: {SID}")).format(SID=value)
++                    raise errors.ValidationError(name=attr, error=err)
+ 
+     def get_dn(self, *keys, **kwargs):
+         trust_type = kwargs.get('trust_type')
+@@ -600,7 +621,8 @@ class trust(LDAPObject):
+                 add_message(
+                     options['version'],
+                     result,
+-                    BrokenTrust(domain=entry.single_value['cn']))
++                    BrokenTrust(domain=entry.single_value['cn'])
++                )
+ 
+ 
+ @register()
+@@ -622,7 +644,7 @@ sides.
+     range_types = {
+         u'ipa-ad-trust': unicode(_('Active Directory domain range')),
+         u'ipa-ad-trust-posix': unicode(_('Active Directory trust range with '
+-                                        'POSIX attributes')),
++                                         'POSIX attributes')),
+                   }
+ 
+     takes_options = LDAPCreate.takes_options + (
+@@ -720,9 +742,10 @@ sides.
+ 
+         trust_filter = "cn=%s" % result['value']
+         trusts, _truncated = ldap.find_entries(
+-                         base_dn=DN(self.api.env.container_trusts, self.api.env.basedn),
+-                         filter=trust_filter,
+-                         attrs_list=attrs_list)
++            base_dn=DN(self.api.env.container_trusts, self.api.env.basedn),
++            filter=trust_filter,
++            attrs_list=attrs_list
++        )
+ 
+         result['result'] = entry_to_dict(trusts[0], **options)
+ 
+@@ -731,10 +754,11 @@ sides.
+         # Note that add_new_domains_from_trust will add needed ranges for
+         # the algorithmic ID mapping case.
+         if (options.get('trust_type') == u'ad' and
+-            options.get('trust_secret') is None):
++                options.get('trust_secret') is None):
++
+             if options.get('bidirectional') == True:
+-                # Bidirectional trust allows us to use cross-realm TGT, so we can
+-                # run the call under original user's credentials
++                # Bidirectional trust allows us to use cross-realm TGT,
++                # so we can run the call under original user's credentials
+                 res = fetch_domains_from_trust(self.api, self.trustinstance,
+                                                **options)
+                 add_new_domains_from_trust(
+@@ -790,7 +814,9 @@ sides.
+         # If domain name and realm does not match, IPA server is not be able
+         # to establish trust with Active Directory.
+ 
+-        realm_not_matching_domain = (self.api.env.domain.upper() != self.api.env.realm)
++        realm_not_matching_domain = (
++            self.api.env.domain.upper() != self.api.env.realm
++        )
+ 
+         if options['trust_type'] == u'ad' and realm_not_matching_domain:
+             raise errors.ValidationError(
+@@ -917,11 +943,12 @@ sides.
+                 )
+ 
+             if range_type and range_type != old_range_type:
+-                raise errors.ValidationError(name=_('range type change'),
+-                    error=_('ID range for the trusted domain already exists, '
+-                            'but it has a different type. Please remove the '
+-                            'old range manually, or do not enforce type '
+-                            'via --range-type option.'))
++                raise errors.ValidationError(
++                    name=_('range type change'),
++                    error=_('ID range for the trusted domain already '
++                            'exists, but it has a different type. Please '
++                            'remove the old range manually, or do not '
++                            'enforce type via --range-type option.'))
+ 
+         return old_range, range_name, dom_sid
+ 
+@@ -956,33 +983,55 @@ sides.
+                     trust_type
+                 )
+             except errors.NotFound:
+-                error_message=_("Unable to resolve domain controller for '%s' domain. ") % (keys[-1])
+-                instructions=[]
++                _message = _("Unable to resolve domain controller for "
++                             "{domain} domain. ")
++                error_message = unicode(_message).format(domain=keys[-1])
++                instructions = []
++
+                 if dns_container_exists(self.obj.backend):
+                     try:
+-                        dns_zone = self.api.Command.dnszone_show(keys[-1])['result']
+-                        if ('idnsforwardpolicy' in dns_zone) and dns_zone['idnsforwardpolicy'][0] == u'only':
+-                            instructions.append(_("Forward policy is defined for it in IPA DNS, "
+-                                                   "perhaps forwarder points to incorrect host?"))
++                        dns_zone = self.api.Command.dnszone_show(
++                            keys[-1])['result']
++
++                        if (('idnsforwardpolicy' in dns_zone) and
++                                dns_zone['idnsforwardpolicy'][0] == u'only'):
++
++                            instructions.append(
++                                _("Forward policy is defined for it in "
++                                  "IPA DNS, perhaps forwarder points to "
++                                  "incorrect host?")
++                            )
+                     except (errors.NotFound, KeyError):
+-                        instructions.append(_("IPA manages DNS, please verify "
+-                                              "your DNS configuration and "
+-                                              "make sure that service records "
+-                                              "of the '%(domain)s' domain can "
+-                                              "be resolved. Examples how to "
+-                                              "configure DNS with CLI commands "
+-                                              "or the Web UI can be found in "
+-                                              "the documentation. " ) %
+-                                              dict(domain=keys[-1]))
++                        _instruction = _(
++                            "IPA manages DNS, please verify your DNS "
++                            "configuration and make sure that service "
++                            "records of the '{domain}' domain can be "
++                            "resolved. Examples how to configure DNS "
++                            "with CLI commands or the Web UI can be "
++                            "found in the documentation. "
++                        )
++                        instructions.append(
++                            unicode(_instruction).format(domain=keys[-1])
++                        )
+                 else:
+-                    instructions.append(_("Since IPA does not manage DNS records, ensure DNS "
+-                                           "is configured to resolve '%(domain)s' domain from "
+-                                           "IPA hosts and back.") % dict(domain=keys[-1]))
+-                raise errors.NotFound(reason=error_message, instructions=instructions)
++                    _instruction = _(
++                        "Since IPA does not manage DNS records, ensure "
++                        "DNS is configured to resolve '{domain}' "
++                        "domain from IPA hosts and back."
++                    )
++                    instructions.append(
++                        unicode(_instruction).format(domain=keys[-1])
++                    )
++                raise errors.NotFound(
++                    reason=error_message,
++                    instructions=instructions
++                )
+ 
+             if result is None:
+-                raise errors.ValidationError(name=_('AD Trust setup'),
+-                                             error=_('Unable to verify write permissions to the AD'))
++                raise errors.ValidationError(
++                    name=_('AD Trust setup'),
++                    error=_('Unable to verify write permissions to the AD')
++                )
+ 
+             ret = dict(
+                 value=pkey_to_value(
+@@ -1019,12 +1068,14 @@ sides.
+                 error=_('Not enough arguments specified to perform trust '
+                         'setup'))
+ 
++
+ @register()
+ class trust_del(LDAPDelete):
+     __doc__ = _('Delete a trust.')
+ 
+     msg_summary = _('Deleted trust "%(value)s"')
+ 
++
+ @register()
+ class trust_mod(LDAPUpdate):
+     __doc__ = _("""
+@@ -1037,13 +1088,14 @@ class trust_mod(LDAPUpdate):
+     msg_summary = _('Modified trust "%(value)s" '
+                     '(change will be effective in 60 seconds)')
+ 
+-    def pre_callback(self, ldap, dn, entry_attrs, attrs_list, *keys, **options):
++    def pre_callback(self, ldap, dn, e_attrs, attrs_list, *keys, **options):
+         assert isinstance(dn, DN)
+ 
+-        self.obj.validate_sid_blacklists(entry_attrs)
++        self.obj.validate_sid_blacklists(e_attrs)
+ 
+         return dn
+ 
++
+ @register()
+ class trust_find(LDAPSearch):
+     __doc__ = _('Search for trusts.')
+@@ -1054,9 +1106,10 @@ class trust_find(LDAPSearch):
+         '%(count)d trust matched', '%(count)d trusts matched', 0
+     )
+ 
+-    # Since all trusts types are stored within separate containers under 'cn=trusts',
+-    # search needs to be done on a sub-tree scope
+-    def pre_callback(self, ldap, filters, attrs_list, base_dn, scope, *args, **options):
++    # Since all trusts types are stored within separate containers
++    # under 'cn=trusts', search needs to be done on a sub-tree scope
++    def pre_callback(self, ldap, filters, attrs_list,
++                     base_dn, scope, *args, **options):
+         # list only trust, not trust domains
+         return (filters, base_dn, ldap.SCOPE_SUBTREE)
+ 
+@@ -1076,13 +1129,16 @@ class trust_find(LDAPSearch):
+             trust_type = attrs.single_value.get('ipanttrusttype', None)
+             attributes = attrs.single_value.get('ipanttrustattributes', 0)
+             if not options.get('raw', False) and trust_type is not None:
+-                attrs['trusttype'] = [trust_type_string(trust_type, attributes)]
++                attrs['trusttype'] = [
++                    trust_type_string(trust_type, attributes)
++                ]
+                 del attrs['ipanttrusttype']
+                 if attributes:
+                     del attrs['ipanttrustattributes']
+ 
+         return truncated
+ 
++
+ @register()
+ class trust_show(LDAPRetrieve):
+     __doc__ = _('Display information about a trust.')
+@@ -1098,7 +1154,7 @@ class trust_show(LDAPRetrieve):
+ 
+         return result
+ 
+-    def post_callback(self, ldap, dn, entry_attrs, *keys, **options):
++    def post_callback(self, ldap, dn, e_attrs, *keys, **options):
+ 
+         assert isinstance(dn, DN)
+         # Translate ipanttrusttype to trusttype
+@@ -1106,25 +1162,28 @@ class trust_show(LDAPRetrieve):
+         # if --raw not used
+ 
+         if not options.get('raw', False):
+-            trust_type = entry_attrs.single_value.get('ipanttrusttype', None)
+-            attributes = entry_attrs.single_value.get('ipanttrustattributes', 0)
++            trust_type = e_attrs.single_value.get('ipanttrusttype', None)
++            attributes = e_attrs.single_value.get('ipanttrustattributes', 0)
+             if trust_type is not None:
+-                entry_attrs['trusttype'] = [trust_type_string(trust_type, attributes)]
+-                del entry_attrs['ipanttrusttype']
++                e_attrs['trusttype'] = [
++                    trust_type_string(trust_type, attributes)
++                ]
++                del e_attrs['ipanttrusttype']
+ 
+-            dir_str = entry_attrs.single_value.get('ipanttrustdirection', None)
++            dir_str = e_attrs.single_value.get('ipanttrustdirection', None)
+             if dir_str is not None:
+-                entry_attrs['trustdirection'] = [trust_direction_string(dir_str)]
+-                del entry_attrs['ipanttrustdirection']
++                e_attrs['trustdirection'] = [trust_direction_string(dir_str)]
++                del e_attrs['ipanttrustdirection']
+ 
+             if attributes:
+-                del entry_attrs['ipanttrustattributes']
++                del e_attrs['ipanttrustattributes']
+ 
+         return dn
+ 
+ 
+ _trustconfig_dn = {
+-    u'ad': DN(('cn', api.env.domain), api.env.container_cifsdomains, api.env.basedn),
++    u'ad': DN(('cn', api.env.domain),
++              api.env.container_cifsdomains, api.env.basedn),
+ }
+ 
+ 
+@@ -1184,8 +1243,10 @@ class trustconfig(LDAPObject):
+         try:
+             return _trustconfig_dn[kwargs['trust_type']]
+         except KeyError:
+-            raise errors.ValidationError(name='trust_type',
+-                error=_("unsupported trust type"))
++            raise errors.ValidationError(
++                name='trust_type',
++                error=_("unsupported trust type")
++            )
+ 
+     def _normalize_groupdn(self, entry_attrs):
+         """
+@@ -1254,8 +1315,8 @@ class trustconfig_mod(LDAPUpdate):
+     msg_summary = _('Modified "%(value)s" trust configuration')
+     has_output = output.simple_entry
+ 
+-    def pre_callback(self, ldap, dn, entry_attrs, attrs_list, *keys, **options):
+-        self.obj._normalize_groupdn(entry_attrs)
++    def pre_callback(self, ldap, dn, e_attrs, attrs_list, *keys, **options):
++        self.obj._normalize_groupdn(e_attrs)
+         return dn
+ 
+     def execute(self, *keys, **options):
+@@ -1263,14 +1324,13 @@ class trustconfig_mod(LDAPUpdate):
+         result['value'] = pkey_to_value(options['trust_type'], options)
+         return result
+ 
+-    def post_callback(self, ldap, dn, entry_attrs, *keys, **options):
+-        self.obj._convert_groupdn(entry_attrs, options)
++    def post_callback(self, ldap, dn, e_attrs, *keys, **options):
++        self.obj._convert_groupdn(e_attrs, options)
+         self.api.Object.config.show_servroles_attributes(
+-            entry_attrs, "AD trust agent", "AD trust controller", **options)
++            e_attrs, "AD trust agent", "AD trust controller", **options)
+         return dn
+ 
+ 
+-
+ @register()
+ class trustconfig_show(LDAPRetrieve):
+     __doc__ = _('Show global trust configuration.')
+@@ -1293,18 +1353,21 @@ class trustconfig_show(LDAPRetrieve):
+ 
+ if _nss_idmap_installed:
+     _idmap_type_dict = {
+-        pysss_nss_idmap.ID_USER  : 'user',
+-        pysss_nss_idmap.ID_GROUP : 'group',
+-        pysss_nss_idmap.ID_BOTH  : 'both',
++        pysss_nss_idmap.ID_USER: 'user',
++        pysss_nss_idmap.ID_GROUP: 'group',
++        pysss_nss_idmap.ID_BOTH: 'both',
+     }
++
+     def idmap_type_string(level):
+         string = _idmap_type_dict.get(int(level), 'unknown')
+         return unicode(string)
+ 
++
+ @register()
+ class trust_resolve(Command):
+     NO_CLI = True
+-    __doc__ = _('Resolve security identifiers of users and groups in trusted domains')
++    __doc__ = _('Resolve security identifiers of users and groups '
++                'in trusted domains')
+ 
+     takes_options = (
+         Str('sids+',
+@@ -1313,8 +1376,8 @@ class trust_resolve(Command):
+     )
+ 
+     has_output_params = (
+-        Str('name', label= _('Name')),
+-        Str('sid', label= _('SID')),
++        Str('name', label=_('Name')),
++        Str('sid', label=_('SID')),
+     )
+ 
+     has_output = (
+@@ -1326,13 +1389,15 @@ class trust_resolve(Command):
+         if not _nss_idmap_installed:
+             return dict(result=result)
+         try:
++            NAME_KEY = pysss_nss_idmap.NAME_KEY
++            TYPE_KEY = pysss_nss_idmap.TYPE_KEY
+             sids = [str(x) for x in options['sids']]
+             xlate = pysss_nss_idmap.getnamebysid(sids)
+             for sid in xlate:
+                 entry = dict()
+                 entry['sid'] = [unicode(sid)]
+-                entry['name'] = [unicode(xlate[sid][pysss_nss_idmap.NAME_KEY])]
+-                entry['type'] = [idmap_type_string(xlate[sid][pysss_nss_idmap.TYPE_KEY])]
++                entry['name'] = [unicode(xlate[sid][NAME_KEY])]
++                entry['type'] = [idmap_type_string(xlate[sid][TYPE_KEY])]
+                 result.append(entry)
+         except ValueError:
+             pass
+@@ -1340,7 +1405,6 @@ class trust_resolve(Command):
+         return dict(result=result)
+ 
+ 
+-
+ @register()
+ class adtrust_is_enabled(Command):
+     NO_CLI = True
+@@ -1367,7 +1431,6 @@ class adtrust_is_enabled(Command):
+         return dict(result=True)
+ 
+ 
+-
+ @register()
+ class compat_is_enabled(Command):
+     NO_CLI = True
+@@ -1411,7 +1474,6 @@ class compat_is_enabled(Command):
+         return dict(result=True)
+ 
+ 
+-
+ @register()
+ class sidgen_was_run(Command):
+     """
+@@ -1461,7 +1523,7 @@ class trustdomain(LDAPObject):
+     Object representing a domain of the AD trust.
+     """
+     parent_object = 'trust'
+-    trust_type_idx = {'2':u'ad'}
++    trust_type_idx = {'2': u'ad'}
+     object_name = _('trust domain')
+     object_name_plural = _('trust domains')
+     object_class = ['ipaNTTrustedDomain']
+@@ -1478,40 +1540,39 @@ class trustdomain(LDAPObject):
+         Str('cn',
+             label=_('Domain name'),
+             cli_name='domain',
+-            primary_key=True
+-        ),
++            primary_key=True),
+         Str('ipantflatname?',
+             cli_name='flat_name',
+-            label=_('Domain NetBIOS name'),
+-        ),
++            label=_('Domain NetBIOS name')),
+         Str('ipanttrusteddomainsid?',
+             cli_name='sid',
+-            label=_('Domain Security Identifier'),
+-        ),
++            label=_('Domain Security Identifier')),
+         Flag('domain_enabled',
+-            label=_('Domain enabled'),
+-            flags={'virtual_attribute', 'no_create', 'no_update', 'no_search'},
+-        ),
++             label=_('Domain enabled'),
++             flags={'virtual_attribute',
++                    'no_create', 'no_update', 'no_search'}),
+     )
+ 
+-    # LDAPObject.get_dn() only passes all but last element of keys and no kwargs
+-    # to the parent object's get_dn() no matter what you pass to it. Make own get_dn()
+-    # as we really need all elements to construct proper dn.
++    # LDAPObject.get_dn() only passes all but last element of keys and no
++    # kwargs to the parent object's get_dn() no matter what you pass to it.
++    # Make own get_dn() as we really need all elements to construct proper dn.
+     def get_dn(self, *keys, **kwargs):
+         sdn = [('cn', x) for x in keys]
+         sdn.reverse()
+         trust_type = kwargs.get('trust_type')
+         if not trust_type:
+-            trust_type=u'ad'
++            trust_type = u'ad'
+ 
+-        dn=make_trust_dn(self.env, trust_type, DN(*sdn))
++        dn = make_trust_dn(self.env, trust_type, DN(*sdn))
+         return dn
+ 
++
+ @register()
+ class trustdomain_find(LDAPSearch):
+     __doc__ = _('Search domains of the trust')
+ 
+-    def pre_callback(self, ldap, filters, attrs_list, base_dn, scope, *args, **options):
++    def pre_callback(self, ldap, filters, attrs_list, base_dn,
++                     scope, *args, **options):
+         return (filters, base_dn, ldap.SCOPE_SUBTREE)
+ 
+     def post_callback(self, ldap, entries, truncated, *args, **options):
+@@ -1532,7 +1593,6 @@ class trustdomain_find(LDAPSearch):
+         return truncated
+ 
+ 
+-
+ @register()
+ class trustdomain_mod(LDAPUpdate):
+     __doc__ = _('Modify trustdomain of the trust')
+@@ -1540,31 +1600,36 @@ class trustdomain_mod(LDAPUpdate):
+     NO_CLI = True
+     takes_options = LDAPUpdate.takes_options + (_trust_type_option,)
+ 
++
+ @register()
+ class trustdomain_add(LDAPCreate):
+     __doc__ = _('Allow access from the trusted domain')
+     NO_CLI = True
+ 
+     takes_options = LDAPCreate.takes_options + (_trust_type_option,)
+-    def pre_callback(self, ldap, dn, entry_attrs, attrs_list, *keys, **options):
+-        # ipaNTTrustPartner must always be set to the name of the trusted domain
+-        # See MS-ADTS 6.1.6.7.13
+-        entry_attrs['ipanttrustpartner'] = [dn[0]['cn']]
++
++    def pre_callback(self, ldap, dn, e_attrs, attrs_list, *keys, **options):
++        # ipaNTTrustPartner must always be set to the name of the trusted
++        # domain. See MS-ADTS 6.1.6.7.13
++        e_attrs['ipanttrustpartner'] = [dn[0]['cn']]
+         return dn
+ 
+ 
+ @register()
+ class trustdomain_del(LDAPDelete):
+-    __doc__ = _('Remove information about the domain associated with the trust.')
++    __doc__ = _('Remove information about the domain associated '
++                'with the trust.')
+ 
+-    msg_summary = _('Removed information about the trusted domain "%(value)s"')
++    msg_summary = _('Removed information about the trusted domain '
++                    '"%(value)s"')
+ 
+     def execute(self, *keys, **options):
+         ldap = self.api.Backend.ldap2
+         verify_samba_component_presence(ldap, self.api)
+ 
+-        # Note that pre-/post- callback handling for LDAPDelete is causing pre_callback
+-        # to always receive empty keys. We need to catch the case when root domain is being deleted
++        # Note that pre-/post- callback handling for LDAPDelete is causing
++        # pre_callback to always receive empty keys. We need to catch the case
++        # when root domain is being deleted
+ 
+         for domain in keys[1]:
+             try:
+@@ -1603,10 +1668,10 @@ def fetch_domains_from_trust(myapi, trustinstance, **options):
+     forest_root_name = trustinstance.remote_domain.info['dns_forest']
+ 
+     # We want to use Kerberos if we have admin credentials even with SMB calls
+-    # as eventually use of NTLMSSP will be deprecated for trusted domain operations
+-    # If admin credentials are missing, 'creds' will be None and fetch_domains
+-    # will use HTTP/ipa.master@IPA.REALM principal, e.g. Kerberos authentication
+-    # as well.
++    # as eventually use of NTLMSSP will be deprecated for trusted domain
++    # operations If admin credentials are missing, 'creds' will be None and
++    # fetch_domains will use HTTP/ipa.master@IPA.REALM principal, e.g. Kerberos
++    # authentication as well.
+     creds = generate_creds(trustinstance, style=CRED_STYLE_KERBEROS, **options)
+     server = options.get('realm_server', None)
+     domains = ipaserver.dcerpc.fetch_domains(
+@@ -1616,7 +1681,8 @@ def fetch_domains_from_trust(myapi, trustinstance, **options):
+     return domains
+ 
+ 
+-def add_new_domains_from_trust(myapi, trustinstance, trust_entry, domains, **options):
++def add_new_domains_from_trust(myapi, trustinstance, trust_entry,
++                               domains, **options):
+     result = []
+     if not domains:
+         return result
+@@ -1728,8 +1794,11 @@ class trustdomain_enable(LDAPQuery):
+         verify_samba_component_presence(ldap, self.api)
+ 
+         if keys[0].lower() == keys[1].lower():
+-            raise errors.ValidationError(name='domain',
+-                error=_("Root domain of the trust is always enabled for the existing trust"))
++            raise errors.ValidationError(
++                name='domain',
++                error=_("Root domain of the trust is always enabled "
++                        "for the existing trust")
++            )
+         try:
+             trust_dn = self.obj.get_dn(keys[0], trust_type=u'ad')
+             trust_entry = ldap.get_entry(trust_dn)
+@@ -1766,8 +1835,11 @@ class trustdomain_disable(LDAPQuery):
+         verify_samba_component_presence(ldap, self.api)
+ 
+         if keys[0].lower() == keys[1].lower():
+-            raise errors.ValidationError(name='domain',
+-                error=_("cannot disable root domain of the trust, use trust-del to delete the trust itself"))
++            raise errors.ValidationError(
++                name='domain',
++                error=_("cannot disable root domain of the trust, "
++                        "use trust-del to delete the trust itself")
++            )
+         try:
+             trust_dn = self.obj.get_dn(keys[0], trust_type=u'ad')
+             trust_entry = ldap.get_entry(trust_dn)
+-- 
+2.13.6
+
diff --git a/SOURCES/0020-Don-t-use-admin-cert-during-KRA-installation.patch b/SOURCES/0020-Don-t-use-admin-cert-during-KRA-installation.patch
new file mode 100644
index 0000000..3762985
--- /dev/null
+++ b/SOURCES/0020-Don-t-use-admin-cert-during-KRA-installation.patch
@@ -0,0 +1,56 @@
+From 6e0720dedc113bf82f3b38f2afb76976ed4e8c12 Mon Sep 17 00:00:00 2001
+From: Fraser Tweedale <ftweedal@redhat.com>
+Date: Wed, 15 Nov 2017 11:59:32 +1100
+Subject: [PATCH] Don't use admin cert during KRA installation
+
+KRA installation currently imports the admin cert.  FreeIPA does not
+track this cert and it may be expired, causing installation to fail.
+Do not import the existing admin cert, and discard the new admin
+cert that gets created during KRA installation.
+
+Part of: https://pagure.io/freeipa/issue/7287
+
+Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
+Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
+---
+ ipaserver/install/krainstance.py | 10 +++++++---
+ 1 file changed, 7 insertions(+), 3 deletions(-)
+
+diff --git a/ipaserver/install/krainstance.py b/ipaserver/install/krainstance.py
+index cdd25b9d05bcb1a30260475cc2341a258a3cf93c..990bb87ca2f0029d2450cbef47958399f534f2a6 100644
+--- a/ipaserver/install/krainstance.py
++++ b/ipaserver/install/krainstance.py
+@@ -152,6 +152,10 @@ class KRAInstance(DogtagInstance):
+                 prefix="tmp-", dir=paths.VAR_LIB_IPA)
+         tmp_agent_pwd = ipautil.ipa_generate_password()
+ 
++        # Create a temporary file for the admin PKCS #12 file
++        (admin_p12_fd, admin_p12_file) = tempfile.mkstemp()
++        os.close(admin_p12_fd)
++
+         # Create KRA configuration
+         config = ConfigParser()
+         config.optionxform = str
+@@ -186,9 +190,8 @@ class KRAInstance(DogtagInstance):
+         config.set("KRA", "pki_admin_nickname", "ipa-ca-agent")
+         config.set("KRA", "pki_admin_subject_dn",
+                    str(DN(('cn', 'ipa-ca-agent'), self.subject_base)))
+-        config.set("KRA", "pki_import_admin_cert", "True")
+-        config.set("KRA", "pki_admin_cert_file", paths.ADMIN_CERT_PATH)
+-        config.set("KRA", "pki_client_admin_cert_p12", paths.DOGTAG_ADMIN_P12)
++        config.set("KRA", "pki_import_admin_cert", "False")
++        config.set("KRA", "pki_client_admin_cert_p12", admin_p12_file)
+ 
+         # Directory server
+         config.set("KRA", "pki_ds_ldap_port", "389")
+@@ -291,6 +294,7 @@ class KRAInstance(DogtagInstance):
+         finally:
+             os.remove(p12_tmpfile_name)
+             os.remove(cfg_file)
++            os.remove(admin_p12_file)
+ 
+         shutil.move(paths.KRA_BACKUP_KEYS_P12, paths.KRACERT_P12)
+         self.log.debug("completed creating KRA instance")
+-- 
+2.13.6
+
diff --git a/SOURCES/0020-configure-fix-disable-server-with-certauth-plugin.patch b/SOURCES/0020-configure-fix-disable-server-with-certauth-plugin.patch
deleted file mode 100644
index 67fec06..0000000
--- a/SOURCES/0020-configure-fix-disable-server-with-certauth-plugin.patch
+++ /dev/null
@@ -1,55 +0,0 @@
-From 1dca2667b1e43540c377a45b0f653b0e9bc8840d Mon Sep 17 00:00:00 2001
-From: Sumit Bose <sbose@redhat.com>
-Date: Mon, 27 Mar 2017 12:18:53 +0200
-Subject: [PATCH] configure: fix --disable-server with certauth plugin
-
-Resolves https://pagure.io/freeipa/issue/6816
-
-Reviewed-By: Christian Heimes <cheimes@redhat.com>
----
- configure.ac | 12 ++++++++++++
- server.m4    |  5 -----
- 2 files changed, 12 insertions(+), 5 deletions(-)
-
-diff --git a/configure.ac b/configure.ac
-index 2d84426d1039e822fa3ee53410c819274e763e32..8d4b82e4590e9e122f7aa5684fd78834c4b6a204 100644
---- a/configure.ac
-+++ b/configure.ac
-@@ -225,6 +225,18 @@ AM_COND_IF([ENABLE_SERVER], [
- ])
- 
- dnl ---------------------------------------------------------------------------
-+dnl - Check if IPA certauth plugin can be build
-+dnl ---------------------------------------------------------------------------
-+
-+AM_CONDITIONAL([BUILD_IPA_CERTAUTH_PLUGIN],
-+               [test x$have_certauth_plugin = xyes -a x"$SSSCERTMAP_LIBS" != x])
-+AM_COND_IF([BUILD_IPA_CERTAUTH_PLUGIN], [
-+    AM_COND_IF([ENABLE_SERVER],
-+               [AC_MSG_NOTICE([Build IPA KDB certauth plugin])],
-+               [AC_MSG_WARN([Cannot build IPA KDB certauth plugin])])
-+])
-+
-+dnl ---------------------------------------------------------------------------
- dnl - Check for program paths
- dnl ---------------------------------------------------------------------------
- AC_PATH_PROG(UNLINK, unlink, [AC_MSG_ERROR([unlink not found])])
-diff --git a/server.m4 b/server.m4
-index 7b2e94df91a4803849e496142788a4ed87ef487d..a4c99195ae535e586445cf5bbe9fef457d224531 100644
---- a/server.m4
-+++ b/server.m4
-@@ -37,11 +37,6 @@ PKG_CHECK_EXISTS([sss_certmap],
- AC_CHECK_HEADER([krb5/certauth_plugin.h],
-                 [have_certauth_plugin=yes],
-                 [have_certauth_plugin=no])
--AM_CONDITIONAL([BUILD_IPA_CERTAUTH_PLUGIN],
--               [test x$have_certauth_plugin = xyes -a x"$SSSCERTMAP_LIBS" != x])
--AM_COND_IF([BUILD_IPA_CERTAUTH_PLUGIN],
--           [AC_MSG_NOTICE([Build IPA KDB certauth plugin])],
--           [AC_MSG_WARN([Cannot build IPA KDB certauth plugin])])
- 
- dnl ---------------------------------------------------------------------------
- dnl - Check for KRB5 krad
--- 
-2.12.1
-
diff --git a/SOURCES/0021-389-ds-base-crashed-as-part-of-ipa-server-intall-in-.patch b/SOURCES/0021-389-ds-base-crashed-as-part-of-ipa-server-intall-in-.patch
new file mode 100644
index 0000000..ef027e3
--- /dev/null
+++ b/SOURCES/0021-389-ds-base-crashed-as-part-of-ipa-server-intall-in-.patch
@@ -0,0 +1,72 @@
+From b047d30b8aabad424fa2bd30872721f9fab9e325 Mon Sep 17 00:00:00 2001
+From: Thierry Bordaz <tbordaz@redhat.com>
+Date: Mon, 25 Sep 2017 16:41:51 +0200
+Subject: [PATCH] 389-ds-base crashed as part of ipa-server-intall in ipa-uuid
+
+Bug Description:
+	When adding an entry, ipa-uuid plugin may generate a unique value
+	for some of its attribute.
+	If the generated attribute is part of the RDN, the target DN
+	is replaced on the fly and the previous one freed.
+	Unfortunately, previous DN may be later used instead of
+	the new one.
+
+Fix Description:
+	Make sure to use only the current DN of the operation
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1496226
+https://pagure.io/freeipa/issue/7227
+
+Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
+---
+ daemons/ipa-slapi-plugins/ipa-uuid/ipa_uuid.c | 12 +++++++++---
+ 1 file changed, 9 insertions(+), 3 deletions(-)
+
+diff --git a/daemons/ipa-slapi-plugins/ipa-uuid/ipa_uuid.c b/daemons/ipa-slapi-plugins/ipa-uuid/ipa_uuid.c
+index ffade14672e8cd9e3f3e18d45a0a7095a6341d30..87d8be2d88d9ff9bbf7d47eab57b765063f7a230 100644
+--- a/daemons/ipa-slapi-plugins/ipa-uuid/ipa_uuid.c
++++ b/daemons/ipa-slapi-plugins/ipa-uuid/ipa_uuid.c
+@@ -911,6 +911,7 @@ static int ipauuid_pre_op(Slapi_PBlock *pb, int modtype)
+         list != ipauuid_global_config;
+         list = PR_NEXT_LINK(list)) {
+         cfgentry = (struct configEntry *) list;
++        char *current_dn = NULL;
+ 
+         generate = false;
+         set_attr = false;
+@@ -920,16 +921,21 @@ static int ipauuid_pre_op(Slapi_PBlock *pb, int modtype)
+                                        cfgentry->attr)) {
+             continue;
+         }
++        /* Current DN may have been reset by
++         * slapi_pblock_set(pb, SLAPI_ADD_TARGET,..) see below
++         * need to reread it
++         */
++        current_dn = ipauuid_get_dn(pb);
+ 
+         /* is the entry in scope? */
+         if (cfgentry->scope) {
+-            if (!slapi_dn_issuffix(dn, cfgentry->scope)) {
++            if (!slapi_dn_issuffix(current_dn, cfgentry->scope)) {
+                 continue;
+             }
+         }
+ 
+         if (cfgentry->exclude_subtree) {
+-                if (slapi_dn_issuffix(dn, cfgentry->exclude_subtree)) {
++                if (slapi_dn_issuffix(current_dn, cfgentry->exclude_subtree)) {
+                         continue;
+                 }
+         }
+@@ -1108,7 +1114,7 @@ static int ipauuid_pre_op(Slapi_PBlock *pb, int modtype)
+                     ret = LDAP_OPERATIONS_ERROR;
+                     goto done;
+                 }
+-                sdn = slapi_sdn_new_dn_byval(dn);
++                sdn = slapi_sdn_new_dn_byval(current_dn);
+                 if (!sdn) {
+                     LOG_OOM();
+                     ret = LDAP_OPERATIONS_ERROR;
+-- 
+2.13.6
+
diff --git a/SOURCES/0021-ipa-kdb-do-not-depend-on-certauth_plugin.h.patch b/SOURCES/0021-ipa-kdb-do-not-depend-on-certauth_plugin.h.patch
deleted file mode 100644
index fcbc083..0000000
--- a/SOURCES/0021-ipa-kdb-do-not-depend-on-certauth_plugin.h.patch
+++ /dev/null
@@ -1,85 +0,0 @@
-From 1c421b3874488c0021a5e0d344be31c84c2b4bd0 Mon Sep 17 00:00:00 2001
-From: Sumit Bose <sbose@redhat.com>
-Date: Mon, 27 Mar 2017 13:19:57 +0200
-Subject: [PATCH] ipa-kdb: do not depend on certauth_plugin.h
-
-Related to https://pagure.io/freeipa/issue/4905
-
-Reviewed-By: Christian Heimes <cheimes@redhat.com>
----
- configure.ac              | 2 ++
- daemons/ipa-kdb/ipa_kdb.c | 2 ++
- daemons/ipa-kdb/ipa_kdb.h | 8 ++++++++
- 3 files changed, 12 insertions(+)
-
-diff --git a/configure.ac b/configure.ac
-index 8d4b82e4590e9e122f7aa5684fd78834c4b6a204..ded1d71fd079a5f6947ef0627fb699783c8cc109 100644
---- a/configure.ac
-+++ b/configure.ac
-@@ -231,6 +231,8 @@ dnl ---------------------------------------------------------------------------
- AM_CONDITIONAL([BUILD_IPA_CERTAUTH_PLUGIN],
-                [test x$have_certauth_plugin = xyes -a x"$SSSCERTMAP_LIBS" != x])
- AM_COND_IF([BUILD_IPA_CERTAUTH_PLUGIN], [
-+    AC_DEFINE([HAVE_KRB5_CERTAUTH_PLUGIN], [1],
-+        [MIT Kerberos version supports certauth plugin])
-     AM_COND_IF([ENABLE_SERVER],
-                [AC_MSG_NOTICE([Build IPA KDB certauth plugin])],
-                [AC_MSG_WARN([Cannot build IPA KDB certauth plugin])])
-diff --git a/daemons/ipa-kdb/ipa_kdb.c b/daemons/ipa-kdb/ipa_kdb.c
-index a961e4e57cf5379eb237551d56e3bc8dc82d952d..050bfc90cef1bce4c932f54bb6050438c60ca79f 100644
---- a/daemons/ipa-kdb/ipa_kdb.c
-+++ b/daemons/ipa-kdb/ipa_kdb.c
-@@ -67,7 +67,9 @@ static void ipadb_context_free(krb5_context kcontext,
-         }
-         free(cfg->authz_data);
- 
-+#ifdef HAVE_KRB5_CERTAUTH_PLUGIN
-         ipa_certauth_free_moddata(&((*ctx)->certauth_moddata));
-+#endif
- 
-         free(*ctx);
-         *ctx = NULL;
-diff --git a/daemons/ipa-kdb/ipa_kdb.h b/daemons/ipa-kdb/ipa_kdb.h
-index 632c1979d15e88aec86d5e408ed6c7017d8362b8..72573a61adecfae152796d61b88b6c43b3a975a3 100644
---- a/daemons/ipa-kdb/ipa_kdb.h
-+++ b/daemons/ipa-kdb/ipa_kdb.h
-@@ -30,6 +30,8 @@
-  * filtering purposes */
- #define SECURID 1
- 
-+#include "config.h"
-+
- #include <errno.h>
- #include <kdb.h>
- #include <ldap.h>
-@@ -40,7 +42,9 @@
- #include <arpa/inet.h>
- #include <endian.h>
- #include <unistd.h>
-+#ifdef HAVE_KRB5_CERTAUTH_PLUGIN
- #include <krb5/certauth_plugin.h>
-+#endif
- 
- #include "ipa_krb5.h"
- #include "ipa_pwd.h"
-@@ -112,7 +116,9 @@ struct ipadb_context {
-     krb5_key_salt_tuple *def_encs;
-     int n_def_encs;
-     struct ipadb_mspac *mspac;
-+#ifdef HAVE_KRB5_CERTAUTH_PLUGIN
-     krb5_certauth_moddata certauth_moddata;
-+#endif
- 
-     /* Don't access this directly, use ipadb_get_global_config(). */
-     struct ipadb_global_config config;
-@@ -334,5 +340,7 @@ int ipadb_get_enc_salt_types(struct ipadb_context *ipactx, LDAPMessage *entry,
-                              char *attr, krb5_key_salt_tuple **enc_salt_types,
-                              int *n_enc_salt_types);
- 
-+#ifdef HAVE_KRB5_CERTAUTH_PLUGIN
- /* CERTAUTH PLUGIN */
- void ipa_certauth_free_moddata(krb5_certauth_moddata *moddata);
-+#endif
--- 
-2.12.1
-
diff --git a/SOURCES/0022-Prevent-set_directive-from-clobbering-other-keys.patch b/SOURCES/0022-Prevent-set_directive-from-clobbering-other-keys.patch
new file mode 100644
index 0000000..85e3e42
--- /dev/null
+++ b/SOURCES/0022-Prevent-set_directive-from-clobbering-other-keys.patch
@@ -0,0 +1,84 @@
+From 8ea1652c64956eea6dd0708f61b3330befcf1a31 Mon Sep 17 00:00:00 2001
+From: Fraser Tweedale <ftweedal@redhat.com>
+Date: Sat, 21 Nov 2020 08:47:57 +1100
+Subject: [PATCH] Prevent set_directive from clobbering other keys
+
+`set_directive` only looks for a prefix of the line matching the
+given directive (key).  If a directive is encountered for which the
+given key is prefix, it will be vanquished.
+
+This occurs in the case of `{ca,kra}.sslserver.cert[req]`; the
+`cert` directive gets updated after certificate renewal, and the
+`certreq` directive gets clobbered.  This can cause failures later
+on during KRA installation, and possibly cloning.
+
+Match the whole directive to avoid this issue.
+
+Fixes: https://pagure.io/freeipa/issue/7288
+Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
+---
+ ipaserver/install/cainstance.py     | 2 +-
+ ipaserver/install/dogtaginstance.py | 2 +-
+ ipaserver/install/installutils.py   | 6 +++---
+ 3 files changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/ipaserver/install/cainstance.py b/ipaserver/install/cainstance.py
+index 62f79b28000b015edb66f4c39a270097ab3ed666..f45d2c8b89ba4b81be5acbbe85f256e85ef630fb 100644
+--- a/ipaserver/install/cainstance.py
++++ b/ipaserver/install/cainstance.py
+@@ -931,7 +931,7 @@ class CAInstance(DogtagInstance):
+         installutils.set_directive(caconfig, 'ca.publish.rule.instance.FileCrlRule.enable', 'true', quotes=False, separator='=')
+         installutils.set_directive(caconfig, 'ca.publish.rule.instance.FileCrlRule.mapper', 'NoMap', quotes=False, separator='=')
+         installutils.set_directive(caconfig, 'ca.publish.rule.instance.FileCrlRule.pluginName', 'Rule', quotes=False, separator='=')
+-        installutils.set_directive(caconfig, 'ca.publish.rule.instance.FileCrlRule.predicate=', '', quotes=False, separator='')
++        installutils.set_directive(caconfig, 'ca.publish.rule.instance.FileCrlRule.predicate', '', quotes=False, separator='=')
+         installutils.set_directive(caconfig, 'ca.publish.rule.instance.FileCrlRule.publisher', 'FileBaseCRLPublisher', quotes=False, separator='=')
+         installutils.set_directive(caconfig, 'ca.publish.rule.instance.FileCrlRule.type', 'crl', quotes=False, separator='=')
+ 
+diff --git a/ipaserver/install/dogtaginstance.py b/ipaserver/install/dogtaginstance.py
+index 1fdc3e50a46877374e4f1aa8435d09f6b4e62180..9470e1a13608a8a84aab8a36c269a708e3f3e9f4 100644
+--- a/ipaserver/install/dogtaginstance.py
++++ b/ipaserver/install/dogtaginstance.py
+@@ -212,7 +212,7 @@ class DogtagInstance(service.Service):
+                 separator='=')
+             # Remove internaldb password as is not needed anymore
+             installutils.set_directive(paths.PKI_TOMCAT_PASSWORD_CONF,
+-                                       'internaldb', None)
++                                       'internaldb', None, separator='=')
+ 
+     def uninstall(self):
+         if self.is_installed():
+diff --git a/ipaserver/install/installutils.py b/ipaserver/install/installutils.py
+index 01930c4de6f0edd16b31aeba1c926fe581e9635b..821609beb533fcc9064500a88ccd07b35142f1df 100644
+--- a/ipaserver/install/installutils.py
++++ b/ipaserver/install/installutils.py
+@@ -433,7 +433,7 @@ def set_directive(filename, directive, value, quotes=True, separator=' '):
+ 
+     A value of None means to drop the directive.
+ 
+-    This has only been tested with nss.conf
++    Does not tolerate (or put) spaces around the separator.
+ 
+     :param filename: input filename
+     :param directive: directive name
+@@ -442,7 +442,7 @@ def set_directive(filename, directive, value, quotes=True, separator=' '):
+         any existing double quotes are first escaped to avoid
+         unparseable directives.
+     :param separator: character serving as separator between directive and
+-        value
++        value.  Correct value required even when dropping a directive.
+     """
+ 
+     new_directive_value = ""
+@@ -457,7 +457,7 @@ def set_directive(filename, directive, value, quotes=True, separator=' '):
+     fd = open(filename)
+     newfile = []
+     for line in fd:
+-        if line.lstrip().startswith(directive):
++        if re.match(r'\s*{}'.format(re.escape(directive + separator)), line):
+             valueset = True
+             if value is not None:
+                 newfile.append(new_directive_value)
+-- 
+2.13.6
+
diff --git a/SOURCES/0022-WebUI-Add-support-for-suppressing-warnings.patch b/SOURCES/0022-WebUI-Add-support-for-suppressing-warnings.patch
deleted file mode 100644
index 8a4d26c..0000000
--- a/SOURCES/0022-WebUI-Add-support-for-suppressing-warnings.patch
+++ /dev/null
@@ -1,46 +0,0 @@
-From 3d8b42ac1e532168c2dae96ab0de3d83df0268d0 Mon Sep 17 00:00:00 2001
-From: Pavel Vomacka <pvomacka@redhat.com>
-Date: Fri, 17 Mar 2017 15:10:42 +0100
-Subject: [PATCH] WebUI: Add support for suppressing warnings
-
-Each command can have specified an array of warning codes which will
-be suppressed and won't be shown.
-
-For specifying this it is necessary to set command property
-'supressed_warnings: [codes_of_warning]'
-
-Part of: https://pagure.io/freeipa/issue/6618
-
-Reviewed-By: Petr Vobornik <pvoborni@redhat.com>
----
- install/ui/src/freeipa/rpc.js | 7 +++++++
- 1 file changed, 7 insertions(+)
-
-diff --git a/install/ui/src/freeipa/rpc.js b/install/ui/src/freeipa/rpc.js
-index 1880f8d5732f982c25924b787b273c9e56636b20..84282f78d940ac2d18d00df92a7430ca51bbf389 100644
---- a/install/ui/src/freeipa/rpc.js
-+++ b/install/ui/src/freeipa/rpc.js
-@@ -72,6 +72,12 @@ rpc.command = function(spec) {
-     that.options = $.extend({}, spec.options || {});
- 
-     /**
-+     * @property {Array} suppress_warnings array of message codes which
-+     * are suppressed
-+     */
-+    that.suppress_warnings = spec.suppress_warnings || [];
-+
-+    /**
-      * Success handler
-      * @property {Function}
-      * @param {Object} data
-@@ -219,6 +225,7 @@ rpc.command = function(spec) {
- 
-         for (var i=0,l=msgs.length; i<l; i++) {
-             var msg = lang.clone(msgs[i]);
-+            if (that.suppress_warnings.indexOf(msg.code) > -1) continue;
-             // escape and reformat message
-             msg.message = util.beautify_message(msg.message);
-             IPA.notify(msg.message, msg.type);
--- 
-2.12.1
-
diff --git a/SOURCES/0023-WebUI-suppress-truncation-warning-in-select-widget.patch b/SOURCES/0023-WebUI-suppress-truncation-warning-in-select-widget.patch
deleted file mode 100644
index b36a576..0000000
--- a/SOURCES/0023-WebUI-suppress-truncation-warning-in-select-widget.patch
+++ /dev/null
@@ -1,37 +0,0 @@
-From 66ea6269d7ad401e5f89b1ab33f8e827efb25dd8 Mon Sep 17 00:00:00 2001
-From: Pavel Vomacka <pvomacka@redhat.com>
-Date: Fri, 17 Mar 2017 15:10:49 +0100
-Subject: [PATCH] WebUI: suppress truncation warning in select widget
-
-This widget is used on details pages and dialogs. When the size limit
-is set to lower number the warning about truncation was shown every time
-the details page was open.
-
-Now, with support for suppressing warning messages from server according
-to its code, we are able to disable warning with 13017 code (truncation
-warning)
-
-https://pagure.io/freeipa/issue/6618
-
-Reviewed-By: Petr Vobornik <pvoborni@redhat.com>
----
- install/ui/src/freeipa/widget.js | 3 ++-
- 1 file changed, 2 insertions(+), 1 deletion(-)
-
-diff --git a/install/ui/src/freeipa/widget.js b/install/ui/src/freeipa/widget.js
-index 223b449962fabb47cf72b0443e39c295c783ab7f..b7a6504cf4af942c99ee217a2b47718af9e40f86 100644
---- a/install/ui/src/freeipa/widget.js
-+++ b/install/ui/src/freeipa/widget.js
-@@ -5012,7 +5012,8 @@ IPA.entity_select_widget = function(spec) {
-             entity: that.other_entity.name,
-             method: 'find',
-             args: [filter],
--            options: that.filter_options
-+            options: that.filter_options,
-+            suppress_warnings: [13017]
-         });
-         var no_members = metadata.get('@mc-opt:' + cmd.get_command() + ':no_members');
-         if (no_members) {
--- 
-2.12.1
-
diff --git a/SOURCES/0023-pep8-reduce-line-lengths-in-CAInstance.__enable_crl_.patch b/SOURCES/0023-pep8-reduce-line-lengths-in-CAInstance.__enable_crl_.patch
new file mode 100644
index 0000000..e0f1a0c
--- /dev/null
+++ b/SOURCES/0023-pep8-reduce-line-lengths-in-CAInstance.__enable_crl_.patch
@@ -0,0 +1,113 @@
+From a87278422807aa4004b63e8e46ad38dab5a911f3 Mon Sep 17 00:00:00 2001
+From: Fraser Tweedale <ftweedal@redhat.com>
+Date: Thu, 30 Nov 2017 12:00:53 +1100
+Subject: [PATCH] pep8: reduce line lengths in CAInstance.__enable_crl_publish
+
+Part of: https://pagure.io/freeipa/issue/7288
+
+Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
+---
+ ipaserver/install/cainstance.py | 71 ++++++++++++++++++++++++-----------------
+ 1 file changed, 41 insertions(+), 30 deletions(-)
+
+diff --git a/ipaserver/install/cainstance.py b/ipaserver/install/cainstance.py
+index f45d2c8b89ba4b81be5acbbe85f256e85ef630fb..dd410d1c97cb4b27d35086bb2f511c42c02d022f 100644
+--- a/ipaserver/install/cainstance.py
++++ b/ipaserver/install/cainstance.py
+@@ -907,52 +907,63 @@ class CAInstance(DogtagInstance):
+ 
+         https://access.redhat.com/knowledge/docs/en-US/Red_Hat_Certificate_System/8.0/html/Admin_Guide/Setting_up_Publishing.html
+         """
+-        caconfig = paths.CA_CS_CFG_PATH
+ 
+-        publishdir = self.prepare_crl_publish_dir()
++        def put(k, v):
++            installutils.set_directive(
++                paths.CA_CS_CFG_PATH, k, v, quotes=False, separator='=')
+ 
+         # Enable file publishing, disable LDAP
+-        installutils.set_directive(caconfig, 'ca.publish.enable', 'true', quotes=False, separator='=')
+-        installutils.set_directive(caconfig, 'ca.publish.ldappublish.enable', 'false', quotes=False, separator='=')
++        put('ca.publish.enable', 'true')
++        put('ca.publish.ldappublish.enable', 'false')
+ 
+         # Create the file publisher, der only, not b64
+-        installutils.set_directive(caconfig, 'ca.publish.publisher.impl.FileBasedPublisher.class','com.netscape.cms.publish.publishers.FileBasedPublisher', quotes=False, separator='=')
+-        installutils.set_directive(caconfig, 'ca.publish.publisher.instance.FileBaseCRLPublisher.crlLinkExt', 'bin', quotes=False, separator='=')
+-        installutils.set_directive(caconfig, 'ca.publish.publisher.instance.FileBaseCRLPublisher.directory', publishdir, quotes=False, separator='=')
+-        installutils.set_directive(caconfig, 'ca.publish.publisher.instance.FileBaseCRLPublisher.latestCrlLink', 'true', quotes=False, separator='=')
+-        installutils.set_directive(caconfig, 'ca.publish.publisher.instance.FileBaseCRLPublisher.pluginName', 'FileBasedPublisher', quotes=False, separator='=')
+-        installutils.set_directive(caconfig, 'ca.publish.publisher.instance.FileBaseCRLPublisher.timeStamp', 'LocalTime', quotes=False, separator='=')
+-        installutils.set_directive(caconfig, 'ca.publish.publisher.instance.FileBaseCRLPublisher.zipCRLs', 'false', quotes=False, separator='=')
+-        installutils.set_directive(caconfig, 'ca.publish.publisher.instance.FileBaseCRLPublisher.zipLevel', '9', quotes=False, separator='=')
+-        installutils.set_directive(caconfig, 'ca.publish.publisher.instance.FileBaseCRLPublisher.Filename.b64', 'false', quotes=False, separator='=')
+-        installutils.set_directive(caconfig, 'ca.publish.publisher.instance.FileBaseCRLPublisher.Filename.der', 'true', quotes=False, separator='=')
++        put('ca.publish.publisher.impl.FileBasedPublisher.class',
++            'com.netscape.cms.publish.publishers.FileBasedPublisher')
++        put('ca.publish.publisher.instance.FileBaseCRLPublisher.crlLinkExt',
++            'bin')
++        put('ca.publish.publisher.instance.FileBaseCRLPublisher.directory',
++            self.prepare_crl_publish_dir())
++        put('ca.publish.publisher.instance.FileBaseCRLPublisher.latestCrlLink',
++            'true')
++        put('ca.publish.publisher.instance.FileBaseCRLPublisher.pluginName',
++            'FileBasedPublisher')
++        put('ca.publish.publisher.instance.FileBaseCRLPublisher.timeStamp',
++            'LocalTime')
++        put('ca.publish.publisher.instance.FileBaseCRLPublisher.zipCRLs',
++            'false')
++        put('ca.publish.publisher.instance.FileBaseCRLPublisher.zipLevel', '9')
++        put('ca.publish.publisher.instance.FileBaseCRLPublisher.Filename.b64',
++            'false')
++        put('ca.publish.publisher.instance.FileBaseCRLPublisher.Filename.der',
++            'true')
+ 
+         # The publishing rule
+-        installutils.set_directive(caconfig, 'ca.publish.rule.instance.FileCrlRule.enable', 'true', quotes=False, separator='=')
+-        installutils.set_directive(caconfig, 'ca.publish.rule.instance.FileCrlRule.mapper', 'NoMap', quotes=False, separator='=')
+-        installutils.set_directive(caconfig, 'ca.publish.rule.instance.FileCrlRule.pluginName', 'Rule', quotes=False, separator='=')
+-        installutils.set_directive(caconfig, 'ca.publish.rule.instance.FileCrlRule.predicate', '', quotes=False, separator='=')
+-        installutils.set_directive(caconfig, 'ca.publish.rule.instance.FileCrlRule.publisher', 'FileBaseCRLPublisher', quotes=False, separator='=')
+-        installutils.set_directive(caconfig, 'ca.publish.rule.instance.FileCrlRule.type', 'crl', quotes=False, separator='=')
++        put('ca.publish.rule.instance.FileCrlRule.enable', 'true')
++        put('ca.publish.rule.instance.FileCrlRule.mapper', 'NoMap')
++        put('ca.publish.rule.instance.FileCrlRule.pluginName', 'Rule')
++        put('ca.publish.rule.instance.FileCrlRule.predicate', '')
++        put('ca.publish.rule.instance.FileCrlRule.publisher',
++            'FileBaseCRLPublisher')
++        put('ca.publish.rule.instance.FileCrlRule.type', 'crl')
+ 
+         # Now disable LDAP publishing
+-        installutils.set_directive(caconfig, 'ca.publish.rule.instance.LdapCaCertRule.enable', 'false', quotes=False, separator='=')
+-        installutils.set_directive(caconfig, 'ca.publish.rule.instance.LdapCrlRule.enable', 'false', quotes=False, separator='=')
+-        installutils.set_directive(caconfig, 'ca.publish.rule.instance.LdapUserCertRule.enable', 'false', quotes=False, separator='=')
+-        installutils.set_directive(caconfig, 'ca.publish.rule.instance.LdapXCertRule.enable', 'false', quotes=False, separator='=')
++        put('ca.publish.rule.instance.LdapCaCertRule.enable', 'false')
++        put('ca.publish.rule.instance.LdapCrlRule.enable', 'false')
++        put('ca.publish.rule.instance.LdapUserCertRule.enable', 'false')
++        put('ca.publish.rule.instance.LdapXCertRule.enable', 'false')
+ 
+         # If we are the initial master then we are the CRL generator, otherwise
+         # we point to that master for CRLs.
+         if not self.clone:
+             # These next two are defaults, but I want to be explicit that the
+             # initial master is the CRL generator.
+-            installutils.set_directive(caconfig, 'ca.crl.MasterCRL.enableCRLCache', 'true', quotes=False, separator='=')
+-            installutils.set_directive(caconfig, 'ca.crl.MasterCRL.enableCRLUpdates', 'true', quotes=False, separator='=')
+-            installutils.set_directive(caconfig, 'ca.listenToCloneModifications', 'true', quotes=False, separator='=')
++            put('ca.crl.MasterCRL.enableCRLCache', 'true')
++            put('ca.crl.MasterCRL.enableCRLUpdates', 'true')
++            put('ca.listenToCloneModifications', 'true')
+         else:
+-            installutils.set_directive(caconfig, 'ca.crl.MasterCRL.enableCRLCache', 'false', quotes=False, separator='=')
+-            installutils.set_directive(caconfig, 'ca.crl.MasterCRL.enableCRLUpdates', 'false', quotes=False, separator='=')
+-            installutils.set_directive(caconfig, 'ca.listenToCloneModifications', 'false', quotes=False, separator='=')
++            put('ca.crl.MasterCRL.enableCRLCache', 'false')
++            put('ca.crl.MasterCRL.enableCRLUpdates', 'false')
++            put('ca.listenToCloneModifications', 'false')
+ 
+     def uninstall(self):
+         # just eat state
+-- 
+2.13.6
+
diff --git a/SOURCES/0024-WebUI-Fix-showing-vault-in-selfservice-view.patch b/SOURCES/0024-WebUI-Fix-showing-vault-in-selfservice-view.patch
deleted file mode 100644
index d729a24..0000000
--- a/SOURCES/0024-WebUI-Fix-showing-vault-in-selfservice-view.patch
+++ /dev/null
@@ -1,54 +0,0 @@
-From 5ccffb9ca109d820c5535140713a5b6672aa4f71 Mon Sep 17 00:00:00 2001
-From: Pavel Vomacka <pvomacka@redhat.com>
-Date: Fri, 24 Mar 2017 10:19:21 +0100
-Subject: [PATCH] WebUI: Fix showing vault in selfservice view
-
-Vaults menu item was shown even when the KRA service was not installed.
-That was caused by different path to the menu item in admin's view
-and in selfservice view.
-
-The path is now set correctly for both situations. 'network_service/vault'
-for admin's view and 'vault' for selfservice view.
-
-https://pagure.io/freeipa/issue/6812
-
-Reviewed-By: Petr Vobornik <pvoborni@redhat.com>
----
- install/ui/src/freeipa/navigation/menu_spec.js | 1 +
- install/ui/src/freeipa/vault.js                | 8 +++++---
- 2 files changed, 6 insertions(+), 3 deletions(-)
-
-diff --git a/install/ui/src/freeipa/navigation/menu_spec.js b/install/ui/src/freeipa/navigation/menu_spec.js
-index 9329694c14a47cbe1ec244554327b40743044d7b..0c30459691d8f652dc35ccf74ed27fae7654020d 100644
---- a/install/ui/src/freeipa/navigation/menu_spec.js
-+++ b/install/ui/src/freeipa/navigation/menu_spec.js
-@@ -326,6 +326,7 @@ nav.self_service = {
-         { entity: 'user' },
-         { entity: 'otptoken' },
-         {
-+            name: 'vault',
-             entity: 'vault',
-             facet: 'search',
-             children: [
-diff --git a/install/ui/src/freeipa/vault.js b/install/ui/src/freeipa/vault.js
-index b5cdc810adea9b521df77eb328b55475a707580a..36a4838ee108020cf6ad7a20c59e4ab5403f3528 100644
---- a/install/ui/src/freeipa/vault.js
-+++ b/install/ui/src/freeipa/vault.js
-@@ -809,9 +809,11 @@ vault.config_sidebar_policy = function(spec) {
- 
- 
- vault.remove_vault_menu_item = function() {
--    if (!IPA.vault_enabled) {
--        menu.remove_item('network_services/vault');
--    }
-+    if (IPA.vault_enabled) return;
-+
-+    var menu_location = IPA.is_selfservice ? 'vault' : 'network_services/vault';
-+
-+    menu.remove_item(menu_location);
- };
- 
- vault.my_vault_spec = make_my_vault_spec();
--- 
-2.12.1
-
diff --git a/SOURCES/0024-installutils-refactor-set_directive.patch b/SOURCES/0024-installutils-refactor-set_directive.patch
new file mode 100644
index 0000000..643edb9
--- /dev/null
+++ b/SOURCES/0024-installutils-refactor-set_directive.patch
@@ -0,0 +1,92 @@
+From 25a6726a350fd4192b45a78b6312ab8345b02586 Mon Sep 17 00:00:00 2001
+From: Fraser Tweedale <ftweedal@redhat.com>
+Date: Tue, 5 Dec 2017 13:43:04 +1100
+Subject: [PATCH] installutils: refactor set_directive
+
+To separate concerns and make it easier to test set_directive,
+extract function ``set_directive_lines`` to do the line-wise
+search/replace, leaving ``set_directive`` to deal with the file
+handling.
+
+Part of: https://pagure.io/freeipa/issue/7288
+
+Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
+---
+ ipaserver/install/installutils.py | 56 +++++++++++++++++++++++----------------
+ 1 file changed, 33 insertions(+), 23 deletions(-)
+
+diff --git a/ipaserver/install/installutils.py b/ipaserver/install/installutils.py
+index 821609beb533fcc9064500a88ccd07b35142f1df..b56cf591496c679e5fcf3e94f458c286216eb1e4 100644
+--- a/ipaserver/install/installutils.py
++++ b/ipaserver/install/installutils.py
+@@ -444,34 +444,44 @@ def set_directive(filename, directive, value, quotes=True, separator=' '):
+     :param separator: character serving as separator between directive and
+         value.  Correct value required even when dropping a directive.
+     """
++    st = os.stat(filename)
++    with open(filename, 'r') as f:
++        lines = list(f)  # read the whole file
++        new_lines = set_directive_lines(
++            quotes, separator, directive, value, lines)
++    with open(filename, 'w') as f:
++        # don't construct the whole string; write line-wise
++        for line in new_lines:
++            f.write(line)
++    os.chown(filename, st.st_uid, st.st_gid)  # reset perms
+ 
+-    new_directive_value = ""
+-    if value is not None:
+-        value_to_set = quote_directive_value(value, '"') if quotes else value
+ 
+-        new_directive_value = "".join(
+-            [directive, separator, value_to_set, '\n'])
++def set_directive_lines(quotes, separator, k, v, lines):
++    """Set a name/value pair in a configuration (iterable of lines).
+ 
+-    valueset = False
+-    st = os.stat(filename)
+-    fd = open(filename)
+-    newfile = []
+-    for line in fd:
+-        if re.match(r'\s*{}'.format(re.escape(directive + separator)), line):
+-            valueset = True
+-            if value is not None:
+-                newfile.append(new_directive_value)
++    Replaces the value of the key if found, otherwise adds it at
++    end.  If value is ``None``, remove the key if found.
++
++    Takes an iterable of lines (with trailing newline).
++    Yields lines (with trailing newline).
++
++    """
++    new_line = ""
++    if v is not None:
++        v_quoted = quote_directive_value(v, '"') if quotes else v
++        new_line = ''.join([k, separator, v_quoted, '\n'])
++
++    found = False
++    for line in lines:
++        if re.match(r'\s*{}'.format(re.escape(k + separator)), line):
++            found = True
++            if v is not None:
++                yield new_line
+         else:
+-            newfile.append(line)
+-    fd.close()
+-    if not valueset:
+-        if value is not None:
+-            newfile.append(new_directive_value)
++            yield line
+ 
+-    fd = open(filename, "w")
+-    fd.write("".join(newfile))
+-    fd.close()
+-    os.chown(filename, st.st_uid, st.st_gid) # reset perms
++    if not found and v is not None:
++        yield new_line
+ 
+ 
+ def get_directive(filename, directive, separator=' '):
+-- 
+2.13.6
+
diff --git a/SOURCES/0025-Add-tests-for-installutils.set_directive.patch b/SOURCES/0025-Add-tests-for-installutils.set_directive.patch
new file mode 100644
index 0000000..da5f49a
--- /dev/null
+++ b/SOURCES/0025-Add-tests-for-installutils.set_directive.patch
@@ -0,0 +1,79 @@
+From 8ffdc78b211c025c19636a5f5dcd12d12191aee4 Mon Sep 17 00:00:00 2001
+From: Fraser Tweedale <ftweedal@redhat.com>
+Date: Tue, 5 Dec 2017 15:00:18 +1100
+Subject: [PATCH] Add tests for installutils.set_directive
+
+Part of: https://pagure.io/freeipa/issue/7288
+
+Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
+---
+ .../test_install/test_installutils.py              | 57 ++++++++++++++++++++++
+ 1 file changed, 57 insertions(+)
+ create mode 100644 ipatests/test_ipaserver/test_install/test_installutils.py
+
+diff --git a/ipatests/test_ipaserver/test_install/test_installutils.py b/ipatests/test_ipaserver/test_install/test_installutils.py
+new file mode 100644
+index 0000000000000000000000000000000000000000..cc8fd3cf3f82c2d9af48287f506a566ffbfc39f6
+--- /dev/null
++++ b/ipatests/test_ipaserver/test_install/test_installutils.py
+@@ -0,0 +1,57 @@
++#
++# Copyright (C) 2017  FreeIPA Contributors.  See COPYING for license
++#
++
++import os
++import tempfile
++
++from ipaserver.install import installutils
++
++EXAMPLE_CONFIG = [
++    'foo=1\n',
++    'foobar=2\n',
++]
++
++
++class test_set_directive_lines(object):
++    def test_remove_directive(self):
++        lines = installutils.set_directive_lines(
++            False, '=', 'foo', None, EXAMPLE_CONFIG)
++        assert list(lines) == ['foobar=2\n']
++
++    def test_add_directive(self):
++        lines = installutils.set_directive_lines(
++            False, '=', 'baz', '4', EXAMPLE_CONFIG)
++        assert list(lines) == ['foo=1\n', 'foobar=2\n', 'baz=4\n']
++
++    def test_set_directive_does_not_clobber_suffix_key(self):
++        lines = installutils.set_directive_lines(
++            False, '=', 'foo', '3', EXAMPLE_CONFIG)
++        assert list(lines) == ['foo=3\n', 'foobar=2\n']
++
++
++class test_set_directive(object):
++    def test_set_directive(self):
++        """Check that set_directive writes the new data and preserves mode."""
++        fd, filename = tempfile.mkstemp()
++        try:
++            os.close(fd)
++            stat_pre = os.stat(filename)
++
++            with open(filename, 'w') as f:
++                for line in EXAMPLE_CONFIG:
++                    f.write(line)
++
++            installutils.set_directive(filename, 'foo', '3', False, '=')
++
++            stat_post = os.stat(filename)
++            with open(filename, 'r') as f:
++                lines = list(f)
++
++            assert lines == ['foo=3\n', 'foobar=2\n']
++            assert stat_pre.st_mode == stat_post.st_mode
++            assert stat_pre.st_uid == stat_post.st_uid
++            assert stat_pre.st_gid == stat_post.st_gid
++
++        finally:
++            os.remove(filename)
+-- 
+2.13.6
+
diff --git a/SOURCES/0025-Set-KDC-Disable-Last-Success-by-default.patch b/SOURCES/0025-Set-KDC-Disable-Last-Success-by-default.patch
deleted file mode 100644
index f5abe43..0000000
--- a/SOURCES/0025-Set-KDC-Disable-Last-Success-by-default.patch
+++ /dev/null
@@ -1,35 +0,0 @@
-From ac3c0d46d947c59aa25f4c9268ef17023c87b4b2 Mon Sep 17 00:00:00 2001
-From: Martin Basti <mbasti@redhat.com>
-Date: Wed, 22 Mar 2017 17:47:04 +0100
-Subject: [PATCH] Set "KDC:Disable Last Success" by default
-
-In big deployments enabled recording of the last sucesfull login
-this creates a huge changelog on DS side and cause performance
-issues even if this is excluded from replication.
-
-Actually this is not used directly by FreeIPA so it is safe to remove
-in new installations. User who need this must manually remove
-"KDC:Disable Last Success" using `ipa config-mod` command or WebUI.
-
-https://pagure.io/freeipa/issue/5313
-
-Reviewed-By: Stanislav Laznicka <slaznick@redhat.com>
----
- install/share/bootstrap-template.ldif | 1 +
- 1 file changed, 1 insertion(+)
-
-diff --git a/install/share/bootstrap-template.ldif b/install/share/bootstrap-template.ldif
-index da12ddf0ca887e8305402048ceed5d5b28816164..ea1e5b222e7af5ed7c5d80bbaf9282735e425e18 100644
---- a/install/share/bootstrap-template.ldif
-+++ b/install/share/bootstrap-template.ldif
-@@ -410,6 +410,7 @@ ipaUserObjectClasses: ipasshuser
- ipaDefaultEmailDomain: $DOMAIN
- ipaMigrationEnabled: FALSE
- ipaConfigString: AllowNThash
-+ipaConfigString: KDC:Disable Last Success
- ipaSELinuxUserMapOrder: guest_u:s0$$xguest_u:s0$$user_u:s0$$staff_u:s0-s0:c0.c1023$$unconfined_u:s0-s0:c0.c1023
- ipaSELinuxUserMapDefault: unconfined_u:s0-s0:c0.c1023
- 
--- 
-2.12.1
-
diff --git a/SOURCES/0026-Add-safe-DirectiveSetter-context-manager.patch b/SOURCES/0026-Add-safe-DirectiveSetter-context-manager.patch
new file mode 100644
index 0000000..c142e7a
--- /dev/null
+++ b/SOURCES/0026-Add-safe-DirectiveSetter-context-manager.patch
@@ -0,0 +1,365 @@
+From dda1087a2e6e0f5fcb8623983f5296b8a426cfc5 Mon Sep 17 00:00:00 2001
+From: Christian Heimes <cheimes@redhat.com>
+Date: Fri, 8 Dec 2017 12:38:41 +0100
+Subject: [PATCH] Add safe DirectiveSetter context manager
+
+installutils.set_directive() is both inefficient and potentially
+dangerous. It does not ensure that the whole file is written and
+properly synced to disk. In worst case it could lead to partially
+written or destroyed config files.
+
+The new DirectiveSetter context manager wraps everything under an easy
+to use interface.
+
+https://pagure.io/freeipa/issue/7312
+
+Signed-off-by: Christian Heimes <cheimes@redhat.com>
+Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
+---
+ ipaserver/install/cainstance.py                    | 109 ++++++++++-----------
+ ipaserver/install/installutils.py                  |  87 +++++++++++++++-
+ .../test_install/test_installutils.py              |  67 +++++++++++++
+ 3 files changed, 205 insertions(+), 58 deletions(-)
+
+diff --git a/ipaserver/install/cainstance.py b/ipaserver/install/cainstance.py
+index dd410d1c97cb4b27d35086bb2f511c42c02d022f..20635eae22268ff72de73b8b9c430050114bb45b 100644
+--- a/ipaserver/install/cainstance.py
++++ b/ipaserver/install/cainstance.py
+@@ -908,62 +908,61 @@ class CAInstance(DogtagInstance):
+         https://access.redhat.com/knowledge/docs/en-US/Red_Hat_Certificate_System/8.0/html/Admin_Guide/Setting_up_Publishing.html
+         """
+ 
+-        def put(k, v):
+-            installutils.set_directive(
+-                paths.CA_CS_CFG_PATH, k, v, quotes=False, separator='=')
++        with installutils.DirectiveSetter(paths.CA_CS_CFG_PATH,
++                                          quotes=False, separator='=') as ds:
+ 
+-        # Enable file publishing, disable LDAP
+-        put('ca.publish.enable', 'true')
+-        put('ca.publish.ldappublish.enable', 'false')
+-
+-        # Create the file publisher, der only, not b64
+-        put('ca.publish.publisher.impl.FileBasedPublisher.class',
+-            'com.netscape.cms.publish.publishers.FileBasedPublisher')
+-        put('ca.publish.publisher.instance.FileBaseCRLPublisher.crlLinkExt',
+-            'bin')
+-        put('ca.publish.publisher.instance.FileBaseCRLPublisher.directory',
+-            self.prepare_crl_publish_dir())
+-        put('ca.publish.publisher.instance.FileBaseCRLPublisher.latestCrlLink',
+-            'true')
+-        put('ca.publish.publisher.instance.FileBaseCRLPublisher.pluginName',
+-            'FileBasedPublisher')
+-        put('ca.publish.publisher.instance.FileBaseCRLPublisher.timeStamp',
+-            'LocalTime')
+-        put('ca.publish.publisher.instance.FileBaseCRLPublisher.zipCRLs',
+-            'false')
+-        put('ca.publish.publisher.instance.FileBaseCRLPublisher.zipLevel', '9')
+-        put('ca.publish.publisher.instance.FileBaseCRLPublisher.Filename.b64',
+-            'false')
+-        put('ca.publish.publisher.instance.FileBaseCRLPublisher.Filename.der',
+-            'true')
+-
+-        # The publishing rule
+-        put('ca.publish.rule.instance.FileCrlRule.enable', 'true')
+-        put('ca.publish.rule.instance.FileCrlRule.mapper', 'NoMap')
+-        put('ca.publish.rule.instance.FileCrlRule.pluginName', 'Rule')
+-        put('ca.publish.rule.instance.FileCrlRule.predicate', '')
+-        put('ca.publish.rule.instance.FileCrlRule.publisher',
+-            'FileBaseCRLPublisher')
+-        put('ca.publish.rule.instance.FileCrlRule.type', 'crl')
+-
+-        # Now disable LDAP publishing
+-        put('ca.publish.rule.instance.LdapCaCertRule.enable', 'false')
+-        put('ca.publish.rule.instance.LdapCrlRule.enable', 'false')
+-        put('ca.publish.rule.instance.LdapUserCertRule.enable', 'false')
+-        put('ca.publish.rule.instance.LdapXCertRule.enable', 'false')
+-
+-        # If we are the initial master then we are the CRL generator, otherwise
+-        # we point to that master for CRLs.
+-        if not self.clone:
+-            # These next two are defaults, but I want to be explicit that the
+-            # initial master is the CRL generator.
+-            put('ca.crl.MasterCRL.enableCRLCache', 'true')
+-            put('ca.crl.MasterCRL.enableCRLUpdates', 'true')
+-            put('ca.listenToCloneModifications', 'true')
+-        else:
+-            put('ca.crl.MasterCRL.enableCRLCache', 'false')
+-            put('ca.crl.MasterCRL.enableCRLUpdates', 'false')
+-            put('ca.listenToCloneModifications', 'false')
++            # Enable file publishing, disable LDAP
++            ds.set('ca.publish.enable', 'true')
++            ds.set('ca.publish.ldappublish.enable', 'false')
++
++            # Create the file publisher, der only, not b64
++            ds.set(
++                'ca.publish.publisher.impl.FileBasedPublisher.class',
++                'com.netscape.cms.publish.publishers.FileBasedPublisher'
++            )
++            prefix = 'ca.publish.publisher.instance.FileBaseCRLPublisher.'
++            ds.set(prefix + 'crlLinkExt', 'bin')
++            ds.set(prefix + 'directory', self.prepare_crl_publish_dir())
++            ds.set(prefix + 'latestCrlLink', 'true')
++            ds.set(prefix + 'pluginName', 'FileBasedPublisher')
++            ds.set(prefix + 'timeStamp', 'LocalTime')
++            ds.set(prefix + 'zipCRLs', 'false')
++            ds.set(prefix + 'zipLevel', '9')
++            ds.set(prefix + 'Filename.b64', 'false')
++            ds.set(prefix + 'Filename.der', 'true')
++
++            # The publishing rule
++            ds.set('ca.publish.rule.instance.FileCrlRule.enable', 'true')
++            ds.set('ca.publish.rule.instance.FileCrlRule.mapper', 'NoMap')
++            ds.set('ca.publish.rule.instance.FileCrlRule.pluginName', 'Rule')
++            ds.set('ca.publish.rule.instance.FileCrlRule.predicate', '')
++            ds.set(
++                'ca.publish.rule.instance.FileCrlRule.publisher',
++                'FileBaseCRLPublisher'
++            )
++            ds.set('ca.publish.rule.instance.FileCrlRule.type', 'crl')
++
++            # Now disable LDAP publishing
++            ds.set('ca.publish.rule.instance.LdapCaCertRule.enable', 'false')
++            ds.set('ca.publish.rule.instance.LdapCrlRule.enable', 'false')
++            ds.set(
++                'ca.publish.rule.instance.LdapUserCertRule.enable',
++                'false'
++            )
++            ds.set('ca.publish.rule.instance.LdapXCertRule.enable', 'false')
++
++            # If we are the initial master then we are the CRL generator,
++            # otherwise we point to that master for CRLs.
++            if not self.clone:
++                # These next two are defaults, but I want to be explicit
++                # that the initial master is the CRL generator.
++                ds.set('ca.crl.MasterCRL.enableCRLCache', 'true')
++                ds.set('ca.crl.MasterCRL.enableCRLUpdates', 'true')
++                ds.set('ca.listenToCloneModifications', 'true')
++            else:
++                ds.set('ca.crl.MasterCRL.enableCRLCache', 'false')
++                ds.set('ca.crl.MasterCRL.enableCRLUpdates', 'false')
++                ds.set('ca.listenToCloneModifications', 'false')
+ 
+     def uninstall(self):
+         # just eat state
+diff --git a/ipaserver/install/installutils.py b/ipaserver/install/installutils.py
+index b56cf591496c679e5fcf3e94f458c286216eb1e4..08e098f8656c8fe61a87fb046c01e1487c25da7f 100644
+--- a/ipaserver/install/installutils.py
++++ b/ipaserver/install/installutils.py
+@@ -24,6 +24,7 @@ import errno
+ import socket
+ import getpass
+ import gssapi
++import io
+ import ldif
+ import os
+ import re
+@@ -31,6 +32,7 @@ import fileinput
+ import sys
+ import tempfile
+ import shutil
++import stat  # pylint: disable=bad-python3-import
+ import traceback
+ import textwrap
+ from contextlib import contextmanager
+@@ -428,6 +430,82 @@ def unquote_directive_value(value, quote_char):
+     return unescaped_value
+ 
+ 
++_SENTINEL = object()
++
++
++class DirectiveSetter(object):
++    """Safe directive setter
++
++    with DirectiveSetter('/path/to/conf') as ds:
++        ds.set(key, value)
++    """
++    def __init__(self, filename, quotes=True, separator=' '):
++        self.filename = os.path.abspath(filename)
++        self.quotes = quotes
++        self.separator = separator
++        self.lines = None
++        self.stat = None
++
++    def __enter__(self):
++        with io.open(self.filename) as f:
++            self.stat = os.fstat(f.fileno())
++            self.lines = list(f)
++        return self
++
++    def __exit__(self, exc_type, exc_val, exc_tb):
++        if exc_type is not None:
++            # something went wrong, reset
++            self.lines = None
++            self.stat = None
++            return
++
++        directory, prefix = os.path.split(self.filename)
++        # use tempfile in same directory to have atomic rename
++        fd, name = tempfile.mkstemp(prefix=prefix, dir=directory, text=True)
++        with io.open(fd, mode='w', closefd=True) as f:
++            for line in self.lines:
++                if not isinstance(line, six.text_type):
++                    line = line.decode('utf-8')
++                f.write(line)
++            self.lines = None
++            os.fchmod(f.fileno(), stat.S_IMODE(self.stat.st_mode))
++            os.fchown(f.fileno(), self.stat.st_uid, self.stat.st_gid)
++            self.stat = None
++            # flush and sync tempfile inode
++            f.flush()
++            os.fsync(f.fileno())
++
++        # rename file and sync directory inode
++        os.rename(name, self.filename)
++        dirfd = os.open(directory, os.O_RDONLY | os.O_DIRECTORY)
++        try:
++            os.fsync(dirfd)
++        finally:
++            os.close(dirfd)
++
++    def set(self, directive, value, quotes=_SENTINEL, separator=_SENTINEL):
++        """Set a single directive
++        """
++        if quotes is _SENTINEL:
++            quotes = self.quotes
++        if separator is _SENTINEL:
++            separator = self.separator
++        # materialize lines
++        # set_directive_lines() modify item, shrink or enlage line count
++        self.lines = list(set_directive_lines(
++            quotes, separator, directive, value, self.lines
++        ))
++
++    def setitems(self, items):
++        """Set multiple directives from a dict or list with key/value pairs
++        """
++        if isinstance(items, dict):
++            # dict-like, use sorted for stable order
++            items = sorted(items.items())
++        for k, v in items:
++            self.set(k, v)
++
++
+ def set_directive(filename, directive, value, quotes=True, separator=' '):
+     """Set a name/value pair directive in a configuration file.
+ 
+@@ -447,8 +525,10 @@ def set_directive(filename, directive, value, quotes=True, separator=' '):
+     st = os.stat(filename)
+     with open(filename, 'r') as f:
+         lines = list(f)  # read the whole file
+-        new_lines = set_directive_lines(
+-            quotes, separator, directive, value, lines)
++        # materialize new list
++        new_lines = list(set_directive_lines(
++            quotes, separator, directive, value, lines
++        ))
+     with open(filename, 'w') as f:
+         # don't construct the whole string; write line-wise
+         for line in new_lines:
+@@ -472,8 +552,9 @@ def set_directive_lines(quotes, separator, k, v, lines):
+         new_line = ''.join([k, separator, v_quoted, '\n'])
+ 
+     found = False
++    matcher = re.compile(r'\s*{}'.format(re.escape(k + separator)))
+     for line in lines:
+-        if re.match(r'\s*{}'.format(re.escape(k + separator)), line):
++        if matcher.match(line):
+             found = True
+             if v is not None:
+                 yield new_line
+diff --git a/ipatests/test_ipaserver/test_install/test_installutils.py b/ipatests/test_ipaserver/test_install/test_installutils.py
+index cc8fd3cf3f82c2d9af48287f506a566ffbfc39f6..3c992c9ab06ddc3af557329de81debe704b0fb16 100644
+--- a/ipatests/test_ipaserver/test_install/test_installutils.py
++++ b/ipatests/test_ipaserver/test_install/test_installutils.py
+@@ -3,8 +3,11 @@
+ #
+ 
+ import os
++import shutil
+ import tempfile
+ 
++import pytest
++
+ from ipaserver.install import installutils
+ 
+ EXAMPLE_CONFIG = [
+@@ -13,6 +16,17 @@ EXAMPLE_CONFIG = [
+ ]
+ 
+ 
++@pytest.fixture
++def tempdir(request):
++    tempdir = tempfile.mkdtemp()
++
++    def fin():
++        shutil.rmtree(tempdir)
++
++    request.addfinalizer(fin)
++    return tempdir
++
++
+ class test_set_directive_lines(object):
+     def test_remove_directive(self):
+         lines = installutils.set_directive_lines(
+@@ -55,3 +69,56 @@ class test_set_directive(object):
+ 
+         finally:
+             os.remove(filename)
++
++
++def test_directivesetter(tempdir):
++    filename = os.path.join(tempdir, 'example.conf')
++    with open(filename, 'w') as f:
++        for line in EXAMPLE_CONFIG:
++            f.write(line)
++
++    ds = installutils.DirectiveSetter(filename)
++    assert ds.lines is None
++    with ds:
++        assert ds.lines == EXAMPLE_CONFIG
++        ds.set('foo', '3')  # quoted, space separated, doesn't change 'foo='
++        ds.set('foobar', None, separator='=')  # remove
++        ds.set('baz', '4', False, '=')  # add
++        ds.setitems([
++            ('list1', 'value1'),
++            ('list2', 'value2'),
++        ])
++        ds.setitems({
++            'dict1': 'value1',
++            'dict2': 'value2',
++        })
++
++    with open(filename, 'r') as f:
++        lines = list(f)
++
++    assert lines == [
++        'foo=1\n',
++        'foo "3"\n',
++        'baz=4\n',
++        'list1 "value1"\n',
++        'list2 "value2"\n',
++        'dict1 "value1"\n',
++        'dict2 "value2"\n',
++    ]
++
++    with installutils.DirectiveSetter(filename, True, '=') as ds:
++        ds.set('foo', '4')  # doesn't change 'foo '
++
++    with open(filename, 'r') as f:
++        lines = list(f)
++
++    assert lines == [
++        'foo="4"\n',
++        'foo "3"\n',
++        'baz=4\n',
++        'list1 "value1"\n',
++        'list2 "value2"\n',
++        'dict1 "value1"\n',
++        'dict2 "value2"\n',
++
++    ]
+-- 
+2.13.6
+
diff --git a/SOURCES/0026-WebUI-Allow-to-add-certs-to-certmapping-with-CERT-LI.patch b/SOURCES/0026-WebUI-Allow-to-add-certs-to-certmapping-with-CERT-LI.patch
deleted file mode 100644
index eb02c8d..0000000
--- a/SOURCES/0026-WebUI-Allow-to-add-certs-to-certmapping-with-CERT-LI.patch
+++ /dev/null
@@ -1,69 +0,0 @@
-From be6eedde5a5aaf7ad1b527c0cfb9699ccb98a6b5 Mon Sep 17 00:00:00 2001
-From: Pavel Vomacka <pvomacka@redhat.com>
-Date: Mon, 27 Mar 2017 14:14:32 +0200
-Subject: [PATCH] WebUI: Allow to add certs to certmapping with CERT LINES
- around
-
-The certificate to the certmapping might be inserted as
-base64 encoded blob. This patch allows to also insert the certificate
-blob with surrounding "-----BEGIN CERTIFICATE-----" and
-"-----END CERTIFICATE-----" lines. This behavior is the same in
-widget for assigning certificates to users, so the change helps
-WebUI to be more consistent.
-
-https://pagure.io/freeipa/issue/6772
-
-Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
-Reviewed-By: Petr Vobornik <pvoborni@redhat.com>
----
- install/ui/src/freeipa/plugins/certmap.js | 13 +++++++++++--
- 1 file changed, 11 insertions(+), 2 deletions(-)
-
-diff --git a/install/ui/src/freeipa/plugins/certmap.js b/install/ui/src/freeipa/plugins/certmap.js
-index ecbe095b9ead5c3dad70380202836608d564cd58..c613601e989f065a3d6289b02b60563020acf978 100644
---- a/install/ui/src/freeipa/plugins/certmap.js
-+++ b/install/ui/src/freeipa/plugins/certmap.js
-@@ -8,6 +8,7 @@ define([
-         'dojo/_base/declare',
-         'dojo/Evented',
-         'dojo/on',
-+        '../certificate',
-         '../navigation',
-         '../field',
-         '../ipa',
-@@ -19,8 +20,8 @@ define([
-         // plain imports
-         '../search',
-         '../entity'],
--            function(lang, declare, Evented, on, navigation, mod_field, IPA,
--                     phases, reg, widget_mod, text, util) {
-+            function(lang, declare, Evented, on, certificate, navigation,
-+                 mod_field, IPA, phases, reg, widget_mod, text, util) {
- /**
-  * Certificate map module
-  * @class
-@@ -312,6 +313,12 @@ certmap.certmap_multivalued_widget = function (spec) {
-         var widget = widgets[0];
-         var inner_widgets = widget.widgets.get_widgets();
- 
-+        var normalize_certs = function(certs) {
-+            for (var k = 0, l = certs.length; k<l; k++) {
-+                certs[k] = certificate.get_base64(certs[k]);
-+            }
-+        };
-+
-         for (var i = 0, l = inner_widgets.length; i<l; i++) {
-             var w = inner_widgets[i];
- 
-@@ -321,6 +328,8 @@ certmap.certmap_multivalued_widget = function (spec) {
- 
-                 if (field.name === 'issuer' || field.name === 'subject') {
-                     value = value[0];
-+                } else if (field.name === 'certificate') {
-+                    normalize_certs(value);
-                 }
- 
-                 if (!util.is_empty(value)) options[field.name] = value;
--- 
-2.12.1
-
diff --git a/SOURCES/0027-Bump-samba-version-for-FIPS-and-priv.-separation.patch b/SOURCES/0027-Bump-samba-version-for-FIPS-and-priv.-separation.patch
deleted file mode 100644
index dd1dc9a..0000000
--- a/SOURCES/0027-Bump-samba-version-for-FIPS-and-priv.-separation.patch
+++ /dev/null
@@ -1,40 +0,0 @@
-From 9897f81c5182ee11e55d350f48968d608ef79f8b Mon Sep 17 00:00:00 2001
-From: Stanislav Laznicka <slaznick@redhat.com>
-Date: Fri, 24 Mar 2017 14:47:38 +0100
-Subject: [PATCH] Bump samba version for FIPS and priv. separation
-
-With the latest Samba, adding trusts to AD under FIPS should now work
-as well as adding trusts as a whole after the privilege separation
-rework.
-
-https://pagure.io/freeipa/issue/6671
-https://pagure.io/freeipa/issue/6697
-
-Reviewed-By: Martin Basti <mbasti@redhat.com>
----
- freeipa.spec.in | 6 ++++--
- 1 file changed, 4 insertions(+), 2 deletions(-)
-
-diff --git a/freeipa.spec.in b/freeipa.spec.in
-index 18291a5793a6b69dcd719f42e80e1652169e5e1d..5419ed10723fc7aa3ecc1b3f66b3ef1c8b38b12f 100644
---- a/freeipa.spec.in
-+++ b/freeipa.spec.in
-@@ -36,11 +36,13 @@
- 
- %global alt_name ipa
- %if 0%{?rhel}
--%global samba_version 4.0.5-1
-+# Require 4.6.0-4 which brings RC4 for FIPS + trust fixes to priv. separation
-+%global samba_version 4.6.0-4
- %global selinux_policy_version 3.12.1-153
- %global slapi_nis_version 0.56.0-4
- %else
--%global samba_version 2:4.0.5-1
-+# Require 4.6.0-4 which brings RC4 for FIPS + trust fixes to priv. separation
-+%global samba_version 2:4.6.0-4
- %global selinux_policy_version 3.13.1-158.4
- %global slapi_nis_version 0.56.1
- %endif
--- 
-2.12.1
-
diff --git a/SOURCES/0027-Old-pylint-doesn-t-support-bad-python3-option.patch b/SOURCES/0027-Old-pylint-doesn-t-support-bad-python3-option.patch
new file mode 100644
index 0000000..820061b
--- /dev/null
+++ b/SOURCES/0027-Old-pylint-doesn-t-support-bad-python3-option.patch
@@ -0,0 +1,27 @@
+From cf61603340f05a78aff51bf7d2b17de559900636 Mon Sep 17 00:00:00 2001
+From: Christian Heimes <cheimes@redhat.com>
+Date: Tue, 12 Dec 2017 15:03:01 +0100
+Subject: [PATCH] Old pylint doesn't support bad python3 option
+
+Signed-off-by: Christian Heimes <cheimes@redhat.com>
+Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
+---
+ ipaserver/install/installutils.py | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/ipaserver/install/installutils.py b/ipaserver/install/installutils.py
+index 08e098f8656c8fe61a87fb046c01e1487c25da7f..40ae9e19f42170a0552a07c9ec73f60b34bcb84d 100644
+--- a/ipaserver/install/installutils.py
++++ b/ipaserver/install/installutils.py
+@@ -32,7 +32,7 @@ import fileinput
+ import sys
+ import tempfile
+ import shutil
+-import stat  # pylint: disable=bad-python3-import
++import stat
+ import traceback
+ import textwrap
+ from contextlib import contextmanager
+-- 
+2.13.6
+
diff --git a/SOURCES/0028-Reworked-the-renaming-mechanism.patch b/SOURCES/0028-Reworked-the-renaming-mechanism.patch
deleted file mode 100644
index 36f0a8d..0000000
--- a/SOURCES/0028-Reworked-the-renaming-mechanism.patch
+++ /dev/null
@@ -1,296 +0,0 @@
-From bd2a0a8d363af6c8b1491314d5da5f3c146e4ce6 Mon Sep 17 00:00:00 2001
-From: Stanislav Laznicka <slaznick@redhat.com>
-Date: Mon, 27 Mar 2017 08:18:29 +0200
-Subject: [PATCH] Reworked the renaming mechanism
-
-The rename operation on *_mod commands was only allowed when
-the primary key of an entry was also its RDN. With these changes,
-it should be possible to rename the rest of the entries as well.
-
-An attribute to the base LDAPObject was added to whitelist the
-objects we want to allow to be renamed. It replaced an old
-attribute rdn_is_primary_key which was used for the very same
-purpose but the name was confusing because it was not set
-correctly for certain objects.
-
-https://pagure.io/freeipa/issue/2466
-https://pagure.io/freeipa/issue/6784
-
-Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
-Reviewed-By: Jan Cholasta <jcholast@redhat.com>
-Reviewed-By: Martin Basti <mbasti@redhat.com>
----
- ipaserver/plugins/automount.py         |  2 +-
- ipaserver/plugins/baseldap.py          | 32 ++++++++++++++++++++------------
- ipaserver/plugins/baseuser.py          |  2 +-
- ipaserver/plugins/ca.py                |  2 +-
- ipaserver/plugins/dns.py               |  2 +-
- ipaserver/plugins/group.py             |  2 +-
- ipaserver/plugins/idviews.py           |  6 +++---
- ipaserver/plugins/otptoken.py          |  2 +-
- ipaserver/plugins/permission.py        |  2 +-
- ipaserver/plugins/privilege.py         |  2 +-
- ipaserver/plugins/radiusproxy.py       |  2 +-
- ipaserver/plugins/role.py              |  2 +-
- ipaserver/plugins/servicedelegation.py |  2 +-
- 13 files changed, 34 insertions(+), 26 deletions(-)
-
-diff --git a/ipaserver/plugins/automount.py b/ipaserver/plugins/automount.py
-index c4cf2d6db876e13c78ecd73fc53bb356bf190e17..03f994c65832e7b6099739e951105c4b5a897391 100644
---- a/ipaserver/plugins/automount.py
-+++ b/ipaserver/plugins/automount.py
-@@ -456,7 +456,7 @@ class automountkey(LDAPObject):
-     default_attributes = [
-         'automountkey', 'automountinformation', 'description'
-     ]
--    rdn_is_primary_key = True
-+    allow_rename = True
-     rdn_separator = ' '
- 
-     takes_params = (
-diff --git a/ipaserver/plugins/baseldap.py b/ipaserver/plugins/baseldap.py
-index 79ba7fc4a14f8105cda481e1599b2acbd8394e45..dbe3cbd28c85ebc3d9254e24e14c5701adc673ab 100644
---- a/ipaserver/plugins/baseldap.py
-+++ b/ipaserver/plugins/baseldap.py
-@@ -36,7 +36,7 @@ from ipalib.text import _
- from ipalib.util import json_serialize, validate_hostname
- from ipalib.capabilities import client_has_capability
- from ipalib.messages import add_message, SearchResultTruncated
--from ipapython.dn import DN
-+from ipapython.dn import DN, RDN
- from ipapython.version import API_VERSION
- 
- if six.PY3:
-@@ -549,7 +549,7 @@ class LDAPObject(Object):
-     rdn_attribute = ''
-     uuid_attribute = ''
-     attribute_members = {}
--    rdn_is_primary_key = False # Do we need RDN change to do a rename?
-+    allow_rename = False
-     password_attributes = []
-     # Can bind as this entry (has userPassword or krbPrincipalKey)
-     bindable = False
-@@ -1384,7 +1384,7 @@ class LDAPUpdate(LDAPQuery, crud.Update):
-     def get_options(self):
-         for option in super(LDAPUpdate, self).get_options():
-             yield option
--        if self.obj.rdn_is_primary_key:
-+        if self.obj.allow_rename:
-             yield self._get_rename_option()
- 
-     def execute(self, *keys, **options):
-@@ -1419,15 +1419,19 @@ class LDAPUpdate(LDAPQuery, crud.Update):
-         _check_limit_object_class(self.api.Backend.ldap2.schema.attribute_types(self.obj.disallow_object_classes), list(entry_attrs), allow_only=False)
- 
-         rdnupdate = False
--        try:
--            if self.obj.rdn_is_primary_key and 'rename' in options:
--                if not options['rename']:
--                    raise errors.ValidationError(name='rename', error=u'can\'t be empty')
--                entry_attrs[self.obj.primary_key.name] = options['rename']
--
--            if self.obj.rdn_is_primary_key and self.obj.primary_key.name in entry_attrs:
-+        if 'rename' in options:
-+            if not options['rename']:
-+                raise errors.ValidationError(
-+                    name='rename', error=u'can\'t be empty')
-+            entry_attrs[self.obj.primary_key.name] = options['rename']
-+
-+        # if setattr was used to change the RDN, the primary_key.name is
-+        # already in entry_attrs
-+        if self.obj.allow_rename and self.obj.primary_key.name in entry_attrs:
-+            # perform RDN change if the primary key is also RDN
-+            if (RDN((self.obj.primary_key.name, keys[-1])) ==
-+                    entry_attrs.dn[0]):
-                 try:
--                    # RDN change
-                     new_dn = DN((self.obj.primary_key.name,
-                                  entry_attrs[self.obj.primary_key.name]),
-                                 *entry_attrs.dn[1:])
-@@ -1435,17 +1439,21 @@ class LDAPUpdate(LDAPQuery, crud.Update):
-                         entry_attrs.dn,
-                         new_dn)
- 
--                    rdnkeys = keys[:-1] + (entry_attrs[self.obj.primary_key.name], )
-+                    rdnkeys = (keys[:-1] +
-+                               (entry_attrs[self.obj.primary_key.name], ))
-                     entry_attrs.dn = self.obj.get_dn(*rdnkeys)
-                     options['rdnupdate'] = True
-                     rdnupdate = True
-                 except errors.EmptyModlist:
-                     # Attempt to rename to the current name, ignore
-                     pass
-+                except errors.NotFound:
-+                    self.obj.handle_not_found(*keys)
-                 finally:
-                     # Delete the primary_key from entry_attrs either way
-                     del entry_attrs[self.obj.primary_key.name]
- 
-+        try:
-             # Exception callbacks will need to test for options['rdnupdate']
-             # to decide what to do. An EmptyModlist in this context doesn't
-             # mean an error occurred, just that there were no other updates to
-diff --git a/ipaserver/plugins/baseuser.py b/ipaserver/plugins/baseuser.py
-index 44adc76ec854dadbe0d8a4e8ca03e71c30df526c..bf24dbf542d3b481671dfe4e8cee14a2edcc26e0 100644
---- a/ipaserver/plugins/baseuser.py
-+++ b/ipaserver/plugins/baseuser.py
-@@ -164,7 +164,7 @@ class baseuser(LDAPObject):
-         'memberof': ['group', 'netgroup', 'role', 'hbacrule', 'sudorule'],
-         'memberofindirect': ['group', 'netgroup', 'role', 'hbacrule', 'sudorule'],
-     }
--    rdn_is_primary_key = True
-+    allow_rename = True
-     bindable = True
-     password_attributes = [('userpassword', 'has_password'),
-                            ('krbprincipalkey', 'has_keytab')]
-diff --git a/ipaserver/plugins/ca.py b/ipaserver/plugins/ca.py
-index f774f78bd6d4ad236b37d06b8b267e8dd78f93b7..9bb163dffa645c1cbb10976e62cbd4a714139319 100644
---- a/ipaserver/plugins/ca.py
-+++ b/ipaserver/plugins/ca.py
-@@ -68,7 +68,7 @@ class ca(LDAPObject):
-         'cn', 'description', 'ipacaid', 'ipacaissuerdn', 'ipacasubjectdn',
-     ]
-     rdn_attribute = 'cn'
--    rdn_is_primary_key = True
-+    allow_rename = True
-     label = _('Certificate Authorities')
-     label_singular = _('Certificate Authority')
- 
-diff --git a/ipaserver/plugins/dns.py b/ipaserver/plugins/dns.py
-index 7007928f3b4b2fd863077193671a03ae46119dc5..47ac963a0ae26fcaa81e70a8143bd7d0c172d20e 100644
---- a/ipaserver/plugins/dns.py
-+++ b/ipaserver/plugins/dns.py
-@@ -3000,7 +3000,7 @@ class dnsrecord(LDAPObject):
-     possible_objectclasses = ['idnsTemplateObject']
-     permission_filter_objectclasses = ['idnsrecord']
-     default_attributes = ['idnsname'] + _record_attributes
--    rdn_is_primary_key = True
-+    allow_rename = True
- 
-     label = _('DNS Resource Records')
-     label_singular = _('DNS Resource Record')
-diff --git a/ipaserver/plugins/group.py b/ipaserver/plugins/group.py
-index 218da3c94d95bb399761acf9414182eff566c63b..1fb092d5f049e86f12681e5eb2397f98f1001697 100644
---- a/ipaserver/plugins/group.py
-+++ b/ipaserver/plugins/group.py
-@@ -173,7 +173,7 @@ class group(LDAPObject):
-         'memberofindirect': ['group', 'netgroup', 'role', 'hbacrule',
-         'sudorule'],
-     }
--    rdn_is_primary_key = True
-+    allow_rename = True
-     managed_permissions = {
-         'System: Read Groups': {
-             'replaces_global_anonymous_aci': True,
-diff --git a/ipaserver/plugins/idviews.py b/ipaserver/plugins/idviews.py
-index 6d4ac75209ea08e3c2969d53e1ae5372c3a535ac..b5ee32cf138677874497e2f345c932c352e20054 100644
---- a/ipaserver/plugins/idviews.py
-+++ b/ipaserver/plugins/idviews.py
-@@ -97,7 +97,7 @@ class idview(LDAPObject):
-     object_class = ['ipaIDView', 'top']
-     possible_objectclasses = ['ipaNameResolutionData']
-     default_attributes = ['cn', 'description', 'ipadomainresolutionorder']
--    rdn_is_primary_key = True
-+    allow_rename = True
- 
-     label = _('ID Views')
-     label_singular = _('ID View')
-@@ -848,7 +848,7 @@ class idoverrideuser(baseidoverride):
- 
-     label = _('User ID overrides')
-     label_singular = _('User ID override')
--    rdn_is_primary_key = True
-+    allow_rename = True
- 
-     # ID user overrides are bindable because we map SASL GSSAPI
-     # authentication of trusted users to ID user overrides in the
-@@ -964,7 +964,7 @@ class idoverridegroup(baseidoverride):
- 
-     label = _('Group ID overrides')
-     label_singular = _('Group ID override')
--    rdn_is_primary_key = True
-+    allow_rename = True
- 
-     permission_filter_objectclasses = ['ipaGroupOverride']
-     managed_permissions = {
-diff --git a/ipaserver/plugins/otptoken.py b/ipaserver/plugins/otptoken.py
-index 98ecbe58b84622d7937a7e6eff77c5e41624bf4f..c66f0980f0fc2ed49b4224be40a18ce528a6da7b 100644
---- a/ipaserver/plugins/otptoken.py
-+++ b/ipaserver/plugins/otptoken.py
-@@ -143,7 +143,7 @@ class otptoken(LDAPObject):
-     relationships = {
-         'managedby': ('Managed by', 'man_by_', 'not_man_by_'),
-     }
--    rdn_is_primary_key = True
-+    allow_rename = True
- 
-     label = _('OTP Tokens')
-     label_singular = _('OTP Token')
-diff --git a/ipaserver/plugins/permission.py b/ipaserver/plugins/permission.py
-index dd2a0183e90ed6da9e55fb0590ea0bd81bf0bd67..977c6fe363c501f820aa82ae5b2ea00d8c78c7ae 100644
---- a/ipaserver/plugins/permission.py
-+++ b/ipaserver/plugins/permission.py
-@@ -188,7 +188,7 @@ class permission(baseldap.LDAPObject):
-         'member': ['privilege'],
-         'memberindirect': ['role'],
-     }
--    rdn_is_primary_key = True
-+    allow_rename = True
-     managed_permissions = {
-         'System: Read Permissions': {
-             'replaces_global_anonymous_aci': True,
-diff --git a/ipaserver/plugins/privilege.py b/ipaserver/plugins/privilege.py
-index b3afbd289ac2e82d5569b5d5306be398a560413e..01d5396902d482eb5a9f21e7ece730a0a35157d6 100644
---- a/ipaserver/plugins/privilege.py
-+++ b/ipaserver/plugins/privilege.py
-@@ -101,7 +101,7 @@ class privilege(LDAPObject):
-     reverse_members = {
-         'member': ['permission'],
-     }
--    rdn_is_primary_key = True
-+    allow_rename = True
-     managed_permissions = {
-         'System: Read Privileges': {
-             'replaces_global_anonymous_aci': True,
-diff --git a/ipaserver/plugins/radiusproxy.py b/ipaserver/plugins/radiusproxy.py
-index 3391b8aed77205fb1a586d5472d8cfdbc9fd1cd5..be77c62432066beec951e5f50afe689e1d6debce 100644
---- a/ipaserver/plugins/radiusproxy.py
-+++ b/ipaserver/plugins/radiusproxy.py
-@@ -101,7 +101,7 @@ class radiusproxy(LDAPObject):
-         'ipatokenradiustimeout', 'ipatokenradiusretries', 'ipatokenusermapattribute'
-     ]
-     search_attributes = ['cn', 'description', 'ipatokenradiusserver']
--    rdn_is_primary_key = True
-+    allow_rename = True
-     label = _('RADIUS Servers')
-     label_singular = _('RADIUS Server')
- 
-diff --git a/ipaserver/plugins/role.py b/ipaserver/plugins/role.py
-index 5d0d1f8c657b8d840762135f5ff16db90fb4893f..e7f115c461a6a0421f9c43d0410daaf9d4307e76 100644
---- a/ipaserver/plugins/role.py
-+++ b/ipaserver/plugins/role.py
-@@ -92,7 +92,7 @@ class role(LDAPObject):
-     reverse_members = {
-         'member': ['privilege'],
-     }
--    rdn_is_primary_key = True
-+    allow_rename = True
-     managed_permissions = {
-         'System: Read Roles': {
-             'replaces_global_anonymous_aci': True,
-diff --git a/ipaserver/plugins/servicedelegation.py b/ipaserver/plugins/servicedelegation.py
-index c8052e957cc5f8d24f6a8d0621ca93422052e35b..4f94924fa76691bcd6c6fc2cef9eb7fb30fce48c 100644
---- a/ipaserver/plugins/servicedelegation.py
-+++ b/ipaserver/plugins/servicedelegation.py
-@@ -138,7 +138,7 @@ class servicedelegation(LDAPObject):
-         },
-     }
- 
--    rdn_is_primary_key = True
-+    allow_rename = True
- 
-     takes_params = (
-         Str(
--- 
-2.12.1
-
diff --git a/SOURCES/0028-WebUI-make-keytab-tables-on-service-and-host-pages-w.patch b/SOURCES/0028-WebUI-make-keytab-tables-on-service-and-host-pages-w.patch
new file mode 100644
index 0000000..45cf8f9
--- /dev/null
+++ b/SOURCES/0028-WebUI-make-keytab-tables-on-service-and-host-pages-w.patch
@@ -0,0 +1,158 @@
+From 8c4561a1ea598f645c33a8ed2f0c841326b2373d Mon Sep 17 00:00:00 2001
+From: Pavel Vomacka <pvomacka@redhat.com>
+Date: Thu, 14 Dec 2017 15:14:03 +0100
+Subject: [PATCH] WebUI: make keytab tables on service and host pages writable
+
+There is no object class before adding the first item into tables,
+therefore there are no ACI and WebUI is not able to figure out
+whether table is writable or not. Adding flag 'w_if_no_aci'
+tells "make it writable even if we have not ACIs and try to do
+the API call.
+
+https://pagure.io/freeipa/issue/7111
+
+Reviewed-By: Felipe Volpone <fbarreto@redhat.com>
+---
+ install/ui/src/freeipa/host.js    | 8 ++++++++
+ install/ui/src/freeipa/service.js | 8 ++++++++
+ 2 files changed, 16 insertions(+)
+
+diff --git a/install/ui/src/freeipa/host.js b/install/ui/src/freeipa/host.js
+index ac434d8455384ded2cbebc28445deaecbafc46b5..acecff1e5b99c541b216a3e6789efb77eb262fef 100644
+--- a/install/ui/src/freeipa/host.js
++++ b/install/ui/src/freeipa/host.js
+@@ -198,6 +198,7 @@ return {
+                             $type: 'association_table',
+                             id: 'host_ipaallowedtoperform_read_keys_user',
+                             name: 'ipaallowedtoperform_read_keys_user',
++                            flags: ['w_if_no_aci'],
+                             add_method: 'allow_retrieve_keytab',
+                             remove_method: 'disallow_retrieve_keytab',
+                             add_title: '@i18n:keytab.add_retrive',
+@@ -214,6 +215,7 @@ return {
+                             $type: 'association_table',
+                             id: 'host_ipaallowedtoperform_read_keys_group',
+                             name: 'ipaallowedtoperform_read_keys_group',
++                            flags: ['w_if_no_aci'],
+                             add_method: 'allow_retrieve_keytab',
+                             remove_method: 'disallow_retrieve_keytab',
+                             add_title: '@i18n:keytab.add_retrive',
+@@ -230,6 +232,7 @@ return {
+                             $type: 'association_table',
+                             id: 'service_ipaallowedtoperform_read_keys_host',
+                             name: 'ipaallowedtoperform_read_keys_host',
++                            flags: ['w_if_no_aci'],
+                             add_method: 'allow_retrieve_keytab',
+                             remove_method: 'disallow_retrieve_keytab',
+                             add_title: '@i18n:keytab.add_retrive',
+@@ -246,6 +249,7 @@ return {
+                             $type: 'association_table',
+                             id: 'service_ipaallowedtoperform_read_keys_hostgroup',
+                             name: 'ipaallowedtoperform_read_keys_hostgroup',
++                            flags: ['w_if_no_aci'],
+                             add_method: 'allow_retrieve_keytab',
+                             remove_method: 'disallow_retrieve_keytab',
+                             add_title: '@i18n:keytab.add_retrive',
+@@ -269,6 +273,7 @@ return {
+                             $type: 'association_table',
+                             id: 'host_ipaallowedtoperform_write_keys_user',
+                             name: 'ipaallowedtoperform_write_keys_user',
++                            flags: ['w_if_no_aci'],
+                             add_method: 'allow_create_keytab',
+                             remove_method: 'disallow_create_keytab',
+                             add_title: '@i18n:keytab.add_create',
+@@ -285,6 +290,7 @@ return {
+                             $type: 'association_table',
+                             id: 'host_ipaallowedtoperform_write_keys_group',
+                             name: 'ipaallowedtoperform_write_keys_group',
++                            flags: ['w_if_no_aci'],
+                             add_method: 'allow_create_keytab',
+                             remove_method: 'disallow_create_keytab',
+                             add_title: '@i18n:keytab.add_create',
+@@ -301,6 +307,7 @@ return {
+                             $type: 'association_table',
+                             id: 'service_ipaallowedtoperform_write_keys_host',
+                             name: 'ipaallowedtoperform_write_keys_host',
++                            flags: ['w_if_no_aci'],
+                             add_method: 'allow_create_keytab',
+                             remove_method: 'disallow_create_keytab',
+                             add_title: '@i18n:keytab.add_create',
+@@ -317,6 +324,7 @@ return {
+                             $type: 'association_table',
+                             id: 'service_ipaallowedtoperform_write_keys_hostgroup',
+                             name: 'ipaallowedtoperform_write_keys_hostgroup',
++                            flags: ['w_if_no_aci'],
+                             add_method: 'allow_create_keytab',
+                             remove_method: 'disallow_create_keytab',
+                             add_title: '@i18n:keytab.add_create',
+diff --git a/install/ui/src/freeipa/service.js b/install/ui/src/freeipa/service.js
+index 752ff98e3e5290442ce5f011a4de53ccc0db8f8f..c798d2999fc909fdbc26b016e4752a3edf1f702e 100644
+--- a/install/ui/src/freeipa/service.js
++++ b/install/ui/src/freeipa/service.js
+@@ -201,6 +201,7 @@ return {
+                             $type: 'association_table',
+                             id: 'service_ipaallowedtoperform_read_keys_user',
+                             name: 'ipaallowedtoperform_read_keys_user',
++                            flags: ['w_if_no_aci'],
+                             add_method: 'allow_retrieve_keytab',
+                             remove_method: 'disallow_retrieve_keytab',
+                             add_title: '@i18n:keytab.add_retrive',
+@@ -217,6 +218,7 @@ return {
+                             $type: 'association_table',
+                             id: 'service_ipaallowedtoperform_read_keys_group',
+                             name: 'ipaallowedtoperform_read_keys_group',
++                            flags: ['w_if_no_aci'],
+                             add_method: 'allow_retrieve_keytab',
+                             remove_method: 'disallow_retrieve_keytab',
+                             add_title: '@i18n:keytab.add_retrive',
+@@ -233,6 +235,7 @@ return {
+                             $type: 'association_table',
+                             id: 'service_ipaallowedtoperform_read_keys_host',
+                             name: 'ipaallowedtoperform_read_keys_host',
++                            flags: ['w_if_no_aci'],
+                             add_method: 'allow_retrieve_keytab',
+                             remove_method: 'disallow_retrieve_keytab',
+                             add_title: '@i18n:keytab.add_retrive',
+@@ -249,6 +252,7 @@ return {
+                             $type: 'association_table',
+                             id: 'service_ipaallowedtoperform_read_keys_hostgroup',
+                             name: 'ipaallowedtoperform_read_keys_hostgroup',
++                            flags: ['w_if_no_aci'],
+                             add_method: 'allow_retrieve_keytab',
+                             remove_method: 'disallow_retrieve_keytab',
+                             add_title: '@i18n:keytab.add_retrive',
+@@ -272,6 +276,7 @@ return {
+                             $type: 'association_table',
+                             id: 'service_ipaallowedtoperform_write_keys_user',
+                             name: 'ipaallowedtoperform_write_keys_user',
++                            flags: ['w_if_no_aci'],
+                             add_method: 'allow_create_keytab',
+                             remove_method: 'disallow_create_keytab',
+                             add_title: '@i18n:keytab.add_create',
+@@ -288,6 +293,7 @@ return {
+                             $type: 'association_table',
+                             id: 'service_ipaallowedtoperform_write_keys_group',
+                             name: 'ipaallowedtoperform_write_keys_group',
++                            flags: ['w_if_no_aci'],
+                             add_method: 'allow_create_keytab',
+                             remove_method: 'disallow_create_keytab',
+                             add_title: '@i18n:keytab.add_create',
+@@ -304,6 +310,7 @@ return {
+                             $type: 'association_table',
+                             id: 'service_ipaallowedtoperform_write_keys_host',
+                             name: 'ipaallowedtoperform_write_keys_host',
++                            flags: ['w_if_no_aci'],
+                             add_method: 'allow_create_keytab',
+                             remove_method: 'disallow_create_keytab',
+                             add_title: '@i18n:keytab.add_create',
+@@ -320,6 +327,7 @@ return {
+                             $type: 'association_table',
+                             id: 'service_ipaallowedtoperform_write_keys_hostgroup',
+                             name: 'ipaallowedtoperform_write_keys_hostgroup',
++                            flags: ['w_if_no_aci'],
+                             add_method: 'allow_create_keytab',
+                             remove_method: 'disallow_create_keytab',
+                             add_title: '@i18n:keytab.add_create',
+-- 
+2.13.6
+
diff --git a/SOURCES/0029-Allow-renaming-of-the-HBAC-rule-objects.patch b/SOURCES/0029-Allow-renaming-of-the-HBAC-rule-objects.patch
deleted file mode 100644
index 2247186..0000000
--- a/SOURCES/0029-Allow-renaming-of-the-HBAC-rule-objects.patch
+++ /dev/null
@@ -1,103 +0,0 @@
-From 496255286bdf83c11deeba08755de56e639de000 Mon Sep 17 00:00:00 2001
-From: Stanislav Laznicka <slaznick@redhat.com>
-Date: Mon, 27 Mar 2017 08:25:04 +0200
-Subject: [PATCH] Allow renaming of the HBAC rule objects
-
-The recent changes allow HBAC rule objects to be renamed.
-
-https://pagure.io/freeipa/issue/6784
-
-Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
-Reviewed-By: Jan Cholasta <jcholast@redhat.com>
-Reviewed-By: Martin Basti <mbasti@redhat.com>
----
- API.txt                                  |  3 ++-
- VERSION.m4                               |  4 ++--
- ipaserver/plugins/hbacrule.py            |  1 +
- ipatests/test_xmlrpc/test_hbac_plugin.py | 15 +++++++++++++++
- 4 files changed, 20 insertions(+), 3 deletions(-)
-
-diff --git a/API.txt b/API.txt
-index f0bd1b6495854decf4470efdcf1f2d915ce71c52..2a63c983a343b07ec7928bc774c6443a84b7c64c 100644
---- a/API.txt
-+++ b/API.txt
-@@ -2163,7 +2163,7 @@ output: ListOfEntries('result')
- output: Output('summary', type=[<type 'unicode'>, <type 'NoneType'>])
- output: Output('truncated', type=[<type 'bool'>])
- command: hbacrule_mod/1
--args: 1,16,3
-+args: 1,17,3
- arg: Str('cn', cli_name='name')
- option: StrEnum('accessruletype?', autofill=False, cli_name='type', default=u'allow', values=[u'allow', u'deny'])
- option: Str('addattr*', cli_name='addattr')
-@@ -2175,6 +2175,7 @@ option: StrEnum('hostcategory?', autofill=False, cli_name='hostcat', values=[u'a
- option: Bool('ipaenabledflag?', autofill=False)
- option: Flag('no_members', autofill=True, default=False)
- option: Flag('raw', autofill=True, cli_name='raw', default=False)
-+option: Str('rename?', cli_name='rename')
- option: Flag('rights', autofill=True, default=False)
- option: StrEnum('servicecategory?', autofill=False, cli_name='servicecat', values=[u'all'])
- option: Str('setattr*', cli_name='setattr')
-diff --git a/VERSION.m4 b/VERSION.m4
-index 743f2dbe0d05126f11c67574c5a9b712cb1f112d..bbb5212e5b8cd9604b6ec90d4a0bd4c3276b1856 100644
---- a/VERSION.m4
-+++ b/VERSION.m4
-@@ -73,8 +73,8 @@ define(IPA_DATA_VERSION, 20100614120000)
- #                                                      #
- ########################################################
- define(IPA_API_VERSION_MAJOR, 2)
--define(IPA_API_VERSION_MINOR, 223)
--# Last change: Add domain resolution order to ID views
-+define(IPA_API_VERSION_MINOR, 224)
-+# Last change: Add rename option to HBAC rule objects
- 
- 
- ########################################################
-diff --git a/ipaserver/plugins/hbacrule.py b/ipaserver/plugins/hbacrule.py
-index 60e5e606fff6d2ffb93db608328c5987b91d1fa8..2495702e87accaf60eb38dae0fb122ac0764452f 100644
---- a/ipaserver/plugins/hbacrule.py
-+++ b/ipaserver/plugins/hbacrule.py
-@@ -141,6 +141,7 @@ class hbacrule(LDAPObject):
-     ]
-     uuid_attribute = 'ipauniqueid'
-     rdn_attribute = 'ipauniqueid'
-+    allow_rename = True
-     attribute_members = {
-         'memberuser': ['user', 'group'],
-         'memberhost': ['host', 'hostgroup'],
-diff --git a/ipatests/test_xmlrpc/test_hbac_plugin.py b/ipatests/test_xmlrpc/test_hbac_plugin.py
-index 75c15c5abe472d975f0c2bc78eb9dd5fda8af45e..b495fe3341f8d0682f65b4fc1d408734d130a7cd 100644
---- a/ipatests/test_xmlrpc/test_hbac_plugin.py
-+++ b/ipatests/test_xmlrpc/test_hbac_plugin.py
-@@ -34,6 +34,7 @@ class test_hbac(XMLRPC_test):
-     Test the `hbacrule` plugin.
-     """
-     rule_name = u'testing_rule1234'
-+    rule_renamed = u'mega_testing_rule'
-     rule_type = u'allow'
-     rule_type_fail = u'value not allowed'
-     rule_service = u'ssh'
-@@ -459,6 +460,20 @@ class test_hbac(XMLRPC_test):
-         assert_attr_equal(entry, 'cn', self.rule_name)
-         assert_attr_equal(entry, 'memberservice_hbacsvc', self.test_service)
- 
-+    def test_o_hbacrule_rename(self):
-+        """
-+        Test renaming an HBAC rule, rename it back afterwards
-+        """
-+        api.Command['hbacrule_mod'](
-+            self.rule_name, rename=self.rule_renamed
-+        )
-+        entry = api.Command['hbacrule_show'](self.rule_renamed)['result']
-+        assert_attr_equal(entry, 'cn', self.rule_renamed)
-+        # clean up by renaming the rule back
-+        api.Command['hbacrule_mod'](
-+            self.rule_renamed, rename=self.rule_name
-+        )
-+
-     def test_y_hbacrule_zap_testing_data(self):
-         """
-         Clear data for HBAC plugin testing.
--- 
-2.12.1
-
diff --git a/SOURCES/0029-Idviews-fix-objectclass-violation-on-idview-add.patch b/SOURCES/0029-Idviews-fix-objectclass-violation-on-idview-add.patch
new file mode 100644
index 0000000..583ad41
--- /dev/null
+++ b/SOURCES/0029-Idviews-fix-objectclass-violation-on-idview-add.patch
@@ -0,0 +1,108 @@
+From 6d4676c4e3403df547ef03a2e716d6254c3c512e Mon Sep 17 00:00:00 2001
+From: Florence Blanc-Renaud <flo@redhat.com>
+Date: Fri, 5 Jan 2018 09:50:26 +0100
+Subject: [PATCH] Idviews: fix objectclass violation on idview-add
+
+When the option --domain-resolution-order is used with the command
+ipa idview-add, the resulting LDAP object stores the value in
+ipadomainresolutionorder attribute.
+The issue is that the add command does not add the needed object
+class (ipaNameResolutionData) because it is part of
+possible_objectclasses but not of object_class.
+
+The fix makes sure to add the objectclass when the option
+--domain-resolution-order is used, and adds a non-regression test.
+
+Note that idview-mod does not have any issue as it correctly handles
+the addition of missing possible objectclasses.
+
+Fixes:
+https://pagure.io/freeipa/issue/7350
+
+Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
+Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
+---
+ ipaserver/plugins/idviews.py                | 15 +++++++++----
+ ipatests/test_xmlrpc/test_idviews_plugin.py | 35 +++++++++++++++++++++++++++++
+ 2 files changed, 46 insertions(+), 4 deletions(-)
+
+diff --git a/ipaserver/plugins/idviews.py b/ipaserver/plugins/idviews.py
+index a55c20bbf2466d9cb3a317d49a8bba3c9379f572..2b06cc54e4b04aac004efbf02a446464b8c89777 100644
+--- a/ipaserver/plugins/idviews.py
++++ b/ipaserver/plugins/idviews.py
+@@ -22,10 +22,11 @@ import re
+ import six
+ 
+ from .baseldap import (LDAPQuery, LDAPObject, LDAPCreate,
+-                                     LDAPDelete, LDAPUpdate, LDAPSearch,
+-                                     LDAPAddAttributeViaOption,
+-                                     LDAPRemoveAttributeViaOption,
+-                                     LDAPRetrieve, global_output_params)
++                       LDAPDelete, LDAPUpdate, LDAPSearch,
++                       LDAPAddAttributeViaOption,
++                       LDAPRemoveAttributeViaOption,
++                       LDAPRetrieve, global_output_params,
++                       add_missing_object_class)
+ from .hostgroup import get_complete_hostgroup_member_list
+ from .service import validate_certificate
+ from ipalib import api, Str, Int, Bytes, Flag, _, ngettext, errors, output
+@@ -169,6 +170,12 @@ class idview_add(LDAPCreate):
+     def pre_callback(self, ldap, dn, entry_attrs, attrs_list, *keys, **options):
+         self.api.Object.config.validate_domain_resolution_order(entry_attrs)
+ 
++        # The objectclass ipaNameResolutionData may not be present on
++        # the id view. We need to add it if we define a new
++        # value for ipaDomainResolutionOrder
++        if 'ipadomainresolutionorder' in entry_attrs:
++            add_missing_object_class(ldap, u'ipanameresolutiondata', dn,
++                                     entry_attrs, update=False)
+         return dn
+ 
+ 
+diff --git a/ipatests/test_xmlrpc/test_idviews_plugin.py b/ipatests/test_xmlrpc/test_idviews_plugin.py
+index 35d31b37d8fb87384d9ae550182e353c1d6383cc..3d4cce5ea0505ef8b0cd8253fd74b037890ce18b 100644
+--- a/ipatests/test_xmlrpc/test_idviews_plugin.py
++++ b/ipatests/test_xmlrpc/test_idviews_plugin.py
+@@ -1704,4 +1704,39 @@ class test_idviews(Declarative):
+             ),
+         ),
+ 
++        # Delete the ID View
++
++        dict(
++            desc='Delete ID View "%s"' % idview1,
++            command=('idview_del', [idview1], {}),
++            expected=dict(
++                result=dict(failed=[]),
++                summary=u'Deleted ID View "%s"' % idview1,
++                value=[idview1],
++            ),
++        ),
++
++        # Test the creation of ID view with domain resolution order
++        # Non-regression test for issue 7350
++
++        dict(
++            desc='Create ID View "%s"' % idview1,
++            command=(
++                'idview_add',
++                [idview1],
++                dict(ipadomainresolutionorder=u'%s' % api.env.domain)
++            ),
++            expected=dict(
++                value=idview1,
++                summary=u'Added ID View "%s"' % idview1,
++                result=dict(
++                    dn=get_idview_dn(idview1),
++                    objectclass=objectclasses.idview +
++                    [u'ipanameresolutiondata'],
++                    cn=[idview1],
++                    ipadomainresolutionorder=[api.env.domain]
++                )
++            ),
++        ),
++
+     ]
+-- 
+2.13.6
+
diff --git a/SOURCES/0030-Allow-renaming-of-the-sudorule-objects.patch b/SOURCES/0030-Allow-renaming-of-the-sudorule-objects.patch
deleted file mode 100644
index 7198e0f..0000000
--- a/SOURCES/0030-Allow-renaming-of-the-sudorule-objects.patch
+++ /dev/null
@@ -1,100 +0,0 @@
-From f868a2016bdad996fac9cc9d3b3e9b4228ab1dd4 Mon Sep 17 00:00:00 2001
-From: Stanislav Laznicka <slaznick@redhat.com>
-Date: Mon, 27 Mar 2017 08:26:03 +0200
-Subject: [PATCH] Allow renaming of the sudorule objects
-
-The recent changes allow the sudorule objects to be renamed.
-
-https://pagure.io/freeipa/issue/2466
-
-Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
-Reviewed-By: Jan Cholasta <jcholast@redhat.com>
-Reviewed-By: Martin Basti <mbasti@redhat.com>
----
- API.txt                                      |  3 ++-
- VERSION.m4                                   |  2 +-
- ipaserver/plugins/sudorule.py                |  1 +
- ipatests/test_xmlrpc/test_sudorule_plugin.py | 14 ++++++++++++++
- 4 files changed, 18 insertions(+), 2 deletions(-)
-
-diff --git a/API.txt b/API.txt
-index 2a63c983a343b07ec7928bc774c6443a84b7c64c..7594157384511c1317738dafb41361676a2a0fd7 100644
---- a/API.txt
-+++ b/API.txt
-@@ -5403,7 +5403,7 @@ output: ListOfEntries('result')
- output: Output('summary', type=[<type 'unicode'>, <type 'NoneType'>])
- output: Output('truncated', type=[<type 'bool'>])
- command: sudorule_mod/1
--args: 1,20,3
-+args: 1,21,3
- arg: Str('cn', cli_name='sudorule_name')
- option: Str('addattr*', cli_name='addattr')
- option: Flag('all', autofill=True, cli_name='all', default=False)
-@@ -5420,6 +5420,7 @@ option: StrEnum('ipasudorunasgroupcategory?', autofill=False, cli_name='runasgro
- option: StrEnum('ipasudorunasusercategory?', autofill=False, cli_name='runasusercat', values=[u'all'])
- option: Flag('no_members', autofill=True, default=False)
- option: Flag('raw', autofill=True, cli_name='raw', default=False)
-+option: Str('rename?', cli_name='rename')
- option: Flag('rights', autofill=True, default=False)
- option: Str('setattr*', cli_name='setattr')
- option: Int('sudoorder?', autofill=False, cli_name='order', default=0)
-diff --git a/VERSION.m4 b/VERSION.m4
-index bbb5212e5b8cd9604b6ec90d4a0bd4c3276b1856..31e7c1d6e7054d3b4ef1d9dfaf349d2959f8330a 100644
---- a/VERSION.m4
-+++ b/VERSION.m4
-@@ -74,7 +74,7 @@ define(IPA_DATA_VERSION, 20100614120000)
- ########################################################
- define(IPA_API_VERSION_MAJOR, 2)
- define(IPA_API_VERSION_MINOR, 224)
--# Last change: Add rename option to HBAC rule objects
-+# Last change: Add rename option to sudorule objects
- 
- 
- ########################################################
-diff --git a/ipaserver/plugins/sudorule.py b/ipaserver/plugins/sudorule.py
-index 90771072ac8645863e77e88b2500c47c0bb2c8df..28c3f21f113fd14160abd518663f2d582f8653fd 100644
---- a/ipaserver/plugins/sudorule.py
-+++ b/ipaserver/plugins/sudorule.py
-@@ -145,6 +145,7 @@ class sudorule(LDAPObject):
-     ]
-     uuid_attribute = 'ipauniqueid'
-     rdn_attribute = 'ipauniqueid'
-+    allow_rename = True
-     attribute_members = {
-         'memberuser': ['user', 'group'],
-         'memberhost': ['host', 'hostgroup'],
-diff --git a/ipatests/test_xmlrpc/test_sudorule_plugin.py b/ipatests/test_xmlrpc/test_sudorule_plugin.py
-index c37262a43cc3805913688be4bda0318d67b364c4..75dbfbe67202a57299330d21200fe7ca1bb3f77e 100644
---- a/ipatests/test_xmlrpc/test_sudorule_plugin.py
-+++ b/ipatests/test_xmlrpc/test_sudorule_plugin.py
-@@ -42,6 +42,7 @@ class test_sudorule(XMLRPC_test):
-     """
-     rule_name = u'testing_sudorule1'
-     rule_name2 = u'testing_sudorule2'
-+    rule_renamed = u'testing_mega_sudorule'
-     rule_command = u'/usr/bin/testsudocmd1'
-     rule_desc = u'description'
-     rule_desc_mod = u'description modified'
-@@ -782,6 +783,19 @@ class test_sudorule(XMLRPC_test):
-         api.Command['sudorule_mod'](self.rule_name, sudoorder=None)
-         api.Command['sudorule_mod'](self.rule_name2, sudoorder=None)
- 
-+    def test_l_1_sudorule_rename(self):
-+        """
-+        Test renaming an HBAC rule, rename it back afterwards
-+        """
-+        api.Command['sudorule_mod'](
-+            self.rule_name, rename=self.rule_renamed
-+        )
-+        entry = api.Command['sudorule_show'](self.rule_renamed)['result']
-+        assert_attr_equal(entry, 'cn', self.rule_renamed)
-+        # clean up by renaming the rule back
-+        api.Command['sudorule_mod'](
-+            self.rule_renamed, rename=self.rule_name
-+        )
- 
-     def test_m_sudorule_del(self):
-         """
--- 
-2.12.1
-
diff --git a/SOURCES/0030-Fixing-the-cert-request-comparing-whole-email-addres.patch b/SOURCES/0030-Fixing-the-cert-request-comparing-whole-email-addres.patch
new file mode 100644
index 0000000..8b381a7
--- /dev/null
+++ b/SOURCES/0030-Fixing-the-cert-request-comparing-whole-email-addres.patch
@@ -0,0 +1,107 @@
+From 7d28e12612ec08e80cf1351ea523bf4a9adfc255 Mon Sep 17 00:00:00 2001
+From: Felipe Volpone <felipevolpone@gmail.com>
+Date: Thu, 11 May 2017 10:20:02 -0300
+Subject: [PATCH] Fixing the cert-request comparing whole email address
+ case-sensitively.
+
+Now, the cert-request command compares the domain part of the
+email case-insensitively.
+
+https://pagure.io/freeipa/issue/5919
+
+Reviewed-By: Fraser Tweedale <ftweedal@redhat.com>
+Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
+---
+ ipaserver/plugins/cert.py                | 27 ++++++++++++++++++++++++---
+ ipatests/test_xmlrpc/test_cert_plugin.py | 23 +++++++++++++++++++++++
+ 2 files changed, 47 insertions(+), 3 deletions(-)
+
+diff --git a/ipaserver/plugins/cert.py b/ipaserver/plugins/cert.py
+index c1d389217265f44e646ac27d9adc8d5524c74ce7..501fc9015468c864215cfb604de37cdf6d805e52 100644
+--- a/ipaserver/plugins/cert.py
++++ b/ipaserver/plugins/cert.py
+@@ -710,7 +710,9 @@ class cert_request(Create, BaseCertMethod, VirtualCommand):
+             # fail if any email addr from DN does not appear in ldap entry
+             email_addrs = csr_obj.subject.get_attributes_for_oid(
+                     cryptography.x509.oid.NameOID.EMAIL_ADDRESS)
+-            if len(set(email_addrs) - set(principal_obj.get('mail', []))) > 0:
++            csr_emails = [attr.value for attr in email_addrs]
++            if not _emails_are_valid(csr_emails,
++                                     principal_obj.get('mail', [])):
+                 raise errors.ValidationError(
+                     name='csr',
+                     error=_(
+@@ -796,8 +798,8 @@ class cert_request(Create, BaseCertMethod, VirtualCommand):
+                             "match requested principal") % gn.name)
+             elif isinstance(gn, cryptography.x509.general_name.RFC822Name):
+                 if principal_type == USER:
+-                    if principal_obj and gn.value not in principal_obj.get(
+-                            'mail', []):
++                    if not _emails_are_valid([gn.value],
++                                             principal_obj.get('mail', [])):
+                         raise errors.ValidationError(
+                             name='csr',
+                             error=_(
+@@ -865,6 +867,25 @@ class cert_request(Create, BaseCertMethod, VirtualCommand):
+         )
+ 
+ 
++def _emails_are_valid(csr_emails, principal_emails):
++    """
++    Checks if any email address from certificate request does not
++    appear in ldap entry, comparing the domain part case-insensitively.
++    """
++
++    def lower_domain(email):
++        email_splitted = email.split('@', 1)
++        if len(email_splitted) > 1:
++            email_splitted[1] = email_splitted[1].lower()
++
++        return '@'.join(email_splitted)
++
++    principal_emails_lower = set(map(lower_domain, principal_emails))
++    csr_emails_lower = set(map(lower_domain, csr_emails))
++
++    return csr_emails_lower.issubset(principal_emails_lower)
++
++
+ def principal_to_principal_type(principal):
+     if principal.is_user:
+         return USER
+diff --git a/ipatests/test_xmlrpc/test_cert_plugin.py b/ipatests/test_xmlrpc/test_cert_plugin.py
+index 0b8277b8a6d67777db2eb328116ed0a761914663..dc9e8cba7b40e7b655ea7c0e3bed7706ac78ed1a 100644
+--- a/ipatests/test_xmlrpc/test_cert_plugin.py
++++ b/ipatests/test_xmlrpc/test_cert_plugin.py
+@@ -253,6 +253,29 @@ class test_cert(BaseCert):
+         res = api.Command['service_find'](self.service_princ)
+         assert res['count'] == 0
+ 
++    def test_00011_emails_are_valid(self):
++        """
++        Verify the different scenarios when checking if any email addr
++        from DN or SAN extension does not appear in ldap entry.
++        """
++
++        from ipaserver.plugins.cert import _emails_are_valid
++        email_addrs = [u'any@EmAiL.CoM']
++        result = _emails_are_valid(email_addrs, [u'any@email.com'])
++        assert True == result, result
++
++        email_addrs = [u'any@EmAiL.CoM']
++        result = _emails_are_valid(email_addrs, [u'any@email.com',
++                                                 u'another@email.com'])
++        assert True == result, result
++
++        result = _emails_are_valid([], [u'any@email.com'])
++        assert True == result, result
++
++        email_addrs = [u'invalidEmailAddress']
++        result = _emails_are_valid(email_addrs, [])
++        assert False == result, result
++
+ 
+ @pytest.mark.tier1
+ class test_cert_find(XMLRPC_test):
+-- 
+2.13.6
+
diff --git a/SOURCES/0031-Add-force-join-into-ipa-replica-install-manpage.patch b/SOURCES/0031-Add-force-join-into-ipa-replica-install-manpage.patch
new file mode 100644
index 0000000..75c9b16
--- /dev/null
+++ b/SOURCES/0031-Add-force-join-into-ipa-replica-install-manpage.patch
@@ -0,0 +1,29 @@
+From c5b8c6256e65e5bb735bd89ab132c28c5a03dd64 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Tibor=20Dudl=C3=A1k?= <tdudlak@redhat.com>
+Date: Tue, 13 Jun 2017 12:27:01 +0200
+Subject: [PATCH] Add --force-join into ipa-replica-install manpage
+
+Resolves: https://pagure.io/freeipa/issue/7011
+Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
+Reviewed-By: Stanislav Laznicka <slaznick@redhat.com>
+---
+ install/tools/man/ipa-replica-install.1 | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/install/tools/man/ipa-replica-install.1 b/install/tools/man/ipa-replica-install.1
+index 7d241324818dd3a5294da5e84b67a19d0d9a31b6..a1284135ac67de2b67b322aec3f6bbfb05f1a8ec 100644
+--- a/install/tools/man/ipa-replica-install.1
++++ b/install/tools/man/ipa-replica-install.1
+@@ -62,6 +62,9 @@ The Kerberos realm of an existing IPA deployment.
+ .TP
+ \fB\-\-hostname\fR
+ The hostname of this machine (FQDN). If specified, the hostname will be set and the system configuration will be updated to persist over reboot.
++.TP
++\fB\-\-force\-join\fR
++Join the host even if it is already enrolled.
+ 
+ .SS "DOMAIN LEVEL 0 OPTIONS"
+ .TP
+-- 
+2.13.6
+
diff --git a/SOURCES/0031-Create-temporaty-directories-at-the-begining-of-unin.patch b/SOURCES/0031-Create-temporaty-directories-at-the-begining-of-unin.patch
deleted file mode 100644
index 3c73e87..0000000
--- a/SOURCES/0031-Create-temporaty-directories-at-the-begining-of-unin.patch
+++ /dev/null
@@ -1,36 +0,0 @@
-From e344a42bfff8c9d124b13ae43baec72c5329e29f Mon Sep 17 00:00:00 2001
-From: David Kupka <dkupka@redhat.com>
-Date: Thu, 23 Mar 2017 12:48:06 +0100
-Subject: [PATCH] Create temporaty directories at the begining of uninstall
-
-Since commit 38c6689 temporary directories are no longer created at package
-install time. Instead they're created at server install time.
-Some steps in uninstall also assume that temporary direcories exist. Creating
-the directories in the begining of server uninstall ensure that the uninstall
-will go through.
-
-https://pagure.io/freeipa/issue/6715
-
-Reviewed-By: Martin Basti <mbasti@redhat.com>
----
- ipaserver/install/server/install.py | 4 ++++
- 1 file changed, 4 insertions(+)
-
-diff --git a/ipaserver/install/server/install.py b/ipaserver/install/server/install.py
-index de6b5b31274c87ceca5d98bcf8e80230ec6ae1f7..d7eb0bfacd0815026c82f59d76962f527e2b7dad 100644
---- a/ipaserver/install/server/install.py
-+++ b/ipaserver/install/server/install.py
-@@ -1042,6 +1042,10 @@ def uninstall(installer):
- 
-     rv = 0
- 
-+    # further steps assumes that temporary directories exists so rather
-+    # ensure they are created
-+    tasks.create_tmpfiles_dirs()
-+
-     print("Shutting down all IPA services")
-     try:
-         services.knownservices.ipa.stop()
--- 
-2.12.1
-
diff --git a/SOURCES/0032-Changed-ownership-of-ldiffile-to-DS_USER.patch b/SOURCES/0032-Changed-ownership-of-ldiffile-to-DS_USER.patch
new file mode 100644
index 0000000..d2e1476
--- /dev/null
+++ b/SOURCES/0032-Changed-ownership-of-ldiffile-to-DS_USER.patch
@@ -0,0 +1,32 @@
+From 780dc73f513cc312e87948b51e90ae885f29a8fb Mon Sep 17 00:00:00 2001
+From: Thorsten Scherf <tscherf@redhat.com>
+Date: Thu, 1 Jun 2017 22:02:57 +0200
+Subject: [PATCH] Changed ownership of ldiffile to DS_USER
+
+Resolves:
+https://pagure.io/freeipa/issue/7010
+
+Reviewed-By: Martin Basti <mbasti@redhat.com>
+Reviewed-By: Stanislav Laznicka <slaznick@redhat.com>
+---
+ ipaserver/install/ipa_restore.py | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/ipaserver/install/ipa_restore.py b/ipaserver/install/ipa_restore.py
+index 923b1d6696d33c0bb07ca018b53dd3dabcc191aa..a3824df230857b02b47c12645fadee1200afdf66 100644
+--- a/ipaserver/install/ipa_restore.py
++++ b/ipaserver/install/ipa_restore.py
+@@ -540,6 +540,10 @@ class Restore(admintool.AdminTool):
+                 ldif_parser = RemoveRUVParser(in_file, ldif_writer, self.log)
+                 ldif_parser.parse()
+ 
++        # Make sure the modified ldiffile is owned by DS_USER
++        pent = pwd.getpwnam(constants.DS_USER)
++        os.chown(ldiffile, pent.pw_uid, pent.pw_gid)
++
+         if online:
+             conn = self.get_connection()
+             ent = conn.make_entry(
+-- 
+2.13.6
+
diff --git a/SOURCES/0032-dogtag-ipa-ca-renew-agent-submit-fix-the-is_replicat.patch b/SOURCES/0032-dogtag-ipa-ca-renew-agent-submit-fix-the-is_replicat.patch
deleted file mode 100644
index cd3f5ba..0000000
--- a/SOURCES/0032-dogtag-ipa-ca-renew-agent-submit-fix-the-is_replicat.patch
+++ /dev/null
@@ -1,38 +0,0 @@
-From c7d19fca09f7398af63ceffb915afc9b5d507e1e Mon Sep 17 00:00:00 2001
-From: Florence Blanc-Renaud <flo@redhat.com>
-Date: Fri, 24 Mar 2017 11:02:33 +0100
-Subject: [PATCH] dogtag-ipa-ca-renew-agent-submit: fix the is_replicated()
- function
-
-dogtag-ipa-ca-renew-agent-submit behaves differently depending on the
-certificate it needs to renew. For instance, some certificates (such as IPA RA)
-are the same on all the hosts and the renewal is actually done only on
-the renewal master. On other nodes, the new cert is downloaded from LDAP.
-
-The function is_replicated() is returning the opposite as what it should. If
-the cert nickname is IPA RA, it should return that the cert is replicated but
-it doesn't, and this leads to a wrong code path to renew the cert.
-
-https://pagure.io/freeipa/issue/6813
-
-Reviewed-By: Jan Cholasta <jcholast@redhat.com>
----
- install/certmonger/dogtag-ipa-ca-renew-agent-submit | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/install/certmonger/dogtag-ipa-ca-renew-agent-submit b/install/certmonger/dogtag-ipa-ca-renew-agent-submit
-index cc690b8fa26854a5ab683915a5ba6a8d3c0d4ae4..5782db703c49d7c2e92c806e24e9925e8e7d710a 100755
---- a/install/certmonger/dogtag-ipa-ca-renew-agent-submit
-+++ b/install/certmonger/dogtag-ipa-ca-renew-agent-submit
-@@ -119,7 +119,7 @@ def is_renewable():
- 
- 
- def is_replicated():
--    return not get_nickname()
-+    return bool(get_nickname())
- 
- 
- def is_renewal_master():
--- 
-2.12.1
-
diff --git a/SOURCES/0033-Checks-if-Dir-Server-is-installed-and-running-before.patch b/SOURCES/0033-Checks-if-Dir-Server-is-installed-and-running-before.patch
new file mode 100644
index 0000000..c6a3dba
--- /dev/null
+++ b/SOURCES/0033-Checks-if-Dir-Server-is-installed-and-running-before.patch
@@ -0,0 +1,57 @@
+From a81a4a502b020e0b0d91e6018914ea18b4e3e47e Mon Sep 17 00:00:00 2001
+From: Felipe Barreto <fbarreto@redhat.com>
+Date: Wed, 20 Sep 2017 09:51:44 -0300
+Subject: [PATCH] Checks if Dir Server is installed and running before IPA
+ installation
+
+In cases when IPA is installed in two steps (external CA), it's
+necessary to check (in the second step) if Dir. Server is
+running before continue with the installation. If it's not,
+start Directory Server.
+
+https://pagure.io/freeipa/issue/6611
+
+Reviewed-By: Fraser Tweedale <ftweedal@redhat.com>
+Reviewed-By: Christian Heimes <cheimes@redhat.com>
+---
+ ipaplatform/redhat/services.py      | 4 ++++
+ ipaserver/install/server/install.py | 8 ++++++++
+ 2 files changed, 12 insertions(+)
+
+diff --git a/ipaplatform/redhat/services.py b/ipaplatform/redhat/services.py
+index 8fae1f3cc5b12dba0fa0192f21bc6d2d369941eb..57aa15ad9a4d83366ff02e5a5ca6e4574561e1fa 100644
+--- a/ipaplatform/redhat/services.py
++++ b/ipaplatform/redhat/services.py
+@@ -119,6 +119,10 @@ class RedHatDirectoryService(RedHatService):
+ 
+         return True
+ 
++    def is_installed(self, instance_name):
++        file_path = "{}/{}-{}".format(paths.ETC_DIRSRV, "slapd", instance_name)
++        return os.path.exists(file_path)
++
+     def restart(self, instance_name="", capture_output=True, wait=True,
+                 ldapi=False):
+     # We need to explicitly enable instances to install proper symlinks as
+diff --git a/ipaserver/install/server/install.py b/ipaserver/install/server/install.py
+index 97cbc6d8c84ee8fc21b6f8983c7897dc5d30c42d..422474fa915b4876530f304ef9424f6b31cf26cc 100644
+--- a/ipaserver/install/server/install.py
++++ b/ipaserver/install/server/install.py
+@@ -616,6 +616,14 @@ def install_check(installer):
+         # check addresses here, dns module is doing own check
+         no_matching_interface_for_ip_address_warning(ip_addresses)
+ 
++    instance_name = "-".join(realm_name.split("."))
++    dirsrv = services.knownservices.dirsrv
++    if (options.external_cert_files
++           and dirsrv.is_installed(instance_name)
++           and not dirsrv.is_running(instance_name)):
++        root_logger.debug('Starting Directory Server')
++        services.knownservices.dirsrv.start(instance_name)
++
+     if options.setup_adtrust:
+         adtrust.install_check(False, options, api)
+ 
+-- 
+2.13.6
+
diff --git a/SOURCES/0033-Simplify-KRA-transport-cert-cache.patch b/SOURCES/0033-Simplify-KRA-transport-cert-cache.patch
deleted file mode 100644
index 2e3441a..0000000
--- a/SOURCES/0033-Simplify-KRA-transport-cert-cache.patch
+++ /dev/null
@@ -1,195 +0,0 @@
-From 1190a1b41d436de4dab7a622d78217baba44a9ef Mon Sep 17 00:00:00 2001
-From: Christian Heimes <cheimes@redhat.com>
-Date: Fri, 17 Mar 2017 10:44:38 +0100
-Subject: [PATCH] Simplify KRA transport cert cache
-
-In-memory cache causes problem in forking servers. A file based cache is
-good enough. It's easier to understand and avoids performance regression
-and synchronization issues when cert becomes out-of-date.
-
-https://pagure.io/freeipa/issue/6787
-Signed-off-by: Christian Heimes <cheimes@redhat.com>
-Reviewed-By: Jan Cholasta <jcholast@redhat.com>
----
- ipaclient/plugins/vault.py | 103 ++++++++++++++++++++++++---------------------
- 1 file changed, 55 insertions(+), 48 deletions(-)
-
-diff --git a/ipaclient/plugins/vault.py b/ipaclient/plugins/vault.py
-index d677ec0287d6b37cfd63820a919c0726d3a4ae9f..3fb4900d9cf90e6902c40e1c3d8cfdafec2e28b8 100644
---- a/ipaclient/plugins/vault.py
-+++ b/ipaclient/plugins/vault.py
-@@ -20,7 +20,6 @@
- from __future__ import print_function
- 
- import base64
--import collections
- import errno
- import getpass
- import io
-@@ -558,74 +557,79 @@ class vault_mod(Local):
-         return response
- 
- 
--class _TransportCertCache(collections.MutableMapping):
-+class _TransportCertCache(object):
-     def __init__(self):
-         self._dirname = os.path.join(
--                USER_CACHE_PATH, 'ipa', 'kra-transport-certs')
--        self._transport_certs = {}
-+                USER_CACHE_PATH, 'ipa', 'kra-transport-certs'
-+        )
- 
-     def _get_filename(self, domain):
-         basename = DNSName(domain).ToASCII() + '.pem'
-         return os.path.join(self._dirname, basename)
- 
--    def __getitem__(self, domain):
--        try:
--            transport_cert = self._transport_certs[domain]
--        except KeyError:
--            transport_cert = None
-+    def load_cert(self, domain):
-+        """Load cert from cache
- 
--            filename = self._get_filename(domain)
-+        :param domain: IPA domain
-+        :return: cryptography.x509.Certificate or None
-+        """
-+        filename = self._get_filename(domain)
-+        try:
-             try:
--                try:
--                    transport_cert = x509.load_certificate_from_file(filename)
--                except EnvironmentError as e:
--                    if e.errno != errno.ENOENT:
--                        raise
--            except Exception:
--                logger.warning("Failed to load %s: %s", filename,
--                               exc_info=True)
--
--            if transport_cert is None:
--                raise KeyError(domain)
--
--            self._transport_certs[domain] = transport_cert
-+                return x509.load_certificate_from_file(filename)
-+            except EnvironmentError as e:
-+                if e.errno != errno.ENOENT:
-+                    raise
-+        except Exception:
-+            logger.warning("Failed to load %s", filename, exc_info=True)
- 
--        return transport_cert
-+    def store_cert(self, domain, transport_cert):
-+        """Store a new cert or override existing cert
- 
--    def __setitem__(self, domain, transport_cert):
-+        :param domain: IPA domain
-+        :param transport_cert: cryptography.x509.Certificate
-+        :return: True if cert was stored successfully
-+        """
-         filename = self._get_filename(domain)
--        transport_cert_der = (
--            transport_cert.public_bytes(serialization.Encoding.DER))
-+        pem = transport_cert.public_bytes(serialization.Encoding.PEM)
-         try:
-             try:
-                 os.makedirs(self._dirname)
-             except EnvironmentError as e:
-                 if e.errno != errno.EEXIST:
-                     raise
--            fd, tmpfilename = tempfile.mkstemp(dir=self._dirname)
--            os.close(fd)
--            x509.write_certificate(transport_cert_der, tmpfilename)
--            os.rename(tmpfilename, filename)
-+            with tempfile.NamedTemporaryFile(dir=self._dirname, delete=False,
-+                                             mode='wb') as f:
-+                try:
-+                    f.write(pem)
-+                    f.flush()
-+                    os.fdatasync(f.fileno())
-+                    f.close()
-+                    os.rename(f.name, filename)
-+                except Exception:
-+                    os.unlink(f.name)
-+                    raise
-         except Exception:
-             logger.warning("Failed to save %s", filename, exc_info=True)
-+            return False
-+        else:
-+            return True
- 
--        self._transport_certs[domain] = transport_cert
-+    def remove_cert(self, domain):
-+        """Remove a cert from cache, ignores errors
- 
--    def __delitem__(self, domain):
-+        :param domain: IPA domain
-+        :return: True if cert was found and removed
-+        """
-         filename = self._get_filename(domain)
-         try:
-             os.unlink(filename)
-         except EnvironmentError as e:
-             if e.errno != errno.ENOENT:
-                 logger.warning("Failed to remove %s", filename, exc_info=True)
--
--        del self._transport_certs[domain]
--
--    def __len__(self):
--        return len(self._transport_certs)
--
--    def __iter__(self):
--        return iter(self._transport_certs)
-+            return False
-+        else:
-+            return True
- 
- 
- _transport_cert_cache = _TransportCertCache()
-@@ -646,7 +650,10 @@ class vaultconfig_show(MethodOverride):
-         # cache transport certificate
-         transport_cert = x509.load_certificate(
-                 response['result']['transport_cert'], x509.DER)
--        _transport_cert_cache[self.api.env.domain] = transport_cert
-+
-+        _transport_cert_cache.store_cert(
-+            self.api.env.domain, transport_cert
-+        )
- 
-         if file:
-             with open(file, 'w') as f:
-@@ -680,7 +687,7 @@ class ModVaultData(Local):
-         except (errors.InternalError,
-                 errors.ExecutionError,
-                 errors.GenericError):
--            _transport_cert_cache.pop(self.api.env.domain, None)
-+            _transport_cert_cache.remove_cert(self.api.env.domain)
-             if raise_unexpected:
-                 raise
- 
-@@ -691,17 +698,17 @@ class ModVaultData(Local):
-         domain = self.api.env.domain
- 
-         # try call with cached transport certificate
--        transport_cert = _transport_cert_cache.get(domain)
-+        transport_cert = _transport_cert_cache.load_cert(domain)
-         if transport_cert is not None:
-             result = self._do_internal(algo, transport_cert, False,
-                                        *args, **options)
-             if result is not None:
-                 return result
- 
--        # retrieve and cache transport certificate
--        self.api.Command.vaultconfig_show()
--        transport_cert = _transport_cert_cache[domain]
--
-+        # retrieve transport certificate (cached by vaultconfig_show)
-+        response = self.api.Command.vaultconfig_show()
-+        transport_cert = x509.load_certificate(
-+            response['result']['transport_cert'], x509.DER)
-         # call with the retrieved transport certificate
-         return self._do_internal(algo, transport_cert, True,
-                                  *args, **options)
--- 
-2.12.1
-
diff --git a/SOURCES/0034-WebUI-Add-positive-number-validator.patch b/SOURCES/0034-WebUI-Add-positive-number-validator.patch
new file mode 100644
index 0000000..f4089e9
--- /dev/null
+++ b/SOURCES/0034-WebUI-Add-positive-number-validator.patch
@@ -0,0 +1,96 @@
+From a919a3ad3463eedee55b4aa2ae680c34241412b0 Mon Sep 17 00:00:00 2001
+From: Pavel Vomacka <pvomacka@redhat.com>
+Date: Tue, 11 Jul 2017 10:46:36 +0200
+Subject: [PATCH] WebUI: Add positive number validator
+
+Add new validator which inherits from integer validator
+and checks whether the integer is positive.
+
+https://pagure.io/freeipa/issue/6980
+
+Reviewed-By: Felipe Volpone <felipevolpone@gmail.com>
+Reviewed-By: Felipe Barreto <fbarreto@redhat.com>
+---
+ install/ui/src/freeipa/field.js | 43 +++++++++++++++++++++++++++++++++++++++++
+ ipaserver/plugins/internal.py   |  1 +
+ 2 files changed, 44 insertions(+)
+
+diff --git a/install/ui/src/freeipa/field.js b/install/ui/src/freeipa/field.js
+index 76ce2533af5388ff5e1a2cfe8e35286f4e55b378..f998b578c38d91819fea418ea50e03589a691cbf 100644
+--- a/install/ui/src/freeipa/field.js
++++ b/install/ui/src/freeipa/field.js
+@@ -1049,9 +1049,51 @@ field.validator = IPA.validator = function(spec) {
+          return that.true_result();
+      };
+ 
++     that.integer_validate = that.validate;
++
+      return that;
+  };
+ 
++
++/**
++ * Javascript positive integer validator
++ *
++ * It allows to insert only positive integer.
++ *
++ * @class
++ * @alternateClassName IPA.positive_integer_validator
++ * @extends IPA.validator
++ */
++ field.positive_integer_validator = IPA.positive_integer_validator = function(spec) {
++
++    var that = IPA.integer_validator(spec);
++
++    /**
++    * @inheritDoc
++    */
++
++    that.validate = function(value) {
++
++        var integer_check = that.integer_validate(value);
++
++        if (!integer_check.valid) {
++            return integer_check;
++        }
++
++        var num = parseInt(value);
++
++        if (num <= 0) {
++            return that.false_result(
++                text.get('@i18n:widget.validation.positive_number'));
++        }
++
++        return that.true_result();
++    };
++
++    return that;
++ };
++
++
+ /**
+  * Metadata validator
+  *
+@@ -1871,6 +1913,7 @@ field.register = function() {
+     v.register('unsupported', field.unsupported_validator);
+     v.register('same_password', field.same_password_validator);
+     v.register('integer', field.integer_validator);
++    v.register('positive_integer', field.positive_integer_validator);
+ 
+     l.register('adapter', field.Adapter);
+     l.register('object_adapter', field.ObjectAdapter);
+diff --git a/ipaserver/plugins/internal.py b/ipaserver/plugins/internal.py
+index ff239db07ec1235c4174c6f9451c71195ab5a60a..c293e0b5e06677f09daa4b820ffd06a2671cd6e1 100644
+--- a/ipaserver/plugins/internal.py
++++ b/ipaserver/plugins/internal.py
+@@ -982,6 +982,7 @@ class i18n_messages(Command):
+                 "min_value": _("Minimum value is ${value}"),
+                 "net_address": _("Not a valid network address (examples: 2001:db8::/64, 192.0.2.0/24)"),
+                 "parse": _("Parse error"),
++                "positive_number": _("Must be a positive number"),
+                 "port": _("'${port}' is not a valid port"),
+                 "required": _("Required field"),
+                 "unsupported": _("Unsupported value"),
+-- 
+2.13.6
+
diff --git a/SOURCES/0034-rpcserver.login_x509-Actually-return-reply-from-__ca.patch b/SOURCES/0034-rpcserver.login_x509-Actually-return-reply-from-__ca.patch
deleted file mode 100644
index 7a5c3b4..0000000
--- a/SOURCES/0034-rpcserver.login_x509-Actually-return-reply-from-__ca.patch
+++ /dev/null
@@ -1,33 +0,0 @@
-From c9eefa180576e7218d6aef063ea52915c0ce18a6 Mon Sep 17 00:00:00 2001
-From: David Kupka <dkupka@redhat.com>
-Date: Mon, 27 Mar 2017 16:09:09 +0200
-Subject: [PATCH] rpcserver.login_x509: Actually return reply from __call__
- method
-
-__call__ didn't return causing internal error in wsgi application. Previously
-this bug was hidden by some other error and the code worked even though it
-shouldn't.
-
-https://pagure.io/freeipa/issue/6819
-
-Reviewed-By: Pavel Vomacka <pvomacka@redhat.com>
----
- ipaserver/rpcserver.py | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/ipaserver/rpcserver.py b/ipaserver/rpcserver.py
-index be4e3916b6011dd2b6c90a0267990bf1e370dfb9..77ed7e124c2ca3dcb49d3a68269d6fa9875d4da0 100644
---- a/ipaserver/rpcserver.py
-+++ b/ipaserver/rpcserver.py
-@@ -842,7 +842,7 @@ class login_x509(KerberosLogin):
-                 environ, start_response, 'KRB5CCNAME not set',
-                 'Authentication failed')
- 
--        super(login_x509, self).__call__(environ, start_response)
-+        return super(login_x509, self).__call__(environ, start_response)
- 
- 
- class login_password(Backend, KerberosSession):
--- 
-2.12.1
-
diff --git a/SOURCES/0035-Backup-CA-cert-from-kerberos-folder.patch b/SOURCES/0035-Backup-CA-cert-from-kerberos-folder.patch
deleted file mode 100644
index 1aebce7..0000000
--- a/SOURCES/0035-Backup-CA-cert-from-kerberos-folder.patch
+++ /dev/null
@@ -1,27 +0,0 @@
-From 32b4dac59052bb48ba4862573d617c35e137e4b7 Mon Sep 17 00:00:00 2001
-From: Stanislav Laznicka <slaznick@redhat.com>
-Date: Mon, 27 Mar 2017 10:44:56 +0200
-Subject: [PATCH] Backup CA cert from kerberos folder
-
-https://pagure.io/freeipa/issue/6748
-
-Reviewed-By: Martin Basti <mbasti@redhat.com>
----
- ipaserver/install/ipa_backup.py | 1 +
- 1 file changed, 1 insertion(+)
-
-diff --git a/ipaserver/install/ipa_backup.py b/ipaserver/install/ipa_backup.py
-index 56583c01b1677a48c103d79123e3fbe106222f38..f71a40bb06545c8d89d1e3fdbc37d5e6e1fe8d58 100644
---- a/ipaserver/install/ipa_backup.py
-+++ b/ipaserver/install/ipa_backup.py
-@@ -165,6 +165,7 @@ class Backup(admintool.AdminTool):
-         paths.KRB5KDC_KDC_CONF,
-         paths.KDC_CERT,
-         paths.KDC_KEY,
-+        paths.CACERT_PEM,
-         paths.SYSTEMD_IPA_SERVICE,
-         paths.SYSTEMD_SYSTEM_HTTPD_IPA_CONF,
-         paths.SYSTEMD_SSSD_SERVICE,
--- 
-2.12.1
-
diff --git a/SOURCES/0035-WebUI-change-validator-of-page-size-settings.patch b/SOURCES/0035-WebUI-change-validator-of-page-size-settings.patch
new file mode 100644
index 0000000..5f15079
--- /dev/null
+++ b/SOURCES/0035-WebUI-change-validator-of-page-size-settings.patch
@@ -0,0 +1,34 @@
+From e37b90a39420cd3e4f5b6e48d83aa331cd52c9da Mon Sep 17 00:00:00 2001
+From: Pavel Vomacka <pvomacka@redhat.com>
+Date: Tue, 11 Jul 2017 10:49:46 +0200
+Subject: [PATCH] WebUI: change validator of page size settings
+
+Previously, this configuration field was validated by integer_validator
+which only checks that the input is number.
+Now new positive_integer_validator can also check that
+the inputed number positive.
+
+https://pagure.io/freeipa/issue/6980
+
+Reviewed-By: Felipe Volpone <felipevolpone@gmail.com>
+Reviewed-By: Felipe Barreto <fbarreto@redhat.com>
+---
+ install/ui/src/freeipa/Application_controller.js | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/install/ui/src/freeipa/Application_controller.js b/install/ui/src/freeipa/Application_controller.js
+index 5eb4e7a5104b780761b9a5179dbfd1501a8d1478..51f579e3cce2c28e8f1d2d231fa10711d0b2498d 100644
+--- a/install/ui/src/freeipa/Application_controller.js
++++ b/install/ui/src/freeipa/Application_controller.js
+@@ -312,7 +312,7 @@ define([
+                         $type: 'text',
+                         name: 'pagination_size',
+                         label: '@i18n:customization.table_pagination',
+-                        validators: ['integer']
++                        validators: ['positive_integer']
+                     }
+                 ]
+             });
+-- 
+2.13.6
+
diff --git a/SOURCES/0036-WebUI-fix-jslint-error.patch b/SOURCES/0036-WebUI-fix-jslint-error.patch
new file mode 100644
index 0000000..93224f9
--- /dev/null
+++ b/SOURCES/0036-WebUI-fix-jslint-error.patch
@@ -0,0 +1,30 @@
+From ae6a8489b65fb28a3381267bcfacf4a1d42047c9 Mon Sep 17 00:00:00 2001
+From: Pavel Vomacka <pvomacka@redhat.com>
+Date: Fri, 21 Jul 2017 18:49:01 +0200
+Subject: [PATCH] WebUI: fix jslint error
+
+jslint warned about parsing string to integer without explicit radix.
+This error was introduced in commit 3cac851 .
+
+Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
+Reviewed-By: Felipe Barreto <fbarreto@redhat.com>
+---
+ install/ui/src/freeipa/field.js | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/install/ui/src/freeipa/field.js b/install/ui/src/freeipa/field.js
+index f998b578c38d91819fea418ea50e03589a691cbf..6c99ddbe2e08522c14980e42ad63e28e5b739794 100644
+--- a/install/ui/src/freeipa/field.js
++++ b/install/ui/src/freeipa/field.js
+@@ -1080,7 +1080,7 @@ field.validator = IPA.validator = function(spec) {
+             return integer_check;
+         }
+ 
+-        var num = parseInt(value);
++        var num = parseInt(value, 10);
+ 
+         if (num <= 0) {
+             return that.false_result(
+-- 
+2.13.6
+
diff --git a/SOURCES/0036-spec-file-Bump-requires-to-make-Certificate-Login-in.patch b/SOURCES/0036-spec-file-Bump-requires-to-make-Certificate-Login-in.patch
deleted file mode 100644
index 1869391..0000000
--- a/SOURCES/0036-spec-file-Bump-requires-to-make-Certificate-Login-in.patch
+++ /dev/null
@@ -1,54 +0,0 @@
-From 03d0b25c585e9202ff0fa7fba96df5c9f0a1a337 Mon Sep 17 00:00:00 2001
-From: David Kupka <dkupka@redhat.com>
-Date: Thu, 23 Mar 2017 08:43:51 +0100
-Subject: [PATCH] spec file: Bump requires to make Certificate Login in WebUI
- work
-
-gssproxy >= 0.7.0-2 - fixes impersonator checking
-mod_lookup_identity >= 0.9.9 - adds support for single certificate assigned to multiple users
-mod_nss >= 1.0.14-3 - no longer sets remote user in fixup hook
-sssd-dbus >= 1.15.2 - adds FindByNameAndCertificate DBus method
-
-https://pagure.io/freeipa/issue/6823
-
-Reviewed-By: Pavel Vomacka <pvomacka@redhat.com>
-Reviewed-By: Jan Cholasta <jcholast@redhat.com>
----
- freeipa.spec.in | 13 ++++++++-----
- 1 file changed, 8 insertions(+), 5 deletions(-)
-
-diff --git a/freeipa.spec.in b/freeipa.spec.in
-index 5419ed10723fc7aa3ecc1b3f66b3ef1c8b38b12f..9c8a14a580ad80ed10e797bef9661e7b1feb81b3 100644
---- a/freeipa.spec.in
-+++ b/freeipa.spec.in
-@@ -270,9 +270,11 @@ Requires: ntp
- Requires: httpd >= 2.4.6-31
- Requires: mod_wsgi
- Requires: mod_auth_gssapi >= 1.5.0
--Requires: mod_nss >= 1.0.8-26
-+# 1.0.14-3: https://bugzilla.redhat.com/show_bug.cgi?id=1431206
-+Requires: mod_nss >= 1.0.14-3
- Requires: mod_session
--Requires: mod_lookup_identity
-+# 0.9.9: https://github.com/adelton/mod_lookup_identity/pull/3
-+Requires: mod_lookup_identity >= 0.9.9
- Requires: python-ldap >= 2.4.15
- Requires: python-gssapi >= 1.2.0
- Requires: acl
-@@ -300,9 +302,10 @@ Requires: systemd-python
- Requires: %{etc_systemd_dir}
- Requires: gzip
- Requires: oddjob
--Requires: gssproxy >= 0.7.0
--# Require 1.15.1 for the certificate identity mapping feature
--Requires: sssd-dbus >= 1.15.1
-+# 0.7.0-2: https://pagure.io/gssproxy/pull-request/172
-+Requires: gssproxy >= 0.7.0-2
-+# 1.15.2: FindByNameAndCertificate (https://pagure.io/SSSD/sssd/issue/3050)
-+Requires: sssd-dbus >= 1.15.2
- 
- Provides: %{alt_name}-server = %{version}
- Conflicts: %{alt_name}-server
--- 
-2.12.1
-
diff --git a/SOURCES/0037-Use-Custodia-0.3.1-features.patch b/SOURCES/0037-Use-Custodia-0.3.1-features.patch
deleted file mode 100644
index 44b805d..0000000
--- a/SOURCES/0037-Use-Custodia-0.3.1-features.patch
+++ /dev/null
@@ -1,236 +0,0 @@
-From a93e6040fdadd41dc7d1c46c09110b7321ed333c Mon Sep 17 00:00:00 2001
-From: Christian Heimes <cheimes@redhat.com>
-Date: Tue, 28 Feb 2017 12:07:19 +0100
-Subject: [PATCH] Use Custodia 0.3.1 features
-
-* Use sd-notify in ipa-custodia.service
-* Introduce libexec/ipa/ipa-custodia script. It comes with correct
-  default setting for IPA's config file. The new file also makes it
-  simpler to run IPA's custodia instance with its own SELinux context.
-* ipapython no longer depends on custodia
-
-The patch addresses three issues:
-
-* https://bugzilla.redhat.com/show_bug.cgi?id=1430247
-  Forward compatibility with Custodia 0.3 in Fedora rawhide
-* https://pagure.io/freeipa/issue/5825
-  Use sd-notify
-* https://pagure.io/freeipa/issue/6788
-  Prepare for separate SELinux context
-
-Signed-off-by: Christian Heimes <cheimes@redhat.com>
-Reviewed-By: Martin Basti <mbasti@redhat.com>
-Reviewed-By: Jan Cholasta <jcholast@redhat.com>
----
- freeipa.spec.in                      | 13 ++++++++-----
- init/systemd/Makefile.am             |  1 +
- init/systemd/ipa-custodia.service.in |  5 ++---
- install/tools/Makefile.am            |  1 +
- install/tools/ipa-custodia           |  6 ++++++
- ipapython/setup.py                   |  1 -
- ipaserver/secrets/service.py         | 30 ++++++++++++++++++++++++++++++
- ipaserver/setup.py                   |  1 +
- ipasetup.py.in                       |  1 +
- 9 files changed, 50 insertions(+), 9 deletions(-)
- create mode 100755 install/tools/ipa-custodia
- create mode 100644 ipaserver/secrets/service.py
-
-diff --git a/freeipa.spec.in b/freeipa.spec.in
-index 9c8a14a580ad80ed10e797bef9661e7b1feb81b3..91fca6ea974bd70847feb1e3b6db8ae3cbda061c 100644
---- a/freeipa.spec.in
-+++ b/freeipa.spec.in
-@@ -181,7 +181,8 @@ BuildRequires:  pki-base-python2
- BuildRequires:  python-pytest-multihost
- BuildRequires:  python-pytest-sourceorder
- BuildRequires:  python-jwcrypto
--BuildRequires:  python-custodia
-+# 0.3: sd_notify (https://pagure.io/freeipa/issue/5825)
-+BuildRequires:  python-custodia >= 0.3.1
- BuildRequires:  dbus-python
- BuildRequires:  python-dateutil
- BuildRequires:  python-enum34
-@@ -216,7 +217,8 @@ BuildRequires:  pki-base-python3
- BuildRequires:  python3-pytest-multihost
- BuildRequires:  python3-pytest-sourceorder
- BuildRequires:  python3-jwcrypto
--BuildRequires:  python3-custodia
-+# 0.3: sd_notify (https://pagure.io/freeipa/issue/5825)
-+BuildRequires:  python3-custodia >= 0.3.1
- BuildRequires:  python3-dbus
- BuildRequires:  python3-dateutil
- BuildRequires:  python3-enum34
-@@ -340,6 +342,7 @@ BuildArch: noarch
- Requires: %{name}-server-common = %{version}-%{release}
- Requires: %{name}-common = %{version}-%{release}
- Requires: python2-ipaclient = %{version}-%{release}
-+Requires: python-custodia >= 0.3.1
- Requires: python-ldap >= 2.4.15
- Requires: python-lxml
- Requires: python-gssapi >= 1.2.0
-@@ -370,6 +373,7 @@ BuildArch: noarch
- Requires: %{name}-server-common = %{version}-%{release}
- Requires: %{name}-common = %{version}-%{release}
- Requires: python3-ipaclient = %{version}-%{release}
-+Requires: python3-custodia >= 0.3.1
- Requires: python3-pyldap >= 2.4.15
- Requires: python3-lxml
- Requires: python3-gssapi >= 1.2.0
-@@ -399,7 +403,7 @@ BuildArch: noarch
- Requires: %{name}-client-common = %{version}-%{release}
- Requires: httpd >= 2.4.6-31
- Requires: systemd-units >= 38
--Requires: custodia
-+Requires: custodia >= 0.3.1
- 
- Provides: %{alt_name}-server-common = %{version}
- Conflicts: %{alt_name}-server-common
-@@ -650,7 +654,6 @@ Requires: python-jwcrypto
- Requires: python-cffi
- Requires: python-ldap >= 2.4.15
- Requires: python-requests
--Requires: python-custodia
- Requires: python-dns >= 1.15
- Requires: python-enum34
- Requires: python-netifaces >= 0.10.4
-@@ -699,7 +702,6 @@ Requires: python3-six
- Requires: python3-jwcrypto
- Requires: python3-cffi
- Requires: python3-pyldap >= 2.4.15
--Requires: python3-custodia
- Requires: python3-requests
- Requires: python3-dns >= 1.15
- Requires: python3-netifaces >= 0.10.4
-@@ -1160,6 +1162,7 @@ fi
- %{_libexecdir}/certmonger/dogtag-ipa-ca-renew-agent-submit
- %{_libexecdir}/certmonger/ipa-server-guard
- %dir %{_libexecdir}/ipa
-+%{_libexecdir}/ipa/ipa-custodia
- %{_libexecdir}/ipa/ipa-dnskeysyncd
- %{_libexecdir}/ipa/ipa-dnskeysync-replica
- %{_libexecdir}/ipa/ipa-ods-exporter
-diff --git a/init/systemd/Makefile.am b/init/systemd/Makefile.am
-index 325e8574812a2ec507911128dbac0315070d2897..945f6ac22a050f393990cad27156e092ce4f7a29 100644
---- a/init/systemd/Makefile.am
-+++ b/init/systemd/Makefile.am
-@@ -18,5 +18,6 @@ CLEANFILES = $(systemdsystemunit_DATA)
- 		-e 's|@IPA_SYSCONF_DIR[@]|$(IPA_SYSCONF_DIR)|g' \
- 		-e 's|@localstatedir[@]|$(localstatedir)|g' \
- 		-e 's|@sbindir[@]|$(sbindir)|g' \
-+		-e 's|@libexecdir[@]|$(libexecdir)|g' \
- 		-e 's|@sysconfenvdir[@]|$(sysconfenvdir)|g' \
- 		'$(srcdir)/$@.in' >$@
-diff --git a/init/systemd/ipa-custodia.service.in b/init/systemd/ipa-custodia.service.in
-index 3f9b128aa1b7ee373c52e1e3566048ec6028c826..0247bd8826529d638c692d827ae31393db292b4a 100644
---- a/init/systemd/ipa-custodia.service.in
-+++ b/init/systemd/ipa-custodia.service.in
-@@ -2,9 +2,8 @@
- Description=IPA Custodia Service
- 
- [Service]
--Type=simple
--
--ExecStart=@sbindir@/custodia @IPA_SYSCONF_DIR@/custodia/custodia.conf
-+Type=notify
-+ExecStart=@libexecdir@/ipa/ipa-custodia @IPA_SYSCONF_DIR@/custodia/custodia.conf
- PrivateTmp=yes
- Restart=on-failure
- RestartSec=60s
-diff --git a/install/tools/Makefile.am b/install/tools/Makefile.am
-index f2c2ce2953c3ac146a80f7e4515769683a01f843..493e5ff4a8290be8ef076135104a85f8315b7842 100644
---- a/install/tools/Makefile.am
-+++ b/install/tools/Makefile.am
-@@ -32,6 +32,7 @@ dist_sbin_SCRIPTS =		\
- 
- appdir = $(libexecdir)/ipa/
- dist_app_SCRIPTS =		\
-+	ipa-custodia		\
- 	ipa-httpd-kdcproxy	\
- 	ipa-pki-retrieve-key	\
- 	$(NULL)
-diff --git a/install/tools/ipa-custodia b/install/tools/ipa-custodia
-new file mode 100755
-index 0000000000000000000000000000000000000000..5deeeffdd78db323b6534934065772bb0ae67438
---- /dev/null
-+++ b/install/tools/ipa-custodia
-@@ -0,0 +1,6 @@
-+#!/usr/bin/python2
-+# Copyright (C) 2017  IPA Project Contributors, see COPYING for license
-+from ipaserver.secrets.service import main
-+
-+if __name__ == '__main__':
-+    main()
-diff --git a/ipapython/setup.py b/ipapython/setup.py
-index 86e4131e5f9cfc106393875018d6ac2645a38be1..2fc039fe7bb673add17404d13bf477c5b8bb0606 100755
---- a/ipapython/setup.py
-+++ b/ipapython/setup.py
-@@ -38,7 +38,6 @@ if __name__ == '__main__':
-         ],
-         install_requires=[
-             "cffi",
--            "custodia",
-             "cryptography",
-             "dnspython",
-             "gssapi",
-diff --git a/ipaserver/secrets/service.py b/ipaserver/secrets/service.py
-new file mode 100644
-index 0000000000000000000000000000000000000000..f51c46a30e4caf76e38659c2f0a6a2c645376978
---- /dev/null
-+++ b/ipaserver/secrets/service.py
-@@ -0,0 +1,30 @@
-+# Copyright (C) 2017  IPA Project Contributors, see COPYING for license
-+import argparse
-+
-+import custodia.server
-+
-+
-+argparser = argparse.ArgumentParser(
-+    prog='ipa-custodia',
-+    description='IPA Custodia service'
-+)
-+argparser.add_argument(
-+    '--debug',
-+    action='store_true',
-+    help='Debug mode'
-+)
-+argparser.add_argument(
-+    'configfile',
-+    nargs='?',
-+    type=argparse.FileType('r'),
-+    help="Path to IPA's custodia server config",
-+    default='/etc/ipa/custodia/custodia.conf'
-+)
-+
-+
-+def main():
-+    return custodia.server.main(argparser)
-+
-+
-+if __name__ == '__main__':
-+    main()
-diff --git a/ipaserver/setup.py b/ipaserver/setup.py
-index d3c735c0f9e604512d6ccd14dcd16a186c6ecad4..42b0c1b0618ef9867acb1fe2add5702a756cf2d2 100755
---- a/ipaserver/setup.py
-+++ b/ipaserver/setup.py
-@@ -47,6 +47,7 @@ if __name__ == '__main__':
-         ],
-         install_requires=[
-             "cryptography",
-+            "custodia",
-             "dbus-python",
-             "dnspython",
-             "dogtag-pki",
-diff --git a/ipasetup.py.in b/ipasetup.py.in
-index 915f0edee7ca291cc4921f6b8e4d38498253b372..7f9b2c918c0cd582706edee087ed5944451aaf2e 100644
---- a/ipasetup.py.in
-+++ b/ipasetup.py.in
-@@ -64,6 +64,7 @@ if SETUPTOOLS_VERSION < (8, 0, 0):
- 
- PACKAGE_VERSION = {
-     'cryptography': 'cryptography >= 1.4',
-+    'custodia': 'custodia >= 0.3.1',
-     'dnspython': 'dnspython >= 1.15',
-     'gssapi': 'gssapi >= 1.2.0',
-     'ipaclient': 'ipaclient == {}'.format(VERSION),
--- 
-2.12.1
-
diff --git a/SOURCES/0037-ipa-advise-for-smartcards-updated.patch b/SOURCES/0037-ipa-advise-for-smartcards-updated.patch
new file mode 100644
index 0000000..d3a9781
--- /dev/null
+++ b/SOURCES/0037-ipa-advise-for-smartcards-updated.patch
@@ -0,0 +1,35 @@
+From 1c18017e2fc7dc4e4d943611115e94dc0bc70263 Mon Sep 17 00:00:00 2001
+From: amitkuma <amitkuma@redhat.com>
+Date: Tue, 16 Jan 2018 15:56:25 +0530
+Subject: [PATCH] ipa-advise for smartcards updated
+
+......
+authconfig --enablesmartcard --smartcardmodule=sssd --updateall
+
+Advise is updated to:
+authconfig --enablesssd --enablesssdauth --enablesmartcard --smartcardmodule=sssd
+--smartcardaction=1 --updateall
+
+Resolves: https://pagure.io/freeipa/issue/7358
+Reviewed-By: Christian Heimes <cheimes@redhat.com>
+---
+ ipaserver/advise/plugins/smart_card_auth.py | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/ipaserver/advise/plugins/smart_card_auth.py b/ipaserver/advise/plugins/smart_card_auth.py
+index fb328f29ca5051ad52c9c5e0000021ad5e8b94e8..109e9ba3815301a556a38f5185918992c4622148 100644
+--- a/ipaserver/advise/plugins/smart_card_auth.py
++++ b/ipaserver/advise/plugins/smart_card_auth.py
+@@ -315,7 +315,8 @@ class config_client_for_smart_card_auth(common_smart_card_auth_config):
+ 
+     def run_authconfig_to_configure_smart_card_auth(self):
+         self.log.exit_on_failed_command(
+-            'authconfig --enablesmartcard --smartcardmodule=sssd --updateall',
++             'authconfig --enablesssd --enablesssdauth --enablesmartcard '
++             '--smartcardmodule=sssd --smartcardaction=1 --updateall',
+             [
+                 'Failed to configure Smart Card authentication in SSSD'
+             ]
+-- 
+2.13.6
+
diff --git a/SOURCES/0038-spec-file-bump-krb5-devel-BuildRequires-for-certauth.patch b/SOURCES/0038-spec-file-bump-krb5-devel-BuildRequires-for-certauth.patch
deleted file mode 100644
index 06d302d..0000000
--- a/SOURCES/0038-spec-file-bump-krb5-devel-BuildRequires-for-certauth.patch
+++ /dev/null
@@ -1,40 +0,0 @@
-From 93e0cc4aaf84e7a988a11d13674c294294b8498a Mon Sep 17 00:00:00 2001
-From: Jan Cholasta <jcholast@redhat.com>
-Date: Tue, 28 Mar 2017 10:43:31 +0000
-Subject: [PATCH] spec file: bump krb5-devel BuildRequires for certauth
-
-Bump BuildRequires on krb5-devel to the version which introduces the
-certauth pluggable interface.
-
-This fixes RPM build failure when an older version of krb5-devel was
-installed.
-
-https://pagure.io/freeipa/issue/4905
-
-Reviewed-By: David Kupka <dkupka@redhat.com>
----
- freeipa.spec.in | 6 ++----
- 1 file changed, 2 insertions(+), 4 deletions(-)
-
-diff --git a/freeipa.spec.in b/freeipa.spec.in
-index 91fca6ea974bd70847feb1e3b6db8ae3cbda061c..e7e39e87bef39653d660a345793750f59c8dd715 100644
---- a/freeipa.spec.in
-+++ b/freeipa.spec.in
-@@ -80,12 +80,10 @@ BuildRequires:  openldap-devel
- # will cause the build to fail due to unsatisfied dependencies.
- # DAL version change may cause code crash or memory leaks, it is better to fail early.
- %if 0%{?fedora} > 25
--BuildRequires: krb5-devel >= 1.15-5
- BuildRequires: krb5-kdb-version = 6.1
--%else
--# 1.12: libkrad (http://krbdev.mit.edu/rt/Ticket/Display.html?id=7678)
--BuildRequires:  krb5-devel >= 1.12
- %endif
-+# 1.15.1-3: certauth (http://krbdev.mit.edu/rt/Ticket/Display.html?id=8561)
-+BuildRequires:  krb5-devel >= 1.15.1-3
- # 1.27.4: xmlrpc_curl_xportparms.gssapi_delegation
- BuildRequires:  xmlrpc-c-devel >= 1.27.4
- BuildRequires:  popt-devel
--- 
-2.12.1
-
diff --git a/SOURCES/0039-Avoid-growing-FILE-ccaches-unnecessarily.patch b/SOURCES/0039-Avoid-growing-FILE-ccaches-unnecessarily.patch
deleted file mode 100644
index 25803da..0000000
--- a/SOURCES/0039-Avoid-growing-FILE-ccaches-unnecessarily.patch
+++ /dev/null
@@ -1,34 +0,0 @@
-From 5c84f945e0fe5e41d706fd7f700392214178b6aa Mon Sep 17 00:00:00 2001
-From: Simo Sorce <simo@redhat.com>
-Date: Wed, 22 Mar 2017 18:25:38 -0400
-Subject: [PATCH] Avoid growing FILE ccaches unnecessarily
-
-Related https://pagure.io/freeipa/issue/6775
-
-Signed-off-by: Simo Sorce <simo@redhat.com>
-Reviewed-By: Christian Heimes <cheimes@redhat.com>
-Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
----
- ipapython/session_storage.py | 6 ++++++
- 1 file changed, 6 insertions(+)
-
-diff --git a/ipapython/session_storage.py b/ipapython/session_storage.py
-index 7fe17fb235614e687a88c090336d3c59a7a24aac..a88f9f7a75c73d4dc753183a100350d197d02199 100644
---- a/ipapython/session_storage.py
-+++ b/ipapython/session_storage.py
-@@ -104,6 +104,12 @@ def store_data(princ_name, key, value):
-     """
-     Stores the session cookie in a hidden ccache entry.
-     """
-+    # FILE ccaches grow every time an entry is stored, so we need
-+    # to avoid storing the same entry multiple times.
-+    oldvalue = get_data(princ_name, key)
-+    if oldvalue == value:
-+        return
-+
-     context = krb5_context()
-     principal = krb5_principal()
-     ccache = krb5_ccache()
--- 
-2.12.1
-
diff --git a/SOURCES/0040-Handle-failed-authentication-via-cookie.patch b/SOURCES/0040-Handle-failed-authentication-via-cookie.patch
deleted file mode 100644
index 7d32ccc..0000000
--- a/SOURCES/0040-Handle-failed-authentication-via-cookie.patch
+++ /dev/null
@@ -1,120 +0,0 @@
-From d1a482316296d32551470de698a1bdd6a7efed1a Mon Sep 17 00:00:00 2001
-From: Simo Sorce <simo@redhat.com>
-Date: Wed, 22 Mar 2017 18:38:22 -0400
-Subject: [PATCH] Handle failed authentication via cookie
-
-If cookie authentication fails and we get back a 401 see if we
-tried a SPNEGO auth by checking if we had a GSSAPI context. If not
-it means our session cookie was invalid or expired or some other
-error happened on the server that requires us to try a full SPNEGO
-handshake, so go ahead and try it.
-
-Fixes https://pagure.io/freeipa/issue/6775
-
-Signed-off-by: Simo Sorce <simo@redhat.com>
-Reviewed-By: Christian Heimes <cheimes@redhat.com>
-Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
----
- ipalib/rpc.py | 52 ++++++++++++++++++++++++++++++++--------------------
- 1 file changed, 32 insertions(+), 20 deletions(-)
-
-diff --git a/ipalib/rpc.py b/ipalib/rpc.py
-index 38321d17cf2c9529738aa45cc44bbd38b08b032b..c1ceeec197c4a9c55f303f0fd431e86adb389598 100644
---- a/ipalib/rpc.py
-+++ b/ipalib/rpc.py
-@@ -586,22 +586,33 @@ class KerbTransport(SSLTransport):
-         else:
-             raise errors.KerberosError(message=unicode(e))
- 
--    def get_host_info(self, host):
-+    def _get_host(self):
-+        return self._connection[0]
-+
-+    def _remove_extra_header(self, name):
-+        for (h, v) in self._extra_headers:
-+            if h == name:
-+                self._extra_headers.remove((h, v))
-+                break
-+
-+    def get_auth_info(self, use_cookie=True):
-         """
-         Two things can happen here. If we have a session we will add
-         a cookie for that. If not we will set an Authorization header.
-         """
--        (host, extra_headers, x509) = SSLTransport.get_host_info(self, host)
--
--        if not isinstance(extra_headers, list):
--            extra_headers = []
-+        if not isinstance(self._extra_headers, list):
-+            self._extra_headers = []
- 
--        session_cookie = getattr(context, 'session_cookie', None)
--        if session_cookie:
--            extra_headers.append(('Cookie', session_cookie))
--            return (host, extra_headers, x509)
-+        # Remove any existing Cookie first
-+        self._remove_extra_header('Cookie')
-+        if use_cookie:
-+            session_cookie = getattr(context, 'session_cookie', None)
-+            if session_cookie:
-+                self._extra_headers.append(('Cookie', session_cookie))
-+                return
- 
-         # Set the remote host principal
-+        host = self._get_host()
-         service = self.service + "@" + host.split(':')[0]
- 
-         try:
-@@ -616,18 +627,14 @@ class KerbTransport(SSLTransport):
-         except gssapi.exceptions.GSSError as e:
-             self._handle_exception(e, service=service)
- 
--        self._set_auth_header(extra_headers, response)
--
--        return (host, extra_headers, x509)
-+        self._set_auth_header(response)
- 
--    def _set_auth_header(self, extra_headers, token):
--        for (h, v) in extra_headers:
--            if h == 'Authorization':
--                extra_headers.remove((h, v))
--                break
-+    def _set_auth_header(self, token):
-+        # Remove any existing authorization header first
-+        self._remove_extra_header('Authorization')
- 
-         if token:
--            extra_headers.append(
-+            self._extra_headers.append(
-                 ('Authorization', 'negotiate %s' % base64.b64encode(token).decode('ascii'))
-             )
- 
-@@ -651,18 +658,23 @@ class KerbTransport(SSLTransport):
-             if self._sec_context.complete:
-                 self._sec_context = None
-                 return True
--            self._set_auth_header(self._extra_headers, token)
-+            self._set_auth_header(token)
-+            return False
-+        elif response.status == 401:
-+            self.get_auth_info(use_cookie=False)
-             return False
-         return True
- 
-     def single_request(self, host, handler, request_body, verbose=0):
-         # Based on Python 2.7's xmllib.Transport.single_request
-         try:
--            h = SSLTransport.make_connection(self, host)
-+            h = self.make_connection(host)
- 
-             if verbose:
-                 h.set_debuglevel(1)
- 
-+            self.get_auth_info()
-+
-             while True:
-                 if six.PY2:
-                     # pylint: disable=no-value-for-parameter
--- 
-2.12.1
-
diff --git a/SOURCES/0041-Work-around-issues-fetching-session-data.patch b/SOURCES/0041-Work-around-issues-fetching-session-data.patch
deleted file mode 100644
index 5be8812..0000000
--- a/SOURCES/0041-Work-around-issues-fetching-session-data.patch
+++ /dev/null
@@ -1,331 +0,0 @@
-From 2f8033174775f55cb2377baf524fc36914aa38fa Mon Sep 17 00:00:00 2001
-From: Simo Sorce <simo@redhat.com>
-Date: Thu, 23 Mar 2017 13:02:00 -0400
-Subject: [PATCH] Work around issues fetching session data
-
-Unfortunately the MIT krb5 library has a severe limitation with FILE
-ccaches when retrieving config data. It will always only search until
-the first entry is found and return that one.
-
-For FILE caches MIT krb5 does not support removing old entries when a
-new one is stored, and storage happens only in append mode, so the end
-result is that even if an update is stored it is never returned with the
-standard krb5_cc_get_config() call.
-
-To work around this issue we simply implement what krb5_cc_get_config()
-does under the hood with the difference that we do not stop at the first
-match but keep going until all ccache entries have been checked.
-
-Related https://pagure.io/freeipa/issue/6775
-
-Signed-off-by: Simo Sorce <simo@redhat.com>
-Reviewed-By: Christian Heimes <cheimes@redhat.com>
-Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
----
- ipapython/session_storage.py | 213 ++++++++++++++++++++++++++++++++++++++-----
- 1 file changed, 190 insertions(+), 23 deletions(-)
-
-diff --git a/ipapython/session_storage.py b/ipapython/session_storage.py
-index a88f9f7a75c73d4dc753183a100350d197d02199..f3094f60000aa6e3f4b27fe91092c4214936f651 100644
---- a/ipapython/session_storage.py
-+++ b/ipapython/session_storage.py
-@@ -13,6 +13,12 @@ try:
- except OSError as e:  # pragma: no cover
-     raise ImportError(str(e))
- 
-+krb5_int32 = ctypes.c_int32
-+krb5_error_code = krb5_int32
-+krb5_magic = krb5_error_code
-+krb5_enctype = krb5_int32
-+krb5_octet = ctypes.c_uint8
-+krb5_timestamp = krb5_int32
- 
- class _krb5_context(ctypes.Structure):  # noqa
-     """krb5/krb5.h struct _krb5_context"""
-@@ -27,7 +33,7 @@ class _krb5_ccache(ctypes.Structure):  # noqa
- class _krb5_data(ctypes.Structure):  # noqa
-     """krb5/krb5.h struct _krb5_data"""
-     _fields_ = [
--        ("magic", ctypes.c_int32),
-+        ("magic", krb5_magic),
-         ("length", ctypes.c_uint),
-         ("data", ctypes.c_char_p),
-     ]
-@@ -38,6 +44,63 @@ class krb5_principal_data(ctypes.Structure):  # noqa
-     _fields_ = []
- 
- 
-+class _krb5_keyblock(ctypes.Structure):  # noqa
-+    """krb5/krb5.h struct _krb5_keyblock"""
-+    _fields_ = [
-+        ("magic", krb5_magic),
-+        ("enctype", krb5_enctype),
-+        ("length", ctypes.c_uint),
-+        ("contents", ctypes.POINTER(krb5_octet))
-+    ]
-+
-+
-+class _krb5_ticket_times(ctypes.Structure):  # noqa
-+    """krb5/krb5.h struct _krb5_ticket_times"""
-+    _fields_ = [
-+        ("authtime", krb5_timestamp),
-+        ("starttime", krb5_timestamp),
-+        ("endtime", krb5_timestamp),
-+        ("renew_till", krb5_timestamp),
-+    ]
-+
-+
-+class _krb5_address(ctypes.Structure):  # noqa
-+    """krb5/krb5.h struct _krb5_address"""
-+    _fields_ = []
-+
-+
-+class _krb5_authdata(ctypes.Structure):  # noqa
-+    """krb5/krb5.h struct _krb5_authdata"""
-+    _fields_ = []
-+
-+
-+krb5_principal = ctypes.POINTER(krb5_principal_data)
-+krb5_keyblock = _krb5_keyblock
-+krb5_ticket_times = _krb5_ticket_times
-+krb5_boolean = ctypes.c_uint
-+krb5_flags = krb5_int32
-+krb5_data = _krb5_data
-+krb5_address_p = ctypes.POINTER(_krb5_address)
-+krb5_authdata_p = ctypes.POINTER(_krb5_authdata)
-+
-+
-+class _krb5_creds(ctypes.Structure):  # noqa
-+    """krb5/krb5.h struct _krb5_creds"""
-+    _fields_ = [
-+        ("magic", krb5_magic),
-+        ("client", krb5_principal),
-+        ("server", krb5_principal),
-+        ("keyblock", krb5_keyblock),
-+        ("times", krb5_ticket_times),
-+        ("is_skey", krb5_boolean),
-+        ("ticket_flags", krb5_flags),
-+        ("addresses", ctypes.POINTER(krb5_address_p)),
-+        ("ticket", krb5_data),
-+        ("second_ticket", krb5_data),
-+        ("authdata", ctypes.POINTER(krb5_authdata_p))
-+    ]
-+
-+
- class KRB5Error(Exception):
-     pass
- 
-@@ -48,11 +111,13 @@ def krb5_errcheck(result, func, arguments):
-         raise KRB5Error(result, func.__name__, arguments)
- 
- 
--krb5_principal = ctypes.POINTER(krb5_principal_data)
- krb5_context = ctypes.POINTER(_krb5_context)
- krb5_ccache = ctypes.POINTER(_krb5_ccache)
- krb5_data_p = ctypes.POINTER(_krb5_data)
- krb5_error = ctypes.c_int32
-+krb5_creds = _krb5_creds
-+krb5_pointer = ctypes.c_void_p
-+krb5_cc_cursor = krb5_pointer
- 
- krb5_init_context = LIBKRB5.krb5_init_context
- krb5_init_context.argtypes = (ctypes.POINTER(krb5_context), )
-@@ -61,15 +126,15 @@ krb5_init_context.errcheck = krb5_errcheck
- 
- krb5_free_context = LIBKRB5.krb5_free_context
- krb5_free_context.argtypes = (krb5_context, )
--krb5_free_context.retval = None
-+krb5_free_context.restype = None
- 
- krb5_free_principal = LIBKRB5.krb5_free_principal
- krb5_free_principal.argtypes = (krb5_context, krb5_principal)
--krb5_free_principal.retval = None
-+krb5_free_principal.restype = None
- 
- krb5_free_data_contents = LIBKRB5.krb5_free_data_contents
- krb5_free_data_contents.argtypes = (krb5_context, krb5_data_p)
--krb5_free_data_contents.retval = None
-+krb5_free_data_contents.restype = None
- 
- krb5_cc_default = LIBKRB5.krb5_cc_default
- krb5_cc_default.argtypes = (krb5_context, ctypes.POINTER(krb5_ccache), )
-@@ -78,26 +143,79 @@ krb5_cc_default.errcheck = krb5_errcheck
- 
- krb5_cc_close = LIBKRB5.krb5_cc_close
- krb5_cc_close.argtypes = (krb5_context, krb5_ccache, )
--krb5_cc_close.retval = krb5_error
-+krb5_cc_close.restype = krb5_error
- krb5_cc_close.errcheck = krb5_errcheck
- 
- krb5_parse_name = LIBKRB5.krb5_parse_name
- krb5_parse_name.argtypes = (krb5_context, ctypes.c_char_p,
-                             ctypes.POINTER(krb5_principal), )
--krb5_parse_name.retval = krb5_error
-+krb5_parse_name.restype = krb5_error
- krb5_parse_name.errcheck = krb5_errcheck
- 
- krb5_cc_set_config = LIBKRB5.krb5_cc_set_config
- krb5_cc_set_config.argtypes = (krb5_context, krb5_ccache, krb5_principal,
-                                ctypes.c_char_p, krb5_data_p, )
--krb5_cc_set_config.retval = krb5_error
-+krb5_cc_set_config.restype = krb5_error
- krb5_cc_set_config.errcheck = krb5_errcheck
- 
--krb5_cc_get_config = LIBKRB5.krb5_cc_get_config
--krb5_cc_get_config.argtypes = (krb5_context, krb5_ccache, krb5_principal,
--                               ctypes.c_char_p, krb5_data_p, )
--krb5_cc_get_config.retval = krb5_error
--krb5_cc_get_config.errcheck = krb5_errcheck
-+krb5_cc_get_principal = LIBKRB5.krb5_cc_get_principal
-+krb5_cc_get_principal.argtypes = (krb5_context, krb5_ccache,
-+                                  ctypes.POINTER(krb5_principal), )
-+krb5_cc_get_principal.restype = krb5_error
-+krb5_cc_get_principal.errcheck = krb5_errcheck
-+
-+# krb5_build_principal is a variadic function but that can't be expressed
-+# in a ctypes argtypes definition, so I explicitly listed the number of
-+# arguments we actually use through the code for type checking purposes
-+krb5_build_principal = LIBKRB5.krb5_build_principal
-+krb5_build_principal.argtypes = (krb5_context, ctypes.POINTER(krb5_principal),
-+                                 ctypes.c_uint, ctypes.c_char_p,
-+                                 ctypes.c_char_p, ctypes.c_char_p,
-+                                 ctypes.c_char_p, ctypes.c_char_p, )
-+krb5_build_principal.restype = krb5_error
-+krb5_build_principal.errcheck = krb5_errcheck
-+
-+krb5_cc_start_seq_get = LIBKRB5.krb5_cc_start_seq_get
-+krb5_cc_start_seq_get.argtypes = (krb5_context, krb5_ccache,
-+                                  ctypes.POINTER(krb5_cc_cursor), )
-+krb5_cc_start_seq_get.restype = krb5_error
-+krb5_cc_start_seq_get.errcheck = krb5_errcheck
-+
-+krb5_cc_next_cred = LIBKRB5.krb5_cc_next_cred
-+krb5_cc_next_cred.argtypes = (krb5_context, krb5_ccache,
-+                              ctypes.POINTER(krb5_cc_cursor),
-+                              ctypes.POINTER(krb5_creds), )
-+krb5_cc_next_cred.restype = krb5_error
-+krb5_cc_next_cred.errcheck = krb5_errcheck
-+
-+krb5_cc_end_seq_get = LIBKRB5.krb5_cc_end_seq_get
-+krb5_cc_end_seq_get.argtypes = (krb5_context, krb5_ccache,
-+                                ctypes.POINTER(krb5_cc_cursor), )
-+krb5_cc_end_seq_get.restype = krb5_error
-+krb5_cc_end_seq_get.errcheck = krb5_errcheck
-+
-+krb5_free_cred_contents = LIBKRB5.krb5_free_cred_contents
-+krb5_free_cred_contents.argtypes = (krb5_context, ctypes.POINTER(krb5_creds))
-+krb5_free_cred_contents.restype = krb5_error
-+krb5_free_cred_contents.errcheck = krb5_errcheck
-+
-+krb5_principal_compare = LIBKRB5.krb5_principal_compare
-+krb5_principal_compare.argtypes = (krb5_context, krb5_principal,
-+                                   krb5_principal, )
-+krb5_principal_compare.restype = krb5_boolean
-+
-+krb5_unparse_name = LIBKRB5.krb5_unparse_name
-+krb5_unparse_name.argtypes = (krb5_context, krb5_principal,
-+                              ctypes.POINTER(ctypes.c_char_p), )
-+krb5_unparse_name.restype = krb5_error
-+krb5_unparse_name.errcheck = krb5_errcheck
-+
-+krb5_free_unparsed_name = LIBKRB5.krb5_free_unparsed_name
-+krb5_free_unparsed_name.argtypes = (krb5_context, ctypes.c_char_p, )
-+krb5_free_unparsed_name.restype = None
-+
-+CONF_REALM = "X-CACHECONF:"
-+CONF_NAME = "krb5_ccache_conf_data"
- 
- 
- def store_data(princ_name, key, value):
-@@ -144,29 +262,78 @@ def get_data(princ_name, key):
-     """
-     context = krb5_context()
-     principal = krb5_principal()
-+    srv_princ = krb5_principal()
-     ccache = krb5_ccache()
--    data = _krb5_data()
-+    pname_princ = krb5_principal()
-+    pname = ctypes.c_char_p()
- 
-     try:
-         krb5_init_context(ctypes.byref(context))
- 
--        krb5_parse_name(context, ctypes.c_char_p(princ_name),
--                        ctypes.byref(principal))
--
-         krb5_cc_default(context, ctypes.byref(ccache))
-+        krb5_cc_get_principal(context, ccache, ctypes.byref(principal))
- 
--        krb5_cc_get_config(context, ccache, principal, key,
--                           ctypes.byref(data))
--
--        return str(data.data)
-+        # We need to parse and then unparse the name in case the pric_name
-+        # passed in comes w/o a realm attached
-+        krb5_parse_name(context, ctypes.c_char_p(princ_name),
-+                        ctypes.byref(pname_princ))
-+        krb5_unparse_name(context, pname_princ, ctypes.byref(pname))
-+
-+        krb5_build_principal(context, ctypes.byref(srv_princ),
-+                             len(CONF_REALM), ctypes.c_char_p(CONF_REALM),
-+                             ctypes.c_char_p(CONF_NAME), ctypes.c_char_p(key),
-+                             pname, ctypes.c_char_p(None))
-+
-+        # Unfortunately we can't just use krb5_cc_get_config()
-+        # because of bugs in some ccache handling code in krb5
-+        # libraries that would always return the first entry
-+        # stored and not the last one, which is the one we want.
-+        cursor = krb5_cc_cursor()
-+        creds = krb5_creds()
-+        got_creds = False
-+        krb5_cc_start_seq_get(context, ccache, ctypes.byref(cursor))
-+        try:
-+            while True:
-+                checkcreds = krb5_creds()
-+                # the next function will throw an error and break out of the
-+                # while loop when we try to access past the last cred
-+                krb5_cc_next_cred(context, ccache, ctypes.byref(cursor),
-+                                  ctypes.byref(checkcreds))
-+                if (krb5_principal_compare(context, principal,
-+                                          checkcreds.client) == 1 and
-+                    krb5_principal_compare(context, srv_princ,
-+                                           checkcreds.server) == 1):
-+                    if got_creds:
-+                        krb5_free_cred_contents(context, ctypes.byref(creds))
-+                    creds = checkcreds
-+                    got_creds = True
-+                    # We do not stop here, as we want the LAST entry
-+                    # in the ccache for those ccaches that cannot delete
-+                    # but only always append, like FILE
-+                else:
-+                    krb5_free_cred_contents(context,
-+                                            ctypes.byref(checkcreds))
-+        except KRB5Error:
-+            pass
-+        finally:
-+            krb5_cc_end_seq_get(context, ccache, ctypes.byref(cursor))
-+
-+        if got_creds:
-+            data = creds.ticket.data.decode('utf-8')
-+            krb5_free_cred_contents(context, ctypes.byref(creds))
-+            return data
- 
-     finally:
-         if principal:
-             krb5_free_principal(context, principal)
-+        if srv_princ:
-+            krb5_free_principal(context, srv_princ)
-+        if pname_princ:
-+            krb5_free_principal(context, pname_princ)
-+        if pname:
-+            krb5_free_unparsed_name(context, pname)
-         if ccache:
-             krb5_cc_close(context, ccache)
--        if data:
--            krb5_free_data_contents(context, data)
-         if context:
-             krb5_free_context(context)
- 
--- 
-2.12.1
-
diff --git a/SOURCES/0042-Prevent-churn-on-ccaches.patch b/SOURCES/0042-Prevent-churn-on-ccaches.patch
deleted file mode 100644
index 1912a24..0000000
--- a/SOURCES/0042-Prevent-churn-on-ccaches.patch
+++ /dev/null
@@ -1,71 +0,0 @@
-From df5600dc012465f2f18a54aa451353f0fd9d5453 Mon Sep 17 00:00:00 2001
-From: Simo Sorce <simo@redhat.com>
-Date: Thu, 23 Mar 2017 17:49:27 -0400
-Subject: [PATCH] Prevent churn on ccaches
-
-We slice down the received cookie so that just the content that matter
-is preserved. Thi is ok because servers can't trust anything else anyway
-and will accept a cookie with the ancillary data missing.
-
-By removing variable parts like the expiry component added by
-mod_session or the Expiration or Max-Age metadata we keep only the part
-of the cookie that changes only when a new session is generated.
-
-This way when storing the cookie we actually add a new entry in the
-ccache only when the session actually changes, and this prevents churn
-on FILE based ccaches.
-
-Related https://pagure.io/freeipa/issue/6775
-
-Signed-off-by: Simo Sorce <simo@redhat.com>
-Reviewed-By: Christian Heimes <cheimes@redhat.com>
-Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
----
- ipalib/rpc.py | 17 ++++++++++++++++-
- 1 file changed, 16 insertions(+), 1 deletion(-)
-
-diff --git a/ipalib/rpc.py b/ipalib/rpc.py
-index c1ceeec197c4a9c55f303f0fd431e86adb389598..5c49bd2456b7e564043a886c840fa2678060f9e3 100644
---- a/ipalib/rpc.py
-+++ b/ipalib/rpc.py
-@@ -38,6 +38,7 @@ import os
- import locale
- import base64
- import json
-+import re
- import socket
- import gzip
- 
-@@ -737,6 +738,20 @@ class KerbTransport(SSLTransport):
-             self.send_content(connection, request_body)
-             return connection
- 
-+    # Find all occurrences of the expiry component
-+    expiry_re = re.compile(r'.*?(&expiry=\d+).*?')
-+
-+    def _slice_session_cookie(self, session_cookie):
-+        # Keep only the cookie value and strip away all other info.
-+        # This is to reduce the churn on FILE ccaches which grow every time we
-+        # set new data. The expiration time for the cookie is set in the
-+        # encrypted data anyway and will be enforced by the server
-+        http_cookie = session_cookie.http_cookie()
-+        # We also remove the "expiry" part from the data which is not required
-+        for exp in self.expiry_re.findall(http_cookie):
-+            http_cookie = http_cookie.replace(exp, '')
-+        return http_cookie
-+
-     def store_session_cookie(self, cookie_header):
-         '''
-         Given the contents of a Set-Cookie header scan the header and
-@@ -787,7 +802,7 @@ class KerbTransport(SSLTransport):
-         if session_cookie is None:
-             return
- 
--        cookie_string = str(session_cookie)
-+        cookie_string = self._slice_session_cookie(session_cookie)
-         root_logger.debug("storing cookie '%s' for principal %s", cookie_string, principal)
-         try:
-             update_persistent_client_session_data(principal, cookie_string)
--- 
-2.12.1
-
diff --git a/SOURCES/0043-Generate-PIN-for-PKI-to-help-Dogtag-in-FIPS.patch b/SOURCES/0043-Generate-PIN-for-PKI-to-help-Dogtag-in-FIPS.patch
deleted file mode 100644
index 4d1370c..0000000
--- a/SOURCES/0043-Generate-PIN-for-PKI-to-help-Dogtag-in-FIPS.patch
+++ /dev/null
@@ -1,68 +0,0 @@
-From 036605789d6b34f5592d2ef38723eeb87e6ae21a Mon Sep 17 00:00:00 2001
-From: Stanislav Laznicka <slaznick@redhat.com>
-Date: Tue, 28 Mar 2017 13:54:16 +0200
-Subject: [PATCH] Generate PIN for PKI to help Dogtag in FIPS
-
-Dogtag is currently unable to generate a PIN it could use for
-an NSS database creation in FIPS. Generate it for them so that
-we don't fail.
-
-https://pagure.io/freeipa/issue/6824
-
-Reviewed-By: Tomas Krizek <tkrizek@redhat.com>
----
- ipaserver/install/cainstance.py  | 6 +++++-
- ipaserver/install/krainstance.py | 6 +++++-
- 2 files changed, 10 insertions(+), 2 deletions(-)
-
-diff --git a/ipaserver/install/cainstance.py b/ipaserver/install/cainstance.py
-index f0d3c236810d01f08192b239c0edb362ed78e071..92bb760d39d23fedb40b7e3c5bea53381f1c87ad 100644
---- a/ipaserver/install/cainstance.py
-+++ b/ipaserver/install/cainstance.py
-@@ -541,6 +541,10 @@ class CAInstance(DogtagInstance):
-         # CA key algorithm
-         config.set("CA", "pki_ca_signing_key_algorithm", self.ca_signing_algorithm)
- 
-+        # generate pin which we know can be used for FIPS NSS database
-+        pki_pin = ipautil.ipa_generate_password()
-+        config.set("CA", "pki_pin", pki_pin)
-+
-         if self.clone:
- 
-             if self.no_db_setup:
-@@ -613,7 +617,7 @@ class CAInstance(DogtagInstance):
-         try:
-             DogtagInstance.spawn_instance(
-                 self, cfg_file,
--                nolog_list=(self.dm_password, self.admin_password)
-+                nolog_list=(self.dm_password, self.admin_password, pki_pin)
-             )
-         finally:
-             os.remove(cfg_file)
-diff --git a/ipaserver/install/krainstance.py b/ipaserver/install/krainstance.py
-index b41ccb6fa6517f53ad1f83389b45795f0cd135bc..34d667857a8055752e258a591af983190f33daa5 100644
---- a/ipaserver/install/krainstance.py
-+++ b/ipaserver/install/krainstance.py
-@@ -235,6 +235,10 @@ class KRAInstance(DogtagInstance):
-             "KRA", "pki_share_dbuser_dn",
-             str(DN(('uid', 'pkidbuser'), ('ou', 'people'), ('o', 'ipaca'))))
- 
-+        # generate pin which we know can be used for FIPS NSS database
-+        pki_pin = ipautil.ipa_generate_password()
-+        config.set("KRA", "pki_pin", pki_pin)
-+
-         _p12_tmpfile_handle, p12_tmpfile_name = tempfile.mkstemp(dir=paths.TMP)
- 
-         if self.clone:
-@@ -275,7 +279,7 @@ class KRAInstance(DogtagInstance):
-         try:
-             DogtagInstance.spawn_instance(
-                 self, cfg_file,
--                nolog_list=(self.dm_password, self.admin_password)
-+                nolog_list=(self.dm_password, self.admin_password, pki_pin)
-             )
-         finally:
-             os.remove(p12_tmpfile_name)
--- 
-2.12.1
-
diff --git a/SOURCES/0044-httpinstance.disable_system_trust-Don-t-fail-if-modu.patch b/SOURCES/0044-httpinstance.disable_system_trust-Don-t-fail-if-modu.patch
deleted file mode 100644
index f8356de..0000000
--- a/SOURCES/0044-httpinstance.disable_system_trust-Don-t-fail-if-modu.patch
+++ /dev/null
@@ -1,47 +0,0 @@
-From 9cacddeb763c3e07ee31ac5bc2528cfb274b57b1 Mon Sep 17 00:00:00 2001
-From: David Kupka <dkupka@redhat.com>
-Date: Mon, 27 Mar 2017 09:30:53 +0200
-Subject: [PATCH] httpinstance.disable_system_trust: Don't fail if module 'Root
- Certs' is not available
-
-Server installation failed when attmpting to disable module 'Root Certs' and
-the module was not available in HTTP_ALIAS_DIR. When the module is not
-available there's no need to disable it and the error may be treated as
-success.
-
-https://pagure.io/freeipa/issue/6803
-
-Reviewed-By: Christian Heimes <cheimes@redhat.com>
-Reviewed-By: Stanislav Laznicka <slaznick@redhat.com>
----
- ipaserver/install/httpinstance.py | 14 +++++++++++---
- 1 file changed, 11 insertions(+), 3 deletions(-)
-
-diff --git a/ipaserver/install/httpinstance.py b/ipaserver/install/httpinstance.py
-index f6f0b0c4f6acd648aa9f6f5d7400617613245473..01b55e7a7b00d020b7745c419267ad4f0ba86804 100644
---- a/ipaserver/install/httpinstance.py
-+++ b/ipaserver/install/httpinstance.py
-@@ -355,9 +355,17 @@ class HTTPInstance(service.Service):
-         name = 'Root Certs'
-         args = [paths.MODUTIL, '-dbdir', paths.HTTPD_ALIAS_DIR, '-force']
- 
--        result = ipautil.run(args + ['-list', name],
--                             env={},
--                             capture_output=True)
-+        try:
-+            result = ipautil.run(args + ['-list', name],
-+                                 env={},
-+                                 capture_output=True)
-+        except ipautil.CalledProcessError as e:
-+            if e.returncode == 29:  # ERROR: Module not found in database.
-+                root_logger.debug(
-+                    'Module %s not available, treating as disabled', name)
-+                return False
-+            raise
-+
-         if 'Status: Enabled' in result.output:
-             ipautil.run(args + ['-disable', name], env={})
-             return True
--- 
-2.12.1
-
diff --git a/SOURCES/0045-extdom-do-reverse-search-for-domain-separator.patch b/SOURCES/0045-extdom-do-reverse-search-for-domain-separator.patch
deleted file mode 100644
index c422b4d..0000000
--- a/SOURCES/0045-extdom-do-reverse-search-for-domain-separator.patch
+++ /dev/null
@@ -1,49 +0,0 @@
-From e795c094ac6ccc8a33e247ba56b93c35ed9cf57d Mon Sep 17 00:00:00 2001
-From: Sumit Bose <sbose@redhat.com>
-Date: Fri, 17 Mar 2017 14:10:52 +0100
-Subject: [PATCH] extdom: do reverse search for domain separator
-
-To avoid issues which @-signs in the short user or group names it is
-better to search for the domain separator starting at the end of the
-fully-qualified name.
-
-Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
-Reviewed-By: David Kupka <dkupka@redhat.com>
----
- daemons/ipa-slapi-plugins/ipa-extdom-extop/ipa_extdom_common.c | 6 +++---
- 1 file changed, 3 insertions(+), 3 deletions(-)
-
-diff --git a/daemons/ipa-slapi-plugins/ipa-extdom-extop/ipa_extdom_common.c b/daemons/ipa-slapi-plugins/ipa-extdom-extop/ipa_extdom_common.c
-index e629247fd771e374d50486d836cd3b0d8d32a78a..aa1ff10dfbf51b87a367261202b39d1346bd337a 100644
---- a/daemons/ipa-slapi-plugins/ipa-extdom-extop/ipa_extdom_common.c
-+++ b/daemons/ipa-slapi-plugins/ipa-extdom-extop/ipa_extdom_common.c
-@@ -515,7 +515,7 @@ int pack_ber_user(struct ipa_extdom_ctx *ctx,
-     char *short_user_name = NULL;
- 
-     short_user_name = strdup(user_name);
--    if ((locat = strchr(short_user_name, SSSD_DOMAIN_SEPARATOR)) != NULL) {
-+    if ((locat = strrchr(short_user_name, SSSD_DOMAIN_SEPARATOR)) != NULL) {
-         if (strcasecmp(locat+1, domain_name) == 0  ) {
-             locat[0] = '\0';
-         } else {
-@@ -626,7 +626,7 @@ int pack_ber_group(enum response_types response_type,
-     char *short_group_name = NULL;
- 
-     short_group_name = strdup(group_name);
--    if ((locat = strchr(short_group_name, SSSD_DOMAIN_SEPARATOR)) != NULL) {
-+    if ((locat = strrchr(short_group_name, SSSD_DOMAIN_SEPARATOR)) != NULL) {
-         if (strcasecmp(locat+1, domain_name) == 0  ) {
-             locat[0] = '\0';
-         } else {
-@@ -901,7 +901,7 @@ static int handle_sid_or_cert_request(struct ipa_extdom_ctx *ctx,
-         goto done;
-     }
- 
--    sep = strchr(fq_name, SSSD_DOMAIN_SEPARATOR);
-+    sep = strrchr(fq_name, SSSD_DOMAIN_SEPARATOR);
-     if (sep == NULL) {
-         set_err_msg(req, "Failed to split fully qualified name");
-         ret = LDAP_OPERATIONS_ERROR;
--- 
-2.12.1
-
diff --git a/SOURCES/0046-extdom-improve-cert-request.patch b/SOURCES/0046-extdom-improve-cert-request.patch
deleted file mode 100644
index bbdf685..0000000
--- a/SOURCES/0046-extdom-improve-cert-request.patch
+++ /dev/null
@@ -1,243 +0,0 @@
-From b2af54f9e327763783f482b3d5b7b3819ce75f82 Mon Sep 17 00:00:00 2001
-From: Sumit Bose <sbose@redhat.com>
-Date: Fri, 17 Mar 2017 14:48:50 +0100
-Subject: [PATCH] extdom: improve cert request
-
-Certificates can be assigned to multiple user so the extdom plugin must
-use sss_nss_getlistbycert() instead of sss_nss_getnamebycert() and
-return a list of fully-qualified user names.
-
-Due to issues on the SSSD side the current version of lookups by
-certificates didn't work at all and the changes here won't break
-existing clients.
-
-Related to https://pagure.io/freeipa/issue/6826
-
-Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
-Reviewed-By: David Kupka <dkupka@redhat.com>
----
- .../ipa-extdom-extop/ipa_extdom.h                  |   3 +-
- .../ipa-extdom-extop/ipa_extdom_common.c           | 157 ++++++++++++++++++---
- server.m4                                          |   2 +-
- 3 files changed, 143 insertions(+), 19 deletions(-)
-
-diff --git a/daemons/ipa-slapi-plugins/ipa-extdom-extop/ipa_extdom.h b/daemons/ipa-slapi-plugins/ipa-extdom-extop/ipa_extdom.h
-index 34e2d3c795e33bbeb9552910d80ddcc828751b93..bc29f069816b0ce13578c9ae14c61edb832d44e4 100644
---- a/daemons/ipa-slapi-plugins/ipa-extdom-extop/ipa_extdom.h
-+++ b/daemons/ipa-slapi-plugins/ipa-extdom-extop/ipa_extdom.h
-@@ -95,7 +95,8 @@ enum response_types {
-     RESP_USER,
-     RESP_GROUP,
-     RESP_USER_GROUPLIST,
--    RESP_GROUP_MEMBERS
-+    RESP_GROUP_MEMBERS,
-+    RESP_NAME_LIST
- };
- 
- struct extdom_req {
-diff --git a/daemons/ipa-slapi-plugins/ipa-extdom-extop/ipa_extdom_common.c b/daemons/ipa-slapi-plugins/ipa-extdom-extop/ipa_extdom_common.c
-index aa1ff10dfbf51b87a367261202b39d1346bd337a..fe225fa86669a6728bec5014be41d80275f10717 100644
---- a/daemons/ipa-slapi-plugins/ipa-extdom-extop/ipa_extdom_common.c
-+++ b/daemons/ipa-slapi-plugins/ipa-extdom-extop/ipa_extdom_common.c
-@@ -698,6 +698,90 @@ done:
-     return ret;
- }
- 
-+int pack_ber_name_list(struct extdom_req *req, char **fq_name_list,
-+                       struct berval **berval)
-+{
-+    BerElement *ber = NULL;
-+    int ret;
-+    char *sep;
-+    size_t c;
-+    size_t len;
-+    size_t name_len;
-+
-+    /* count the names */
-+    for (c = 0; fq_name_list[c] != NULL; c++);
-+    if (c == 0) {
-+        set_err_msg(req, "Empty name list");
-+        return LDAP_NO_SUCH_OBJECT;
-+    }
-+
-+    ber = ber_alloc_t( LBER_USE_DER );
-+    if (ber == NULL) {
-+        set_err_msg(req, "BER alloc failed");
-+        return LDAP_OPERATIONS_ERROR;
-+    }
-+
-+
-+    ret = ber_printf(ber,"{e{", RESP_NAME_LIST);
-+    if (ret == -1) {
-+        set_err_msg(req, "BER start failed");
-+        ber_free(ber, 1);
-+        return LDAP_OPERATIONS_ERROR;
-+    }
-+
-+    for (c = 0; fq_name_list[c] != NULL; c++) {
-+        len = strlen(fq_name_list[c]);
-+        if (len < 3) {
-+            set_err_msg(req, "Fully qualified name too short");
-+            ber_free(ber, 1);
-+            return LDAP_OPERATIONS_ERROR;
-+        }
-+
-+        sep = strrchr(fq_name_list[c], SSSD_DOMAIN_SEPARATOR);
-+        if (sep == NULL) {
-+            set_err_msg(req, "Failed to split fully qualified name");
-+            ber_free(ber, 1);
-+            return LDAP_OPERATIONS_ERROR;
-+        }
-+
-+        name_len = sep - fq_name_list[c];
-+        if (name_len == 0) {
-+            set_err_msg(req, "Missing name.");
-+            ber_free(ber, 1);
-+            return LDAP_OPERATIONS_ERROR;
-+        }
-+        if (name_len + 1 == len) {
-+            set_err_msg(req, "Missing domain.");
-+            ber_free(ber, 1);
-+            return LDAP_OPERATIONS_ERROR;
-+        }
-+
-+        ret = ber_printf(ber,"{oo}", (sep + 1),  len - name_len -1,
-+                                      fq_name_list[c], name_len);
-+        if (ret == -1) {
-+        set_err_msg(req, "BER list item failed");
-+            ber_free(ber, 1);
-+            return LDAP_OPERATIONS_ERROR;
-+        }
-+    }
-+
-+    ret = ber_printf(ber,"}}");
-+    if (ret == -1) {
-+        set_err_msg(req, "BER end failed");
-+        ber_free(ber, 1);
-+        return LDAP_OPERATIONS_ERROR;
-+    }
-+
-+    ret = ber_flatten(ber, berval);
-+    ber_free(ber, 1);
-+    if (ret == -1) {
-+        set_err_msg(req, "BER flatten failed");
-+        return LDAP_OPERATIONS_ERROR;
-+    }
-+
-+    return LDAP_SUCCESS;
-+}
-+
- int pack_ber_name(const char *domain_name, const char *name,
-                   struct berval **berval)
- {
-@@ -867,12 +951,56 @@ done:
-     return ret;
- }
- 
--static int handle_sid_or_cert_request(struct ipa_extdom_ctx *ctx,
--                                      struct extdom_req *req,
--                                      enum request_types request_type,
--                                      enum input_types input_type,
--                                      const char *input,
--                                      struct berval **berval)
-+static int handle_cert_request(struct ipa_extdom_ctx *ctx,
-+                               struct extdom_req *req,
-+                               enum request_types request_type,
-+                               enum input_types input_type,
-+                               const char *input,
-+                               struct berval **berval)
-+{
-+    int ret;
-+    char **fq_names = NULL;
-+    enum sss_id_type *id_types = NULL;
-+    size_t c;
-+
-+    if (request_type != REQ_SIMPLE) {
-+        set_err_msg(req, "Only simple request type allowed "
-+                         "for lookups by certificate");
-+        ret = LDAP_PROTOCOL_ERROR;
-+        goto done;
-+    }
-+
-+    ret = sss_nss_getlistbycert(input, &fq_names, &id_types);
-+    if (ret != 0) {
-+        if (ret == ENOENT) {
-+            ret = LDAP_NO_SUCH_OBJECT;
-+        } else {
-+            set_err_msg(req, "Failed to lookup name by certificate");
-+            ret = LDAP_OPERATIONS_ERROR;
-+        }
-+        goto done;
-+    }
-+
-+    ret = pack_ber_name_list(req, fq_names, berval);
-+
-+done:
-+    if (fq_names != NULL) {
-+        for (c = 0; fq_names[c] != NULL; c++) {
-+            free(fq_names[c]);
-+        }
-+        free(fq_names);
-+    }
-+    free(id_types);
-+
-+    return ret;
-+}
-+
-+static int handle_sid_request(struct ipa_extdom_ctx *ctx,
-+                              struct extdom_req *req,
-+                              enum request_types request_type,
-+                              enum input_types input_type,
-+                              const char *input,
-+                              struct berval **berval)
- {
-     int ret;
-     struct passwd pwd;
-@@ -886,11 +1014,7 @@ static int handle_sid_or_cert_request(struct ipa_extdom_ctx *ctx,
-     enum sss_id_type id_type;
-     struct sss_nss_kv *kv_list = NULL;
- 
--    if (input_type == INP_SID) {
--        ret = sss_nss_getnamebysid(input, &fq_name, &id_type);
--    } else {
--        ret = sss_nss_getnamebycert(input, &fq_name, &id_type);
--    }
-+    ret = sss_nss_getnamebysid(input, &fq_name, &id_type);
-     if (ret != 0) {
-         if (ret == ENOENT) {
-             ret = LDAP_NO_SUCH_OBJECT;
-@@ -1147,13 +1271,12 @@ int handle_request(struct ipa_extdom_ctx *ctx, struct extdom_req *req,
- 
-         break;
-     case INP_SID:
-+        ret = handle_sid_request(ctx, req, req->request_type,
-+                                 req->input_type, req->data.sid, berval);
-+        break;
-     case INP_CERT:
--        ret = handle_sid_or_cert_request(ctx, req, req->request_type,
--                                         req->input_type,
--                                         req->input_type == INP_SID ?
--                                                                 req->data.sid :
--                                                                 req->data.cert,
--                                         berval);
-+        ret = handle_cert_request(ctx, req, req->request_type,
-+                                  req->input_type, req->data.cert, berval);
-         break;
-     case INP_NAME:
-         ret = handle_name_request(ctx, req, req->request_type,
-diff --git a/server.m4 b/server.m4
-index a4c99195ae535e586445cf5bbe9fef457d224531..5d5333e194cb339d31576f54a70d96becadf9a87 100644
---- a/server.m4
-+++ b/server.m4
-@@ -28,7 +28,7 @@ DIRSRV_CFLAGS="$DIRSRV_CFLAGS $NSPR_CFLAGS"
- 
- dnl -- sss_idmap is needed by the extdom exop --
- PKG_CHECK_MODULES([SSSIDMAP], [sss_idmap])
--PKG_CHECK_MODULES([SSSNSSIDMAP], [sss_nss_idmap >= 1.13.90])
-+PKG_CHECK_MODULES([SSSNSSIDMAP], [sss_nss_idmap >= 1.15.2])
- 
- dnl -- sss_certmap and certauth.h are needed by the IPA KDB certauth plugin --
- PKG_CHECK_EXISTS([sss_certmap],
--- 
-2.12.1
-
diff --git a/SOURCES/0047-spec-file-bump-libsss_nss_idmap-devel-BuildRequires.patch b/SOURCES/0047-spec-file-bump-libsss_nss_idmap-devel-BuildRequires.patch
deleted file mode 100644
index a7fd0f5..0000000
--- a/SOURCES/0047-spec-file-bump-libsss_nss_idmap-devel-BuildRequires.patch
+++ /dev/null
@@ -1,37 +0,0 @@
-From e7091fc939b7b7a1c23f4e95220e343ca21958ad Mon Sep 17 00:00:00 2001
-From: Jan Cholasta <jcholast@redhat.com>
-Date: Wed, 29 Mar 2017 07:14:24 +0000
-Subject: [PATCH] spec file: bump libsss_nss_idmap-devel BuildRequires
-
-Bump BuildRequires on libsss_nss_idmap-devel to the version which
-introduces the sss_nss_getlistbycert function.
-
-This fixes RPM build failure when an older version of
-libsss_nss_idmap-devel was installed.
-
-https://pagure.io/freeipa/issue/6828
-
-Reviewed-By: Tomas Krizek <tkrizek@redhat.com>
-Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
----
- freeipa.spec.in | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
-diff --git a/freeipa.spec.in b/freeipa.spec.in
-index e7e39e87bef39653d660a345793750f59c8dd715..829c3f0b2898de1ecbf0cfb769fde5cd978c241c 100644
---- a/freeipa.spec.in
-+++ b/freeipa.spec.in
-@@ -121,8 +121,8 @@ BuildRequires:  libtevent-devel
- BuildRequires:  libuuid-devel
- BuildRequires:  libsss_idmap-devel
- BuildRequires:  libsss_certmap-devel
--# 1.14.0: sss_nss_getnamebycert (https://fedorahosted.org/sssd/ticket/2897)
--BuildRequires:  libsss_nss_idmap-devel >= 1.14.0
-+# 1.15.3: sss_nss_getlistbycert (https://pagure.io/SSSD/sssd/issue/3050)
-+BuildRequires:  libsss_nss_idmap-devel >= 1.15.3
- BuildRequires:  rhino
- BuildRequires:  libverto-devel
- BuildRequires:  libunistring-devel
--- 
-2.12.2
-
diff --git a/SOURCES/0048-server-make-sure-we-test-for-sss_nss_getlistbycert.patch b/SOURCES/0048-server-make-sure-we-test-for-sss_nss_getlistbycert.patch
deleted file mode 100644
index 1da5471..0000000
--- a/SOURCES/0048-server-make-sure-we-test-for-sss_nss_getlistbycert.patch
+++ /dev/null
@@ -1,32 +0,0 @@
-From 6c76be7f9d5c25d940b026310e2efec3d46b5d23 Mon Sep 17 00:00:00 2001
-From: Alexander Bokovoy <abokovoy@redhat.com>
-Date: Wed, 29 Mar 2017 10:43:11 +0300
-Subject: [PATCH] server: make sure we test for sss_nss_getlistbycert
-
-Fixes https://pagure.io/freeipa/issue/6828
-
-Reviewed-By: Christian Heimes <cheimes@redhat.com>
-Reviewed-By: Tomas Krizek <tkrizek@redhat.com>
----
- server.m4 | 5 +++++
- 1 file changed, 5 insertions(+)
-
-diff --git a/server.m4 b/server.m4
-index 5d5333e194cb339d31576f54a70d96becadf9a87..346d73e906c5d0499e46fcc4da070007b2ff5973 100644
---- a/server.m4
-+++ b/server.m4
-@@ -29,6 +29,11 @@ DIRSRV_CFLAGS="$DIRSRV_CFLAGS $NSPR_CFLAGS"
- dnl -- sss_idmap is needed by the extdom exop --
- PKG_CHECK_MODULES([SSSIDMAP], [sss_idmap])
- PKG_CHECK_MODULES([SSSNSSIDMAP], [sss_nss_idmap >= 1.15.2])
-+AC_CHECK_LIB([sss_nss_idmap],
-+             [sss_nss_getlistbycert],
-+             [],
-+             [AC_MSG_ERROR([Required sss_nss_getlistbycert symbol in sss_nss_idmap not found])],
-+             [])
- 
- dnl -- sss_certmap and certauth.h are needed by the IPA KDB certauth plugin --
- PKG_CHECK_EXISTS([sss_certmap],
--- 
-2.12.2
-
diff --git a/SOURCES/0049-Upgrade-configure-PKINIT-after-adding-anonymous-prin.patch b/SOURCES/0049-Upgrade-configure-PKINIT-after-adding-anonymous-prin.patch
deleted file mode 100644
index 9ce9eec..0000000
--- a/SOURCES/0049-Upgrade-configure-PKINIT-after-adding-anonymous-prin.patch
+++ /dev/null
@@ -1,34 +0,0 @@
-From a4140595a3fcb42d9666aea823d3d8cd9ae0c7c3 Mon Sep 17 00:00:00 2001
-From: Martin Babinsky <mbabinsk@redhat.com>
-Date: Tue, 21 Mar 2017 17:03:35 +0100
-Subject: [PATCH] Upgrade: configure PKINIT after adding anonymous principal
-
-In order to set up PKINIT, the anonymous principal must already be
-created, otherwise the upgrade with fail when trying out anonymous
-PKINIT. Switch the order of steps so that this issue does not occur.
-
-https://pagure.io/freeipa/issue/6792
-
-Reviewed-By: Stanislav Laznicka <slaznick@redhat.com>
----
- ipaserver/install/server/upgrade.py | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/ipaserver/install/server/upgrade.py b/ipaserver/install/server/upgrade.py
-index 1706079da86d9ba9066f71f02b170c161c1f2963..be07d78585d4772eb6dd0aaa8fb4ccb588c42c65 100644
---- a/ipaserver/install/server/upgrade.py
-+++ b/ipaserver/install/server/upgrade.py
-@@ -1809,9 +1809,9 @@ def upgrade_configuration():
-                         KDC_CERT=paths.KDC_CERT,
-                         KDC_KEY=paths.KDC_KEY,
-                         CACERT_PEM=paths.CACERT_PEM)
--    setup_pkinit(krb)
-     enable_anonymous_principal(krb)
-     http.request_anon_keytab()
-+    setup_pkinit(krb)
- 
-     if not ds_running:
-         ds.stop(ds_serverid)
--- 
-2.12.2
-
diff --git a/SOURCES/0050-Remove-unused-variable-from-failed-anonymous-PKINIT-.patch b/SOURCES/0050-Remove-unused-variable-from-failed-anonymous-PKINIT-.patch
deleted file mode 100644
index bdc94ba..0000000
--- a/SOURCES/0050-Remove-unused-variable-from-failed-anonymous-PKINIT-.patch
+++ /dev/null
@@ -1,28 +0,0 @@
-From 7b4ef6d23fb335d99b38347f1c4516a21222231e Mon Sep 17 00:00:00 2001
-From: Martin Babinsky <mbabinsk@redhat.com>
-Date: Wed, 22 Mar 2017 10:01:34 +0100
-Subject: [PATCH] Remove unused variable from failed anonymous PKINIT handling
-
-https://pagure.io/freeipa/issue/6792
-
-Reviewed-By: Stanislav Laznicka <slaznick@redhat.com>
----
- ipaserver/install/krbinstance.py | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/ipaserver/install/krbinstance.py b/ipaserver/install/krbinstance.py
-index d936cc5f4f47e0e641a2d9ba4f943aab0301045c..c817076249a224347421b1bf18088eecb8eb345f 100644
---- a/ipaserver/install/krbinstance.py
-+++ b/ipaserver/install/krbinstance.py
-@@ -413,7 +413,7 @@ class KrbInstance(service.Service):
-         with ipautil.private_ccache() as anon_ccache:
-             try:
-                 ipautil.run([paths.KINIT, '-n', '-c', anon_ccache])
--            except ipautil.CalledProcessError as e:
-+            except ipautil.CalledProcessError:
-                 raise RuntimeError("Failed to configure anonymous PKINIT")
- 
-     def enable_ssl(self):
--- 
-2.12.2
-
diff --git a/SOURCES/0051-Split-out-anonymous-PKINIT-test-to-a-separate-method.patch b/SOURCES/0051-Split-out-anonymous-PKINIT-test-to-a-separate-method.patch
deleted file mode 100644
index f509598..0000000
--- a/SOURCES/0051-Split-out-anonymous-PKINIT-test-to-a-separate-method.patch
+++ /dev/null
@@ -1,37 +0,0 @@
-From b12c465ae8b8ffb1e34741daf8c0dea6525e5fcf Mon Sep 17 00:00:00 2001
-From: Martin Babinsky <mbabinsk@redhat.com>
-Date: Wed, 22 Mar 2017 10:04:52 +0100
-Subject: [PATCH] Split out anonymous PKINIT test to a separate method
-
-This allows for more flexibility in the whole PKINIT setup process.
-
-https://pagure.io/freeipa/issue/6792
-
-Reviewed-By: Stanislav Laznicka <slaznick@redhat.com>
----
- ipaserver/install/krbinstance.py | 2 ++
- 1 file changed, 2 insertions(+)
-
-diff --git a/ipaserver/install/krbinstance.py b/ipaserver/install/krbinstance.py
-index c817076249a224347421b1bf18088eecb8eb345f..5f4b5282f54234c15b1a8d8273eff69e134e665b 100644
---- a/ipaserver/install/krbinstance.py
-+++ b/ipaserver/install/krbinstance.py
-@@ -410,6 +410,7 @@ class KrbInstance(service.Service):
-             root_logger.critical("krb5kdc service failed to restart")
-             raise
- 
-+    def test_anonymous_pkinit(self):
-         with ipautil.private_ccache() as anon_ccache:
-             try:
-                 ipautil.run([paths.KINIT, '-n', '-c', anon_ccache])
-@@ -421,6 +422,7 @@ class KrbInstance(service.Service):
-             self.steps = []
-             self.step("installing X509 Certificate for PKINIT",
-                       self.setup_pkinit)
-+            self.step("testing anonymous PKINIT", self.test_anonymous_pkinit)
- 
-             self.start_creation()
- 
--- 
-2.12.2
-
diff --git a/SOURCES/0052-Ensure-KDC-is-propery-configured-after-upgrade.patch b/SOURCES/0052-Ensure-KDC-is-propery-configured-after-upgrade.patch
deleted file mode 100644
index 4be94d5..0000000
--- a/SOURCES/0052-Ensure-KDC-is-propery-configured-after-upgrade.patch
+++ /dev/null
@@ -1,47 +0,0 @@
-From 73ed5d59d0777329450cb8d6dce78f8ee862068b Mon Sep 17 00:00:00 2001
-From: Martin Babinsky <mbabinsk@redhat.com>
-Date: Wed, 22 Mar 2017 11:56:18 +0100
-Subject: [PATCH] Ensure KDC is propery configured after upgrade
-
-https://pagure.io/freeipa/issue/6792
-
-Reviewed-By: Stanislav Laznicka <slaznick@redhat.com>
----
- ipaserver/install/server/upgrade.py | 10 +++++-----
- 1 file changed, 5 insertions(+), 5 deletions(-)
-
-diff --git a/ipaserver/install/server/upgrade.py b/ipaserver/install/server/upgrade.py
-index be07d78585d4772eb6dd0aaa8fb4ccb588c42c65..0db764cb80f6d0fb22f00719dadf1f921f97bf62 100644
---- a/ipaserver/install/server/upgrade.py
-+++ b/ipaserver/install/server/upgrade.py
-@@ -1499,15 +1499,14 @@ def enable_anonymous_principal(krb):
- def setup_pkinit(krb):
-     root_logger.info("[Setup PKINIT]")
- 
--    if os.path.exists(paths.KDC_CERT):
--        root_logger.info("PKINIT already set up")
--        return
--
-     if not api.Command.ca_is_enabled()['result']:
-         root_logger.info("CA is not enabled")
-         return
- 
--    krb.setup_pkinit()
-+    if not os.path.exists(paths.KDC_CERT):
-+        root_logger.info("Requesting PKINIT certificate")
-+        krb.setup_pkinit()
-+
-     replacevars = dict()
-     replacevars['pkinit_identity'] = 'FILE:{},{}'.format(
-         paths.KDC_CERT,paths.KDC_KEY)
-@@ -1519,6 +1518,7 @@ def setup_pkinit(krb):
-     if krb.is_running():
-         krb.stop()
-     krb.start()
-+    krb.test_anonymous_pkinit()
- 
- 
- def disable_httpd_system_trust(http):
--- 
-2.12.2
-
diff --git a/SOURCES/0053-adtrust-make-sure-that-runtime-hostname-result-is-co.patch b/SOURCES/0053-adtrust-make-sure-that-runtime-hostname-result-is-co.patch
deleted file mode 100644
index d1feda9..0000000
--- a/SOURCES/0053-adtrust-make-sure-that-runtime-hostname-result-is-co.patch
+++ /dev/null
@@ -1,77 +0,0 @@
-From dd4ae3da2d341a25b63936b689e53fdbc8e93f65 Mon Sep 17 00:00:00 2001
-From: Alexander Bokovoy <abokovoy@redhat.com>
-Date: Mon, 20 Mar 2017 13:23:44 +0200
-Subject: [PATCH] adtrust: make sure that runtime hostname result is consistent
- with the configuration
-
-FreeIPA's `ipasam` module to Samba uses gethostname() call to identify
-own server's host name. This value is then used in multiple places,
-including construction of cifs/host.name principal. `ipasam` module
-always uses GSSAPI authentication when talking to LDAP, so Kerberos
-keys must be available in the /etc/samba/samba.keytab. However, if
-the principal was created using non-FQDN name but system reports
-FQDN name, `ipasam` will fail to acquire Kerberos credentials.
-Same with FQDN principal and non-FQDN hostname.
-
-Also host name and principal name must have the same case.
-
-Report an error when configuring ADTrust instance with inconsistent
-runtime hostname and configuration. This prevents errors like this:
-
-    [20/21]: starting CIFS services
-    ipa         : CRITICAL CIFS services failed to start
-
-    where samba logs have this:
-
-    [2017/03/20 06:34:27.385307,  0] ipa_sam.c:4193(bind_callback_cleanup)
-      kerberos error: code=-1765328203, message=Keytab contains no suitable keys for cifs/ipatrust@EXAMPLE.COM
-    [2017/03/20 06:34:27.385476,  1] ../source3/lib/smbldap.c:1206(get_cached_ldap_connect)
-      Connection to LDAP server failed for the 16 try!
-
-Fixes https://pagure.io/freeipa/issue/6786
-
-Reviewed-By: Martin Basti <mbasti@redhat.com>
----
- ipaserver/install/adtrustinstance.py | 12 ++++++++++++
- 1 file changed, 12 insertions(+)
-
-diff --git a/ipaserver/install/adtrustinstance.py b/ipaserver/install/adtrustinstance.py
-index 0b189854f568ea5d8c0e68077255939887ff0cc3..b4db055045823ce8ae7e3b264e1442a085f81b2d 100644
---- a/ipaserver/install/adtrustinstance.py
-+++ b/ipaserver/install/adtrustinstance.py
-@@ -27,6 +27,7 @@ import uuid
- import string
- import struct
- import re
-+import socket
- 
- import six
- 
-@@ -689,6 +690,15 @@ class ADTRUSTInstance(service.Service):
-         except Exception as e:
-             root_logger.critical("Enabling nsswitch support in slapi-nis failed with error '%s'" % e)
- 
-+    def __validate_server_hostname(self):
-+        hostname = socket.gethostname()
-+        if hostname != self.fqdn:
-+            raise ValueError("Host reports different name than configured: "
-+                             "'%s' versus '%s'. Samba requires to have "
-+                             "the same hostname or Kerberos principal "
-+                             "'cifs/%s' will not be found in Samba keytab." %
-+                             (hostname, self.fqdn, self.fqdn))
-+
-     def __start(self):
-         try:
-             self.start()
-@@ -804,6 +814,8 @@ class ADTRUSTInstance(service.Service):
-         api.Backend.ldap2.add_entry(entry)
- 
-     def create_instance(self):
-+        self.step("validate server hostname",
-+                  self.__validate_server_hostname)
-         self.step("stopping smbd", self.__stop)
-         self.step("creating samba domain object", \
-                   self.__create_samba_domain_object)
--- 
-2.12.2
-
diff --git a/SOURCES/0054-Allow-erasing-ipaDomainResolutionOrder-attribute.patch b/SOURCES/0054-Allow-erasing-ipaDomainResolutionOrder-attribute.patch
deleted file mode 100644
index 2fe04fe..0000000
--- a/SOURCES/0054-Allow-erasing-ipaDomainResolutionOrder-attribute.patch
+++ /dev/null
@@ -1,42 +0,0 @@
-From 5b9fe9df34d0eff697adefa171d35a57e561c17e Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Fabiano=20Fid=C3=AAncio?= <fidencio@redhat.com>
-Date: Tue, 28 Mar 2017 16:15:21 +0200
-Subject: [PATCH] Allow erasing ipaDomainResolutionOrder attribute
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Currently when trying to erase the ipaDomainResolutionOrder attribute we
-hit an internal error as the split() method is called on a None object.
-
-By returning early in case of empty string we now allow removing the
-ipaDomainResolutionOrder attribute by both calling delattr or setting
-its value to an empty string.
-
-https://pagure.io/freeipa/issue/6825
-
-Signed-off-by: Fabiano Fidêncio <fidencio@redhat.com>
-Reviewed-By: Martin Basti <mbasti@redhat.com>
----
- ipaserver/plugins/config.py | 5 +++++
- 1 file changed, 5 insertions(+)
-
-diff --git a/ipaserver/plugins/config.py b/ipaserver/plugins/config.py
-index 232c88121fd2c938f77a1e76e1d7c9f0ad8e7550..b50e7a4691bd76bfaf7c332cd89b0f1bf55bac46 100644
---- a/ipaserver/plugins/config.py
-+++ b/ipaserver/plugins/config.py
-@@ -359,6 +359,11 @@ class config(LDAPObject):
- 
-         domain_resolution_order = entry_attrs[attr_name]
- 
-+        # setting up an empty string means that the previous configuration has
-+        # to be cleaned up/removed. So, do nothing and let it pass
-+        if not domain_resolution_order:
-+            return
-+
-         # empty resolution order is signalized by single separator, do nothing
-         # and let it pass
-         if domain_resolution_order == DOMAIN_RESOLUTION_ORDER_SEPARATOR:
--- 
-2.12.2
-
diff --git a/SOURCES/0055-Always-check-and-create-anonymous-principal-during-K.patch b/SOURCES/0055-Always-check-and-create-anonymous-principal-during-K.patch
deleted file mode 100644
index 4a67768..0000000
--- a/SOURCES/0055-Always-check-and-create-anonymous-principal-during-K.patch
+++ /dev/null
@@ -1,70 +0,0 @@
-From 6602dffc7ab8e9bdc7fefd02f9ed11e5575f5f7b Mon Sep 17 00:00:00 2001
-From: Martin Babinsky <mbabinsk@redhat.com>
-Date: Wed, 22 Mar 2017 16:41:59 +0100
-Subject: [PATCH] Always check and create anonymous principal during KDC
- install
-
-The anonymous principal will now be checked for presence and created on
-both server and replica install. This fixes errors caused during replica
-installation against older master that do not have anonymous principal
-present.
-
-https://pagure.io/freeipa/issue/6799
-
-Reviewed-By: Stanislav Laznicka <slaznick@redhat.com>
----
- ipaserver/install/krbinstance.py | 17 +++++++++++++----
- 1 file changed, 13 insertions(+), 4 deletions(-)
-
-diff --git a/ipaserver/install/krbinstance.py b/ipaserver/install/krbinstance.py
-index 5f4b5282f54234c15b1a8d8273eff69e134e665b..6c105f74c8da2bfd34ace607b13170bc96a8ff1d 100644
---- a/ipaserver/install/krbinstance.py
-+++ b/ipaserver/install/krbinstance.py
-@@ -33,7 +33,7 @@ from ipaserver.install import installutils
- from ipapython import ipaldap
- from ipapython import ipautil
- from ipapython import kernel_keyring
--from ipalib import api
-+from ipalib import api, errors
- from ipalib.constants import ANON_USER
- from ipalib.install import certmonger
- from ipapython.ipa_log_manager import root_logger
-@@ -142,6 +142,7 @@ class KrbInstance(service.Service):
-             pass
- 
-     def __common_post_setup(self):
-+        self.step("creating anonymous principal", self.add_anonymous_principal)
-         self.step("starting the KDC", self.__start_instance)
-         self.step("configuring KDC to start on boot", self.__enable)
- 
-@@ -160,7 +161,6 @@ class KrbInstance(service.Service):
-         self.step("creating a keytab for the directory", self.__create_ds_keytab)
-         self.step("creating a keytab for the machine", self.__create_host_keytab)
-         self.step("adding the password extension to the directory", self.__add_pwd_extop_module)
--        self.step("creating anonymous principal", self.add_anonymous_principal)
- 
-         self.__common_post_setup()
- 
-@@ -432,8 +432,17 @@ class KrbInstance(service.Service):
-     def add_anonymous_principal(self):
-         # Create the special anonymous principal
-         princ_realm = self.get_anonymous_principal_name()
--        installutils.kadmin_addprinc(princ_realm)
--        self._ldap_mod("anon-princ-aci.ldif", self.sub_dict)
-+        dn = DN(('krbprincipalname', princ_realm), self.get_realm_suffix())
-+        try:
-+            self.api.Backend.ldap2.get_entry(dn)
-+        except errors.NotFound:
-+            installutils.kadmin_addprinc(princ_realm)
-+            self._ldap_mod("anon-princ-aci.ldif", self.sub_dict)
-+
-+        try:
-+            self.api.Backend.ldap2.set_entry_active(dn, True)
-+        except errors.AlreadyActive:
-+            pass
- 
-     def __convert_to_gssapi_replication(self):
-         repl = replication.ReplicationManager(self.realm,
--- 
-2.12.2
-
diff --git a/SOURCES/0056-Remove-duplicate-functionality-in-upgrade.patch b/SOURCES/0056-Remove-duplicate-functionality-in-upgrade.patch
deleted file mode 100644
index 2b9d354..0000000
--- a/SOURCES/0056-Remove-duplicate-functionality-in-upgrade.patch
+++ /dev/null
@@ -1,53 +0,0 @@
-From dd300d7db884db2d0aa228c08d2447539ce14c1c Mon Sep 17 00:00:00 2001
-From: Martin Babinsky <mbabinsk@redhat.com>
-Date: Wed, 22 Mar 2017 16:52:14 +0100
-Subject: [PATCH] Remove duplicate functionality in upgrade
-
-Since krbinstance code can now handle all operations of the
-`enabled_anonymous_principal` function from upgrade we can remove
-extraneous function altogether.
-
-https://pagure.io/freeipa/issue/6799
-
-Reviewed-By: Stanislav Laznicka <slaznick@redhat.com>
----
- ipaserver/install/server/upgrade.py | 16 +---------------
- 1 file changed, 1 insertion(+), 15 deletions(-)
-
-diff --git a/ipaserver/install/server/upgrade.py b/ipaserver/install/server/upgrade.py
-index 0db764cb80f6d0fb22f00719dadf1f921f97bf62..25b86297af3ae9d5f21cebb93f493b90670dcfc3 100644
---- a/ipaserver/install/server/upgrade.py
-+++ b/ipaserver/install/server/upgrade.py
-@@ -1482,20 +1482,6 @@ def add_default_caacl(ca):
-     sysupgrade.set_upgrade_state('caacl', 'add_default_caacl', True)
- 
- 
--def enable_anonymous_principal(krb):
--    princ_realm = krb.get_anonymous_principal_name()
--    dn = DN(('krbprincipalname', princ_realm), krb.get_realm_suffix())
--    try:
--        _ = api.Backend.ldap2.get_entry(dn)  # pylint: disable=unused-variable
--    except ipalib.errors.NotFound:
--        krb.add_anonymous_principal()
--
--    try:
--        api.Backend.ldap2.set_entry_active(dn, True)
--    except ipalib.errors.AlreadyActive:
--        pass
--
--
- def setup_pkinit(krb):
-     root_logger.info("[Setup PKINIT]")
- 
-@@ -1809,7 +1795,7 @@ def upgrade_configuration():
-                         KDC_CERT=paths.KDC_CERT,
-                         KDC_KEY=paths.KDC_KEY,
-                         CACERT_PEM=paths.CACERT_PEM)
--    enable_anonymous_principal(krb)
-+    krb.add_anonymous_principal()
-     http.request_anon_keytab()
-     setup_pkinit(krb)
- 
--- 
-2.12.2
-
diff --git a/SOURCES/0057-Fix-the-order-of-cert-files-check.patch b/SOURCES/0057-Fix-the-order-of-cert-files-check.patch
deleted file mode 100644
index d1c9c42..0000000
--- a/SOURCES/0057-Fix-the-order-of-cert-files-check.patch
+++ /dev/null
@@ -1,47 +0,0 @@
-From 9bc2481d6669906e105e1035a10cd81374464e5b Mon Sep 17 00:00:00 2001
-From: Stanislav Laznicka <slaznick@redhat.com>
-Date: Wed, 22 Mar 2017 17:10:56 +0100
-Subject: [PATCH] Fix the order of cert-files check
-
-Without this patch, if either of dirsrv_cert_files, http_cert_files
-or pkinit_cert_files is set along with no-pkinit, the user is first
-requested to add the remaining options and when they do that,
-they are told that they are using 'no-pkinit' along with
-'pkinit-cert-file'.
-
-https://pagure.io/freeipa/issue/6801
-
-Reviewed-By: Martin Basti <mbasti@redhat.com>
----
- ipaserver/install/server/__init__.py | 10 +++++-----
- 1 file changed, 5 insertions(+), 5 deletions(-)
-
-diff --git a/ipaserver/install/server/__init__.py b/ipaserver/install/server/__init__.py
-index 14f1ec48a1b8c7a520db69ffad378d488efa29cc..117f51c4ebfaeba51d3c85625cda0d0eee305696 100644
---- a/ipaserver/install/server/__init__.py
-+++ b/ipaserver/install/server/__init__.py
-@@ -340,16 +340,16 @@ class ServerInstallInterface(ServerCertificateInstallInterface,
-         cert_file_opt = (self.pkinit_cert_files,)
-         if not self.no_pkinit:
-             cert_file_req += cert_file_opt
--        if any(cert_file_req + cert_file_opt) and not all(cert_file_req):
--            raise RuntimeError(
--                "--dirsrv-cert-file, --http-cert-file, and --pkinit-cert-file "
--                "or --no-pkinit are required if any key file options are used."
--            )
-         if self.no_pkinit and self.pkinit_cert_files:
-             raise RuntimeError(
-                 "--no-pkinit and --pkinit-cert-file cannot be specified "
-                 "together"
-             )
-+        if any(cert_file_req + cert_file_opt) and not all(cert_file_req):
-+            raise RuntimeError(
-+                "--dirsrv-cert-file, --http-cert-file, and --pkinit-cert-file "
-+                "or --no-pkinit are required if any key file options are used."
-+            )
- 
-         if not self.interactive:
-             if self.dirsrv_cert_files and self.dirsrv_pin is None:
--- 
-2.12.2
-
diff --git a/SOURCES/0058-Don-t-allow-setting-pkinit-related-options-on-DL0.patch b/SOURCES/0058-Don-t-allow-setting-pkinit-related-options-on-DL0.patch
deleted file mode 100644
index 1675a78..0000000
--- a/SOURCES/0058-Don-t-allow-setting-pkinit-related-options-on-DL0.patch
+++ /dev/null
@@ -1,95 +0,0 @@
-From 60b57639295ab94949986ec59de3c8e6c92bee7d Mon Sep 17 00:00:00 2001
-From: Stanislav Laznicka <slaznick@redhat.com>
-Date: Wed, 22 Mar 2017 17:26:51 +0100
-Subject: [PATCH] Don't allow setting pkinit-related options on DL0
-
-pkinit is not supported on DL0, remove options that allow to set it
-from ipa-{server,replica}-install.
-
-https://pagure.io/freeipa/issue/6801
-
-Reviewed-By: Martin Basti <mbasti@redhat.com>
----
- install/tools/man/ipa-replica-install.1 |  2 +-
- install/tools/man/ipa-server-install.1  |  2 +-
- ipaserver/install/server/__init__.py    | 21 +++++++++++++++++++++
- 3 files changed, 23 insertions(+), 2 deletions(-)
-
-diff --git a/install/tools/man/ipa-replica-install.1 b/install/tools/man/ipa-replica-install.1
-index d63912c7018bd09a8567688a1f8d4db0c698ac3f..7d241324818dd3a5294da5e84b67a19d0d9a31b6 100644
---- a/install/tools/man/ipa-replica-install.1
-+++ b/install/tools/man/ipa-replica-install.1
-@@ -114,7 +114,7 @@ Install and configure a CA on this replica. If a CA is not configured then
- certificate operations will be forwarded to a master with a CA installed.
- .TP
- \fB\-\-no\-pkinit\fR
--Disables pkinit setup steps
-+Disables pkinit setup steps. This is the default and only allowed behavior on domain level 0.
- .TP
- \fB\-\-dirsrv\-cert\-file\fR=FILE
- File containing the Directory Server SSL certificate and private key
-diff --git a/install/tools/man/ipa-server-install.1 b/install/tools/man/ipa-server-install.1
-index c48bdae7485a34d72381188191d6423ca2d16044..d5d28df8e72295296a9ac321623ead49fe4692a3 100644
---- a/install/tools/man/ipa-server-install.1
-+++ b/install/tools/man/ipa-server-install.1
-@@ -93,7 +93,7 @@ Type of the external CA. Possible values are "generic", "ms-cs". Default value i
- File containing the IPA CA certificate and the external CA certificate chain. The file is accepted in PEM and DER certificate and PKCS#7 certificate chain formats. This option may be used multiple times.
- .TP
- \fB\-\-no\-pkinit\fR
--Disables pkinit setup steps
-+Disables pkinit setup steps. This is the default and only allowed behavior on domain level 0.
- .TP
- \fB\-\-dirsrv\-cert\-file\fR=\fIFILE\fR
- File containing the Directory Server SSL certificate and private key. The files are accepted in PEM and DER certificate, PKCS#7 certificate chain, PKCS#8 and raw private key and PKCS#12 formats. This option may be used multiple times.
-diff --git a/ipaserver/install/server/__init__.py b/ipaserver/install/server/__init__.py
-index 117f51c4ebfaeba51d3c85625cda0d0eee305696..096cb0142fc7fe70fdc3d2ad1e5caedf0f65b643 100644
---- a/ipaserver/install/server/__init__.py
-+++ b/ipaserver/install/server/__init__.py
-@@ -332,9 +332,24 @@ class ServerInstallInterface(ServerCertificateInstallInterface,
-         if not os.path.exists(value):
-             raise ValueError("File %s does not exist." % value)
- 
-+    def _is_promote(self):
-+        """
-+        :returns: True if domain level options correspond to domain level > 0
-+        """
-+        raise NotImplementedError()
-+
-     def __init__(self, **kwargs):
-         super(ServerInstallInterface, self).__init__(**kwargs)
- 
-+        # pkinit is not supported on DL0, don't allow related options
-+        if not self._is_promote():
-+            if (self.no_pkinit or self.pkinit_cert_files is not None or
-+                    self.pkinit_pin is not None):
-+                raise RuntimeError(
-+                    "pkinit on domain level 0 is not supported. Please "
-+                    "don't use any pkinit-related options.")
-+            self.no_pkinit = True
-+
-         # If any of the key file options are selected, all are required.
-         cert_file_req = (self.dirsrv_cert_files, self.http_cert_files)
-         cert_file_opt = (self.pkinit_cert_files,)
-@@ -557,6 +572,9 @@ class ServerMasterInstall(ServerMasterInstallInterface):
-     add_sids = True
-     add_agents = False
- 
-+    def _is_promote(self):
-+        return self.domain_level > constants.DOMAIN_LEVEL_0
-+
-     def __init__(self, **kwargs):
-         super(ServerMasterInstall, self).__init__(**kwargs)
-         master_init(self)
-@@ -590,6 +608,9 @@ class ServerReplicaInstall(ServerReplicaInstallInterface):
-         description="Kerberos password for the specified admin principal",
-     )
- 
-+    def _is_promote(self):
-+        return self.replica_file is None
-+
-     def __init__(self, **kwargs):
-         super(ServerReplicaInstall, self).__init__(**kwargs)
-         replica_init(self)
--- 
-2.12.2
-
diff --git a/SOURCES/0059-replica-prepare-man-remove-pkinit-option-refs.patch b/SOURCES/0059-replica-prepare-man-remove-pkinit-option-refs.patch
deleted file mode 100644
index ac24ad6..0000000
--- a/SOURCES/0059-replica-prepare-man-remove-pkinit-option-refs.patch
+++ /dev/null
@@ -1,60 +0,0 @@
-From a0b479ef9f9be97cc170734c0af5330d9fd702ce Mon Sep 17 00:00:00 2001
-From: Stanislav Laznicka <slaznick@redhat.com>
-Date: Fri, 24 Mar 2017 12:29:53 +0100
-Subject: [PATCH] replica-prepare man: remove pkinit option refs
-
-Remove the references to the pkinit options which was forgotten
-about in 46d4d534c0
-
-https://pagure.io/freeipa/issue/6801
-
-Reviewed-By: Martin Basti <mbasti@redhat.com>
----
- install/tools/man/ipa-replica-prepare.1 | 12 ------------
- 1 file changed, 12 deletions(-)
-
-diff --git a/install/tools/man/ipa-replica-prepare.1 b/install/tools/man/ipa-replica-prepare.1
-index 2063657f8eb4e97fc11b1abb95a892e26b4344e6..afc5408ef87ec5cf967d00dd21aa848584c7eb1e 100644
---- a/install/tools/man/ipa-replica-prepare.1
-+++ b/install/tools/man/ipa-replica-prepare.1
-@@ -43,27 +43,18 @@ File containing the Directory Server SSL certificate and private key. The files
- \fB\-\-http\-cert\-file\fR=\fIFILE\fR
- File containing the Apache Server SSL certificate and private key. The files are accepted in PEM and DER certificate, PKCS#7 certificate chain, PKCS#8 and raw private key and PKCS#12 formats. This option may be used multiple times.
- .TP
--\fB\-\-pkinit\-cert\-file\fR=\fIFILE\fR
--File containing the Kerberos KDC SSL certificate and private key. The files are accepted in PEM and DER certificate, PKCS#7 certificate chain, PKCS#8 and raw private key and PKCS#12 formats. This option may be used multiple times.
--.TP
- \fB\-\-dirsrv\-pin\fR=\fIPIN\fR
- The password to unlock the Directory Server private key
- .TP
- \fB\-\-http\-pin\fR=\fIPIN\fR
- The password to unlock the Apache Server private key
- .TP
--\fB\-\-pkinit\-pin\fR=\fIPIN\fR
--The password to unlock the Kerberos KDC private key
--.TP
- \fB\-\-dirsrv\-cert\-name\fR=\fINAME\fR
- Name of the Directory Server SSL certificate to install
- .TP
- \fB\-\-http\-cert\-name\fR=\fINAME\fR
- Name of the Apache Server SSL certificate to install
- .TP
--\fB\-\-pkinit\-cert\-name\fR=\fINAME\fR
--Name of the Kerberos KDC SSL certificate to install
--.TP
- \fB\-p\fR \fIDM_PASSWORD\fR, \fB\-\-password\fR=\fIDM_PASSWORD\fR
- Directory Manager (existing master) password
- .TP
-@@ -81,9 +72,6 @@ Do not create reverse DNS zone
- \fB\-\-ca\fR=\fICA_FILE\fR
- Location of CA PKCS#12 file, default /root/cacert.p12
- .TP
--\fB\-\-no\-pkinit\fR
--Disables pkinit setup steps
--.TP
- \fB\-\-debug\fR
- Prints info log messages to the output
- .SH "EXIT STATUS"
--- 
-2.12.2
-
diff --git a/SOURCES/0060-Remove-redundant-option-check-for-cert-files.patch b/SOURCES/0060-Remove-redundant-option-check-for-cert-files.patch
deleted file mode 100644
index 09e8115..0000000
--- a/SOURCES/0060-Remove-redundant-option-check-for-cert-files.patch
+++ /dev/null
@@ -1,41 +0,0 @@
-From abb400e3fbb7c607b6ec40cfd155aa14175d35d7 Mon Sep 17 00:00:00 2001
-From: Stanislav Laznicka <slaznick@redhat.com>
-Date: Wed, 29 Mar 2017 09:00:09 +0200
-Subject: [PATCH] Remove redundant option check for cert files
-
-There was a redundant check for CA-less install certificate files
-for replicas but the same check is done for all installers before
-that.
-
-https://pagure.io/freeipa/issue/6801
-
-Reviewed-By: Martin Basti <mbasti@redhat.com>
----
- ipaserver/install/server/__init__.py | 10 +---------
- 1 file changed, 1 insertion(+), 9 deletions(-)
-
-diff --git a/ipaserver/install/server/__init__.py b/ipaserver/install/server/__init__.py
-index 096cb0142fc7fe70fdc3d2ad1e5caedf0f65b643..89444f21fefc902931b7ecfaba861a18ecc28dbe 100644
---- a/ipaserver/install/server/__init__.py
-+++ b/ipaserver/install/server/__init__.py
-@@ -470,16 +470,8 @@ class ServerInstallInterface(ServerCertificateInstallInterface,
-                     "idmax (%s) cannot be smaller than idstart (%s)" %
-                     (self.idmax, self.idstart))
-         else:
--            cert_file_req = (self.dirsrv_cert_files, self.http_cert_files)
--            cert_file_opt = (self.pkinit_cert_files,)
--
-+            # replica installers
-             if self.replica_file is None:
--                # If any of the PKCS#12 options are selected, all are required.
--                if any(cert_file_req + cert_file_opt) and not all(cert_file_req):
--                    raise RuntimeError(
--                        "--dirsrv-cert-file and --http-cert-file are required "
--                        "if any PKCS#12 options are used")
--
-                 if self.servers and not self.domain_name:
-                     raise RuntimeError(
-                         "The --server option cannot be used without providing "
--- 
-2.12.2
-
diff --git a/SOURCES/0061-Hide-request_type-doc-string-in-cert-request-help.patch b/SOURCES/0061-Hide-request_type-doc-string-in-cert-request-help.patch
deleted file mode 100644
index 75c7a38..0000000
--- a/SOURCES/0061-Hide-request_type-doc-string-in-cert-request-help.patch
+++ /dev/null
@@ -1,34 +0,0 @@
-From 9a6731643f1b0e3c47df13866109323ddd4c5db0 Mon Sep 17 00:00:00 2001
-From: Abhijeet Kasurde <akasurde@redhat.com>
-Date: Sat, 18 Feb 2017 16:31:07 +0530
-Subject: [PATCH] Hide request_type doc string in cert-request help
-
-Fix hides description of request_type argument in cert-request
-command help
-
-Fixes https://pagure.io/freeipa/issue/6494
-Fixes https://pagure.io/freeipa/issue/5734
-
-Signed-off-by: Abhijeet Kasurde <akasurde@redhat.com>
-Reviewed-By: Martin Basti <mbasti@redhat.com>
-Reviewed-By: Fraser Tweedale <ftweedal@redhat.com>
----
- ipaserver/plugins/cert.py | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/ipaserver/plugins/cert.py b/ipaserver/plugins/cert.py
-index 1a6d04533cebb2eb00022981dae9ffe5b785ba8b..dfc7444ddbf31ac3c194e050af28220fc2a87a92 100644
---- a/ipaserver/plugins/cert.py
-+++ b/ipaserver/plugins/cert.py
-@@ -491,7 +491,7 @@ class certreq(BaseCertObject):
-             'request_type',
-             default=u'pkcs10',
-             autofill=True,
--            flags={'no_update', 'no_update', 'no_search'},
-+            flags={'no_option', 'no_update', 'no_update', 'no_search'},
-         ),
-         Str(
-             'profile_id?', validate_profile_id,
--- 
-2.12.2
-
diff --git a/SOURCES/0062-Get-correct-CA-cert-nickname-in-CA-less.patch b/SOURCES/0062-Get-correct-CA-cert-nickname-in-CA-less.patch
deleted file mode 100644
index cfd0cb5..0000000
--- a/SOURCES/0062-Get-correct-CA-cert-nickname-in-CA-less.patch
+++ /dev/null
@@ -1,60 +0,0 @@
-From f57c0fbd46d0cca82b45c2f16fab316aa2554a08 Mon Sep 17 00:00:00 2001
-From: Stanislav Laznicka <slaznick@redhat.com>
-Date: Fri, 24 Mar 2017 09:52:18 +0100
-Subject: [PATCH] Get correct CA cert nickname in CA-less
-
-During CA-less installation, we initialize the HTTPD alias
-database from a pkcs12 file. This means there's going to
-be different nicknames to the added certificates. Store
-the CA certificate nickname in HTTPInstance__setup_ssl()
-to be able to correctly export it later.
-
-https://pagure.io/freeipa/issue/6806
-
-Reviewed-By: Jan Cholasta <jcholast@redhat.com>
----
- ipaserver/install/httpinstance.py | 7 ++++++-
- 1 file changed, 6 insertions(+), 1 deletion(-)
-
-diff --git a/ipaserver/install/httpinstance.py b/ipaserver/install/httpinstance.py
-index 01b55e7a7b00d020b7745c419267ad4f0ba86804..3e4252cb1e907618d4aa15f7381caff5e4e868e3 100644
---- a/ipaserver/install/httpinstance.py
-+++ b/ipaserver/install/httpinstance.py
-@@ -118,6 +118,7 @@ class WebGuiInstance(service.SimpleServiceInstance):
-     def __init__(self):
-         service.SimpleServiceInstance.__init__(self, "ipa_webgui")
- 
-+
- class HTTPInstance(service.Service):
-     def __init__(self, fstore=None, cert_nickname='Server-Cert',
-                  api=api):
-@@ -130,6 +131,7 @@ class HTTPInstance(service.Service):
-             service_user=HTTPD_USER,
-             keytab=paths.HTTP_KEYTAB)
- 
-+        self.cacert_nickname = None
-         self.cert_nickname = cert_nickname
-         self.ca_is_configured = True
-         self.keytab_user = constants.GSSPROXY_USER
-@@ -441,6 +443,9 @@ class HTTPInstance(service.Service):
-             if not server_certs:
-                 raise RuntimeError("Could not find a suitable server cert.")
- 
-+        # store the CA cert nickname so that we can publish it later on
-+        self.cacert_nickname = db.cacert_name
-+
-     def __import_ca_certs(self):
-         db = certs.CertDB(self.realm, nssdir=paths.HTTPD_ALIAS_DIR,
-                           subject_base=self.subject_base)
-@@ -449,7 +454,7 @@ class HTTPInstance(service.Service):
-     def __publish_ca_cert(self):
-         ca_db = certs.CertDB(self.realm, nssdir=paths.HTTPD_ALIAS_DIR,
-                              subject_base=self.subject_base)
--        ca_db.publish_ca_cert(paths.CA_CRT)
-+        ca_db.export_pem_cert(self.cacert_nickname, paths.CA_CRT)
- 
-     def is_kdcproxy_configured(self):
-         """Check if KDC proxy has already been configured in the past"""
--- 
-2.12.2
-
diff --git a/SOURCES/0063-Remove-publish_ca_cert-method-from-NSSDatabase.patch b/SOURCES/0063-Remove-publish_ca_cert-method-from-NSSDatabase.patch
deleted file mode 100644
index 2ac172a..0000000
--- a/SOURCES/0063-Remove-publish_ca_cert-method-from-NSSDatabase.patch
+++ /dev/null
@@ -1,49 +0,0 @@
-From caa2c2b6e4b6ac29774dc7f8ec7c3f5210e2f828 Mon Sep 17 00:00:00 2001
-From: Stanislav Laznicka <slaznick@redhat.com>
-Date: Mon, 27 Mar 2017 10:31:36 +0200
-Subject: [PATCH] Remove publish_ca_cert() method from NSSDatabase
-
-NSSDatabase.publish_ca_cert() is not used anymore, remove it.
-
-https://pagure.io/freeipa/issue/6806
-
-Reviewed-By: Jan Cholasta <jcholast@redhat.com>
----
- ipapython/certdb.py        | 9 ---------
- ipaserver/install/certs.py | 3 ---
- 2 files changed, 12 deletions(-)
-
-diff --git a/ipapython/certdb.py b/ipapython/certdb.py
-index f1410e5ae4290263573e9554ab4e66873d4344a1..0665f944457fb09820eb244c742cb1782e515ad1 100644
---- a/ipapython/certdb.py
-+++ b/ipapython/certdb.py
-@@ -596,12 +596,3 @@ class NSSDatabase(object):
-         finally:
-             del certdb, cert
-             nss.nss_shutdown()
--
--    def publish_ca_cert(self, canickname, location):
--        args = ["-L", "-n", canickname, "-a"]
--        result = self.run_certutil(args, capture_output=True)
--        cert = result.output
--        fd = open(location, "w+")
--        fd.write(cert)
--        fd.close()
--        os.chmod(location, 0o444)
-diff --git a/ipaserver/install/certs.py b/ipaserver/install/certs.py
-index 0ca971358030db6a6e7e410e58a984675bcf53ac..16139f81f0d0bd6889a9f38948204bb5bc018028 100644
---- a/ipaserver/install/certs.py
-+++ b/ipaserver/install/certs.py
-@@ -640,9 +640,6 @@ class CertDB(object):
- 
-         self.export_ca_cert(nickname, False)
- 
--    def publish_ca_cert(self, location):
--        self.nssdb.publish_ca_cert(self.cacert_name, location)
--
-     def export_pem_cert(self, nickname, location):
-         return self.nssdb.export_pem_cert(nickname, location)
- 
--- 
-2.12.2
-
diff --git a/SOURCES/0064-httpinstance-make-sure-NSS-database-is-backed-up.patch b/SOURCES/0064-httpinstance-make-sure-NSS-database-is-backed-up.patch
deleted file mode 100644
index 4e78d20..0000000
--- a/SOURCES/0064-httpinstance-make-sure-NSS-database-is-backed-up.patch
+++ /dev/null
@@ -1,39 +0,0 @@
-From 27360b29b510d5ae92469b079569973676efd26c Mon Sep 17 00:00:00 2001
-From: Jan Cholasta <jcholast@redhat.com>
-Date: Mon, 3 Apr 2017 10:49:26 +0000
-Subject: [PATCH] httpinstance: make sure NSS database is backed up
-
-The NSS database at /etc/httpd/alias is not properly initialized and backed
-up in CA-less replica promotion. This might cause the install to fail after
-previous install and uninstall.
-
-Make sure the NSS database is initialized and backed up even in CA-less
-replica promotion to fix the issue.
-
-https://pagure.io/freeipa/issue/4639
-
-Reviewed-By: Stanislav Laznicka <slaznick@redhat.com>
----
- ipaserver/install/httpinstance.py | 3 ++-
- 1 file changed, 2 insertions(+), 1 deletion(-)
-
-diff --git a/ipaserver/install/httpinstance.py b/ipaserver/install/httpinstance.py
-index 3e4252cb1e907618d4aa15f7381caff5e4e868e3..079ea92606cc53f98beca1759a7e24db64bfd3f4 100644
---- a/ipaserver/install/httpinstance.py
-+++ b/ipaserver/install/httpinstance.py
-@@ -375,10 +375,11 @@ class HTTPInstance(service.Service):
-         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=(not self.promote))
-+                          truncate=truncate)
-         self.disable_system_trust()
-         if self.pkcs12_info:
-             if self.ca_is_configured:
--- 
-2.12.2
-
diff --git a/SOURCES/0065-IPA-KDB-use-relative-path-in-ipa-certmap-config-snip.patch b/SOURCES/0065-IPA-KDB-use-relative-path-in-ipa-certmap-config-snip.patch
deleted file mode 100644
index 544e546..0000000
--- a/SOURCES/0065-IPA-KDB-use-relative-path-in-ipa-certmap-config-snip.patch
+++ /dev/null
@@ -1,72 +0,0 @@
-From cae66046bb31205283341cd3b19af799c5fe6a30 Mon Sep 17 00:00:00 2001
-From: Sumit Bose <sbose@redhat.com>
-Date: Wed, 29 Mar 2017 15:46:50 +0200
-Subject: [PATCH] IPA-KDB: use relative path in ipa-certmap config snippet
-
-Architecture specific paths should be avoided in the global Kerberos
-configuration because it is read e.g. by 32bit and 64bit libraries they
-are installed in parallel.
-
-Resolves https://pagure.io/freeipa/issue/6833
-
-Reviewed-By: Christian Heimes <cheimes@redhat.com>
-Reviewed-By: Jan Cholasta <jcholast@redhat.com>
----
- daemons/ipa-kdb/Makefile.am                       | 12 ++++--------
- daemons/ipa-kdb/{ipa-certauth.in => ipa-certauth} |  2 +-
- 2 files changed, 5 insertions(+), 9 deletions(-)
- rename daemons/ipa-kdb/{ipa-certauth.in => ipa-certauth} (56%)
-
-diff --git a/daemons/ipa-kdb/Makefile.am b/daemons/ipa-kdb/Makefile.am
-index 715666e779a4fa64c2c0f71767f09efb19b5f908..259bc3b20fa96cadff43c3acdce1bd3ba49cdb31 100644
---- a/daemons/ipa-kdb/Makefile.am
-+++ b/daemons/ipa-kdb/Makefile.am
-@@ -40,18 +40,16 @@ ipadb_la_SOURCES = 		\
- 	ipa_kdb_audit_as.c	\
- 	$(NULL)
- 
-+dist_noinst_DATA = ipa_kdb.exports
-+
- if BUILD_IPA_CERTAUTH_PLUGIN
- ipadb_la_SOURCES += ipa_kdb_certauth.c
- 
- 
--%: %.in
--	sed \
--		-e 's|@plugindir@|$(plugindir)|g' \
--		'$(srcdir)/$@.in' >$@
--
- krb5confdir = $(sysconfdir)/krb5.conf.d
- krb5conf_DATA = ipa-certauth
--CLEANFILES = $(krb5conf_DATA)
-+else
-+dist_noinst_DATA += ipa-certauth
- endif
- 
- ipadb_la_LDFLAGS = 		\
-@@ -105,8 +103,6 @@ ipa_kdb_tests_LDADD =          \
-        -lsss_idmap             \
-        $(NULL)
- 
--dist_noinst_DATA = ipa_kdb.exports ipa-certauth.in
--
- clean-local:
- 	rm -f tests/.dirstamp
- 
-diff --git a/daemons/ipa-kdb/ipa-certauth.in b/daemons/ipa-kdb/ipa-certauth
-similarity index 56%
-rename from daemons/ipa-kdb/ipa-certauth.in
-rename to daemons/ipa-kdb/ipa-certauth
-index eda89a26f02fbea449eb754b232b8115904acd21..6fde08284da22161a97df675d15392f80ffcc6fb 100644
---- a/daemons/ipa-kdb/ipa-certauth.in
-+++ b/daemons/ipa-kdb/ipa-certauth
-@@ -1,5 +1,5 @@
- [plugins]
-  certauth = {
--  module = ipakdb:@plugindir@/ipadb.so
-+  module = ipakdb:kdb/ipadb.so
-   enable_only = ipakdb
-  }
--- 
-2.12.2
-
diff --git a/SOURCES/0066-Add-pki_pin-only-when-needed.patch b/SOURCES/0066-Add-pki_pin-only-when-needed.patch
deleted file mode 100644
index 880c676..0000000
--- a/SOURCES/0066-Add-pki_pin-only-when-needed.patch
+++ /dev/null
@@ -1,62 +0,0 @@
-From 71061059a6c56bad818cb379070ef742bbe517a3 Mon Sep 17 00:00:00 2001
-From: Stanislav Laznicka <slaznick@redhat.com>
-Date: Mon, 3 Apr 2017 14:08:46 +0200
-Subject: [PATCH] Add pki_pin only when needed
-
-If both the pki-tomcat NSS database and its password.conf have been
-created, don't try to override the password.conf file.
-
-https://pagure.io/freeipa/issue/6839
-
-Reviewed-By: Tomas Krizek <tkrizek@redhat.com>
-Reviewed-By: Christian Heimes <cheimes@redhat.com>
----
- ipaserver/install/cainstance.py  | 10 +++++++---
- ipaserver/install/krainstance.py | 10 +++++++---
- 2 files changed, 14 insertions(+), 6 deletions(-)
-
-diff --git a/ipaserver/install/cainstance.py b/ipaserver/install/cainstance.py
-index 92bb760d39d23fedb40b7e3c5bea53381f1c87ad..3980e412603437b0db5804623f6626d11e52c009 100644
---- a/ipaserver/install/cainstance.py
-+++ b/ipaserver/install/cainstance.py
-@@ -541,9 +541,13 @@ class CAInstance(DogtagInstance):
-         # CA key algorithm
-         config.set("CA", "pki_ca_signing_key_algorithm", self.ca_signing_algorithm)
- 
--        # generate pin which we know can be used for FIPS NSS database
--        pki_pin = ipautil.ipa_generate_password()
--        config.set("CA", "pki_pin", pki_pin)
-+        if not (os.path.isdir(paths.PKI_TOMCAT_ALIAS_DIR) and
-+                os.path.isfile(paths.PKI_TOMCAT_PASSWORD_CONF)):
-+            # generate pin which we know can be used for FIPS NSS database
-+            pki_pin = ipautil.ipa_generate_password()
-+            config.set("CA", "pki_pin", pki_pin)
-+        else:
-+            pki_pin = None
- 
-         if self.clone:
- 
-diff --git a/ipaserver/install/krainstance.py b/ipaserver/install/krainstance.py
-index 34d667857a8055752e258a591af983190f33daa5..fc25ac72b0dc593f06a8b070b67b5d54a0ab8bce 100644
---- a/ipaserver/install/krainstance.py
-+++ b/ipaserver/install/krainstance.py
-@@ -235,9 +235,13 @@ class KRAInstance(DogtagInstance):
-             "KRA", "pki_share_dbuser_dn",
-             str(DN(('uid', 'pkidbuser'), ('ou', 'people'), ('o', 'ipaca'))))
- 
--        # generate pin which we know can be used for FIPS NSS database
--        pki_pin = ipautil.ipa_generate_password()
--        config.set("KRA", "pki_pin", pki_pin)
-+        if not (os.path.isdir(paths.PKI_TOMCAT_ALIAS_DIR) and
-+                os.path.isfile(paths.PKI_TOMCAT_PASSWORD_CONF)):
-+            # generate pin which we know can be used for FIPS NSS database
-+            pki_pin = ipautil.ipa_generate_password()
-+            config.set("KRA", "pki_pin", pki_pin)
-+        else:
-+            pki_pin = None
- 
-         _p12_tmpfile_handle, p12_tmpfile_name = tempfile.mkstemp(dir=paths.TMP)
- 
--- 
-2.9.3
-
diff --git a/SOURCES/0067-idrange-add-properly-handle-empty-dom-name-option.patch b/SOURCES/0067-idrange-add-properly-handle-empty-dom-name-option.patch
deleted file mode 100644
index 3ef7ec8..0000000
--- a/SOURCES/0067-idrange-add-properly-handle-empty-dom-name-option.patch
+++ /dev/null
@@ -1,35 +0,0 @@
-From 1f9d9de5dd0e5935bb71060d867b46f675977163 Mon Sep 17 00:00:00 2001
-From: Florence Blanc-Renaud <flo@redhat.com>
-Date: Tue, 28 Mar 2017 16:02:45 +0200
-Subject: [PATCH] idrange-add: properly handle empty --dom-name option
-
-When idrange-add is called with --dom-name=, the CLI exits with
-ipa: ERROR: an internal error has occurred
-This happens because the code checks if the option is provided but does not
-check if the value is None.
-
-We need to handle empty dom-name as if the option was not specified.
-
-https://pagure.io/freeipa/issue/6404
-
-Reviewed-By: Stanislav Laznicka <slaznick@redhat.com>
----
- ipaserver/plugins/idrange.py | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/ipaserver/plugins/idrange.py b/ipaserver/plugins/idrange.py
-index 5b88a6b0fd91271eaeb19c8315e23299a13ff7e4..c8ea95af801a86dd0180497964ddbd1b2741f279 100644
---- a/ipaserver/plugins/idrange.py
-+++ b/ipaserver/plugins/idrange.py
-@@ -411,7 +411,7 @@ class idrange_add(LDAPCreate):
- 
-         # This needs to stay in options since there is no
-         # ipanttrusteddomainname attribute in LDAP
--        if 'ipanttrusteddomainname' in options:
-+        if options.get('ipanttrusteddomainname'):
-             if is_set('ipanttrusteddomainsid'):
-                 raise errors.ValidationError(name='ID Range setup',
-                     error=_('Options dom-sid and dom-name '
--- 
-2.9.3
-
diff --git a/SOURCES/0068-ipa-sam-create-the-gidNumber-attribute-in-the-truste.patch b/SOURCES/0068-ipa-sam-create-the-gidNumber-attribute-in-the-truste.patch
deleted file mode 100644
index 462657b..0000000
--- a/SOURCES/0068-ipa-sam-create-the-gidNumber-attribute-in-the-truste.patch
+++ /dev/null
@@ -1,145 +0,0 @@
-From 376a1fbfe97624116d8fb10f26d97ef15fd3b917 Mon Sep 17 00:00:00 2001
-From: Florence Blanc-Renaud <flo@redhat.com>
-Date: Tue, 21 Mar 2017 17:33:20 +0100
-Subject: [PATCH] ipa-sam: create the gidNumber attribute in the trusted domain
- entry
-
-When a trusted domain entry is created, the uidNumber attribute is created
-but not the gidNumber attribute. This causes samba to log
-	Failed to find a Unix account for DOM-AD$
-because the samu structure does not contain a group_sid and is not put
-in the cache.
-The fix creates the gidNumber attribute in the trusted domain entry,
-and initialises the group_sid field in the samu structure returned
-by ldapsam_getsampwnam. This ensures that the entry is put in the cache.
-
-Note that this is only a partial fix for 6660 as it does not prevent
-_netr_ServerAuthenticate3 from failing with the log
-	_netr_ServerAuthenticate3: netlogon_creds_server_check failed. Rejecting auth request from client VM-AD machine account dom-ad.example.com.
-
-https://pagure.io/freeipa/issue/6827
-
-Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
----
- daemons/ipa-sam/ipa_sam.c | 40 +++++++++++++++++++++++++++++++++++++---
- 1 file changed, 37 insertions(+), 3 deletions(-)
-
-diff --git a/daemons/ipa-sam/ipa_sam.c b/daemons/ipa-sam/ipa_sam.c
-index 4c1fda5f82b43f69929613f9938410b32cff31e7..6a29e8e10b4299356b9ead76276eecc8083791a3 100644
---- a/daemons/ipa-sam/ipa_sam.c
-+++ b/daemons/ipa-sam/ipa_sam.c
-@@ -195,6 +195,7 @@ struct ipasam_privates {
- 	char *trust_dn;
- 	char *flat_name;
- 	struct dom_sid fallback_primary_group;
-+	char *fallback_primary_group_gid_str;
- 	char *server_princ;
- 	char *client_princ;
- 	struct sss_idmap_ctx *idmap_ctx;
-@@ -2419,6 +2420,9 @@ static NTSTATUS ipasam_set_trusted_domain(struct pdb_methods *methods,
- 	if (entry == NULL || sid == NULL) {
- 		smbldap_make_mod(priv2ld(ldap_state), entry, &mods,
- 				 LDAP_ATTRIBUTE_UIDNUMBER, IPA_MAGIC_ID_STR);
-+		smbldap_make_mod(priv2ld(ldap_state), entry, &mods,
-+		                 LDAP_ATTRIBUTE_GIDNUMBER,
-+				 ldap_state->ipasam_privates->fallback_primary_group_gid_str);
- 	}
- 
- 	if (td->netbios_name != NULL) {
-@@ -2829,6 +2833,7 @@ static bool init_sam_from_td(struct samu *user, struct pdb_trusted_domain *td,
- {
- 	NTSTATUS status;
- 	struct dom_sid *u_sid;
-+	struct dom_sid *g_sid;
- 	char *name;
- 	char *trustpw = NULL;
- 	char *trustpw_utf8 = NULL;
-@@ -2884,6 +2889,11 @@ static bool init_sam_from_td(struct samu *user, struct pdb_trusted_domain *td,
- 	}
- 	talloc_free(u_sid);
- 
-+	g_sid = &ldap_state->ipasam_privates->fallback_primary_group;
-+	if (!pdb_set_group_sid(user, g_sid, PDB_SET)) {
-+		return false;
-+	}
-+
- 	status = get_trust_pwd(user, &td->trust_auth_incoming, &trustpw, NULL);
- 	if (!NT_STATUS_IS_OK(status)) {
- 		return false;
-@@ -3594,14 +3604,17 @@ static void ipasam_free_private_data(void **vp)
- static struct dom_sid *get_fallback_group_sid(TALLOC_CTX *mem_ctx,
- 					      struct smbldap_state *ldap_state,
- 					      struct sss_idmap_ctx *idmap_ctx,
--					      LDAPMessage *dom_entry)
-+					      LDAPMessage *dom_entry,
-+					      char **fallback_group_gid_str)
- {
- 	char *dn;
- 	char *sid;
-+	char *gidnumber;
- 	int ret;
- 	const char *filter = "objectClass=*";
- 	const char *attr_list[] = {
- 					LDAP_ATTRIBUTE_SID,
-+					LDAP_ATTRIBUTE_GIDNUMBER,
- 					NULL};
- 	LDAPMessage *result;
- 	LDAPMessage *entry;
-@@ -3648,9 +3661,20 @@ static struct dom_sid *get_fallback_group_sid(TALLOC_CTX *mem_ctx,
- 		talloc_free(sid);
- 		return NULL;
- 	}
-+	talloc_free(sid);
-+
-+	gidnumber = get_single_attribute(mem_ctx, ldap_state->ldap_struct,
-+					entry, LDAP_ATTRIBUTE_GIDNUMBER);
-+	if (gidnumber == NULL) {
-+		DEBUG(0, ("Missing mandatory attribute %s.\n",
-+			  LDAP_ATTRIBUTE_GIDNUMBER));
-+		ldap_msgfree(result);
-+		return NULL;
-+	}
-+
-+	*fallback_group_gid_str = gidnumber;
- 
- 	ldap_msgfree(result);
--	talloc_free(sid);
- 
- 	return fallback_group_sid;
- }
-@@ -4443,6 +4467,7 @@ static NTSTATUS pdb_init_ipasam(struct pdb_methods **pdb_method,
- 	char *domain_sid_string = NULL;
- 	struct dom_sid *ldap_domain_sid = NULL;
- 	struct dom_sid *fallback_group_sid = NULL;
-+	char *fallback_group_gid_str = NULL;
- 
- 	LDAPMessage *result = NULL;
- 	LDAPMessage *entry = NULL;
-@@ -4586,7 +4611,8 @@ static NTSTATUS pdb_init_ipasam(struct pdb_methods **pdb_method,
- 	fallback_group_sid = get_fallback_group_sid(ldap_state,
- 					ldap_state->smbldap_state,
- 					ldap_state->ipasam_privates->idmap_ctx,
--					result);
-+					result,
-+					&fallback_group_gid_str);
- 	if (fallback_group_sid == NULL) {
- 		DEBUG(0, ("Cannot find SID of fallback group.\n"));
- 		ldap_msgfree(result);
-@@ -4596,6 +4622,14 @@ static NTSTATUS pdb_init_ipasam(struct pdb_methods **pdb_method,
- 		 fallback_group_sid);
- 	talloc_free(fallback_group_sid);
- 
-+	if (fallback_group_gid_str == NULL) {
-+		DEBUG(0, ("Cannot find gidNumber of fallback group.\n"));
-+		ldap_msgfree(result);
-+		return NT_STATUS_INVALID_PARAMETER;
-+	}
-+	ldap_state->ipasam_privates->fallback_primary_group_gid_str =
-+		fallback_group_gid_str;
-+
- 	domain_sid_string = get_single_attribute(
- 				ldap_state,
- 				ldap_state->smbldap_state->ldap_struct,
--- 
-2.9.3
-
diff --git a/SOURCES/0069-Upgrade-add-gidnumber-to-trusted-domain-entry.patch b/SOURCES/0069-Upgrade-add-gidnumber-to-trusted-domain-entry.patch
deleted file mode 100644
index 3a887bf..0000000
--- a/SOURCES/0069-Upgrade-add-gidnumber-to-trusted-domain-entry.patch
+++ /dev/null
@@ -1,104 +0,0 @@
-From 54422d3c58ace8496b0bd2fc536365159e6666e6 Mon Sep 17 00:00:00 2001
-From: Florence Blanc-Renaud <flo@redhat.com>
-Date: Mon, 3 Apr 2017 15:57:47 +0200
-Subject: [PATCH] Upgrade: add gidnumber to trusted domain entry
-
-The trusted domain entries created in earlier versions are missing gidnumber.
-During upgrade, a new plugin will read the gidnumber of the fallback group
-cn=Default SMB Group and add this value to trusted domain entries which do
-not have a gidNumber.
-
-https://pagure.io/freeipa/issue/6827
-
-Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
----
- install/updates/90-post_upgrade_plugins.update |  1 +
- ipaserver/install/plugins/adtrust.py           | 56 ++++++++++++++++++++++++++
- 2 files changed, 57 insertions(+)
-
-diff --git a/install/updates/90-post_upgrade_plugins.update b/install/updates/90-post_upgrade_plugins.update
-index 34069e7457dd9690a14c5c055c6d05ad76004d16..8477199e07d6729d5847e58bfa67d061bd1410c2 100644
---- a/install/updates/90-post_upgrade_plugins.update
-+++ b/install/updates/90-post_upgrade_plugins.update
-@@ -10,6 +10,7 @@ plugin: update_sigden_extdom_broken_config
- plugin: update_sids
- plugin: update_default_range
- plugin: update_default_trust_view
-+plugin: update_tdo_gidnumber
- plugin: update_ca_renewal_master
- plugin: update_idrange_type
- plugin: update_pacs
-diff --git a/ipaserver/install/plugins/adtrust.py b/ipaserver/install/plugins/adtrust.py
-index 42968089f547f61edd2f1223d088a22762a33b70..075f197780edc2aadf42fa82b71e9e2b29e66ea9 100644
---- a/ipaserver/install/plugins/adtrust.py
-+++ b/ipaserver/install/plugins/adtrust.py
-@@ -22,6 +22,7 @@ from ipalib import Updater
- from ipapython.dn import DN
- from ipapython.ipa_log_manager import root_logger
- from ipaserver.install import sysupgrade
-+from ipaserver.install.adtrustinstance import ADTRUSTInstance
- 
- register = Registry()
- 
-@@ -316,3 +317,58 @@ class update_sids(Updater):
- 
-         sysupgrade.set_upgrade_state('sidgen', 'update_sids', False)
-         return False, ()
-+
-+
-+@register()
-+class update_tdo_gidnumber(Updater):
-+    """
-+    Create a gidNumber attribute for Trusted Domain Objects.
-+
-+    The value is taken from the fallback group defined in cn=Default SMB Group.
-+    """
-+    def execute(self, **options):
-+        ldap = self.api.Backend.ldap2
-+
-+        # Read the gidnumber of the fallback group
-+        dn = DN(('cn', ADTRUSTInstance.FALLBACK_GROUP_NAME),
-+                self.api.env.container_group,
-+                self.api.env.basedn)
-+
-+        try:
-+            entry = ldap.get_entry(dn, ['gidnumber'])
-+            gidNumber = entry.get('gidnumber')
-+        except errors.NotFound:
-+            self.log.error("{0} not found".format(
-+                ADTRUSTInstance.FALLBACK_GROUP_NAME))
-+            return False, ()
-+
-+        if not gidNumber:
-+            self.log.error("{0} does not have a gidnumber".format(
-+                ADTRUSTInstance.FALLBACK_GROUP_NAME))
-+            return False, ()
-+
-+        # For each trusted domain object, add gidNumber
-+        try:
-+            tdos = ldap.get_entries(
-+                DN(self.api.env.container_adtrusts, self.api.env.basedn),
-+                scope=ldap.SCOPE_ONELEVEL,
-+                filter="(objectclass=ipaNTTrustedDomain)",
-+                attrs_list=['gidnumber'])
-+            for tdo in tdos:
-+                # if the trusted domain object does not contain gidnumber,
-+                # add the default fallback group gidnumber
-+                if not tdo.get('gidnumber'):
-+                    try:
-+                        tdo['gidnumber'] = gidNumber
-+                        ldap.update_entry(tdo)
-+                        self.log.debug("Added gidnumber {0} to {1}".format(
-+                            gidNumber, tdo.dn))
-+                    except Exception:
-+                        self.log.warning(
-+                            "Failed to add gidnumber to {0}".format(tdo.dn))
-+
-+        except errors.NotFound:
-+            self.log.debug("No trusted domain object to update")
-+            return False, ()
-+
-+        return False, ()
--- 
-2.9.3
-
diff --git a/SOURCES/0070-dsinstance-reconnect-ldap2-after-DS-is-restarted-by-.patch b/SOURCES/0070-dsinstance-reconnect-ldap2-after-DS-is-restarted-by-.patch
deleted file mode 100644
index 0e7a34c..0000000
--- a/SOURCES/0070-dsinstance-reconnect-ldap2-after-DS-is-restarted-by-.patch
+++ /dev/null
@@ -1,53 +0,0 @@
-From f6ecef4bdf8f5f99c89c0649232a230c28191869 Mon Sep 17 00:00:00 2001
-From: Jan Cholasta <jcholast@redhat.com>
-Date: Fri, 7 Apr 2017 07:40:19 +0200
-Subject: [PATCH] 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
-
-Reviewed-By: Martin Babinsky <mbabinsk@redhat.com>
----
- 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 b4c9490c10506aba60eee16c3f46ee7cb0474f50..ff476cac46f76d4964d39b12c04401dfc19c2d3a 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 79dc90e92cac49a2b64ff6645f75dc3a8cbcc104..fb5f925de8e658dca9370714413012527f00c39d 100644
---- a/ipaserver/install/dsinstance.py
-+++ b/ipaserver/install/dsinstance.py
-@@ -837,6 +837,10 @@ class DsInstance(service.Service):
-             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()
--- 
-2.9.3
-
diff --git a/SOURCES/0071-httpinstance-avoid-httpd-restart-during-certificate-.patch b/SOURCES/0071-httpinstance-avoid-httpd-restart-during-certificate-.patch
deleted file mode 100644
index a9b55ba..0000000
--- a/SOURCES/0071-httpinstance-avoid-httpd-restart-during-certificate-.patch
+++ /dev/null
@@ -1,52 +0,0 @@
-From 19738b56604f50e3806b220e74ac4a5ab52f71a4 Mon Sep 17 00:00:00 2001
-From: Jan Cholasta <jcholast@redhat.com>
-Date: Fri, 7 Apr 2017 07:40:41 +0200
-Subject: [PATCH] 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
-
-Reviewed-By: Martin Babinsky <mbabinsk@redhat.com>
----
- 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 079ea92606cc53f98beca1759a7e24db64bfd3f4..d7cd776ab9831b5408797ae41b7c7fbb10707b18 100644
---- a/ipaserver/install/httpinstance.py
-+++ b/ipaserver/install/httpinstance.py
-@@ -160,6 +160,7 @@ class HTTPInstance(service.Service):
-             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 @@ class HTTPInstance(service.Service):
-             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())
--- 
-2.9.3
-
diff --git a/SOURCES/0072-dsinstance-httpinstance-consolidate-certificate-requ.patch b/SOURCES/0072-dsinstance-httpinstance-consolidate-certificate-requ.patch
deleted file mode 100644
index 9c7a67f..0000000
--- a/SOURCES/0072-dsinstance-httpinstance-consolidate-certificate-requ.patch
+++ /dev/null
@@ -1,289 +0,0 @@
-From 2409b5204101cceafb28289db0d99c1474ee2430 Mon Sep 17 00:00:00 2001
-From: Jan Cholasta <jcholast@redhat.com>
-Date: Fri, 7 Apr 2017 07:43:09 +0200
-Subject: [PATCH] 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
-
-Reviewed-By: Martin Babinsky <mbabinsk@redhat.com>
----
- 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 fb5f925de8e658dca9370714413012527f00c39d..31dbd4ec8bcaf4a7545b4f9f316fe609b845cb75 100644
---- a/ipaserver/install/dsinstance.py
-+++ b/ipaserver/install/dsinstance.py
-@@ -396,10 +396,7 @@ class DsInstance(service.Service):
- 
-         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 @@ class DsInstance(service.Service):
-                 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 @@ class DsInstance(service.Service):
-                     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 @@ class DsInstance(service.Service):
- 
-             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 @@ class DsInstance(service.Service):
-         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 d7cd776ab9831b5408797ae41b7c7fbb10707b18..45bf479d1088c3b3396d955bf2592c4bce1e886f 100644
---- a/ipaserver/install/httpinstance.py
-+++ b/ipaserver/install/httpinstance.py
-@@ -376,12 +376,12 @@ class HTTPInstance(service.Service):
-         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 @@ class HTTPInstance(service.Service):
-             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 @@ class HTTPInstance(service.Service):
- 
-         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 @@ class HTTPInstance(service.Service):
-                 ]
-                 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 d7eb0bfacd0815026c82f59d76962f527e2b7dad..f8e64ec26e85bbc6218018eec8f403a0567b45a2 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 f489e691999fd9d6e82879341922510e56eac47d..cd6a62f9540f4a46da70e0cc5686eff5f54e7dfe 100644
---- a/ipaserver/install/server/replicainstall.py
-+++ b/ipaserver/install/server/replicainstall.py
-@@ -27,7 +27,6 @@ from ipapython.dn import DN
- 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:
--- 
-2.9.3
-
diff --git a/SOURCES/0073-install-request-service-certs-after-host-keytab-is-s.patch b/SOURCES/0073-install-request-service-certs-after-host-keytab-is-s.patch
deleted file mode 100644
index 45e18e6..0000000
--- a/SOURCES/0073-install-request-service-certs-after-host-keytab-is-s.patch
+++ /dev/null
@@ -1,135 +0,0 @@
-From acb04249a77f62f72179899223bfeacdd2292883 Mon Sep 17 00:00:00 2001
-From: Jan Cholasta <jcholast@redhat.com>
-Date: Fri, 7 Apr 2017 07:44:21 +0200
-Subject: [PATCH] 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
-
-Reviewed-By: Martin Babinsky <mbabinsk@redhat.com>
----
- 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 31dbd4ec8bcaf4a7545b4f9f316fe609b845cb75..72fcb65f2eb699d0077d3c5cc02a3fcaaad9b8e5 100644
---- a/ipaserver/install/dsinstance.py
-+++ b/ipaserver/install/dsinstance.py
-@@ -256,7 +256,7 @@ class DsInstance(service.Service):
- 
-     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 @@ class DsInstance(service.Service):
-         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 @@ class DsInstance(service.Service):
-         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 @@ class DsInstance(service.Service):
-         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 f8e64ec26e85bbc6218018eec8f403a0567b45a2..bf2e248dceaae36ba0030d3eaa47976f51ce60ba 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 cd6a62f9540f4a46da70e0cc5686eff5f54e7dfe..6f1a0d6d29b20d53986205a63382a385e75f80ea 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,
--- 
-2.9.3
-
diff --git a/SOURCES/0074-renew-agent-revert-to-host-keytab-authentication.patch b/SOURCES/0074-renew-agent-revert-to-host-keytab-authentication.patch
deleted file mode 100644
index 3dbde6d..0000000
--- a/SOURCES/0074-renew-agent-revert-to-host-keytab-authentication.patch
+++ /dev/null
@@ -1,53 +0,0 @@
-From 37ddd26bc4b2f99dfa27b2ad45219290a2f44ec5 Mon Sep 17 00:00:00 2001
-From: Jan Cholasta <jcholast@redhat.com>
-Date: Fri, 7 Apr 2017 07:46:58 +0200
-Subject: [PATCH] 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
-
-Reviewed-By: Martin Babinsky <mbabinsk@redhat.com>
----
- 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 5782db703c49d7c2e92c806e24e9925e8e7d710a..3389447a99d9ab9dac159b0d57ca02f60698ce0c 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():
--- 
-2.9.3
-
diff --git a/SOURCES/0075-renew-agent-restart-scripts-connect-to-LDAP-after-ki.patch b/SOURCES/0075-renew-agent-restart-scripts-connect-to-LDAP-after-ki.patch
deleted file mode 100644
index baf91f4..0000000
--- a/SOURCES/0075-renew-agent-restart-scripts-connect-to-LDAP-after-ki.patch
+++ /dev/null
@@ -1,117 +0,0 @@
-From 429f07426014c51025d136b505165a43f5e0df21 Mon Sep 17 00:00:00 2001
-From: Jan Cholasta <jcholast@redhat.com>
-Date: Fri, 7 Apr 2017 07:51:01 +0200
-Subject: [PATCH] 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
-
-Reviewed-By: Martin Babinsky <mbabinsk@redhat.com>
----
- 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 3389447a99d9ab9dac159b0d57ca02f60698ce0c..7a3d9551884c0fe43566dd9012699211a39294eb 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 bbeae1ae1da5a230f3de1c2569c2324606ae9789..7a54b4c7e05a35b40b17e46b75ff8d47db1b2d23 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 5c71d5791fa8254de686d1c3a8d01e2cda4d493b..486ee786629076687864f6ef9c3a69b8e389dc28 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():
--- 
-2.9.3
-
diff --git a/SOURCES/0076-ipaserver-dcerpc-unify-error-processing.patch b/SOURCES/0076-ipaserver-dcerpc-unify-error-processing.patch
deleted file mode 100644
index 40b8580..0000000
--- a/SOURCES/0076-ipaserver-dcerpc-unify-error-processing.patch
+++ /dev/null
@@ -1,93 +0,0 @@
-From 65579492d3d545d6acabaedc019c457551c32063 Mon Sep 17 00:00:00 2001
-From: Alexander Bokovoy <abokovoy@redhat.com>
-Date: Mon, 3 Apr 2017 10:29:21 +0300
-Subject: [PATCH] ipaserver/dcerpc: unify error processing
-
-Samba error code reporting changes from version to version but we also
-did not provide proper input into DCE RPC error processing method we
-have.
-
-Unify error processing and add few more fallback entries.
-
-With Samba 4.7 we'll have to change it again because error code
-processing for Samba Python modules will change with introduction of
-samba.ntstatus and samba.werror modules.
-
-Note that this commit also changes a message returned for error code
--1073741772 (NT_STATUS_OBJECT_NOT_FOUND) because it is more general one.
-
-Fixes https://pagure.io/freeipa/issue/6859
-
-Reviewed-By: Martin Basti <mbasti@redhat.com>
----
- ipaserver/dcerpc.py | 23 +++++++++++++++++------
- 1 file changed, 17 insertions(+), 6 deletions(-)
-
-diff --git a/ipaserver/dcerpc.py b/ipaserver/dcerpc.py
-index 2d9d7e5577f1cac6f35701dd277199f9a37387f8..d684a17cabe43bbbd43d29f75f534b6e50fccd12 100644
---- a/ipaserver/dcerpc.py
-+++ b/ipaserver/dcerpc.py
-@@ -117,19 +117,27 @@ dcerpc_error_codes = {
-                   # we simply will skip the binding
-         access_denied_error,
-     -1073741772:  # NT_STATUS_OBJECT_NAME_NOT_FOUND
--        errors.RemoteRetrieveError(
--            reason=_('CIFS server configuration does not allow '
--                     'access to \\\\pipe\\lsarpc')),
-+        errors.NotFound(
-+            reason=_('Cannot find specified domain or server name')),
- }
- 
- dcerpc_error_messages = {
-     "NT_STATUS_OBJECT_NAME_NOT_FOUND":
-         errors.NotFound(
-             reason=_('Cannot find specified domain or server name')),
-+    "The object name is not found.":
-+        errors.NotFound(
-+            reason=_('Cannot find specified domain or server name')),
-     "WERR_NO_LOGON_SERVERS":
-         errors.RemoteRetrieveError(
-             reason=_('AD DC was unable to reach any IPA domain controller. '
-                      'Most likely it is a DNS or firewall issue')),
-+    # This is a very long key, don't change it
-+    "There are currently no logon servers available to "
-+    "service the logon request.":
-+        errors.RemoteRetrieveError(
-+            reason=_('AD DC was unable to reach any IPA domain controller. '
-+                     'Most likely it is a DNS or firewall issue')),
-     "NT_STATUS_INVALID_PARAMETER_MIX":
-         errors.RequirementError(
-             name=_('At least the domain or IP address should be specified')),
-@@ -802,7 +810,8 @@ class DomainValidator(object):
- 
-         # Both methods should not fail at the same time
-         if finddc_error and len(info['gc']) == 0:
--            raise assess_dcerpc_exception(message=str(finddc_error))
-+            num, message = e.args  # pylint: disable=unpacking-non-sequence
-+            raise assess_dcerpc_exception(num=num, message=message)
- 
-         self._info[domain] = info
-         return info
-@@ -908,7 +917,8 @@ class TrustDomainInstance(object):
-             else:
-                 result = netrc.finddc(address=remote_host, flags=flags)
-         except RuntimeError as e:
--            raise assess_dcerpc_exception(message=str(e))
-+            num, message = e.args  # pylint: disable=unpacking-non-sequence
-+            raise assess_dcerpc_exception(num=num, message=message)
- 
-         if not result:
-             return False
-@@ -1408,7 +1418,8 @@ def fetch_domains(api, mydomain, trustdomain, creds=None, server=None):
-             result = netrc.finddc(domain=trustdomain,
-                                   flags=nbt.NBT_SERVER_LDAP | nbt.NBT_SERVER_DS)
-     except RuntimeError as e:
--        raise assess_dcerpc_exception(message=str(e))
-+        num, message = e.args  # pylint: disable=unpacking-non-sequence
-+        raise assess_dcerpc_exception(num=num, message=message)
- 
-     td.info['dc'] = unicode(result.pdc_dns_name)
-     td.info['name'] = unicode(result.dns_domain)
--- 
-2.9.3
-
diff --git a/SOURCES/0077-trust-always-use-oddjobd-helper-for-fetching-trust-i.patch b/SOURCES/0077-trust-always-use-oddjobd-helper-for-fetching-trust-i.patch
deleted file mode 100644
index db6b720..0000000
--- a/SOURCES/0077-trust-always-use-oddjobd-helper-for-fetching-trust-i.patch
+++ /dev/null
@@ -1,86 +0,0 @@
-From 3353a259bb8ace57efcfd784f2a0c0c6884d9966 Mon Sep 17 00:00:00 2001
-From: Alexander Bokovoy <abokovoy@redhat.com>
-Date: Wed, 5 Apr 2017 12:37:10 +0300
-Subject: [PATCH] trust: always use oddjobd helper for fetching trust
- information
-
-Since introduction of privilege separation in IPA framework none of the
-operations that require direct access to the framework's credentials can
-be done. All authentication has to be performed with GSSAPI.
-
-As result, we cannot obtain TGT for HTTP/.. principal with kinit
-anymore, so it is better to re-route all types of trust to oddjobd
-helper and get rid of casing out two-way trust.
-
-Fixes https://bugzilla.redhat.com/show_bug.cgi?id=1438366
-
-Reviewed-By: Martin Basti <mbasti@redhat.com>
----
- ipaserver/plugins/trust.py | 43 ++++++++++---------------------------------
- 1 file changed, 10 insertions(+), 33 deletions(-)
-
-diff --git a/ipaserver/plugins/trust.py b/ipaserver/plugins/trust.py
-index 3de2458466214044f6b1b5d8560a2a7ac53ede57..0829f8c714f15c4384a89e18ba29e417405c249c 100644
---- a/ipaserver/plugins/trust.py
-+++ b/ipaserver/plugins/trust.py
-@@ -1742,47 +1742,24 @@ class trust_fetch_domains(LDAPRetrieve):
-         ldap = self.api.Backend.ldap2
-         verify_samba_component_presence(ldap, self.api)
- 
--        trust = self.api.Command.trust_show(
--            keys[0], all=True, raw=True)['result']
-+        # Check first that the trust actually exists
-+        result = self.api.Command.trust_show(keys[0], all=True, raw=True)
-+        self.obj.warning_if_ad_trust_dom_have_missing_SID(result, **options)
- 
-         result = dict()
-         result['result'] = []
-         result['count'] = 0
-         result['truncated'] = False
- 
--        trust_direction = int(trust['ipanttrustdirection'][0])
--        is_nontransitive = int(trust.get('ipanttrustattributes',
--                               [0])[0]) & LSA_TRUST_ATTRIBUTE_NON_TRANSITIVE
-         # For one-way trust and external trust fetch over DBus.
-         # We don't get the list in this case.
--        if trust_direction != TRUST_BIDIRECTIONAL or is_nontransitive:
--            fetch_trusted_domains_over_dbus(self.api, self.log, keys[0])
--            result['summary'] = unicode(_('List of trust domains successfully refreshed. Use trustdomain-find command to list them.'))
--            return result
--
--        trustinstance = ipaserver.dcerpc.TrustDomainJoins(self.api)
--        if not trustinstance.configured:
--            raise errors.NotFound(
--                name=_('AD Trust setup'),
--                reason=_(
--                    'Cannot perform join operation without own domain '
--                    'configured. Make sure you have run ipa-adtrust-install '
--                    'on the IPA server first'
--                )
--            )
--
--        trustinstance.populate_remote_domain(keys[0])
--
--        res = fetch_domains_from_trust(self.api, trustinstance, **options)
--        domains = add_new_domains_from_trust(self.api, trustinstance, trust, res, **options)
--
--        if len(domains) > 0:
--            result['summary'] = unicode(_('List of trust domains successfully refreshed'))
--        else:
--            result['summary'] = unicode(_('No new trust domains were found'))
--
--        result['result'] = domains
--        result['count'] = len(domains)
-+        # With privilege separation we also cannot authenticate as
-+        # HTTP/ principal because we have no access to its key material.
-+        # Thus, we'll use DBus call out to oddjobd helper in all cases
-+        fetch_trusted_domains_over_dbus(self.api, self.log, keys[0])
-+        result['summary'] = unicode(_('List of trust domains successfully '
-+                                      'refreshed. Use trustdomain-find '
-+                                      'command to list them.'))
-         return result
- 
- 
--- 
-2.9.3
-
diff --git a/SOURCES/0078-WebUI-cert-login-Configure-name-of-parameter-used-to.patch b/SOURCES/0078-WebUI-cert-login-Configure-name-of-parameter-used-to.patch
deleted file mode 100644
index d547750..0000000
--- a/SOURCES/0078-WebUI-cert-login-Configure-name-of-parameter-used-to.patch
+++ /dev/null
@@ -1,34 +0,0 @@
-From 5ac1c55462297d4458d07a6ff9941170056216ef Mon Sep 17 00:00:00 2001
-From: David Kupka <dkupka@redhat.com>
-Date: Mon, 10 Apr 2017 13:11:13 +0200
-Subject: [PATCH] WebUI: cert login: Configure name of parameter used to pass
- username
-
-Directive LookupUserByCertificateParamName tells mod_lookup_identity module the
-name of GET parameter that is used to provide username in case certificate is
-mapped to multiple user accounts.
-Without this directive login with certificate that's mapped to multiple users
-doesn't work.
-
-https://pagure.io/freeipa/issue/6860
-
-Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
----
- install/conf/ipa.conf | 1 +
- 1 file changed, 1 insertion(+)
-
-diff --git a/install/conf/ipa.conf b/install/conf/ipa.conf
-index e1f1a581b4e8a91b899bcf165ca81f266fa9e516..75c122e6c94b941c278d724add84315753082531 100644
---- a/install/conf/ipa.conf
-+++ b/install/conf/ipa.conf
-@@ -117,6 +117,7 @@ Alias /ipa/session/cookie "/usr/share/ipa/gssapi.login"
-   NSSVerifyClient require
-   NSSUserName SSL_CLIENT_CERT
-   LookupUserByCertificate On
-+  LookupUserByCertificateParamName "username"
-   WSGIProcessGroup ipa
-   WSGIApplicationGroup ipa
-   GssapiImpersonate On
--- 
-2.9.3
-
diff --git a/SOURCES/0079-Create-system-users-for-FreeIPA-services-during-pack.patch b/SOURCES/0079-Create-system-users-for-FreeIPA-services-during-pack.patch
deleted file mode 100644
index 586cc85..0000000
--- a/SOURCES/0079-Create-system-users-for-FreeIPA-services-during-pack.patch
+++ /dev/null
@@ -1,414 +0,0 @@
-From a4a85c69a945b023b4017ecf4285f9f5e97d5f20 Mon Sep 17 00:00:00 2001
-From: David Kupka <dkupka@redhat.com>
-Date: Tue, 11 Apr 2017 11:43:40 +0200
-Subject: [PATCH] Create system users for FreeIPA services during package
- installation
-
-Previously system users needed by FreeIPA server services was created during
-ipa-server-install. This led to problem when DBus policy was configured during
-package installation but the user specified in the policy didn't exist yet
-(and potentionally similar ones). Now the users will be created in package %pre
-section so all users freeipa-server package needs exist before any installation
-or configuration begins.
-Another possibility would be using systemd-sysusers(8) for this purpose but
-given that systemd is not available during container build the traditional
-approach is superior.
-Also dirsrv and pkiuser users are no longer created by FreeIPA instead it
-depends on 389ds and dogtag to create those users.
-
-https://pagure.io/freeipa/issue/6743
-
-Reviewed-By: Jan Cholasta <jcholast@redhat.com>
-Reviewed-By: Christian Heimes <cheimes@redhat.com>
-Reviewed-By: Stanislav Laznicka <slaznick@redhat.com>
----
- freeipa.spec.in                            |  9 +++++
- ipaplatform/base/tasks.py                  | 53 ------------------------------
- ipaplatform/redhat/tasks.py                | 26 ---------------
- ipaserver/install/cainstance.py            | 12 -------
- ipaserver/install/dsinstance.py            | 11 -------
- ipaserver/install/httpinstance.py          | 13 --------
- ipaserver/install/installutils.py          | 13 --------
- ipaserver/install/ipa_restore.py           |  7 ----
- ipaserver/install/server/install.py        |  6 +---
- ipaserver/install/server/replicainstall.py |  6 +---
- ipaserver/install/server/upgrade.py        |  2 --
- 11 files changed, 11 insertions(+), 147 deletions(-)
-
-diff --git a/freeipa.spec.in b/freeipa.spec.in
-index 829c3f0b2898de1ecbf0cfb769fde5cd978c241c..978ebb184f7d051b303940560f44c7a094b071a1 100644
---- a/freeipa.spec.in
-+++ b/freeipa.spec.in
-@@ -1030,6 +1030,15 @@ if [ -e /usr/sbin/ipa_kpasswd ]; then
- # END
- fi
- 
-+# create users and groups
-+# create kdcproxy group and user
-+getent group kdcproxy >/dev/null || groupadd -f -r kdcproxy
-+getent passwd kdcproxy >/dev/null || useradd -r -g kdcproxy -s /sbin/nologin -d / -c "IPA KDC Proxy User" kdcproxy
-+# create ipaapi group and user
-+getent group ipaapi >/dev/null || groupadd -f -r ipaapi
-+getent passwd ipaapi >/dev/null || useradd -r -g ipaapi -s /sbin/nologin -d / -c "IPA Framework User" ipaapi
-+# add apache to ipaaapi group
-+id -Gn apache | grep '\bipaapi\b' >/dev/null || usermod apache -a -G ipaapi
- 
- %postun server-trust-ad
- if [ "$1" -ge "1" ]; then
-diff --git a/ipaplatform/base/tasks.py b/ipaplatform/base/tasks.py
-index 9f91fef2b572a29bf876641fd9ad879604054a2f..3358b7d257cc60ceaecfbbac5155d79b0e63de2e 100644
---- a/ipaplatform/base/tasks.py
-+++ b/ipaplatform/base/tasks.py
-@@ -22,9 +22,6 @@
- This module contains default platform-specific implementations of system tasks.
- '''
- 
--import pwd
--import grp
--
- from pkg_resources import parse_version
- 
- from ipaplatform.paths import paths
-@@ -186,56 +183,6 @@ class BaseTaskNamespace(object):
- 
-         raise NotImplementedError()
- 
--    def create_system_user(self, name, group, homedir, shell,
--                           uid=None, gid=None, comment=None,
--                           create_homedir=False, groups=None):
--        """Create a system user with a corresponding group"""
--        try:
--            grp.getgrnam(group)
--        except KeyError:
--            log.debug('Adding group %s', group)
--            args = [paths.GROUPADD, '-r', group]
--            if gid:
--                args += ['-g', str(gid)]
--            try:
--                ipautil.run(args)
--                log.debug('Done adding group')
--            except ipautil.CalledProcessError as e:
--                log.critical('Failed to add group: %s', e)
--                raise
--        else:
--            log.debug('group %s exists', group)
--
--        try:
--            pwd.getpwnam(name)
--        except KeyError:
--            log.debug('Adding user %s', name)
--            args = [
--                paths.USERADD,
--                '-g', group,
--                '-d', homedir,
--                '-s', shell,
--                '-r', name,
--            ]
--            if uid:
--                args += ['-u', str(uid)]
--            if comment:
--                args += ['-c', comment]
--            if create_homedir:
--                args += ['-m']
--            else:
--                args += ['-M']
--            if groups is not None:
--                args += ['-G', groups.join(',')]
--            try:
--                ipautil.run(args)
--                log.debug('Done adding user')
--            except ipautil.CalledProcessError as e:
--                log.critical('Failed to add user: %s', e)
--                raise
--        else:
--            log.debug('user %s exists', name)
--
-     @staticmethod
-     def parse_ipa_version(version):
-         """
-diff --git a/ipaplatform/redhat/tasks.py b/ipaplatform/redhat/tasks.py
-index d0ef5fbd1ceb8110dd417dda44a74dc63898456a..07efebab97eabcf2dc39bd345920a1c7be56e9f5 100644
---- a/ipaplatform/redhat/tasks.py
-+++ b/ipaplatform/redhat/tasks.py
-@@ -431,32 +431,6 @@ class RedHatTaskNamespace(BaseTaskNamespace):
- 
-         return True
- 
--    def create_system_user(self, name, group, homedir, shell,
--                           uid=None, gid=None, comment=None,
--                           create_homedir=False, groups=None):
--        """
--        Create a system user with a corresponding group
--
--        According to https://fedoraproject.org/wiki/Packaging:UsersAndGroups?rd=Packaging/UsersAndGroups#Soft_static_allocation
--        some system users should have fixed UID, GID and other parameters set.
--        This values should be constant and may be hardcoded.
--        Add other values for other users when needed.
--        """
--        if name == constants.PKI_USER:
--            if uid is None:
--                uid = 17
--            if gid is None:
--                gid = 17
--            if comment is None:
--                comment = 'CA System User'
--        if name == constants.DS_USER:
--            if comment is None:
--                comment = 'DS System User'
--
--        super(RedHatTaskNamespace, self).create_system_user(
--            name, group, homedir, shell, uid, gid, comment, create_homedir,
--            groups)
--
-     def parse_ipa_version(self, version):
-         """
-         :param version: textual version
-diff --git a/ipaserver/install/cainstance.py b/ipaserver/install/cainstance.py
-index 3980e412603437b0db5804623f6626d11e52c009..ac5d9e2fc633c5ad732670245b72bee0f03268a6 100644
---- a/ipaserver/install/cainstance.py
-+++ b/ipaserver/install/cainstance.py
-@@ -46,7 +46,6 @@ from ipalib import errors
- import ipalib.constants
- from ipalib.install import certmonger
- from ipaplatform import services
--from ipaplatform.constants import constants
- from ipaplatform.paths import paths
- from ipaplatform.tasks import tasks
- 
-@@ -263,16 +262,6 @@ def is_ca_installed_locally():
-     return os.path.exists(paths.CA_CS_CFG_PATH)
- 
- 
--def create_ca_user():
--    """Create PKI user/group if it doesn't exist yet."""
--    tasks.create_system_user(
--        name=constants.PKI_USER,
--        group=constants.PKI_GROUP,
--        homedir=paths.VAR_LIB,
--        shell=paths.NOLOGIN,
--    )
--
--
- class CAInstance(DogtagInstance):
-     """
-     When using a dogtag CA the DS database contains just the
-@@ -382,7 +371,6 @@ class CAInstance(DogtagInstance):
-             has_ra_cert = False
- 
-         if not ra_only:
--            self.step("creating certificate server user", create_ca_user)
-             if promote:
-                 # Setup Database
-                 self.step("creating certificate server db", self.__create_ds_db)
-diff --git a/ipaserver/install/dsinstance.py b/ipaserver/install/dsinstance.py
-index 72fcb65f2eb699d0077d3c5cc02a3fcaaad9b8e5..99a1781ca4475805e9bf3b2bac3f26b5fb107a43 100644
---- a/ipaserver/install/dsinstance.py
-+++ b/ipaserver/install/dsinstance.py
-@@ -158,16 +158,6 @@ def is_ds_running(server_id=''):
-     return services.knownservices.dirsrv.is_running(instance_name=server_id)
- 
- 
--def create_ds_user():
--    """Create DS user/group if it doesn't exist yet."""
--    tasks.create_system_user(
--        name=DS_USER,
--        group=DS_USER,
--        homedir=paths.VAR_LIB_DIRSRV,
--        shell=paths.NOLOGIN,
--    )
--
--
- def get_domain_level(api=api):
-     ldap_uri = ipaldap.get_ldap_uri(protocol='ldapi', realm=api.env.realm)
-     conn = ipaldap.LDAPClient(ldap_uri)
-@@ -258,7 +248,6 @@ class DsInstance(service.Service):
- 
-     def __common_setup(self):
- 
--        self.step("creating directory server user", create_ds_user)
-         self.step("creating directory server instance", self.__create_instance)
-         self.step("enabling ldapi", self.__enable_ldapi)
-         self.step("configure autobind for root", self.__root_autobind)
-diff --git a/ipaserver/install/httpinstance.py b/ipaserver/install/httpinstance.py
-index 45bf479d1088c3b3396d955bf2592c4bce1e886f..8e444be2d23ec5e7890d221508bc866de2854c89 100644
---- a/ipaserver/install/httpinstance.py
-+++ b/ipaserver/install/httpinstance.py
-@@ -102,18 +102,6 @@ def httpd_443_configured():
-     return False
- 
- 
--def create_kdcproxy_user():
--    """Create KDC proxy user/group if it doesn't exist yet."""
--    tasks.create_system_user(
--        name=KDCPROXY_USER,
--        group=KDCPROXY_USER,
--        homedir=paths.VAR_LIB_KDCPROXY,
--        shell=paths.NOLOGIN,
--        comment="IPA KDC Proxy User",
--        create_homedir=True,
--    )
--
--
- class WebGuiInstance(service.SimpleServiceInstance):
-     def __init__(self):
-         service.SimpleServiceInstance.__init__(self, "ipa_webgui")
-@@ -183,7 +171,6 @@ class HTTPInstance(service.Service):
-                   self.remove_httpd_ccaches)
-         self.step("configuring SELinux for httpd", self.configure_selinux_for_httpd)
-         if not self.is_kdcproxy_configured():
--            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("starting httpd", self.start)
-diff --git a/ipaserver/install/installutils.py b/ipaserver/install/installutils.py
-index ef6a399ad28ae8b8646864baea9965f762050484..9230e70056b1a773246a0d95e6ecb943cada953c 100644
---- a/ipaserver/install/installutils.py
-+++ b/ipaserver/install/installutils.py
-@@ -44,7 +44,6 @@ import six
- from six.moves.configparser import SafeConfigParser, NoOptionError
- # pylint: enable=import-error
- 
--from ipalib.constants import IPAAPI_USER, IPAAPI_GROUP
- from ipalib.install import sysrestore
- from ipalib.install.kinit import kinit_password
- import ipaplatform
-@@ -56,7 +55,6 @@ from ipalib import api, errors, x509
- from ipapython.dn import DN
- from ipaserver.install import certs, service, sysupgrade
- from ipaplatform import services
--from ipaplatform.constants import constants
- from ipaplatform.paths import paths
- from ipaplatform.tasks import tasks
- 
-@@ -1515,14 +1513,3 @@ def default_subject_base(realm_name):
- 
- def default_ca_subject_dn(subject_base):
-     return DN(('CN', 'Certificate Authority'), subject_base)
--
--
--def create_ipaapi_user():
--    """Create IPA API user/group if it doesn't exist yet."""
--    tasks.create_system_user(
--        name=IPAAPI_USER,
--        group=IPAAPI_GROUP,
--        homedir=paths.VAR_LIB,
--        shell=paths.NOLOGIN
--    )
--    tasks.add_user_to_group(constants.HTTPD_USER, IPAAPI_GROUP)
-diff --git a/ipaserver/install/ipa_restore.py b/ipaserver/install/ipa_restore.py
-index 2552bbdef36f653f1c377ea096ca227d09e5f3e6..378c013b6f4a4656768d7a484d2014a0f9eef3c0 100644
---- a/ipaserver/install/ipa_restore.py
-+++ b/ipaserver/install/ipa_restore.py
-@@ -36,8 +36,6 @@ from ipapython import version, ipautil
- from ipapython.ipautil import run, user_input
- from ipapython import admintool
- from ipapython.dn import DN
--from ipaserver.install.dsinstance import create_ds_user
--from ipaserver.install.cainstance import create_ca_user
- from ipaserver.install.replication import (wait_for_task, ReplicationManager,
-                                            get_cs_replication_manager)
- from ipaserver.install import installutils
-@@ -296,7 +294,6 @@ class Restore(admintool.AdminTool):
-                     not user_input("Continue to restore?", False)):
-                 raise admintool.ScriptError("Aborted")
- 
--        create_ds_user()
-         pent = pwd.getpwnam(constants.DS_USER)
- 
-         # Temporary directory for decrypting files before restoring
-@@ -379,15 +376,11 @@ class Restore(admintool.AdminTool):
-             # We do either a full file restore or we restore data.
-             if restore_type == 'FULL':
-                 self.remove_old_files()
--                if 'CA' in self.backup_services:
--                    create_ca_user()
-                 self.cert_restore_prepare()
-                 self.file_restore(options.no_logs)
-                 self.cert_restore()
-                 if 'CA' in self.backup_services:
-                     self.__create_dogtag_log_dirs()
--                if http.is_kdcproxy_configured():
--                    httpinstance.create_kdcproxy_user()
- 
-             # Always restore the data from ldif
-             # We need to restore both userRoot and ipaca.
-diff --git a/ipaserver/install/server/install.py b/ipaserver/install/server/install.py
-index bf2e248dceaae36ba0030d3eaa47976f51ce60ba..197f01ccef58bb3564eb4c6b5b4d615bff1e523d 100644
---- a/ipaserver/install/server/install.py
-+++ b/ipaserver/install/server/install.py
-@@ -39,7 +39,7 @@ from ipaserver.install import (
- from ipaserver.install.installutils import (
-     IPA_MODULES, BadHostError, get_fqdn, get_server_ip_address,
-     is_ipa_configured, load_pkcs12, read_password, verify_fqdn,
--    update_hosts_file, create_ipaapi_user)
-+    update_hosts_file)
- 
- if six.PY3:
-     unicode = str
-@@ -721,12 +721,8 @@ def install(installer):
-         update_hosts_file(ip_addresses, host_name, fstore)
- 
-     # Make sure tmpfiles dir exist before installing components
--    create_ipaapi_user()
-     tasks.create_tmpfiles_dirs()
- 
--    # Create DS user/group if it doesn't exist yet
--    dsinstance.create_ds_user()
--
-     # Create a directory server instance
-     if not options.external_cert_files:
-         # Configure ntpd
-diff --git a/ipaserver/install/server/replicainstall.py b/ipaserver/install/server/replicainstall.py
-index 6f1a0d6d29b20d53986205a63382a385e75f80ea..b82d7b474640e24da7d978e9546ebd7a8e602c29 100644
---- a/ipaserver/install/server/replicainstall.py
-+++ b/ipaserver/install/server/replicainstall.py
-@@ -41,8 +41,7 @@ from ipaserver.install import (
-     installutils, kra, krbinstance,
-     ntpinstance, otpdinstance, custodiainstance, service)
- from ipaserver.install.installutils import (
--    create_replica_config, ReplicaConfig, load_pkcs12, is_ipa_configured,
--    create_ipaapi_user)
-+    create_replica_config, ReplicaConfig, load_pkcs12, is_ipa_configured)
- from ipaserver.install.replication import (
-     ReplicationManager, replica_conn_check)
- import SSSDConfig
-@@ -1347,7 +1346,6 @@ def install(installer):
-     ccache = os.environ['KRB5CCNAME']
- 
-     # Make sure tmpfiles dir exist before installing components
--    create_ipaapi_user()
-     tasks.create_tmpfiles_dirs()
- 
-     if promote:
-@@ -1376,8 +1374,6 @@ def install(installer):
-         ntp = ntpinstance.NTPInstance()
-         ntp.create_instance()
- 
--    dsinstance.create_ds_user()
--
-     try:
-         if promote:
-             conn.connect(ccache=ccache)
-diff --git a/ipaserver/install/server/upgrade.py b/ipaserver/install/server/upgrade.py
-index 25b86297af3ae9d5f21cebb93f493b90670dcfc3..927acb011172de926773196eb1d032af8376f3d9 100644
---- a/ipaserver/install/server/upgrade.py
-+++ b/ipaserver/install/server/upgrade.py
-@@ -1652,7 +1652,6 @@ def upgrade_configuration():
- 
-     if not http.is_kdcproxy_configured():
-         root_logger.info('[Enabling KDC Proxy]')
--        httpinstance.create_kdcproxy_user()
-         http.create_kdcproxy_conf()
-         http.enable_kdcproxy()
- 
-@@ -1837,7 +1836,6 @@ def upgrade_check(options):
- 
- def upgrade():
-     # Do this early so that any code depending on these dirs will not fail
--    installutils.create_ipaapi_user()
-     tasks.create_tmpfiles_dirs()
-     tasks.configure_tmpfiles()
- 
--- 
-2.9.3
-
diff --git a/SOURCES/0080-Fix-s4u2self-with-adtrust.patch b/SOURCES/0080-Fix-s4u2self-with-adtrust.patch
deleted file mode 100644
index af64e74..0000000
--- a/SOURCES/0080-Fix-s4u2self-with-adtrust.patch
+++ /dev/null
@@ -1,60 +0,0 @@
-From 542c31e057cbd4bd6261abcc883ace14f69719d6 Mon Sep 17 00:00:00 2001
-From: Simo Sorce <simo@redhat.com>
-Date: Mon, 10 Apr 2017 15:32:54 -0400
-Subject: [PATCH] Fix s4u2self with adtrust
-
-When ADtrust is installed we add a PAC to all tickets, during protocol
-transition we need to generate a new PAC for the requested user ticket,
-not check the existing PAC on the requestor ticket.
-
-https://pagure.io/freeipa/issue/6862
-
-Signed-off-by: Simo Sorce <simo@redhat.com>
-Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
-Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
----
- daemons/ipa-kdb/ipa_kdb_mspac.c | 14 ++++++++++----
- 1 file changed, 10 insertions(+), 4 deletions(-)
-
-diff --git a/daemons/ipa-kdb/ipa_kdb_mspac.c b/daemons/ipa-kdb/ipa_kdb_mspac.c
-index cf1bd5b4eaf6ac8eba92639cc48cb7c333a6e836..00cc19ca1e757e28530eafcd38ebf73003e251e3 100644
---- a/daemons/ipa-kdb/ipa_kdb_mspac.c
-+++ b/daemons/ipa-kdb/ipa_kdb_mspac.c
-@@ -2117,6 +2117,7 @@ krb5_error_code ipadb_sign_authdata(krb5_context context,
-     struct ipadb_context *ipactx;
-     bool with_pac;
-     bool with_pad;
-+    bool make_ad = false;
-     int result;
-     krb5_db_entry *client_entry = NULL;
-     krb5_boolean is_equal;
-@@ -2165,7 +2166,14 @@ krb5_error_code ipadb_sign_authdata(krb5_context context,
-                                   "currently not supported.");
-     }
- 
--    if (is_as_req && with_pac && (flags & KRB5_KDB_FLAG_INCLUDE_PAC)) {
-+    /* we need to create a PAC if we are requested one and this is an AS REQ,
-+     * or we are doing protocol transition (s4u2self) */
-+    if ((is_as_req && (flags & KRB5_KDB_FLAG_INCLUDE_PAC)) ||
-+        (flags & KRB5_KDB_FLAG_PROTOCOL_TRANSITION)) {
-+        make_ad = true;
-+    }
-+
-+    if (with_pac && make_ad) {
-         /* Be aggressive here: special case for discovering range type
-          * immediately after establishing the trust by IPA framework */
-         if ((krb5_princ_size(context, ks_client_princ) == 2) &&
-@@ -2188,9 +2196,7 @@ krb5_error_code ipadb_sign_authdata(krb5_context context,
-         if (kerr != 0 && kerr != ENOENT) {
-             goto done;
-         }
--    }
--
--    if (!is_as_req && with_pac) {
-+    } else if (with_pac && !is_as_req) {
-         /* find the existing PAC, if present */
-         kerr = krb5_find_authdata(context, tgt_auth_data, NULL,
-                                   KRB5_AUTHDATA_WIN2K_PAC, &pac_auth_data);
--- 
-2.9.3
-
diff --git a/SOURCES/0081-Add-debug-log-in-case-cookie-retrieval-went-wrong.patch b/SOURCES/0081-Add-debug-log-in-case-cookie-retrieval-went-wrong.patch
deleted file mode 100644
index eef3ee2..0000000
--- a/SOURCES/0081-Add-debug-log-in-case-cookie-retrieval-went-wrong.patch
+++ /dev/null
@@ -1,31 +0,0 @@
-From 6a66a69f4500fc8b324f3f3f0f0a4d79ea3fbe1e Mon Sep 17 00:00:00 2001
-From: Stanislav Laznicka <slaznick@redhat.com>
-Date: Fri, 17 Mar 2017 08:55:30 +0100
-Subject: [PATCH] Add debug log in case cookie retrieval went wrong
-
-https://pagure.io/freeipa/issue/6774
-
-Reviewed-By: Martin Basti <mbasti@redhat.com>
----
- ipalib/rpc.py | 5 ++++-
- 1 file changed, 4 insertions(+), 1 deletion(-)
-
-diff --git a/ipalib/rpc.py b/ipalib/rpc.py
-index 5c49bd2456b7e564043a886c840fa2678060f9e3..e23ca3d061645b2695a9e0deaa0b7d666f986e0e 100644
---- a/ipalib/rpc.py
-+++ b/ipalib/rpc.py
-@@ -895,7 +895,10 @@ class RPCClient(Connectible):
-             session_cookie = Cookie.get_named_cookie_from_string(
-                 cookie_string, COOKIE_NAME,
-                 timestamp=datetime.datetime.utcnow())
--        except Exception:
-+        except Exception as e:
-+            self.log.debug(
-+                'Error retrieving cookie from the persistent storage: {err}'
-+                .format(err=e))
-             return None
- 
-         return session_cookie
--- 
-2.12.2
-
diff --git a/SOURCES/0082-server-install-remove-broken-no-pkinit-check.patch b/SOURCES/0082-server-install-remove-broken-no-pkinit-check.patch
deleted file mode 100644
index bb4e410..0000000
--- a/SOURCES/0082-server-install-remove-broken-no-pkinit-check.patch
+++ /dev/null
@@ -1,36 +0,0 @@
-From e4f21a17762e3dcdbe05d9d62255fff9a7e2c8fa Mon Sep 17 00:00:00 2001
-From: Stanislav Laznicka <slaznick@redhat.com>
-Date: Tue, 4 Apr 2017 10:41:23 +0200
-Subject: [PATCH] server-install: remove broken no-pkinit check
-
-Don't check for no-pkinit option in case pkinit cert file was
-provided. Setting no-pkinit is prohibited in this case, so without
-this fix we have an impossible option-check if we want to provide
-an own pkinit certificate and private key.
-
-https://pagure.io/freeipa/issue/6807
-
-Reviewed-By: Martin Basti <mbasti@redhat.com>
----
- ipaserver/install/server/install.py | 5 -----
- 1 file changed, 5 deletions(-)
-
-diff --git a/ipaserver/install/server/install.py b/ipaserver/install/server/install.py
-index 197f01ccef58bb3564eb4c6b5b4d615bff1e523d..b899b4be4028e6cdfd95bb9868fba8be25a07b65 100644
---- a/ipaserver/install/server/install.py
-+++ b/ipaserver/install/server/install.py
-@@ -513,11 +513,6 @@ def install_check(installer):
-         dirsrv_pkcs12_info = (dirsrv_pkcs12_file.name, dirsrv_pin)
- 
-     if options.pkinit_cert_files:
--        if not options.no_pkinit:
--            raise ScriptError("Cannot create KDC PKINIT certificate and use "
--                              "provided external PKINIT certificate at the "
--                              "same time. Please choose one of them.")
--
-         if options.pkinit_pin is None:
-             options.pkinit_pin = read_password(
-                 "Enter Kerberos KDC private key unlock",
--- 
-2.12.2
-
diff --git a/SOURCES/0083-Add-the-force-join-option-to-replica-install.patch b/SOURCES/0083-Add-the-force-join-option-to-replica-install.patch
deleted file mode 100644
index db317df..0000000
--- a/SOURCES/0083-Add-the-force-join-option-to-replica-install.patch
+++ /dev/null
@@ -1,55 +0,0 @@
-From 8af160743817054289d1fff9aa904168e9606061 Mon Sep 17 00:00:00 2001
-From: Stanislav Laznicka <slaznick@redhat.com>
-Date: Wed, 5 Apr 2017 09:49:57 +0200
-Subject: [PATCH] Add the force-join option to replica install
-
-When installing client from inside replica installation on DL1,
-it's possible that the client installation would fail and recommend
-using --force-join option which is not available in replica installer.
-Add the option there.
-
-https://pagure.io/freeipa/issue/6183
-
-Reviewed-By: Tomas Krizek <tkrizek@redhat.com>
-Reviewed-By: Jan Cholasta <jcholast@redhat.com>
----
- ipaserver/install/server/__init__.py       | 2 +-
- ipaserver/install/server/replicainstall.py | 2 ++
- 2 files changed, 3 insertions(+), 1 deletion(-)
-
-diff --git a/ipaserver/install/server/__init__.py b/ipaserver/install/server/__init__.py
-index 89444f21fefc902931b7ecfaba861a18ecc28dbe..028a4aa60feccf5af85f76d443dcb42b01684406 100644
---- a/ipaserver/install/server/__init__.py
-+++ b/ipaserver/install/server/__init__.py
-@@ -166,7 +166,6 @@ class ServerInstallInterface(ServerCertificateInstallInterface,
-     """
-     description = "Server"
- 
--    force_join = False
-     kinit_attempts = 1
-     fixed_primary = True
-     ntp_servers = None
-@@ -526,6 +525,7 @@ class ServerMasterInstall(ServerMasterInstallInterface):
-     Server master installer
-     """
- 
-+    force_join = False
-     servers = None
-     no_wait_for_dns = True
-     host_password = None
-diff --git a/ipaserver/install/server/replicainstall.py b/ipaserver/install/server/replicainstall.py
-index b82d7b474640e24da7d978e9546ebd7a8e602c29..383932b39b9ee99a7a5ce3275a5a7e02581b85b7 100644
---- a/ipaserver/install/server/replicainstall.py
-+++ b/ipaserver/install/server/replicainstall.py
-@@ -935,6 +935,8 @@ def ensure_enrolled(installer):
-             args.append("--no-sshd")
-         if installer.mkhomedir:
-             args.append("--mkhomedir")
-+        if installer.force_join:
-+            args.append("--force-join")
- 
-         ipautil.run(args, stdin=stdin, nolog=nolog, redirect_output=True)
-         print()
--- 
-2.12.2
-
diff --git a/SOURCES/0084-replicainstall-better-client-install-exception-handl.patch b/SOURCES/0084-replicainstall-better-client-install-exception-handl.patch
deleted file mode 100644
index 6e8ac10..0000000
--- a/SOURCES/0084-replicainstall-better-client-install-exception-handl.patch
+++ /dev/null
@@ -1,120 +0,0 @@
-From 9303e3d0912e60b2069f7c5bad6b816ed8b033ef Mon Sep 17 00:00:00 2001
-From: Stanislav Laznicka <slaznick@redhat.com>
-Date: Wed, 5 Apr 2017 09:57:44 +0200
-Subject: [PATCH] replicainstall: better client install exception handling
-
-The exception handling of client install inside replica installation
-was rather promiscuous, hungrily eating any possible exception thrown
-at it. Scoped down the try-except block and reduced its promiscuity.
-This change should improve the future development experience debugging
-this part of the code.
-
-https://pagure.io/freeipa/issue/6183
-
-Reviewed-By: Tomas Krizek <tkrizek@redhat.com>
-Reviewed-By: Jan Cholasta <jcholast@redhat.com>
----
- ipaserver/install/server/replicainstall.py | 83 +++++++++++++++---------------
- 1 file changed, 41 insertions(+), 42 deletions(-)
-
-diff --git a/ipaserver/install/server/replicainstall.py b/ipaserver/install/server/replicainstall.py
-index 383932b39b9ee99a7a5ce3275a5a7e02581b85b7..aa8e67f60b8abe591d55a907c409b584c74d4541 100644
---- a/ipaserver/install/server/replicainstall.py
-+++ b/ipaserver/install/server/replicainstall.py
-@@ -895,52 +895,51 @@ def install_check(installer):
- 
- 
- def ensure_enrolled(installer):
--    # Call client install script
--    service.print_msg("Configuring client side components")
-+    args = [paths.IPA_CLIENT_INSTALL, "--unattended", "--no-ntp"]
-+    stdin = None
-+    nolog = []
-+
-+    if installer.domain_name:
-+        args.extend(["--domain", installer.domain_name])
-+    if installer.server:
-+        args.extend(["--server", installer.server])
-+    if installer.realm_name:
-+        args.extend(["--realm", installer.realm_name])
-+    if installer.host_name:
-+        args.extend(["--hostname", installer.host_name])
-+
-+    if installer.password:
-+        args.extend(["--password", installer.password])
-+        nolog.append(installer.password)
-+    else:
-+        if installer.admin_password:
-+            # Always set principal if password was set explicitly,
-+            # the password itself gets passed directly via stdin
-+            args.extend(["--principal", installer.principal or "admin"])
-+            stdin = installer.admin_password
-+        if installer.keytab:
-+            args.extend(["--keytab", installer.keytab])
-+
-+    if installer.no_dns_sshfp:
-+        args.append("--no-dns-sshfp")
-+    if installer.ssh_trust_dns:
-+        args.append("--ssh-trust-dns")
-+    if installer.no_ssh:
-+        args.append("--no-ssh")
-+    if installer.no_sshd:
-+        args.append("--no-sshd")
-+    if installer.mkhomedir:
-+        args.append("--mkhomedir")
-+    if installer.force_join:
-+        args.append("--force-join")
-+
-     try:
-+        # Call client install script
-+        service.print_msg("Configuring client side components")
-         installer._enrollment_performed = True
--
--        args = [paths.IPA_CLIENT_INSTALL, "--unattended", "--no-ntp"]
--        stdin = None
--        nolog = []
--
--        if installer.domain_name:
--            args.extend(["--domain", installer.domain_name])
--        if installer.server:
--            args.extend(["--server", installer.server])
--        if installer.realm_name:
--            args.extend(["--realm", installer.realm_name])
--        if installer.host_name:
--            args.extend(["--hostname", installer.host_name])
--
--        if installer.password:
--            args.extend(["--password", installer.password])
--            nolog.append(installer.password)
--        else:
--            if installer.admin_password:
--                # Always set principal if password was set explicitly,
--                # the password itself gets passed directly via stdin
--                args.extend(["--principal", installer.principal or "admin"])
--                stdin = installer.admin_password
--            if installer.keytab:
--                args.extend(["--keytab", installer.keytab])
--
--        if installer.no_dns_sshfp:
--            args.append("--no-dns-sshfp")
--        if installer.ssh_trust_dns:
--            args.append("--ssh-trust-dns")
--        if installer.no_ssh:
--            args.append("--no-ssh")
--        if installer.no_sshd:
--            args.append("--no-sshd")
--        if installer.mkhomedir:
--            args.append("--mkhomedir")
--        if installer.force_join:
--            args.append("--force-join")
--
-         ipautil.run(args, stdin=stdin, nolog=nolog, redirect_output=True)
-         print()
--    except Exception:
-+    except ipautil.CalledProcessError:
-         raise ScriptError("Configuration of client side components failed!")
- 
- 
--- 
-2.12.2
-
diff --git a/SOURCES/0085-Fix-CA-less-to-CA-full-upgrade.patch b/SOURCES/0085-Fix-CA-less-to-CA-full-upgrade.patch
deleted file mode 100644
index 18f9500..0000000
--- a/SOURCES/0085-Fix-CA-less-to-CA-full-upgrade.patch
+++ /dev/null
@@ -1,110 +0,0 @@
-From c3ee037c2dd92ccb277523919e991471c9caa3c6 Mon Sep 17 00:00:00 2001
-From: Stanislav Laznicka <slaznick@redhat.com>
-Date: Tue, 11 Apr 2017 10:21:15 +0200
-Subject: [PATCH] Fix CA-less to CA-full upgrade
-
-CertDB would have always created a directory on initialization. This
-behavior changes here by replacing the truncate argument with create
-which will only create the database when really required.
-
-https://pagure.io/freeipa/issue/6853
-
-Reviewed-By: Tomas Krizek <tkrizek@redhat.com>
----
- ipaserver/install/ca.py           |  2 ++
- ipaserver/install/certs.py        | 38 ++++++++++++++++++++++++++++----------
- ipaserver/install/httpinstance.py |  2 +-
- 3 files changed, 31 insertions(+), 11 deletions(-)
-
-diff --git a/ipaserver/install/ca.py b/ipaserver/install/ca.py
-index db3b744a51b0ae2ba12f79c155a1bb0698d94bec..8ee0fda23411563c70b7db5f39f43c2869c108b5 100644
---- a/ipaserver/install/ca.py
-+++ b/ipaserver/install/ca.py
-@@ -183,6 +183,8 @@ def install_check(standalone, replica_config, options):
-             realm_name, nssdir=dirname, subject_base=options._subject_base)
- 
-         for db in (cadb, dsdb):
-+            if not db.exists():
-+                continue
-             for nickname, _trust_flags in db.list_certs():
-                 if nickname == certdb.get_ca_nickname(realm_name):
-                     raise ScriptError(
-diff --git a/ipaserver/install/certs.py b/ipaserver/install/certs.py
-index 16139f81f0d0bd6889a9f38948204bb5bc018028..89e57134f24c505d669057eefffb7862b3b8179a 100644
---- a/ipaserver/install/certs.py
-+++ b/ipaserver/install/certs.py
-@@ -99,7 +99,7 @@ class CertDB(object):
-     # TODO: Remove all selfsign code
-     def __init__(self, realm, nssdir, fstore=None,
-                  host_name=None, subject_base=None, ca_subject=None,
--                 user=None, group=None, mode=None, truncate=False):
-+                 user=None, group=None, mode=None, create=False):
-         self.nssdb = NSSDatabase(nssdir)
- 
-         self.secdir = nssdir
-@@ -132,15 +132,16 @@ class CertDB(object):
-         self.uid = 0
-         self.gid = 0
- 
--        if not truncate and os.path.exists(self.secdir):
--            # We are going to set the owner of all of the cert
--            # files to the owner of the containing directory
--            # instead of that of the process. This works when
--            # this is called by root for a daemon that runs as
--            # a normal user
--            mode = os.stat(self.secdir)
--            self.uid = mode[stat.ST_UID]
--            self.gid = mode[stat.ST_GID]
-+        if not create:
-+            if os.path.isdir(self.secdir):
-+                # We are going to set the owner of all of the cert
-+                # files to the owner of the containing directory
-+                # instead of that of the process. This works when
-+                # this is called by root for a daemon that runs as
-+                # a normal user
-+                mode = os.stat(self.secdir)
-+                self.uid = mode[stat.ST_UID]
-+                self.gid = mode[stat.ST_GID]
-         else:
-             if user is not None:
-                 pu = pwd.getpwnam(user)
-@@ -162,6 +163,23 @@ class CertDB(object):
-     def passwd_fname(self):
-         return self.nssdb.pwd_file
- 
-+    def exists(self):
-+        """
-+        Checks whether all NSS database files + our pwd_file exist
-+        """
-+        db_files = (
-+            self.secdir,
-+            self.certdb_fname,
-+            self.keydb_fname,
-+            self.secmod_fname,
-+            self.nssdb.pwd_file,
-+        )
-+
-+        for f in db_files:
-+            if not os.path.exists(f):
-+                return False
-+        return True
-+
-     def __del__(self):
-         if self.reqdir is not None:
-             shutil.rmtree(self.reqdir, ignore_errors=True)
-diff --git a/ipaserver/install/httpinstance.py b/ipaserver/install/httpinstance.py
-index 8e444be2d23ec5e7890d221508bc866de2854c89..aeb5c5e450813469e1b6cd374b30cd4aab338537 100644
---- a/ipaserver/install/httpinstance.py
-+++ b/ipaserver/install/httpinstance.py
-@@ -366,7 +366,7 @@ class HTTPInstance(service.Service):
-         db = certs.CertDB(self.realm, nssdir=paths.HTTPD_ALIAS_DIR,
-                           subject_base=self.subject_base, user="root",
-                           group=constants.HTTPD_GROUP,
--                          truncate=True)
-+                          create=True)
-         self.disable_system_trust()
-         self.create_password_conf()
-         if self.pkcs12_info:
--- 
-2.12.2
-
diff --git a/SOURCES/0086-cert-defer-cert-find-result-post-processing.patch b/SOURCES/0086-cert-defer-cert-find-result-post-processing.patch
deleted file mode 100644
index 044f33a..0000000
--- a/SOURCES/0086-cert-defer-cert-find-result-post-processing.patch
+++ /dev/null
@@ -1,221 +0,0 @@
-From eb9d14debc4276f422ae55d141e30246d5943067 Mon Sep 17 00:00:00 2001
-From: Jan Cholasta <jcholast@redhat.com>
-Date: Thu, 30 Mar 2017 08:33:30 +0000
-Subject: [PATCH] cert: defer cert-find result post-processing
-
-Rather than post-processing the results of each internal search,
-post-process the combined result.
-
-This avoids expensive per-certificate searches when cert-find is executed
-with the --all option on certificates which won't even be included in the
-combined result.
-
-https://pagure.io/freeipa/issue/6808
-
-Reviewed-By: Stanislav Laznicka <slaznick@redhat.com>
----
- ipaserver/plugins/cert.py   | 93 +++++++++++++++++++++++++++------------------
- ipaserver/plugins/dogtag.py | 10 +++++
- 2 files changed, 66 insertions(+), 37 deletions(-)
-
-diff --git a/ipaserver/plugins/cert.py b/ipaserver/plugins/cert.py
-index dfc7444ddbf31ac3c194e050af28220fc2a87a92..68402679cf0320e9c664ea89276f6c4332730a15 100644
---- a/ipaserver/plugins/cert.py
-+++ b/ipaserver/plugins/cert.py
-@@ -162,6 +162,11 @@ def normalize_pkidate(value):
-     return datetime.datetime.strptime(value, PKIDATE_FORMAT)
- 
- 
-+def convert_pkidatetime(value):
-+    value = datetime.datetime.fromtimestamp(int(value) // 1000)
-+    return x509.format_datetime(value)
-+
-+
- def validate_csr(ugettext, csr):
-     """
-     Ensure the CSR is base64-encoded and can be decoded by our PKCS#10
-@@ -1296,18 +1301,7 @@ class cert_find(Search, CertMethod):
- 
-         return (DN(cert_obj.issuer), cert_obj.serial_number)
- 
--    def _get_cert_obj(self, cert, all, raw, pkey_only):
--        obj = {'certificate': base64.b64encode(cert).decode('ascii')}
--
--        full = not pkey_only and all
--        if not raw:
--            self.obj._parse(obj, full)
--        if not full:
--            del obj['certificate']
--
--        return obj
--
--    def _cert_search(self, all, raw, pkey_only, **options):
-+    def _cert_search(self, pkey_only, **options):
-         result = collections.OrderedDict()
- 
-         try:
-@@ -1316,15 +1310,19 @@ class cert_find(Search, CertMethod):
-             return result, False, False
- 
-         try:
--            key = self._get_cert_key(cert)
-+            issuer, serial_number = self._get_cert_key(cert)
-         except ValueError:
-             return result, True, True
- 
--        result[key] = self._get_cert_obj(cert, all, raw, pkey_only)
-+        obj = {'serial_number': serial_number}
-+        if not pkey_only:
-+            obj['certificate'] = base64.b64encode(cert).decode('ascii')
-+
-+        result[issuer, serial_number] = obj
- 
-         return result, False, True
- 
--    def _ca_search(self, all, raw, pkey_only, exactly, **options):
-+    def _ca_search(self, raw, pkey_only, exactly, **options):
-         ra_options = {}
-         for name in ('revocation_reason',
-                      'issuer',
-@@ -1357,7 +1355,6 @@ class cert_find(Search, CertMethod):
-             return result, False, complete
- 
-         ca_objs = self.api.Command.ca_find(
--            all=all,
-             timelimit=0,
-             sizelimit=0,
-         )['result']
-@@ -1377,24 +1374,16 @@ class cert_find(Search, CertMethod):
-                 obj = {'serial_number': serial_number}
-             else:
-                 obj = ra_obj
--                if all:
--                    obj.update(ra.get_certificate(str(serial_number)))
- 
-                 if not raw:
-                     obj['issuer'] = issuer
-                     obj['subject'] = DN(ra_obj['subject'])
-+                    obj['valid_not_before'] = (
-+                        convert_pkidatetime(obj['valid_not_before']))
-+                    obj['valid_not_after'] = (
-+                        convert_pkidatetime(obj['valid_not_after']))
-                     obj['revoked'] = (
-                         ra_obj['status'] in (u'REVOKED', u'REVOKED_EXPIRED'))
--                    if all:
--                        obj['certificate'] = (
--                            obj['certificate'].replace('\r\n', ''))
--                        self.obj._parse(obj)
--
--                if 'certificate_chain' in ca_obj:
--                    cert = x509.load_certificate(obj['certificate'])
--                    cert_der = cert.public_bytes(serialization.Encoding.DER)
--                    obj['certificate_chain'] = (
--                        [cert_der] + ca_obj['certificate_chain'])
- 
-             obj['cacn'] = ca_obj['cn'][0]
- 
-@@ -1402,7 +1391,7 @@ class cert_find(Search, CertMethod):
- 
-         return result, False, complete
- 
--    def _ldap_search(self, all, raw, pkey_only, no_members, **options):
-+    def _ldap_search(self, all, pkey_only, no_members, **options):
-         ldap = self.api.Backend.ldap2
- 
-         filters = []
-@@ -1461,26 +1450,25 @@ class cert_find(Search, CertMethod):
-             for attr in ('usercertificate', 'usercertificate;binary'):
-                 for cert in entry.get(attr, []):
-                     try:
--                        key = self._get_cert_key(cert)
-+                        issuer, serial_number = self._get_cert_key(cert)
-                     except ValueError:
-                         truncated = True
-                         continue
- 
-                     try:
--                        obj = result[key]
-+                        obj = result[issuer, serial_number]
-                     except KeyError:
--                        obj = self._get_cert_obj(cert, all, raw, pkey_only)
--                        result[key] = obj
-+                        obj = {'serial_number': serial_number}
-+                        if not pkey_only and all:
-+                            obj['certificate'] = (
-+                                base64.b64encode(cert).decode('ascii'))
-+                        result[issuer, serial_number] = obj
- 
-                     if not pkey_only and (all or not no_members):
-                         owners = obj.setdefault('owner', [])
-                         if entry.dn not in owners:
-                             owners.append(entry.dn)
- 
--        if not raw:
--            for obj in six.itervalues(result):
--                self.obj._fill_owners(obj)
--
-         return result, truncated, complete
- 
-     def execute(self, criteria=None, all=False, raw=False, pkey_only=False,
-@@ -1537,6 +1525,37 @@ class cert_find(Search, CertMethod):
-             truncated = truncated or sub_truncated
-             complete = complete or sub_complete
- 
-+        if not pkey_only:
-+            ca_objs = {}
-+            ra = self.api.Backend.ra
-+
-+            for key, obj in six.iteritems(result):
-+                if all and 'cacn' in obj:
-+                    _issuer, serial_number = key
-+                    cacn = obj['cacn']
-+
-+                    try:
-+                        ca_obj = ca_objs[cacn]
-+                    except KeyError:
-+                        ca_obj = ca_objs[cacn] = (
-+                            self.api.Command.ca_show(cacn, all=True)['result'])
-+
-+                    obj.update(ra.get_certificate(str(serial_number)))
-+                    if not raw:
-+                        obj['certificate'] = (
-+                            obj['certificate'].replace('\r\n', ''))
-+
-+                    if 'certificate_chain' in ca_obj:
-+                        cert = x509.load_certificate(obj['certificate'])
-+                        cert_der = (
-+                            cert.public_bytes(serialization.Encoding.DER))
-+                        obj['certificate_chain'] = (
-+                            [cert_der] + ca_obj['certificate_chain'])
-+
-+                if not raw:
-+                    self.obj._parse(obj, all)
-+                    self.obj._fill_owners(obj)
-+
-         result = list(six.itervalues(result))
-         if sizelimit > 0 and len(result) > sizelimit:
-             if not truncated:
-diff --git a/ipaserver/plugins/dogtag.py b/ipaserver/plugins/dogtag.py
-index d1dd707f145e0f58bfa721df55513d46c14358f2..3997531032746a22243a4219250af4172e9ae5b3 100644
---- a/ipaserver/plugins/dogtag.py
-+++ b/ipaserver/plugins/dogtag.py
-@@ -1945,6 +1945,16 @@ class ra(rabase.rabase, RestClient):
-             if len(issuer_dn) == 1:
-                 response_request['issuer'] = unicode(issuer_dn[0].text)
- 
-+            not_valid_before = cert.xpath('NotValidBefore')
-+            if len(not_valid_before) == 1:
-+                response_request['valid_not_before'] = (
-+                    unicode(not_valid_before[0].text))
-+
-+            not_valid_after = cert.xpath('NotValidAfter')
-+            if len(not_valid_after) == 1:
-+                response_request['valid_not_after'] = (
-+                    unicode(not_valid_after[0].text))
-+
-             status = cert.xpath('Status')
-             if len(status) == 1:
-                 response_request['status'] = unicode(status[0].text)
--- 
-2.12.2
-
diff --git a/SOURCES/0087-server-install-No-double-Kerberos-install.patch b/SOURCES/0087-server-install-No-double-Kerberos-install.patch
deleted file mode 100644
index 9750dd7..0000000
--- a/SOURCES/0087-server-install-No-double-Kerberos-install.patch
+++ /dev/null
@@ -1,42 +0,0 @@
-From fabf804e7351b546310cc1f50164785099ff1811 Mon Sep 17 00:00:00 2001
-From: Stanislav Laznicka <slaznick@redhat.com>
-Date: Tue, 18 Apr 2017 17:14:27 +0200
-Subject: [PATCH] server-install: No double Kerberos install
-
-When we're installing server with an external CA, the installation
-would have failed in the second step where it's passed the required
-CA cert file because it would have tried to perform the Kerberos
-installation for the second time.
-
-https://pagure.io/freeipa/issue/6757
-
-Reviewed-By: Jan Cholasta <jcholast@redhat.com>
----
- ipaserver/install/server/install.py | 11 ++++++-----
- 1 file changed, 6 insertions(+), 5 deletions(-)
-
-diff --git a/ipaserver/install/server/install.py b/ipaserver/install/server/install.py
-index b899b4be4028e6cdfd95bb9868fba8be25a07b65..b360e0532ce1b9b729be1cc2398cb2b46620901c 100644
---- a/ipaserver/install/server/install.py
-+++ b/ipaserver/install/server/install.py
-@@ -762,11 +762,12 @@ def install(installer):
-             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 not options.external_cert_files:
-+        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:
--- 
-2.12.2
-
diff --git a/SOURCES/0088-ext.-CA-correctly-write-the-cert-chain.patch b/SOURCES/0088-ext.-CA-correctly-write-the-cert-chain.patch
deleted file mode 100644
index 92d8a1c..0000000
--- a/SOURCES/0088-ext.-CA-correctly-write-the-cert-chain.patch
+++ /dev/null
@@ -1,35 +0,0 @@
-From 3ee73ed6d739a9d89dadd78f37388e8cfdba143b Mon Sep 17 00:00:00 2001
-From: Stanislav Laznicka <slaznick@redhat.com>
-Date: Tue, 18 Apr 2017 17:17:48 +0200
-Subject: [PATCH] ext. CA: correctly write the cert chain
-
-The cert file would have been rewritten all over again with
-any of the cert in the CA cert chain without this patch.
-
-https://pagure.io/freeipa/issue/6872
-
-Reviewed-By: Jan Cholasta <jcholast@redhat.com>
----
- ipaserver/install/cainstance.py | 5 +++--
- 1 file changed, 3 insertions(+), 2 deletions(-)
-
-diff --git a/ipaserver/install/cainstance.py b/ipaserver/install/cainstance.py
-index ac5d9e2fc633c5ad732670245b72bee0f03268a6..e2070e39f7e162fcff6e1f8cca41218e440b5f58 100644
---- a/ipaserver/install/cainstance.py
-+++ b/ipaserver/install/cainstance.py
-@@ -783,9 +783,10 @@ class CAInstance(DogtagInstance):
-         certlist = x509.pkcs7_to_pems(data, x509.DER)
- 
-         # We have all the certificates in certlist, write them to a PEM file
--        for cert in certlist:
--            with open(paths.IPA_CA_CRT, 'w') as ipaca_pem:
-+        with open(paths.IPA_CA_CRT, 'w') as ipaca_pem:
-+            for cert in certlist:
-                 ipaca_pem.write(cert)
-+                ipaca_pem.write('\n')
- 
-     def __request_ra_certificate(self):
-         # create a temp file storing the pwd
--- 
-2.12.2
-
diff --git a/SOURCES/0089-Fix-RA-cert-import-during-DL0-replication.patch b/SOURCES/0089-Fix-RA-cert-import-during-DL0-replication.patch
deleted file mode 100644
index 0804309..0000000
--- a/SOURCES/0089-Fix-RA-cert-import-during-DL0-replication.patch
+++ /dev/null
@@ -1,122 +0,0 @@
-From 899f9b980afba02cfdf80155905354a7371ad871 Mon Sep 17 00:00:00 2001
-From: Stanislav Laznicka <slaznick@redhat.com>
-Date: Wed, 19 Apr 2017 11:42:40 +0200
-Subject: [PATCH] Fix RA cert import during DL0 replication
-
-Previous versions of FreeIPA add password to the ra.p12 file
-contained in the password-protected tarball. This was forgotten
-about in the recent changes and fixed now.
-
-https://pagure.io/freeipa/issue/6878
-
-Reviewed-By: Jan Cholasta <jcholast@redhat.com>
----
- ipaserver/install/cainstance.py          | 43 +++++++++++++++++++-------------
- ipaserver/install/ipa_replica_prepare.py | 17 +++++++------
- 2 files changed, 35 insertions(+), 25 deletions(-)
-
-diff --git a/ipaserver/install/cainstance.py b/ipaserver/install/cainstance.py
-index e2070e39f7e162fcff6e1f8cca41218e440b5f58..640d2884130dd152012e50dde45514f5ca26a523 100644
---- a/ipaserver/install/cainstance.py
-+++ b/ipaserver/install/cainstance.py
-@@ -338,6 +338,7 @@ class CAInstance(DogtagInstance):
-             self.clone = True
-         self.master_host = master_host
-         self.master_replication_port = master_replication_port
-+        self.ra_p12 = ra_p12
- 
-         self.subject_base = \
-             subject_base or installutils.default_subject_base(self.realm)
-@@ -400,7 +401,7 @@ class CAInstance(DogtagInstance):
-                     self.step("Importing RA key", self.__import_ra_key)
-                 else:
-                     self.step("importing RA certificate from PKCS #12 file",
--                              lambda: self.import_ra_cert(ra_p12))
-+                              self.__import_ra_cert)
- 
-             if not ra_only:
-                 self.step("setting up signing cert profile", self.__setup_sign_profile)
-@@ -673,28 +674,36 @@ class CAInstance(DogtagInstance):
-                                    'NSS_ENABLE_PKIX_VERIFY', '1',
-                                    quotes=False, separator='=')
- 
--    def import_ra_cert(self, rafile):
-+    def __import_ra_cert(self):
-+        """
-+        Helper method for IPA domain level 0 replica install
-+        """
-+        self.import_ra_cert(self.ra_p12, self.dm_password)
-+
-+    def import_ra_cert(self, rafile, password=''):
-         """
-         Cloned RAs will use the same RA agent cert as the master so we
-         need to import from a PKCS#12 file.
- 
-         Used when setting up replication
-         """
--        # get the private key from the file
--        ipautil.run([paths.OPENSSL,
--                     "pkcs12",
--                     "-in", rafile,
--                     "-nocerts", "-nodes",
--                     "-out", paths.RA_AGENT_KEY,
--                     "-passin", "pass:"])
--
--        # get the certificate from the pkcs12 file
--        ipautil.run([paths.OPENSSL,
--                     "pkcs12",
--                     "-in", rafile,
--                     "-clcerts", "-nokeys",
--                     "-out", paths.RA_AGENT_PEM,
--                     "-passin", "pass:"])
-+        with ipautil.write_tmp_file(password) as f:
-+            pwdarg = 'file:{file}'.format(file=f.name)
-+            # get the private key from the file
-+            ipautil.run([paths.OPENSSL,
-+                         "pkcs12",
-+                         "-in", rafile,
-+                         "-nocerts", "-nodes",
-+                         "-out", paths.RA_AGENT_KEY,
-+                         "-passin", pwdarg])
-+
-+            # get the certificate from the pkcs12 file
-+            ipautil.run([paths.OPENSSL,
-+                         "pkcs12",
-+                         "-in", rafile,
-+                         "-clcerts", "-nokeys",
-+                         "-out", paths.RA_AGENT_PEM,
-+                         "-passin", pwdarg])
-         self.__set_ra_cert_perms()
- 
-         self.configure_agent_renewal()
-diff --git a/ipaserver/install/ipa_replica_prepare.py b/ipaserver/install/ipa_replica_prepare.py
-index 95c3818a9fc34c937f8b418e91a1bfc28352b02e..d4456dd796167c3717be013d2378413519a3b366 100644
---- a/ipaserver/install/ipa_replica_prepare.py
-+++ b/ipaserver/install/ipa_replica_prepare.py
-@@ -571,14 +571,15 @@ class ReplicaPrepare(admintool.AdminTool):
-     def export_ra_pkcs12(self):
-         if (os.path.exists(paths.RA_AGENT_PEM) and
-            os.path.exists(paths.RA_AGENT_KEY)):
--            ipautil.run([
--                paths.OPENSSL,
--                "pkcs12", "-export",
--                "-inkey", paths.RA_AGENT_KEY,
--                "-in", paths.RA_AGENT_PEM,
--                "-out", os.path.join(self.dir, "ra.p12"),
--                "-passout", "pass:"
--            ])
-+            with ipautil.write_tmp_file(self.dirman_password) as f:
-+                ipautil.run([
-+                    paths.OPENSSL,
-+                    "pkcs12", "-export",
-+                    "-inkey", paths.RA_AGENT_KEY,
-+                    "-in", paths.RA_AGENT_PEM,
-+                    "-out", os.path.join(self.dir, "ra.p12"),
-+                    "-passout", "file:{pwfile}".format(pwfile=f.name)
-+                ])
- 
-     def update_pki_admin_password(self):
-         dn = DN('uid=admin', 'ou=people', 'o=ipaca')
--- 
-2.12.2
-
diff --git a/SOURCES/0090-configure-fix-AC_CHECK_LIB-usage.patch b/SOURCES/0090-configure-fix-AC_CHECK_LIB-usage.patch
deleted file mode 100644
index edc2836..0000000
--- a/SOURCES/0090-configure-fix-AC_CHECK_LIB-usage.patch
+++ /dev/null
@@ -1,64 +0,0 @@
-From 03750b1c1ba8ed670691e4e464d110b9329d85be Mon Sep 17 00:00:00 2001
-From: Jan Cholasta <jcholast@redhat.com>
-Date: Wed, 5 Apr 2017 10:24:17 +0000
-Subject: [PATCH] configure: fix AC_CHECK_LIB usage
-
-Replace empty string with a single space in the third argument of
-`AC_CHECK_LIB` (`action-if-found`) where applicable.
-
-Empty string in the argument causes `AC_CHECK_LIB` to use the default
-action when a library is found which includes adding the library to `LIBS`,
-which specifies libraries to be linked in every binary and library in the
-project.
-
-This fixes libkrad, liblber, libldap_r and libsss_nss_idmap being linked to
-every binary and library in IPA, even where unused.
-
-https://pagure.io/freeipa/issue/6846
-
-Reviewed-By: Stanislav Laznicka <slaznick@redhat.com>
----
- configure.ac | 4 ++--
- server.m4    | 4 ++--
- 2 files changed, 4 insertions(+), 4 deletions(-)
-
-diff --git a/configure.ac b/configure.ac
-index ded1d71fd079a5f6947ef0627fb699783c8cc109..e31a9849c4c0556833f5cd47104381d006c96eef 100644
---- a/configure.ac
-+++ b/configure.ac
-@@ -86,8 +86,8 @@ dnl ---------------------------------------------------------------------------
- 
- SAVE_CPPFLAGS=$CPPFLAGS
- CPPFLAGS="$NSPR_CFLAGS $NSS_CFLAGS"
--AC_CHECK_LIB([ldap_r], [ldap_search], [], AC_MSG_ERROR([libldap_r not found]))
--AC_CHECK_LIB([lber], [ber_peek_tag], [], AC_MSG_ERROR([liblber not found]))
-+AC_CHECK_LIB([ldap_r], [ldap_search], [ ], AC_MSG_ERROR([libldap_r not found]))
-+AC_CHECK_LIB([lber], [ber_peek_tag], [ ], AC_MSG_ERROR([liblber not found]))
- LDAP_LIBS="-lldap_r -llber"
- LDAP_CFLAGS=""
- AC_SUBST(LDAP_LIBS)
-diff --git a/server.m4 b/server.m4
-index 346d73e906c5d0499e46fcc4da070007b2ff5973..aa784e096299d5a6cc599a0d6a0652168f9bafbc 100644
---- a/server.m4
-+++ b/server.m4
-@@ -31,7 +31,7 @@ PKG_CHECK_MODULES([SSSIDMAP], [sss_idmap])
- PKG_CHECK_MODULES([SSSNSSIDMAP], [sss_nss_idmap >= 1.15.2])
- AC_CHECK_LIB([sss_nss_idmap],
-              [sss_nss_getlistbycert],
--             [],
-+             [ ],
-              [AC_MSG_ERROR([Required sss_nss_getlistbycert symbol in sss_nss_idmap not found])],
-              [])
- 
-@@ -48,7 +48,7 @@ dnl - Check for KRB5 krad
- dnl ---------------------------------------------------------------------------
- 
- AC_CHECK_HEADER(krad.h, [], [AC_MSG_ERROR([krad.h not found])])
--AC_CHECK_LIB(krad, main, [], [AC_MSG_ERROR([libkrad not found])])
-+AC_CHECK_LIB(krad, main, [ ], [AC_MSG_ERROR([libkrad not found])])
- KRAD_LIBS="-lkrad"
- krb5rundir="${localstatedir}/run/krb5kdc"
- AC_SUBST(KRAD_LIBS)
--- 
-2.12.2
-
diff --git a/SOURCES/0091-Fix-CAInstance.import_ra_cert-for-empty-passwords.patch b/SOURCES/0091-Fix-CAInstance.import_ra_cert-for-empty-passwords.patch
deleted file mode 100644
index cc63d38..0000000
--- a/SOURCES/0091-Fix-CAInstance.import_ra_cert-for-empty-passwords.patch
+++ /dev/null
@@ -1,30 +0,0 @@
-From 61b5a76bcd856d679f05c5f5f12f770cc6826783 Mon Sep 17 00:00:00 2001
-From: Stanislav Laznicka <slaznick@redhat.com>
-Date: Thu, 20 Apr 2017 10:09:05 +0200
-Subject: [PATCH] Fix CAInstance.import_ra_cert for empty passwords
-
-OpenSSL can't cope with empty files, add a newline after each password
-
-https://pagure.io/freeipa/issue/6878
-
-Reviewed-By: Jan Cholasta <jcholast@redhat.com>
----
- ipaserver/install/cainstance.py | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/ipaserver/install/cainstance.py b/ipaserver/install/cainstance.py
-index 640d2884130dd152012e50dde45514f5ca26a523..0672bccf79d7cc6133fdb20f0854366306bfc2e0 100644
---- a/ipaserver/install/cainstance.py
-+++ b/ipaserver/install/cainstance.py
-@@ -687,7 +687,7 @@ class CAInstance(DogtagInstance):
- 
-         Used when setting up replication
-         """
--        with ipautil.write_tmp_file(password) as f:
-+        with ipautil.write_tmp_file(password + '\n') as f:
-             pwdarg = 'file:{file}'.format(file=f.name)
-             # get the private key from the file
-             ipautil.run([paths.OPENSSL,
--- 
-2.12.2
-
diff --git a/SOURCES/0092-upgrade-adtrust-update_tdo_gidnumber-plugin-must-che.patch b/SOURCES/0092-upgrade-adtrust-update_tdo_gidnumber-plugin-must-che.patch
deleted file mode 100644
index 8d8b44a..0000000
--- a/SOURCES/0092-upgrade-adtrust-update_tdo_gidnumber-plugin-must-che.patch
+++ /dev/null
@@ -1,37 +0,0 @@
-From f50331d2f9f34ae17a3d5323e74982ca87eba12e Mon Sep 17 00:00:00 2001
-From: Florence Blanc-Renaud <flo@redhat.com>
-Date: Thu, 20 Apr 2017 16:31:53 +0200
-Subject: [PATCH] upgrade: adtrust update_tdo_gidnumber plugin must check if
- adtrust is installed
-
-During upgrade, the plugin update_tdo_gidnumber is launched in order to
-add a gidnumber to the Trusted Domain Object.
-This plugin should not be run when ad trust is not installed, otherwise an
-error message is displayed.
-
-https://pagure.io/freeipa/issue/6881
-
-Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
----
- ipaserver/install/plugins/adtrust.py | 5 +++++
- 1 file changed, 5 insertions(+)
-
-diff --git a/ipaserver/install/plugins/adtrust.py b/ipaserver/install/plugins/adtrust.py
-index 075f197780edc2aadf42fa82b71e9e2b29e66ea9..a72af00635649ddf54640738c2f28cb09c7e91bb 100644
---- a/ipaserver/install/plugins/adtrust.py
-+++ b/ipaserver/install/plugins/adtrust.py
-@@ -329,6 +329,11 @@ class update_tdo_gidnumber(Updater):
-     def execute(self, **options):
-         ldap = self.api.Backend.ldap2
- 
-+        # First, see if trusts are enabled on the server
-+        if not self.api.Command.adtrust_is_enabled()['result']:
-+            self.log.debug('AD Trusts are not enabled on this server')
-+            return False, []
-+
-         # Read the gidnumber of the fallback group
-         dn = DN(('cn', ADTRUSTInstance.FALLBACK_GROUP_NAME),
-                 self.api.env.container_group,
--- 
-2.12.2
-
diff --git a/SOURCES/0093-compat-manage-behave-the-same-for-all-users.patch b/SOURCES/0093-compat-manage-behave-the-same-for-all-users.patch
deleted file mode 100644
index 0729953..0000000
--- a/SOURCES/0093-compat-manage-behave-the-same-for-all-users.patch
+++ /dev/null
@@ -1,34 +0,0 @@
-From 03b605a70c8f5a6def7a572ceb302051934c78e7 Mon Sep 17 00:00:00 2001
-From: Stanislav Laznicka <slaznick@redhat.com>
-Date: Fri, 21 Apr 2017 09:32:34 +0200
-Subject: [PATCH] compat-manage: behave the same for all users
-
-Due to LDAP connection refactoring, compat-manage would have behaved
-differently for root and for other users even though it requires
-the directory manager password. This is caused by it trying to do
-external bind when it does not have the DIRMAN password which was
-previously not supplied.
-
-https://pagure.io/freeipa/issue/6821
-
-Reviewed-By: Martin Basti <mbasti@redhat.com>
----
- install/tools/ipa-compat-manage | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/install/tools/ipa-compat-manage b/install/tools/ipa-compat-manage
-index a29a92fabd653bb983778420cca0983048ee39ef..6dd259d2aad870e575093d6732157de743502ac2 100755
---- a/install/tools/ipa-compat-manage
-+++ b/install/tools/ipa-compat-manage
-@@ -105,7 +105,7 @@ def main():
-                   debug=options.debug,
-                   confdir=paths.ETC_IPA)
-     api.finalize()
--    api.Backend.ldap2.connect()
-+    api.Backend.ldap2.connect(bind_pw=dirman_password)
- 
-     if args[0] == "status":
-         entry = None
--- 
-2.12.2
-
diff --git a/SOURCES/0094-Move-the-compat-plugin-setup-at-the-end-of-install.patch b/SOURCES/0094-Move-the-compat-plugin-setup-at-the-end-of-install.patch
deleted file mode 100644
index 2a1fcb9..0000000
--- a/SOURCES/0094-Move-the-compat-plugin-setup-at-the-end-of-install.patch
+++ /dev/null
@@ -1,317 +0,0 @@
-From f0bd45fb0c1071006887dc10abac233d2756d951 Mon Sep 17 00:00:00 2001
-From: Stanislav Laznicka <slaznick@redhat.com>
-Date: Thu, 13 Apr 2017 09:15:47 +0200
-Subject: [PATCH] Move the compat plugin setup at the end of install
-
-The compat plugin was causing deadlocks with the topology plugin. Move
-its setup at the end of the installation and remove the
-cn=topology,cn=ipa,cn=etc subtree from its scope.
-
-https://pagure.io/freeipa/issue/6821
-
-Reviewed-By: Martin Basti <mbasti@redhat.com>
----
- install/share/Makefile.am                          |  1 -
- install/updates/10-schema_compat.update            | 93 ---------------------
- .../80-schema_compat.update}                       | 96 +++++++++++++++++++++-
- install/updates/Makefile.am                        |  2 +-
- ipaplatform/base/paths.py                          |  3 +-
- ipaserver/install/dsinstance.py                    |  9 --
- 6 files changed, 98 insertions(+), 106 deletions(-)
- delete mode 100644 install/updates/10-schema_compat.update
- rename install/{share/schema_compat.uldif => updates/80-schema_compat.update} (55%)
-
-diff --git a/install/share/Makefile.am b/install/share/Makefile.am
-index 9e539a3f30c2979de26575ba66bbb23fecd03a88..b27861da37153d77d693ce6e46340525bbd50173 100644
---- a/install/share/Makefile.am
-+++ b/install/share/Makefile.am
-@@ -65,7 +65,6 @@ dist_app_DATA =				\
- 	opendnssec_conf.template	\
- 	opendnssec_kasp.template	\
- 	unique-attributes.ldif		\
--	schema_compat.uldif		\
- 	ldapi.ldif			\
- 	wsgi.py				\
- 	repoint-managed-entries.ldif	\
-diff --git a/install/updates/10-schema_compat.update b/install/updates/10-schema_compat.update
-deleted file mode 100644
-index fbe8703407aacd75baf160630c20835a1b4ddc65..0000000000000000000000000000000000000000
---- a/install/updates/10-schema_compat.update
-+++ /dev/null
-@@ -1,93 +0,0 @@
--dn: cn=sudoers,cn=Schema Compatibility,cn=plugins,cn=config
--only:schema-compat-entry-rdn:%ifeq("ipaEnabledFlag", "FALSE", "DISABLED", "cn=%{cn}")
--add:schema-compat-entry-attribute: sudoHost=%ifeq("hostCategory","all","ALL","%{hostMask}")
--add:schema-compat-entry-attribute: sudoRunAsUser=%%%{ipaSudoRunAsExtUserGroup}
--# Fix for #4324 (regression of #1309)
--remove:schema-compat-entry-attribute:sudoRunAsGroup=%deref("ipaSudoRunAs","cn")
--remove:schema-compat-entry-attribute:sudoRunAsUser=%{ipaSudoRunAsExtUser}
--remove:schema-compat-entry-attribute:sudoRunAsUser=%%%{ipaSudoRunAsExtUserGroup}
--remove:schema-compat-entry-attribute:sudoRunAsUser=%deref("ipaSudoRunAs","uid")
--remove:schema-compat-entry-attribute:sudoRunAsGroup=%{ipaSudoRunAsExtGroup}
--remove:schema-compat-entry-attribute:sudoRunAsGroup=%deref_f("ipaSudoRunAsGroup","(objectclass=posixGroup)","cn")
--
--# We need to add the value in a separate transaction
--dn: cn=sudoers,cn=Schema Compatibility,cn=plugins,cn=config
--add: schema-compat-entry-attribute: sudoRunAsGroup=%deref_f("ipaSudoRunAsGroup","(objectclass=posixGroup)","cn")
--add: schema-compat-entry-attribute: sudoRunAsUser=%ifeq("ipaSudoRunAsUserCategory","all","ALL","%{ipaSudoRunAsExtUser}")
--add: schema-compat-entry-attribute: sudoRunAsUser=%ifeq("ipaSudoRunAsUserCategory","all","ALL","%%%{ipaSudoRunAsExtUserGroup}")
--add: schema-compat-entry-attribute: sudoRunAsUser=%ifeq("ipaSudoRunAsUserCategory","all","ALL","%deref_f(\"ipaSudoRunAs\",\"(objectclass=posixAccount)\",\"uid\")")
--add: schema-compat-entry-attribute: sudoRunAsGroup=%ifeq("ipaSudoRunAsGroupCategory","all","ALL","%{ipaSudoRunAsExtGroup}")
--add: schema-compat-entry-attribute: sudoRunAsGroup=%ifeq("ipaSudoRunAsGroupCategory","all","ALL","%deref_f(\"ipaSudoRunAsGroup\",\"(objectclass=posixGroup)\",\"cn\")")
--remove: schema-compat-ignore-subtree: cn=changelog
--remove: schema-compat-ignore-subtree: o=ipaca
--add: schema-compat-restrict-subtree: $SUFFIX
--add: schema-compat-restrict-subtree: cn=Schema Compatibility,cn=plugins,cn=config
--add: schema-compat-ignore-subtree: cn=dna,cn=ipa,cn=etc,$SUFFIX
--
--# Change padding for host and userCategory so the pad returns the same value
--# as the original, '' or -.
--dn: cn=ng,cn=Schema Compatibility,cn=plugins,cn=config
--replace: schema-compat-entry-attribute:nisNetgroupTriple=(%link("%ifeq(\"hostCategory\",\"all\",\"\",\"%collect(\\\"%{externalHost}\\\",\\\"%deref(\\\\\\\"memberHost\\\\\\\",\\\\\\\"fqdn\\\\\\\")\\\",\\\"%deref_r(\\\\\\\"member\\\\\\\",\\\\\\\"fqdn\\\\\\\")\\\",\\\"%deref_r(\\\\\\\"memberHost\\\\\\\",\\\\\\\"member\\\\\\\",\\\\\\\"fqdn\\\\\\\")\\\")\")","-",",","%ifeq(\"userCategory\",\"all\",\"\",\"%collect(\\\"%deref(\\\\\\\"memberUser\\\\\\\",\\\\\\\"uid\\\\\\\")\\\",\\\"%deref_r(\\\\\\\"member\\\\\\\",\\\\\\\"uid\\\\\\\")\\\",\\\"%deref_r(\\\\\\\"memberUser\\\\\\\",\\\\\\\"member\\\\\\\",\\\\\\\"uid\\\\\\\")\\\")\")","-"),%{nisDomainName:-})::nisNetgroupTriple=(%link("%ifeq(\"hostCategory\",\"all\",\"\",\"%collect(\\\"%{externalHost}\\\",\\\"%deref(\\\\\\\"memberHost\\\\\\\",\\\\\\\"fqdn\\\\\\\")\\\",\\\"%deref_r(\\\\\\\"member\\\\\\\",\\\\\\\"fqdn\\\\\\\")\\\",\\\"%deref_r(\\\\\\\"memberHost\\\\\\\",\\\\\\\"member\\\\\\\",\\\\\\\"fqdn\\\\\\\")\\\")\")","%ifeq(\"hostCategory\",\"all\",\"\",\"-\")",",","%ifeq(\"userCategory\",\"all\",\"\",\"%collect(\\\"%deref(\\\\\\\"memberUser\\\\\\\",\\\\\\\"uid\\\\\\\")\\\",\\\"%deref_r(\\\\\\\"member\\\\\\\",\\\\\\\"uid\\\\\\\")\\\",\\\"%deref_r(\\\\\\\"memberUser\\\\\\\",\\\\\\\"member\\\\\\\",\\\\\\\"uid\\\\\\\")\\\")\")","%ifeq(\"userCategory\",\"all\",\"\",\"-\")"),%{nisDomainName:-})
--remove: schema-compat-ignore-subtree: cn=changelog
--remove: schema-compat-ignore-subtree: o=ipaca
--add: schema-compat-restrict-subtree: $SUFFIX
--add: schema-compat-restrict-subtree: cn=Schema Compatibility,cn=plugins,cn=config
--add: schema-compat-ignore-subtree: cn=dna,cn=ipa,cn=etc,$SUFFIX
--
--dn: cn=computers, cn=Schema Compatibility, cn=plugins, cn=config
--default:objectClass: top
--default:objectClass: extensibleObject
--default:cn: computers
--default:schema-compat-container-group: cn=compat, $SUFFIX
--default:schema-compat-container-rdn: cn=computers
--default:schema-compat-search-base: cn=computers, cn=accounts, $SUFFIX
--default:schema-compat-search-filter: (&(macAddress=*)(fqdn=*)(objectClass=ipaHost))
--default:schema-compat-entry-rdn: cn=%first("%{fqdn}")
--default:schema-compat-entry-attribute: objectclass=device
--default:schema-compat-entry-attribute: objectclass=ieee802Device
--default:schema-compat-entry-attribute: cn=%{fqdn}
--default:schema-compat-entry-attribute: macAddress=%{macAddress}
--remove: schema-compat-ignore-subtree: cn=changelog
--remove: schema-compat-ignore-subtree: o=ipaca
--add: schema-compat-restrict-subtree: $SUFFIX
--add: schema-compat-restrict-subtree: cn=Schema Compatibility,cn=plugins,cn=config
--add: schema-compat-ignore-subtree: cn=dna,cn=ipa,cn=etc,$SUFFIX
--
--dn: cn=sudoers,cn=Schema Compatibility,cn=plugins,cn=config
--add:schema-compat-entry-attribute: sudoOrder=%{sudoOrder}
--
--dn: cn=users,cn=Schema Compatibility,cn=plugins,cn=config
--remove: schema-compat-ignore-subtree: cn=changelog
--remove: schema-compat-ignore-subtree: o=ipaca
--add: schema-compat-restrict-subtree: $SUFFIX
--add: schema-compat-restrict-subtree: cn=Schema Compatibility,cn=plugins,cn=config
--add: schema-compat-ignore-subtree: cn=dna,cn=ipa,cn=etc,$SUFFIX
--
--dn: cn=groups,cn=Schema Compatibility,cn=plugins,cn=config
--remove: schema-compat-ignore-subtree: cn=changelog
--remove: schema-compat-ignore-subtree: o=ipaca
--add: schema-compat-restrict-subtree: $SUFFIX
--add: schema-compat-restrict-subtree: cn=Schema Compatibility,cn=plugins,cn=config
--add: schema-compat-ignore-subtree: cn=dna,cn=ipa,cn=etc,$SUFFIX
--
--dn: cn=Schema Compatibility,cn=plugins,cn=config
--# We need to run schema-compat pre-bind callback before
--# other IPA pre-bind callbacks to make sure bind DN is
--# rewritten to the original entry if needed
--add:nsslapd-pluginprecedence: 40
--
--dn: cn=users,cn=Schema Compatibility,cn=plugins,cn=config
--add:schema-compat-entry-attribute: %ifeq("ipauniqueid","%{ipauniqueid}","objectclass=ipaOverrideTarget","")
--add:schema-compat-entry-attribute: %ifeq("ipauniqueid","%{ipauniqueid}","ipaanchoruuid=:IPA:$DOMAIN:%{ipauniqueid}","")
--add:schema-compat-entry-attribute: ipaanchoruuid=%{ipaanchoruuid}
--add:schema-compat-entry-attribute: %ifeq("ipaanchoruuid","%{ipaanchoruuid}","objectclass=ipaOverrideTarget","")
--
--dn: cn=groups,cn=Schema Compatibility,cn=plugins,cn=config
--add:schema-compat-entry-attribute: %ifeq("ipauniqueid","%{ipauniqueid}","objectclass=ipaOverrideTarget","")
--add:schema-compat-entry-attribute: %ifeq("ipauniqueid","%{ipauniqueid}","ipaanchoruuid=:IPA:$DOMAIN:%{ipauniqueid}","")
--add:schema-compat-entry-attribute: ipaanchoruuid=%{ipaanchoruuid}
--add:schema-compat-entry-attribute: %ifeq("ipaanchoruuid","%{ipaanchoruuid}","objectclass=ipaOverrideTarget","")
--
--dn: cn=users,cn=Schema Compatibility,cn=plugins,cn=config
--add:schema-compat-entry-attribute: uid=%{uid}
--replace:schema-compat-entry-rdn: uid=%{uid}::uid=%first("%{uid}")
-diff --git a/install/share/schema_compat.uldif b/install/updates/80-schema_compat.update
-similarity index 55%
-rename from install/share/schema_compat.uldif
-rename to install/updates/80-schema_compat.update
-index 66f8ea1c31bc534b3ee134c6df6132f4318c81fc..06cbcab8ad809d95a907c161044ff91df827ebf3 100644
---- a/install/share/schema_compat.uldif
-+++ b/install/updates/80-schema_compat.update
-@@ -1,5 +1,6 @@
- #
--# Enable the Schema Compatibility plugin provided by slapi-nis.
-+# Setup the Schema Compatibility plugin provided by slapi-nis.
-+# This should be done after all other updates have been applied
- #
- # http://slapi-nis.fedorahosted.org/
- #
-@@ -126,3 +127,96 @@ default:schema-compat-entry-attribute: macAddress=%{macAddress}
- dn: oid=2.16.840.1.113730.3.4.9,cn=features,cn=config
- only:aci: (targetattr !="aci")(version 3.0; acl "VLV Request Control"; allow (read, search, compare, proxy) userdn = "ldap:///anyone"; )
- 
-+dn: cn=sudoers,cn=Schema Compatibility,cn=plugins,cn=config
-+only:schema-compat-entry-rdn:%ifeq("ipaEnabledFlag", "FALSE", "DISABLED", "cn=%{cn}")
-+add:schema-compat-entry-attribute: sudoHost=%ifeq("hostCategory","all","ALL","%{hostMask}")
-+add:schema-compat-entry-attribute: sudoRunAsUser=%%%{ipaSudoRunAsExtUserGroup}
-+# Fix for #4324 (regression of #1309)
-+remove:schema-compat-entry-attribute:sudoRunAsGroup=%deref("ipaSudoRunAs","cn")
-+remove:schema-compat-entry-attribute:sudoRunAsUser=%{ipaSudoRunAsExtUser}
-+remove:schema-compat-entry-attribute:sudoRunAsUser=%%%{ipaSudoRunAsExtUserGroup}
-+remove:schema-compat-entry-attribute:sudoRunAsUser=%deref("ipaSudoRunAs","uid")
-+remove:schema-compat-entry-attribute:sudoRunAsGroup=%{ipaSudoRunAsExtGroup}
-+remove:schema-compat-entry-attribute:sudoRunAsGroup=%deref_f("ipaSudoRunAsGroup","(objectclass=posixGroup)","cn")
-+
-+# We need to add the value in a separate transaction
-+dn: cn=sudoers,cn=Schema Compatibility,cn=plugins,cn=config
-+add: schema-compat-entry-attribute: sudoRunAsGroup=%deref_f("ipaSudoRunAsGroup","(objectclass=posixGroup)","cn")
-+add: schema-compat-entry-attribute: sudoRunAsUser=%ifeq("ipaSudoRunAsUserCategory","all","ALL","%{ipaSudoRunAsExtUser}")
-+add: schema-compat-entry-attribute: sudoRunAsUser=%ifeq("ipaSudoRunAsUserCategory","all","ALL","%%%{ipaSudoRunAsExtUserGroup}")
-+add: schema-compat-entry-attribute: sudoRunAsUser=%ifeq("ipaSudoRunAsUserCategory","all","ALL","%deref_f(\"ipaSudoRunAs\",\"(objectclass=posixAccount)\",\"uid\")")
-+add: schema-compat-entry-attribute: sudoRunAsGroup=%ifeq("ipaSudoRunAsGroupCategory","all","ALL","%{ipaSudoRunAsExtGroup}")
-+add: schema-compat-entry-attribute: sudoRunAsGroup=%ifeq("ipaSudoRunAsGroupCategory","all","ALL","%deref_f(\"ipaSudoRunAsGroup\",\"(objectclass=posixGroup)\",\"cn\")")
-+remove: schema-compat-ignore-subtree: cn=changelog
-+remove: schema-compat-ignore-subtree: o=ipaca
-+add: schema-compat-restrict-subtree: $SUFFIX
-+add: schema-compat-restrict-subtree: cn=Schema Compatibility,cn=plugins,cn=config
-+add: schema-compat-ignore-subtree: cn=dna,cn=ipa,cn=etc,$SUFFIX
-+
-+# Change padding for host and userCategory so the pad returns the same value
-+# as the original, '' or -.
-+dn: cn=ng,cn=Schema Compatibility,cn=plugins,cn=config
-+replace: schema-compat-entry-attribute:nisNetgroupTriple=(%link("%ifeq(\"hostCategory\",\"all\",\"\",\"%collect(\\\"%{externalHost}\\\",\\\"%deref(\\\\\\\"memberHost\\\\\\\",\\\\\\\"fqdn\\\\\\\")\\\",\\\"%deref_r(\\\\\\\"member\\\\\\\",\\\\\\\"fqdn\\\\\\\")\\\",\\\"%deref_r(\\\\\\\"memberHost\\\\\\\",\\\\\\\"member\\\\\\\",\\\\\\\"fqdn\\\\\\\")\\\")\")","-",",","%ifeq(\"userCategory\",\"all\",\"\",\"%collect(\\\"%deref(\\\\\\\"memberUser\\\\\\\",\\\\\\\"uid\\\\\\\")\\\",\\\"%deref_r(\\\\\\\"member\\\\\\\",\\\\\\\"uid\\\\\\\")\\\",\\\"%deref_r(\\\\\\\"memberUser\\\\\\\",\\\\\\\"member\\\\\\\",\\\\\\\"uid\\\\\\\")\\\")\")","-"),%{nisDomainName:-})::nisNetgroupTriple=(%link("%ifeq(\"hostCategory\",\"all\",\"\",\"%collect(\\\"%{externalHost}\\\",\\\"%deref(\\\\\\\"memberHost\\\\\\\",\\\\\\\"fqdn\\\\\\\")\\\",\\\"%deref_r(\\\\\\\"member\\\\\\\",\\\\\\\"fqdn\\\\\\\")\\\",\\\"%deref_r(\\\\\\\"memberHost\\\\\\\",\\\\\\\"member\\\\\\\",\\\\\\\"fqdn\\\\\\\")\\\")\")","%ifeq(\"hostCategory\",\"all\",\"\",\"-\")",",","%ifeq(\"userCategory\",\"all\",\"\",\"%collect(\\\"%deref(\\\\\\\"memberUser\\\\\\\",\\\\\\\"uid\\\\\\\")\\\",\\\"%deref_r(\\\\\\\"member\\\\\\\",\\\\\\\"uid\\\\\\\")\\\",\\\"%deref_r(\\\\\\\"memberUser\\\\\\\",\\\\\\\"member\\\\\\\",\\\\\\\"uid\\\\\\\")\\\")\")","%ifeq(\"userCategory\",\"all\",\"\",\"-\")"),%{nisDomainName:-})
-+remove: schema-compat-ignore-subtree: cn=changelog
-+remove: schema-compat-ignore-subtree: o=ipaca
-+add: schema-compat-restrict-subtree: $SUFFIX
-+add: schema-compat-restrict-subtree: cn=Schema Compatibility,cn=plugins,cn=config
-+add: schema-compat-ignore-subtree: cn=dna,cn=ipa,cn=etc,$SUFFIX
-+
-+dn: cn=computers, cn=Schema Compatibility, cn=plugins, cn=config
-+default:objectClass: top
-+default:objectClass: extensibleObject
-+default:cn: computers
-+default:schema-compat-container-group: cn=compat, $SUFFIX
-+default:schema-compat-container-rdn: cn=computers
-+default:schema-compat-search-base: cn=computers, cn=accounts, $SUFFIX
-+default:schema-compat-search-filter: (&(macAddress=*)(fqdn=*)(objectClass=ipaHost))
-+default:schema-compat-entry-rdn: cn=%first("%{fqdn}")
-+default:schema-compat-entry-attribute: objectclass=device
-+default:schema-compat-entry-attribute: objectclass=ieee802Device
-+default:schema-compat-entry-attribute: cn=%{fqdn}
-+default:schema-compat-entry-attribute: macAddress=%{macAddress}
-+remove: schema-compat-ignore-subtree: cn=changelog
-+remove: schema-compat-ignore-subtree: o=ipaca
-+add: schema-compat-restrict-subtree: $SUFFIX
-+add: schema-compat-restrict-subtree: cn=Schema Compatibility,cn=plugins,cn=config
-+add: schema-compat-ignore-subtree: cn=dna,cn=ipa,cn=etc,$SUFFIX
-+
-+dn: cn=sudoers,cn=Schema Compatibility,cn=plugins,cn=config
-+add:schema-compat-entry-attribute: sudoOrder=%{sudoOrder}
-+
-+dn: cn=users,cn=Schema Compatibility,cn=plugins,cn=config
-+remove: schema-compat-ignore-subtree: cn=changelog
-+remove: schema-compat-ignore-subtree: o=ipaca
-+add: schema-compat-restrict-subtree: $SUFFIX
-+add: schema-compat-restrict-subtree: cn=Schema Compatibility,cn=plugins,cn=config
-+add: schema-compat-ignore-subtree: cn=dna,cn=ipa,cn=etc,$SUFFIX
-+
-+dn: cn=groups,cn=Schema Compatibility,cn=plugins,cn=config
-+remove: schema-compat-ignore-subtree: cn=changelog
-+remove: schema-compat-ignore-subtree: o=ipaca
-+add: schema-compat-restrict-subtree: $SUFFIX
-+add: schema-compat-restrict-subtree: cn=Schema Compatibility,cn=plugins,cn=config
-+add: schema-compat-ignore-subtree: cn=dna,cn=ipa,cn=etc,$SUFFIX
-+
-+dn: cn=Schema Compatibility,cn=plugins,cn=config
-+# We need to run schema-compat pre-bind callback before
-+# other IPA pre-bind callbacks to make sure bind DN is
-+# rewritten to the original entry if needed
-+add:nsslapd-pluginprecedence: 40
-+
-+dn: cn=users,cn=Schema Compatibility,cn=plugins,cn=config
-+add:schema-compat-entry-attribute: %ifeq("ipauniqueid","%{ipauniqueid}","objectclass=ipaOverrideTarget","")
-+add:schema-compat-entry-attribute: %ifeq("ipauniqueid","%{ipauniqueid}","ipaanchoruuid=:IPA:$DOMAIN:%{ipauniqueid}","")
-+add:schema-compat-entry-attribute: ipaanchoruuid=%{ipaanchoruuid}
-+add:schema-compat-entry-attribute: %ifeq("ipaanchoruuid","%{ipaanchoruuid}","objectclass=ipaOverrideTarget","")
-+
-+dn: cn=groups,cn=Schema Compatibility,cn=plugins,cn=config
-+add:schema-compat-entry-attribute: %ifeq("ipauniqueid","%{ipauniqueid}","objectclass=ipaOverrideTarget","")
-+add:schema-compat-entry-attribute: %ifeq("ipauniqueid","%{ipauniqueid}","ipaanchoruuid=:IPA:$DOMAIN:%{ipauniqueid}","")
-+add:schema-compat-entry-attribute: ipaanchoruuid=%{ipaanchoruuid}
-+add:schema-compat-entry-attribute: %ifeq("ipaanchoruuid","%{ipaanchoruuid}","objectclass=ipaOverrideTarget","")
-+
-+dn: cn=users,cn=Schema Compatibility,cn=plugins,cn=config
-+add:schema-compat-entry-attribute: uid=%{uid}
-+replace:schema-compat-entry-rdn: uid=%{uid}::uid=%first("%{uid}")
-diff --git a/install/updates/Makefile.am b/install/updates/Makefile.am
-index 0ff0edb93abf4c4656b7504bd9ce8f774918fc2d..e18d01127b592a6c7941729d6160d10fb2d3e76c 100644
---- a/install/updates/Makefile.am
-+++ b/install/updates/Makefile.am
-@@ -9,7 +9,6 @@ app_DATA =				\
- 	10-selinuxusermap.update	\
- 	10-rootdse.update		\
- 	10-uniqueness.update		\
--	10-schema_compat.update		\
- 	19-managed-entries.update	\
- 	20-aci.update			\
- 	20-dna.update			\
-@@ -62,6 +61,7 @@ app_DATA =				\
- 	73-custodia.update		\
- 	73-winsync.update		\
- 	73-certmap.update		\
-+	80-schema_compat.update \
- 	90-post_upgrade_plugins.update	\
- 	$(NULL)
- 
-diff --git a/ipaplatform/base/paths.py b/ipaplatform/base/paths.py
-index 9cf160fac483157b508dedac7a5fc26cb12c63a4..dbdd71ed0b4d69c1101db4aeb7d93152ab8aa730 100644
---- a/ipaplatform/base/paths.py
-+++ b/ipaplatform/base/paths.py
-@@ -236,7 +236,8 @@ class BasePathNamespace(object):
-     HTML_KRBREALM_CON = "/usr/share/ipa/html/krbrealm.con"
-     NIS_ULDIF = "/usr/share/ipa/nis.uldif"
-     NIS_UPDATE_ULDIF = "/usr/share/ipa/nis-update.uldif"
--    SCHEMA_COMPAT_ULDIF = "/usr/share/ipa/schema_compat.uldif"
-+    SCHEMA_COMPAT_ULDIF = "/usr/share/ipa/updates/91-schema_compat.update"
-+    SCHEMA_COMPAT_POST_ULDIF = "/usr/share/ipa/schema_compat_post.uldif"
-     IPA_JS_PLUGINS_DIR = "/usr/share/ipa/ui/js/plugins"
-     UPDATES_DIR = "/usr/share/ipa/updates/"
-     DICT_WORDS = "/usr/share/dict/words"
-diff --git a/ipaserver/install/dsinstance.py b/ipaserver/install/dsinstance.py
-index 99a1781ca4475805e9bf3b2bac3f26b5fb107a43..403fe8489fdd9e0dbf40dd4df3794b51185d45b9 100644
---- a/ipaserver/install/dsinstance.py
-+++ b/ipaserver/install/dsinstance.py
-@@ -38,7 +38,6 @@ from ipapython import dogtag
- from ipaserver.install import service
- from ipaserver.install import installutils
- from ipaserver.install import certs
--from ipaserver.install import ldapupdate
- from ipaserver.install import replication
- from ipaserver.install import sysupgrade
- from ipaserver.install import upgradeinstance
-@@ -281,8 +280,6 @@ class DsInstance(service.Service):
-         self.step("configuring Posix uid/gid generation",
-                   self.__config_uidgid_gen)
-         self.step("adding replication acis", self.__add_replication_acis)
--        self.step("enabling compatibility plugin",
--                  self.__enable_compat_plugin)
-         self.step("activating sidgen plugin", self._add_sidgen_plugin)
-         self.step("activating extdom plugin", self._add_extdom_plugin)
-         self.step("tuning directory server", self.__tuning)
-@@ -706,12 +703,6 @@ class DsInstance(service.Service):
-     def __add_winsync_module(self):
-         self._ldap_mod("ipa-winsync-conf.ldif")
- 
--    def __enable_compat_plugin(self):
--        ld = ldapupdate.LDAPUpdate(dm_password=self.dm_password, sub_dict=self.sub_dict)
--        rv = ld.update([paths.SCHEMA_COMPAT_ULDIF])
--        if not rv:
--            raise RuntimeError("Enabling compatibility plugin failed")
--
-     def __config_version_module(self):
-         self._ldap_mod("version-conf.ldif")
- 
--- 
-2.12.2
-
diff --git a/SOURCES/0095-compat-ignore-cn-topology-cn-ipa-cn-etc-subtree.patch b/SOURCES/0095-compat-ignore-cn-topology-cn-ipa-cn-etc-subtree.patch
deleted file mode 100644
index 43b196f..0000000
--- a/SOURCES/0095-compat-ignore-cn-topology-cn-ipa-cn-etc-subtree.patch
+++ /dev/null
@@ -1,62 +0,0 @@
-From 08c5150d76971ab17eb02ceef0e65e993b7732ff Mon Sep 17 00:00:00 2001
-From: Stanislav Laznicka <slaznick@redhat.com>
-Date: Fri, 21 Apr 2017 09:39:56 +0200
-Subject: [PATCH] compat: ignore cn=topology,cn=ipa,cn=etc subtree
-
-The entries in cn=topology,cn=ipa,cn=etc should not be taken in
-account for the compat plugin.
-
-https://pagure.io/freeipa/issue/6821
-
-Reviewed-By: Martin Basti <mbasti@redhat.com>
----
- install/updates/80-schema_compat.update | 5 +++++
- 1 file changed, 5 insertions(+)
-
-diff --git a/install/updates/80-schema_compat.update b/install/updates/80-schema_compat.update
-index 06cbcab8ad809d95a907c161044ff91df827ebf3..7483518134aad47195ab136626acb5130c0d536d 100644
---- a/install/updates/80-schema_compat.update
-+++ b/install/updates/80-schema_compat.update
-@@ -152,6 +152,7 @@ remove: schema-compat-ignore-subtree: o=ipaca
- add: schema-compat-restrict-subtree: $SUFFIX
- add: schema-compat-restrict-subtree: cn=Schema Compatibility,cn=plugins,cn=config
- add: schema-compat-ignore-subtree: cn=dna,cn=ipa,cn=etc,$SUFFIX
-+add: schema-compat-ignore-subtree: cn=topology,cn=ipa,cn=etc,$SUFFIX
- 
- # Change padding for host and userCategory so the pad returns the same value
- # as the original, '' or -.
-@@ -162,6 +163,7 @@ remove: schema-compat-ignore-subtree: o=ipaca
- add: schema-compat-restrict-subtree: $SUFFIX
- add: schema-compat-restrict-subtree: cn=Schema Compatibility,cn=plugins,cn=config
- add: schema-compat-ignore-subtree: cn=dna,cn=ipa,cn=etc,$SUFFIX
-+add: schema-compat-ignore-subtree: cn=topology,cn=ipa,cn=etc,$SUFFIX
- 
- dn: cn=computers, cn=Schema Compatibility, cn=plugins, cn=config
- default:objectClass: top
-@@ -181,6 +183,7 @@ remove: schema-compat-ignore-subtree: o=ipaca
- add: schema-compat-restrict-subtree: $SUFFIX
- add: schema-compat-restrict-subtree: cn=Schema Compatibility,cn=plugins,cn=config
- add: schema-compat-ignore-subtree: cn=dna,cn=ipa,cn=etc,$SUFFIX
-+add: schema-compat-ignore-subtree: cn=topology,cn=ipa,cn=etc,$SUFFIX
- 
- dn: cn=sudoers,cn=Schema Compatibility,cn=plugins,cn=config
- add:schema-compat-entry-attribute: sudoOrder=%{sudoOrder}
-@@ -191,6 +194,7 @@ remove: schema-compat-ignore-subtree: o=ipaca
- add: schema-compat-restrict-subtree: $SUFFIX
- add: schema-compat-restrict-subtree: cn=Schema Compatibility,cn=plugins,cn=config
- add: schema-compat-ignore-subtree: cn=dna,cn=ipa,cn=etc,$SUFFIX
-+add: schema-compat-ignore-subtree: cn=topology,cn=ipa,cn=etc,$SUFFIX
- 
- dn: cn=groups,cn=Schema Compatibility,cn=plugins,cn=config
- remove: schema-compat-ignore-subtree: cn=changelog
-@@ -198,6 +202,7 @@ remove: schema-compat-ignore-subtree: o=ipaca
- add: schema-compat-restrict-subtree: $SUFFIX
- add: schema-compat-restrict-subtree: cn=Schema Compatibility,cn=plugins,cn=config
- add: schema-compat-ignore-subtree: cn=dna,cn=ipa,cn=etc,$SUFFIX
-+add: schema-compat-ignore-subtree: cn=topology,cn=ipa,cn=etc,$SUFFIX
- 
- dn: cn=Schema Compatibility,cn=plugins,cn=config
- # We need to run schema-compat pre-bind callback before
--- 
-2.12.2
-
diff --git a/SOURCES/0096-spec-file-bump-krb5-Requires-for-certauth-fixes.patch b/SOURCES/0096-spec-file-bump-krb5-Requires-for-certauth-fixes.patch
deleted file mode 100644
index 2f0c64d..0000000
--- a/SOURCES/0096-spec-file-bump-krb5-Requires-for-certauth-fixes.patch
+++ /dev/null
@@ -1,68 +0,0 @@
-From c8a4e5d946d8261748d632361a016950ab42f4ba Mon Sep 17 00:00:00 2001
-From: Jan Cholasta <jcholast@redhat.com>
-Date: Tue, 25 Apr 2017 12:35:34 +0000
-Subject: [PATCH] spec file: bump krb5 Requires for certauth fixes
-
-Bump krb5-* Requires to the version which includes the final version of
-certauth support.
-
-https://pagure.io/freeipa/issue/4905
-
-Reviewed-By: Stanislav Laznicka <slaznick@redhat.com>
----
- freeipa.spec.in | 12 ++++++++----
- 1 file changed, 8 insertions(+), 4 deletions(-)
-
-diff --git a/freeipa.spec.in b/freeipa.spec.in
-index 978ebb184f7d051b303940560f44c7a094b071a1..3b7410b6bda3afc877d928b4df21529ae2faf0aa 100644
---- a/freeipa.spec.in
-+++ b/freeipa.spec.in
-@@ -36,11 +36,15 @@
- 
- %global alt_name ipa
- %if 0%{?rhel}
-+# 1.15.1-7: certauth (http://krbdev.mit.edu/rt/Ticket/Display.html?id=8561)
-+%global krb5_version 1.15.1-4
- # Require 4.6.0-4 which brings RC4 for FIPS + trust fixes to priv. separation
- %global samba_version 4.6.0-4
- %global selinux_policy_version 3.12.1-153
- %global slapi_nis_version 0.56.0-4
- %else
-+# 1.15.1-7: certauth (http://krbdev.mit.edu/rt/Ticket/Display.html?id=8561)
-+%global krb5_version 1.15.1-7
- # Require 4.6.0-4 which brings RC4 for FIPS + trust fixes to priv. separation
- %global samba_version 2:4.6.0-4
- %global selinux_policy_version 3.13.1-158.4
-@@ -82,8 +86,7 @@ BuildRequires:  openldap-devel
- %if 0%{?fedora} > 25
- BuildRequires: krb5-kdb-version = 6.1
- %endif
--# 1.15.1-3: certauth (http://krbdev.mit.edu/rt/Ticket/Display.html?id=8561)
--BuildRequires:  krb5-devel >= 1.15.1-3
-+BuildRequires:  krb5-devel >= %{krb5_version}
- # 1.27.4: xmlrpc_curl_xportparms.gssapi_delegation
- BuildRequires:  xmlrpc-c-devel >= 1.27.4
- BuildRequires:  popt-devel
-@@ -263,8 +266,9 @@ Requires: 389-ds-base >= 1.3.5.14
- Requires: openldap-clients > 2.4.35-4
- Requires: nss >= 3.14.3-12.0
- Requires: nss-tools >= 3.14.3-12.0
-+Requires(post): krb5-server >= %{krb5_version}
- Requires(post): krb5-server >= %{krb5_base_version}, krb5-server < %{krb5_base_version}.100
--Requires: krb5-pkinit-openssl
-+Requires: krb5-pkinit-openssl >= %{krb5_version}
- Requires: cyrus-sasl-gssapi%{?_isa}
- Requires: ntp
- Requires: httpd >= 2.4.6-31
-@@ -481,7 +485,7 @@ Requires: python2-ipaclient = %{version}-%{release}
- Requires: python-ldap
- Requires: cyrus-sasl-gssapi%{?_isa}
- Requires: ntp
--Requires: krb5-workstation
-+Requires: krb5-workstation >= %{krb5_version}
- Requires: authconfig
- Requires: curl
- # NIS domain name config: /usr/lib/systemd/system/*-domainname.service
--- 
-2.12.2
-
diff --git a/SOURCES/0097-Hide-PKI-Client-database-password-in-log-file.patch b/SOURCES/0097-Hide-PKI-Client-database-password-in-log-file.patch
deleted file mode 100644
index bb0c79f..0000000
--- a/SOURCES/0097-Hide-PKI-Client-database-password-in-log-file.patch
+++ /dev/null
@@ -1,70 +0,0 @@
-From 4106c7dcfc685580eeb0f2074872036cd5faaaae Mon Sep 17 00:00:00 2001
-From: Abhijeet Kasurde <akasurde@redhat.com>
-Date: Thu, 27 Apr 2017 16:23:41 +0530
-Subject: [PATCH] Hide PKI Client database password in log file
-
-This fix masks PKI client database password from showing
-in CA/KRA installer log file
-
-Fixes https://pagure.io/freeipa/issue/6904
-
-Signed-off-by: Abhijeet Kasurde <akasurde@redhat.com>
-Reviewed-By: Stanislav Laznicka <slaznick@redhat.com>
----
- ipaserver/install/cainstance.py  | 5 ++++-
- ipaserver/install/krainstance.py | 9 ++++++---
- 2 files changed, 10 insertions(+), 4 deletions(-)
-
-diff --git a/ipaserver/install/cainstance.py b/ipaserver/install/cainstance.py
-index 0672bccf79d7cc6133fdb20f0854366306bfc2e0..84d60bfddc0fb968f31706e54e36557e9543846e 100644
---- a/ipaserver/install/cainstance.py
-+++ b/ipaserver/install/cainstance.py
-@@ -610,7 +610,10 @@ class CAInstance(DogtagInstance):
-         try:
-             DogtagInstance.spawn_instance(
-                 self, cfg_file,
--                nolog_list=(self.dm_password, self.admin_password, pki_pin)
-+                nolog_list=(self.dm_password,
-+                            self.admin_password,
-+                            pki_pin,
-+                            self.tmp_agent_pwd)
-             )
-         finally:
-             os.remove(cfg_file)
-diff --git a/ipaserver/install/krainstance.py b/ipaserver/install/krainstance.py
-index fc25ac72b0dc593f06a8b070b67b5d54a0ab8bce..c39d6874a9d685f91b5d30ea1954320b8ee0c1ed 100644
---- a/ipaserver/install/krainstance.py
-+++ b/ipaserver/install/krainstance.py
-@@ -150,6 +150,7 @@ class KRAInstance(DogtagInstance):
-         os.chown(cfg_file, pent.pw_uid, pent.pw_gid)
-         self.tmp_agent_db = tempfile.mkdtemp(
-                 prefix="tmp-", dir=paths.VAR_LIB_IPA)
-+        tmp_agent_pwd = ipautil.ipa_generate_password()
- 
-         # Create KRA configuration
-         config = ConfigParser()
-@@ -173,8 +174,7 @@ class KRAInstance(DogtagInstance):
- 
-         # Client security database
-         config.set("KRA", "pki_client_database_dir", self.tmp_agent_db)
--        config.set("KRA", "pki_client_database_password",
--                   ipautil.ipa_generate_password())
-+        config.set("KRA", "pki_client_database_password", tmp_agent_pwd)
-         config.set("KRA", "pki_client_database_purge", "True")
-         config.set("KRA", "pki_client_pkcs12_password", self.admin_password)
- 
-@@ -283,7 +283,10 @@ class KRAInstance(DogtagInstance):
-         try:
-             DogtagInstance.spawn_instance(
-                 self, cfg_file,
--                nolog_list=(self.dm_password, self.admin_password, pki_pin)
-+                nolog_list=(self.dm_password,
-+                            self.admin_password,
-+                            pki_pin,
-+                            tmp_agent_pwd)
-             )
-         finally:
-             os.remove(p12_tmpfile_name)
--- 
-2.12.2
-
diff --git a/SOURCES/0098-Vault-Explicitly-default-to-3DES-CBC.patch b/SOURCES/0098-Vault-Explicitly-default-to-3DES-CBC.patch
deleted file mode 100644
index b6cf014..0000000
--- a/SOURCES/0098-Vault-Explicitly-default-to-3DES-CBC.patch
+++ /dev/null
@@ -1,50 +0,0 @@
-From c6b9b76307faa001670bc990fbe88aeb23bad403 Mon Sep 17 00:00:00 2001
-From: Christian Heimes <cheimes@redhat.com>
-Date: Wed, 26 Apr 2017 18:15:40 +0200
-Subject: [PATCH] Vault: Explicitly default to 3DES CBC
-
-The server-side plugin for IPA Vault relied on the fact that the default
-oid for encryption algorithm is 3DES in CBC mode (DES-EDE3-CBC). Dogtag
-10.4 has changed the default from 3DES to AES. Pass the correct
-algorithm OID to KeyClient.archive_encrypted_data().
-
-Closes: https://pagure.io/freeipa/issue/6899
-Signed-off-by: Christian Heimes <cheimes@redhat.com>
-Reviewed-By: Fraser Tweedale <ftweedal@redhat.com>
----
- ipaserver/plugins/vault.py | 12 ++++++++++--
- 1 file changed, 10 insertions(+), 2 deletions(-)
-
-diff --git a/ipaserver/plugins/vault.py b/ipaserver/plugins/vault.py
-index 57e1ed7800063822f87da5a71f0f3a0df4d8dd33..d46aca821d2ec94a38dd7cc930f26038d5d80a90 100644
---- a/ipaserver/plugins/vault.py
-+++ b/ipaserver/plugins/vault.py
-@@ -38,6 +38,14 @@ from ipapython.dn import DN
- if api.env.in_server:
-     import pki.account
-     import pki.key
-+    # pylint: disable=no-member
-+    try:
-+        # pki >= 10.4.0
-+        from pki.crypto import DES_EDE3_CBC_OID
-+    except ImportError:
-+        DES_EDE3_CBC_OID = pki.key.KeyClient.DES_EDE3_CBC_OID
-+    # pylint: enable=no-member
-+
- 
- if six.PY3:
-     unicode = str
-@@ -1059,8 +1067,8 @@ class vault_archive_internal(PKQuery):
-                 pki.key.KeyClient.PASS_PHRASE_TYPE,
-                 wrapped_vault_data,
-                 wrapped_session_key,
--                None,
--                nonce,
-+                algorithm_oid=DES_EDE3_CBC_OID,
-+                nonce_iv=nonce,
-             )
- 
-             kra_account.logout()
--- 
-2.12.2
-
diff --git a/SOURCES/0099-separate-function-to-set-ipaConfigString-values-on-s.patch b/SOURCES/0099-separate-function-to-set-ipaConfigString-values-on-s.patch
deleted file mode 100644
index 2ca4e1b..0000000
--- a/SOURCES/0099-separate-function-to-set-ipaConfigString-values-on-s.patch
+++ /dev/null
@@ -1,244 +0,0 @@
-From fd6873ad33493b5f395a92f03d54cd184b90d2a2 Mon Sep 17 00:00:00 2001
-From: Martin Babinsky <mbabinsk@redhat.com>
-Date: Tue, 25 Apr 2017 18:55:59 +0200
-Subject: [PATCH] separate function to set ipaConfigString values on service
- entry
-
-There is some code duplication regarding setting ipaConfigString values
-when:
-   * LDAP-enabling a service entry
-   * advertising enabled KDCProxy in LDAP
-
-We can delegate the common work to a single re-usable function and thus
-expose it to future use-cases (like PKINIT advertising).
-
-https://pagure.io/freeipa/issue/6830
-
-Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
-Reviewed-By: Jan Cholasta <jcholast@redhat.com>
-Reviewed-By: Martin Basti <mbasti@redhat.com>
-Reviewed-By: Simo Sorce <ssorce@redhat.com>
----
- ipaserver/install/httpinstance.py |  43 +-----------
- ipaserver/install/service.py      | 135 ++++++++++++++++++++++++++------------
- 2 files changed, 94 insertions(+), 84 deletions(-)
-
-diff --git a/ipaserver/install/httpinstance.py b/ipaserver/install/httpinstance.py
-index aeb5c5e450813469e1b6cd374b30cd4aab338537..f0a477e0bf16b03ed8b937279dad88e6e2b3aab6 100644
---- a/ipaserver/install/httpinstance.py
-+++ b/ipaserver/install/httpinstance.py
-@@ -42,7 +42,6 @@ from ipapython.ipa_log_manager import root_logger
- import ipapython.errors
- from ipaserver.install import sysupgrade
- from ipalib import api
--from ipalib import errors
- from ipalib.constants import ANON_USER
- from ipaplatform.constants import constants
- from ipaplatform.tasks import tasks
-@@ -451,46 +450,8 @@ class HTTPInstance(service.Service):
- 
-     def enable_kdcproxy(self):
-         """Add ipaConfigString=kdcProxyEnabled to cn=KDC"""
--        entry_name = DN(('cn', 'KDC'), ('cn', self.fqdn), ('cn', 'masters'),
--                        ('cn', 'ipa'), ('cn', 'etc'), self.suffix)
--        attr_name = 'kdcProxyEnabled'
--
--        try:
--            entry = api.Backend.ldap2.get_entry(
--                entry_name, ['ipaConfigString'])
--        except errors.NotFound:
--            pass
--        else:
--            if any(attr_name.lower() == val.lower()
--                   for val in entry.get('ipaConfigString', [])):
--                root_logger.debug("service KDCPROXY already enabled")
--                return
--
--            entry.setdefault('ipaConfigString', []).append(attr_name)
--            try:
--                api.Backend.ldap2.update_entry(entry)
--            except errors.EmptyModlist:
--                root_logger.debug("service KDCPROXY already enabled")
--                return
--            except:
--                root_logger.debug("failed to enable service KDCPROXY")
--                raise
--
--            root_logger.debug("service KDCPROXY enabled")
--            return
--
--        entry = api.Backend.ldap2.make_entry(
--            entry_name,
--            objectclass=["nsContainer", "ipaConfigObject"],
--            cn=['KDC'],
--            ipaconfigstring=[attr_name]
--        )
--
--        try:
--            api.Backend.ldap2.add_entry(entry)
--        except errors.DuplicateEntry:
--            root_logger.debug("failed to add service KDCPROXY entry")
--            raise
-+        service.set_service_entry_config(
-+            'KDC', self.fqdn, [u'kdcProxyEnabled'], self.suffix)
- 
-     def create_kdcproxy_conf(self):
-         """Create ipa-kdc-proxy.conf in /etc/ipa/kdcproxy"""
-diff --git a/ipaserver/install/service.py b/ipaserver/install/service.py
-index 9533a887ca41b8d9f9480ec30b908b213807ca7e..6b5e69ccd08444c591f15eb680b4cbdf5b6f4de1 100644
---- a/ipaserver/install/service.py
-+++ b/ipaserver/install/service.py
-@@ -136,6 +136,87 @@ def find_providing_server(svcname, conn, host_name=None, api=api):
-     return None
- 
- 
-+def case_insensitive_attr_has_value(attr, value):
-+    """
-+    Helper function to find value in an attribute having case-insensitive
-+    matching rules
-+
-+    :param attr: attribute values
-+    :param value: value to find
-+
-+    :returns: True if the case-insensitive match succeeds, false otherwise
-+
-+    """
-+    if any(value.lower() == val.lower()
-+           for val in attr):
-+        return True
-+
-+    return False
-+
-+
-+def set_service_entry_config(name, fqdn, config_values,
-+                             ldap_suffix='',
-+                             post_add_config=()):
-+    """
-+    Sets the 'ipaConfigString' values on the entry. If the entry is not present
-+    already, create a new one with desired 'ipaConfigString'
-+
-+    :param name: service entry name
-+    :param config_values: configuration values to store
-+    :param fqdn: master fqdn
-+    :param ldap_suffix: LDAP backend suffix
-+    :param post_add_config: additional configuration to add when adding a
-+        non-existent entry
-+    """
-+    assert isinstance(ldap_suffix, DN)
-+
-+    entry_name = DN(
-+        ('cn', name), ('cn', fqdn), ('cn', 'masters'),
-+        ('cn', 'ipa'), ('cn', 'etc'), ldap_suffix)
-+
-+    # enable disabled service
-+    try:
-+        entry = api.Backend.ldap2.get_entry(
-+            entry_name, ['ipaConfigString'])
-+    except errors.NotFound:
-+        pass
-+    else:
-+        existing_values = entry.get('ipaConnfigString', [])
-+        for value in config_values:
-+            if case_insensitive_attr_has_value(existing_values, value):
-+                root_logger.debug(
-+                    "service %s: config string %s already set", name, value)
-+
-+            entry.setdefault('ipaConfigString', []).append(value)
-+
-+        try:
-+            api.Backend.ldap2.update_entry(entry)
-+        except errors.EmptyModlist:
-+            root_logger.debug(
-+                "service %s has already enabled config values %s", name,
-+                config_values)
-+            return
-+        except:
-+            root_logger.debug("failed to set service %s config values", name)
-+            raise
-+
-+        root_logger.debug("service %s has all config values set", name)
-+        return
-+
-+    entry = api.Backend.ldap2.make_entry(
-+        entry_name,
-+        objectclass=["nsContainer", "ipaConfigObject"],
-+        cn=[name],
-+        ipaconfigstring=config_values + list(post_add_config),
-+    )
-+
-+    try:
-+        api.Backend.ldap2.add_entry(entry)
-+    except (errors.DuplicateEntry) as e:
-+        root_logger.debug("failed to add service entry %s", name)
-+        raise e
-+
-+
- class Service(object):
-     def __init__(self, service_name, service_desc=None, sstore=None,
-                  fstore=None, api=api, realm_name=None,
-@@ -442,51 +523,19 @@ class Service(object):
- 
-     def ldap_enable(self, name, fqdn, dm_password=None, ldap_suffix='',
-                     config=[]):
--        assert isinstance(ldap_suffix, DN)
--        self.disable()
-+        extra_config_opts = [
-+            ' '.join([u'startOrder', unicode(SERVICE_LIST[name][1])])
-+        ]
-+        extra_config_opts.extend(config)
- 
--        entry_name = DN(('cn', name), ('cn', fqdn), ('cn', 'masters'), ('cn', 'ipa'), ('cn', 'etc'), ldap_suffix)
--
--        # enable disabled service
--        try:
--            entry = api.Backend.ldap2.get_entry(
--                entry_name, ['ipaConfigString'])
--        except errors.NotFound:
--            pass
--        else:
--            if any(u'enabledservice' == val.lower()
--                   for val in entry.get('ipaConfigString', [])):
--                root_logger.debug("service %s startup entry already enabled", name)
--                return
--
--            entry.setdefault('ipaConfigString', []).append(u'enabledService')
--
--            try:
--                api.Backend.ldap2.update_entry(entry)
--            except errors.EmptyModlist:
--                root_logger.debug("service %s startup entry already enabled", name)
--                return
--            except:
--                root_logger.debug("failed to enable service %s startup entry", name)
--                raise
--
--            root_logger.debug("service %s startup entry enabled", name)
--            return
--
--        order = SERVICE_LIST[name][1]
--        entry = api.Backend.ldap2.make_entry(
--            entry_name,
--            objectclass=["nsContainer", "ipaConfigObject"],
--            cn=[name],
--            ipaconfigstring=[
--                "enabledService", "startOrder " + str(order)] + config,
--        )
-+        self.disable()
- 
--        try:
--            api.Backend.ldap2.add_entry(entry)
--        except (errors.DuplicateEntry) as e:
--            root_logger.debug("failed to add service %s startup entry", name)
--            raise e
-+        set_service_entry_config(
-+            name,
-+            fqdn,
-+            [u'enabledService'],
-+            ldap_suffix=ldap_suffix,
-+            post_add_config=extra_config_opts)
- 
-     def ldap_disable(self, name, fqdn, ldap_suffix):
-         assert isinstance(ldap_suffix, DN)
--- 
-2.12.2
-
diff --git a/SOURCES/0100-Allow-for-configuration-of-all-three-PKINIT-variants.patch b/SOURCES/0100-Allow-for-configuration-of-all-three-PKINIT-variants.patch
deleted file mode 100644
index 0106656..0000000
--- a/SOURCES/0100-Allow-for-configuration-of-all-three-PKINIT-variants.patch
+++ /dev/null
@@ -1,205 +0,0 @@
-From 152715b8514b1b94e1c353baedff12d24efaacb7 Mon Sep 17 00:00:00 2001
-From: Martin Babinsky <mbabinsk@redhat.com>
-Date: Fri, 31 Mar 2017 15:06:46 +0200
-Subject: [PATCH] Allow for configuration of all three PKINIT variants when
- deploying KDC
-
-The PKINIT setup code now can configure PKINIT using IPA CA signed
-certificate, 3rd party certificate and local PKINIT with self-signed
-keypair. The local PKINIT is also selected as a fallback mechanism if
-the CSR is rejected by CA master or `--no-pkinit` is used.
-
-http://www.freeipa.org/page/V4/Kerberos_PKINIT
-https://pagure.io/freeipa/issue/6830
-
-Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
-Reviewed-By: Jan Cholasta <jcholast@redhat.com>
-Reviewed-By: Martin Basti <mbasti@redhat.com>
-Reviewed-By: Simo Sorce <ssorce@redhat.com>
----
- ipaserver/install/krbinstance.py | 145 +++++++++++++++++++++++++--------------
- 1 file changed, 93 insertions(+), 52 deletions(-)
-
-diff --git a/ipaserver/install/krbinstance.py b/ipaserver/install/krbinstance.py
-index 6c105f74c8da2bfd34ace607b13170bc96a8ff1d..80215788cf4031ef82e9ec7e08bde6cfc4390303 100644
---- a/ipaserver/install/krbinstance.py
-+++ b/ipaserver/install/krbinstance.py
-@@ -38,6 +38,7 @@ from ipalib.constants import ANON_USER
- from ipalib.install import certmonger
- from ipapython.ipa_log_manager import root_logger
- from ipapython.dn import DN
-+from ipapython.dogtag import KDC_PROFILE
- 
- from ipaserver.install import replication
- from ipaserver.install import ldapupdate
-@@ -354,61 +355,84 @@ class KrbInstance(service.Service):
-             remote_ldap.gssapi_bind()
-             replication.wait_for_entry(remote_ldap, kdc_dn, timeout=60)
- 
--    def setup_pkinit(self):
--        if self.pkcs12_info:
--            certs.install_pem_from_p12(self.pkcs12_info[0],
--                                       self.pkcs12_info[1],
--                                       paths.KDC_CERT)
--            certs.install_key_from_p12(self.pkcs12_info[0],
--                                       self.pkcs12_info[1],
--                                       paths.KDC_KEY)
--        else:
--            subject = str(DN(('cn', self.fqdn), self.subject_base))
--            krbtgt = "krbtgt/" + self.realm + "@" + self.realm
--            certpath = (paths.KDC_CERT, paths.KDC_KEY)
-+    def _call_certmonger(self, certmonger_ca='IPA'):
-+        subject = str(DN(('cn', self.fqdn), self.subject_base))
-+        krbtgt = "krbtgt/" + self.realm + "@" + self.realm
-+        certpath = (paths.KDC_CERT, paths.KDC_KEY)
- 
--            try:
--                prev_helper = None
--                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:
--                    self._wait_for_replica_kdc_entry()
--
--                certmonger.request_and_wait_for_cert(
--                    certpath,
--                    subject,
--                    krbtgt,
--                    dns=self.fqdn,
--                    storage='FILE',
--                    profile='KDCs_PKINIT_Certs')
--            except dbus.DBusException as e:
--                # if the certificate is already tracked, ignore the error
--                name = e.get_dbus_name()
--                if name != 'org.fedorahosted.certmonger.duplicate':
--                    root_logger.error("Failed to initiate the request: %s", e)
--                return
--            finally:
--                if prev_helper is not None:
--                    certmonger.modify_ca_helper('IPA', prev_helper)
--
--        # Finally copy the cacert in the krb directory so we don't
--        # have any selinux issues with the file context
-+        try:
-+            prev_helper = None
-+            # on the first CA-ful master without '--no-pkinit', we issue the
-+            # certificate by contacting Dogtag directly
-+            use_dogtag_submit = all(
-+                [self.master_fqdn is None,
-+                 self.pkcs12_info is None,
-+                 self.config_pkinit])
-+
-+            if use_dogtag_submit:
-+                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(certmonger_ca, helper)
-+
-+            certmonger.request_and_wait_for_cert(
-+                certpath,
-+                subject,
-+                krbtgt,
-+                ca=certmonger_ca,
-+                dns=self.fqdn,
-+                storage='FILE',
-+                profile=KDC_PROFILE)
-+        except dbus.DBusException as e:
-+            # if the certificate is already tracked, ignore the error
-+            name = e.get_dbus_name()
-+            if name != 'org.fedorahosted.certmonger.duplicate':
-+                root_logger.error("Failed to initiate the request: %s", e)
-+            return
-+        finally:
-+            if prev_helper is not None:
-+                certmonger.modify_ca_helper(certmonger_ca, prev_helper)
-+
-+    def issue_selfsigned_pkinit_certs(self):
-+        self._call_certmonger(certmonger_ca="SelfSign")
-+        # for self-signed certificate, the certificate is its own CA, copy it
-+        # as CA cert
-+        shutil.copyfile(paths.KDC_CERT, paths.CACERT_PEM)
-+
-+    def issue_ipa_ca_signed_pkinit_certs(self):
-+        try:
-+            self._call_certmonger()
-+            # copy IPA CA bundle to the KDC's CA cert bundle
-+            shutil.copyfile(paths.IPA_CA_CRT, paths.CACERT_PEM)
-+        except RuntimeError as e:
-+            root_logger.error("PKINIT certificate request failed: %s", e)
-+            root_logger.error("Failed to configure PKINIT")
-+            self.stop_tracking_certs()
-+            self.issue_selfsigned_pkinit_certs()
-+
-+    def install_external_pkinit_certs(self):
-+        certs.install_pem_from_p12(self.pkcs12_info[0],
-+                                   self.pkcs12_info[1],
-+                                   paths.KDC_CERT)
-+        certs.install_key_from_p12(self.pkcs12_info[0],
-+                                   self.pkcs12_info[1],
-+                                   paths.KDC_KEY)
-+        # copy IPA CA bundle to the KDC's CA cert bundle
-+        # NOTE: this may not be the same set of CA certificates trusted by
-+        # externally provided PKINIT cert.
-         shutil.copyfile(paths.IPA_CA_CRT, paths.CACERT_PEM)
- 
--        try:
--            self.restart()
--        except Exception:
--            root_logger.critical("krb5kdc service failed to restart")
--            raise
-+    def setup_pkinit(self):
-+        if self.pkcs12_info:
-+            self.install_external_pkinit_certs()
-+        elif self.config_pkinit:
-+            self.issue_ipa_ca_signed_pkinit_certs()
- 
-     def test_anonymous_pkinit(self):
-         with ipautil.private_ccache() as anon_ccache:
-@@ -418,6 +442,15 @@ class KrbInstance(service.Service):
-                 raise RuntimeError("Failed to configure anonymous PKINIT")
- 
-     def enable_ssl(self):
-+        """
-+        generate PKINIT certificate for KDC. If `--no-pkinit` was specified,
-+        only configure local self-signed KDC certificate for use as a FAST
-+        channel generator for WebUI. Do not advertise the installation steps in
-+        this case.
-+        """
-+        if self.master_fqdn is not None:
-+            self._wait_for_replica_kdc_entry()
-+
-         if self.config_pkinit:
-             self.steps = []
-             self.step("installing X509 Certificate for PKINIT",
-@@ -425,6 +458,14 @@ class KrbInstance(service.Service):
-             self.step("testing anonymous PKINIT", self.test_anonymous_pkinit)
- 
-             self.start_creation()
-+        else:
-+            self.issue_selfsigned_pkinit_certs()
-+
-+        try:
-+            self.restart()
-+        except Exception:
-+            root_logger.critical("krb5kdc service failed to restart")
-+            raise
- 
-     def get_anonymous_principal_name(self):
-         return "%s@%s" % (ANON_USER, self.realm)
--- 
-2.12.2
-
diff --git a/SOURCES/0101-API-for-retrieval-of-master-s-PKINIT-status-and-publ.patch b/SOURCES/0101-API-for-retrieval-of-master-s-PKINIT-status-and-publ.patch
deleted file mode 100644
index 8c7687e..0000000
--- a/SOURCES/0101-API-for-retrieval-of-master-s-PKINIT-status-and-publ.patch
+++ /dev/null
@@ -1,99 +0,0 @@
-From a6f958875f3b42a8ea5856b672f5e8416c0aad90 Mon Sep 17 00:00:00 2001
-From: Martin Babinsky <mbabinsk@redhat.com>
-Date: Fri, 31 Mar 2017 14:44:29 +0200
-Subject: [PATCH] API for retrieval of master's PKINIT status and publishing it
- in LDAP
-
-An API was provided to report whether PKINIT is enabled for clients or
-not. If yes, the pkinitEnabled value will be added to the
-ipaConfigString attribute of master's KDC entry.
-
-See http://www.freeipa.org/page/V4/Kerberos_PKINIT#Configuration for
-more details.
-
-https://pagure.io/freeipa/issue/6830
-
-Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
-Reviewed-By: Jan Cholasta <jcholast@redhat.com>
-Reviewed-By: Martin Basti <mbasti@redhat.com>
-Reviewed-By: Simo Sorce <ssorce@redhat.com>
----
- ipaserver/install/krbinstance.py | 41 ++++++++++++++++++++++++++++++++++++++++
- 1 file changed, 41 insertions(+)
-
-diff --git a/ipaserver/install/krbinstance.py b/ipaserver/install/krbinstance.py
-index 80215788cf4031ef82e9ec7e08bde6cfc4390303..ad3475f95371c9ae17c8b0ac082039c041d5c64c 100644
---- a/ipaserver/install/krbinstance.py
-+++ b/ipaserver/install/krbinstance.py
-@@ -48,6 +48,38 @@ from ipaplatform.constants import constants
- from ipaplatform.tasks import tasks
- from ipaplatform.paths import paths
- 
-+PKINIT_ENABLED = 'pkinitEnabled'
-+
-+
-+def get_pkinit_request_ca():
-+    """
-+    Return the certmonger CA name which is serving the PKINIT certificate
-+    request. If the certificate is not tracked by Certmonger, return None
-+    """
-+    pkinit_request_id = certmonger.get_request_id(
-+        {'cert-file': paths.KDC_CERT})
-+
-+    if pkinit_request_id is None:
-+        return
-+
-+    return certmonger.get_request_value(pkinit_request_id, 'ca-name')
-+
-+
-+def is_pkinit_enabled():
-+    """
-+    check whether PKINIT is enabled on the master by checking for the presence
-+    of KDC certificate and it's tracking CA
-+    """
-+
-+    if os.path.exists(paths.KDC_CERT):
-+        pkinit_request_ca = get_pkinit_request_ca()
-+
-+        if pkinit_request_ca != "SelfSign":
-+            return True
-+
-+    return False
-+
-+
- class KpasswdInstance(service.SimpleServiceInstance):
-     def __init__(self):
-         service.SimpleServiceInstance.__init__(self, "kadmin")
-@@ -399,6 +431,13 @@ class KrbInstance(service.Service):
-             if prev_helper is not None:
-                 certmonger.modify_ca_helper(certmonger_ca, prev_helper)
- 
-+    def pkinit_enable(self):
-+        """
-+        advertise enabled PKINIT feature in master's KDC entry in LDAP
-+        """
-+        service.set_service_entry_config(
-+            'KDC', self.fqdn, [PKINIT_ENABLED], self.suffix)
-+
-     def issue_selfsigned_pkinit_certs(self):
-         self._call_certmonger(certmonger_ca="SelfSign")
-         # for self-signed certificate, the certificate is its own CA, copy it
-@@ -410,6 +449,7 @@ class KrbInstance(service.Service):
-             self._call_certmonger()
-             # copy IPA CA bundle to the KDC's CA cert bundle
-             shutil.copyfile(paths.IPA_CA_CRT, paths.CACERT_PEM)
-+            self.pkinit_enable()
-         except RuntimeError as e:
-             root_logger.error("PKINIT certificate request failed: %s", e)
-             root_logger.error("Failed to configure PKINIT")
-@@ -427,6 +467,7 @@ class KrbInstance(service.Service):
-         # NOTE: this may not be the same set of CA certificates trusted by
-         # externally provided PKINIT cert.
-         shutil.copyfile(paths.IPA_CA_CRT, paths.CACERT_PEM)
-+        self.pkinit_enable()
- 
-     def setup_pkinit(self):
-         if self.pkcs12_info:
--- 
-2.12.2
-
diff --git a/SOURCES/0102-Use-only-anonymous-PKINIT-to-fetch-armor-ccache.patch b/SOURCES/0102-Use-only-anonymous-PKINIT-to-fetch-armor-ccache.patch
deleted file mode 100644
index 0588dee..0000000
--- a/SOURCES/0102-Use-only-anonymous-PKINIT-to-fetch-armor-ccache.patch
+++ /dev/null
@@ -1,79 +0,0 @@
-From 15da0d16e99f5c6956f1ed687cc3cffdade83cb5 Mon Sep 17 00:00:00 2001
-From: Martin Babinsky <mbabinsk@redhat.com>
-Date: Fri, 31 Mar 2017 14:14:11 +0200
-Subject: [PATCH] Use only anonymous PKINIT to fetch armor ccache
-
-Since the anonymous principal can only use PKINIT to fetch credential
-cache it makes no sense to try and use its kerberos key to establish
-FAST channel.
-
-We should also be able to use custom PKINIT anchor for the armoring.
-
-https://pagure.io/freeipa/issue/6830
-
-Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
-Reviewed-By: Jan Cholasta <jcholast@redhat.com>
-Reviewed-By: Martin Basti <mbasti@redhat.com>
-Reviewed-By: Simo Sorce <ssorce@redhat.com>
----
- ipalib/install/kinit.py | 30 +++++++++++++-----------------
- 1 file changed, 13 insertions(+), 17 deletions(-)
-
-diff --git a/ipalib/install/kinit.py b/ipalib/install/kinit.py
-index 1e4d1a82fdefe968db13c3847b9b37b3b3f75d6f..fb6caee4d6b5fef27b53753b21ad83572da31ac4 100644
---- a/ipalib/install/kinit.py
-+++ b/ipalib/install/kinit.py
-@@ -7,7 +7,6 @@ import time
- 
- import gssapi
- 
--from ipalib.constants import ANON_USER
- from ipaplatform.paths import paths
- from ipapython.ipa_log_manager import root_logger
- from ipapython.ipautil import run
-@@ -97,29 +96,26 @@ def kinit_password(principal, password, ccache_name, config=None,
-         raise RuntimeError(result.error_output)
- 
- 
--def kinit_armor(ccache_name):
-+def kinit_armor(ccache_name, pkinit_anchor=None):
-     """
--    perform kinit to obtain anonymous ticket to be used as armor for FAST.
-+    perform anonymous pkinit to obtain anonymous ticket to be used as armor
-+    for FAST.
-+
-+    :param ccache_name: location of the armor ccache
-+    :param pkinit_anchor: if not None, the location of PKINIT anchor file to
-+        use. Otherwise the value from Kerberos client library configuration is
-+        used
-+
-+    :raises: CalledProcessError if the anonymous PKINIT fails
-     """
-     root_logger.debug("Initializing anonymous ccache")
- 
-     env = {'LC_ALL': 'C'}
--    # try with the keytab first and then again fallback to try with pkinit in
--    # case someone decided it is fun to remove Anonymous keys from the entry
--    # or in future pkinit enabled principal enforce the use of pkinit
--    try:
--        # Gssapi does not understand anonymous cred use kinit command instead
--        args = [paths.KINIT, '-k', '-t', paths.ANON_KEYTAB,
--                ANON_USER, '-c', ccache_name]
--        run(args, env=env, raiseonerr=True, capture_error=True)
--        return
--    except Exception as e:
--        root_logger.debug("Failed to init Anonymous keytab: %s", e,
--                          exc_info=True)
--
--    root_logger.debug("Fallback to slower Anonymous PKINIT")
-     args = [paths.KINIT, '-n', '-c', ccache_name]
- 
-+    if pkinit_anchor is not None:
-+        args.extend(['-X', 'X509_anchors=FILE:{}'.format(pkinit_anchor)])
-+
-     # this workaround enables us to capture stderr and put it
-     # into the raised exception in case of unsuccessful authentication
-     run(args, env=env, raiseonerr=True, capture_error=True)
--- 
-2.12.2
-
diff --git a/SOURCES/0103-Stop-requesting-anonymous-keytab-and-purge-all-refer.patch b/SOURCES/0103-Stop-requesting-anonymous-keytab-and-purge-all-refer.patch
deleted file mode 100644
index 0b0431a..0000000
--- a/SOURCES/0103-Stop-requesting-anonymous-keytab-and-purge-all-refer.patch
+++ /dev/null
@@ -1,110 +0,0 @@
-From 2bd0e49b7a7ba98a8ee6872cc7c3e619578c4431 Mon Sep 17 00:00:00 2001
-From: Martin Babinsky <mbabinsk@redhat.com>
-Date: Wed, 5 Apr 2017 17:29:26 +0200
-Subject: [PATCH] Stop requesting anonymous keytab and purge all references of
- it
-
-anonymous kinit using keytab never worked so we may safely remove all
-code that requests/uses it.
-
-https://pagure.io/freeipa/issue/6830
-
-Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
-Reviewed-By: Jan Cholasta <jcholast@redhat.com>
-Reviewed-By: Martin Basti <mbasti@redhat.com>
-Reviewed-By: Simo Sorce <ssorce@redhat.com>
----
- ipaplatform/base/paths.py           |  1 -
- ipaserver/install/httpinstance.py   | 17 -----------------
- ipaserver/install/ipa_backup.py     |  1 -
- ipaserver/install/server/upgrade.py |  1 -
- 4 files changed, 20 deletions(-)
-
-diff --git a/ipaplatform/base/paths.py b/ipaplatform/base/paths.py
-index dbdd71ed0b4d69c1101db4aeb7d93152ab8aa730..f80c9e95ab875222887e3692ab80151f84345469 100644
---- a/ipaplatform/base/paths.py
-+++ b/ipaplatform/base/paths.py
-@@ -50,7 +50,6 @@ class BasePathNamespace(object):
-     HTTPD_SSL_CONF = "/etc/httpd/conf.d/ssl.conf"
-     OLD_IPA_KEYTAB = "/etc/httpd/conf/ipa.keytab"
-     HTTP_KEYTAB = "/var/lib/ipa/gssproxy/http.keytab"
--    ANON_KEYTAB = "/var/lib/ipa/api/anon.keytab"
-     HTTPD_PASSWORD_CONF = "/etc/httpd/conf/password.conf"
-     IDMAPD_CONF = "/etc/idmapd.conf"
-     ETC_IPA = "/etc/ipa"
-diff --git a/ipaserver/install/httpinstance.py b/ipaserver/install/httpinstance.py
-index f0a477e0bf16b03ed8b937279dad88e6e2b3aab6..7898c53bc02785e2750dba61a5696f079355c9d7 100644
---- a/ipaserver/install/httpinstance.py
-+++ b/ipaserver/install/httpinstance.py
-@@ -30,7 +30,6 @@ import locale
- 
- import six
- 
--from ipalib.constants import IPAAPI_USER
- from ipalib.install import certmonger
- from ipaserver.install import service
- from ipaserver.install import certs
-@@ -42,7 +41,6 @@ from ipapython.ipa_log_manager import root_logger
- import ipapython.errors
- from ipaserver.install import sysupgrade
- from ipalib import api
--from ipalib.constants import ANON_USER
- from ipaplatform.constants import constants
- from ipaplatform.tasks import tasks
- from ipaplatform.paths import paths
-@@ -158,7 +156,6 @@ class HTTPInstance(service.Service):
-         self.step("adding URL rewriting rules", self.__add_include)
-         self.step("configuring httpd", self.__configure_http)
-         self.step("setting up httpd keytab", self.request_service_keytab)
--        self.step("retrieving anonymous keytab", self.request_anon_keytab)
-         self.step("configuring Gssproxy", self.configure_gssproxy)
-         self.step("setting up ssl", self.__setup_ssl)
-         if self.ca_is_configured:
-@@ -304,20 +301,6 @@ class HTTPInstance(service.Service):
-             if certmonger_stopped:
-                 certmonger.stop()
- 
--    def request_anon_keytab(self):
--        parent = os.path.dirname(paths.ANON_KEYTAB)
--        if not os.path.exists(parent):
--            os.makedirs(parent, 0o755)
--
--        self.clean_previous_keytab(keytab=paths.ANON_KEYTAB)
--        self.run_getkeytab(self.api.env.ldap_uri, paths.ANON_KEYTAB, ANON_USER)
--
--        pent = pwd.getpwnam(IPAAPI_USER)
--        os.chmod(parent, 0o700)
--        os.chown(parent, pent.pw_uid, pent.pw_gid)
--
--        self.set_keytab_owner(keytab=paths.ANON_KEYTAB, owner=IPAAPI_USER)
--
-     def create_password_conf(self):
-         """
-         This is the format of mod_nss pin files.
-diff --git a/ipaserver/install/ipa_backup.py b/ipaserver/install/ipa_backup.py
-index f71a40bb06545c8d89d1e3fdbc37d5e6e1fe8d58..40f08d7d727a8b97b5996f15d27c1e20788e1473 100644
---- a/ipaserver/install/ipa_backup.py
-+++ b/ipaserver/install/ipa_backup.py
-@@ -120,7 +120,6 @@ class Backup(admintool.AdminTool):
-     )
- 
-     files = (
--        paths.ANON_KEYTAB,
-         paths.NAMED_CONF,
-         paths.NAMED_KEYTAB,
-         paths.RESOLV_CONF,
-diff --git a/ipaserver/install/server/upgrade.py b/ipaserver/install/server/upgrade.py
-index 927acb011172de926773196eb1d032af8376f3d9..ea2918f5037898b6b8dc601441a439b6150d54e5 100644
---- a/ipaserver/install/server/upgrade.py
-+++ b/ipaserver/install/server/upgrade.py
-@@ -1795,7 +1795,6 @@ def upgrade_configuration():
-                         KDC_KEY=paths.KDC_KEY,
-                         CACERT_PEM=paths.CACERT_PEM)
-     krb.add_anonymous_principal()
--    http.request_anon_keytab()
-     setup_pkinit(krb)
- 
-     if not ds_running:
--- 
-2.12.2
-
diff --git a/SOURCES/0104-Use-local-anchor-when-armoring-password-requests.patch b/SOURCES/0104-Use-local-anchor-when-armoring-password-requests.patch
deleted file mode 100644
index eb161d5..0000000
--- a/SOURCES/0104-Use-local-anchor-when-armoring-password-requests.patch
+++ /dev/null
@@ -1,31 +0,0 @@
-From b5992ea987f6d8d49c988a9ab42463655b3d8e05 Mon Sep 17 00:00:00 2001
-From: Martin Babinsky <mbabinsk@redhat.com>
-Date: Fri, 31 Mar 2017 15:15:50 +0200
-Subject: [PATCH] Use local anchor when armoring password requests
-
-https://pagure.io/freeipa/issue/6830
-
-Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
-Reviewed-By: Jan Cholasta <jcholast@redhat.com>
-Reviewed-By: Martin Basti <mbasti@redhat.com>
-Reviewed-By: Simo Sorce <ssorce@redhat.com>
----
- ipaserver/rpcserver.py | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/ipaserver/rpcserver.py b/ipaserver/rpcserver.py
-index 77ed7e124c2ca3dcb49d3a68269d6fa9875d4da0..161872450d141a61af4345a20e278db728fe2aac 100644
---- a/ipaserver/rpcserver.py
-+++ b/ipaserver/rpcserver.py
-@@ -944,7 +944,7 @@ class login_password(Backend, KerberosSession):
-         self.debug('Obtaining armor in ccache %s', armor_path)
- 
-         try:
--            kinit_armor(armor_path)
-+            kinit_armor(armor_path, pkinit_anchor=paths.CACERT_PEM)
-         except RuntimeError as e:
-             self.error("Failed to obtain armor cache")
-             # We try to continue w/o armor, 2FA will be impacted
--- 
-2.12.2
-
diff --git a/SOURCES/0105-Upgrade-configure-local-full-PKINIT-depending-on-the.patch b/SOURCES/0105-Upgrade-configure-local-full-PKINIT-depending-on-the.patch
deleted file mode 100644
index b679de0..0000000
--- a/SOURCES/0105-Upgrade-configure-local-full-PKINIT-depending-on-the.patch
+++ /dev/null
@@ -1,52 +0,0 @@
-From c40683f85776f401b3e6bb0a3a69a48a206ab633 Mon Sep 17 00:00:00 2001
-From: Martin Babinsky <mbabinsk@redhat.com>
-Date: Thu, 6 Apr 2017 18:52:05 +0200
-Subject: [PATCH] Upgrade: configure local/full PKINIT depending on the master
- status
-
-The upgrader has been modified to configure either local or full PKINIT
-depending on the CA status. Additionally, the new PKINIT configuration
-will be written to the master's KDC entry.
-
-https://pagure.io/freeipa/issue/6830
-http://www.freeipa.org/page/V4/Kerberos_PKINIT
-
-Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
-Reviewed-By: Jan Cholasta <jcholast@redhat.com>
-Reviewed-By: Martin Basti <mbasti@redhat.com>
-Reviewed-By: Simo Sorce <ssorce@redhat.com>
----
- ipaserver/install/server/upgrade.py | 15 +++++++++------
- 1 file changed, 9 insertions(+), 6 deletions(-)
-
-diff --git a/ipaserver/install/server/upgrade.py b/ipaserver/install/server/upgrade.py
-index ea2918f5037898b6b8dc601441a439b6150d54e5..8da918114066598ec5a74098d85dfef06d22bf86 100644
---- a/ipaserver/install/server/upgrade.py
-+++ b/ipaserver/install/server/upgrade.py
-@@ -1485,14 +1485,17 @@ def add_default_caacl(ca):
- def setup_pkinit(krb):
-     root_logger.info("[Setup PKINIT]")
- 
--    if not api.Command.ca_is_enabled()['result']:
--        root_logger.info("CA is not enabled")
--        return
-+    pkinit_is_enabled = krbinstance.is_pkinit_enabled()
-+    ca_is_enabled = api.Command.ca_is_enabled()['result']
- 
--    if not os.path.exists(paths.KDC_CERT):
--        root_logger.info("Requesting PKINIT certificate")
--        krb.setup_pkinit()
-+    if not pkinit_is_enabled:
-+        if ca_is_enabled:
-+            krb.issue_ipa_ca_signed_pkinit_certs()
-+        else:
-+            krb.issue_selfsigned_pkinit_certs()
- 
-+    # reconfigure KDC just in case in order to handle potentially broken
-+    # 4.5.0 -> 4.5.1 upgrade path
-     replacevars = dict()
-     replacevars['pkinit_identity'] = 'FILE:{},{}'.format(
-         paths.KDC_CERT,paths.KDC_KEY)
--- 
-2.12.2
-
diff --git a/SOURCES/0106-Do-not-test-anonymous-PKINIT-after-install-upgrade.patch b/SOURCES/0106-Do-not-test-anonymous-PKINIT-after-install-upgrade.patch
deleted file mode 100644
index 34a1b07..0000000
--- a/SOURCES/0106-Do-not-test-anonymous-PKINIT-after-install-upgrade.patch
+++ /dev/null
@@ -1,62 +0,0 @@
-From 60412d08baa5a6836e505428a8b9bc73bdce0353 Mon Sep 17 00:00:00 2001
-From: Martin Babinsky <mbabinsk@redhat.com>
-Date: Tue, 25 Apr 2017 19:12:51 +0200
-Subject: [PATCH] Do not test anonymous PKINIT after install/upgrade
-
-Local FAST armoring will now work regardless of PKINIT status so there
-is no need to explicitly test for working PKINIT. If there is, there
-should be a test case for that.
-
-https://pagure.io/freeipa/issue/6830
-
-Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
-Reviewed-By: Jan Cholasta <jcholast@redhat.com>
-Reviewed-By: Martin Basti <mbasti@redhat.com>
-Reviewed-By: Simo Sorce <ssorce@redhat.com>
----
- ipaserver/install/krbinstance.py    | 9 ---------
- ipaserver/install/server/upgrade.py | 1 -
- 2 files changed, 10 deletions(-)
-
-diff --git a/ipaserver/install/krbinstance.py b/ipaserver/install/krbinstance.py
-index ad3475f95371c9ae17c8b0ac082039c041d5c64c..76ac3029ca6d1cbdd85c6ced6272c6f9a21f04a1 100644
---- a/ipaserver/install/krbinstance.py
-+++ b/ipaserver/install/krbinstance.py
-@@ -475,13 +475,6 @@ class KrbInstance(service.Service):
-         elif self.config_pkinit:
-             self.issue_ipa_ca_signed_pkinit_certs()
- 
--    def test_anonymous_pkinit(self):
--        with ipautil.private_ccache() as anon_ccache:
--            try:
--                ipautil.run([paths.KINIT, '-n', '-c', anon_ccache])
--            except ipautil.CalledProcessError:
--                raise RuntimeError("Failed to configure anonymous PKINIT")
--
-     def enable_ssl(self):
-         """
-         generate PKINIT certificate for KDC. If `--no-pkinit` was specified,
-@@ -496,8 +489,6 @@ class KrbInstance(service.Service):
-             self.steps = []
-             self.step("installing X509 Certificate for PKINIT",
-                       self.setup_pkinit)
--            self.step("testing anonymous PKINIT", self.test_anonymous_pkinit)
--
-             self.start_creation()
-         else:
-             self.issue_selfsigned_pkinit_certs()
-diff --git a/ipaserver/install/server/upgrade.py b/ipaserver/install/server/upgrade.py
-index 8da918114066598ec5a74098d85dfef06d22bf86..0f27428dd492bb44dd8c69a7e7f47abb531843f5 100644
---- a/ipaserver/install/server/upgrade.py
-+++ b/ipaserver/install/server/upgrade.py
-@@ -1507,7 +1507,6 @@ def setup_pkinit(krb):
-     if krb.is_running():
-         krb.stop()
-     krb.start()
--    krb.test_anonymous_pkinit()
- 
- 
- def disable_httpd_system_trust(http):
--- 
-2.12.2
-
diff --git a/SOURCES/0107-vault-piped-input-for-ipa-vault-add-fails.patch b/SOURCES/0107-vault-piped-input-for-ipa-vault-add-fails.patch
deleted file mode 100644
index 545fb7f..0000000
--- a/SOURCES/0107-vault-piped-input-for-ipa-vault-add-fails.patch
+++ /dev/null
@@ -1,104 +0,0 @@
-From a0ea8706fddb0459982c2ae276679cea6b0a812e Mon Sep 17 00:00:00 2001
-From: Florence Blanc-Renaud <flo@redhat.com>
-Date: Thu, 27 Apr 2017 18:20:06 +0200
-Subject: [PATCH] vault: piped input for ipa vault-add fails
-
-An exception is raised when using echo "Secret123\n" | ipa vault-add myvault
-
-This happens because the code is using (string).decode(sys.stdin.encoding)
-and sys.stdin.encoding is None when the input is read from a pipe.
-The fix is using the prompt_password method defined by Backend.textui,
-which gracefully handles this issue.
-
-https://pagure.io/freeipa/issue/6907
-
-Reviewed-By: Christian Heimes <cheimes@redhat.com>
-Reviewed-By: Abhijeet Kasurde <akasurde@redhat.com>
-Reviewed-By: Stanislav Laznicka <slaznick@redhat.com>
----
- ipaclient/plugins/vault.py | 37 ++++++++-----------------------------
- 1 file changed, 8 insertions(+), 29 deletions(-)
-
-diff --git a/ipaclient/plugins/vault.py b/ipaclient/plugins/vault.py
-index 3fb4900d9cf90e6902c40e1c3d8cfdafec2e28b8..f21dc4dbb6579c0f92ae9ab94d76a6396b26b233 100644
---- a/ipaclient/plugins/vault.py
-+++ b/ipaclient/plugins/vault.py
-@@ -21,11 +21,9 @@ from __future__ import print_function
- 
- import base64
- import errno
--import getpass
- import io
- import json
- import os
--import sys
- import tempfile
- 
- from cryptography.fernet import Fernet, InvalidToken
-@@ -84,29 +82,6 @@ register = Registry()
- MAX_VAULT_DATA_SIZE = 2**20  # = 1 MB
- 
- 
--def get_new_password():
--    """
--    Gets new password from user and verify it.
--    """
--    while True:
--        password = getpass.getpass('New password: ').decode(
--            sys.stdin.encoding)
--        password2 = getpass.getpass('Verify password: ').decode(
--            sys.stdin.encoding)
--
--        if password == password2:
--            return password
--
--        print('  ** Passwords do not match! **')
--
--
--def get_existing_password():
--    """
--    Gets existing password from user.
--    """
--    return getpass.getpass('Password: ').decode(sys.stdin.encoding)
--
--
- def generate_symmetric_key(password, salt):
-     """
-     Generates symmetric key from password and salt.
-@@ -304,7 +279,8 @@ class vault_add(Local):
-                 password = password.rstrip('\n')
- 
-             else:
--                password = get_new_password()
-+                password = self.api.Backend.textui.prompt_password(
-+                    'New password')
- 
-             # generate vault salt
-             options['ipavaultsalt'] = os.urandom(16)
-@@ -887,9 +863,11 @@ class vault_archive(ModVaultData):
- 
-             else:
-                 if override_password:
--                    password = get_new_password()
-+                    password = self.api.Backend.textui.prompt_password(
-+                        'New password')
-                 else:
--                    password = get_existing_password()
-+                    password = self.api.Backend.textui.prompt_password(
-+                        'Password', confirm=False)
- 
-             if not override_password:
-                 # verify password by retrieving existing data
-@@ -1112,7 +1090,8 @@ class vault_retrieve(ModVaultData):
-                 password = password.rstrip('\n')
- 
-             else:
--                password = get_existing_password()
-+                password = self.api.Backend.textui.prompt_password(
-+                    'Password', confirm=False)
- 
-             # generate encryption key from password
-             encryption_key = generate_symmetric_key(password, salt)
--- 
-2.12.2
-
diff --git a/SOURCES/0108-automount-install-fix-checking-of-SSSD-functionality.patch b/SOURCES/0108-automount-install-fix-checking-of-SSSD-functionality.patch
deleted file mode 100644
index 524993f..0000000
--- a/SOURCES/0108-automount-install-fix-checking-of-SSSD-functionality.patch
+++ /dev/null
@@ -1,83 +0,0 @@
-From 5a96db72e6bb7597217c5fbbcaa1b29836a9c8c0 Mon Sep 17 00:00:00 2001
-From: Petr Vobornik <pvoborni@redhat.com>
-Date: Tue, 25 Apr 2017 18:19:21 +0200
-Subject: [PATCH] automount install: fix checking of SSSD functionality on
- uninstall
-
-Change in 2d4d1a9dc0ef2bbe86751768d6e6b009a52c0dc9 no longer initializes
-api in `ipa-client-automount --uninstallation` Which caused error in
-wait_for_sssd which gets realm from initialized API.
-
-This patch initializes the API in a way that it doesn't download schema
-on uninstallation and on installation it uses host keytab for it so it
-no longer requires user's Kerberos credentials.
-
-Also fix call of xxx_service_class_factory which requires api as param.
-
-https://pagure.io/freeipa/issue/6861
-
-Reviewed-By: Rob Crittenden <rcritten@redhat.com>
-Reviewed-By: Tomas Krizek <tkrizek@redhat.com>
----
- client/ipa-client-automount | 16 ++++++++++------
- 1 file changed, 10 insertions(+), 6 deletions(-)
-
-diff --git a/client/ipa-client-automount b/client/ipa-client-automount
-index 18914bd74932180f300fcbc7b7db0ba1505881bd..2b1d8b9a8ca14d5403635fb20cee37984fe4a101 100755
---- a/client/ipa-client-automount
-+++ b/client/ipa-client-automount
-@@ -193,7 +193,7 @@ def configure_autofs_sssd(fstore, statestore, autodiscover, options):
-     sssdconfig.write(paths.SSSD_CONF)
-     statestore.backup_state('autofs', 'sssd', True)
- 
--    sssd = services.service('sssd')
-+    sssd = services.service('sssd', api)
-     sssd.restart()
-     print("Restarting sssd, waiting for it to become available.")
-     wait_for_sssd()
-@@ -281,7 +281,7 @@ def uninstall(fstore, statestore):
-                         break
-                 sssdconfig.save_domain(domain)
-                 sssdconfig.write(paths.SSSD_CONF)
--                sssd = services.service('sssd')
-+                sssd = services.service('sssd', api)
-                 sssd.restart()
-                 wait_for_sssd()
-             except Exception as e:
-@@ -379,9 +379,6 @@ def main():
-         paths.IPACLIENT_INSTALL_LOG, verbose=False, debug=options.debug,
-         filemode='a', console_format='%(message)s')
- 
--    if options.uninstall:
--        return uninstall(fstore, statestore)
--
-     cfg = dict(
-         context='cli_installer',
-         confdir=paths.ETC_IPA,
-@@ -390,8 +387,11 @@ def main():
-         verbose=0,
-     )
- 
-+    # Bootstrap API early so that env object is available
-     api.bootstrap(**cfg)
--    api.finalize()
-+
-+    if options.uninstall:
-+        return uninstall(fstore, statestore)
- 
-     ca_cert_path = None
-     if os.path.exists(paths.IPA_CA_CRT):
-@@ -449,6 +449,10 @@ def main():
-             os.environ['KRB5CCNAME'] = ccache_name
-         except gssapi.exceptions.GSSError as e:
-             sys.exit("Failed to obtain host TGT: %s" % e)
-+
-+        # Finalize API when TGT obtained using host keytab exists
-+        api.finalize()
-+
-         # Now we have a TGT, connect to IPA
-         try:
-             api.Backend.rpcclient.connect()
--- 
-2.12.2
-
diff --git a/SOURCES/0109-Fix-CA-server-cert-validation-in-FIPS.patch b/SOURCES/0109-Fix-CA-server-cert-validation-in-FIPS.patch
deleted file mode 100644
index f10a3a1..0000000
--- a/SOURCES/0109-Fix-CA-server-cert-validation-in-FIPS.patch
+++ /dev/null
@@ -1,72 +0,0 @@
-From 83fe9a4eb7b96d9d02066a73fe1894fb8b797753 Mon Sep 17 00:00:00 2001
-From: Stanislav Laznicka <slaznick@redhat.com>
-Date: Wed, 26 Apr 2017 08:19:27 +0200
-Subject: [PATCH] Fix CA/server cert validation in FIPS
-
-In FIPS, the NSS library needs to be passed passwords to perform
-certificate validation. Should we not have passed it and the NSS
-guys have not fixed this yet, we would get SEC_ERROR_BAD_SIGNATURE
-which is completely different error than one would expect but
-that's just how things are with NSS right now.
-
-https://pagure.io/freeipa/issue/6897
-
-Reviewed-By: Christian Heimes <cheimes@redhat.com>
-Reviewed-By: Abhijeet Kasurde <akasurde@redhat.com>
----
- ipapython/certdb.py | 13 +++++++++++--
- 1 file changed, 11 insertions(+), 2 deletions(-)
-
-diff --git a/ipapython/certdb.py b/ipapython/certdb.py
-index 0665f944457fb09820eb244c742cb1782e515ad1..ea73ec139df9013b860df447fcffd9038cf7c8f2 100644
---- a/ipapython/certdb.py
-+++ b/ipapython/certdb.py
-@@ -77,6 +77,11 @@ def find_cert_from_txt(cert, start=0):
-     return (cert, e)
- 
- 
-+def get_file_cont(slot, token, filename):
-+    with open(filename) as f:
-+        return f.read()
-+
-+
- class NSSDatabase(object):
-     """A general-purpose wrapper around a NSS cert database
- 
-@@ -547,12 +552,14 @@ class NSSDatabase(object):
-         if nss.nss_is_initialized():
-             nss.nss_shutdown()
-         nss.nss_init(self.secdir)
-+        nss.set_password_callback(get_file_cont)
-         try:
-             certdb = nss.get_default_certdb()
-             cert = nss.find_cert_from_nickname(nickname)
-             intended_usage = nss.certificateUsageSSLServer
-             try:
--                approved_usage = cert.verify_now(certdb, True, intended_usage)
-+                approved_usage = cert.verify_now(certdb, True, intended_usage,
-+                                                 self.pwd_file)
-             except NSPRError as e:
-                 if e.errno != -8102:
-                     raise ValueError(e.strerror)
-@@ -572,6 +579,7 @@ class NSSDatabase(object):
-         if nss.nss_is_initialized():
-             nss.nss_shutdown()
-         nss.nss_init(self.secdir)
-+        nss.set_password_callback(get_file_cont)
-         try:
-             certdb = nss.get_default_certdb()
-             cert = nss.find_cert_from_nickname(nickname)
-@@ -586,7 +594,8 @@ class NSSDatabase(object):
-                 raise ValueError("not a CA certificate")
-             intended_usage = nss.certificateUsageSSLCA
-             try:
--                approved_usage = cert.verify_now(certdb, True, intended_usage)
-+                approved_usage = cert.verify_now(certdb, True, intended_usage,
-+                                                 self.pwd_file)
-             except NSPRError as e:
-                 if e.errno != -8102:    # SEC_ERROR_INADEQUATE_KEY_USAGE
-                     raise ValueError(e.strerror)
--- 
-2.12.2
-
diff --git a/SOURCES/0110-restore-restart-reload-gssproxy-after-restore.patch b/SOURCES/0110-restore-restart-reload-gssproxy-after-restore.patch
deleted file mode 100644
index 5905a68..0000000
--- a/SOURCES/0110-restore-restart-reload-gssproxy-after-restore.patch
+++ /dev/null
@@ -1,77 +0,0 @@
-From 5a2424fc07c931be1788bca19726df41f02479e7 Mon Sep 17 00:00:00 2001
-From: Petr Vobornik <pvoborni@redhat.com>
-Date: Wed, 26 Apr 2017 18:47:53 +0200
-Subject: [PATCH] restore: restart/reload gssproxy after restore
-
-So that gssproxy picks up new configuration and therefore related
-usages like authentication of CLI against server works
-
-https://pagure.io/freeipa/issue/6902
-
-Reviewed-By: Tomas Krizek <tkrizek@redhat.com>
----
- ipaplatform/base/services.py     | 21 ++++++++++++++++++---
- ipaserver/install/ipa_restore.py |  3 +++
- 2 files changed, 21 insertions(+), 3 deletions(-)
-
-diff --git a/ipaplatform/base/services.py b/ipaplatform/base/services.py
-index 068b9723cab2773ca2e274e1734723371410675a..fca6298fc07e03ab4ceeba0b51286e33ae168fcc 100644
---- a/ipaplatform/base/services.py
-+++ b/ipaplatform/base/services.py
-@@ -154,6 +154,10 @@ class PlatformService(object):
- 
-         return
- 
-+    def reload_or_restart(self, instance_name="", capture_output=True,
-+                          wait=True):
-+        return
-+
-     def restart(self, instance_name="", capture_output=True, wait=True):
-         return
- 
-@@ -298,14 +302,25 @@ class SystemdService(PlatformService):
-             instance_name,
-             update_service_list=update_service_list)
- 
--    def restart(self, instance_name="", capture_output=True, wait=True):
--        ipautil.run([paths.SYSTEMCTL, "restart",
--                     self.service_instance(instance_name)],
-+    def _restart_base(self, instance_name, operation, capture_output=True,
-+                      wait=False):
-+
-+        ipautil.run([paths.SYSTEMCTL, operation,
-+                    self.service_instance(instance_name)],
-                     skip_output=not capture_output)
- 
-         if wait and self.is_running(instance_name):
-             self.wait_for_open_ports(self.service_instance(instance_name))
- 
-+    def reload_or_restart(self, instance_name="", capture_output=True,
-+                          wait=True):
-+        self._restart_base(instance_name, "reload-or-restart",
-+                           capture_output, wait)
-+
-+    def restart(self, instance_name="", capture_output=True, wait=True):
-+        self._restart_base(instance_name, "restart",
-+                           capture_output, wait)
-+
-     def is_running(self, instance_name="", wait=True):
-         instance = self.service_instance(instance_name, 'is-active')
- 
-diff --git a/ipaserver/install/ipa_restore.py b/ipaserver/install/ipa_restore.py
-index 378c013b6f4a4656768d7a484d2014a0f9eef3c0..96fc493c774f5de4c8149bf477cb66ec4960de4f 100644
---- a/ipaserver/install/ipa_restore.py
-+++ b/ipaserver/install/ipa_restore.py
-@@ -401,6 +401,9 @@ class Restore(admintool.AdminTool):
-                 services.knownservices.pki_tomcatd.enable()
-                 services.knownservices.pki_tomcatd.disable()
- 
-+                self.log.info('Restarting GSS-proxy')
-+                gssproxy = services.service('gssproxy', api)
-+                gssproxy.reload_or_restart()
-                 self.log.info('Starting IPA services')
-                 run(['ipactl', 'start'])
-                 self.log.info('Restarting SSSD')
--- 
-2.12.2
-
diff --git a/SOURCES/0111-kerberos-session-use-CA-cert-with-full-cert-chain-fo.patch b/SOURCES/0111-kerberos-session-use-CA-cert-with-full-cert-chain-fo.patch
deleted file mode 100644
index 2b6cf22..0000000
--- a/SOURCES/0111-kerberos-session-use-CA-cert-with-full-cert-chain-fo.patch
+++ /dev/null
@@ -1,39 +0,0 @@
-From 1815435956746814362ddafca4f7a967e8886d90 Mon Sep 17 00:00:00 2001
-From: Petr Vobornik <pvoborni@redhat.com>
-Date: Tue, 25 Apr 2017 17:19:36 +0200
-Subject: [PATCH] kerberos session: use CA cert with full cert chain for
- obtaining cookie
-
-Http request performed in finalize_kerberos_acquisition doesn't use
-CA certificate/certificate store with full certificate chain of IPA server.
-So it might happen that in case that IPA is installed with externally signed
-CA certificate, the call can fail because of certificate validation
-and e.g. prevent session acquisition.
-
-If it will fail for sure is not known - the use case was not discovered,
-but it is faster and safer to fix preemptively.
-
-https://pagure.io/freeipa/issue/6876
-
-Reviewed-By: Martin Basti <mbasti@redhat.com>
----
- ipaserver/rpcserver.py | 3 ++-
- 1 file changed, 2 insertions(+), 1 deletion(-)
-
-diff --git a/ipaserver/rpcserver.py b/ipaserver/rpcserver.py
-index 161872450d141a61af4345a20e278db728fe2aac..996a3d29884ca0180c39841f6986abf9b23ff13a 100644
---- a/ipaserver/rpcserver.py
-+++ b/ipaserver/rpcserver.py
-@@ -602,7 +602,8 @@ class KerberosSession(HTTP_Status):
-         try:
-             target = self.api.env.host
-             r = requests.get('http://{0}/ipa/session/cookie'.format(target),
--                             auth=NegotiateAuth(target, ccache_name))
-+                             auth=NegotiateAuth(target, ccache_name),
-+                             verify=paths.IPA_CA_CRT)
-             session_cookie = r.cookies.get("ipa_session")
-             if not session_cookie:
-                 raise ValueError('No session cookie found')
--- 
-2.12.2
-
diff --git a/SOURCES/0112-ipa-client-install-remove-extra-space-in-pkinit_anch.patch b/SOURCES/0112-ipa-client-install-remove-extra-space-in-pkinit_anch.patch
deleted file mode 100644
index 05ccb90..0000000
--- a/SOURCES/0112-ipa-client-install-remove-extra-space-in-pkinit_anch.patch
+++ /dev/null
@@ -1,34 +0,0 @@
-From 7066dcf1154f9538e9da6bcbcedb69b973509b3c Mon Sep 17 00:00:00 2001
-From: Florence Blanc-Renaud <flo@redhat.com>
-Date: Tue, 2 May 2017 10:22:22 +0200
-Subject: [PATCH] ipa-client-install: remove extra space in pkinit_anchors
- definition
-
-ipa-client-install modifies /etc/krb5.conf and defines the following line:
-    pkinit_anchors = FILE: /etc/ipa/ca.crt
-
-The extra space between FILE: and /etc/ipa/ca.crt break pkinit.
-
-https://pagure.io/freeipa/issue/6916
-
-Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
----
- ipaclient/install/client.py | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/ipaclient/install/client.py b/ipaclient/install/client.py
-index 549c9b8199255ec57cde3624d34e98d2a9be8d69..abca692fd61be4a9f35a1398fb2af4b1d9e8689b 100644
---- a/ipaclient/install/client.py
-+++ b/ipaclient/install/client.py
-@@ -710,7 +710,7 @@ def configure_krb5_conf(
-         kropts.append(krbconf.setOption('default_domain', cli_domain))
- 
-     kropts.append(
--        krbconf.setOption('pkinit_anchors', 'FILE: %s' % paths.IPA_CA_CRT))
-+        krbconf.setOption('pkinit_anchors', 'FILE:%s' % paths.IPA_CA_CRT))
-     ropts = [{
-         'name': cli_realm,
-         'type': 'subsection',
--- 
-2.12.2
-
diff --git a/SOURCES/0113-Refresh-Dogtag-RestClient.ca_host-property.patch b/SOURCES/0113-Refresh-Dogtag-RestClient.ca_host-property.patch
deleted file mode 100644
index 509618f..0000000
--- a/SOURCES/0113-Refresh-Dogtag-RestClient.ca_host-property.patch
+++ /dev/null
@@ -1,114 +0,0 @@
-From 103d784865c4ebab9085e8edda34f9cb47d70150 Mon Sep 17 00:00:00 2001
-From: Stanislav Laznicka <slaznick@redhat.com>
-Date: Thu, 27 Apr 2017 12:51:30 +0200
-Subject: [PATCH] Refresh Dogtag RestClient.ca_host property
-
-Refresh the ca_host property of the Dogtag's RestClient class when
-it's requested as a context manager.
-
-This solves the problem which would occur on DL0 when installing
-CA which needs to perform a set of steps against itself accessing
-8443 port. This port should however only be available locally so
-trying to connect to remote master would fail. We need to make
-sure the right CA host is accessed.
-
-https://pagure.io/freeipa/issue/6878
-
-Reviewed-By: Martin Basti <mbasti@redhat.com>
-Reviewed-By: Christian Heimes <cheimes@redhat.com>
----
- ipaserver/install/cainstance.py |  5 ++---
- ipaserver/plugins/dogtag.py     | 30 ++++++++++++++++++------------
- 2 files changed, 20 insertions(+), 15 deletions(-)
-
-diff --git a/ipaserver/install/cainstance.py b/ipaserver/install/cainstance.py
-index 84d60bfddc0fb968f31706e54e36557e9543846e..d72feb884964ecf49fe0166cbfeb3cb2c10737fe 100644
---- a/ipaserver/install/cainstance.py
-+++ b/ipaserver/install/cainstance.py
-@@ -425,6 +425,8 @@ class CAInstance(DogtagInstance):
-                 self.step("Configure HTTP to proxy connections",
-                           self.http_proxy)
-                 self.step("restarting certificate server", self.restart_instance)
-+                self.step("updating IPA configuration", update_ipa_conf)
-+                self.step("enabling CA instance", self.__enable_instance)
-                 if not promote:
-                     self.step("migrating certificate profiles to LDAP",
-                               migrate_profiles_to_ldap)
-@@ -432,9 +434,6 @@ class CAInstance(DogtagInstance):
-                               import_included_profiles)
-                     self.step("adding default CA ACL", ensure_default_caacl)
-                     self.step("adding 'ipa' CA entry", ensure_ipa_authority_entry)
--                self.step("updating IPA configuration", update_ipa_conf)
--
--                self.step("enabling CA instance", self.__enable_instance)
- 
-                 self.step("configuring certmonger renewal for lightweight CAs",
-                           self.__add_lightweight_ca_tracking_requests)
-diff --git a/ipaserver/plugins/dogtag.py b/ipaserver/plugins/dogtag.py
-index 3997531032746a22243a4219250af4172e9ae5b3..bddaab58a546196958811f10bb4d049db4aea524 100644
---- a/ipaserver/plugins/dogtag.py
-+++ b/ipaserver/plugins/dogtag.py
-@@ -1202,7 +1202,6 @@ import os
- import random
- from ipaserver.plugins import rabase
- from ipalib.constants import TYPE_ERROR
--from ipalib.util import cachedproperty
- from ipalib import _
- from ipaplatform.paths import paths
- 
-@@ -1250,34 +1249,41 @@ class RestClient(Backend):
-             self.client_keyfile = paths.RA_AGENT_KEY
-         super(RestClient, self).__init__(api)
- 
-+        self._ca_host = None
-         # session cookie
-         self.override_port = None
-         self.cookie = None
- 
--    @cachedproperty
-+    @property
-     def ca_host(self):
-         """
--        :return:   host
--                   as str
-+        :returns: FQDN of a host hopefully providing a CA service
- 
--        Select our CA host.
-+        Select our CA host, cache it for the first time.
-         """
-+        if self._ca_host is not None:
-+            return self._ca_host
-+
-         ldap2 = self.api.Backend.ldap2
-         if host_has_service(api.env.ca_host, ldap2, "CA"):
--            return api.env.ca_host
--        if api.env.host != api.env.ca_host:
-+            object.__setattr__(self, '_ca_host', api.env.ca_host)
-+        elif api.env.host != api.env.ca_host:
-             if host_has_service(api.env.host, ldap2, "CA"):
--                return api.env.host
--        host = select_any_master(ldap2)
--        if host:
--            return host
-+                object.__setattr__(self, '_ca_host', api.env.host)
-         else:
--            return api.env.ca_host
-+            object.__setattr__(self, '_ca_host', select_any_master(ldap2))
-+        if self._ca_host is None:
-+            object.__setattr__(self, '_ca_host', api.env.ca_host)
-+        return self._ca_host
- 
-     def __enter__(self):
-         """Log into the REST API"""
-         if self.cookie is not None:
-             return
-+
-+        # Refresh the ca_host property
-+        object.__setattr__(self, '_ca_host', None)
-+
-         status, resp_headers, _resp_body = dogtag.https_request(
-             self.ca_host, self.override_port or self.env.ca_agent_port,
-             url='/ca/rest/account/login',
--- 
-2.12.2
-
diff --git a/SOURCES/0114-Remove-the-cachedproperty-class.patch b/SOURCES/0114-Remove-the-cachedproperty-class.patch
deleted file mode 100644
index 727c632..0000000
--- a/SOURCES/0114-Remove-the-cachedproperty-class.patch
+++ /dev/null
@@ -1,71 +0,0 @@
-From 4fe9684ccd97f0c6cd32d858f681f98fb97162dc Mon Sep 17 00:00:00 2001
-From: Stanislav Laznicka <slaznick@redhat.com>
-Date: Fri, 28 Apr 2017 09:31:45 +0200
-Subject: [PATCH] Remove the cachedproperty class
-
-The cachedproperty class was used in one special use-case where it only
-caused issues. Let's get rid of it.
-
-https://pagure.io/freeipa/issue/6878
-
-Reviewed-By: Martin Basti <mbasti@redhat.com>
-Reviewed-By: Christian Heimes <cheimes@redhat.com>
----
- ipalib/util.py | 34 ----------------------------------
- 1 file changed, 34 deletions(-)
-
-diff --git a/ipalib/util.py b/ipalib/util.py
-index e9d4105775a2c9096b1718a604d31034b44bf0bd..8973a19abf56d1d1c5ba04f6edb4228dd2329e65 100644
---- a/ipalib/util.py
-+++ b/ipalib/util.py
-@@ -34,7 +34,6 @@ import dns
- import encodings
- import sys
- import ssl
--from weakref import WeakKeyDictionary
- 
- import netaddr
- from dns import resolver, rdatatype
-@@ -492,39 +491,6 @@ def remove_sshpubkey_from_output_list_post(context, entries):
-         delattr(context, 'ipasshpubkey_added')
- 
- 
--class cachedproperty(object):
--    """
--    A property-like attribute that caches the return value of a method call.
--
--    When the attribute is first read, the method is called and its return
--    value is saved and returned. On subsequent reads, the saved value is
--    returned.
--
--    Typical usage:
--    class C(object):
--        @cachedproperty
--        def attr(self):
--            return 'value'
--    """
--    __slots__ = ('getter', 'store')
--
--    def __init__(self, getter):
--        self.getter = getter
--        self.store = WeakKeyDictionary()
--
--    def __get__(self, obj, cls):
--        if obj is None:
--            return None
--        if obj not in self.store:
--            self.store[obj] = self.getter(obj)
--        return self.store[obj]
--
--    def __set__(self, obj, value):
--        raise AttributeError("can't set attribute")
--
--    def __delete__(self, obj):
--        raise AttributeError("can't delete attribute")
--
- # regexp matching signed floating point number (group 1) followed by
- # optional whitespace followed by time unit, e.g. day, hour (group 7)
- time_duration_re = re.compile(r'([-+]?((\d+)|(\d+\.\d+)|(\.\d+)|(\d+\.)))\s*([a-z]+)', re.IGNORECASE)
--- 
-2.12.2
-
diff --git a/SOURCES/0115-ipa-server-install-with-external-CA-fix-pkinit-cert-.patch b/SOURCES/0115-ipa-server-install-with-external-CA-fix-pkinit-cert-.patch
deleted file mode 100644
index 74bfec8..0000000
--- a/SOURCES/0115-ipa-server-install-with-external-CA-fix-pkinit-cert-.patch
+++ /dev/null
@@ -1,62 +0,0 @@
-From 23030ef4f4faa9bf3ee13d13dedb2e0a21da1f2a Mon Sep 17 00:00:00 2001
-From: Florence Blanc-Renaud <flo@redhat.com>
-Date: Wed, 3 May 2017 10:21:12 +0200
-Subject: [PATCH] ipa-server-install with external CA: fix pkinit cert issuance
-
-ipa-server-install with external CA fails to issue pkinit certs.
-This happens because the installer calls
-krb = krbinstance.KrbInstance(fstore)
-then
-krb.enable_ssl()
-and in this code path self.config_pkinit is set to None, leading to a wrong
-code path.
-
-The fix initializes the required fields of the krbinstance before calling
-krb.enable_ssl.
-
-https://pagure.io/freeipa/issue/6921
-
-Reviewed-By: Stanislav Laznicka <slaznick@redhat.com>
-Reviewed-By: Abhijeet Kasurde <akasurde@redhat.com>
----
- ipaserver/install/krbinstance.py    | 8 ++++++++
- ipaserver/install/server/install.py | 4 ++++
- 2 files changed, 12 insertions(+)
-
-diff --git a/ipaserver/install/krbinstance.py b/ipaserver/install/krbinstance.py
-index 76ac3029ca6d1cbdd85c6ced6272c6f9a21f04a1..2f14ff592064d3446f73b31e615b2de88d6d786c 100644
---- a/ipaserver/install/krbinstance.py
-+++ b/ipaserver/install/krbinstance.py
-@@ -108,6 +108,14 @@ class KrbInstance(service.Service):
-     suffix = ipautil.dn_attribute_property('_suffix')
-     subject_base = ipautil.dn_attribute_property('_subject_base')
- 
-+    def init_info(self, realm_name, host_name, setup_pkinit=False,
-+                  subject_base=None):
-+        self.fqdn = host_name
-+        self.realm = realm_name
-+        self.suffix = ipautil.realm_to_suffix(realm_name)
-+        self.subject_base = subject_base
-+        self.config_pkinit = setup_pkinit
-+
-     def get_realm_suffix(self):
-         return DN(('cn', self.realm), ('cn', 'kerberos'), self.suffix)
- 
-diff --git a/ipaserver/install/server/install.py b/ipaserver/install/server/install.py
-index b360e0532ce1b9b729be1cc2398cb2b46620901c..0ce60e964cb210708e56fb43a5b70f8e3405caf2 100644
---- a/ipaserver/install/server/install.py
-+++ b/ipaserver/install/server/install.py
-@@ -768,6 +768,10 @@ def install(installer):
-                             setup_pkinit=not options.no_pkinit,
-                             pkcs12_info=pkinit_pkcs12_info,
-                             subject_base=options.subject_base)
-+    else:
-+        krb.init_info(realm_name, host_name,
-+                      setup_pkinit=not options.no_pkinit,
-+                      subject_base=options.subject_base)
- 
-     if setup_ca:
-         if not options.external_cert_files and options.external_ca:
--- 
-2.12.2
-
diff --git a/SOURCES/0116-kra-install-update-installation-failure-message.patch b/SOURCES/0116-kra-install-update-installation-failure-message.patch
deleted file mode 100644
index 086a672..0000000
--- a/SOURCES/0116-kra-install-update-installation-failure-message.patch
+++ /dev/null
@@ -1,32 +0,0 @@
-From 17a0ed476c206cea4e72a262da6392f9c2ad2eff Mon Sep 17 00:00:00 2001
-From: Tomas Krizek <tkrizek@redhat.com>
-Date: Wed, 3 May 2017 15:29:55 +0200
-Subject: [PATCH] kra install: update installation failure message
-
-When installation fails, do not advise the user to use the
-obsoleted --uninstall option.
-
-Signed-off-by: Tomas Krizek <tkrizek@redhat.com>
-Fixes https://pagure.io/freeipa/issue/6923
-
-Reviewed-By: Martin Basti <mbasti@redhat.com>
----
- ipaserver/install/ipa_kra_install.py | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/ipaserver/install/ipa_kra_install.py b/ipaserver/install/ipa_kra_install.py
-index 25766541df53f034a813487321a3ad6a0ae43e57..b06d49c834d0ffa4f2e35c3241a83e42c4c9c337 100644
---- a/ipaserver/install/ipa_kra_install.py
-+++ b/ipaserver/install/ipa_kra_install.py
-@@ -103,7 +103,7 @@ class KRAInstaller(KRAInstall):
- 
-     FAIL_MESSAGE = '''
-         Your system may be partly configured.
--        Run ipa-kra-install --uninstall to clean up.
-+        If you run into issues, you may have to re-install IPA on this server.
-     '''
- 
-     def validate_options(self, needs_root=True):
--- 
-2.12.2
-
diff --git a/SOURCES/0117-Make-sure-remote-hosts-have-our-keys.patch b/SOURCES/0117-Make-sure-remote-hosts-have-our-keys.patch
deleted file mode 100644
index 37fc42f..0000000
--- a/SOURCES/0117-Make-sure-remote-hosts-have-our-keys.patch
+++ /dev/null
@@ -1,114 +0,0 @@
-From 948ab2a1f44676769e1e8c9be439606d05672c9b Mon Sep 17 00:00:00 2001
-From: Simo Sorce <simo@redhat.com>
-Date: Fri, 31 Mar 2017 11:22:45 -0400
-Subject: [PATCH] Make sure remote hosts have our keys
-
-In complex replication setups a replica may try to obtain CA keys from a
-host that is not the master we initially create the keys against.
-In this case race conditions may happen due to replication. So we need
-to make sure the server we are contacting to get the CA keys has our
-keys in LDAP. We do this by waiting to positively fetch our encryption
-public key (the last one we create) from the target host LDAP server.
-
-Fixes: https://pagure.io/freeipa/issue/6838
-
-Signed-off-by: Simo Sorce <simo@redhat.com>
-Reviewed-By: Stanislav Laznicka <slaznick@redhat.com>
-Reviewed-By: Christian Heimes <cheimes@redhat.com>
----
- ipaserver/install/custodiainstance.py | 28 +++++++++++++++++++++++++++-
- ipaserver/secrets/kem.py              | 12 ++++++++++++
- 2 files changed, 39 insertions(+), 1 deletion(-)
-
-diff --git a/ipaserver/install/custodiainstance.py b/ipaserver/install/custodiainstance.py
-index 6a613923163bccd1b59e0c3b3672905715a8de7c..390576bc0c0edfb7d8f8895eca9df30079526aa8 100644
---- a/ipaserver/install/custodiainstance.py
-+++ b/ipaserver/install/custodiainstance.py
-@@ -1,6 +1,6 @@
- # Copyright (C) 2015 FreeIPa Project Contributors, see 'COPYING' for license.
- 
--from ipaserver.secrets.kem import IPAKEMKeys
-+from ipaserver.secrets.kem import IPAKEMKeys, KEMLdap
- from ipaserver.secrets.client import CustodiaClient
- from ipaplatform.paths import paths
- from ipaplatform.constants import constants
-@@ -18,6 +18,7 @@ import shutil
- import os
- import stat
- import tempfile
-+import time
- import pwd
- 
- 
-@@ -122,6 +123,27 @@ class CustodiaInstance(SimpleServiceInstance):
-         cli = self.__CustodiaClient(server=master_host_name)
-         cli.fetch_key('dm/DMHash')
- 
-+    def __wait_keys(self, host, timeout=300):
-+        ldap_uri = 'ldap://%s' % host
-+        deadline = int(time.time()) + timeout
-+        root_logger.info("Waiting up to {} seconds to see our keys "
-+                         "appear on host: {}".format(timeout, host))
-+
-+        konn = KEMLdap(ldap_uri)
-+        saved_e = None
-+        while True:
-+            try:
-+                return konn.check_host_keys(self.fqdn)
-+            except Exception as e:
-+                # log only once for the same error
-+                if not isinstance(e, type(saved_e)):
-+                    root_logger.debug(
-+                        "Transient error getting keys: '{err}'".format(err=e))
-+                    saved_e = e
-+                if int(time.time()) > deadline:
-+                    raise RuntimeError("Timed out trying to obtain keys.")
-+                time.sleep(1)
-+
-     def __get_keys(self, ca_host, cacerts_file, cacerts_pwd, data):
-         # Fecth all needed certs one by one, then combine them in a single
-         # p12 file
-@@ -129,6 +151,10 @@ class CustodiaInstance(SimpleServiceInstance):
-         prefix = data['prefix']
-         certlist = data['list']
- 
-+        # Before we attempt to fetch keys from this host, make sure our public
-+        # keys have been replicated there.
-+        self.__wait_keys(ca_host)
-+
-         cli = self.__CustodiaClient(server=ca_host)
- 
-         # Temporary nssdb
-diff --git a/ipaserver/secrets/kem.py b/ipaserver/secrets/kem.py
-index 28fb4d31b35fc96c77ddd3f09cb3927efb4000fa..c1991c6b2ae00ed7147b2ec18389e463784b9f98 100644
---- a/ipaserver/secrets/kem.py
-+++ b/ipaserver/secrets/kem.py
-@@ -24,6 +24,7 @@ import ldap
- 
- IPA_REL_BASE_DN = 'cn=custodia,cn=ipa,cn=etc'
- IPA_KEYS_QUERY = '(&(ipaKeyUsage={usage:s})(memberPrincipal={princ:s}))'
-+IPA_CHECK_QUERY = '(cn=enc/{host:s})'
- RFC5280_USAGE_MAP = {KEY_USAGE_SIG: 'digitalSignature',
-                      KEY_USAGE_ENC: 'dataEncipherment'}
- 
-@@ -78,6 +79,17 @@ class KEMLdap(iSecLdap):
-         jwk['use'] = KEY_USAGE_MAP[usage]
-         return json_encode(jwk)
- 
-+    def check_host_keys(self, host):
-+        conn = self.connect()
-+        scope = ldap.SCOPE_SUBTREE
-+
-+        ldap_filter = self.build_filter(IPA_CHECK_QUERY, {'host': host})
-+        r = conn.search_s(self.keysbase, scope, ldap_filter)
-+        if len(r) != 1:
-+            raise ValueError("Incorrect number of results (%d) searching for"
-+                             "public key for %s" % (len(r), host))
-+        return True
-+
-     def _format_public_key(self, key):
-         if isinstance(key, str):
-             jwkey = json_decode(key)
--- 
-2.12.2
-
diff --git a/SOURCES/0118-Use-proper-SELinux-context-with-http.keytab.patch b/SOURCES/0118-Use-proper-SELinux-context-with-http.keytab.patch
deleted file mode 100644
index d5c36af..0000000
--- a/SOURCES/0118-Use-proper-SELinux-context-with-http.keytab.patch
+++ /dev/null
@@ -1,40 +0,0 @@
-From 488c433c369bfcd13e95d910b500c455a01715b6 Mon Sep 17 00:00:00 2001
-From: Martin Basti <mbasti@redhat.com>
-Date: Wed, 3 May 2017 13:51:02 +0200
-Subject: [PATCH] Use proper SELinux context with http.keytab
-
-During upgrade keytab is moved to a new location using "move" operation.
-This commit replaces move operation with "copy" and "remove" that
-ensures a proper selinux context.
-
-https://pagure.io/freeipa/issue/6924
-
-Reviewed-By: Martin Babinsky <mbabinsk@redhat.com>
----
- ipaserver/install/server/upgrade.py | 10 +++++++++-
- 1 file changed, 9 insertions(+), 1 deletion(-)
-
-diff --git a/ipaserver/install/server/upgrade.py b/ipaserver/install/server/upgrade.py
-index 0f27428dd492bb44dd8c69a7e7f47abb531843f5..4d8fd666dfd4e918103b449d4c31bb7661727115 100644
---- a/ipaserver/install/server/upgrade.py
-+++ b/ipaserver/install/server/upgrade.py
-@@ -1427,7 +1427,15 @@ def update_ipa_httpd_service_conf(http):
- def update_http_keytab(http):
-     root_logger.info('[Moving HTTPD service keytab to gssproxy]')
-     if os.path.exists(paths.OLD_IPA_KEYTAB):
--        shutil.move(paths.OLD_IPA_KEYTAB, http.keytab)
-+        # ensure proper SELinux context by using copy operation
-+        shutil.copy(paths.OLD_IPA_KEYTAB, http.keytab)
-+        try:
-+            os.remove(paths.OLD_IPA_KEYTAB)
-+        except OSError as e:
-+            root_logger.error(
-+                'Cannot remove file %s (%s). Please remove the file manually.',
-+                paths.OLD_IPA_KEYTAB, e
-+            )
-     pent = pwd.getpwnam(http.keytab_user)
-     os.chown(http.keytab, pent.pw_uid, pent.pw_gid)
- 
--- 
-2.12.2
-
diff --git a/SOURCES/0119-ipa-kra-install-fix-check_host_keys.patch b/SOURCES/0119-ipa-kra-install-fix-check_host_keys.patch
deleted file mode 100644
index 50522f5..0000000
--- a/SOURCES/0119-ipa-kra-install-fix-check_host_keys.patch
+++ /dev/null
@@ -1,47 +0,0 @@
-From 85cd84580f45c99b6ab49814ead7eb2f259ca444 Mon Sep 17 00:00:00 2001
-From: Florence Blanc-Renaud <flo@redhat.com>
-Date: Fri, 5 May 2017 17:06:09 +0200
-Subject: [PATCH] ipa-kra-install: fix check_host_keys
-
-ipa-kra-install on a replica checks that the keys are available before
-going further to avoid race condition due to replication. The issue is
-that the check_host_keys method expects to find exactly one key for
-cn=env/host but 2 may exist: one below cn=custodia and one below
-cn=dogtag,cn=custodia.
-The fix is to check that at least one key exist (not exactly one key).
-
-https://pagure.io/freeipa/issue/6934
-
-Reviewed-By: Martin Basti <mbasti@redhat.com>
----
- ipaserver/secrets/kem.py | 7 +++----
- 1 file changed, 3 insertions(+), 4 deletions(-)
-
-diff --git a/ipaserver/secrets/kem.py b/ipaserver/secrets/kem.py
-index c1991c6b2ae00ed7147b2ec18389e463784b9f98..3363d82fef54c463f498edeb95ddee454b20d31d 100644
---- a/ipaserver/secrets/kem.py
-+++ b/ipaserver/secrets/kem.py
-@@ -72,7 +72,7 @@ class KEMLdap(iSecLdap):
-                                          'princ': principal})
-         r = conn.search_s(self.keysbase, scope, ldap_filter)
-         if len(r) != 1:
--            raise ValueError("Incorrect number of results (%d) searching for"
-+            raise ValueError("Incorrect number of results (%d) searching for "
-                              "public key for %s" % (len(r), principal))
-         ipa_public_key = r[0][1]['ipaPublicKey'][0]
-         jwk = self._parse_public_key(ipa_public_key)
-@@ -85,9 +85,8 @@ class KEMLdap(iSecLdap):
- 
-         ldap_filter = self.build_filter(IPA_CHECK_QUERY, {'host': host})
-         r = conn.search_s(self.keysbase, scope, ldap_filter)
--        if len(r) != 1:
--            raise ValueError("Incorrect number of results (%d) searching for"
--                             "public key for %s" % (len(r), host))
-+        if not r:
-+            raise ValueError("No public keys were found for %s" % host)
-         return True
- 
-     def _format_public_key(self, key):
--- 
-2.12.2
-
diff --git a/SOURCES/0120-python2-ipalib-add-missing-python-dependency.patch b/SOURCES/0120-python2-ipalib-add-missing-python-dependency.patch
deleted file mode 100644
index ef73fef..0000000
--- a/SOURCES/0120-python2-ipalib-add-missing-python-dependency.patch
+++ /dev/null
@@ -1,30 +0,0 @@
-From d0df144c6411bc0966dfd475c5d781ac5d44f476 Mon Sep 17 00:00:00 2001
-From: Tomas Krizek <tkrizek@redhat.com>
-Date: Tue, 2 May 2017 18:32:34 +0200
-Subject: [PATCH] python2-ipalib: add missing python dependency
-
-Commit dfd560a190cb2ab13f34ed9e21c5fb5c6e793f18 started to use
-ssl symbols like ssl.OP_NO_SSLv2 that were introduced in Python 2.7.9.
-
-Related https://pagure.io/freeipa/issue/6920
-
-Reviewed-By: Martin Babinsky <mbabinsk@redhat.com>
----
- freeipa.spec.in | 1 +
- 1 file changed, 1 insertion(+)
-
-diff --git a/freeipa.spec.in b/freeipa.spec.in
-index 3b7410b6bda3afc877d928b4df21529ae2faf0aa..1dd550bd39fd14349ede58bde337783aa5c0ea04 100644
---- a/freeipa.spec.in
-+++ b/freeipa.spec.in
-@@ -639,6 +639,7 @@ Requires: python-gssapi >= 1.2.0
- Requires: gnupg
- Requires: keyutils
- Requires: pyOpenSSL
-+Requires: python >= 2.7.9
- Requires: python-nss >= 0.16
- Requires: python-cryptography >= 1.4
- Requires: python-netaddr
--- 
-2.9.3
-
diff --git a/SOURCES/0121-installer-service-fix-typo-in-service-entry.patch b/SOURCES/0121-installer-service-fix-typo-in-service-entry.patch
deleted file mode 100644
index 4bb270e..0000000
--- a/SOURCES/0121-installer-service-fix-typo-in-service-entry.patch
+++ /dev/null
@@ -1,31 +0,0 @@
-From b7c0c372c3d78e60f5b2889c88f4f3b4a5abdcad Mon Sep 17 00:00:00 2001
-From: Tomas Krizek <tkrizek@redhat.com>
-Date: Tue, 2 May 2017 18:42:13 +0200
-Subject: [PATCH] installer service: fix typo in service entry
-
-The typo would result in incorrect resolution of existing keys and
-their existence wasn't properly logged as intended.
-
-Related https://pagure.io/freeipa/issue/6920
-
-Reviewed-By: Martin Babinsky <mbabinsk@redhat.com>
----
- ipaserver/install/service.py | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/ipaserver/install/service.py b/ipaserver/install/service.py
-index 6b5e69ccd08444c591f15eb680b4cbdf5b6f4de1..1aa49ed25b25366afd2bb17073b4b214c231d54b 100644
---- a/ipaserver/install/service.py
-+++ b/ipaserver/install/service.py
-@@ -181,7 +181,7 @@ def set_service_entry_config(name, fqdn, config_values,
-     except errors.NotFound:
-         pass
-     else:
--        existing_values = entry.get('ipaConnfigString', [])
-+        existing_values = entry.get('ipaConfigString', [])
-         for value in config_values:
-             if case_insensitive_attr_has_value(existing_values, value):
-                 root_logger.debug(
--- 
-2.9.3
-
diff --git a/SOURCES/0122-upgrade-add-missing-suffix-to-http-instance.patch b/SOURCES/0122-upgrade-add-missing-suffix-to-http-instance.patch
deleted file mode 100644
index 2dbb567..0000000
--- a/SOURCES/0122-upgrade-add-missing-suffix-to-http-instance.patch
+++ /dev/null
@@ -1,31 +0,0 @@
-From b16fba6f07455cc62284f0a225e2cd6aa6253efb Mon Sep 17 00:00:00 2001
-From: Tomas Krizek <tkrizek@redhat.com>
-Date: Tue, 2 May 2017 19:26:04 +0200
-Subject: [PATCH] upgrade: add missing suffix to http instance
-
-During an upgrade, http.suffix is used to identify ldap entry when
-configuring kdc proxy. When the suffix is missing, the script crashed
-when enabling KDC proxy, because it used invalid DN.
-
-Fixes https://pagure.io/freeipa/issue/6920
-
-Reviewed-By: Martin Babinsky <mbabinsk@redhat.com>
----
- ipaserver/install/server/upgrade.py | 1 +
- 1 file changed, 1 insertion(+)
-
-diff --git a/ipaserver/install/server/upgrade.py b/ipaserver/install/server/upgrade.py
-index 4d8fd666dfd4e918103b449d4c31bb7661727115..9aec2d857aee1a601f351218e253d44b14f6d4ec 100644
---- a/ipaserver/install/server/upgrade.py
-+++ b/ipaserver/install/server/upgrade.py
-@@ -1638,6 +1638,7 @@ def upgrade_configuration():
-     http = httpinstance.HTTPInstance(fstore)
-     http.fqdn = fqdn
-     http.realm = api.env.realm
-+    http.suffix = ipautil.realm_to_suffix(api.env.realm)
-     http.configure_selinux_for_httpd()
-     http.change_mod_nss_port_from_http()
- 
--- 
-2.9.3
-
diff --git a/SOURCES/0123-Turn-on-NSSOCSP-check-in-mod_nss-conf.patch b/SOURCES/0123-Turn-on-NSSOCSP-check-in-mod_nss-conf.patch
deleted file mode 100644
index 8d4caa9..0000000
--- a/SOURCES/0123-Turn-on-NSSOCSP-check-in-mod_nss-conf.patch
+++ /dev/null
@@ -1,227 +0,0 @@
-From e8f329dd4340d5216d86160a8065e0530b981b47 Mon Sep 17 00:00:00 2001
-From: Pavel Vomacka <pvomacka@redhat.com>
-Date: Thu, 6 Apr 2017 16:15:47 +0200
-Subject: [PATCH] Turn on NSSOCSP check in mod_nss conf
-
-Turn on NSSOCSP directive during install/replica install/upgrade.
-That check whether the certificate which is used for login is
-revoked or not using OSCP.
-
-Marks the server cert in httpd NSS DB as trusted peer ('P,,')
-to avoid chicken and egg problem when it is needed to contact
-the OCSP responder when httpd is starting.
-
-https://pagure.io/freeipa/issue/6370
-
-Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
-Reviewed-By: Rob Crittenden <rcritten@redhat.com>
-Reviewed-By: Jan Cholasta <jcholast@redhat.com>
-Reviewed-By: Martin Basti <mbasti@redhat.com>
----
- freeipa.spec.in                       |  4 ++++
- install/restart_scripts/restart_httpd | 14 +++++++++++++-
- ipaserver/install/httpinstance.py     | 30 ++++++++++++++++++++++++++++++
- ipaserver/install/server/upgrade.py   | 25 +++++++++++++++++++++++++
- ipaserver/setup.py                    |  1 +
- 5 files changed, 73 insertions(+), 1 deletion(-)
-
-diff --git a/freeipa.spec.in b/freeipa.spec.in
-index 1dd550bd39fd14349ede58bde337783aa5c0ea04..1b3ed15036eab6262b144d970cbdfdad31ac13ea 100644
---- a/freeipa.spec.in
-+++ b/freeipa.spec.in
-@@ -195,6 +195,7 @@ BuildRequires:  python-nose
- BuildRequires:  python-paste
- BuildRequires:  systemd-python
- BuildRequires:  python2-jinja2
-+BuildRequires:  python-augeas
- 
- %if 0%{?with_python3}
- # FIXME: this depedency is missing - server will not work
-@@ -232,6 +233,7 @@ BuildRequires:  python3-nose
- BuildRequires:  python3-paste
- BuildRequires:  python3-systemd
- BuildRequires:  python3-jinja2
-+BuildRequires:  python3-augeas
- %endif # with_python3
- %endif # with_lint
- 
-@@ -355,6 +357,7 @@ Requires: python-dns >= 1.15
- Requires: python-kdcproxy >= 0.3
- Requires: rpm-libs
- Requires: pki-base-python2
-+Requires: python-augeas
- 
- %description -n python2-ipaserver
- IPA is an integrated solution to provide centrally managed Identity (users,
-@@ -384,6 +387,7 @@ Requires: python3-pyasn1
- Requires: python3-dbus
- Requires: python3-dns >= 1.15
- Requires: python3-kdcproxy >= 0.3
-+Requires: python3-augeas
- Requires: rpm-libs
- Requires: pki-base-python3
- 
-diff --git a/install/restart_scripts/restart_httpd b/install/restart_scripts/restart_httpd
-index d1684812904a9d32842a0ca548ec6b9df5a5a0b7..b661b82b896b109c3859ac82c2d84ab27b839f72 100644
---- a/install/restart_scripts/restart_httpd
-+++ b/install/restart_scripts/restart_httpd
-@@ -21,11 +21,23 @@
- 
- import syslog
- import traceback
-+from ipalib import api
- from ipaplatform import services
--from ipaserver.install import certs
-+from ipaplatform.paths import paths
-+from ipaserver.install import certs, installutils
- 
- 
- def _main():
-+
-+    api.bootstrap(in_server=True, context='restart', confdir=paths.ETC_IPA)
-+    api.finalize()
-+
-+    db = certs.CertDB(api.env.realm, nssdir=paths.HTTPD_ALIAS_DIR)
-+    nickname = installutils.get_directive(paths.HTTPD_NSS_CONF, "NSSNickname")
-+
-+    # Add trust flag which set certificate trusted for SSL connections.
-+    db.trust_root_cert(nickname, "P,,")
-+
-     syslog.syslog(syslog.LOG_NOTICE, 'certmonger restarted httpd')
- 
-     try:
-diff --git a/ipaserver/install/httpinstance.py b/ipaserver/install/httpinstance.py
-index 7898c53bc02785e2750dba61a5696f079355c9d7..ab688a85f157b1886842a91bb7d22f9ea99e3615 100644
---- a/ipaserver/install/httpinstance.py
-+++ b/ipaserver/install/httpinstance.py
-@@ -29,6 +29,7 @@ import pipes
- import locale
- 
- import six
-+from augeas import Augeas
- 
- from ipalib.install import certmonger
- from ipaserver.install import service
-@@ -153,6 +154,7 @@ class HTTPInstance(service.Service):
-                   self.set_mod_nss_protocol)
-         self.step("setting mod_nss password file", self.__set_mod_nss_passwordfile)
-         self.step("enabling mod_nss renegotiate", self.enable_mod_nss_renegotiate)
-+        self.step("enabling mod_nss OCSP", self.enable_mod_nss_ocsp)
-         self.step("adding URL rewriting rules", self.__add_include)
-         self.step("configuring httpd", self.__configure_http)
-         self.step("setting up httpd keytab", self.request_service_keytab)
-@@ -259,6 +261,31 @@ class HTTPInstance(service.Service):
-         installutils.set_directive(paths.HTTPD_NSS_CONF, 'NSSRenegotiation', 'on', False)
-         installutils.set_directive(paths.HTTPD_NSS_CONF, 'NSSRequireSafeNegotiation', 'on', False)
- 
-+    def enable_mod_nss_ocsp(self):
-+        aug = Augeas(flags=Augeas.NO_LOAD | Augeas.NO_MODL_AUTOLOAD)
-+
-+        aug.set('/augeas/load/Httpd/lens', 'Httpd.lns')
-+        aug.set('/augeas/load/Httpd/incl', paths.HTTPD_NSS_CONF)
-+        aug.load()
-+
-+        path = '/files{}/VirtualHost'.format(paths.HTTPD_NSS_CONF)
-+
-+        ocsp_comment = aug.get(
-+                        '{}/#comment[.=~regexp("NSSOCSP .*")]'.format(path))
-+        ocsp_dir = aug.get('{}/directive[.="NSSOCSP"]'.format(path))
-+
-+        if ocsp_dir is None and ocsp_comment is not None:
-+            # Directive is missing, comment is present
-+            aug.set('{}/#comment[.=~regexp("NSSOCSP .*")]'.format(path),
-+                    'NSSOCSP')
-+            aug.rename('{}/#comment[.="NSSOCSP"]'.format(path), 'directive')
-+        elif ocsp_dir is None:
-+            # Directive is missing and comment is missing
-+            aug.set('{}/directive[last()+1]'.format(path), "NSSOCSP")
-+
-+        aug.set('{}/directive[. = "NSSOCSP"]/arg'.format(path), 'on')
-+        aug.save()
-+
-     def set_mod_nss_cipher_suite(self):
-         ciphers = ','.join(NSS_CIPHER_SUITE)
-         installutils.set_directive(paths.HTTPD_NSS_CONF, 'NSSCipherSuite', ciphers, False)
-@@ -351,6 +378,7 @@ class HTTPInstance(service.Service):
-                           create=True)
-         self.disable_system_trust()
-         self.create_password_conf()
-+
-         if self.pkcs12_info:
-             if self.ca_is_configured:
-                 trust_flags = 'CT,C,C'
-@@ -375,6 +403,8 @@ class HTTPInstance(service.Service):
-             self.__set_mod_nss_nickname(nickname)
-             self.add_cert_to_service()
- 
-+            db.trust_root_cert(nickname, "P,,")
-+
-         else:
-             if not self.promote:
-                 ca_args = [
-diff --git a/ipaserver/install/server/upgrade.py b/ipaserver/install/server/upgrade.py
-index 9aec2d857aee1a601f351218e253d44b14f6d4ec..7b0476d442902f2c3dc65819d54953e820f5e560 100644
---- a/ipaserver/install/server/upgrade.py
-+++ b/ipaserver/install/server/upgrade.py
-@@ -1392,6 +1392,24 @@ def fix_trust_flags():
-     sysupgrade.set_upgrade_state('http', 'fix_trust_flags', True)
- 
- 
-+def fix_server_cert_trust_flags():
-+    root_logger.info(
-+        '[Fixing server certificate trust flags in %s]' %
-+        paths.HTTPD_ALIAS_DIR)
-+
-+    if sysupgrade.get_upgrade_state('http', 'fix_serv_cert_trust_flags'):
-+        root_logger.info("Trust flags already processed")
-+        return
-+
-+    db = certs.CertDB(api.env.realm, nssdir=paths.HTTPD_ALIAS_DIR)
-+    sc_nickname = installutils.get_directive(paths.HTTPD_NSS_CONF,
-+                                             "NSSNickname")
-+    # Add trust flag which set certificate trusted for SSL connections.
-+    db.trust_root_cert(sc_nickname, "P,,")
-+
-+    sysupgrade.set_upgrade_state('http', 'fix_serv_cert_trust_flags', True)
-+
-+
- def update_mod_nss_protocol(http):
-     root_logger.info('[Updating mod_nss protocol versions]')
- 
-@@ -1404,6 +1422,11 @@ def update_mod_nss_protocol(http):
-     sysupgrade.set_upgrade_state('nss.conf', 'protocol_updated_tls12', True)
- 
- 
-+def enable_mod_nss_ocsp(http):
-+    root_logger.info('[Updating mod_nss enabling OCSP]')
-+    http.enable_mod_nss_ocsp()
-+
-+
- def update_mod_nss_cipher_suite(http):
-     root_logger.info('[Updating mod_nss cipher suite]')
- 
-@@ -1671,7 +1694,9 @@ def upgrade_configuration():
-     update_ipa_httpd_service_conf(http)
-     update_mod_nss_protocol(http)
-     update_mod_nss_cipher_suite(http)
-+    enable_mod_nss_ocsp(http)
-     fix_trust_flags()
-+    fix_server_cert_trust_flags()
-     update_http_keytab(http)
-     http.configure_gssproxy()
-     http.start()
-diff --git a/ipaserver/setup.py b/ipaserver/setup.py
-index 42b0c1b0618ef9867acb1fe2add5702a756cf2d2..e0b69e547ef8c2b76ce14ab27c1c29260e33f57f 100755
---- a/ipaserver/setup.py
-+++ b/ipaserver/setup.py
-@@ -60,6 +60,7 @@ if __name__ == '__main__':
-             "pyasn1",
-             "pyldap",
-             "six",
-+            "python-augeas",
-             # not available on PyPI
-             # "python-libipa_hbac",
-             # "python-sss",
--- 
-2.9.3
-
diff --git a/SOURCES/0124-cert-show-writable-files-does-not-mean-dirs.patch b/SOURCES/0124-cert-show-writable-files-does-not-mean-dirs.patch
deleted file mode 100644
index 70b071f..0000000
--- a/SOURCES/0124-cert-show-writable-files-does-not-mean-dirs.patch
+++ /dev/null
@@ -1,31 +0,0 @@
-From 348fdfd66d9b3ab0214af91d193ae93b9969610e Mon Sep 17 00:00:00 2001
-From: Stanislav Laznicka <slaznick@redhat.com>
-Date: Tue, 9 May 2017 17:49:56 +0200
-Subject: [PATCH] cert-show: writable files does not mean dirs
-
-ipalib.util.check_writable_file didn't check whether the argument
-is an actual file which is now fixed.
-
-https://pagure.io/freeipa/issue/6883
-
-Reviewed-By: Fraser Tweedale <ftweedal@redhat.com>
----
- ipalib/util.py | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/ipalib/util.py b/ipalib/util.py
-index 8973a19abf56d1d1c5ba04f6edb4228dd2329e65..713fc107e9374eefe7805bc4e1abc40b6d150c32 100644
---- a/ipalib/util.py
-+++ b/ipalib/util.py
-@@ -170,7 +170,7 @@ def check_writable_file(filename):
-     if filename is None:
-         raise errors.FileError(reason=_('Filename is empty'))
-     try:
--        if os.path.exists(filename):
-+        if os.path.isfile(filename):
-             if not os.access(filename, os.W_OK):
-                 raise errors.FileError(reason=_('Permission denied: %(file)s') % dict(file=filename))
-         else:
--- 
-2.9.3
-
diff --git a/SOURCES/0125-Bump-version-of-ipa.conf-file.patch b/SOURCES/0125-Bump-version-of-ipa.conf-file.patch
deleted file mode 100644
index d45ab9c..0000000
--- a/SOURCES/0125-Bump-version-of-ipa.conf-file.patch
+++ /dev/null
@@ -1,30 +0,0 @@
-From dd433bd402b847b651ba2aa722e4b37c3235984b Mon Sep 17 00:00:00 2001
-From: David Kupka <dkupka@redhat.com>
-Date: Thu, 11 May 2017 10:17:33 +0200
-Subject: [PATCH] Bump version of ipa.conf file
-
-In commit 157831a287c64106eed4 the version bump was forgotten and therefore the
-ipa.conf file is not replaced during upgrade and login using certificate when
-single certificate is mapped to multiple users doesn't work.
-
-https://pagure.io/freeipa/issue/6860
-
-Reviewed-By: Martin Basti <mbasti@redhat.com>
----
- install/conf/ipa.conf | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/install/conf/ipa.conf b/install/conf/ipa.conf
-index 75c122e6c94b941c278d724add84315753082531..a7ca5ce715e55960b8edd307cdbe41dcbd6b29ca 100644
---- a/install/conf/ipa.conf
-+++ b/install/conf/ipa.conf
-@@ -1,5 +1,5 @@
- #
--# VERSION 25 - DO NOT REMOVE THIS LINE
-+# VERSION 26 - DO NOT REMOVE THIS LINE
- #
- # This file may be overwritten on upgrades.
- #
--- 
-2.9.3
-
diff --git a/SOURCES/0126-ipa-kra-install-manpage-document-domain-level-1.patch b/SOURCES/0126-ipa-kra-install-manpage-document-domain-level-1.patch
deleted file mode 100644
index 35e0738..0000000
--- a/SOURCES/0126-ipa-kra-install-manpage-document-domain-level-1.patch
+++ /dev/null
@@ -1,72 +0,0 @@
-From 6534557508ba2ae7bda4ec2f2508d80dcef8297f Mon Sep 17 00:00:00 2001
-From: Florence Blanc-Renaud <flo@redhat.com>
-Date: Wed, 10 May 2017 18:04:52 +0200
-Subject: [PATCH] ipa-kra-install manpage: document domain-level 1
-
-ipa-kra-install man page was missing a specific section for domain level 1.
-This commits also fixes a wrong option short name (for --log-file) and
-indents the text corresponding to -p DM_PASSWORD
-
-https://pagure.io/freeipa/issue/6922
-
-Reviewed-By: Tomas Krizek <tkrizek@redhat.com>
----
- install/tools/man/ipa-kra-install.1 | 17 ++++++++++++++---
- 1 file changed, 14 insertions(+), 3 deletions(-)
-
-diff --git a/install/tools/man/ipa-kra-install.1 b/install/tools/man/ipa-kra-install.1
-index 0aa9073c3303bd852627e430102ceb40575decc4..51afaac6474a9483e8c02bae605fe95994cce1f2 100644
---- a/install/tools/man/ipa-kra-install.1
-+++ b/install/tools/man/ipa-kra-install.1
-@@ -16,26 +16,37 @@
- .\"
- .\" Author: Ade Lee <alee@redhat.com>
- .\"
--.TH "ipa-kra-install" "1" "Aug 24 2014" "FreeIPA" "FreeIPA Manual Pages"
-+.TH "ipa-kra-install" "1" "May 10 2017" "FreeIPA" "FreeIPA Manual Pages"
- .SH "NAME"
- ipa\-kra\-install \- Install a KRA on a server
- .SH "SYNOPSIS"
-+.SS "DOMAIN LEVEL 0"
-+.TP
- ipa\-kra\-install [\fIOPTION\fR]... [replica_file]
-+.SS "DOMAIN LEVEL 1"
-+.TP
-+ipa\-kra\-install [\fIOPTION\fR]...
- .SH "DESCRIPTION"
- Adds a KRA as an IPA\-managed service. This requires that the IPA server is already installed and configured, including a CA.
- 
- The KRA (Key Recovery Authority) is a component used to securely store secrets such as passwords, symmetric keys and private asymmetric keys.  It is used as the back-end repository for the IPA Password Vault.
- 
--ipa\-kra\-install can be run without replica_file to add KRA to the existing CA.
-+In a domain at domain level 0, ipa\-kra\-install can be run without replica_file to add KRA to the existing CA, or with replica_file to install the KRA service on the replica.
- ipa\-kra\-install will contact the CA to determine if a KRA has already been installed on another replica, and if so, will exit indicating that a replica_file is required.
- 
- The replica_file is created using the ipa\-replica\-prepare utility.  A new replica_file should be generated on the master IPA server after the KRA has been installed and configured, so that the replica_file will contain the master KRA configuration and system certificates.
- 
-+In a domain at domain level 1, ipa\-kra\-install can be used to add KRA to the existing CA, or to install the KRA service on a replica, and does not require any replica file.
-+
- KRA can only be removed along with the entire server using ipa\-server\-install \-\-uninstall.
- .SH "OPTIONS"
-+.TP
- \fB\-p\fR \fIDM_PASSWORD\fR, \fB\-\-password\fR=\fIDM_PASSWORD\fR
- Directory Manager (existing master) password
- .TP
-+\fB\-\-no-host-dns\fR
-+Do not use DNS for hostname lookup during installation
-+.TP
- \fB\-U\fR, \fB\-\-unattended\fR
- An unattended installation that will never prompt for user input
- .TP
-@@ -45,7 +56,7 @@ Enable debug output when more verbose output is needed
- \fB\-q\fR, \fB\-\-quiet\fR
- Output only errors
- .TP
--\fB\-v\fR, \fB\-\-log-file\fR=\fFILE\fR
-+\fB\-\-log-file\fR=\fRFILE\fR
- Log to the given file
- .SH "EXIT STATUS"
- 0 if the command was successful
--- 
-2.9.3
-
diff --git a/SOURCES/0127-renew-agent-respect-CA-renewal-master-setting.patch b/SOURCES/0127-renew-agent-respect-CA-renewal-master-setting.patch
deleted file mode 100644
index a1aafa9..0000000
--- a/SOURCES/0127-renew-agent-respect-CA-renewal-master-setting.patch
+++ /dev/null
@@ -1,54 +0,0 @@
-From 55e779b19714532744c8b22e514e9e49563350e3 Mon Sep 17 00:00:00 2001
-From: Jan Cholasta <jcholast@redhat.com>
-Date: Mon, 24 Apr 2017 05:24:24 +0000
-Subject: [PATCH] renew agent: respect CA renewal master setting
-
-Do not bypass the renewal master check when a non-virtual profile is used
-in dogtag-ipa-ca-renew-agent-submit.
-
-This fixes dogtag-ipa-ca-renew-agent not respecting the CA renewal master
-setting for certificates tracked with a real profile. (Note that there
-currently aren't any such certificates tracked by us.)
-
-Request the RA certificate using dogtag-submit rather than
-dogtag-ipa-ca-renew-agent-submit as the CA renewal master setting is not
-available so early in the install process.
-
-https://pagure.io/freeipa/issue/5799
-
-Reviewed-By: David Kupka <dkupka@redhat.com>
-Reviewed-By: Stanislav Laznicka <slaznick@redhat.com>
----
- install/certmonger/dogtag-ipa-ca-renew-agent-submit | 2 +-
- ipaserver/install/cainstance.py                     | 2 +-
- 2 files changed, 2 insertions(+), 2 deletions(-)
-
-diff --git a/install/certmonger/dogtag-ipa-ca-renew-agent-submit b/install/certmonger/dogtag-ipa-ca-renew-agent-submit
-index 7a3d9551884c0fe43566dd9012699211a39294eb..f253fd9587ac1ef3ece712ca9999c1ea4f3d55d8 100755
---- a/install/certmonger/dogtag-ipa-ca-renew-agent-submit
-+++ b/install/certmonger/dogtag-ipa-ca-renew-agent-submit
-@@ -535,7 +535,7 @@ def main():
- 
-         profile = os.environ.get('CERTMONGER_CA_PROFILE')
-         if is_replicated():
--            if profile or is_renewal_master():
-+            if is_renewal_master():
-                 handler = request_and_store_cert
-             else:
-                 handler = retrieve_cert_continuous
-diff --git a/ipaserver/install/cainstance.py b/ipaserver/install/cainstance.py
-index d72feb884964ecf49fe0166cbfeb3cb2c10737fe..97baa606c960806376e025b5654eea816da207ed 100644
---- a/ipaserver/install/cainstance.py
-+++ b/ipaserver/install/cainstance.py
-@@ -822,7 +822,7 @@ class CAInstance(DogtagInstance):
-              "-out", chain_file.name,
-              ], stdin=data, capture_output=False)
- 
--        agent_args = [paths.DOGTAG_IPA_CA_RENEW_AGENT_SUBMIT,
-+        agent_args = [paths.CERTMONGER_DOGTAG_SUBMIT,
-                       "--dbdir", self.tmp_agent_db,
-                       "--nickname", "ipa-ca-agent",
-                       "--cafile", chain_file.name,
--- 
-2.9.3
-
diff --git a/SOURCES/0128-server-upgrade-always-fix-certmonger-tracking-reques.patch b/SOURCES/0128-server-upgrade-always-fix-certmonger-tracking-reques.patch
deleted file mode 100644
index 8e8a48d..0000000
--- a/SOURCES/0128-server-upgrade-always-fix-certmonger-tracking-reques.patch
+++ /dev/null
@@ -1,93 +0,0 @@
-From ba42557e2acb526587b07956e75a2a1394882771 Mon Sep 17 00:00:00 2001
-From: Jan Cholasta <jcholast@redhat.com>
-Date: Tue, 28 Feb 2017 10:55:54 +0000
-Subject: [PATCH] server upgrade: always fix certmonger tracking request
-
-Fix certmonger tracking requests on every run of ipa-server-upgrade rather
-than only when the tracking configuration has changed and the requests have
-not yet been updated.
-
-This allows fixing broken tracking requests just by re-running
-ipa-server-upgrade.
-
-https://pagure.io/freeipa/issue/5799
-
-Reviewed-By: David Kupka <dkupka@redhat.com>
-Reviewed-By: Stanislav Laznicka <slaznick@redhat.com>
----
- ipaserver/install/server/upgrade.py | 28 +++++++---------------------
- 1 file changed, 7 insertions(+), 21 deletions(-)
-
-diff --git a/ipaserver/install/server/upgrade.py b/ipaserver/install/server/upgrade.py
-index 7b0476d442902f2c3dc65819d54953e820f5e560..855056dc1fa20e813d82ecc5090a14cfc4f91831 100644
---- a/ipaserver/install/server/upgrade.py
-+++ b/ipaserver/install/server/upgrade.py
-@@ -905,8 +905,6 @@ def certificate_renewal_update(ca, ds, http):
-     template = paths.CERTMONGER_COMMAND_TEMPLATE
-     serverid = installutils.realm_to_serverid(api.env.realm)
- 
--    # bump version when requests is changed
--    version = 6
-     requests = [
-         {
-             'cert-database': paths.PKI_TOMCAT_ALIAS_DIR,
-@@ -971,25 +969,17 @@ def certificate_renewal_update(ca, ds, http):
-         }
-     ]
- 
--    root_logger.info("[Update certmonger certificate renewal configuration to "
--                     "version %d]" % version)
-+    root_logger.info("[Update certmonger certificate renewal configuration]")
-     if not ca.is_configured():
-         root_logger.info('CA is not configured')
-         return False
- 
--    state = 'certificate_renewal_update_%d' % version
--    if sysupgrade.get_upgrade_state('dogtag', state):
--        return False
--
-     # State not set, lets see if we are already configured
-     for request in requests:
-         request_id = certmonger.get_request_id(request)
-         if request_id is None:
-             break
-     else:
--        sysupgrade.set_upgrade_state('dogtag', state, True)
--        root_logger.info("Certmonger certificate renewal configuration is "
--                         "already at version %d" % version)
-         return False
- 
-     # Ok, now we need to stop tracking, then we can start tracking them
-@@ -998,13 +988,11 @@ def certificate_renewal_update(ca, ds, http):
-     ds.stop_tracking_certificates(serverid)
-     http.stop_tracking_certificates()
- 
--    if not sysupgrade.get_upgrade_state('dogtag',
--                                        'certificate_renewal_update_1'):
--        filename = paths.CERTMONGER_CAS_CA_RENEWAL
--        if os.path.exists(filename):
--            with installutils.stopped_service('certmonger'):
--                root_logger.info("Removing %s" % filename)
--                installutils.remove_file(filename)
-+    filename = paths.CERTMONGER_CAS_CA_RENEWAL
-+    if os.path.exists(filename):
-+        with installutils.stopped_service('certmonger'):
-+            root_logger.info("Removing %s" % filename)
-+            installutils.remove_file(filename)
- 
-     ca.configure_certmonger_renewal()
-     ca.configure_renewal()
-@@ -1013,9 +1001,7 @@ def certificate_renewal_update(ca, ds, http):
-     ds.start_tracking_certificates(serverid)
-     http.start_tracking_certificates()
- 
--    sysupgrade.set_upgrade_state('dogtag', state, True)
--    root_logger.info("Certmonger certificate renewal configuration updated to "
--                     "version %d" % version)
-+    root_logger.info("Certmonger certificate renewal configuration updated")
-     return True
- 
- def copy_crl_file(old_path, new_path=None):
--- 
-2.9.3
-
diff --git a/SOURCES/0129-cainstance-use-correct-profile-for-lightweight-CA-ce.patch b/SOURCES/0129-cainstance-use-correct-profile-for-lightweight-CA-ce.patch
deleted file mode 100644
index 2865b5c..0000000
--- a/SOURCES/0129-cainstance-use-correct-profile-for-lightweight-CA-ce.patch
+++ /dev/null
@@ -1,182 +0,0 @@
-From 1b17dfa9fb62215eeb1ceadc7902785a7ed384e9 Mon Sep 17 00:00:00 2001
-From: Jan Cholasta <jcholast@redhat.com>
-Date: Tue, 28 Feb 2017 10:58:28 +0000
-Subject: [PATCH] cainstance: use correct profile for lightweight CA
- certificates
-
-Use Dogtag's `caCACert` CA certificate profile rather than the
-`ipaCACertRenewal` virtual profile for lightweight CA certificates.
-
-The `ipaCACertRenewal` virtual profile adds special handling of externally
-signed CA certificates and LDAP replication of issued certificates on top
-of `caCACert`, neither of which is relevant for lightweight CA
-certificates.
-
-Remove all of the special casing of lightweight CA certificates from
-dogtag-ipa-ca-renew-agent-submit.
-
-Make sure existing lightweight CA certmonger tracking requests are updated
-on server upgrade.
-
-https://pagure.io/freeipa/issue/5799
-
-Reviewed-By: David Kupka <dkupka@redhat.com>
-Reviewed-By: Stanislav Laznicka <slaznick@redhat.com>
----
- .../certmonger/dogtag-ipa-ca-renew-agent-submit    | 36 +++-------------------
- ipaserver/install/cainstance.py                    |  7 ++---
- ipaserver/install/server/upgrade.py                | 16 ++++++++++
- 3 files changed, 23 insertions(+), 36 deletions(-)
-
-diff --git a/install/certmonger/dogtag-ipa-ca-renew-agent-submit b/install/certmonger/dogtag-ipa-ca-renew-agent-submit
-index f253fd9587ac1ef3ece712ca9999c1ea4f3d55d8..51b0880c5b57758845e2ffa0c9545bbca7e8c751 100755
---- a/install/certmonger/dogtag-ipa-ca-renew-agent-submit
-+++ b/install/certmonger/dogtag-ipa-ca-renew-agent-submit
-@@ -98,25 +98,7 @@ def get_nickname():
-         DN('CN=IPA RA', subject_base): 'ipaCert',
-     }
- 
--    try:
--        return nickname_by_subject_dn[DN(subject)]
--    except KeyError:
--        cas = api.Command.ca_find(ipacasubjectdn=DN(subject))['result']
--        if len(cas) == 0:
--            return None
--        return 'caSigningCert cert-pki-ca {}'.format(cas[0]['ipacaid'][0])
--
--
--def is_lightweight_ca():
--    nickname = get_nickname() or ''
--    return nickname != IPA_CA_NICKNAME and nickname.startswith(IPA_CA_NICKNAME)
--
--def is_renewable():
--    cert = os.environ.get('CERTMONGER_CERTIFICATE')
--    if not cert:
--        return False
--    else:
--        return x509.is_self_signed(cert) or is_lightweight_ca()
-+    return nickname_by_subject_dn.get(DN(subject))
- 
- 
- def is_replicated():
-@@ -276,11 +258,6 @@ def store_cert():
-     if not cert:
-         return (REJECTED, "New certificate requests not supported")
- 
--    if is_lightweight_ca():
--        # Lightweight CAs are updated in Dogtag's NSSDB
--        # by Dogtag itself, so do not store it
--        return (ISSUED, cert)
--
-     dercert = x509.normalize_certificate(cert)
- 
-     dn = DN(('cn', nickname), ('cn', 'ca_renewal'),
-@@ -405,12 +382,6 @@ def retrieve_cert_continuous():
-     if old_cert:
-         old_cert = x509.normalize_certificate(old_cert)
- 
--    if is_lightweight_ca():
--        # Lightweight CAs are updated in Dogtag's NSSDB
--        # by Dogtag itself, so do not try to retrieve it.
--        # Everything is fine as is.
--        return (ISSUED, os.environ.get('CERTMONGER_CERTIFICATE'))
--
-     result = call_handler(retrieve_or_reuse_cert)
-     if result[0] != ISSUED:
-         return result
-@@ -466,12 +437,13 @@ def renew_ca_cert():
-     cert = os.environ.get('CERTMONGER_CERTIFICATE')
-     if not cert:
-         return (REJECTED, "New certificate requests not supported")
-+    is_self_signed = x509.is_self_signed(cert)
- 
-     operation = os.environ.get('CERTMONGER_OPERATION')
-     if operation == 'SUBMIT':
-         state = 'retrieve'
- 
--        if is_renewable() and is_renewal_master():
-+        if is_self_signed and is_renewal_master():
-             state = 'request'
-     elif operation == 'POLL':
-         cookie = os.environ.get('CERTMONGER_CA_COOKIE')
-@@ -489,7 +461,7 @@ def renew_ca_cert():
- 
-     if state == 'retrieve':
-         result = call_handler(retrieve_cert)
--        if result[0] == REJECTED and not is_renewable():
-+        if result[0] == REJECTED and not is_self_signed:
-             syslog.syslog(syslog.LOG_ALERT,
-                           "Certificate with subject '%s' is about to expire, "
-                           "use ipa-cacert-manage to renew it"
-diff --git a/ipaserver/install/cainstance.py b/ipaserver/install/cainstance.py
-index 97baa606c960806376e025b5654eea816da207ed..546e1b7b39b323bbaeae3fb57d31ea4152d5e418 100644
---- a/ipaserver/install/cainstance.py
-+++ b/ipaserver/install/cainstance.py
-@@ -436,7 +436,7 @@ class CAInstance(DogtagInstance):
-                     self.step("adding 'ipa' CA entry", ensure_ipa_authority_entry)
- 
-                 self.step("configuring certmonger renewal for lightweight CAs",
--                          self.__add_lightweight_ca_tracking_requests)
-+                          self.add_lightweight_ca_tracking_requests)
- 
-         if ra_only:
-             runtime = None
-@@ -1246,7 +1246,7 @@ class CAInstance(DogtagInstance):
-         os.chmod(keyfile, 0o600)
-         os.chown(keyfile, pent.pw_uid, pent.pw_gid)
- 
--    def __add_lightweight_ca_tracking_requests(self):
-+    def add_lightweight_ca_tracking_requests(self):
-         try:
-             lwcas = api.Backend.ldap2.get_entries(
-                 base_dn=api.env.basedn,
-@@ -1810,11 +1810,10 @@ def add_lightweight_ca_tracking_requests(logger, lwcas):
-                     pin=certmonger.get_pin('internal'),
-                     nickname=nickname,
-                     ca=ipalib.constants.RENEWAL_CA_NAME,
-+                    profile='caCACert',
-                     pre_command='stop_pkicad',
-                     post_command='renew_ca_cert "%s"' % nickname,
-                 )
--                request_id = certmonger.get_request_id(criteria)
--                certmonger.modify(request_id, profile='ipaCACertRenewal')
-                 logger.debug(
-                     'Lightweight CA renewal: '
-                     'added tracking request for "%s"', nickname)
-diff --git a/ipaserver/install/server/upgrade.py b/ipaserver/install/server/upgrade.py
-index 855056dc1fa20e813d82ecc5090a14cfc4f91831..96fdadf751ef619e198a861d9f62440c98f3abae 100644
---- a/ipaserver/install/server/upgrade.py
-+++ b/ipaserver/install/server/upgrade.py
-@@ -974,6 +974,21 @@ def certificate_renewal_update(ca, ds, http):
-         root_logger.info('CA is not configured')
-         return False
- 
-+    db = certs.CertDB(api.env.realm, paths.PKI_TOMCAT_ALIAS_DIR)
-+    for nickname, _trust_flags in db.list_certs():
-+        if nickname.startswith('caSigningCert cert-pki-ca '):
-+            requests.append(
-+                {
-+                    'cert-database': paths.PKI_TOMCAT_ALIAS_DIR,
-+                    'cert-nickname': nickname,
-+                    'ca': 'dogtag-ipa-ca-renew-agent',
-+                    'cert-presave-command': template % 'stop_pkicad',
-+                    'cert-postsave-command':
-+                        (template % ('renew_ca_cert "%s"' % nickname)),
-+                    'template-profile': 'caCACert',
-+                }
-+            )
-+
-     # State not set, lets see if we are already configured
-     for request in requests:
-         request_id = certmonger.get_request_id(request)
-@@ -998,6 +1013,7 @@ def certificate_renewal_update(ca, ds, http):
-     ca.configure_renewal()
-     ca.configure_agent_renewal()
-     ca.track_servercert()
-+    ca.add_lightweight_ca_tracking_requests()
-     ds.start_tracking_certificates(serverid)
-     http.start_tracking_certificates()
- 
--- 
-2.9.3
-
diff --git a/SOURCES/0130-renew-agent-allow-reusing-existing-certs.patch b/SOURCES/0130-renew-agent-allow-reusing-existing-certs.patch
deleted file mode 100644
index e1db085..0000000
--- a/SOURCES/0130-renew-agent-allow-reusing-existing-certs.patch
+++ /dev/null
@@ -1,260 +0,0 @@
-From 854ceb13a72630ba357ca5c1ec8ac5b320a4c9c5 Mon Sep 17 00:00:00 2001
-From: Jan Cholasta <jcholast@redhat.com>
-Date: Wed, 19 Apr 2017 12:55:47 +0000
-Subject: [PATCH] renew agent: allow reusing existing certs
-
-Add a switch which makes `dogtag-ipa-ca-renew-agent-submit` reuse the
-existing certificate rather than request a new one from the CA while
-maintaining LDAP replication of the certificate.
-
-Make this available as a new `dogtag-ipa-ca-renew-agent-reuse` certmonger
-CA.
-
-This allows redoing the LDAP replication and reexecuting pre- and post-save
-commands of a tracking request without reissuing the certificate.
-
-https://pagure.io/freeipa/issue/5799
-
-Reviewed-By: David Kupka <dkupka@redhat.com>
-Reviewed-By: Stanislav Laznicka <slaznick@redhat.com>
----
- .../certmonger/dogtag-ipa-ca-renew-agent-submit    | 67 ++++++++++++++++------
- ipaserver/install/cainstance.py                    |  8 ++-
- ipaserver/install/dogtaginstance.py                | 15 +++--
- 3 files changed, 63 insertions(+), 27 deletions(-)
-
-diff --git a/install/certmonger/dogtag-ipa-ca-renew-agent-submit b/install/certmonger/dogtag-ipa-ca-renew-agent-submit
-index 51b0880c5b57758845e2ffa0c9545bbca7e8c751..7b5489555d069856a6da7a21b5ab2b0f4dd4a41c 100755
---- a/install/certmonger/dogtag-ipa-ca-renew-agent-submit
-+++ b/install/certmonger/dogtag-ipa-ca-renew-agent-submit
-@@ -193,10 +193,18 @@ def call_handler(_handler, *args, **kwargs):
- 
-     return result
- 
--def request_cert():
-+
-+def request_cert(reuse_existing, **kwargs):
-     """
-     Request certificate from IPA CA.
-     """
-+    if reuse_existing:
-+        cert = os.environ.get('CERTMONGER_CERTIFICATE')
-+        if cert:
-+            return (ISSUED, cert)
-+        else:
-+            return (REJECTED, "New certificate requests not supported")
-+
-     syslog.syslog(syslog.LOG_NOTICE,
-                   "Forwarding request to dogtag-ipa-renew-agent")
- 
-@@ -231,7 +239,8 @@ def request_cert():
-     else:
-         return (rc, stdout)
- 
--def store_cert():
-+
-+def store_cert(**kwargs):
-     """
-     Store certificate in LDAP.
-     """
-@@ -292,7 +301,8 @@ def store_cert():
- 
-     return (ISSUED, cert)
- 
--def request_and_store_cert():
-+
-+def request_and_store_cert(**kwargs):
-     """
-     Request certificate from IPA CA and store it in LDAP.
-     """
-@@ -318,7 +328,7 @@ def request_and_store_cert():
-         else:
-             os.environ['CERTMONGER_CA_COOKIE'] = cookie
- 
--        result = call_handler(request_cert)
-+        result = call_handler(request_cert, **kwargs)
-         if result[0] == WAIT:
-             return (result[0], 'request:%s' % result[1])
-         elif result[0] == WAIT_WITH_DELAY:
-@@ -337,7 +347,7 @@ def request_and_store_cert():
-         os.environ['CERTMONGER_CA_COOKIE'] = cookie
-     os.environ['CERTMONGER_CERTIFICATE'] = cert
- 
--    result = call_handler(store_cert)
-+    result = call_handler(store_cert, **kwargs)
-     if result[0] == WAIT:
-         return (result[0], 'store:%s:%s' % (cert, result[1]))
-     elif result[0] == WAIT_WITH_DELAY:
-@@ -345,7 +355,8 @@ def request_and_store_cert():
-     else:
-         return result
- 
--def retrieve_or_reuse_cert():
-+
-+def retrieve_or_reuse_cert(**kwargs):
-     """
-     Retrieve certificate from LDAP. If the certificate is not available, reuse
-     the old certificate.
-@@ -373,7 +384,8 @@ def retrieve_or_reuse_cert():
- 
-     return (ISSUED, cert)
- 
--def retrieve_cert_continuous():
-+
-+def retrieve_cert_continuous(reuse_existing, **kwargs):
-     """
-     Retrieve new certificate from LDAP. Repeat every eight hours until the
-     certificate is available.
-@@ -382,8 +394,10 @@ def retrieve_cert_continuous():
-     if old_cert:
-         old_cert = x509.normalize_certificate(old_cert)
- 
--    result = call_handler(retrieve_or_reuse_cert)
--    if result[0] != ISSUED:
-+    result = call_handler(retrieve_or_reuse_cert,
-+                          reuse_existing=reuse_existing,
-+                          **kwargs)
-+    if result[0] != ISSUED or reuse_existing:
-         return result
- 
-     new_cert = x509.normalize_certificate(result[1])
-@@ -394,17 +408,19 @@ def retrieve_cert_continuous():
- 
-     return result
- 
--def retrieve_cert():
-+
-+def retrieve_cert(**kwargs):
-     """
-     Retrieve new certificate from LDAP.
-     """
--    result = call_handler(retrieve_cert_continuous)
-+    result = call_handler(retrieve_cert_continuous, **kwargs)
-     if result[0] == WAIT_WITH_DELAY:
-         return (REJECTED, "Updated certificate not available")
- 
-     return result
- 
--def export_csr():
-+
-+def export_csr(**kwargs):
-     """
-     This does not actually renew the cert, it just writes the CSR provided
-     by certmonger to /var/lib/ipa/ca.csr and returns the existing cert.
-@@ -430,7 +446,8 @@ def export_csr():
- 
-     return (ISSUED, cert)
- 
--def renew_ca_cert():
-+
-+def renew_ca_cert(reuse_existing, **kwargs):
-     """
-     This is used for automatic CA certificate renewal.
-     """
-@@ -443,7 +460,7 @@ def renew_ca_cert():
-     if operation == 'SUBMIT':
-         state = 'retrieve'
- 
--        if is_self_signed and is_renewal_master():
-+        if is_self_signed and not reuse_existing and is_renewal_master():
-             state = 'request'
-     elif operation == 'POLL':
-         cookie = os.environ.get('CERTMONGER_CA_COOKIE')
-@@ -460,8 +477,10 @@ def renew_ca_cert():
-         return (OPERATION_NOT_SUPPORTED_BY_HELPER,)
- 
-     if state == 'retrieve':
--        result = call_handler(retrieve_cert)
--        if result[0] == REJECTED and not is_self_signed:
-+        result = call_handler(retrieve_cert,
-+                              reuse_existing=reuse_existing,
-+                              **kwargs)
-+        if result[0] == REJECTED and not is_self_signed and not reuse_existing:
-             syslog.syslog(syslog.LOG_ALERT,
-                           "Certificate with subject '%s' is about to expire, "
-                           "use ipa-cacert-manage to renew it"
-@@ -469,7 +488,9 @@ def renew_ca_cert():
-     elif state == 'request':
-         profile = os.environ['CERTMONGER_CA_PROFILE']
-         os.environ['CERTMONGER_CA_PROFILE'] = 'caCACert'
--        result = call_handler(request_and_store_cert)
-+        result = call_handler(request_and_store_cert,
-+                              reuse_existing=reuse_existing,
-+                              **kwargs)
-         os.environ['CERTMONGER_CA_PROFILE'] = profile
- 
-     if result[0] == WAIT:
-@@ -480,6 +501,16 @@ def renew_ca_cert():
-         return result
- 
- def main():
-+    kwargs = {
-+        'reuse_existing': False,
-+    }
-+    try:
-+        sys.argv.remove('--reuse-existing')
-+    except ValueError:
-+        pass
-+    else:
-+        kwargs['reuse_existing'] = True
-+
-     handlers = {
-         'ipaStorage':           store_cert,
-         'ipaRetrievalOrReuse':  retrieve_or_reuse_cert,
-@@ -515,7 +546,7 @@ def main():
-             handler = request_cert
-         handler = handlers.get(profile, handler)
- 
--        res = call_handler(handler)
-+        res = call_handler(handler, **kwargs)
-         for item in res[1:]:
-             print(item)
-         return res[0]
-diff --git a/ipaserver/install/cainstance.py b/ipaserver/install/cainstance.py
-index 546e1b7b39b323bbaeae3fb57d31ea4152d5e418..ff5432d1a7460f1b853c7cf7490b3604c82cd1f7 100644
---- a/ipaserver/install/cainstance.py
-+++ b/ipaserver/install/cainstance.py
-@@ -964,9 +964,11 @@ class CAInstance(DogtagInstance):
-         obj = bus.get_object('org.fedorahosted.certmonger',
-                              '/org/fedorahosted/certmonger')
-         iface = dbus.Interface(obj, 'org.fedorahosted.certmonger')
--        path = iface.find_ca_by_nickname('dogtag-ipa-ca-renew-agent')
--        if path:
--            iface.remove_known_ca(path)
-+        for suffix in ['', '-reuse']:
-+            name = 'dogtag-ipa-ca-renew-agent' + suffix
-+            path = iface.find_ca_by_nickname(name)
-+            if path:
-+                iface.remove_known_ca(path)
- 
-         cmonger.stop()
- 
-diff --git a/ipaserver/install/dogtaginstance.py b/ipaserver/install/dogtaginstance.py
-index 356358adf1b60e236ce821fb44a77ca5f8c1942f..e0515973f7a598b30c6f12675b9ebdbfd0cf3423 100644
---- a/ipaserver/install/dogtaginstance.py
-+++ b/ipaserver/install/dogtaginstance.py
-@@ -265,12 +265,15 @@ class DogtagInstance(service.Service):
-         obj = bus.get_object('org.fedorahosted.certmonger',
-                              '/org/fedorahosted/certmonger')
-         iface = dbus.Interface(obj, 'org.fedorahosted.certmonger')
--        path = iface.find_ca_by_nickname('dogtag-ipa-ca-renew-agent')
--        if not path:
--            iface.add_known_ca(
--                'dogtag-ipa-ca-renew-agent',
--                paths.DOGTAG_IPA_CA_RENEW_AGENT_SUBMIT,
--                dbus.Array([], dbus.Signature('s')))
-+        for suffix, args in [('', ''), ('-reuse', ' --reuse-existing')]:
-+            name = 'dogtag-ipa-ca-renew-agent' + suffix
-+            path = iface.find_ca_by_nickname(name)
-+            if not path:
-+                command = paths.DOGTAG_IPA_CA_RENEW_AGENT_SUBMIT + args
-+                iface.add_known_ca(
-+                    name,
-+                    command,
-+                    dbus.Array([], dbus.Signature('s')))
- 
-     def __get_pin(self):
-         try:
--- 
-2.9.3
-
diff --git a/SOURCES/0131-renew-agent-always-export-CSR-on-IPA-CA-certificate-.patch b/SOURCES/0131-renew-agent-always-export-CSR-on-IPA-CA-certificate-.patch
deleted file mode 100644
index c13f5f9..0000000
--- a/SOURCES/0131-renew-agent-always-export-CSR-on-IPA-CA-certificate-.patch
+++ /dev/null
@@ -1,51 +0,0 @@
-From da3e6ab68f4f40b2851770fcc928b5bb93831c42 Mon Sep 17 00:00:00 2001
-From: Jan Cholasta <jcholast@redhat.com>
-Date: Mon, 24 Apr 2017 06:20:07 +0000
-Subject: [PATCH] renew agent: always export CSR on IPA CA certificate renewal
-
-Make sure a CSR is exported for the IPA CA whenever certmonger detects that
-the CA certificate is about to expire.
-
-This is a pre-requisite for using the `dogtag-ipa-ca-renew-agent-reuse` CA
-instead of the `ipaCSRExport` virtual profile to export the CSR.
-
-https://pagure.io/freeipa/issue/5799
-
-Reviewed-By: David Kupka <dkupka@redhat.com>
-Reviewed-By: Stanislav Laznicka <slaznick@redhat.com>
----
- install/certmonger/dogtag-ipa-ca-renew-agent-submit | 11 +++++++++++
- 1 file changed, 11 insertions(+)
-
-diff --git a/install/certmonger/dogtag-ipa-ca-renew-agent-submit b/install/certmonger/dogtag-ipa-ca-renew-agent-submit
-index 7b5489555d069856a6da7a21b5ab2b0f4dd4a41c..657a1bc638e1da680522c638e92914098fc6ab4b 100755
---- a/install/certmonger/dogtag-ipa-ca-renew-agent-submit
-+++ b/install/certmonger/dogtag-ipa-ca-renew-agent-submit
-@@ -451,6 +451,10 @@ def renew_ca_cert(reuse_existing, **kwargs):
-     """
-     This is used for automatic CA certificate renewal.
-     """
-+    csr = os.environ.get('CERTMONGER_CSR')
-+    if not csr:
-+        return (UNCONFIGURED, "Certificate request not provided")
-+
-     cert = os.environ.get('CERTMONGER_CERTIFICATE')
-     if not cert:
-         return (REJECTED, "New certificate requests not supported")
-@@ -462,6 +466,13 @@ def renew_ca_cert(reuse_existing, **kwargs):
- 
-         if is_self_signed and not reuse_existing and is_renewal_master():
-             state = 'request'
-+
-+        csr_file = paths.IPA_CA_CSR
-+        try:
-+            with open(csr_file, 'wb') as f:
-+                f.write(csr)
-+        except Exception as e:
-+            return (UNREACHABLE, "Failed to write %s: %s" % (csr_file, e))
-     elif operation == 'POLL':
-         cookie = os.environ.get('CERTMONGER_CA_COOKIE')
-         if not cookie:
--- 
-2.9.3
-
diff --git a/SOURCES/0132-renew-agent-get-rid-of-virtual-profiles.patch b/SOURCES/0132-renew-agent-get-rid-of-virtual-profiles.patch
deleted file mode 100644
index 3088979..0000000
--- a/SOURCES/0132-renew-agent-get-rid-of-virtual-profiles.patch
+++ /dev/null
@@ -1,321 +0,0 @@
-From 6a30753c5a437240e4678ef4acae3255ad6d15ee Mon Sep 17 00:00:00 2001
-From: Jan Cholasta <jcholast@redhat.com>
-Date: Mon, 24 Apr 2017 06:40:11 +0000
-Subject: [PATCH] renew agent: get rid of virtual profiles
-
-Replace all uses of virtual profiles with `dogtag-ipa-ca-renew-agent-reuse`
-and remove profile from the IPA CA certificate tracking request.
-
-This prevents virtual profiles from making their way into CSRs and in turn
-being rejected by certain CAs. This affected the IPA CA CSR with Microsoft
-CS in particular.
-
-https://pagure.io/freeipa/issue/5799
-
-Reviewed-By: David Kupka <dkupka@redhat.com>
-Reviewed-By: Stanislav Laznicka <slaznick@redhat.com>
----
- .../certmonger/dogtag-ipa-ca-renew-agent-submit    | 50 ++++------------------
- ipaclient/install/ipa_certupdate.py                |  4 +-
- ipalib/install/certmonger.py                       | 25 ++++++++---
- ipaserver/install/cainstance.py                    |  8 ++--
- ipaserver/install/dogtaginstance.py                |  6 +--
- ipaserver/install/ipa_cacert_manage.py             | 12 +++---
- ipaserver/install/krainstance.py                   |  6 +--
- ipaserver/install/server/upgrade.py                |  2 +-
- 8 files changed, 46 insertions(+), 67 deletions(-)
-
-diff --git a/install/certmonger/dogtag-ipa-ca-renew-agent-submit b/install/certmonger/dogtag-ipa-ca-renew-agent-submit
-index 657a1bc638e1da680522c638e92914098fc6ab4b..3d3e791449014082060ecdc50118a28a9ef315b8 100755
---- a/install/certmonger/dogtag-ipa-ca-renew-agent-submit
-+++ b/install/certmonger/dogtag-ipa-ca-renew-agent-submit
-@@ -297,7 +297,7 @@ def store_cert(**kwargs):
-             syslog.syslog(
-                 syslog.LOG_ERR,
-                 "Giving up. To retry storing the certificate, resubmit the "
--                "request with profile \"ipaStorage\"")
-+                "request with CA \"dogtag-ipa-ca-renew-agent-reuse\"")
- 
-     return (ISSUED, cert)
- 
-@@ -420,33 +420,6 @@ def retrieve_cert(**kwargs):
-     return result
- 
- 
--def export_csr(**kwargs):
--    """
--    This does not actually renew the cert, it just writes the CSR provided
--    by certmonger to /var/lib/ipa/ca.csr and returns the existing cert.
--    """
--    operation = os.environ.get('CERTMONGER_OPERATION')
--    if operation != 'SUBMIT':
--        return (OPERATION_NOT_SUPPORTED_BY_HELPER,)
--
--    csr = os.environ.get('CERTMONGER_CSR')
--    if not csr:
--        return (UNCONFIGURED, "Certificate request not provided")
--
--    cert = os.environ.get('CERTMONGER_CERTIFICATE')
--    if not cert:
--        return (REJECTED, "New certificate requests not supported")
--
--    csr_file = paths.IPA_CA_CSR
--    try:
--        with open(csr_file, 'wb') as f:
--            f.write(csr)
--    except Exception as e:
--        return (UNREACHABLE, "Failed to write %s: %s" % (csr_file, e))
--
--    return (ISSUED, cert)
--
--
- def renew_ca_cert(reuse_existing, **kwargs):
-     """
-     This is used for automatic CA certificate renewal.
-@@ -497,12 +470,15 @@ def renew_ca_cert(reuse_existing, **kwargs):
-                           "use ipa-cacert-manage to renew it"
-                           % (os.environ.get("CERTMONGER_REQ_SUBJECT"),))
-     elif state == 'request':
--        profile = os.environ['CERTMONGER_CA_PROFILE']
-+        profile = os.environ.get('CERTMONGER_CA_PROFILE')
-         os.environ['CERTMONGER_CA_PROFILE'] = 'caCACert'
-         result = call_handler(request_and_store_cert,
-                               reuse_existing=reuse_existing,
-                               **kwargs)
--        os.environ['CERTMONGER_CA_PROFILE'] = profile
-+        if profile is not None:
-+            os.environ['CERTMONGER_CA_PROFILE'] = profile
-+        else:
-+            del os.environ['CERTMONGER_CA_PROFILE']
- 
-     if result[0] == WAIT:
-         return (result[0], '%s:%s' % (state, result[1]))
-@@ -522,14 +498,6 @@ def main():
-     else:
-         kwargs['reuse_existing'] = True
- 
--    handlers = {
--        'ipaStorage':           store_cert,
--        'ipaRetrievalOrReuse':  retrieve_or_reuse_cert,
--        'ipaRetrieval':         retrieve_cert,
--        'ipaCSRExport':         export_csr,
--        'ipaCACertRenewal':     renew_ca_cert,
--    }
--
-     api.bootstrap(in_server=True, context='renew', confdir=paths.ETC_IPA)
-     api.finalize()
- 
-@@ -547,15 +515,15 @@ def main():
- 
-         api.Backend.ldap2.connect()
- 
--        profile = os.environ.get('CERTMONGER_CA_PROFILE')
--        if is_replicated():
-+        if get_nickname() == IPA_CA_NICKNAME:
-+            handler = renew_ca_cert
-+        elif is_replicated():
-             if is_renewal_master():
-                 handler = request_and_store_cert
-             else:
-                 handler = retrieve_cert_continuous
-         else:
-             handler = request_cert
--        handler = handlers.get(profile, handler)
- 
-         res = call_handler(handler, **kwargs)
-         for item in res[1:]:
-diff --git a/ipaclient/install/ipa_certupdate.py b/ipaclient/install/ipa_certupdate.py
-index d6ffbde1900280b548877752726e4f066632877a..7dc88f07ae14e5416f6fe3dc8400b7d4bcabef72 100644
---- a/ipaclient/install/ipa_certupdate.py
-+++ b/ipaclient/install/ipa_certupdate.py
-@@ -153,7 +153,7 @@ class CertUpdate(admintool.AdminTool):
- 
-             self.log.debug("resubmitting certmonger request '%s'", request_id)
-             certmonger.resubmit_request(
--                request_id, profile='ipaRetrievalOrReuse')
-+                request_id, ca='dogtag-ipa-ca-renew-agent-reuse', profile='')
-             try:
-                 state = certmonger.wait_for_request(request_id, timeout)
-             except RuntimeError:
-@@ -167,7 +167,7 @@ class CertUpdate(admintool.AdminTool):
-                     "please check the request manually" % request_id)
- 
-             self.log.debug("modifying certmonger request '%s'", request_id)
--            certmonger.modify(request_id, profile='ipaCACertRenewal')
-+            certmonger.modify(request_id, ca='dogtag-ipa-ca-renew-agent')
- 
-         self.update_file(paths.CA_CRT, certs)
- 
-diff --git a/ipalib/install/certmonger.py b/ipalib/install/certmonger.py
-index 2a7876ea9ba986f57c00fc7ad61d10fe91894f55..5709853ffebdbf58929b9a935e906ae67341bea8 100644
---- a/ipalib/install/certmonger.py
-+++ b/ipalib/install/certmonger.py
-@@ -501,18 +501,29 @@ def stop_tracking(secdir=None, request_id=None, nickname=None, certfile=None):
-         request.parent.obj_if.remove_request(request.path)
- 
- 
--def modify(request_id, profile=None):
--    if profile:
-+def modify(request_id, ca=None, profile=None):
-+    if ca or profile:
-         request = _get_request({'nickname': request_id})
--        if request:
--            request.obj_if.modify({'template-profile': profile})
-+        update = {}
-+        if ca is not None:
-+            cm = _certmonger()
-+            update['CA'] = cm.obj_if.find_ca_by_nickname(ca)
-+        if profile is not None:
-+            update['template-profile'] = profile
-+        request.obj_if.modify(update)
- 
- 
--def resubmit_request(request_id, profile=None):
-+def resubmit_request(request_id, ca=None, profile=None):
-     request = _get_request({'nickname': request_id})
-     if request:
--        if profile:
--            request.obj_if.modify({'template-profile': profile})
-+        if ca or profile:
-+            update = {}
-+            if ca is not None:
-+                cm = _certmonger()
-+                update['CA'] = cm.obj_if.find_ca_by_nickname(ca)
-+            if profile is not None:
-+                update['template-profile'] = profile
-+            request.obj_if.modify(update)
-         request.obj_if.resubmit()
- 
- 
-diff --git a/ipaserver/install/cainstance.py b/ipaserver/install/cainstance.py
-index ff5432d1a7460f1b853c7cf7490b3604c82cd1f7..a4aa4f2069277181501ebd92f3795c452b10acd0 100644
---- a/ipaserver/install/cainstance.py
-+++ b/ipaserver/install/cainstance.py
-@@ -279,10 +279,10 @@ class CAInstance(DogtagInstance):
-        2 = have signed cert, continue installation
-     """
- 
--    tracking_reqs = (('auditSigningCert cert-pki-ca', None),
--                     ('ocspSigningCert cert-pki-ca', None),
--                     ('subsystemCert cert-pki-ca', None),
--                     ('caSigningCert cert-pki-ca', 'ipaCACertRenewal'))
-+    tracking_reqs = ('auditSigningCert cert-pki-ca',
-+                     'ocspSigningCert cert-pki-ca',
-+                     'subsystemCert cert-pki-ca',
-+                     'caSigningCert cert-pki-ca')
-     server_cert_name = 'Server-Cert cert-pki-ca'
- 
-     def __init__(self, realm=None, host_name=None):
-diff --git a/ipaserver/install/dogtaginstance.py b/ipaserver/install/dogtaginstance.py
-index e0515973f7a598b30c6f12675b9ebdbfd0cf3423..3ba13815055612c5fff44831c8f874e6175d94cd 100644
---- a/ipaserver/install/dogtaginstance.py
-+++ b/ipaserver/install/dogtaginstance.py
-@@ -287,7 +287,7 @@ class DogtagInstance(service.Service):
-         """ Configure certmonger to renew system certs """
-         pin = self.__get_pin()
- 
--        for nickname, profile in self.tracking_reqs:
-+        for nickname in self.tracking_reqs:
-             try:
-                 certmonger.start_tracking(
-                     certpath=self.nss_db,
-@@ -296,7 +296,7 @@ class DogtagInstance(service.Service):
-                     pin=pin,
-                     pre_command='stop_pkicad',
-                     post_command='renew_ca_cert "%s"' % nickname,
--                    profile=profile)
-+                )
-             except RuntimeError as e:
-                 self.log.error(
-                     "certmonger failed to start tracking certificate: %s", e)
-@@ -331,7 +331,7 @@ class DogtagInstance(service.Service):
-         services.knownservices.messagebus.start()
-         cmonger.start()
- 
--        nicknames = [nickname for nickname, _profile in self.tracking_reqs]
-+        nicknames = self.tracking_reqs
-         if self.server_cert_name is not None:
-             nicknames.append(self.server_cert_name)
- 
-diff --git a/ipaserver/install/ipa_cacert_manage.py b/ipaserver/install/ipa_cacert_manage.py
-index 363ba378ab206fae5c220b754f212666f20384af..6d28c62b36b3909c9a3d95a5c6c84d1779fe4c33 100644
---- a/ipaserver/install/ipa_cacert_manage.py
-+++ b/ipaserver/install/ipa_cacert_manage.py
-@@ -172,14 +172,14 @@ class CACertManage(admintool.AdminTool):
-         except errors.NotFound:
-             raise admintool.ScriptError("CA renewal master not found")
- 
--        self.resubmit_request(ca, 'caCACert')
-+        self.resubmit_request()
- 
-         print("CA certificate successfully renewed")
- 
-     def renew_external_step_1(self, ca):
-         print("Exporting CA certificate signing request, please wait")
- 
--        self.resubmit_request(ca, 'ipaCSRExport')
-+        self.resubmit_request('dogtag-ipa-ca-renew-agent-reuse')
- 
-         print(("The next step is to get %s signed by your CA and re-run "
-               "ipa-cacert-manage as:" % paths.IPA_CA_CSR))
-@@ -282,15 +282,15 @@ class CACertManage(admintool.AdminTool):
-         except errors.NotFound:
-             raise admintool.ScriptError("CA renewal master not found")
- 
--        self.resubmit_request(ca, 'ipaRetrieval')
-+        self.resubmit_request('dogtag-ipa-ca-renew-agent-reuse')
- 
-         print("CA certificate successfully renewed")
- 
--    def resubmit_request(self, ca, profile):
-+    def resubmit_request(self, ca='dogtag-ipa-ca-renew-agent'):
-         timeout = api.env.startup_timeout + 60
- 
-         self.log.debug("resubmitting certmonger request '%s'", self.request_id)
--        certmonger.resubmit_request(self.request_id, profile=profile)
-+        certmonger.resubmit_request(self.request_id, ca=ca, profile='')
-         try:
-             state = certmonger.wait_for_request(self.request_id, timeout)
-         except RuntimeError:
-@@ -304,7 +304,7 @@ class CACertManage(admintool.AdminTool):
-                 "please check the request manually" % self.request_id)
- 
-         self.log.debug("modifying certmonger request '%s'", self.request_id)
--        certmonger.modify(self.request_id, profile='ipaCACertRenewal')
-+        certmonger.modify(self.request_id, ca='dogtag-ipa-ca-renew-agent')
- 
-     def install(self):
-         print("Installing CA certificate, please wait")
-diff --git a/ipaserver/install/krainstance.py b/ipaserver/install/krainstance.py
-index c39d6874a9d685f91b5d30ea1954320b8ee0c1ed..abb81897a404613e20be10d348096402ef08624b 100644
---- a/ipaserver/install/krainstance.py
-+++ b/ipaserver/install/krainstance.py
-@@ -60,9 +60,9 @@ class KRAInstance(DogtagInstance):
-     be the same for both the CA and KRA.
-     """
- 
--    tracking_reqs = (('auditSigningCert cert-pki-kra', None),
--                     ('transportCert cert-pki-kra', None),
--                     ('storageCert cert-pki-kra', None))
-+    tracking_reqs = ('auditSigningCert cert-pki-kra',
-+                     'transportCert cert-pki-kra',
-+                     'storageCert cert-pki-kra')
- 
-     def __init__(self, realm):
-         super(KRAInstance, self).__init__(
-diff --git a/ipaserver/install/server/upgrade.py b/ipaserver/install/server/upgrade.py
-index 96fdadf751ef619e198a861d9f62440c98f3abae..5e5c83731d3d3415deb61271baa7865c62f60336 100644
---- a/ipaserver/install/server/upgrade.py
-+++ b/ipaserver/install/server/upgrade.py
-@@ -937,7 +937,7 @@ def certificate_renewal_update(ca, ds, http):
-             'cert-presave-command': template % 'stop_pkicad',
-             'cert-postsave-command':
-                 (template % 'renew_ca_cert "caSigningCert cert-pki-ca"'),
--            'template-profile': 'ipaCACertRenewal',
-+            'template-profile': '',
-         },
-         {
-             'cert-database': paths.PKI_TOMCAT_ALIAS_DIR,
--- 
-2.9.3
-
diff --git a/SOURCES/0133-ipa-cacert-manage-add-external-ca-type.patch b/SOURCES/0133-ipa-cacert-manage-add-external-ca-type.patch
deleted file mode 100644
index 0e037b2..0000000
--- a/SOURCES/0133-ipa-cacert-manage-add-external-ca-type.patch
+++ /dev/null
@@ -1,97 +0,0 @@
-From 993d41e5105653412cec40b8e2a386da802a62bb Mon Sep 17 00:00:00 2001
-From: Jan Cholasta <jcholast@redhat.com>
-Date: Mon, 24 Apr 2017 07:10:41 +0000
-Subject: [PATCH] ipa-cacert-manage: add --external-ca-type
-
-Add the `--external-ca-type`, as known from `ipa-server-install` and
-`ipa-ca-install`, to `ipa-cacert-manage`.
-
-This allows creating IPA CA CSRs suitable for use with Microsoft CS using
-`ipa-cacert-manage`:
-
-```
-ipa-cacert-manage renew --external-ca --external-ca-type=ms-cs
-```
-
-https://pagure.io/freeipa/issue/5799
-
-Reviewed-By: David Kupka <dkupka@redhat.com>
-Reviewed-By: Stanislav Laznicka <slaznick@redhat.com>
----
- install/tools/man/ipa-cacert-manage.1  |  3 +++
- ipaserver/install/ipa_cacert_manage.py | 21 +++++++++++++++++----
- 2 files changed, 20 insertions(+), 4 deletions(-)
-
-diff --git a/install/tools/man/ipa-cacert-manage.1 b/install/tools/man/ipa-cacert-manage.1
-index 128edd8bd2500a09f406da8dc01a53b269007ab0..e36258d0f96aa1050fe88b05f4fe9a1a8f9a7978 100644
---- a/install/tools/man/ipa-cacert-manage.1
-+++ b/install/tools/man/ipa-cacert-manage.1
-@@ -78,6 +78,9 @@ Sign the renewed certificate by itself.
- \fB\-\-external\-ca\fR
- Sign the renewed certificate by external CA.
- .TP
-+\fB\-\-external\-ca\-type\fR=\fITYPE\fR
-+Type of the external CA. Possible values are "generic", "ms-cs". Default value is "generic". Use "ms-cs" to include template name required by Microsoft Certificate Services (MS CS) in the generated CSR.
-+.TP
- \fB\-\-external\-cert\-file\fR=\fIFILE\fR
- File containing the IPA CA certificate and the external CA certificate chain. The file is accepted in PEM and DER certificate and PKCS#7 certificate chain formats. This option may be used multiple times.
- .RE
-diff --git a/ipaserver/install/ipa_cacert_manage.py b/ipaserver/install/ipa_cacert_manage.py
-index 6d28c62b36b3909c9a3d95a5c6c84d1779fe4c33..3b732e4dcbb5c9b4dfbb9e3608bc7d7afd3e10c2 100644
---- a/ipaserver/install/ipa_cacert_manage.py
-+++ b/ipaserver/install/ipa_cacert_manage.py
-@@ -54,6 +54,12 @@ class CACertManage(admintool.AdminTool):
-             "--self-signed", dest='self_signed',
-             action='store_true',
-             help="Sign the renewed certificate by itself")
-+        ext_cas = ("generic", "ms-cs")
-+        renew_group.add_option(
-+            "--external-ca-type", dest="external_ca_type",
-+            type="choice", choices=ext_cas,
-+            metavar="{{{0}}}".format(",".join(ext_cas)),
-+            help="Type of the external CA. Default: generic")
-         renew_group.add_option(
-             "--external-ca", dest='self_signed',
-             action='store_false',
-@@ -179,7 +185,12 @@ class CACertManage(admintool.AdminTool):
-     def renew_external_step_1(self, ca):
-         print("Exporting CA certificate signing request, please wait")
- 
--        self.resubmit_request('dogtag-ipa-ca-renew-agent-reuse')
-+        if self.options.external_ca_type == 'ms-cs':
-+            profile = 'SubCA'
-+        else:
-+            profile = ''
-+
-+        self.resubmit_request('dogtag-ipa-ca-renew-agent-reuse', profile)
- 
-         print(("The next step is to get %s signed by your CA and re-run "
-               "ipa-cacert-manage as:" % paths.IPA_CA_CSR))
-@@ -286,11 +297,11 @@ class CACertManage(admintool.AdminTool):
- 
-         print("CA certificate successfully renewed")
- 
--    def resubmit_request(self, ca='dogtag-ipa-ca-renew-agent'):
-+    def resubmit_request(self, ca='dogtag-ipa-ca-renew-agent', profile=''):
-         timeout = api.env.startup_timeout + 60
- 
-         self.log.debug("resubmitting certmonger request '%s'", self.request_id)
--        certmonger.resubmit_request(self.request_id, ca=ca, profile='')
-+        certmonger.resubmit_request(self.request_id, ca=ca, profile=profile)
-         try:
-             state = certmonger.wait_for_request(self.request_id, timeout)
-         except RuntimeError:
-@@ -304,7 +315,9 @@ class CACertManage(admintool.AdminTool):
-                 "please check the request manually" % self.request_id)
- 
-         self.log.debug("modifying certmonger request '%s'", self.request_id)
--        certmonger.modify(self.request_id, ca='dogtag-ipa-ca-renew-agent')
-+        certmonger.modify(self.request_id,
-+                          ca='dogtag-ipa-ca-renew-agent',
-+                          profile='')
- 
-     def install(self):
-         print("Installing CA certificate, please wait")
--- 
-2.9.3
-
diff --git a/SOURCES/0134-Fixing-adding-authenticator-indicators-to-host.patch b/SOURCES/0134-Fixing-adding-authenticator-indicators-to-host.patch
deleted file mode 100644
index e080db4..0000000
--- a/SOURCES/0134-Fixing-adding-authenticator-indicators-to-host.patch
+++ /dev/null
@@ -1,70 +0,0 @@
-From 43871c023ac22a0ae2c4b5fb264b69c6e8029f49 Mon Sep 17 00:00:00 2001
-From: Felipe Volpone <felipevolpone@gmail.com>
-Date: Thu, 11 May 2017 10:26:03 -0300
-Subject: [PATCH] Fixing adding authenticator indicators to host
-
-The check for krbprincipalaux in the entries is now made
-case-insensitively.
-
-https://pagure.io/freeipa/issue/6911
-
-Reviewed-By: Stanislav Laznicka <slaznick@redhat.com>
-Reviewed-By: Petr Vobornik <pvoborni@redhat.com>
----
- ipaserver/plugins/host.py | 13 ++++++++-----
- 1 file changed, 8 insertions(+), 5 deletions(-)
-
-diff --git a/ipaserver/plugins/host.py b/ipaserver/plugins/host.py
-index dcadd54a10692f64f0464d964f43c7881875d433..1e1f9d82dfdfcf9e7fef65ce729cd8ee7b76e605 100644
---- a/ipaserver/plugins/host.py
-+++ b/ipaserver/plugins/host.py
-@@ -884,7 +884,8 @@ class host_mod(LDAPUpdate):
-                 msg = 'Principal name already set, it is unchangeable.'
-                 raise errors.ACIError(info=msg)
-             obj_classes = entry_attrs_old['objectclass']
--            if 'krbprincipalaux' not in obj_classes:
-+            if 'krbprincipalaux' not in (item.lower() for item in
-+                                         obj_classes):
-                 obj_classes.append('krbprincipalaux')
-                 entry_attrs['objectclass'] = obj_classes
- 
-@@ -920,7 +921,7 @@ class host_mod(LDAPUpdate):
-             else:
-                 _entry_attrs = ldap.get_entry(dn, ['objectclass'])
-                 obj_classes = _entry_attrs['objectclass']
--            if 'ieee802device' not in obj_classes:
-+            if 'ieee802device' not in (item.lower() for item in obj_classes):
-                 obj_classes.append('ieee802device')
-                 entry_attrs['objectclass'] = obj_classes
- 
-@@ -940,7 +941,7 @@ class host_mod(LDAPUpdate):
-             else:
-                 _entry_attrs = ldap.get_entry(dn, ['objectclass'])
-                 obj_classes = entry_attrs['objectclass'] = _entry_attrs['objectclass']
--            if 'ipasshhost' not in obj_classes:
-+            if 'ipasshhost' not in (item.lower() for item in obj_classes):
-                 obj_classes.append('ipasshhost')
- 
-         update_krbticketflags(ldap, entry_attrs, attrs_list, options, True)
-@@ -949,14 +950,16 @@ class host_mod(LDAPUpdate):
-             if 'objectclass' not in entry_attrs:
-                 entry_attrs_old = ldap.get_entry(dn, ['objectclass'])
-                 entry_attrs['objectclass'] = entry_attrs_old['objectclass']
--            if 'krbticketpolicyaux' not in entry_attrs['objectclass']:
-+            if 'krbticketpolicyaux' not in (item.lower() for item in
-+                                            entry_attrs['objectclass']):
-                 entry_attrs['objectclass'].append('krbticketpolicyaux')
- 
-         if 'krbprincipalauthind' in entry_attrs:
-             if 'objectclass' not in entry_attrs:
-                 entry_attrs_old = ldap.get_entry(dn, ['objectclass'])
-                 entry_attrs['objectclass'] = entry_attrs_old['objectclass']
--            if 'krbprincipalaux' not in entry_attrs['objectclass']:
-+            if 'krbprincipalaux' not in (item.lower() for item in
-+                                         entry_attrs['objectclass']):
-                 entry_attrs['objectclass'].append('krbprincipalaux')
- 
-         add_sshpubkey_to_attrs_pre(self.context, attrs_list)
--- 
-2.9.3
-
diff --git a/SOURCES/0135-Added-plugins-directory-to-ipaclient-subpackages.patch b/SOURCES/0135-Added-plugins-directory-to-ipaclient-subpackages.patch
deleted file mode 100644
index eb46399..0000000
--- a/SOURCES/0135-Added-plugins-directory-to-ipaclient-subpackages.patch
+++ /dev/null
@@ -1,35 +0,0 @@
-From b62710ef8fe96ac012d61f6fc76f7d4e69a49f09 Mon Sep 17 00:00:00 2001
-From: Oliver Gutierrez <ogutierrez@redhat.com>
-Date: Fri, 28 Apr 2017 15:21:49 +0100
-Subject: [PATCH] Added plugins directory to ipaclient subpackages
-
-https://pagure.io/freeipa/issue/6927
-
-Reviewed-By: Pavel Vomacka <pvomacka@redhat.com>
----
- freeipa.spec.in | 2 ++
- 1 file changed, 2 insertions(+)
-
-diff --git a/freeipa.spec.in b/freeipa.spec.in
-index 1b3ed15036eab6262b144d970cbdfdad31ac13ea..3a5a9b4087d2394d6e8556d62da46a3dc922c913 100644
---- a/freeipa.spec.in
-+++ b/freeipa.spec.in
-@@ -1404,6 +1404,7 @@ fi
- %doc README.md Contributors.txt
- %license COPYING
- %dir %{python_sitelib}/ipaclient
-+%dir %{python_sitelib}/ipaclient/plugins
- %{python_sitelib}/ipaclient/*.py*
- %{python_sitelib}/ipaclient/install/*.py*
- %{python_sitelib}/ipaclient/plugins/*.py*
-@@ -1422,6 +1423,7 @@ fi
- %doc README.md Contributors.txt
- %license COPYING
- %dir %{python3_sitelib}/ipaclient
-+%dir %{python3_sitelib}/ipaclient/plugins
- %{python3_sitelib}/ipaclient/*.py
- %{python3_sitelib}/ipaclient/__pycache__/*.py*
- %{python3_sitelib}/ipaclient/install/*.py
--- 
-2.9.3
-
diff --git a/SOURCES/0136-ipaclient-fix-missing-RPM-ownership.patch b/SOURCES/0136-ipaclient-fix-missing-RPM-ownership.patch
deleted file mode 100644
index 3f1cbff..0000000
--- a/SOURCES/0136-ipaclient-fix-missing-RPM-ownership.patch
+++ /dev/null
@@ -1,71 +0,0 @@
-From 6f2708e350a096a8d3ea4feb177370d9cb1afa81 Mon Sep 17 00:00:00 2001
-From: Martin Basti <mbasti@redhat.com>
-Date: Wed, 10 May 2017 18:39:22 +0200
-Subject: [PATCH] ipaclient: fix missing RPM ownership
-
-FreeIPA package should own all subdirectories to work properly with
-3rd party packages/plugins.
-
-https://pagure.io/freeipa/issue/6927
-
-Reviewed-By: Pavel Vomacka <pvomacka@redhat.com>
----
- freeipa.spec.in | 16 ++++++++++++++--
- 1 file changed, 14 insertions(+), 2 deletions(-)
-
-diff --git a/freeipa.spec.in b/freeipa.spec.in
-index 3a5a9b4087d2394d6e8556d62da46a3dc922c913..0335a9970be82e80e98696f3d7fd4ec64894ef5f 100644
---- a/freeipa.spec.in
-+++ b/freeipa.spec.in
-@@ -1404,14 +1404,20 @@ fi
- %doc README.md Contributors.txt
- %license COPYING
- %dir %{python_sitelib}/ipaclient
--%dir %{python_sitelib}/ipaclient/plugins
- %{python_sitelib}/ipaclient/*.py*
-+%dir %{python_sitelib}/ipaclient/install
- %{python_sitelib}/ipaclient/install/*.py*
-+%dir %{python_sitelib}/ipaclient/plugins
- %{python_sitelib}/ipaclient/plugins/*.py*
-+%dir %{python_sitelib}/ipaclient/remote_plugins
- %{python_sitelib}/ipaclient/remote_plugins/*.py*
- %{python_sitelib}/ipaclient/remote_plugins/2_*/*.py*
-+%dir %{python_sitelib}/ipaclient/csrgen
-+%dir %{python_sitelib}/ipaclient/csrgen/profiles
- %{python_sitelib}/ipaclient/csrgen/profiles/*.json
-+%dir %{python_sitelib}/ipaclient/csrgen/rules
- %{python_sitelib}/ipaclient/csrgen/rules/*.json
-+%dir %{python_sitelib}/ipaclient/csrgen/templates
- %{python_sitelib}/ipaclient/csrgen/templates/*.tmpl
- %{python_sitelib}/ipaclient-*.egg-info
- 
-@@ -1423,19 +1429,25 @@ fi
- %doc README.md Contributors.txt
- %license COPYING
- %dir %{python3_sitelib}/ipaclient
--%dir %{python3_sitelib}/ipaclient/plugins
- %{python3_sitelib}/ipaclient/*.py
- %{python3_sitelib}/ipaclient/__pycache__/*.py*
-+%dir %{python3_sitelib}/ipaclient/install
- %{python3_sitelib}/ipaclient/install/*.py
- %{python3_sitelib}/ipaclient/install/__pycache__/*.py*
-+%dir %{python3_sitelib}/ipaclient/plugins
- %{python3_sitelib}/ipaclient/plugins/*.py
- %{python3_sitelib}/ipaclient/plugins/__pycache__/*.py*
-+%dir %{python3_sitelib}/ipaclient/remote_plugins
- %{python3_sitelib}/ipaclient/remote_plugins/*.py
- %{python3_sitelib}/ipaclient/remote_plugins/__pycache__/*.py*
- %{python3_sitelib}/ipaclient/remote_plugins/2_*/*.py
- %{python3_sitelib}/ipaclient/remote_plugins/2_*/__pycache__/*.py*
-+%dir %{python3_sitelib}/ipaclient/csrgen
-+%dir %{python3_sitelib}/ipaclient/csrgen/profiles
- %{python3_sitelib}/ipaclient/csrgen/profiles/*.json
-+%dir %{python3_sitelib}/ipaclient/csrgen/rules
- %{python3_sitelib}/ipaclient/csrgen/rules/*.json
-+%dir %{python3_sitelib}/ipaclient/csrgen/templates
- %{python3_sitelib}/ipaclient/csrgen/templates/*.tmpl
- %{python3_sitelib}/ipaclient-*.egg-info
- 
--- 
-2.9.3
-
diff --git a/SOURCES/0137-otptoken-add-yubikey-When-digits-not-provided-use-de.patch b/SOURCES/0137-otptoken-add-yubikey-When-digits-not-provided-use-de.patch
deleted file mode 100644
index 62760ea..0000000
--- a/SOURCES/0137-otptoken-add-yubikey-When-digits-not-provided-use-de.patch
+++ /dev/null
@@ -1,36 +0,0 @@
-From b16661f4dab141ef692ed6c893c0cb05566b64ec Mon Sep 17 00:00:00 2001
-From: David Kupka <dkupka@redhat.com>
-Date: Fri, 12 May 2017 17:17:05 +0200
-Subject: [PATCH] otptoken-add-yubikey: When --digits not provided use default
- value
-
-Since Thin client was introduced default values for options are not populated
-in client side plugins. When option has default value and is needed in client
-plugin it must be handled by explicitly.
-
-https://pagure.io/freeipa/issue/6900
-
-Reviewed-By: Stanislav Laznicka <slaznick@redhat.com>
----
- ipaclient/plugins/otptoken_yubikey.py | 5 ++++-
- 1 file changed, 4 insertions(+), 1 deletion(-)
-
-diff --git a/ipaclient/plugins/otptoken_yubikey.py b/ipaclient/plugins/otptoken_yubikey.py
-index 759b7226819f0fa693e475b25262b5d93ac2d39f..9e0e98996ca2d34f34f61c9c07088a3f544ad166 100644
---- a/ipaclient/plugins/otptoken_yubikey.py
-+++ b/ipaclient/plugins/otptoken_yubikey.py
-@@ -142,7 +142,10 @@ class otptoken_add_yubikey(Command):
- 
-         # Write the config.
-         cfg = yk.init_config()
--        cfg.mode_oath_hotp(key, kwargs['ipatokenotpdigits'])
-+        cfg.mode_oath_hotp(key, kwargs.get(
-+            'ipatokenotpdigits',
-+            self.get_default_of('ipatokenotpdigits')
-+        ))
-         cfg.extended_flag('SERIAL_API_VISIBLE', True)
-         yk.write_config(cfg, slot=kwargs['slot'])
- 
--- 
-2.9.3
-
diff --git a/SOURCES/0138-ipa-server-install-fix-uninstall.patch b/SOURCES/0138-ipa-server-install-fix-uninstall.patch
deleted file mode 100644
index badd794..0000000
--- a/SOURCES/0138-ipa-server-install-fix-uninstall.patch
+++ /dev/null
@@ -1,34 +0,0 @@
-From 632a1d97c2110cf8ccb4311fac51b98b03b7e26b Mon Sep 17 00:00:00 2001
-From: Florence Blanc-Renaud <flo@redhat.com>
-Date: Mon, 15 May 2017 16:36:44 +0200
-Subject: [PATCH] ipa-server-install: fix uninstall
-
-ipa-server-install --uninstall fails to stop tracking the certificates
-because it assigns a tuple to the variable nicknames, then tries to
-call nicknames.append(). This is a regression introduced by 21f4cbf8.
-
-Assignment should be done using nicknames = list(self.tracking_reqs) instead.
-
-https://pagure.io/freeipa/issue/6950
-
-Reviewed-By: Jan Cholasta <jcholast@redhat.com>
----
- ipaserver/install/dogtaginstance.py | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/ipaserver/install/dogtaginstance.py b/ipaserver/install/dogtaginstance.py
-index 3ba13815055612c5fff44831c8f874e6175d94cd..4c6e1f70672f1553696d53bcd0cf8064c411441d 100644
---- a/ipaserver/install/dogtaginstance.py
-+++ b/ipaserver/install/dogtaginstance.py
-@@ -331,7 +331,7 @@ class DogtagInstance(service.Service):
-         services.knownservices.messagebus.start()
-         cmonger.start()
- 
--        nicknames = self.tracking_reqs
-+        nicknames = list(self.tracking_reqs)
-         if self.server_cert_name is not None:
-             nicknames.append(self.server_cert_name)
- 
--- 
-2.9.4
-
diff --git a/SOURCES/0139-ca-install-merge-duplicated-code-for-DM-password.patch b/SOURCES/0139-ca-install-merge-duplicated-code-for-DM-password.patch
deleted file mode 100644
index e0ac02e..0000000
--- a/SOURCES/0139-ca-install-merge-duplicated-code-for-DM-password.patch
+++ /dev/null
@@ -1,85 +0,0 @@
-From fd7b5b32f907fff7c454a91838f5483501220971 Mon Sep 17 00:00:00 2001
-From: Tomas Krizek <tkrizek@redhat.com>
-Date: Wed, 3 May 2017 10:05:25 +0200
-Subject: [PATCH] ca install: merge duplicated code for DM password
-
-Extract copy-pasted code to a single function.
-
-Related https://pagure.io/freeipa/issue/6892
-
-Signed-off-by: Tomas Krizek <tkrizek@redhat.com>
-Reviewed-By: Martin Basti <mbasti@redhat.com>
-Reviewed-By: Christian Heimes <cheimes@redhat.com>
-Reviewed-By: Stanislav Laznicka <slaznick@redhat.com>
----
- install/tools/ipa-ca-install | 40 +++++++++++++++++-----------------------
- 1 file changed, 17 insertions(+), 23 deletions(-)
-
-diff --git a/install/tools/ipa-ca-install b/install/tools/ipa-ca-install
-index c05abb9646884ad5a4411dba98df466c37f09613..4bcb59a29d5a64c118649374104ae8f1cd451ea4 100755
---- a/install/tools/ipa-ca-install
-+++ b/install/tools/ipa-ca-install
-@@ -116,9 +116,19 @@ def parse_options():
-     return safe_options, options, filename
- 
- 
--def get_dirman_password():
--    return installutils.read_password(
--        "Directory Manager (existing master)", confirm=False, validate=False)
-+def _get_dirman_password(password=None, unattended=False):
-+    if not password:
-+        if unattended:
-+            sys.exit('Directory Manager password required')
-+        try:
-+            password = installutils.read_password(
-+                "Directory Manager (existing master)", confirm=False,
-+                validate=False)
-+        except KeyboardInterrupt:
-+            sys.exit(0)
-+        if password is None:
-+            sys.exit("Directory Manager password required")
-+    return password
- 
- 
- def install_replica(safe_options, options, filename):
-@@ -142,16 +152,8 @@ def install_replica(safe_options, options, filename):
-         check_creds(options, api.env.realm)
- 
-     # get the directory manager password
--    dirman_password = options.password
--    if not dirman_password:
--        if options.unattended:
--            sys.exit('Directory Manager password required')
--        try:
--            dirman_password = get_dirman_password()
--        except KeyboardInterrupt:
--            sys.exit(0)
--        if dirman_password is None:
--            sys.exit("Directory Manager password required")
-+    dirman_password = _get_dirman_password(
-+        options.password, options.unattended)
- 
-     if (not options.promote and not options.admin_password and
-             not options.skip_conncheck and options.unattended):
-@@ -199,16 +201,8 @@ def install_replica(safe_options, options, filename):
- 
- 
- def install_master(safe_options, options):
--    dm_password = options.password
--    if not dm_password:
--        if options.unattended:
--            sys.exit('Directory Manager password required')
--        try:
--            dm_password = get_dirman_password()
--        except KeyboardInterrupt:
--            sys.exit(0)
--        if dm_password is None:
--            sys.exit("Directory Manager password required")
-+    dm_password = _get_dirman_password(
-+        options.password, options.unattended)
- 
-     options.realm_name = api.env.realm
-     options.domain_name = api.env.domain
--- 
-2.9.4
-
diff --git a/SOURCES/0140-installutils-add-DM-password-validator.patch b/SOURCES/0140-installutils-add-DM-password-validator.patch
deleted file mode 100644
index 91ee892..0000000
--- a/SOURCES/0140-installutils-add-DM-password-validator.patch
+++ /dev/null
@@ -1,55 +0,0 @@
-From fe7778b52ac9bacbedceec641ccb41d5f79f131c Mon Sep 17 00:00:00 2001
-From: Tomas Krizek <tkrizek@redhat.com>
-Date: Wed, 3 May 2017 10:01:09 +0200
-Subject: [PATCH] installutils: add DM password validator
-
-Add a validator that checks whether provided Directory Manager
-is valid by attempting to connect to LDAP.
-
-Related https://pagure.io/freeipa/issue/6892
-
-Signed-off-by: Tomas Krizek <tkrizek@redhat.com>
-Reviewed-By: Martin Basti <mbasti@redhat.com>
-Reviewed-By: Christian Heimes <cheimes@redhat.com>
-Reviewed-By: Stanislav Laznicka <slaznick@redhat.com>
----
- ipaserver/install/installutils.py | 16 ++++++++++++++++
- 1 file changed, 16 insertions(+)
-
-diff --git a/ipaserver/install/installutils.py b/ipaserver/install/installutils.py
-index 9230e70056b1a773246a0d95e6ecb943cada953c..b6f01489ccc65dcbc360929e0a7b315b074df8ce 100644
---- a/ipaserver/install/installutils.py
-+++ b/ipaserver/install/installutils.py
-@@ -50,6 +50,7 @@ import ipaplatform
- from ipapython import ipautil, admintool, version
- from ipapython.admintool import ScriptError
- from ipapython.ipa_log_manager import root_logger
-+from ipapython.ipaldap import DIRMAN_DN, LDAPClient
- from ipalib.util import validate_hostname
- from ipalib import api, errors, x509
- from ipapython.dn import DN
-@@ -329,6 +330,21 @@ def _read_password_default_validator(password):
-     if len(password) < 8:
-         raise ValueError("Password must be at least 8 characters long")
- 
-+
-+def validate_dm_password_ldap(password):
-+    """
-+    Validate DM password by attempting to connect to LDAP. api.env has to
-+    contain valid ldap_uri.
-+    """
-+    client = LDAPClient(api.env.ldap_uri, cacert=paths.IPA_CA_CRT)
-+    try:
-+        client.simple_bind(DIRMAN_DN, password)
-+    except errors.ACIError:
-+        raise ValueError("Invalid Directory Manager password")
-+    else:
-+        client.unbind()
-+
-+
- def read_password(user, confirm=True, validate=True, retry=True, validator=_read_password_default_validator):
-     correct = False
-     pwd = None
--- 
-2.9.4
-
diff --git a/SOURCES/0141-ca-kra-install-validate-DM-password.patch b/SOURCES/0141-ca-kra-install-validate-DM-password.patch
deleted file mode 100644
index 57ae8c1..0000000
--- a/SOURCES/0141-ca-kra-install-validate-DM-password.patch
+++ /dev/null
@@ -1,73 +0,0 @@
-From 391fe8e9d0587ad44a92c320a8d1c9de2c9b980a Mon Sep 17 00:00:00 2001
-From: Tomas Krizek <tkrizek@redhat.com>
-Date: Wed, 3 May 2017 10:16:13 +0200
-Subject: [PATCH] ca, kra install: validate DM password
-
-Before proceeding with installation, validate DM password. If the
-provided DM password is invalid, abort the installation.
-
-Fixes https://pagure.io/freeipa/issue/6892
-
-Signed-off-by: Tomas Krizek <tkrizek@redhat.com>
-Reviewed-By: Martin Basti <mbasti@redhat.com>
-Reviewed-By: Christian Heimes <cheimes@redhat.com>
-Reviewed-By: Stanislav Laznicka <slaznick@redhat.com>
----
- install/tools/ipa-ca-install         | 18 ++++++++++--------
- ipaserver/install/ipa_kra_install.py |  8 ++++++++
- 2 files changed, 18 insertions(+), 8 deletions(-)
-
-diff --git a/install/tools/ipa-ca-install b/install/tools/ipa-ca-install
-index 4bcb59a29d5a64c118649374104ae8f1cd451ea4..f84b4749a3e2a80aca002a2aa057b200e6187f18 100755
---- a/install/tools/ipa-ca-install
-+++ b/install/tools/ipa-ca-install
-@@ -117,17 +117,19 @@ def parse_options():
- 
- 
- def _get_dirman_password(password=None, unattended=False):
-+    # sys.exit() is used on purpose, because otherwise user is advised to
-+    # uninstall the component, even though it is not needed
-     if not password:
-         if unattended:
-             sys.exit('Directory Manager password required')
--        try:
--            password = installutils.read_password(
--                "Directory Manager (existing master)", confirm=False,
--                validate=False)
--        except KeyboardInterrupt:
--            sys.exit(0)
--        if password is None:
--            sys.exit("Directory Manager password required")
-+        password = installutils.read_password(
-+            "Directory Manager (existing master)", confirm=False,
-+            validate=False)
-+    try:
-+        installutils.validate_dm_password_ldap(password)
-+    except ValueError:
-+        sys.exit("Directory Manager password is invalid")
-+
-     return password
- 
- 
-diff --git a/ipaserver/install/ipa_kra_install.py b/ipaserver/install/ipa_kra_install.py
-index b06d49c834d0ffa4f2e35c3241a83e42c4c9c337..8369d2f4082d35b453487ee0f17c9ce050188daf 100644
---- a/ipaserver/install/ipa_kra_install.py
-+++ b/ipaserver/install/ipa_kra_install.py
-@@ -137,6 +137,14 @@ class KRAInstaller(KRAInstall):
-     def run(self):
-         super(KRAInstaller, self).run()
- 
-+        # Verify DM password. This has to be called after ask_for_options(),
-+        # so it can't be placed in validate_options().
-+        try:
-+            installutils.validate_dm_password_ldap(self.options.password)
-+        except ValueError:
-+            raise admintool.ScriptError(
-+                "Directory Manager password is invalid")
-+
-         if not cainstance.is_ca_installed_locally():
-             raise RuntimeError("Dogtag CA is not installed. "
-                                "Please install the CA first")
--- 
-2.9.4
-
diff --git a/SOURCES/0142-ipa-kra-install-fix-pkispawn-setting-for-pki_securit.patch b/SOURCES/0142-ipa-kra-install-fix-pkispawn-setting-for-pki_securit.patch
deleted file mode 100644
index ff1f2f8..0000000
--- a/SOURCES/0142-ipa-kra-install-fix-pkispawn-setting-for-pki_securit.patch
+++ /dev/null
@@ -1,45 +0,0 @@
-From 58a9bd7ec98de555db23159e614b2021ec91b2e3 Mon Sep 17 00:00:00 2001
-From: Florence Blanc-Renaud <flo@redhat.com>
-Date: Thu, 11 May 2017 14:53:09 +0200
-Subject: [PATCH] ipa-kra-install: fix pkispawn setting for
- pki_security_domain_hostname
-
-During ipa-kra-install, the installer prepares a configuration file
-provided to pkispawn. This configuration file defines
-pki_security_domain_hostname=(first master)
-
-but when we are installing a clone, it should be set to the local hostname
-instead, see man page pki_default.cfg:
-      pki_security_domain_hostname, pki_security_domain_https_port
-              Location  of  the security domain.  Required for KRA, OCSP, TKS,
-              and TPS subsystems and for  CA  subsystems  joining  a  security
-              domain.  Defaults to the location of the CA subsystem within the
-              same instance.
-
-When pki_security_domain_hostname points to the 1st master, and this first
-master is decommissioned, ipa-kra-install fails on new replicas because pkispawn
-tries to connect to this (non-existing) host.
-
-https://pagure.io/freeipa/issue/6895
-
-Reviewed-By: Stanislav Laznicka <slaznick@redhat.com>
----
- ipaserver/install/krainstance.py | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/ipaserver/install/krainstance.py b/ipaserver/install/krainstance.py
-index abb81897a404613e20be10d348096402ef08624b..cdd25b9d05bcb1a30260475cc2341a258a3cf93c 100644
---- a/ipaserver/install/krainstance.py
-+++ b/ipaserver/install/krainstance.py
-@@ -252,7 +252,7 @@ class KRAInstance(DogtagInstance):
-             os.chown(p12_tmpfile_name, pent.pw_uid, pent.pw_gid)
- 
-             # Security domain registration
--            config.set("KRA", "pki_security_domain_hostname", self.master_host)
-+            config.set("KRA", "pki_security_domain_hostname", self.fqdn)
-             config.set("KRA", "pki_security_domain_https_port", "443")
-             config.set("KRA", "pki_security_domain_user", self.admin_user)
-             config.set("KRA", "pki_security_domain_password",
--- 
-2.9.4
-
diff --git a/SOURCES/0143-certdb-add-named-trust-flag-constants.patch b/SOURCES/0143-certdb-add-named-trust-flag-constants.patch
deleted file mode 100644
index 3c81de1..0000000
--- a/SOURCES/0143-certdb-add-named-trust-flag-constants.patch
+++ /dev/null
@@ -1,344 +0,0 @@
-From b98b21aaa709ccd91369e89a836f64c06c4593e8 Mon Sep 17 00:00:00 2001
-From: Jan Cholasta <jcholast@redhat.com>
-Date: Thu, 27 Apr 2017 09:33:25 +0200
-Subject: [PATCH] certdb: add named trust flag constants
-
-Add named constants for common trust flag combinations.
-
-Use the named constants instead of trust flags strings in the code.
-
-https://pagure.io/freeipa/issue/6831
-
-Reviewed-By: Stanislav Laznicka <slaznick@redhat.com>
-Reviewed-By: Martin Babinsky <mbabinsk@redhat.com>
----
- install/restart_scripts/restart_httpd      |  3 ++-
- install/tools/ipa-replica-conncheck        |  4 +++-
- ipaclient/install/client.py                |  9 ++++++---
- ipapython/certdb.py                        |  9 +++++++--
- ipaserver/install/ca.py                    |  2 +-
- ipaserver/install/certs.py                 |  5 +++--
- ipaserver/install/dsinstance.py            |  5 +++--
- ipaserver/install/httpinstance.py          |  5 +++--
- ipaserver/install/ipa_cacert_manage.py     | 16 +++++++++++-----
- ipaserver/install/plugins/upload_cacrt.py  |  2 +-
- ipaserver/install/server/replicainstall.py |  3 ++-
- ipaserver/install/server/upgrade.py        |  4 ++--
- 12 files changed, 44 insertions(+), 23 deletions(-)
-
-diff --git a/install/restart_scripts/restart_httpd b/install/restart_scripts/restart_httpd
-index b661b82b896b109c3859ac82c2d84ab27b839f72..cd7f12024ea3cab16e9c664687cd854e666c9570 100644
---- a/install/restart_scripts/restart_httpd
-+++ b/install/restart_scripts/restart_httpd
-@@ -24,6 +24,7 @@ import traceback
- from ipalib import api
- from ipaplatform import services
- from ipaplatform.paths import paths
-+from ipapython.certdb import TRUSTED_PEER_TRUST_FLAGS
- from ipaserver.install import certs, installutils
- 
- 
-@@ -36,7 +37,7 @@ def _main():
-     nickname = installutils.get_directive(paths.HTTPD_NSS_CONF, "NSSNickname")
- 
-     # Add trust flag which set certificate trusted for SSL connections.
--    db.trust_root_cert(nickname, "P,,")
-+    db.trust_root_cert(nickname, TRUSTED_PEER_TRUST_FLAGS)
- 
-     syslog.syslog(syslog.LOG_NOTICE, 'certmonger restarted httpd')
- 
-diff --git a/install/tools/ipa-replica-conncheck b/install/tools/ipa-replica-conncheck
-index fdbd4f32d9fa4a625cca3614e13e71d00f58e57e..528242268f9992e903781b76a379039d533853c0 100755
---- a/install/tools/ipa-replica-conncheck
-+++ b/install/tools/ipa-replica-conncheck
-@@ -549,7 +549,9 @@ def main():
-                             data = ca_cert.public_bytes(
-                                 serialization.Encoding.DER)
-                             nss_db.add_cert(
--                                data, str(DN(ca_cert.subject)), 'C,,')
-+                                data,
-+                                str(DN(ca_cert.subject)),
-+                                certdb.EXTERNAL_CA_TRUST_FLAGS)
- 
-                     api.bootstrap(context='client',
-                                   confdir=paths.ETC_IPA,
-diff --git a/ipaclient/install/client.py b/ipaclient/install/client.py
-index abca692fd61be4a9f35a1398fb2af4b1d9e8689b..e78be904dd6bad491d9f3c1bb1e1410bc1779d45 100644
---- a/ipaclient/install/client.py
-+++ b/ipaclient/install/client.py
-@@ -2318,8 +2318,9 @@ def update_ipa_nssdb():
-     if not os.path.exists(os.path.join(ipa_db.secdir, 'cert8.db')):
-         create_ipa_nssdb()
- 
--    for nickname, trust_flags in (('IPA CA', 'CT,C,C'),
--                                  ('External CA cert', 'C,,')):
-+    for nickname, trust_flags in (
-+            ('IPA CA', certdb.IPA_CA_TRUST_FLAGS),
-+            ('External CA cert', certdb.EXTERNAL_CA_TRUST_FLAGS)):
-         try:
-             cert = sys_db.get_cert(nickname)
-         except RuntimeError:
-@@ -2680,7 +2681,9 @@ def _install(options):
-             tmp_db.create_db()
- 
-             for i, cert in enumerate(ca_certs):
--                tmp_db.add_cert(cert, 'CA certificate %d' % (i + 1), 'C,,')
-+                tmp_db.add_cert(cert,
-+                                'CA certificate %d' % (i + 1),
-+                                certdb.EXTERNAL_CA_TRUST_FLAGS)
-         except CalledProcessError:
-             raise ScriptError(
-                 "Failed to add CA to temporary NSS database.",
-diff --git a/ipapython/certdb.py b/ipapython/certdb.py
-index ea73ec139df9013b860df447fcffd9038cf7c8f2..44c7bf3197c198295035742e6db48527d76e85a6 100644
---- a/ipapython/certdb.py
-+++ b/ipapython/certdb.py
-@@ -52,6 +52,11 @@ CA_NICKNAME_FMT = "%s IPA CA"
- 
- NSS_FILES = ("cert8.db", "key3.db", "secmod.db", "pwdfile.txt")
- 
-+EMPTY_TRUST_FLAGS = ',,'
-+IPA_CA_TRUST_FLAGS = 'CT,C,C'
-+EXTERNAL_CA_TRUST_FLAGS = 'C,,'
-+TRUSTED_PEER_TRUST_FLAGS = 'P,,'
-+
- 
- def get_ca_nickname(realm, format=CA_NICKNAME_FMT):
-     return format % realm
-@@ -441,7 +446,7 @@ class NSSDatabase(object):
-             cert = x509.load_certificate(cert_pem)
-             nickname = str(DN(cert.subject))
-             data = cert.public_bytes(serialization.Encoding.DER)
--            self.add_cert(data, nickname, ',,')
-+            self.add_cert(data, nickname, EMPTY_TRUST_FLAGS)
- 
-         if extracted_key:
-             in_file = ipautil.write_tmp_file(
-@@ -473,7 +478,7 @@ class NSSDatabase(object):
-                 root_nickname)
-         else:
-             if trust_flags is None:
--                trust_flags = 'C,,'
-+                trust_flags = EXTERNAL_CA_TRUST_FLAGS
-             try:
-                 self.run_certutil(["-M", "-n", root_nickname,
-                                    "-t", trust_flags])
-diff --git a/ipaserver/install/ca.py b/ipaserver/install/ca.py
-index 8ee0fda23411563c70b7db5f39f43c2869c108b5..52cb20f1cb3612394544a6a41f10e9e939bc0657 100644
---- a/ipaserver/install/ca.py
-+++ b/ipaserver/install/ca.py
-@@ -320,7 +320,7 @@ def install_step_1(standalone, replica_config, options):
-             realm_name, nssdir=dirname, subject_base=subject_base)
-         cacert = cadb.get_cert_from_db('caSigningCert cert-pki-ca', pem=False)
-         nickname = certdb.get_ca_nickname(realm_name)
--        trust_flags = 'CT,C,C'
-+        trust_flags = certdb.IPA_CA_TRUST_FLAGS
-         dsdb.add_cert(cacert, nickname, trust_flags)
-         certstore.put_ca_cert_nss(api.Backend.ldap2, api.env.basedn,
-                                   cacert, nickname, trust_flags,
-diff --git a/ipaserver/install/certs.py b/ipaserver/install/certs.py
-index 89e57134f24c505d669057eefffb7862b3b8179a..f87e00eb5e9c14ed30d39ef9f6e86b6f24bb1c61 100644
---- a/ipaserver/install/certs.py
-+++ b/ipaserver/install/certs.py
-@@ -37,6 +37,7 @@ from ipalib.install import certmonger, sysrestore
- from ipapython.ipa_log_manager import root_logger
- from ipapython import dogtag
- from ipapython import ipautil
-+from ipapython.certdb import EMPTY_TRUST_FLAGS, IPA_CA_TRUST_FLAGS
- from ipapython.certdb import get_ca_nickname, find_cert_from_txt, NSSDatabase
- from ipapython.dn import DN
- from ipalib import pkcs10, x509, api
-@@ -597,7 +598,7 @@ class CertDB(object):
-         # a new certificate database.
-         self.create_passwd_file()
-         self.create_certdbs()
--        self.load_cacert(cacert_fname, 'CT,C,C')
-+        self.load_cacert(cacert_fname, IPA_CA_TRUST_FLAGS)
- 
-     def create_from_pkcs12(self, pkcs12_fname, pkcs12_passwd, passwd=None,
-                            ca_file=None, trust_flags=None):
-@@ -643,7 +644,7 @@ class CertDB(object):
-                     cert, st = find_cert_from_txt(certs, st)
-                 except RuntimeError:
-                     break
--                self.add_cert(cert, 'CA %s' % num, ',,', pem=True)
-+                self.add_cert(cert, 'CA %s' % num, EMPTY_TRUST_FLAGS, pem=True)
-                 num += 1
- 
-         # We only handle one server cert
-diff --git a/ipaserver/install/dsinstance.py b/ipaserver/install/dsinstance.py
-index 403fe8489fdd9e0dbf40dd4df3794b51185d45b9..0db0368fa4b48495718afd779291ce164d1687c8 100644
---- a/ipaserver/install/dsinstance.py
-+++ b/ipaserver/install/dsinstance.py
-@@ -32,6 +32,7 @@ import fnmatch
- import ldap
- 
- from ipalib.install import certmonger, certstore
-+from ipapython.certdb import IPA_CA_TRUST_FLAGS, EXTERNAL_CA_TRUST_FLAGS
- from ipapython.ipa_log_manager import root_logger
- from ipapython import ipautil, ipaldap
- from ipapython import dogtag
-@@ -766,7 +767,7 @@ class DsInstance(service.Service):
-         )
-         if self.pkcs12_info:
-             if self.ca_is_configured:
--                trust_flags = 'CT,C,C'
-+                trust_flags = IPA_CA_TRUST_FLAGS
-             else:
-                 trust_flags = None
-             dsdb.create_from_pkcs12(self.pkcs12_info[0], self.pkcs12_info[1],
-@@ -1065,7 +1066,7 @@ class DsInstance(service.Service):
-         certdb.cacert_name = cacert_name
-         status = True
-         try:
--            certdb.load_cacert(cacert_fname, 'C,,')
-+            certdb.load_cacert(cacert_fname, EXTERNAL_CA_TRUST_FLAGS)
-         except ipautil.CalledProcessError as e:
-             root_logger.critical("Error importing CA cert file named [%s]: %s" %
-                                          (cacert_fname, str(e)))
-diff --git a/ipaserver/install/httpinstance.py b/ipaserver/install/httpinstance.py
-index ab688a85f157b1886842a91bb7d22f9ea99e3615..a6aeb21edc73783ff9a3f9b526409ea525aa66dd 100644
---- a/ipaserver/install/httpinstance.py
-+++ b/ipaserver/install/httpinstance.py
-@@ -32,6 +32,7 @@ import six
- from augeas import Augeas
- 
- from ipalib.install import certmonger
-+from ipapython.certdb import IPA_CA_TRUST_FLAGS, TRUSTED_PEER_TRUST_FLAGS
- from ipaserver.install import service
- from ipaserver.install import certs
- from ipaserver.install import installutils
-@@ -381,7 +382,7 @@ class HTTPInstance(service.Service):
- 
-         if self.pkcs12_info:
-             if self.ca_is_configured:
--                trust_flags = 'CT,C,C'
-+                trust_flags = IPA_CA_TRUST_FLAGS
-             else:
-                 trust_flags = None
-             db.init_from_pkcs12(self.pkcs12_info[0], self.pkcs12_info[1],
-@@ -403,7 +404,7 @@ class HTTPInstance(service.Service):
-             self.__set_mod_nss_nickname(nickname)
-             self.add_cert_to_service()
- 
--            db.trust_root_cert(nickname, "P,,")
-+            db.trust_root_cert(nickname, TRUSTED_PEER_TRUST_FLAGS)
- 
-         else:
-             if not self.promote:
-diff --git a/ipaserver/install/ipa_cacert_manage.py b/ipaserver/install/ipa_cacert_manage.py
-index 3b732e4dcbb5c9b4dfbb9e3608bc7d7afd3e10c2..88b40d45e10281d272882d21e06f5d53cf5a701d 100644
---- a/ipaserver/install/ipa_cacert_manage.py
-+++ b/ipaserver/install/ipa_cacert_manage.py
-@@ -26,6 +26,7 @@ import gssapi
- 
- from ipalib.install import certmonger, certstore
- from ipapython import admintool, ipautil
-+from ipapython.certdb import EMPTY_TRUST_FLAGS, EXTERNAL_CA_TRUST_FLAGS
- from ipapython.dn import DN
- from ipaplatform.paths import paths
- from ipalib import api, errors, x509
-@@ -242,10 +243,10 @@ class CACertManage(admintool.AdminTool):
- 
-         with certs.NSSDatabase() as tmpdb:
-             tmpdb.create_db()
--            tmpdb.add_cert(old_cert_der, 'IPA CA', 'C,,')
-+            tmpdb.add_cert(old_cert_der, 'IPA CA', EXTERNAL_CA_TRUST_FLAGS)
- 
-             try:
--                tmpdb.add_cert(new_cert_der, 'IPA CA', 'C,,')
-+                tmpdb.add_cert(new_cert_der, 'IPA CA', EXTERNAL_CA_TRUST_FLAGS)
-             except ipautil.CalledProcessError as e:
-                 raise admintool.ScriptError(
-                     "Not compatible with the current CA certificate: %s" % e)
-@@ -253,7 +254,8 @@ class CACertManage(admintool.AdminTool):
-             ca_certs = x509.load_certificate_list_from_file(ca_file.name)
-             for ca_cert in ca_certs:
-                 data = ca_cert.public_bytes(serialization.Encoding.DER)
--                tmpdb.add_cert(data, str(DN(ca_cert.subject)), 'C,,')
-+                tmpdb.add_cert(
-+                    data, str(DN(ca_cert.subject)), EXTERNAL_CA_TRUST_FLAGS)
- 
-             try:
-                 tmpdb.verify_ca_cert_validity('IPA CA')
-@@ -270,7 +272,11 @@ class CACertManage(admintool.AdminTool):
-                 except RuntimeError:
-                     break
-                 certstore.put_ca_cert_nss(
--                    conn, api.env.basedn, ca_cert, nickname, ',,')
-+                    conn,
-+                    api.env.basedn,
-+                    ca_cert,
-+                    nickname,
-+                    EMPTY_TRUST_FLAGS)
- 
-         dn = DN(('cn', self.cert_nickname), ('cn', 'ca_renewal'),
-                 ('cn', 'ipa'), ('cn', 'etc'), api.env.basedn)
-@@ -343,7 +349,7 @@ class CACertManage(admintool.AdminTool):
- 
-         with certs.NSSDatabase() as tmpdb:
-             tmpdb.create_db()
--            tmpdb.add_cert(cert, nickname, 'C,,')
-+            tmpdb.add_cert(cert, nickname, EXTERNAL_CA_TRUST_FLAGS)
-             for ca_cert, ca_nickname, ca_trust_flags in ca_certs:
-                 tmpdb.add_cert(ca_cert, ca_nickname, ca_trust_flags)
- 
-diff --git a/ipaserver/install/plugins/upload_cacrt.py b/ipaserver/install/plugins/upload_cacrt.py
-index 425ea63976ec92a6d69492d90a1e970e528c4a26..7d294ff971bd109e5fbb3570bfff0198f24b68d3 100644
---- a/ipaserver/install/plugins/upload_cacrt.py
-+++ b/ipaserver/install/plugins/upload_cacrt.py
-@@ -55,7 +55,7 @@ class update_upload_cacrt(Updater):
-             if 'u' in trust_flags:
-                 continue
-             if nickname == ca_nickname and ca_enabled:
--                trust_flags = 'CT,C,C'
-+                trust_flags = certdb.IPA_CA_TRUST_FLAGS
-             cert = db.get_cert_from_db(nickname, pem=False)
-             trust, _ca, eku = certstore.trust_flags_to_key_policy(trust_flags)
- 
-diff --git a/ipaserver/install/server/replicainstall.py b/ipaserver/install/server/replicainstall.py
-index aa8e67f60b8abe591d55a907c409b584c74d4541..5e78e6faf51ded2fe7634f230c66aa15ae84bad4 100644
---- a/ipaserver/install/server/replicainstall.py
-+++ b/ipaserver/install/server/replicainstall.py
-@@ -23,6 +23,7 @@ import ipaclient.install.ntpconf
- from ipalib.install import certstore, sysrestore
- from ipalib.install.kinit import kinit_keytab
- from ipapython import ipaldap, ipautil
-+from ipapython.certdb import IPA_CA_TRUST_FLAGS
- from ipapython.dn import DN
- from ipapython.ipa_log_manager import root_logger
- from ipapython.admintool import ScriptError
-@@ -737,7 +738,7 @@ def install_check(installer):
-                                   nssdir=tmp_db_dir,
-                                   subject_base=config.subject_base)
-             if ca_enabled:
--                trust_flags = 'CT,C,C'
-+                trust_flags = IPA_CA_TRUST_FLAGS
-             else:
-                 trust_flags = None
-             tmp_db.create_from_pkcs12(pkcs12_info[0], pkcs12_info[1],
-diff --git a/ipaserver/install/server/upgrade.py b/ipaserver/install/server/upgrade.py
-index 5e5c83731d3d3415deb61271baa7865c62f60336..73a4f1108a56a766cdbbcb93d7050482a8264a75 100644
---- a/ipaserver/install/server/upgrade.py
-+++ b/ipaserver/install/server/upgrade.py
-@@ -1389,7 +1389,7 @@ def fix_trust_flags():
-     nickname = certdb.get_ca_nickname(api.env.realm)
-     cert = db.get_cert_from_db(nickname)
-     if cert:
--        db.trust_root_cert(nickname, 'CT,C,C')
-+        db.trust_root_cert(nickname, certdb.IPA_CA_TRUST_FLAGS)
- 
-     sysupgrade.set_upgrade_state('http', 'fix_trust_flags', True)
- 
-@@ -1407,7 +1407,7 @@ def fix_server_cert_trust_flags():
-     sc_nickname = installutils.get_directive(paths.HTTPD_NSS_CONF,
-                                              "NSSNickname")
-     # Add trust flag which set certificate trusted for SSL connections.
--    db.trust_root_cert(sc_nickname, "P,,")
-+    db.trust_root_cert(sc_nickname, certdb.TRUSTED_PEER_TRUST_FLAGS)
- 
-     sysupgrade.set_upgrade_state('http', 'fix_serv_cert_trust_flags', True)
- 
--- 
-2.9.4
-
diff --git a/SOURCES/0144-certdb-certs-make-trust-flags-argument-mandatory.patch b/SOURCES/0144-certdb-certs-make-trust-flags-argument-mandatory.patch
deleted file mode 100644
index 8ed40ad..0000000
--- a/SOURCES/0144-certdb-certs-make-trust-flags-argument-mandatory.patch
+++ /dev/null
@@ -1,181 +0,0 @@
-From 997ebc0f56963769bdcbeda60a2dca222c884b1e Mon Sep 17 00:00:00 2001
-From: Jan Cholasta <jcholast@redhat.com>
-Date: Thu, 27 Apr 2017 09:57:45 +0200
-Subject: [PATCH] certdb, certs: make trust flags argument mandatory
-
-Make the trust flags argument mandatory in all functions in `certdb` and
-`certs`.
-
-https://pagure.io/freeipa/issue/6831
-
-Reviewed-By: Stanislav Laznicka <slaznick@redhat.com>
-Reviewed-By: Martin Babinsky <mbabinsk@redhat.com>
----
- ipapython/certdb.py                        |  4 +---
- ipaserver/install/certs.py                 | 11 +++++------
- ipaserver/install/dsinstance.py            |  2 +-
- ipaserver/install/httpinstance.py          |  6 ++++--
- ipaserver/install/installutils.py          |  5 +++--
- ipaserver/install/server/replicainstall.py |  4 ++--
- 6 files changed, 16 insertions(+), 16 deletions(-)
-
-diff --git a/ipapython/certdb.py b/ipapython/certdb.py
-index 44c7bf3197c198295035742e6db48527d76e85a6..88dcae750de5881ae7b4921ca1ae23daa9c5d4b0 100644
---- a/ipapython/certdb.py
-+++ b/ipapython/certdb.py
-@@ -471,14 +471,12 @@ class NSSDatabase(object):
- 
-             self.import_pkcs12(out_file.name, out_password)
- 
--    def trust_root_cert(self, root_nickname, trust_flags=None):
-+    def trust_root_cert(self, root_nickname, trust_flags):
-         if root_nickname[:7] == "Builtin":
-             root_logger.debug(
-                 "No need to add trust for built-in root CAs, skipping %s" %
-                 root_nickname)
-         else:
--            if trust_flags is None:
--                trust_flags = EXTERNAL_CA_TRUST_FLAGS
-             try:
-                 self.run_certutil(["-M", "-n", root_nickname,
-                                    "-t", trust_flags])
-diff --git a/ipaserver/install/certs.py b/ipaserver/install/certs.py
-index f87e00eb5e9c14ed30d39ef9f6e86b6f24bb1c61..17b9ebad4a128e292e453af44ca9d63cfb1e6ea2 100644
---- a/ipaserver/install/certs.py
-+++ b/ipaserver/install/certs.py
-@@ -550,7 +550,7 @@ class CertDB(object):
- 
-         return root_nicknames
- 
--    def trust_root_cert(self, root_nickname, trust_flags=None):
-+    def trust_root_cert(self, root_nickname, trust_flags):
-         if root_nickname is None:
-             root_logger.debug("Unable to identify root certificate to trust. Continuing but things are likely to fail.")
-             return
-@@ -600,14 +600,13 @@ class CertDB(object):
-         self.create_certdbs()
-         self.load_cacert(cacert_fname, IPA_CA_TRUST_FLAGS)
- 
--    def create_from_pkcs12(self, pkcs12_fname, pkcs12_passwd, passwd=None,
--                           ca_file=None, trust_flags=None):
-+    def create_from_pkcs12(self, pkcs12_fname, pkcs12_passwd,
-+                           ca_file, trust_flags):
-         """Create a new NSS database using the certificates in a PKCS#12 file.
- 
-            pkcs12_fname: the filename of the PKCS#12 file
-            pkcs12_pwd_fname: the file containing the pin for the PKCS#12 file
-            nickname: the nickname/friendly-name of the cert we are loading
--           passwd: The password to use for the new NSS database we are creating
- 
-            The global CA may be added as well in case it wasn't included in the
-            PKCS#12 file. Extra certs won't hurt in any case.
-@@ -615,7 +614,7 @@ class CertDB(object):
-            The global CA may be specified in ca_file, as a PEM filename.
-         """
-         self.create_noise_file()
--        self.create_passwd_file(passwd)
-+        self.create_passwd_file()
-         self.create_certdbs()
-         self.init_from_pkcs12(
-             pkcs12_fname,
-@@ -624,7 +623,7 @@ class CertDB(object):
-             trust_flags=trust_flags)
- 
-     def init_from_pkcs12(self, pkcs12_fname, pkcs12_passwd,
--                         ca_file=None, trust_flags=None):
-+                         ca_file, trust_flags):
-         self.import_pkcs12(pkcs12_fname, pkcs12_passwd)
-         server_certs = self.find_server_certs()
-         if len(server_certs) == 0:
-diff --git a/ipaserver/install/dsinstance.py b/ipaserver/install/dsinstance.py
-index 0db0368fa4b48495718afd779291ce164d1687c8..0e4ae4bfe6f1445de167df8fe5328d6a421e416f 100644
---- a/ipaserver/install/dsinstance.py
-+++ b/ipaserver/install/dsinstance.py
-@@ -769,7 +769,7 @@ class DsInstance(service.Service):
-             if self.ca_is_configured:
-                 trust_flags = IPA_CA_TRUST_FLAGS
-             else:
--                trust_flags = None
-+                trust_flags = EXTERNAL_CA_TRUST_FLAGS
-             dsdb.create_from_pkcs12(self.pkcs12_info[0], self.pkcs12_info[1],
-                                     ca_file=self.ca_file,
-                                     trust_flags=trust_flags)
-diff --git a/ipaserver/install/httpinstance.py b/ipaserver/install/httpinstance.py
-index a6aeb21edc73783ff9a3f9b526409ea525aa66dd..c76a1a4e484c5777ced92761916c1c586e8b2d5d 100644
---- a/ipaserver/install/httpinstance.py
-+++ b/ipaserver/install/httpinstance.py
-@@ -32,7 +32,9 @@ import six
- from augeas import Augeas
- 
- from ipalib.install import certmonger
--from ipapython.certdb import IPA_CA_TRUST_FLAGS, TRUSTED_PEER_TRUST_FLAGS
-+from ipapython.certdb import (IPA_CA_TRUST_FLAGS,
-+                              EXTERNAL_CA_TRUST_FLAGS,
-+                              TRUSTED_PEER_TRUST_FLAGS)
- from ipaserver.install import service
- from ipaserver.install import certs
- from ipaserver.install import installutils
-@@ -384,7 +386,7 @@ class HTTPInstance(service.Service):
-             if self.ca_is_configured:
-                 trust_flags = IPA_CA_TRUST_FLAGS
-             else:
--                trust_flags = None
-+                trust_flags = EXTERNAL_CA_TRUST_FLAGS
-             db.init_from_pkcs12(self.pkcs12_info[0], self.pkcs12_info[1],
-                                 ca_file=self.ca_file,
-                                 trust_flags=trust_flags)
-diff --git a/ipaserver/install/installutils.py b/ipaserver/install/installutils.py
-index b6f01489ccc65dcbc360929e0a7b315b074df8ce..0445a1d3c403fab690e5afb7c8801ed85773b1e0 100644
---- a/ipaserver/install/installutils.py
-+++ b/ipaserver/install/installutils.py
-@@ -49,6 +49,7 @@ from ipalib.install.kinit import kinit_password
- import ipaplatform
- from ipapython import ipautil, admintool, version
- from ipapython.admintool import ScriptError
-+from ipapython.certdb import EXTERNAL_CA_TRUST_FLAGS
- from ipapython.ipa_log_manager import root_logger
- from ipapython.ipaldap import DIRMAN_DN, LDAPClient
- from ipalib.util import validate_hostname
-@@ -1036,7 +1037,7 @@ def load_pkcs12(cert_files, key_password, key_nickname, ca_cert_files,
-             if 'u' in trust_flags:
-                 key_nickname = nickname
-                 continue
--            nssdb.trust_root_cert(nickname)
-+            nssdb.trust_root_cert(nickname, EXTERNAL_CA_TRUST_FLAGS)
- 
-         # Check we have the whole cert chain & the CA is in it
-         trust_chain = list(reversed(nssdb.get_trust_chain(key_nickname)))
-@@ -1176,7 +1177,7 @@ def load_external_cert(files, ca_subject):
-             cache[nickname] = (cert, subject, issuer)
-             if subject == ca_subject:
-                 ca_nickname = nickname
--            nssdb.trust_root_cert(nickname)
-+            nssdb.trust_root_cert(nickname, EXTERNAL_CA_TRUST_FLAGS)
- 
-         if ca_nickname is None:
-             raise ScriptError(
-diff --git a/ipaserver/install/server/replicainstall.py b/ipaserver/install/server/replicainstall.py
-index 5e78e6faf51ded2fe7634f230c66aa15ae84bad4..fb738cb9f590f3f9595de92ef025c6032e9343f8 100644
---- a/ipaserver/install/server/replicainstall.py
-+++ b/ipaserver/install/server/replicainstall.py
-@@ -23,7 +23,7 @@ import ipaclient.install.ntpconf
- from ipalib.install import certstore, sysrestore
- from ipalib.install.kinit import kinit_keytab
- from ipapython import ipaldap, ipautil
--from ipapython.certdb import IPA_CA_TRUST_FLAGS
-+from ipapython.certdb import IPA_CA_TRUST_FLAGS, EXTERNAL_CA_TRUST_FLAGS
- from ipapython.dn import DN
- from ipapython.ipa_log_manager import root_logger
- from ipapython.admintool import ScriptError
-@@ -740,7 +740,7 @@ def install_check(installer):
-             if ca_enabled:
-                 trust_flags = IPA_CA_TRUST_FLAGS
-             else:
--                trust_flags = None
-+                trust_flags = EXTERNAL_CA_TRUST_FLAGS
-             tmp_db.create_from_pkcs12(pkcs12_info[0], pkcs12_info[1],
-                                       ca_file=cafile,
-                                       trust_flags=trust_flags)
--- 
-2.9.4
-
diff --git a/SOURCES/0145-certdb-use-custom-object-for-trust-flags.patch b/SOURCES/0145-certdb-use-custom-object-for-trust-flags.patch
deleted file mode 100644
index 6699565..0000000
--- a/SOURCES/0145-certdb-use-custom-object-for-trust-flags.patch
+++ /dev/null
@@ -1,358 +0,0 @@
-From e8805e118446a1ad542d183e2f6bea0f87651795 Mon Sep 17 00:00:00 2001
-From: Jan Cholasta <jcholast@redhat.com>
-Date: Thu, 27 Apr 2017 09:37:38 +0200
-Subject: [PATCH] certdb: use custom object for trust flags
-
-Replace trust flag strings with `TrustFlags` objects. The `TrustFlags`
-class encapsulates `certstore` key policy and has an additional flag
-indicating the presence of a private key.
-
-https://pagure.io/freeipa/issue/6831
-
-Reviewed-By: Stanislav Laznicka <slaznick@redhat.com>
-Reviewed-By: Martin Babinsky <mbabinsk@redhat.com>
----
- install/restart_scripts/renew_ca_cert       |   2 +-
- ipalib/install/certstore.py                 |  49 +------------
- ipapython/certdb.py                         | 109 ++++++++++++++++++++++++++--
- ipaserver/install/installutils.py           |   2 +-
- ipaserver/install/ipa_cacert_manage.py      |   6 +-
- ipaserver/install/ipa_server_certinstall.py |   4 +-
- ipaserver/install/plugins/upload_cacrt.py   |   2 +-
- ipaserver/install/server/upgrade.py         |   2 +-
- 8 files changed, 117 insertions(+), 59 deletions(-)
-
-diff --git a/install/restart_scripts/renew_ca_cert b/install/restart_scripts/renew_ca_cert
-index 7a54b4c7e05a35b40b17e46b75ff8d47db1b2d23..bb31defc0e2bdca044e68ae067f42fb3bd41a57f 100644
---- a/install/restart_scripts/renew_ca_cert
-+++ b/install/restart_scripts/renew_ca_cert
-@@ -125,7 +125,7 @@ def _main():
- 
-             # Remove old external CA certificates
-             for ca_nick, ca_flags in db.list_certs():
--                if 'u' in ca_flags:
-+                if ca_flags.has_key:
-                     continue
-                 # Delete *all* certificates that use the nickname
-                 while True:
-diff --git a/ipalib/install/certstore.py b/ipalib/install/certstore.py
-index 310e08ed2273badba6fde4ada0ee52501fddc72c..bc2079fb12873444cbe6796eebfdfcfebd0e284d 100644
---- a/ipalib/install/certstore.py
-+++ b/ipalib/install/certstore.py
-@@ -25,7 +25,7 @@ LDAP shared certificate store.
- from pyasn1.error import PyAsn1Error
- 
- from ipapython.dn import DN
--from ipapython.certdb import get_ca_nickname
-+from ipapython.certdb import get_ca_nickname, TrustFlags
- from ipalib import errors, x509
- 
- def _parse_cert(dercert):
-@@ -344,57 +344,14 @@ def trust_flags_to_key_policy(trust_flags):
-     """
-     Convert certutil trust flags to certificate store key policy.
-     """
--    if 'p' in trust_flags:
--        if 'C' in trust_flags or 'P' in trust_flags or 'T' in trust_flags:
--            raise ValueError("cannot be both trusted and not trusted")
--        return False, None, None
--    elif 'C' in trust_flags or 'T' in trust_flags:
--        if 'P' in trust_flags:
--            raise ValueError("cannot be both CA and not CA")
--        ca = True
--    elif 'P' in trust_flags:
--        ca = False
--    else:
--        return None, None, set()
--
--    trust_flags = trust_flags.split(',')
--    ext_key_usage = set()
--    for i, kp in enumerate((x509.EKU_SERVER_AUTH,
--                            x509.EKU_EMAIL_PROTECTION,
--                            x509.EKU_CODE_SIGNING)):
--        if 'C' in trust_flags[i] or 'P' in trust_flags[i]:
--            ext_key_usage.add(kp)
--    if 'T' in trust_flags[0]:
--        ext_key_usage.add(x509.EKU_CLIENT_AUTH)
--
--    return True, ca, ext_key_usage
-+    return trust_flags[1:]
- 
- 
- def key_policy_to_trust_flags(trusted, ca, ext_key_usage):
-     """
-     Convert certificate store key policy to certutil trust flags.
-     """
--    if trusted is False:
--        return 'p,p,p'
--    elif trusted is None or ca is None:
--        return ',,'
--    elif ext_key_usage is None:
--        if ca:
--            return 'CT,C,C'
--        else:
--            return 'P,P,P'
--
--    trust_flags = ['', '', '']
--    for i, kp in enumerate((x509.EKU_SERVER_AUTH,
--                            x509.EKU_EMAIL_PROTECTION,
--                            x509.EKU_CODE_SIGNING)):
--        if kp in ext_key_usage:
--            trust_flags[i] += ('C' if ca else 'P')
--    if ca and x509.EKU_CLIENT_AUTH in ext_key_usage:
--        trust_flags[0] += 'T'
--
--    trust_flags = ','.join(trust_flags)
--    return trust_flags
-+    return TrustFlags(False, trusted, ca, ext_key_usage)
- 
- 
- def put_ca_cert_nss(ldap, base_dn, dercert, nickname, trust_flags,
-diff --git a/ipapython/certdb.py b/ipapython/certdb.py
-index 88dcae750de5881ae7b4921ca1ae23daa9c5d4b0..af95eba3cbad1c354615457ed0501f97bff0e22d 100644
---- a/ipapython/certdb.py
-+++ b/ipapython/certdb.py
-@@ -17,6 +17,7 @@
- # along with this program.  If not, see <http://www.gnu.org/licenses/>.
- #
- 
-+import collections
- import os
- import io
- import pwd
-@@ -52,10 +53,26 @@ CA_NICKNAME_FMT = "%s IPA CA"
- 
- NSS_FILES = ("cert8.db", "key3.db", "secmod.db", "pwdfile.txt")
- 
--EMPTY_TRUST_FLAGS = ',,'
--IPA_CA_TRUST_FLAGS = 'CT,C,C'
--EXTERNAL_CA_TRUST_FLAGS = 'C,,'
--TRUSTED_PEER_TRUST_FLAGS = 'P,,'
-+TrustFlags = collections.namedtuple('TrustFlags', 'has_key trusted ca usages')
-+
-+EMPTY_TRUST_FLAGS = TrustFlags(False, None, None, None)
-+
-+IPA_CA_TRUST_FLAGS = TrustFlags(
-+    False, True, True, frozenset({
-+        x509.EKU_SERVER_AUTH,
-+        x509.EKU_CLIENT_AUTH,
-+        x509.EKU_CODE_SIGNING,
-+        x509.EKU_EMAIL_PROTECTION,
-+    }),
-+)
-+
-+EXTERNAL_CA_TRUST_FLAGS = TrustFlags(
-+    False, True, True, frozenset({x509.EKU_SERVER_AUTH}),
-+)
-+
-+TRUSTED_PEER_TRUST_FLAGS = TrustFlags(
-+    False, True, False, frozenset({x509.EKU_SERVER_AUTH}),
-+)
- 
- 
- def get_ca_nickname(realm, format=CA_NICKNAME_FMT):
-@@ -87,6 +104,82 @@ def get_file_cont(slot, token, filename):
-         return f.read()
- 
- 
-+def parse_trust_flags(trust_flags):
-+    """
-+    Convert certutil trust flags to TrustFlags object.
-+    """
-+    has_key = 'u' in trust_flags
-+
-+    if 'p' in trust_flags:
-+        if 'C' in trust_flags or 'P' in trust_flags or 'T' in trust_flags:
-+            raise ValueError("cannot be both trusted and not trusted")
-+        return False, None, None
-+    elif 'C' in trust_flags or 'T' in trust_flags:
-+        if 'P' in trust_flags:
-+            raise ValueError("cannot be both CA and not CA")
-+        ca = True
-+    elif 'P' in trust_flags:
-+        ca = False
-+    else:
-+        return TrustFlags(has_key, None, None, frozenset())
-+
-+    trust_flags = trust_flags.split(',')
-+    ext_key_usage = set()
-+    for i, kp in enumerate((x509.EKU_SERVER_AUTH,
-+                            x509.EKU_EMAIL_PROTECTION,
-+                            x509.EKU_CODE_SIGNING)):
-+        if 'C' in trust_flags[i] or 'P' in trust_flags[i]:
-+            ext_key_usage.add(kp)
-+    if 'T' in trust_flags[0]:
-+        ext_key_usage.add(x509.EKU_CLIENT_AUTH)
-+
-+    return TrustFlags(has_key, True, ca, frozenset(ext_key_usage))
-+
-+
-+def unparse_trust_flags(trust_flags):
-+    """
-+    Convert TrustFlags object to certutil trust flags.
-+    """
-+    has_key, trusted, ca, ext_key_usage = trust_flags
-+
-+    if trusted is False:
-+        if has_key:
-+            return 'pu,pu,pu'
-+        else:
-+            return 'p,p,p'
-+    elif trusted is None or ca is None:
-+        if has_key:
-+            return 'u,u,u'
-+        else:
-+            return ',,'
-+    elif ext_key_usage is None:
-+        if ca:
-+            if has_key:
-+                return 'CTu,Cu,Cu'
-+            else:
-+                return 'CT,C,C'
-+        else:
-+            if has_key:
-+                return 'Pu,Pu,Pu'
-+            else:
-+                return 'P,P,P'
-+
-+    trust_flags = ['', '', '']
-+    for i, kp in enumerate((x509.EKU_SERVER_AUTH,
-+                            x509.EKU_EMAIL_PROTECTION,
-+                            x509.EKU_CODE_SIGNING)):
-+        if kp in ext_key_usage:
-+            trust_flags[i] += ('C' if ca else 'P')
-+    if ca and x509.EKU_CLIENT_AUTH in ext_key_usage:
-+        trust_flags[0] += 'T'
-+    if has_key:
-+        for i in range(3):
-+            trust_flags[i] += 'u'
-+
-+    trust_flags = ','.join(trust_flags)
-+    return trust_flags
-+
-+
- class NSSDatabase(object):
-     """A general-purpose wrapper around a NSS cert database
- 
-@@ -205,7 +298,9 @@ class NSSDatabase(object):
-         for cert in certs:
-             match = re.match(r'^(.+?)\s+(\w*,\w*,\w*)\s*$', cert)
-             if match:
--                certlist.append(match.groups())
-+                nickname = match.group(1)
-+                trust_flags = parse_trust_flags(match.group(2))
-+                certlist.append((nickname, trust_flags))
- 
-         return tuple(certlist)
- 
-@@ -218,7 +313,7 @@ class NSSDatabase(object):
-         """
-         server_certs = []
-         for name, flags in self.list_certs():
--            if 'u' in flags:
-+            if flags.has_key:
-                 server_certs.append((name, flags))
- 
-         return server_certs
-@@ -477,6 +572,7 @@ class NSSDatabase(object):
-                 "No need to add trust for built-in root CAs, skipping %s" %
-                 root_nickname)
-         else:
-+            trust_flags = unparse_trust_flags(trust_flags)
-             try:
-                 self.run_certutil(["-M", "-n", root_nickname,
-                                    "-t", trust_flags])
-@@ -538,6 +634,7 @@ class NSSDatabase(object):
-                              location)
- 
-     def add_cert(self, cert, nick, flags, pem=False):
-+        flags = unparse_trust_flags(flags)
-         args = ["-A", "-n", nick, "-t", flags]
-         if pem:
-             args.append("-a")
-diff --git a/ipaserver/install/installutils.py b/ipaserver/install/installutils.py
-index 0445a1d3c403fab690e5afb7c8801ed85773b1e0..5bce9894780bd920db11196b925492a7fe8f22d0 100644
---- a/ipaserver/install/installutils.py
-+++ b/ipaserver/install/installutils.py
-@@ -1034,7 +1034,7 @@ def load_pkcs12(cert_files, key_password, key_nickname, ca_cert_files,
-                 raise ScriptError(str(e))
- 
-         for nickname, trust_flags in nssdb.list_certs():
--            if 'u' in trust_flags:
-+            if trust_flags.has_key:
-                 key_nickname = nickname
-                 continue
-             nssdb.trust_root_cert(nickname, EXTERNAL_CA_TRUST_FLAGS)
-diff --git a/ipaserver/install/ipa_cacert_manage.py b/ipaserver/install/ipa_cacert_manage.py
-index 88b40d45e10281d272882d21e06f5d53cf5a701d..d28a5966f054141819463cdb1dfef48ee1e46e92 100644
---- a/ipaserver/install/ipa_cacert_manage.py
-+++ b/ipaserver/install/ipa_cacert_manage.py
-@@ -26,7 +26,9 @@ import gssapi
- 
- from ipalib.install import certmonger, certstore
- from ipapython import admintool, ipautil
--from ipapython.certdb import EMPTY_TRUST_FLAGS, EXTERNAL_CA_TRUST_FLAGS
-+from ipapython.certdb import (EMPTY_TRUST_FLAGS,
-+                              EXTERNAL_CA_TRUST_FLAGS,
-+                              parse_trust_flags)
- from ipapython.dn import DN
- from ipaplatform.paths import paths
- from ipalib import api, errors, x509
-@@ -366,6 +368,8 @@ class CACertManage(admintool.AdminTool):
-             len(trust_flags.split(',')) != 3):
-             raise admintool.ScriptError("Invalid trust flags")
- 
-+        trust_flags = parse_trust_flags(trust_flags)
-+
-         try:
-             certstore.put_ca_cert_nss(
-                 api.Backend.ldap2, api.env.basedn, cert, nickname, trust_flags)
-diff --git a/ipaserver/install/ipa_server_certinstall.py b/ipaserver/install/ipa_server_certinstall.py
-index ee93535edfd258fe71099881c54c413516b24d17..9f2cd9573a156949ae979e7b69fbd23adaf2feb8 100644
---- a/ipaserver/install/ipa_server_certinstall.py
-+++ b/ipaserver/install/ipa_server_certinstall.py
-@@ -170,13 +170,13 @@ class ServerCertInstall(admintool.AdminTool):
-             # this leaves only the server certs in the temp db
-             tempnssdb.import_pkcs12(pkcs12_filename, pkcs12_pin)
-             for nickname, flags in tempnssdb.list_certs():
--                if 'u' not in flags:
-+                if not flags.has_key:
-                     while tempnssdb.has_nickname(nickname):
-                         tempnssdb.delete_cert(nickname)
- 
-             # import all the CA certs from nssdb into the temp db
-             for nickname, flags in nssdb.list_certs():
--                if 'u' not in flags:
-+                if not flags.has_key:
-                     cert = nssdb.get_cert_from_db(nickname)
-                     tempnssdb.add_cert(cert, nickname, flags)
- 
-diff --git a/ipaserver/install/plugins/upload_cacrt.py b/ipaserver/install/plugins/upload_cacrt.py
-index 7d294ff971bd109e5fbb3570bfff0198f24b68d3..73cc91d8f6dd5811ec74efecd6c885cd8937a0f2 100644
---- a/ipaserver/install/plugins/upload_cacrt.py
-+++ b/ipaserver/install/plugins/upload_cacrt.py
-@@ -52,7 +52,7 @@ class update_upload_cacrt(Updater):
-         ldap = self.api.Backend.ldap2
- 
-         for nickname, trust_flags in db.list_certs():
--            if 'u' in trust_flags:
-+            if trust_flags.has_key:
-                 continue
-             if nickname == ca_nickname and ca_enabled:
-                 trust_flags = certdb.IPA_CA_TRUST_FLAGS
-diff --git a/ipaserver/install/server/upgrade.py b/ipaserver/install/server/upgrade.py
-index 73a4f1108a56a766cdbbcb93d7050482a8264a75..c244958f4cddba0d1edded5165a295b1e1ee2b8a 100644
---- a/ipaserver/install/server/upgrade.py
-+++ b/ipaserver/install/server/upgrade.py
-@@ -1547,7 +1547,7 @@ def disable_httpd_system_trust(http):
- 
-     db = certs.CertDB(api.env.realm, nssdir=paths.HTTPD_ALIAS_DIR)
-     for nickname, trust_flags in db.list_certs():
--        if 'u' not in trust_flags:
-+        if not trust_flags.has_key:
-             cert = db.get_cert_from_db(nickname, pem=False)
-             if cert:
-                 ca_certs.append((cert, nickname, trust_flags))
--- 
-2.9.4
-
diff --git a/SOURCES/0146-install-trust-IPA-CA-for-PKINIT.patch b/SOURCES/0146-install-trust-IPA-CA-for-PKINIT.patch
deleted file mode 100644
index c69b8f0..0000000
--- a/SOURCES/0146-install-trust-IPA-CA-for-PKINIT.patch
+++ /dev/null
@@ -1,202 +0,0 @@
-From e45762bf5b94c064668752160271a00af854b6cf Mon Sep 17 00:00:00 2001
-From: Jan Cholasta <jcholast@redhat.com>
-Date: Wed, 3 May 2017 06:38:20 +0000
-Subject: [PATCH] install: trust IPA CA for PKINIT
-
-Trust IPA CA to issue PKINIT KDC and client authentication certificates in
-the IPA certificate store.
-
-https://pagure.io/freeipa/issue/6831
-
-Reviewed-By: Stanislav Laznicka <slaznick@redhat.com>
-Reviewed-By: Martin Babinsky <mbabinsk@redhat.com>
----
- ipalib/x509.py                             |  2 ++
- ipapython/certdb.py                        |  2 ++
- ipaserver/install/dsinstance.py            | 31 +++++++++++++++++++++++-------
- ipaserver/install/plugins/upload_cacrt.py  |  6 +++++-
- ipaserver/install/server/install.py        |  9 ++++++---
- ipaserver/install/server/replicainstall.py |  1 +
- 6 files changed, 40 insertions(+), 11 deletions(-)
-
-diff --git a/ipalib/x509.py b/ipalib/x509.py
-index f65cf816c9ead50a43e08a3b982f428112e7c1b3..5d1a7b8f4b99e057d4732d388efb0f27def07085 100644
---- a/ipalib/x509.py
-+++ b/ipalib/x509.py
-@@ -64,6 +64,8 @@ EKU_SERVER_AUTH = '1.3.6.1.5.5.7.3.1'
- EKU_CLIENT_AUTH = '1.3.6.1.5.5.7.3.2'
- EKU_CODE_SIGNING = '1.3.6.1.5.5.7.3.3'
- EKU_EMAIL_PROTECTION = '1.3.6.1.5.5.7.3.4'
-+EKU_PKINIT_CLIENT_AUTH = '1.3.6.1.5.2.3.4'
-+EKU_PKINIT_KDC = '1.3.6.1.5.2.3.5'
- EKU_ANY = '2.5.29.37.0'
- EKU_PLACEHOLDER = '1.3.6.1.4.1.3319.6.10.16'
- 
-diff --git a/ipapython/certdb.py b/ipapython/certdb.py
-index af95eba3cbad1c354615457ed0501f97bff0e22d..1ee2603653452577476cf413e6af951cd29c273e 100644
---- a/ipapython/certdb.py
-+++ b/ipapython/certdb.py
-@@ -63,6 +63,8 @@ IPA_CA_TRUST_FLAGS = TrustFlags(
-         x509.EKU_CLIENT_AUTH,
-         x509.EKU_CODE_SIGNING,
-         x509.EKU_EMAIL_PROTECTION,
-+        x509.EKU_PKINIT_CLIENT_AUTH,
-+        x509.EKU_PKINIT_KDC,
-     }),
- )
- 
-diff --git a/ipaserver/install/dsinstance.py b/ipaserver/install/dsinstance.py
-index 0e4ae4bfe6f1445de167df8fe5328d6a421e416f..39248edb285ee4d792b4500d83d88b24f5732d10 100644
---- a/ipaserver/install/dsinstance.py
-+++ b/ipaserver/install/dsinstance.py
-@@ -31,8 +31,11 @@ import fnmatch
- 
- import ldap
- 
-+from ipalib import x509
- from ipalib.install import certmonger, certstore
--from ipapython.certdb import IPA_CA_TRUST_FLAGS, EXTERNAL_CA_TRUST_FLAGS
-+from ipapython.certdb import (IPA_CA_TRUST_FLAGS,
-+                              EXTERNAL_CA_TRUST_FLAGS,
-+                              TrustFlags)
- from ipapython.ipa_log_manager import root_logger
- from ipapython import ipautil, ipaldap
- from ipapython import dogtag
-@@ -289,7 +292,8 @@ class DsInstance(service.Service):
- 
-     def init_info(self, realm_name, fqdn, domain_name, dm_password,
-                   subject_base, ca_subject,
--                  idstart, idmax, pkcs12_info, ca_file=None):
-+                  idstart, idmax, pkcs12_info, ca_file=None,
-+                  setup_pkinit=False):
-         self.realm = realm_name.upper()
-         self.serverid = installutils.realm_to_serverid(self.realm)
-         self.suffix = ipautil.realm_to_suffix(self.realm)
-@@ -303,6 +307,7 @@ class DsInstance(service.Service):
-         self.pkcs12_info = pkcs12_info
-         if pkcs12_info:
-             self.ca_is_configured = False
-+        self.setup_pkinit = setup_pkinit
-         self.ca_file = ca_file
- 
-         self.__setup_sub_dict()
-@@ -311,11 +316,12 @@ class DsInstance(service.Service):
-                         dm_password, pkcs12_info=None,
-                         idstart=1100, idmax=999999,
-                         subject_base=None, ca_subject=None,
--                        hbac_allow=True, ca_file=None):
-+                        hbac_allow=True, ca_file=None, setup_pkinit=False):
-         self.init_info(
-             realm_name, fqdn, domain_name, dm_password,
-             subject_base, ca_subject,
--            idstart, idmax, pkcs12_info, ca_file=ca_file)
-+            idstart, idmax, pkcs12_info, ca_file=ca_file,
-+            setup_pkinit=setup_pkinit)
- 
-         self.__common_setup()
-         self.step("restarting directory server", self.__restart_instance)
-@@ -354,7 +360,8 @@ class DsInstance(service.Service):
-                        domain_name, dm_password,
-                        subject_base, ca_subject,
-                        api, pkcs12_info=None, ca_file=None,
--                       ca_is_configured=None, promote=False):
-+                       ca_is_configured=None, promote=False,
-+                       setup_pkinit=False):
-         # idstart and idmax are configured so that the range is seen as
-         # depleted by the DNA plugin and the replica will go and get a
-         # new range from the master.
-@@ -372,7 +379,8 @@ class DsInstance(service.Service):
-             idstart=idstart,
-             idmax=idmax,
-             pkcs12_info=pkcs12_info,
--            ca_file=ca_file
-+            ca_file=ca_file,
-+            setup_pkinit=setup_pkinit,
-         )
-         self.master_fqdn = master_fqdn
-         if ca_is_configured is not None:
-@@ -882,8 +890,17 @@ class DsInstance(service.Service):
- 
-         nickname = self.cacert_name
-         cert = dsdb.get_cert_from_db(nickname, pem=False)
-+        cacert_flags = trust_flags[nickname]
-+        if self.setup_pkinit:
-+            cacert_flags = TrustFlags(
-+                cacert_flags.has_key,
-+                cacert_flags.trusted,
-+                cacert_flags.ca,
-+                (cacert_flags.usages |
-+                    {x509.EKU_PKINIT_CLIENT_AUTH, x509.EKU_PKINIT_KDC}),
-+            )
-         certstore.put_ca_cert_nss(conn, self.suffix, cert, nickname,
--                                  trust_flags[nickname],
-+                                  cacert_flags,
-                                   config_ipa=self.ca_is_configured,
-                                   config_compat=self.master_fqdn is None)
- 
-diff --git a/ipaserver/install/plugins/upload_cacrt.py b/ipaserver/install/plugins/upload_cacrt.py
-index 73cc91d8f6dd5811ec74efecd6c885cd8937a0f2..a1957ca5b675b86f0df36dc820ee31305f54f863 100644
---- a/ipaserver/install/plugins/upload_cacrt.py
-+++ b/ipaserver/install/plugins/upload_cacrt.py
-@@ -79,7 +79,11 @@ class update_upload_cacrt(Updater):
-             try:
-                 ldap.add_entry(entry)
-             except errors.DuplicateEntry:
--                pass
-+                if nickname == ca_nickname and ca_enabled:
-+                    try:
-+                        ldap.update_entry(entry)
-+                    except errors.EmptyModlist:
-+                        pass
- 
-         if ca_cert:
-             dn = DN(('cn', 'CACert'), ('cn', 'ipa'), ('cn','etc'),
-diff --git a/ipaserver/install/server/install.py b/ipaserver/install/server/install.py
-index 0ce60e964cb210708e56fb43a5b70f8e3405caf2..25c21db721c58388ae8fd6ab1fbc443d513a4324 100644
---- a/ipaserver/install/server/install.py
-+++ b/ipaserver/install/server/install.py
-@@ -737,7 +737,8 @@ def install(installer):
-                                idstart=options.idstart, idmax=options.idmax,
-                                subject_base=options.subject_base,
-                                ca_subject=options.ca_subject,
--                               hbac_allow=not options.no_hbac_allow)
-+                               hbac_allow=not options.no_hbac_allow,
-+                               setup_pkinit=not options.no_pkinit)
-         else:
-             ds = dsinstance.DsInstance(fstore=fstore,
-                                        domainlevel=options.domainlevel,
-@@ -748,7 +749,8 @@ def install(installer):
-                                idstart=options.idstart, idmax=options.idmax,
-                                subject_base=options.subject_base,
-                                ca_subject=options.ca_subject,
--                               hbac_allow=not options.no_hbac_allow)
-+                               hbac_allow=not options.no_hbac_allow,
-+                               setup_pkinit=not options.no_pkinit)
- 
-         ntpinstance.ntp_ldap_enable(host_name, ds.suffix, realm_name)
- 
-@@ -759,7 +761,8 @@ def install(installer):
-         installer._ds = ds
-         ds.init_info(
-             realm_name, host_name, domain_name, dm_password,
--            options.subject_base, options.ca_subject, 1101, 1100, None)
-+            options.subject_base, options.ca_subject, 1101, 1100, None,
-+            setup_pkinit=not options.no_pkinit)
- 
-     krb = krbinstance.KrbInstance(fstore)
-     if not options.external_cert_files:
-diff --git a/ipaserver/install/server/replicainstall.py b/ipaserver/install/server/replicainstall.py
-index fb738cb9f590f3f9595de92ef025c6032e9343f8..c19edceec42845f3169adc923762f700739232f2 100644
---- a/ipaserver/install/server/replicainstall.py
-+++ b/ipaserver/install/server/replicainstall.py
-@@ -107,6 +107,7 @@ def install_replica_ds(config, options, ca_is_configured, remote_api,
-         ca_file=ca_file,
-         promote=promote,  # we need promote because of replication setup
-         api=remote_api,
-+        setup_pkinit=not options.no_pkinit,
-     )
- 
-     return ds
--- 
-2.9.4
-
diff --git a/SOURCES/0147-client-install-fix-client-PKINIT-configuration.patch b/SOURCES/0147-client-install-fix-client-PKINIT-configuration.patch
deleted file mode 100644
index 2f7ca49..0000000
--- a/SOURCES/0147-client-install-fix-client-PKINIT-configuration.patch
+++ /dev/null
@@ -1,254 +0,0 @@
-From e5491b62d3ec21feb7809f7f65797151d256c580 Mon Sep 17 00:00:00 2001
-From: Jan Cholasta <jcholast@redhat.com>
-Date: Wed, 3 May 2017 06:48:57 +0000
-Subject: [PATCH] client install: fix client PKINIT configuration
-
-Set `pkinit_anchors` in `krb5.conf` to a CA certificate bundle of CAs
-trusted to issue KDC certificates rather than `/etc/ipa/ca.crt`.
-
-Set `pkinit_pool` in `krb5.conf` to a CA certificate bundle of all CAs
-known to IPA.
-
-Make sure both bundles are exported in all installation code paths.
-
-https://pagure.io/freeipa/issue/6831
-
-Reviewed-By: Stanislav Laznicka <slaznick@redhat.com>
-Reviewed-By: Martin Babinsky <mbabinsk@redhat.com>
----
- client/Makefile.am                         |  1 +
- freeipa.spec.in                            | 10 ++++++++++
- install/share/krb5.conf.template           |  3 ++-
- ipaclient/install/client.py                | 15 ++++++++++++++-
- ipaclient/install/ipa_certupdate.py        |  2 ++
- ipaplatform/base/paths.py                  |  2 ++
- ipaserver/install/cainstance.py            | 11 +++++++----
- ipaserver/install/ipa_backup.py            |  2 ++
- ipaserver/install/krbinstance.py           |  4 +++-
- ipaserver/install/server/install.py        | 10 ++++++++++
- ipaserver/install/server/replicainstall.py |  4 ++++
- ipaserver/install/server/upgrade.py        |  4 +++-
- 12 files changed, 60 insertions(+), 8 deletions(-)
-
-diff --git a/client/Makefile.am b/client/Makefile.am
-index b6c9dea437460b0f912854a6a2fb9d1f30f3b1e7..e354cb41a4ee0d7da04197abe0e750c5d727bb4d 100644
---- a/client/Makefile.am
-+++ b/client/Makefile.am
-@@ -101,4 +101,5 @@ EXTRA_DIST =			\
- 
- install-data-hook:
- 	$(INSTALL) -d -m 755 $(DESTDIR)$(IPA_SYSCONF_DIR)/nssdb
-+	$(INSTALL) -d -m 755 $(DESTDIR)$(localstatedir)/lib/ipa-client/pki
- 	$(INSTALL) -d -m 755 $(DESTDIR)$(localstatedir)/lib/ipa-client/sysrestore
-diff --git a/freeipa.spec.in b/freeipa.spec.in
-index 0335a9970be82e80e98696f3d7fd4ec64894ef5f..6cb37ae53b039aa1d0e0509f62a3237504be6555 100644
---- a/freeipa.spec.in
-+++ b/freeipa.spec.in
-@@ -1097,6 +1097,15 @@ if [ $1 -gt 1 ] ; then
-         fi
-     fi
- 
-+    if [ $restore -ge 2 ]; then
-+        if grep -E -q '\s*pkinit_anchors = FILE:/etc/ipa/ca.crt$' /etc/krb5.conf 2>/dev/null; then
-+            sed -E 's|(\s*)pkinit_anchors = FILE:/etc/ipa/ca.crt$|\1pkinit_anchors = FILE:/var/lib/ipa-client/pki/kdc-ca-bundle.pem\n\1pkinit_pool = FILE:/var/lib/ipa-client/pki/ca-bundle.pem|' /etc/krb5.conf >/etc/krb5.conf.ipanew
-+            mv -Z /etc/krb5.conf.ipanew /etc/krb5.conf
-+            cp /etc/ipa/ca.crt /var/lib/ipa-client/pki/kdc-ca-bundle.pem
-+            cp /etc/ipa/ca.crt /var/lib/ipa-client/pki/ca-bundle.pem
-+        fi
-+    fi
-+
-     if [ -f '/etc/sysconfig/ntpd' -a $restore -ge 2 ]; then
-         if grep -E -q 'OPTIONS=.*-u ntp:ntp' /etc/sysconfig/ntpd 2>/dev/null; then
-             sed -r '/OPTIONS=/ { s/\s+-u ntp:ntp\s+/ /; s/\s*-u ntp:ntp\s*// }' /etc/sysconfig/ntpd >/etc/sysconfig/ntpd.ipanew
-@@ -1468,6 +1477,7 @@ fi
- %ghost %config(noreplace) %{_sysconfdir}/ipa/nssdb/pwdfile.txt
- %ghost %config(noreplace) %{_sysconfdir}/pki/ca-trust/source/ipa.p11-kit
- %dir %{_localstatedir}/lib/ipa-client
-+%dir %{_localstatedir}/lib/ipa-client/pki
- %dir %{_localstatedir}/lib/ipa-client/sysrestore
- %{_mandir}/man5/default.conf.5*
- 
-diff --git a/install/share/krb5.conf.template b/install/share/krb5.conf.template
-index e8b2ad8dace8264cd9345285f55c42422bf81ca3..1f18ff90d34ccccb42c4b64d188e7d70e9892b71 100644
---- a/install/share/krb5.conf.template
-+++ b/install/share/krb5.conf.template
-@@ -21,7 +21,8 @@ $OTHER_LIBDEFAULTS
-   master_kdc = $FQDN:88
-   admin_server = $FQDN:749
-   default_domain = $DOMAIN
--  pkinit_anchors = FILE:/etc/ipa/ca.crt
-+  pkinit_anchors = FILE:$KDC_CA_BUNDLE_PEM
-+  pkinit_pool = FILE:$CA_BUNDLE_PEM
- }
- 
- [domain_realm]
-diff --git a/ipaclient/install/client.py b/ipaclient/install/client.py
-index e78be904dd6bad491d9f3c1bb1e1410bc1779d45..6f10f5258747881b9af8c6b70b499f9ff7d577ff 100644
---- a/ipaclient/install/client.py
-+++ b/ipaclient/install/client.py
-@@ -710,7 +710,11 @@ def configure_krb5_conf(
-         kropts.append(krbconf.setOption('default_domain', cli_domain))
- 
-     kropts.append(
--        krbconf.setOption('pkinit_anchors', 'FILE:%s' % paths.IPA_CA_CRT))
-+        krbconf.setOption('pkinit_anchors',
-+                          'FILE:%s' % paths.KDC_CA_BUNDLE_PEM))
-+    kropts.append(
-+        krbconf.setOption('pkinit_pool',
-+                          'FILE:%s' % paths.CA_BUNDLE_PEM))
-     ropts = [{
-         'name': cli_realm,
-         'type': 'subsection',
-@@ -2770,6 +2774,13 @@ def _install(options):
-     ca_certs_trust = [(c, n, certstore.key_policy_to_trust_flags(t, True, u))
-                       for (c, n, t, u) in ca_certs]
- 
-+    x509.write_certificate_list(
-+        [c for c, n, t, u in ca_certs if t is not False],
-+        paths.KDC_CA_BUNDLE_PEM)
-+    x509.write_certificate_list(
-+        [c for c, n, t, u in ca_certs if t is not False],
-+        paths.CA_BUNDLE_PEM)
-+
-     # Add the CA certificates to the IPA NSS database
-     root_logger.debug("Adding CA certificates to the IPA NSS database.")
-     ipa_db = certdb.NSSDatabase(paths.IPA_NSSDB_DIR)
-@@ -3317,6 +3328,8 @@ def uninstall(options):
- 
-     # Remove the CA cert
-     remove_file(paths.IPA_CA_CRT)
-+    remove_file(paths.KDC_CA_BUNDLE_PEM)
-+    remove_file(paths.CA_BUNDLE_PEM)
- 
-     root_logger.info("Client uninstall complete.")
- 
-diff --git a/ipaclient/install/ipa_certupdate.py b/ipaclient/install/ipa_certupdate.py
-index 7dc88f07ae14e5416f6fe3dc8400b7d4bcabef72..7e8527e1fcb575844e8f4c90016435124b70e381 100644
---- a/ipaclient/install/ipa_certupdate.py
-+++ b/ipaclient/install/ipa_certupdate.py
-@@ -113,6 +113,8 @@ class CertUpdate(admintool.AdminTool):
- 
-     def update_client(self, certs):
-         self.update_file(paths.IPA_CA_CRT, certs)
-+        self.update_file(paths.KDC_CA_BUNDLE_PEM, certs)
-+        self.update_file(paths.CA_BUNDLE_PEM, certs)
- 
-         ipa_db = certdb.NSSDatabase(api.env.nss_dir)
- 
-diff --git a/ipaplatform/base/paths.py b/ipaplatform/base/paths.py
-index f80c9e95ab875222887e3692ab80151f84345469..804fddee60f787e161947bbe4b1914995257ceb4 100644
---- a/ipaplatform/base/paths.py
-+++ b/ipaplatform/base/paths.py
-@@ -331,6 +331,8 @@ class BasePathNamespace(object):
-     VAR_RUN_DIRSRV_DIR = "/var/run/dirsrv"
-     IPA_CCACHES = "/var/run/ipa/ccaches"
-     HTTP_CCACHE = "/var/lib/ipa/gssproxy/http.ccache"
-+    CA_BUNDLE_PEM = "/var/lib/ipa-client/pki/ca-bundle.pem"
-+    KDC_CA_BUNDLE_PEM = "/var/lib/ipa-client/pki/kdc-ca-bundle.pem"
-     IPA_RENEWAL_LOCK = "/var/run/ipa/renewal.lock"
-     SVC_LIST_FILE = "/var/run/ipa/services.list"
-     KRB5CC_SAMBA = "/var/run/samba/krb5cc_samba"
-diff --git a/ipaserver/install/cainstance.py b/ipaserver/install/cainstance.py
-index a4aa4f2069277181501ebd92f3795c452b10acd0..b8c8cc4fc4532fc2c911ec174d363f8280ce863b 100644
---- a/ipaserver/install/cainstance.py
-+++ b/ipaserver/install/cainstance.py
-@@ -794,10 +794,13 @@ class CAInstance(DogtagInstance):
-         certlist = x509.pkcs7_to_pems(data, x509.DER)
- 
-         # We have all the certificates in certlist, write them to a PEM file
--        with open(paths.IPA_CA_CRT, 'w') as ipaca_pem:
--            for cert in certlist:
--                ipaca_pem.write(cert)
--                ipaca_pem.write('\n')
-+        for path in [paths.IPA_CA_CRT,
-+                     paths.KDC_CA_BUNDLE_PEM,
-+                     paths.CA_BUNDLE_PEM]:
-+            with open(path, 'w') as ipaca_pem:
-+                for cert in certlist:
-+                    ipaca_pem.write(cert)
-+                    ipaca_pem.write('\n')
- 
-     def __request_ra_certificate(self):
-         # create a temp file storing the pwd
-diff --git a/ipaserver/install/ipa_backup.py b/ipaserver/install/ipa_backup.py
-index 40f08d7d727a8b97b5996f15d27c1e20788e1473..f8cdd56d26636678279ba5afb423c5eef10c33d0 100644
---- a/ipaserver/install/ipa_backup.py
-+++ b/ipaserver/install/ipa_backup.py
-@@ -150,6 +150,8 @@ class Backup(admintool.AdminTool):
-         paths.SSHD_CONFIG,
-         paths.SSH_CONFIG,
-         paths.KRB5_CONF,
-+        paths.KDC_CA_BUNDLE_PEM,
-+        paths.CA_BUNDLE_PEM,
-         paths.IPA_CA_CRT,
-         paths.IPA_DEFAULT_CONF,
-         paths.DS_KEYTAB,
-diff --git a/ipaserver/install/krbinstance.py b/ipaserver/install/krbinstance.py
-index 2f14ff592064d3446f73b31e615b2de88d6d786c..e52577bbaa15064946f9a3c9720aa40ffc3251aa 100644
---- a/ipaserver/install/krbinstance.py
-+++ b/ipaserver/install/krbinstance.py
-@@ -261,7 +261,9 @@ class KrbInstance(service.Service):
-                              KRB5KDC_KADM5_KEYTAB=paths.KRB5KDC_KADM5_KEYTAB,
-                              KDC_CERT=paths.KDC_CERT,
-                              KDC_KEY=paths.KDC_KEY,
--                             CACERT_PEM=paths.CACERT_PEM)
-+                             CACERT_PEM=paths.CACERT_PEM,
-+                             KDC_CA_BUNDLE_PEM=paths.KDC_CA_BUNDLE_PEM,
-+                             CA_BUNDLE_PEM=paths.CA_BUNDLE_PEM)
- 
-         # IPA server/KDC is not a subdomain of default domain
-         # Proper domain-realm mapping needs to be specified
-diff --git a/ipaserver/install/server/install.py b/ipaserver/install/server/install.py
-index 25c21db721c58388ae8fd6ab1fbc443d513a4324..c1bdce6c8459dfeabd0096d105e535ec4ee56a2a 100644
---- a/ipaserver/install/server/install.py
-+++ b/ipaserver/install/server/install.py
-@@ -796,6 +796,16 @@ def install(installer):
-         x509.write_certificate(http_ca_cert, paths.IPA_CA_CRT)
-         os.chmod(paths.IPA_CA_CRT, 0o444)
- 
-+        if not options.no_pkinit:
-+            x509.write_certificate(http_ca_cert, paths.KDC_CA_BUNDLE_PEM)
-+        else:
-+            with open(paths.KDC_CA_BUNDLE_PEM, 'w'):
-+                pass
-+        os.chmod(paths.KDC_CA_BUNDLE_PEM, 0o444)
-+
-+        x509.write_certificate(http_ca_cert, paths.CA_BUNDLE_PEM)
-+        os.chmod(paths.CA_BUNDLE_PEM, 0o444)
-+
-     # we now need to enable ssl on the ds
-     ds.enable_ssl()
- 
-diff --git a/ipaserver/install/server/replicainstall.py b/ipaserver/install/server/replicainstall.py
-index c19edceec42845f3169adc923762f700739232f2..66d7ba44645aed69b12f0e5ea14f5080492fe5ef 100644
---- a/ipaserver/install/server/replicainstall.py
-+++ b/ipaserver/install/server/replicainstall.py
-@@ -1390,6 +1390,10 @@ def install(installer):
- 
-         # Update and istall updated CA file
-         cafile = install_ca_cert(conn, api.env.basedn, api.env.realm, cafile)
-+        install_ca_cert(conn, api.env.basedn, api.env.realm, cafile,
-+                        destfile=paths.KDC_CA_BUNDLE_PEM)
-+        install_ca_cert(conn, api.env.basedn, api.env.realm, cafile,
-+                        destfile=paths.CA_BUNDLE_PEM)
- 
-         # Configure dirsrv
-         ds = install_replica_ds(config, options, ca_enabled,
-diff --git a/ipaserver/install/server/upgrade.py b/ipaserver/install/server/upgrade.py
-index c244958f4cddba0d1edded5165a295b1e1ee2b8a..648dc1f29c44f89d9fbceb7b50373d93c88b5c1a 100644
---- a/ipaserver/install/server/upgrade.py
-+++ b/ipaserver/install/server/upgrade.py
-@@ -1831,7 +1831,9 @@ def upgrade_configuration():
-                         KRB5KDC_KADM5_KEYTAB=paths.KRB5KDC_KADM5_KEYTAB,
-                         KDC_CERT=paths.KDC_CERT,
-                         KDC_KEY=paths.KDC_KEY,
--                        CACERT_PEM=paths.CACERT_PEM)
-+                        CACERT_PEM=paths.CACERT_PEM,
-+                        KDC_CA_BUNDLE_PEM=paths.KDC_CA_BUNDLE_PEM,
-+                        CA_BUNDLE_PEM=paths.CA_BUNDLE_PEM)
-     krb.add_anonymous_principal()
-     setup_pkinit(krb)
- 
--- 
-2.9.4
-
diff --git a/SOURCES/0148-install-introduce-generic-Kerberos-Augeas-lens.patch b/SOURCES/0148-install-introduce-generic-Kerberos-Augeas-lens.patch
deleted file mode 100644
index eed37f5..0000000
--- a/SOURCES/0148-install-introduce-generic-Kerberos-Augeas-lens.patch
+++ /dev/null
@@ -1,98 +0,0 @@
-From 01440531b0805d647b0a0a37e2c3ea9489d19a35 Mon Sep 17 00:00:00 2001
-From: Jan Cholasta <jcholast@redhat.com>
-Date: Thu, 18 May 2017 07:57:40 +0000
-Subject: [PATCH] install: introduce generic Kerberos Augeas lens
-
-Introduce new IPAKrb5 lens to handle krb5.conf and kdc.conf changes using
-Augeas. The stock Krb5 lens does not work on our krb5.conf and kdc.conf.
-
-https://pagure.io/freeipa/issue/6831
-
-Reviewed-By: Stanislav Laznicka <slaznick@redhat.com>
-Reviewed-By: Martin Babinsky <mbabinsk@redhat.com>
----
- freeipa.spec.in           |  1 +
- install/share/Makefile.am |  1 +
- install/share/ipakrb5.aug | 46 ++++++++++++++++++++++++++++++++++++++++++++++
- 3 files changed, 48 insertions(+)
- create mode 100644 install/share/ipakrb5.aug
-
-diff --git a/freeipa.spec.in b/freeipa.spec.in
-index 6cb37ae53b039aa1d0e0509f62a3237504be6555..790e5838e0ba45ea9bbfe3bc3a1bd40c0bd3ac1a 100644
---- a/freeipa.spec.in
-+++ b/freeipa.spec.in
-@@ -1362,6 +1362,7 @@ fi
- %dir %{_usr}/share/ipa/schema.d
- %attr(0644,root,root) %{_usr}/share/ipa/schema.d/README
- %attr(0644,root,root) %{_usr}/share/ipa/gssapi.login
-+%{_usr}/share/ipa/ipakrb5.aug
- 
- %files server-dns
- %defattr(-,root,root,-)
-diff --git a/install/share/Makefile.am b/install/share/Makefile.am
-index b27861da37153d77d693ce6e46340525bbd50173..85a061c6976dcc55b0ba2250423a344e14f2ce97 100644
---- a/install/share/Makefile.am
-+++ b/install/share/Makefile.am
-@@ -89,6 +89,7 @@ dist_app_DATA =				\
- 	gssapi.login			\
- 	ipa.conf.tmpfiles		\
- 	gssproxy.conf.template		\
-+	ipakrb5.aug			\
- 	$(NULL)
- 
- kdcproxyconfdir = $(IPA_SYSCONF_DIR)/kdcproxy
-diff --git a/install/share/ipakrb5.aug b/install/share/ipakrb5.aug
-new file mode 100644
-index 0000000000000000000000000000000000000000..4a31a84e147a680067acddac683c672ccb6f9c31
---- /dev/null
-+++ b/install/share/ipakrb5.aug
-@@ -0,0 +1,46 @@
-+module IPAKrb5 =
-+  autoload xfm
-+
-+  let dels (s:string) = Util.del_str s
-+
-+  let indent    = Util.indent
-+  let space     = Sep.space
-+  let opt_space = Sep.opt_space
-+  let sep       = Sep.space_equal
-+  let eol       = IniFile.eol
-+
-+  let kw  = Rx.word
-+  let val = Rx.space_in
-+
-+  let comment = IniFile.comment IniFile.comment_re "# "
-+  let empty   = IniFile.empty
-+
-+  let entry_generic (v:lens) = [ indent . key kw . sep . v . eol ]
-+
-+  (*
-+    FIXME: combine entry and subrecord into a single recursive lens
-+
-+    This does not work for some reason:
-+      let rec entry = entry_generic ( store ( val - "{" ) )
-+                    | entry_generic ( dels "{" . eol
-+                                    . ( entry | comment | empty )*
-+                                    . indent . dels "}" )
-+  *)
-+  let entry     = entry_generic ( store ( val - "{" ) )
-+  let subrecord = entry_generic ( dels "{" . eol
-+                                . ( entry | comment | empty )*
-+                                . indent . dels "}" )
-+
-+  let title  = IniFile.indented_title kw
-+  let record = IniFile.record title ( entry | subrecord | comment )
-+
-+  let directive = Build.key_value_line kw space ( store val )
-+
-+  let lns = IniFile.lns record ( directive | comment )
-+
-+  let filter = incl "/etc/krb5.conf"
-+             . incl "/etc/krb5.conf.d/*"
-+             . incl "/var/kerberos/krb5kdc/kdc.conf"
-+             . Util.stdexcl
-+
-+  let xfm = transform lns filter
--- 
-2.9.4
-
diff --git a/SOURCES/0149-server-install-fix-KDC-PKINIT-configuration.patch b/SOURCES/0149-server-install-fix-KDC-PKINIT-configuration.patch
deleted file mode 100644
index 5e9747e..0000000
--- a/SOURCES/0149-server-install-fix-KDC-PKINIT-configuration.patch
+++ /dev/null
@@ -1,292 +0,0 @@
-From 2558a0336e9d61b2b7e321b7dfa32426151b4bbb Mon Sep 17 00:00:00 2001
-From: Jan Cholasta <jcholast@redhat.com>
-Date: Wed, 3 May 2017 06:09:03 +0000
-Subject: [PATCH] server install: fix KDC PKINIT configuration
-
-Set `pkinit_pool` in `kdc.conf` to a CA certificate bundle of all CAs known
-to IPA.
-
-Make sure `cacert.pem` is exported in all installation code paths.
-
-Use the KDC certificate itself as a PKINIT anchor in `login_password`.
-
-https://pagure.io/freeipa/issue/6831
-
-Reviewed-By: Stanislav Laznicka <slaznick@redhat.com>
-Reviewed-By: Martin Babinsky <mbabinsk@redhat.com>
----
- install/restart_scripts/Makefile.am    |  1 +
- install/restart_scripts/renew_kdc_cert | 31 ++++++++++++++++++
- install/share/kdc.conf.template        |  2 ++
- ipaclient/install/ipa_certupdate.py    |  1 +
- ipalib/install/kinit.py                |  7 +++--
- ipaserver/install/krbinstance.py       | 27 +++++++++-------
- ipaserver/install/server/upgrade.py    | 57 ++++++++++++++++++++++++++--------
- ipaserver/rpcserver.py                 |  5 ++-
- 8 files changed, 103 insertions(+), 28 deletions(-)
- create mode 100755 install/restart_scripts/renew_kdc_cert
-
-diff --git a/install/restart_scripts/Makefile.am b/install/restart_scripts/Makefile.am
-index 04881b406b6be92b46e630f30d724918506e2aa8..240cebdee8cae7a0c7bdf88f5300583b4232fc94 100644
---- a/install/restart_scripts/Makefile.am
-+++ b/install/restart_scripts/Makefile.am
-@@ -5,6 +5,7 @@ app_DATA =                              \
- 	restart_dirsrv			\
- 	restart_httpd			\
- 	renew_ca_cert			\
-+	renew_kdc_cert			\
- 	renew_ra_cert			\
- 	stop_pkicad			\
- 	renew_ra_cert_pre		\
-diff --git a/install/restart_scripts/renew_kdc_cert b/install/restart_scripts/renew_kdc_cert
-new file mode 100755
-index 0000000000000000000000000000000000000000..9247920874fc9540ac3421dd59fd902cc195243f
---- /dev/null
-+++ b/install/restart_scripts/renew_kdc_cert
-@@ -0,0 +1,31 @@
-+#!/usr/bin/python2 -E
-+#
-+# Copyright (C) 2017  FreeIPA Contributors see COPYING for license
-+#
-+
-+import os
-+import syslog
-+import traceback
-+
-+from ipaplatform import services
-+from ipaplatform.paths import paths
-+from ipaserver.install import certs
-+
-+
-+def main():
-+    with certs.renewal_lock:
-+        os.chmod(paths.KDC_CERT, 0o644)
-+
-+        try:
-+            if services.knownservices.krb5kdc.is_running():
-+                syslog.syslog(syslog.LOG_NOTICE, 'restarting krb5kdc')
-+                services.knownservices.krb5kdc.restart()
-+        except Exception as e:
-+            syslog.syslog(
-+                syslog.LOG_ERR, "cannot restart krb5kdc: {}".format(e))
-+
-+
-+try:
-+    main()
-+except Exception:
-+    syslog.syslog(syslog.LOG_ERR, traceback.format_exc())
-diff --git a/install/share/kdc.conf.template b/install/share/kdc.conf.template
-index ec53a1ff5f7110704143074bc7a5d1dfdc705344..306351b86111eb0e883b2398678f50b821e0ad7f 100644
---- a/install/share/kdc.conf.template
-+++ b/install/share/kdc.conf.template
-@@ -13,5 +13,7 @@
-   default_principal_flags = +preauth
- ;  admin_keytab = $KRB5KDC_KADM5_KEYTAB
-   pkinit_identity = FILE:$KDC_CERT,$KDC_KEY
-+  pkinit_anchors = FILE:$KDC_CERT
-   pkinit_anchors = FILE:$CACERT_PEM
-+  pkinit_pool = FILE:$CA_BUNDLE_PEM
-  }
-diff --git a/ipaclient/install/ipa_certupdate.py b/ipaclient/install/ipa_certupdate.py
-index 7e8527e1fcb575844e8f4c90016435124b70e381..93da8422b6f503b8c44db678736d7f71f7d7567e 100644
---- a/ipaclient/install/ipa_certupdate.py
-+++ b/ipaclient/install/ipa_certupdate.py
-@@ -172,6 +172,7 @@ class CertUpdate(admintool.AdminTool):
-             certmonger.modify(request_id, ca='dogtag-ipa-ca-renew-agent')
- 
-         self.update_file(paths.CA_CRT, certs)
-+        self.update_file(paths.CACERT_PEM, certs)
- 
-     def update_file(self, filename, certs, mode=0o444):
-         certs = (c[0] for c in certs if c[2] is not False)
-diff --git a/ipalib/install/kinit.py b/ipalib/install/kinit.py
-index fb6caee4d6b5fef27b53753b21ad83572da31ac4..73471f103eabfe39580c8fbd0665157f635fa5c5 100644
---- a/ipalib/install/kinit.py
-+++ b/ipalib/install/kinit.py
-@@ -96,7 +96,7 @@ def kinit_password(principal, password, ccache_name, config=None,
-         raise RuntimeError(result.error_output)
- 
- 
--def kinit_armor(ccache_name, pkinit_anchor=None):
-+def kinit_armor(ccache_name, pkinit_anchors=None):
-     """
-     perform anonymous pkinit to obtain anonymous ticket to be used as armor
-     for FAST.
-@@ -113,8 +113,9 @@ def kinit_armor(ccache_name, pkinit_anchor=None):
-     env = {'LC_ALL': 'C'}
-     args = [paths.KINIT, '-n', '-c', ccache_name]
- 
--    if pkinit_anchor is not None:
--        args.extend(['-X', 'X509_anchors=FILE:{}'.format(pkinit_anchor)])
-+    if pkinit_anchors is not None:
-+        for pkinit_anchor in pkinit_anchors:
-+            args.extend(['-X', 'X509_anchors=FILE:{}'.format(pkinit_anchor)])
- 
-     # this workaround enables us to capture stderr and put it
-     # into the raised exception in case of unsuccessful authentication
-diff --git a/ipaserver/install/krbinstance.py b/ipaserver/install/krbinstance.py
-index e52577bbaa15064946f9a3c9720aa40ffc3251aa..1692e0b2badb23c18386346a552c83881018cf60 100644
---- a/ipaserver/install/krbinstance.py
-+++ b/ipaserver/install/krbinstance.py
-@@ -20,7 +20,6 @@
- from __future__ import absolute_import
- from __future__ import print_function
- 
--import shutil
- import os
- import pwd
- import socket
-@@ -28,6 +27,8 @@ import dbus
- 
- import dns.name
- 
-+from ipalib import x509
-+from ipalib.install import certstore
- from ipaserver.install import service
- from ipaserver.install import installutils
- from ipapython import ipaldap
-@@ -430,7 +431,8 @@ class KrbInstance(service.Service):
-                 ca=certmonger_ca,
-                 dns=self.fqdn,
-                 storage='FILE',
--                profile=KDC_PROFILE)
-+                profile=KDC_PROFILE,
-+                post_command='renew_kdc_cert')
-         except dbus.DBusException as e:
-             # if the certificate is already tracked, ignore the error
-             name = e.get_dbus_name()
-@@ -448,17 +450,23 @@ class KrbInstance(service.Service):
-         service.set_service_entry_config(
-             'KDC', self.fqdn, [PKINIT_ENABLED], self.suffix)
- 
-+    def _install_pkinit_ca_bundle(self):
-+        ca_certs = certstore.get_ca_certs(self.api.Backend.ldap2,
-+                                          self.api.env.basedn,
-+                                          self.api.env.realm,
-+                                          False)
-+        ca_certs = [c for c, _n, t, _u in ca_certs if t is not False]
-+        x509.write_certificate_list(ca_certs, paths.CACERT_PEM)
-+
-     def issue_selfsigned_pkinit_certs(self):
-         self._call_certmonger(certmonger_ca="SelfSign")
--        # for self-signed certificate, the certificate is its own CA, copy it
--        # as CA cert
--        shutil.copyfile(paths.KDC_CERT, paths.CACERT_PEM)
-+        with open(paths.CACERT_PEM, 'w'):
-+            pass
- 
-     def issue_ipa_ca_signed_pkinit_certs(self):
-         try:
-             self._call_certmonger()
--            # copy IPA CA bundle to the KDC's CA cert bundle
--            shutil.copyfile(paths.IPA_CA_CRT, paths.CACERT_PEM)
-+            self._install_pkinit_ca_bundle()
-             self.pkinit_enable()
-         except RuntimeError as e:
-             root_logger.error("PKINIT certificate request failed: %s", e)
-@@ -473,10 +481,7 @@ class KrbInstance(service.Service):
-         certs.install_key_from_p12(self.pkcs12_info[0],
-                                    self.pkcs12_info[1],
-                                    paths.KDC_KEY)
--        # copy IPA CA bundle to the KDC's CA cert bundle
--        # NOTE: this may not be the same set of CA certificates trusted by
--        # externally provided PKINIT cert.
--        shutil.copyfile(paths.IPA_CA_CRT, paths.CACERT_PEM)
-+        self._install_pkinit_ca_bundle()
-         self.pkinit_enable()
- 
-     def setup_pkinit(self):
-diff --git a/ipaserver/install/server/upgrade.py b/ipaserver/install/server/upgrade.py
-index 648dc1f29c44f89d9fbceb7b50373d93c88b5c1a..db86353165809c57d1ac27bf762393721231fefd 100644
---- a/ipaserver/install/server/upgrade.py
-+++ b/ipaserver/install/server/upgrade.py
-@@ -11,6 +11,7 @@ import pwd
- import fileinput
- import sys
- 
-+from augeas import Augeas
- import dns.exception
- 
- import six
-@@ -1527,19 +1528,49 @@ def setup_pkinit(krb):
-         else:
-             krb.issue_selfsigned_pkinit_certs()
- 
--    # reconfigure KDC just in case in order to handle potentially broken
--    # 4.5.0 -> 4.5.1 upgrade path
--    replacevars = dict()
--    replacevars['pkinit_identity'] = 'FILE:{},{}'.format(
--        paths.KDC_CERT,paths.KDC_KEY)
--    appendvars = {}
--    ipautil.backup_config_and_replace_variables(
--        krb.fstore, paths.KRB5KDC_KDC_CONF, replacevars=replacevars,
--        appendvars=appendvars)
--    tasks.restore_context(paths.KRB5KDC_KDC_CONF)
--    if krb.is_running():
--        krb.stop()
--    krb.start()
-+    aug = Augeas(flags=Augeas.NO_LOAD | Augeas.NO_MODL_AUTOLOAD,
-+                 loadpath=paths.USR_SHARE_IPA_DIR)
-+    try:
-+        aug.transform('IPAKrb5', paths.KRB5KDC_KDC_CONF)
-+        aug.load()
-+
-+        path = '/files{}/realms/{}'.format(paths.KRB5KDC_KDC_CONF, krb.realm)
-+        modified = False
-+
-+        value = 'FILE:{},{}'.format(paths.KDC_CERT, paths.KDC_KEY)
-+        expr = '{}[count(pkinit_identity)=1][pkinit_identity="{}"]'.format(
-+            path, value)
-+        if not aug.match(expr):
-+            aug.remove('{}/pkinit_identity'.format(path))
-+            aug.set('{}/pkinit_identity'.format(path), value)
-+            modified = True
-+
-+        for value in  ['FILE:{}'.format(paths.KDC_CERT),
-+                       'FILE:{}'.format(paths.CACERT_PEM)]:
-+            expr = '{}/pkinit_anchors[.="{}"]'.format(path, value)
-+            if not aug.match(expr):
-+                aug.set('{}/pkinit_anchors[last()+1]'.format(path), value)
-+                modified = True
-+
-+        value = 'FILE:{}'.format(paths.CA_BUNDLE_PEM)
-+        expr = '{}/pkinit_pool[.="{}"]'.format(path, value)
-+        if not aug.match(expr):
-+            aug.set('{}/pkinit_pool[last()+1]'.format(path), value)
-+            modified = True
-+
-+        if modified:
-+            try:
-+                aug.save()
-+            except IOError:
-+                for error_path in aug.match('/augeas//error'):
-+                    root_logger.error('augeas: %s', aug.get(error_path))
-+                raise
-+
-+            if krb.is_running():
-+                krb.stop()
-+            krb.start()
-+    finally:
-+        aug.close()
- 
- 
- def disable_httpd_system_trust(http):
-diff --git a/ipaserver/rpcserver.py b/ipaserver/rpcserver.py
-index 996a3d29884ca0180c39841f6986abf9b23ff13a..4cde2815a0fe9332d67c84b531f573ff88b1a302 100644
---- a/ipaserver/rpcserver.py
-+++ b/ipaserver/rpcserver.py
-@@ -945,7 +945,10 @@ class login_password(Backend, KerberosSession):
-         self.debug('Obtaining armor in ccache %s', armor_path)
- 
-         try:
--            kinit_armor(armor_path, pkinit_anchor=paths.CACERT_PEM)
-+            kinit_armor(
-+                armor_path,
-+                pkinit_anchors=[paths.KDC_CERT, paths.KDC_CA_BUNDLE_PEM],
-+            )
-         except RuntimeError as e:
-             self.error("Failed to obtain armor cache")
-             # We try to continue w/o armor, 2FA will be impacted
--- 
-2.9.4
-
diff --git a/SOURCES/0150-ipapython.ipautil.run-Add-option-to-set-umask-before.patch b/SOURCES/0150-ipapython.ipautil.run-Add-option-to-set-umask-before.patch
deleted file mode 100644
index bc31a32..0000000
--- a/SOURCES/0150-ipapython.ipautil.run-Add-option-to-set-umask-before.patch
+++ /dev/null
@@ -1,85 +0,0 @@
-From 68d97e2beca1ee3b398fc5f0d3ed70aa8b69e732 Mon Sep 17 00:00:00 2001
-From: David Kupka <dkupka@redhat.com>
-Date: Tue, 11 Apr 2017 17:35:30 +0200
-Subject: [PATCH] ipapython.ipautil.run: Add option to set umask before
- executing command
-
-https://pagure.io/freeipa/issue/6831
-
-Reviewed-By: Stanislav Laznicka <slaznick@redhat.com>
-Reviewed-By: Martin Babinsky <mbabinsk@redhat.com>
----
- ipapython/ipautil.py | 43 +++++++++++++++++++++++--------------------
- 1 file changed, 23 insertions(+), 20 deletions(-)
-
-diff --git a/ipapython/ipautil.py b/ipapython/ipautil.py
-index cd66328e6c9a0f69e6f83582a9d288ac239c5be3..317fc225b722ad3ce2f4b9d92822b4f19d49adb9 100644
---- a/ipapython/ipautil.py
-+++ b/ipapython/ipautil.py
-@@ -309,7 +309,7 @@ class _RunResult(collections.namedtuple('_RunResult',
- def run(args, stdin=None, raiseonerr=True, nolog=(), env=None,
-         capture_output=False, skip_output=False, cwd=None,
-         runas=None, suplementary_groups=[],
--        capture_error=False, encoding=None, redirect_output=False):
-+        capture_error=False, encoding=None, redirect_output=False, umask=None):
-     """
-     Execute an external command.
- 
-@@ -345,6 +345,7 @@ def run(args, stdin=None, raiseonerr=True, nolog=(), env=None,
-         error_output, and (if it's not bytes) stdin.
-         If None, the current encoding according to locale is used.
-     :param redirect_output: Redirect (error) output to standard (error) output.
-+    :param umask: Set file-creation mask before running the command.
- 
-     :return: An object with these attributes:
- 
-@@ -416,25 +417,27 @@ def run(args, stdin=None, raiseonerr=True, nolog=(), env=None,
-     root_logger.debug('Starting external process')
-     root_logger.debug('args=%s' % arg_string)
- 
--    preexec_fn = None
--    if runas is not None:
--        pent = pwd.getpwnam(runas)
--
--        suplementary_gids = [
--            grp.getgrnam(group).gr_gid for group in suplementary_groups
--        ]
--
--        root_logger.debug('runas=%s (UID %d, GID %s)', runas,
--            pent.pw_uid, pent.pw_gid)
--        if suplementary_groups:
--            for group, gid in zip(suplementary_groups, suplementary_gids):
--                root_logger.debug('suplementary_group=%s (GID %d)', group, gid)
--
--        preexec_fn = lambda: (
--            os.setgroups(suplementary_gids),
--            os.setregid(pent.pw_gid, pent.pw_gid),
--            os.setreuid(pent.pw_uid, pent.pw_uid),
--        )
-+    def preexec_fn():
-+        if runas is not None:
-+            pent = pwd.getpwnam(runas)
-+
-+            suplementary_gids = [
-+                grp.getgrnam(group).gr_gid for group in suplementary_groups
-+            ]
-+
-+            root_logger.debug('runas=%s (UID %d, GID %s)', runas,
-+                              pent.pw_uid, pent.pw_gid)
-+            if suplementary_groups:
-+                for group, gid in zip(suplementary_groups, suplementary_gids):
-+                    root_logger.debug('suplementary_group=%s (GID %d)',
-+                                      group, gid)
-+
-+            os.setgroups(suplementary_gids)
-+            os.setregid(pent.pw_gid, pent.pw_gid)
-+            os.setreuid(pent.pw_uid, pent.pw_uid)
-+
-+        if umask:
-+            os.umask(umask)
- 
-     try:
-         p = subprocess.Popen(args, stdin=p_in, stdout=p_out, stderr=p_err,
--- 
-2.9.4
-
diff --git a/SOURCES/0151-certs-do-not-export-keys-world-readable-in-install_k.patch b/SOURCES/0151-certs-do-not-export-keys-world-readable-in-install_k.patch
deleted file mode 100644
index b12e21d..0000000
--- a/SOURCES/0151-certs-do-not-export-keys-world-readable-in-install_k.patch
+++ /dev/null
@@ -1,33 +0,0 @@
-From 9e724963967a79fd171e79d2353ec7b655f13c47 Mon Sep 17 00:00:00 2001
-From: Jan Cholasta <jcholast@redhat.com>
-Date: Thu, 11 May 2017 07:00:42 +0000
-Subject: [PATCH] certs: do not export keys world-readable in
- install_key_from_p12
-
-Make sure the exported private key files are readable only by the owner.
-
-https://pagure.io/freeipa/issue/6831
-
-Reviewed-By: Stanislav Laznicka <slaznick@redhat.com>
-Reviewed-By: Martin Babinsky <mbabinsk@redhat.com>
----
- ipaserver/install/certs.py | 3 ++-
- 1 file changed, 2 insertions(+), 1 deletion(-)
-
-diff --git a/ipaserver/install/certs.py b/ipaserver/install/certs.py
-index 17b9ebad4a128e292e453af44ca9d63cfb1e6ea2..06a7e2143964484fa45106ca381043eb440dc5b1 100644
---- a/ipaserver/install/certs.py
-+++ b/ipaserver/install/certs.py
-@@ -73,7 +73,8 @@ def install_key_from_p12(p12_fname, p12_passwd, pem_fname):
-     pwd = ipautil.write_tmp_file(p12_passwd)
-     ipautil.run([paths.OPENSSL, "pkcs12", "-nodes", "-nocerts",
-                  "-in", p12_fname, "-out", pem_fname,
--                 "-passin", "file:" + pwd.name])
-+                 "-passin", "file:" + pwd.name],
-+                umask=0o077)
- 
- 
- def export_pem_p12(pkcs12_fname, pkcs12_pwd_fname, nickname, pem_fname):
--- 
-2.9.4
-
diff --git a/SOURCES/0152-certs-do-not-export-CA-certs-in-install_pem_from_p12.patch b/SOURCES/0152-certs-do-not-export-CA-certs-in-install_pem_from_p12.patch
deleted file mode 100644
index 90d2d3e..0000000
--- a/SOURCES/0152-certs-do-not-export-CA-certs-in-install_pem_from_p12.patch
+++ /dev/null
@@ -1,33 +0,0 @@
-From b66796bcd888e0204955913e642d8e45937843dd Mon Sep 17 00:00:00 2001
-From: Jan Cholasta <jcholast@redhat.com>
-Date: Wed, 3 May 2017 06:12:36 +0000
-Subject: [PATCH] certs: do not export CA certs in install_pem_from_p12
-
-This fixes `kdc.crt` containing the full chain rather than just the KDC
-certificate in CA-less server install.
-
-https://pagure.io/freeipa/issue/6831
-https://pagure.io/freeipa/issue/6869
-
-Reviewed-By: Stanislav Laznicka <slaznick@redhat.com>
-Reviewed-By: Martin Babinsky <mbabinsk@redhat.com>
----
- ipaserver/install/certs.py | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/ipaserver/install/certs.py b/ipaserver/install/certs.py
-index 06a7e2143964484fa45106ca381043eb440dc5b1..02c479d92511fcf4043e7d6798c85cf8256c3299 100644
---- a/ipaserver/install/certs.py
-+++ b/ipaserver/install/certs.py
-@@ -64,7 +64,7 @@ def get_cert_nickname(cert):
- 
- def install_pem_from_p12(p12_fname, p12_passwd, pem_fname):
-     pwd = ipautil.write_tmp_file(p12_passwd)
--    ipautil.run([paths.OPENSSL, "pkcs12", "-nokeys",
-+    ipautil.run([paths.OPENSSL, "pkcs12", "-nokeys", "-clcerts",
-                  "-in", p12_fname, "-out", pem_fname,
-                  "-passin", "file:" + pwd.name])
- 
--- 
-2.9.4
-
diff --git a/SOURCES/0153-server-install-fix-KDC-certificate-validation-in-CA-.patch b/SOURCES/0153-server-install-fix-KDC-certificate-validation-in-CA-.patch
deleted file mode 100644
index 039d3c5..0000000
--- a/SOURCES/0153-server-install-fix-KDC-certificate-validation-in-CA-.patch
+++ /dev/null
@@ -1,203 +0,0 @@
-From 5301e86fccfde6ab444a2c600a412487318fbd13 Mon Sep 17 00:00:00 2001
-From: Jan Cholasta <jcholast@redhat.com>
-Date: Wed, 3 May 2017 06:14:27 +0000
-Subject: [PATCH] server install: fix KDC certificate validation in CA-less
-
-Verify that the provided certificate has the extended key usage and subject
-alternative name required for KDC.
-
-https://pagure.io/freeipa/issue/6831
-https://pagure.io/freeipa/issue/6869
-
-Reviewed-By: Stanislav Laznicka <slaznick@redhat.com>
-Reviewed-By: Martin Babinsky <mbabinsk@redhat.com>
----
- ipapython/certdb.py                        | 42 ++++++++++++++++++++++++++++++
- ipaserver/install/installutils.py          | 24 +++++++++++------
- ipaserver/install/server/install.py        | 11 ++++++--
- ipaserver/install/server/replicainstall.py | 11 ++++++--
- 4 files changed, 76 insertions(+), 12 deletions(-)
-
-diff --git a/ipapython/certdb.py b/ipapython/certdb.py
-index 1ee2603653452577476cf413e6af951cd29c273e..114c58340253141706afa461ecaf87797562ca1d 100644
---- a/ipapython/certdb.py
-+++ b/ipapython/certdb.py
-@@ -24,14 +24,17 @@ import pwd
- import grp
- import re
- import tempfile
-+from tempfile import NamedTemporaryFile
- import shutil
- import base64
- from cryptography.hazmat.primitives import serialization
-+import cryptography.x509
- from nss import nss
- from nss.error import NSPRError
- 
- from ipapython.dn import DN
- from ipapython.ipa_log_manager import root_logger
-+from ipapython.kerberos import Principal
- from ipapython import ipautil
- from ipalib import x509     # pylint: disable=ipa-forbidden-import
- 
-@@ -182,6 +185,38 @@ def unparse_trust_flags(trust_flags):
-     return trust_flags
- 
- 
-+def verify_kdc_cert_validity(kdc_cert, ca_certs, realm):
-+    pem_kdc_cert = kdc_cert.public_bytes(serialization.Encoding.PEM)
-+    pem_ca_certs = '\n'.join(
-+        cert.public_bytes(serialization.Encoding.PEM) for cert in ca_certs)
-+
-+    with NamedTemporaryFile() as kdc_file, NamedTemporaryFile() as ca_file:
-+        kdc_file.write(pem_kdc_cert)
-+        kdc_file.flush()
-+        ca_file.write(pem_ca_certs)
-+        ca_file.flush()
-+
-+        try:
-+            ipautil.run(
-+                [OPENSSL, 'verify', '-CAfile', ca_file.name, kdc_file.name])
-+            eku = kdc_cert.extensions.get_extension_for_class(
-+                cryptography.x509.ExtendedKeyUsage)
-+            list(eku.value).index(
-+                cryptography.x509.ObjectIdentifier(x509.EKU_PKINIT_KDC))
-+        except (ipautil.CalledProcessError,
-+                cryptography.x509.ExtensionNotFound,
-+                ValueError):
-+            raise ValueError("invalid for a KDC")
-+
-+        principal = str(Principal(['krbtgt', realm], realm))
-+        gns = x509.process_othernames(x509.get_san_general_names(kdc_cert))
-+        for gn in gns:
-+            if isinstance(gn, x509.KRB5PrincipalName) and gn.name == principal:
-+                break
-+        else:
-+            raise ValueError("invalid for realm %s" % realm)
-+
-+
- class NSSDatabase(object):
-     """A general-purpose wrapper around a NSS cert database
- 
-@@ -707,3 +742,10 @@ class NSSDatabase(object):
-         finally:
-             del certdb, cert
-             nss.nss_shutdown()
-+
-+    def verify_kdc_cert_validity(self, nickname, realm):
-+        nicknames = self.get_trust_chain(nickname)
-+        certs = [self.get_cert(nickname) for nickname in nicknames]
-+        certs = [x509.load_certificate(cert, x509.DER) for cert in certs]
-+
-+        verify_kdc_cert_validity(certs[-1], certs[:-1], realm)
-diff --git a/ipaserver/install/installutils.py b/ipaserver/install/installutils.py
-index 5bce9894780bd920db11196b925492a7fe8f22d0..d2283af20485fd5d66bfd3cc49059d08d1802575 100644
---- a/ipaserver/install/installutils.py
-+++ b/ipaserver/install/installutils.py
-@@ -1001,7 +1001,7 @@ def handle_error(error, log_file_name=None):
- 
- 
- def load_pkcs12(cert_files, key_password, key_nickname, ca_cert_files,
--                host_name):
-+                host_name=None, realm_name=None):
-     """
-     Load and verify server certificate and private key from multiple files
- 
-@@ -1066,13 +1066,21 @@ def load_pkcs12(cert_files, key_password, key_nickname, ca_cert_files,
-                     "CA certificate %s in %s is not valid: %s" %
-                     (subject, ", ".join(cert_files), e))
- 
--        # Check server validity
--        try:
--            nssdb.verify_server_cert_validity(key_nickname, host_name)
--        except ValueError as e:
--            raise ScriptError(
--                "The server certificate in %s is not valid: %s" %
--                (", ".join(cert_files), e))
-+        if host_name is not None:
-+            try:
-+                nssdb.verify_server_cert_validity(key_nickname, host_name)
-+            except ValueError as e:
-+                raise ScriptError(
-+                    "The server certificate in %s is not valid: %s" %
-+                    (", ".join(cert_files), e))
-+
-+        if realm_name is not None:
-+            try:
-+                nssdb.verify_kdc_cert_validity(key_nickname, realm_name)
-+            except ValueError as e:
-+                raise ScriptError(
-+                    "The KDC certificate in %s is not valid: %s" %
-+                    (", ".join(cert_files), e))
- 
-         out_file = tempfile.NamedTemporaryFile()
-         out_password = ipautil.ipa_generate_password()
-diff --git a/ipaserver/install/server/install.py b/ipaserver/install/server/install.py
-index c1bdce6c8459dfeabd0096d105e535ec4ee56a2a..03380b8d0e9150224b014a1a174d7ea81ccdcf00 100644
---- a/ipaserver/install/server/install.py
-+++ b/ipaserver/install/server/install.py
-@@ -520,12 +520,12 @@ def install_check(installer):
-             if options.pkinit_pin is None:
-                 raise ScriptError(
-                     "Kerberos KDC private key unlock password required")
--        pkinit_pkcs12_file, pkinit_pin, _pkinit_ca_cert = load_pkcs12(
-+        pkinit_pkcs12_file, pkinit_pin, pkinit_ca_cert = load_pkcs12(
-             cert_files=options.pkinit_cert_files,
-             key_password=options.pkinit_pin,
-             key_nickname=options.pkinit_cert_name,
-             ca_cert_files=options.ca_cert_files,
--            host_name=host_name)
-+            realm_name=realm_name)
-         pkinit_pkcs12_info = (pkinit_pkcs12_file.name, pkinit_pin)
- 
-     if (options.http_cert_files and options.dirsrv_cert_files and
-@@ -534,6 +534,13 @@ def install_check(installer):
-             "Apache Server SSL certificate and Directory Server SSL "
-             "certificate are not signed by the same CA certificate")
- 
-+    if (options.http_cert_files and
-+            options.pkinit_cert_files and
-+            http_ca_cert != pkinit_ca_cert):
-+        raise ScriptError(
-+            "Apache Server SSL certificate and PKINIT KDC "
-+            "certificate are not signed by the same CA certificate")
-+
-     if not options.dm_password:
-         dm_password = read_dm_password()
- 
-diff --git a/ipaserver/install/server/replicainstall.py b/ipaserver/install/server/replicainstall.py
-index 66d7ba44645aed69b12f0e5ea14f5080492fe5ef..6f71f0b51812943fea3fb1c576a0174c739a070b 100644
---- a/ipaserver/install/server/replicainstall.py
-+++ b/ipaserver/install/server/replicainstall.py
-@@ -1069,12 +1069,12 @@ def promote_check(installer):
-             if options.pkinit_pin is None:
-                 raise ScriptError(
-                     "Kerberos KDC private key unlock password required")
--        pkinit_pkcs12_file, pkinit_pin, _pkinit_ca_cert = load_pkcs12(
-+        pkinit_pkcs12_file, pkinit_pin, pkinit_ca_cert = load_pkcs12(
-             cert_files=options.pkinit_cert_files,
-             key_password=options.pkinit_pin,
-             key_nickname=options.pkinit_cert_name,
-             ca_cert_files=options.ca_cert_files,
--            host_name=config.host_name)
-+            realm_name=config.realm_name)
-         pkinit_pkcs12_info = (pkinit_pkcs12_file.name, pkinit_pin)
- 
-     if (options.http_cert_files and options.dirsrv_cert_files and
-@@ -1083,6 +1083,13 @@ def promote_check(installer):
-                            "Server SSL certificate are not signed by the same"
-                            " CA certificate")
- 
-+    if (options.http_cert_files and
-+            options.pkinit_cert_files and
-+            http_ca_cert != pkinit_ca_cert):
-+        raise RuntimeError("Apache Server SSL certificate and PKINIT KDC "
-+                           "certificate are not signed by the same CA "
-+                           "certificate")
-+
-     installutils.verify_fqdn(config.host_name, options.no_host_dns)
-     installutils.verify_fqdn(config.master_host_name, options.no_host_dns)
- 
--- 
-2.9.4
-
diff --git a/SOURCES/0154-replica-install-respect-pkinit-cert-file.patch b/SOURCES/0154-replica-install-respect-pkinit-cert-file.patch
deleted file mode 100644
index c0673f4..0000000
--- a/SOURCES/0154-replica-install-respect-pkinit-cert-file.patch
+++ /dev/null
@@ -1,56 +0,0 @@
-From c1b49645c22b91aff51a29e715e29c5df7a0892a Mon Sep 17 00:00:00 2001
-From: Jan Cholasta <jcholast@redhat.com>
-Date: Thu, 11 May 2017 07:40:40 +0000
-Subject: [PATCH] replica install: respect --pkinit-cert-file
-
-When --pkinit-cert-file is used, make sure the certificate and key is
-actually passed to `KrbInstance`.
-
-https://pagure.io/freeipa/issue/6831
-
-Reviewed-By: Stanislav Laznicka <slaznick@redhat.com>
-Reviewed-By: Martin Babinsky <mbabinsk@redhat.com>
----
- ipaserver/install/server/replicainstall.py | 9 ++++++---
- 1 file changed, 6 insertions(+), 3 deletions(-)
-
-diff --git a/ipaserver/install/server/replicainstall.py b/ipaserver/install/server/replicainstall.py
-index 6f71f0b51812943fea3fb1c576a0174c739a070b..b30133ffa22d410452ae04624d49db209175bed9 100644
---- a/ipaserver/install/server/replicainstall.py
-+++ b/ipaserver/install/server/replicainstall.py
-@@ -113,12 +113,13 @@ def install_replica_ds(config, options, ca_is_configured, remote_api,
-     return ds
- 
- 
--def install_krb(config, setup_pkinit=False, promote=False):
-+def install_krb(config, setup_pkinit=False, pkcs12_info=None, promote=False):
-     krb = krbinstance.KrbInstance()
- 
-     # pkinit files
--    pkcs12_info = make_pkcs12_info(config.dir, "pkinitcert.p12",
--                                   "pkinit_pin.txt")
-+    if pkcs12_info is None:
-+        pkcs12_info = make_pkcs12_info(config.dir, "pkinitcert.p12",
-+                                       "pkinit_pin.txt")
- 
-     krb.create_replica(config.realm_name,
-                        config.master_host_name, config.host_name,
-@@ -1350,6 +1351,7 @@ def install(installer):
-     cafile = installer._ca_file
-     dirsrv_pkcs12_info = installer._dirsrv_pkcs12_info
-     http_pkcs12_info = installer._http_pkcs12_info
-+    pkinit_pkcs12_info = installer._pkinit_pkcs12_info
- 
-     remote_api = installer._remote_api
-     conn = remote_api.Backend.ldap2
-@@ -1430,6 +1432,7 @@ def install(installer):
-     krb = install_krb(
-         config,
-         setup_pkinit=not options.no_pkinit,
-+        pkcs12_info=pkinit_pkcs12_info,
-         promote=promote)
- 
-     # we now need to enable ssl on the ds
--- 
-2.9.4
-
diff --git a/SOURCES/0155-cacert-manage-support-PKINIT.patch b/SOURCES/0155-cacert-manage-support-PKINIT.patch
deleted file mode 100644
index 5c59888..0000000
--- a/SOURCES/0155-cacert-manage-support-PKINIT.patch
+++ /dev/null
@@ -1,74 +0,0 @@
-From 7aca75a7142eba58d9cb3ab5d40f3224e53e2243 Mon Sep 17 00:00:00 2001
-From: Jan Cholasta <jcholast@redhat.com>
-Date: Wed, 3 May 2017 06:17:32 +0000
-Subject: [PATCH] cacert manage: support PKINIT
-
-Allow installing 3rd party CA certificates trusted to issue PKINIT KDC
-and/or client certificates.
-
-https://pagure.io/freeipa/issue/6831
-
-Reviewed-By: Stanislav Laznicka <slaznick@redhat.com>
-Reviewed-By: Martin Babinsky <mbabinsk@redhat.com>
----
- install/tools/man/ipa-cacert-manage.1  |  2 +-
- ipaserver/install/ipa_cacert_manage.py | 21 +++++++++++++++++----
- 2 files changed, 18 insertions(+), 5 deletions(-)
-
-diff --git a/install/tools/man/ipa-cacert-manage.1 b/install/tools/man/ipa-cacert-manage.1
-index e36258d0f96aa1050fe88b05f4fe9a1a8f9a7978..03172814ffb603b656952ce5e9ad6af9c8238ab3 100644
---- a/install/tools/man/ipa-cacert-manage.1
-+++ b/install/tools/man/ipa-cacert-manage.1
-@@ -90,7 +90,7 @@ File containing the IPA CA certificate and the external CA certificate chain. Th
- Nickname for the certificate.
- .TP
- \fB\-t\fR \fITRUST_FLAGS\fR, \fB\-\-trust\-flags\fR=\fITRUST_FLAGS\fR
--Trust flags for the certificate in certutil format. Trust flags are of the form "X,Y,Z" where X is for SSL, Y is for S/MIME, and Z is for code signing. Use ",," for no explicit trust.
-+Trust flags for the certificate in certutil format. Trust flags are of the form "A,B,C" or "A,B,C,D" where A is for SSL, B is for S/MIME, C is for code signing, and D is for PKINIT. Use ",," for no explicit trust.
- .sp
- The supported trust flags are:
- .RS
-diff --git a/ipaserver/install/ipa_cacert_manage.py b/ipaserver/install/ipa_cacert_manage.py
-index d28a5966f054141819463cdb1dfef48ee1e46e92..e88e8b63ae94759ac835f3b3b31b0735d68a67b0 100644
---- a/ipaserver/install/ipa_cacert_manage.py
-+++ b/ipaserver/install/ipa_cacert_manage.py
-@@ -28,6 +28,7 @@ from ipalib.install import certmonger, certstore
- from ipapython import admintool, ipautil
- from ipapython.certdb import (EMPTY_TRUST_FLAGS,
-                               EXTERNAL_CA_TRUST_FLAGS,
-+                              TrustFlags,
-                               parse_trust_flags)
- from ipapython.dn import DN
- from ipaplatform.paths import paths
-@@ -363,12 +364,24 @@ class CACertManage(admintool.AdminTool):
-                     "http://www.freeipa.org/page/Troubleshooting for "
-                     "troubleshooting guide)" % e)
- 
--        trust_flags = options.trust_flags
--        if ((set(trust_flags) - set(',CPTcgpuw')) or
--            len(trust_flags.split(',')) != 3):
-+        trust_flags = options.trust_flags.split(',')
-+        if (set(options.trust_flags) - set(',CPTcgpuw') or
-+                len(trust_flags) not in [3, 4]):
-             raise admintool.ScriptError("Invalid trust flags")
- 
--        trust_flags = parse_trust_flags(trust_flags)
-+        extra_flags = trust_flags[3:]
-+        extra_usages = set()
-+        if extra_flags:
-+            if 'C' in extra_flags[0]:
-+                extra_usages.add(x509.EKU_PKINIT_KDC)
-+            if 'T' in extra_flags[0]:
-+                extra_usages.add(x509.EKU_PKINIT_CLIENT_AUTH)
-+
-+        trust_flags = parse_trust_flags(','.join(trust_flags[:3]))
-+        trust_flags = TrustFlags(trust_flags.has_key,
-+                                 trust_flags.trusted,
-+                                 trust_flags.ca,
-+                                 trust_flags.usages | extra_usages)
- 
-         try:
-             certstore.put_ca_cert_nss(
--- 
-2.9.4
-
diff --git a/SOURCES/0156-server-certinstall-support-PKINIT.patch b/SOURCES/0156-server-certinstall-support-PKINIT.patch
deleted file mode 100644
index 82dcce4..0000000
--- a/SOURCES/0156-server-certinstall-support-PKINIT.patch
+++ /dev/null
@@ -1,163 +0,0 @@
-From 96afd05dda2ce502994b6c9ceae819d79d96a666 Mon Sep 17 00:00:00 2001
-From: Jan Cholasta <jcholast@redhat.com>
-Date: Wed, 3 May 2017 06:18:05 +0000
-Subject: [PATCH] server certinstall: support PKINIT
-
-Allow replacing the KDC certificate.
-
-https://pagure.io/freeipa/issue/6831
-
-Reviewed-By: Stanislav Laznicka <slaznick@redhat.com>
-Reviewed-By: Martin Babinsky <mbabinsk@redhat.com>
----
- install/tools/man/ipa-server-certinstall.1  |  5 ++-
- ipaserver/install/ipa_server_certinstall.py | 70 +++++++++++++++++++++++++++--
- 2 files changed, 70 insertions(+), 5 deletions(-)
-
-diff --git a/install/tools/man/ipa-server-certinstall.1 b/install/tools/man/ipa-server-certinstall.1
-index d23bbd490e2b0454b8fb908e22f33c7a611c8874..35cd8c6c711119d7c782c6a89ac78b4894cec073 100644
---- a/install/tools/man/ipa-server-certinstall.1
-+++ b/install/tools/man/ipa-server-certinstall.1
-@@ -22,7 +22,7 @@ ipa\-server\-certinstall \- Install new SSL server certificates
- .SH "SYNOPSIS"
- ipa\-server\-certinstall [\fIOPTION\fR]... FILE...
- .SH "DESCRIPTION"
--Replace the current SSL Directory and/or Apache server certificate(s) with the certificate in the specified files. The files are accepted in PEM and DER certificate, PKCS#7 certificate chain, PKCS#8 and raw private key and PKCS#12 formats.
-+Replace the current Directory server SSL certificate, Apache server SSL certificate and/or Kerberos KDC certificate with the certificate in the specified files. The files are accepted in PEM and DER certificate, PKCS#7 certificate chain, PKCS#8 and raw private key and PKCS#12 formats.
- 
- PKCS#12 is a file format used to safely transport SSL certificates and public/private keypairs.
- 
-@@ -37,6 +37,9 @@ Install the certificate on the Directory Server
- \fB\-w\fR, \fB\-\-http\fR
- Install the certificate in the Apache Web Server
- .TP
-+\fB\-k\fR, \fB\-\-kdc\fR
-+Install the certificate in the Kerberos KDC
-+.TP
- \fB\-\-pin\fR=\fIPIN\fR
- The password to unlock the private key
- .TP
-diff --git a/ipaserver/install/ipa_server_certinstall.py b/ipaserver/install/ipa_server_certinstall.py
-index 9f2cd9573a156949ae979e7b69fbd23adaf2feb8..a14a84f188c62170c8ac11f823ebba60609e4cc7 100644
---- a/ipaserver/install/ipa_server_certinstall.py
-+++ b/ipaserver/install/ipa_server_certinstall.py
-@@ -21,12 +21,17 @@
- import os
- import os.path
- import pwd
-+import tempfile
- import optparse  # pylint: disable=deprecated-module
- 
-+from ipalib import x509
-+from ipalib.install import certmonger
- from ipaplatform.constants import constants
- from ipaplatform.paths import paths
- from ipapython import admintool
--from ipapython.certdb import get_ca_nickname, NSSDatabase
-+from ipapython.certdb import (get_ca_nickname,
-+                              NSSDatabase,
-+                              verify_kdc_cert_validity)
- from ipapython.dn import DN
- from ipalib import api, errors
- from ipaserver.install import certs, dsinstance, installutils
-@@ -35,7 +40,7 @@ from ipaserver.install import certs, dsinstance, installutils
- class ServerCertInstall(admintool.AdminTool):
-     command_name = 'ipa-server-certinstall'
- 
--    usage = "%prog <-d|-w> [options] <file> ..."
-+    usage = "%prog <-d|-w|-k> [options] <file> ..."
- 
-     description = "Install new SSL server certificates."
- 
-@@ -52,6 +57,10 @@ class ServerCertInstall(admintool.AdminTool):
-             dest="http", action="store_true", default=False,
-             help="install certificate for the http server")
-         parser.add_option(
-+            "-k", "--kdc",
-+            dest="kdc", action="store_true", default=False,
-+            help="install PKINIT certificate for the KDC")
-+        parser.add_option(
-             "--pin",
-             dest="pin", metavar="PIN", sensitive=True,
-             help="The password of the PKCS#12 file")
-@@ -73,8 +82,9 @@ class ServerCertInstall(admintool.AdminTool):
- 
-         installutils.check_server_configuration()
- 
--        if not self.options.dirsrv and not self.options.http:
--            self.option_parser.error("you must specify dirsrv and/or http")
-+        if not any((self.options.dirsrv, self.options.http, self.options.kdc)):
-+            self.option_parser.error(
-+                "you must specify dirsrv, http and/or kdc")
- 
-         if not self.args:
-             self.option_parser.error("you must provide certificate filename")
-@@ -108,6 +118,9 @@ class ServerCertInstall(admintool.AdminTool):
-         if self.options.http:
-             self.install_http_cert()
- 
-+        if self.options.kdc:
-+            self.install_kdc_cert()
-+
-         api.Backend.ldap2.disconnect()
- 
-     def install_dirsrv_cert(self):
-@@ -161,6 +174,55 @@ class ServerCertInstall(admintool.AdminTool):
-         os.chown(os.path.join(dirname, 'key3.db'), 0, pent.pw_gid)
-         os.chown(os.path.join(dirname, 'secmod.db'), 0, pent.pw_gid)
- 
-+    def install_kdc_cert(self):
-+        ca_cert_file = paths.CA_BUNDLE_PEM
-+        pkcs12_file, pin, ca_cert = installutils.load_pkcs12(
-+            cert_files=self.args,
-+            key_password=self.options.pin,
-+            key_nickname=self.options.cert_name,
-+            ca_cert_files=[ca_cert_file],
-+            realm_name=api.env.realm)
-+
-+        cdb = certs.CertDB(api.env.realm, nssdir=paths.IPA_NSSDB_DIR)
-+
-+        # Check that the ca_cert is known and trusted
-+        with tempfile.NamedTemporaryFile() as temp:
-+            certs.install_pem_from_p12(pkcs12_file.name, pin, temp.name)
-+
-+            kdc_cert = x509.load_certificate_from_file(temp.name)
-+            ca_certs = x509.load_certificate_list_from_file(ca_cert_file)
-+
-+            try:
-+                verify_kdc_cert_validity(kdc_cert, ca_certs, api.env.realm)
-+            except ValueError as e:
-+                raise admintool.ScriptError(
-+                    "Peer's certificate issuer is not trusted (%s). "
-+                    "Please run ipa-cacert-manage install and ipa-certupdate "
-+                    "to install the CA certificate." % str(e))
-+
-+        try:
-+            ca_enabled = api.Command.ca_is_enabled()['result']
-+            if ca_enabled:
-+                certmonger.stop_tracking(certfile=paths.KDC_CERT)
-+
-+            certs.install_pem_from_p12(pkcs12_file.name, pin, paths.KDC_CERT)
-+            certs.install_key_from_p12(pkcs12_file.name, pin, paths.KDC_KEY)
-+
-+            if ca_enabled:
-+                # Start tracking only if the cert was issued by IPA CA
-+                # Retrieve IPA CA
-+                ipa_ca_cert = cdb.get_cert_from_db(
-+                    get_ca_nickname(api.env.realm),
-+                    pem=False)
-+                # And compare with the CA which signed this certificate
-+                if ca_cert == ipa_ca_cert:
-+                    certmonger.start_tracking(
-+                        (paths.KDC_CERT, paths.KDC_KEY),
-+                        storage='FILE',
-+                        profile='KDCs_PKINIT_Certs')
-+        except RuntimeError as e:
-+            raise admintool.ScriptError(str(e))
-+
-     def check_chain(self, pkcs12_filename, pkcs12_pin, nssdb):
-         # create a temp nssdb
-         with NSSDatabase() as tempnssdb:
--- 
-2.9.4
-
diff --git a/SOURCES/0157-ipa-ca-install-append-CA-cert-chain-into-etc-ipa-ca..patch b/SOURCES/0157-ipa-ca-install-append-CA-cert-chain-into-etc-ipa-ca..patch
deleted file mode 100644
index d2ba8e1..0000000
--- a/SOURCES/0157-ipa-ca-install-append-CA-cert-chain-into-etc-ipa-ca..patch
+++ /dev/null
@@ -1,41 +0,0 @@
-From ceb0d5c2a4a8e8fae271e5a37ee32f58a2d36273 Mon Sep 17 00:00:00 2001
-From: Florence Blanc-Renaud <flo@redhat.com>
-Date: Tue, 16 May 2017 17:24:09 +0200
-Subject: [PATCH] ipa-ca-install: append CA cert chain into /etc/ipa/ca.crt
-
-ipa-ca-install currently overwrites /etc/ipa/ca.crt with the CA chain
-retrieved from Dogtag. It should instead append the new certs, otherwise
-the CA that signed dirsrv and httpd certificates is removed and ipa tools
-fail.
-A consequence is that ipa-kra-install fails.
-This is a regression introduced by 5ab85b36.
-
-https://pagure.io/freeipa/issue/6925
-
-Reviewed-By: Stanislav Laznicka <slaznick@redhat.com>
----
- ipaserver/install/cainstance.py | 8 ++++++++
- 1 file changed, 8 insertions(+)
-
-diff --git a/ipaserver/install/cainstance.py b/ipaserver/install/cainstance.py
-index b8c8cc4fc4532fc2c911ec174d363f8280ce863b..b0e9e8757ec3e3c0d03ed930743ef5a1253b864a 100644
---- a/ipaserver/install/cainstance.py
-+++ b/ipaserver/install/cainstance.py
-@@ -793,6 +793,14 @@ class CAInstance(DogtagInstance):
-         # Get list of PEM certificates
-         certlist = x509.pkcs7_to_pems(data, x509.DER)
- 
-+        # We need to append the certs to the existing file, so start by
-+        # reading the file
-+        if ipautil.file_exists(paths.IPA_CA_CRT):
-+            ca_certs = x509.load_certificate_list_from_file(paths.IPA_CA_CRT)
-+            ca_certs = [cert.public_bytes(serialization.Encoding.PEM)
-+                        for cert in ca_certs]
-+            certlist.extend(ca_certs)
-+
-         # We have all the certificates in certlist, write them to a PEM file
-         for path in [paths.IPA_CA_CRT,
-                      paths.KDC_CA_BUNDLE_PEM,
--- 
-2.9.4
-
diff --git a/SOURCES/0158-ca-cert-show-check-certificate_out-in-options.patch b/SOURCES/0158-ca-cert-show-check-certificate_out-in-options.patch
deleted file mode 100644
index e02a510..0000000
--- a/SOURCES/0158-ca-cert-show-check-certificate_out-in-options.patch
+++ /dev/null
@@ -1,73 +0,0 @@
-From c1258d68268bc93536ba66921d65a2550bdf475e Mon Sep 17 00:00:00 2001
-From: Stanislav Laznicka <slaznick@redhat.com>
-Date: Tue, 9 May 2017 17:45:20 +0200
-Subject: [PATCH] ca/cert-show: check certificate_out in options
-
-If --certificate-out was specified on the command line, it will appear
-among the options. If it was empty, it will be None.
-
-This check was done properly in the ca plugin. Lets' just unify how this
-is handled and improve user experience by announcing which option causes
-the failure.
-
-https://pagure.io/freeipa/issue/6885
-
-Reviewed-By: Fraser Tweedale <ftweedal@redhat.com>
-Reviewed-By: Jan Cholasta <jcholast@redhat.com>
----
- ipaclient/plugins/ca.py   |  8 ++++++--
- ipaclient/plugins/cert.py | 12 +++++++++---
- 2 files changed, 15 insertions(+), 5 deletions(-)
-
-diff --git a/ipaclient/plugins/ca.py b/ipaclient/plugins/ca.py
-index fcdf484635c7611d905f28629a380a0152c7bde1..fe9c55f4c07b4682de1ad882b6c5651dafece716 100644
---- a/ipaclient/plugins/ca.py
-+++ b/ipaclient/plugins/ca.py
-@@ -4,7 +4,7 @@
- 
- import base64
- from ipaclient.frontend import MethodOverride
--from ipalib import util, x509, Str
-+from ipalib import errors, util, x509, Str
- from ipalib.plugable import Registry
- from ipalib.text import _
- 
-@@ -26,7 +26,11 @@ class WithCertOutArgs(MethodOverride):
-         filename = None
-         if 'certificate_out' in options:
-             filename = options.pop('certificate_out')
--            util.check_writable_file(filename)
-+            try:
-+                util.check_writable_file(filename)
-+            except errors.FileError as e:
-+                raise errors.ValidationError(name='certificate-out',
-+                                             error=str(e))
- 
-         result = super(WithCertOutArgs, self).forward(*keys, **options)
-         if filename:
-diff --git a/ipaclient/plugins/cert.py b/ipaclient/plugins/cert.py
-index 9ec6970b18d0cdc3863259faee3a697f63799c3f..93cd3cef1a14925bc0795b32e97e44d69897be5c 100644
---- a/ipaclient/plugins/cert.py
-+++ b/ipaclient/plugins/cert.py
-@@ -50,9 +50,15 @@ class CertRetrieveOverride(MethodOverride):
-     )
- 
-     def forward(self, *args, **options):
--        certificate_out = options.pop('certificate_out', None)
--        if certificate_out is not None:
--            util.check_writable_file(certificate_out)
-+        if 'certificate_out' in options:
-+            certificate_out = options.pop('certificate_out')
-+            try:
-+                util.check_writable_file(certificate_out)
-+            except errors.FileError as e:
-+                raise errors.ValidationError(name='certificate-out',
-+                                             error=str(e))
-+        else:
-+            certificate_out = None
- 
-         result = super(CertRetrieveOverride, self).forward(*args, **options)
- 
--- 
-2.9.4
-
diff --git a/SOURCES/0159-Fix-rare-race-condition-with-missing-ccache-file.patch b/SOURCES/0159-Fix-rare-race-condition-with-missing-ccache-file.patch
deleted file mode 100644
index b30af31..0000000
--- a/SOURCES/0159-Fix-rare-race-condition-with-missing-ccache-file.patch
+++ /dev/null
@@ -1,47 +0,0 @@
-From 341d5790afb01e9d99c73ba336103e38e2b30091 Mon Sep 17 00:00:00 2001
-From: Simo Sorce <simo@redhat.com>
-Date: Mon, 22 May 2017 10:56:41 -0400
-Subject: [PATCH] Fix rare race condition with missing ccache file
-
-In some circumstances the ccache file may disappear while
-mod_auth_gssapi still has a valid cookie and the client is performing a
-json server call.
-
-This may lead to credentials getting sourced from the keytab.
-Make sure we enforce what GSS NAME we want to resolve so HTTP creds are
-never mistakenly sourced.
-
-Ticket: #6972
-
-Signed-off-by: Simo Sorce <simo@redhat.com>
-Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
----
- ipaserver/rpcserver.py | 11 ++++++++++-
- 1 file changed, 10 insertions(+), 1 deletion(-)
-
-diff --git a/ipaserver/rpcserver.py b/ipaserver/rpcserver.py
-index 4cde2815a0fe9332d67c84b531f573ff88b1a302..32f286148bbdf294f941116b4bdca85714a52837 100644
---- a/ipaserver/rpcserver.py
-+++ b/ipaserver/rpcserver.py
-@@ -777,8 +777,17 @@ class jsonserver_session(jsonserver, KerberosSession):
-             self.debug('no ccache, need login')
-             return self.need_login(start_response)
- 
-+        # If we have a ccache, make sure we have a GSS_NAME and use
-+        # it to resolve the ccache name (Issue: 6972 )
-+        principal = environ.get('GSS_NAME')
-+        if principal is None:
-+            self.debug('no GSS Name, need login')
-+            return self.need_login(start_response)
-+        gss_name = gssapi.Name(principal, gssapi.NameType.kerberos_principal)
-+
-         # Redirect to login if Kerberos credentials are expired
--        creds = get_credentials_if_valid(ccache_name=ccache_name)
-+        creds = get_credentials_if_valid(name=gss_name,
-+                                         ccache_name=ccache_name)
-         if not creds:
-             self.debug('ccache expired, deleting session, need login')
-             # The request is finished with the ccache, destroy it.
--- 
-2.9.4
-
diff --git a/SOURCES/0160-Remove-pkinit-anonymous-command.patch b/SOURCES/0160-Remove-pkinit-anonymous-command.patch
deleted file mode 100644
index 9bd28fe..0000000
--- a/SOURCES/0160-Remove-pkinit-anonymous-command.patch
+++ /dev/null
@@ -1,176 +0,0 @@
-From 2eb94f86872ee7ea191dc3e44fcb3d5a4683ae67 Mon Sep 17 00:00:00 2001
-From: Stanislav Laznicka <slaznick@redhat.com>
-Date: Wed, 10 May 2017 15:54:21 +0200
-Subject: [PATCH] Remove pkinit-anonymous command
-
-Ever since from v4.5, FreeIPA expects at least some kind of
-anonymous PKINIT to work. The pkinit-anonymous command was supposed
-to enable/disable anonymous pkinit by locking/unlocking the
-anonymous principal. We can't allow this for FreeIPA to work
-so we are removing the command as it was never supported anyway.
-
-https://pagure.io/freeipa/issue/6936
-
-Reviewed-By: Martin Babinsky <mbabinsk@redhat.com>
----
- API.txt                     |  6 ---
- VERSION.m4                  |  4 +-
- ipaserver/plugins/pkinit.py | 94 ++-------------------------------------------
- 3 files changed, 6 insertions(+), 98 deletions(-)
-
-diff --git a/API.txt b/API.txt
-index 7594157384511c1317738dafb41361676a2a0fd7..4e6754afe2deab5c963577f1e1363f1123a31a86 100644
---- a/API.txt
-+++ b/API.txt
-@@ -3736,11 +3736,6 @@ command: ping/1
- args: 0,1,1
- option: Str('version?')
- output: Output('summary', type=[<type 'unicode'>, <type 'NoneType'>])
--command: pkinit_anonymous/1
--args: 1,1,1
--arg: Str('action')
--option: Str('version?')
--output: Output('result')
- command: plugins/1
- args: 0,3,3
- option: Flag('all', autofill=True, cli_name='all', default=True)
-@@ -6803,7 +6798,6 @@ default: permission_remove_member/1
- default: permission_show/1
- default: ping/1
- default: pkinit/1
--default: pkinit_anonymous/1
- default: plugins/1
- default: privilege/1
- default: privilege_add/1
-diff --git a/VERSION.m4 b/VERSION.m4
-index 31e7c1d6e7054d3b4ef1d9dfaf349d2959f8330a..e10ee3cad6f5a6e023ea3cb9ec20591b7caae0bd 100644
---- a/VERSION.m4
-+++ b/VERSION.m4
-@@ -73,8 +73,8 @@ define(IPA_DATA_VERSION, 20100614120000)
- #                                                      #
- ########################################################
- define(IPA_API_VERSION_MAJOR, 2)
--define(IPA_API_VERSION_MINOR, 224)
--# Last change: Add rename option to sudorule objects
-+define(IPA_API_VERSION_MINOR, 226)
-+# Last change: Remove the pkinit-anonymous command
- 
- 
- ########################################################
-diff --git a/ipaserver/plugins/pkinit.py b/ipaserver/plugins/pkinit.py
-index b6b3f38828e86e6e677fadc9c4a638b2eee5171f..e49b31091d676865fa7f023be8edc3cdef9d6d2c 100644
---- a/ipaserver/plugins/pkinit.py
-+++ b/ipaserver/plugins/pkinit.py
-@@ -1,52 +1,14 @@
--# Authors:
--#   Simo Sorce <ssorce@redhat.com>
- #
--# Copyright (C) 2010  Red Hat
--# see file 'COPYING' for use and warranty information
-+# Copyright (C) 2017  FreeIPA Contributors see COPYING for license
- #
--# This program is free software; you can redistribute it and/or modify
--# it under the terms of the GNU General Public License as published by
--# the Free Software Foundation, either version 3 of the License, or
--# (at your option) any later version.
--#
--# This program is distributed in the hope that it will be useful,
--# but WITHOUT ANY WARRANTY; without even the implied warranty of
--# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
--# GNU General Public License for more details.
--#
--# You should have received a copy of the GNU General Public License
--# along with this program.  If not, see <http://www.gnu.org/licenses/>.
- 
--from ipalib import api, errors
--from ipalib import Str
--from ipalib import Object, Command
-+from ipalib import Object
- from ipalib import _
- from ipalib.plugable import Registry
--from ipalib.constants import ANON_USER
--from ipapython.dn import DN
--
--__doc__ = _("""
--Kerberos pkinit options
--
--Enable or disable anonymous pkinit using the principal
--WELLKNOWN/ANONYMOUS@REALM. The server must have been installed with
--pkinit support.
--
--EXAMPLES:
--
-- Enable anonymous pkinit:
--  ipa pkinit-anonymous enable
--
-- Disable anonymous pkinit:
--  ipa pkinit-anonymous disable
--
--For more information on anonymous pkinit see:
--
--http://k5wiki.kerberos.org/wiki/Projects/Anonymous_pkinit
--""")
- 
- register = Registry()
- 
-+
- @register()
- class pkinit(Object):
-     """
-@@ -54,52 +16,4 @@ class pkinit(Object):
-     """
-     object_name = _('pkinit')
- 
--    label=_('PKINIT')
--
--
--def valid_arg(ugettext, action):
--    """
--    Accepts only Enable/Disable.
--    """
--    a = action.lower()
--    if a != 'enable' and a != 'disable':
--        raise errors.ValidationError(
--            name='action',
--            error=_('Unknown command %s') % action
--        )
--
--@register()
--class pkinit_anonymous(Command):
--    __doc__ = _('Enable or Disable Anonymous PKINIT.')
--
--    princ_name = '%s@%s' % (ANON_USER, api.env.realm)
--    default_dn = DN(('krbprincipalname', princ_name), ('cn', api.env.realm), ('cn', 'kerberos'), api.env.basedn)
--
--    takes_args = (
--        Str('action', valid_arg),
--    )
--
--    def execute(self, action, **options):
--        ldap = self.api.Backend.ldap2
--        set_lock = False
--        lock = None
--
--        entry_attrs = ldap.get_entry(self.default_dn, ['nsaccountlock'])
--
--        if 'nsaccountlock' in entry_attrs:
--            lock = entry_attrs['nsaccountlock'][0].lower()
--
--        if action.lower() == 'enable':
--            if lock == 'true':
--                set_lock = True
--                lock = None
--        elif action.lower() == 'disable':
--            if lock != 'true':
--                set_lock = True
--                lock = 'TRUE'
--
--        if set_lock:
--            entry_attrs['nsaccountlock'] = lock
--            ldap.update_entry(entry_attrs)
--
--        return dict(result=True)
-+    label = _('PKINIT')
--- 
-2.9.4
-
diff --git a/SOURCES/0161-krb5-make-sure-KDC-certificate-is-readable.patch b/SOURCES/0161-krb5-make-sure-KDC-certificate-is-readable.patch
deleted file mode 100644
index 20e9312..0000000
--- a/SOURCES/0161-krb5-make-sure-KDC-certificate-is-readable.patch
+++ /dev/null
@@ -1,108 +0,0 @@
-From 131fbeff0397aa4e98bab8a22f0a1d366f223f05 Mon Sep 17 00:00:00 2001
-From: Alexander Bokovoy <abokovoy@redhat.com>
-Date: Mon, 22 May 2017 22:36:18 +0300
-Subject: [PATCH] krb5: make sure KDC certificate is readable
-
-When requesting certificate for KDC profile, make sure its public part
-is actually readable to others.
-
-Fixes https://pagure.io/freeipa/issue/6973
-
-Reviewed-By: Simo Sorce <ssorce@redhat.com>
-Reviewed-By: Jan Cholasta <jcholast@redhat.com>
----
- install/restart_scripts/renew_kdc_cert |  4 ----
- ipalib/install/certmonger.py           | 12 +++++++++---
- ipaserver/install/krbinstance.py       |  3 ++-
- 3 files changed, 11 insertions(+), 8 deletions(-)
-
-diff --git a/install/restart_scripts/renew_kdc_cert b/install/restart_scripts/renew_kdc_cert
-index 9247920874fc9540ac3421dd59fd902cc195243f..14902893f0e61e31f798fa39737a6ed9d31de111 100755
---- a/install/restart_scripts/renew_kdc_cert
-+++ b/install/restart_scripts/renew_kdc_cert
-@@ -3,19 +3,15 @@
- # Copyright (C) 2017  FreeIPA Contributors see COPYING for license
- #
- 
--import os
- import syslog
- import traceback
- 
- from ipaplatform import services
--from ipaplatform.paths import paths
- from ipaserver.install import certs
- 
- 
- def main():
-     with certs.renewal_lock:
--        os.chmod(paths.KDC_CERT, 0o644)
--
-         try:
-             if services.knownservices.krb5kdc.is_running():
-                 syslog.syslog(syslog.LOG_NOTICE, 'restarting krb5kdc')
-diff --git a/ipalib/install/certmonger.py b/ipalib/install/certmonger.py
-index 5709853ffebdbf58929b9a935e906ae67341bea8..ad031a738f4397d230ed131bde6ac7ddb7ef6fdb 100644
---- a/ipalib/install/certmonger.py
-+++ b/ipalib/install/certmonger.py
-@@ -302,7 +302,7 @@ def add_subject(request_id, subject):
- def request_and_wait_for_cert(
-         certpath, subject, principal, nickname=None, passwd_fname=None,
-         dns=None, ca='IPA', profile=None,
--        pre_command=None, post_command=None, storage='NSSDB'):
-+        pre_command=None, post_command=None, storage='NSSDB', perms=None):
-     """
-     Execute certmonger to request a server certificate.
- 
-@@ -310,7 +310,7 @@ def request_and_wait_for_cert(
-     """
-     reqId = request_cert(certpath, subject, principal, nickname,
-                          passwd_fname, dns, ca, profile,
--                         pre_command, post_command, storage)
-+                         pre_command, post_command, storage, perms)
-     state = wait_for_request(reqId, api.env.startup_timeout)
-     ca_error = get_request_value(reqId, 'ca-error')
-     if state != 'MONITORING' or ca_error:
-@@ -321,12 +321,14 @@ def request_and_wait_for_cert(
- def request_cert(
-         certpath, subject, principal, nickname=None, passwd_fname=None,
-         dns=None, ca='IPA', profile=None,
--        pre_command=None, post_command=None, storage='NSSDB'):
-+        pre_command=None, post_command=None, storage='NSSDB', perms=None):
-     """
-     Execute certmonger to request a server certificate.
- 
-     ``dns``
-         A sequence of DNS names to appear in SAN request extension.
-+    ``perms``
-+        A tuple of (cert, key) permissions in e.g., (0644,0660)
-     """
-     if storage == 'FILE':
-         certfile, keyfile = certpath
-@@ -367,6 +369,10 @@ def request_cert(
-             post_command = certmonger_cmd_template % (post_command)
-         request_parameters['cert-postsave-command'] = post_command
- 
-+    if perms:
-+        request_parameters['key-perms'] = perms[0]
-+        request_parameters['cert-perms'] = perms[1]
-+
-     result = cm.obj_if.add_request(request_parameters)
-     try:
-         if result[0]:
-diff --git a/ipaserver/install/krbinstance.py b/ipaserver/install/krbinstance.py
-index 1692e0b2badb23c18386346a552c83881018cf60..a1053d55ccaae17bef93547c036fb9d08d296f0b 100644
---- a/ipaserver/install/krbinstance.py
-+++ b/ipaserver/install/krbinstance.py
-@@ -432,7 +432,8 @@ class KrbInstance(service.Service):
-                 dns=self.fqdn,
-                 storage='FILE',
-                 profile=KDC_PROFILE,
--                post_command='renew_kdc_cert')
-+                post_command='renew_kdc_cert',
-+                perms=(0o644, 0o600))
-         except dbus.DBusException as e:
-             # if the certificate is already tracked, ignore the error
-             name = e.get_dbus_name()
--- 
-2.9.4
-
diff --git a/SOURCES/0162-Change-python-cryptography-to-python2-cryptography.patch b/SOURCES/0162-Change-python-cryptography-to-python2-cryptography.patch
deleted file mode 100644
index ac26a93..0000000
--- a/SOURCES/0162-Change-python-cryptography-to-python2-cryptography.patch
+++ /dev/null
@@ -1,41 +0,0 @@
-From a2747fd0b73818babe82a81c07a098124830b85d Mon Sep 17 00:00:00 2001
-From: Pavel Vomacka <pvomacka@redhat.com>
-Date: Fri, 19 May 2017 16:32:28 +0200
-Subject: [PATCH] Change python-cryptography to python2-cryptography
-
-Package name is python2-cryptography and even that it Provides
-python-cryptography package, it causes problems during update of IPA
-on RHEL - python2-cryptography is not updated. After changing required package
-name to python2-cryptography upgrade on RHEL works well.
-
-Fixes: https://pagure.io/freeipa/issue/6749
-Reviewed-By: Martin Babinsky <mbabinsk@redhat.com>
----
- freeipa.spec.in | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
-diff --git a/freeipa.spec.in b/freeipa.spec.in
-index 790e5838e0ba45ea9bbfe3bc3a1bd40c0bd3ac1a..2cbaa60df0db021a4a1ce10af383cd6a15e1e57c 100644
---- a/freeipa.spec.in
-+++ b/freeipa.spec.in
-@@ -164,7 +164,7 @@ BuildRequires:  python3-wheel
- %if 0%{?with_lint}
- BuildRequires:  samba-python
- # 1.4: the version where Certificate.serial changed to .serial_number
--BuildRequires:  python-cryptography >= 1.4
-+BuildRequires:  python2-cryptography >= 1.4
- BuildRequires:  python-gssapi >= 1.2.0
- BuildRequires:  pylint >= 1.6
- # workaround for https://bugzilla.redhat.com/show_bug.cgi?id=1096506
-@@ -645,7 +645,7 @@ Requires: keyutils
- Requires: pyOpenSSL
- Requires: python >= 2.7.9
- Requires: python-nss >= 0.16
--Requires: python-cryptography >= 1.4
-+Requires: python2-cryptography >= 1.4
- Requires: python-netaddr
- Requires: python-libipa_hbac
- Requires: python-qrcode-core >= 5.0.0
--- 
-2.9.4
-
diff --git a/SOURCES/0163-Allow-for-multivalued-server-attributes.patch b/SOURCES/0163-Allow-for-multivalued-server-attributes.patch
deleted file mode 100644
index f6fc013..0000000
--- a/SOURCES/0163-Allow-for-multivalued-server-attributes.patch
+++ /dev/null
@@ -1,270 +0,0 @@
-From a3801d66f5cf3f08062c3aa67a7b33d13fae56b7 Mon Sep 17 00:00:00 2001
-From: Martin Babinsky <mbabinsk@redhat.com>
-Date: Thu, 11 May 2017 15:55:53 +0200
-Subject: [PATCH] Allow for multivalued server attributes
-
-In order to achieve the task, the following changes were required:
-
-* vectorize the base class for server attributes
-* add a child class that enforces single-value attributes. It still
-  accepts/returns single-value lists in order to not break Liskov
-  substitution principle
-* Existing attributes inherit from the child class
-
-https://pagure.io/freeipa/issue/6937
-
-Reviewed-By: Jan Cholasta <jcholast@redhat.com>
-Reviewed-By: Stanislav Laznicka <slaznick@redhat.com>
----
- ipaserver/plugins/serverroles.py            |   4 +-
- ipaserver/servroles.py                      | 109 +++++++++++++++++++---------
- ipatests/test_ipaserver/test_serverroles.py |  10 +--
- 3 files changed, 79 insertions(+), 44 deletions(-)
-
-diff --git a/ipaserver/plugins/serverroles.py b/ipaserver/plugins/serverroles.py
-index e22eadd7b163469cc9fc4472640aa64d21c9d38f..e81635c3315cc3fca84450f43fb7df883aae57d9 100644
---- a/ipaserver/plugins/serverroles.py
-+++ b/ipaserver/plugins/serverroles.py
-@@ -136,9 +136,7 @@ class serverroles(Backend):
- 
-         for name, attr in assoc_attributes.items():
-             attr_value = attr.get(self.api)
--
--            if attr_value is not None:
--                result.update({name: attr_value})
-+            result.update({name: attr_value})
- 
-         return result
- 
-diff --git a/ipaserver/servroles.py b/ipaserver/servroles.py
-index cf4599995118c589a5b51236c68e13f14ac1257b..84fed1046b3b46dc9f5f8bbe6e03354725f1136c 100644
---- a/ipaserver/servroles.py
-+++ b/ipaserver/servroles.py
-@@ -277,29 +277,33 @@ class ServerAttribute(LDAPBasedProperty):
-         try:
-             entries = ldap2.get_entries(search_base, filter=search_filter)
-         except errors.EmptyResult:
--            return
-+            return []
- 
--        master_cn = entries[0].dn[1]['cn']
-+        master_cns = {e.dn[1]['cn'] for e in entries}
- 
-         associated_role_providers = set(
-             self._get_assoc_role_providers(api_instance))
- 
--        if master_cn not in associated_role_providers:
-+        if not master_cns.issubset(associated_role_providers):
-             raise errors.ValidationError(
-                 name=self.name,
-                 error=_("all masters must have %(role)s role enabled" %
-                         {'role': self.associated_role.name})
-             )
- 
--        return master_cn
-+        return sorted(master_cns)
- 
--    def _get_master_dn(self, api_instance, server):
--        return DN(('cn', server), api_instance.env.container_masters,
--                  api_instance.env.basedn)
-+    def _get_master_dns(self, api_instance, servers):
-+        return [
-+            DN(('cn', server), api_instance.env.container_masters,
-+               api_instance.env.basedn) for server in servers]
-+
-+    def _get_masters_service_entries(self, ldap, master_dns):
-+        service_dns = [
-+            DN(('cn', self.associated_service_name), master_dn) for master_dn
-+            in master_dns]
- 
--    def _get_masters_service_entry(self, ldap, master_dn):
--        service_dn = DN(('cn', self.associated_service_name), master_dn)
--        return ldap.get_entry(service_dn)
-+        return [ldap.get_entry(service_dn) for service_dn in service_dns]
- 
-     def _add_attribute_to_svc_entry(self, ldap, service_entry):
-         """
-@@ -341,65 +345,98 @@ class ServerAttribute(LDAPBasedProperty):
-             r[u'server_server'] for r in self.associated_role.status(
-                 api_instance) if r[u'status'] == ENABLED]
- 
--    def _remove(self, api_instance, master):
-+    def _remove(self, api_instance, masters):
-         """
--        remove attribute from the master
-+        remove attribute from one or more masters
- 
-         :param api_instance: API instance
--        :param master: master FQDN
-+        :param master: list or iterable containing master FQDNs
-         """
- 
-         ldap = api_instance.Backend.ldap2
- 
--        master_dn = self._get_master_dn(api_instance, master)
--        service_entry = self._get_masters_service_entry(ldap, master_dn)
--        self._remove_attribute_from_svc_entry(ldap, service_entry)
-+        master_dns = self._get_master_dns(api_instance, masters)
-+        service_entries = self._get_masters_service_entries(ldap, master_dns)
-+
-+        for service_entry in service_entries:
-+            self._remove_attribute_from_svc_entry(ldap, service_entry)
- 
--    def _add(self, api_instance, master):
-+    def _add(self, api_instance, masters):
-         """
-         add attribute to the master
-         :param api_instance: API instance
--        :param master: master FQDN
-+        :param master: iterable containing master FQDNs
- 
-         :raises: * errors.ValidationError if the associated role is not enabled
-                    on the master
-         """
- 
--        assoc_role_providers = self._get_assoc_role_providers(api_instance)
-+        assoc_role_providers = set(
-+            self._get_assoc_role_providers(api_instance))
-+        masters_set = set(masters)
-         ldap = api_instance.Backend.ldap2
- 
--        if master not in assoc_role_providers:
-+        masters_without_role = masters_set - assoc_role_providers
-+
-+        if masters_without_role:
-             raise errors.ValidationError(
--                name=master,
-+                name=', '.join(sorted(masters_without_role)),
-                 error=_("must have %(role)s role enabled" %
-                         {'role': self.associated_role.name})
-             )
- 
--        master_dn = self._get_master_dn(api_instance, master)
--        service_entry = self._get_masters_service_entry(ldap, master_dn)
--        self._add_attribute_to_svc_entry(ldap, service_entry)
-+        master_dns = self._get_master_dns(api_instance, masters)
-+        service_entries = self._get_masters_service_entries(ldap, master_dns)
-+        for service_entry in service_entries:
-+            self._add_attribute_to_svc_entry(ldap, service_entry)
- 
--    def set(self, api_instance, master):
-+    def set(self, api_instance, masters):
-         """
--        set the attribute on master
-+        set the attribute on masters
- 
-         :param api_instance: API instance
--        :param master: FQDN of the new master
-+        :param masters: an interable with FQDNs of the new masters
- 
--        the attribute is automatically unset from previous master if present
-+        the attribute is automatically unset from previous masters if present
- 
-         :raises: errors.EmptyModlist if the new masters is the same as
--                 the original on
-+                 the original ones
-         """
--        old_master = self.get(api_instance)
-+        old_masters = self.get(api_instance)
- 
--        if old_master == master:
-+        if sorted(old_masters) == sorted(masters):
-             raise errors.EmptyModlist
- 
--        self._add(api_instance, master)
-+        if old_masters:
-+            self._remove(api_instance, old_masters)
-+
-+        self._add(api_instance, masters)
-+
-+
-+class SingleValuedServerAttribute(ServerAttribute):
-+    """
-+    Base class for server attributes that are forced to be single valued
-+
-+    this means that `get` method will return a one-element list, and `set`
-+    method will accept only one-element list
-+    """
-+
-+    def set(self, api_instance, masters):
-+        if len(masters) > 1:
-+            raise errors.ValidationError(
-+                name=self.attr_name,
-+                error=_("must be enabled only on a single master"))
-+
-+        super(SingleValuedServerAttribute, self).set(api_instance, masters)
-+
-+    def get(self, api_instance):
-+        masters = super(SingleValuedServerAttribute, self).get(api_instance)
-+        num_masters = len(masters)
-+
-+        if num_masters > 1:
-+            raise errors.SingleMatchExpected(found=num_masters)
- 
--        if old_master is not None:
--            self._remove(api_instance, old_master)
-+        return masters
- 
- 
- _Service = namedtuple('Service', ['name', 'enabled'])
-@@ -574,14 +611,14 @@ role_instances = (
- )
- 
- attribute_instances = (
--    ServerAttribute(
-+    SingleValuedServerAttribute(
-         u"ca_renewal_master_server",
-         u"CA renewal master",
-         u"ca_server_server",
-         u"CA",
-         u"caRenewalMaster",
-     ),
--    ServerAttribute(
-+    SingleValuedServerAttribute(
-         u"dnssec_key_master_server",
-         u"DNSSec key master",
-         u"dns_server_server",
-diff --git a/ipatests/test_ipaserver/test_serverroles.py b/ipatests/test_ipaserver/test_serverroles.py
-index d8844df3007f076532a34d625379ab552ef45363..e671272783d8d71c2ee56074459433b98b79dd0a 100644
---- a/ipatests/test_ipaserver/test_serverroles.py
-+++ b/ipatests/test_ipaserver/test_serverroles.py
-@@ -706,7 +706,7 @@ class TestServerAttributes(object):
-         actual_attr_masters = self.config_retrieve(
-             assoc_role, mock_api)[attr_name]
- 
--        assert actual_attr_masters == fqdn
-+        assert actual_attr_masters == [fqdn]
- 
-     def test_set_attribute_on_the_same_provider_raises_emptymodlist(
-             self, mock_api, mock_masters):
-@@ -727,7 +727,7 @@ class TestServerAttributes(object):
-         non_ca_fqdn = mock_masters.get_fqdn('trust-controller-dns')
- 
-         with pytest.raises(errors.ValidationError):
--            self.config_update(mock_api, **{attr_name: non_ca_fqdn})
-+            self.config_update(mock_api, **{attr_name: [non_ca_fqdn]})
- 
-     def test_set_unknown_attribute_on_master_raises_notfound(
-             self, mock_api, mock_masters):
-@@ -735,7 +735,7 @@ class TestServerAttributes(object):
-         fqdn = mock_masters.get_fqdn('trust-controller-ca')
- 
-         with pytest.raises(errors.NotFound):
--            self.config_update(mock_api, **{attr_name: fqdn})
-+            self.config_update(mock_api, **{attr_name: [fqdn]})
- 
-     def test_set_ca_renewal_master_on_other_ca_and_back(self, mock_api,
-                                                         mock_masters):
-@@ -747,7 +747,7 @@ class TestServerAttributes(object):
-         other_ca_server = mock_masters.get_fqdn('trust-controller-ca')
- 
-         for host in (other_ca_server, original_renewal_master):
--            self.config_update(mock_api, **{attr_name: host})
-+            self.config_update(mock_api, **{attr_name: [host]})
- 
-             assert (
--                self.config_retrieve(role_name, mock_api)[attr_name] == host)
-+                self.config_retrieve(role_name, mock_api)[attr_name] == [host])
--- 
-2.9.4
-
diff --git a/SOURCES/0164-Refactor-the-role-attribute-member-reporting-code.patch b/SOURCES/0164-Refactor-the-role-attribute-member-reporting-code.patch
deleted file mode 100644
index c234e58..0000000
--- a/SOURCES/0164-Refactor-the-role-attribute-member-reporting-code.patch
+++ /dev/null
@@ -1,179 +0,0 @@
-From 352b1bc2735e8571bd4bf3a46f599834c6b0aefa Mon Sep 17 00:00:00 2001
-From: Martin Babinsky <mbabinsk@redhat.com>
-Date: Tue, 16 May 2017 17:29:39 +0200
-Subject: [PATCH] Refactor the role/attribute member reporting code
-
-The `config` object now hosts a generic method for updating the config
-entry for desired server role configuration (if not empty). The
-duplicated code in dns/trust/vaultconfig commands was replaced by a call
-to a common method.
-
-https://pagure.io/freeipa/issue/6937
-
-Reviewed-By: Jan Cholasta <jcholast@redhat.com>
-Reviewed-By: Stanislav Laznicka <slaznick@redhat.com>
----
- ipaserver/plugins/config.py | 24 ++++++++++++++++--------
- ipaserver/plugins/dns.py    | 16 ++++------------
- ipaserver/plugins/trust.py  | 22 ++++------------------
- ipaserver/plugins/vault.py  |  6 +++---
- 4 files changed, 27 insertions(+), 41 deletions(-)
-
-diff --git a/ipaserver/plugins/config.py b/ipaserver/plugins/config.py
-index b50e7a4691bd76bfaf7c332cd89b0f1bf55bac46..c88cb99b47ac746f8e18cf189708d457b535416a 100644
---- a/ipaserver/plugins/config.py
-+++ b/ipaserver/plugins/config.py
-@@ -267,15 +267,21 @@ class config(LDAPObject):
-     def get_dn(self, *keys, **kwargs):
-         return DN(('cn', 'ipaconfig'), ('cn', 'etc'), api.env.basedn)
- 
--    def show_servroles_attributes(self, entry_attrs, **options):
-+    def update_entry_with_role_config(self, role_name, entry_attrs):
-+        backend = self.api.Backend.serverroles
-+
-+        role_config = backend.config_retrieve(role_name)
-+        for key, value in role_config.items():
-+            if value:
-+                entry_attrs.update({key: value})
-+
-+
-+    def show_servroles_attributes(self, entry_attrs, *roles, **options):
-         if options.get('raw', False):
-             return
- 
--        backend = self.api.Backend.serverroles
--
--        for role in ("CA server", "IPA master", "NTP server"):
--            config = backend.config_retrieve(role)
--            entry_attrs.update(config)
-+        for role in roles:
-+            self.update_entry_with_role_config(role, entry_attrs)
- 
-     def gather_trusted_domains(self):
-         """
-@@ -525,7 +531,8 @@ class config_mod(LDAPUpdate):
-             keys, options, exc, call_func, *call_args, **call_kwargs)
- 
-     def post_callback(self, ldap, dn, entry_attrs, *keys, **options):
--        self.obj.show_servroles_attributes(entry_attrs, **options)
-+        self.obj.show_servroles_attributes(
-+            entry_attrs, "CA server", "IPA master", "NTP server", **options)
-         return dn
- 
- 
-@@ -534,5 +541,6 @@ class config_show(LDAPRetrieve):
-     __doc__ = _('Show the current configuration.')
- 
-     def post_callback(self, ldap, dn, entry_attrs, *keys, **options):
--        self.obj.show_servroles_attributes(entry_attrs, **options)
-+        self.obj.show_servroles_attributes(
-+            entry_attrs, "CA server", "IPA master", "NTP server", **options)
-         return dn
-diff --git a/ipaserver/plugins/dns.py b/ipaserver/plugins/dns.py
-index 47ac963a0ae26fcaa81e70a8143bd7d0c172d20e..f0e6c48f06313def57cdd6a4c7114357c9d8de8a 100644
---- a/ipaserver/plugins/dns.py
-+++ b/ipaserver/plugins/dns.py
-@@ -4184,16 +4184,6 @@ class dnsconfig(LDAPObject):
-         if is_config_empty:
-             result['summary'] = unicode(_('Global DNS configuration is empty'))
- 
--    def show_servroles_attributes(self, entry_attrs, **options):
--        if options.get('raw', False):
--            return
--
--        backend = self.api.Backend.serverroles
--        entry_attrs.update(
--            backend.config_retrieve("DNS server")
--        )
--
--
- @register()
- class dnsconfig_mod(LDAPUpdate):
-     __doc__ = _('Modify global DNS configuration.')
-@@ -4247,7 +4237,8 @@ class dnsconfig_mod(LDAPUpdate):
-         return result
- 
-     def post_callback(self, ldap, dn, entry_attrs, *keys, **options):
--        self.obj.show_servroles_attributes(entry_attrs, **options)
-+        self.api.Object.config.show_servroles_attributes(
-+            entry_attrs, "DNS server", **options)
-         return dn
- 
- 
-@@ -4261,7 +4252,8 @@ class dnsconfig_show(LDAPRetrieve):
-         return result
- 
-     def post_callback(self, ldap, dn, entry_attrs, *keys, **options):
--        self.obj.show_servroles_attributes(entry_attrs, **options)
-+        self.api.Object.config.show_servroles_attributes(
-+            entry_attrs, "DNS server", **options)
-         return dn
- 
- 
-diff --git a/ipaserver/plugins/trust.py b/ipaserver/plugins/trust.py
-index 0829f8c714f15c4384a89e18ba29e417405c249c..075b39dcc33a79f3e73e8e1e9e31ebbef17618fe 100644
---- a/ipaserver/plugins/trust.py
-+++ b/ipaserver/plugins/trust.py
-@@ -1278,22 +1278,6 @@ class trustconfig(LDAPObject):
- 
-         entry_attrs['ipantfallbackprimarygroup'] = [groupdn[0][0].value]
- 
--    def show_servroles(self, entry_attrs, **options):
--        if options.get('raw', False):
--            return
--
--        backend = self.api.Backend.serverroles
--
--        adtrust_agents = backend.config_retrieve(
--            "AD trust agent"
--        )
--        adtrust_controllers = backend.config_retrieve(
--            "AD trust controller"
--        )
--
--        entry_attrs.update(adtrust_agents)
--        entry_attrs.update(adtrust_controllers)
--
- 
- @register()
- class trustconfig_mod(LDAPUpdate):
-@@ -1314,7 +1298,8 @@ class trustconfig_mod(LDAPUpdate):
- 
-     def post_callback(self, ldap, dn, entry_attrs, *keys, **options):
-         self.obj._convert_groupdn(entry_attrs, options)
--        self.obj.show_servroles(entry_attrs, **options)
-+        self.api.Object.config.show_servroles_attributes(
-+            entry_attrs, "AD trust agent", "AD trust controller", **options)
-         return dn
- 
- 
-@@ -1333,7 +1318,8 @@ class trustconfig_show(LDAPRetrieve):
- 
-     def post_callback(self, ldap, dn, entry_attrs, *keys, **options):
-         self.obj._convert_groupdn(entry_attrs, options)
--        self.obj.show_servroles(entry_attrs, **options)
-+        self.api.Object.config.show_servroles_attributes(
-+            entry_attrs, "AD trust agent", "AD trust controller", **options)
- 
-         return dn
- 
-diff --git a/ipaserver/plugins/vault.py b/ipaserver/plugins/vault.py
-index d46aca821d2ec94a38dd7cc930f26038d5d80a90..d05a240c39bc1b47f1eba19cb893ab7408b35fa8 100644
---- a/ipaserver/plugins/vault.py
-+++ b/ipaserver/plugins/vault.py
-@@ -997,9 +997,9 @@ class vaultconfig_show(Retrieve):
-         with self.api.Backend.kra.get_client() as kra_client:
-             transport_cert = kra_client.system_certs.get_transport_cert()
-             config = {'transport_cert': transport_cert.binary}
--            config.update(
--                self.api.Backend.serverroles.config_retrieve("KRA server")
--            )
-+
-+        self.api.Object.config.show_servroles_attributes(
-+            config, "KRA server", **options)
- 
-         return {
-             'result': config,
--- 
-2.9.4
-
diff --git a/SOURCES/0165-Add-an-attribute-reporting-client-PKINIT-capable-ser.patch b/SOURCES/0165-Add-an-attribute-reporting-client-PKINIT-capable-ser.patch
deleted file mode 100644
index 4c9a12e..0000000
--- a/SOURCES/0165-Add-an-attribute-reporting-client-PKINIT-capable-ser.patch
+++ /dev/null
@@ -1,275 +0,0 @@
-From 48f20550f175503cb226bac47c570a2ff3e79be1 Mon Sep 17 00:00:00 2001
-From: Martin Babinsky <mbabinsk@redhat.com>
-Date: Fri, 12 May 2017 15:15:37 +0200
-Subject: [PATCH] Add an attribute reporting client PKINIT-capable servers
-
-A new multi-valued server attribute `pkinit_server` was added which
-reports IPA masters that have PKINIT configuration usable by clients.
-
-The existing tests were modified to allow for testing the new attribute.
-
-https://pagure.io/freeipa/issue/6937
-
-Reviewed-By: Jan Cholasta <jcholast@redhat.com>
-Reviewed-By: Stanislav Laznicka <slaznick@redhat.com>
----
- ipaserver/servroles.py                      |   7 ++
- ipatests/test_ipaserver/test_serverroles.py | 109 +++++++++++++---------------
- 2 files changed, 59 insertions(+), 57 deletions(-)
-
-diff --git a/ipaserver/servroles.py b/ipaserver/servroles.py
-index 84fed1046b3b46dc9f5f8bbe6e03354725f1136c..f6e79338b9187aa741fe45b9fae42476cc65f724 100644
---- a/ipaserver/servroles.py
-+++ b/ipaserver/servroles.py
-@@ -625,4 +625,11 @@ attribute_instances = (
-         u"DNSSEC",
-         u"dnssecKeyMaster",
-     ),
-+    ServerAttribute(
-+        u"pkinit_server_server",
-+        u"PKINIT enabled server",
-+        u"ipa_master_server",
-+        u"KDC",
-+        u"pkinitEnabled"
-+    )
- )
-diff --git a/ipatests/test_ipaserver/test_serverroles.py b/ipatests/test_ipaserver/test_serverroles.py
-index e671272783d8d71c2ee56074459433b98b79dd0a..b373a4d32f60e5ef48bcf07ac29162516113e8a8 100644
---- a/ipatests/test_ipaserver/test_serverroles.py
-+++ b/ipatests/test_ipaserver/test_serverroles.py
-@@ -58,7 +58,7 @@ _adtrust_agents = DN(
- 
- 
- master_data = {
--    'ca-dns-dnssec-keymaster': {
-+    'ca-dns-dnssec-keymaster-pkinit-server': {
-         'services': {
-             'CA': {
-                 'enabled': True,
-@@ -72,14 +72,19 @@ master_data = {
-             'DNSSEC': {
-                 'enabled': True,
-                 'config': ['DNSSecKeyMaster']
-+            },
-+            'KDC': {
-+                'enabled': True,
-+                'config': ['pkinitEnabled']
-             }
-         },
-         'expected_roles': {
-             'enabled': ['IPA master', 'CA server', 'DNS server']
-         },
--        'expected_attributes': {'DNS server': 'dnssec_key_master_server'}
-+        'expected_attributes': {'DNS server': 'dnssec_key_master_server',
-+                                'IPA master': 'pkinit_server_server'}
-     },
--    'ca-kra-renewal-master': {
-+    'ca-kra-renewal-master-pkinit-server': {
-         'services': {
-             'CA': {
-                 'enabled': True,
-@@ -88,11 +93,16 @@ master_data = {
-             'KRA': {
-                 'enabled': True,
-             },
-+            'KDC': {
-+                'enabled': True,
-+                'config': ['pkinitEnabled']
-+            },
-         },
-         'expected_roles': {
-             'enabled': ['IPA master', 'CA server', 'KRA server']
-         },
--        'expected_attributes': {'CA server': 'ca_renewal_master_server'}
-+        'expected_attributes': {'CA server': 'ca_renewal_master_server',
-+                                'IPA master': 'pkinit_server_server'}
-     },
-     'dns-trust-agent': {
-         'services': {
-@@ -234,7 +244,7 @@ class MockMasterTopology(object):
-                 no_members=True,
-                 raw=True)['result']}
- 
--        self.existing_attributes = self._check_test_host_attributes()
-+        self.original_dns_configs = self._remove_test_host_attrs()
- 
-     def iter_domain_data(self):
-         MasterData = namedtuple('MasterData',
-@@ -287,7 +297,6 @@ class MockMasterTopology(object):
-             pass
- 
-     def _add_svc_entries(self, master_dn, svc_desc):
--        self._add_ipamaster_services(master_dn)
-         for name in svc_desc:
-             svc_dn = self.get_service_dn(name, master_dn)
-             svc_mods = svc_desc[name]
-@@ -298,6 +307,8 @@ class MockMasterTopology(object):
-                     enabled=svc_mods['enabled'],
-                     other_config=svc_mods.get('config', None)))
- 
-+        self._add_ipamaster_services(master_dn)
-+
-     def _remove_svc_master_entries(self, master_dn):
-         try:
-             entries = self.ldap.connection.search_s(
-@@ -317,7 +328,11 @@ class MockMasterTopology(object):
-         """
-         for svc_name in self.ipamaster_services:
-             svc_dn = self.get_service_dn(svc_name, master_dn)
--            self.ldap.add_entry(str(svc_dn), _make_service_entry_mods())
-+            try:
-+                self.api.Backend.ldap2.get_entry(svc_dn)
-+            except errors.NotFound:
-+                self.ldap.add_entry(
-+                    str(svc_dn), _make_service_entry_mods())
- 
-     def _add_members(self, dn, fqdn, member_attrs):
-         _entry, attrs = self.ldap.connection.search_s(
-@@ -376,57 +391,36 @@ class MockMasterTopology(object):
-         except (ldap.NO_SUCH_OBJECT, ldap.NO_SUCH_ATTRIBUTE):
-             pass
- 
--    def _check_test_host_attributes(self):
--        existing_attributes = set()
--
--        for service, value, attr_name in (
--                ('CA', 'caRenewalMaster', 'ca renewal master'),
--                ('DNSSEC', 'DNSSecKeyMaster', 'dnssec key master')):
-+    def _remove_test_host_attrs(self):
-+        original_dns_configs = []
- 
--            svc_dn = DN(('cn', service), self.test_master_dn)
-+        for attr_name in (
-+                'caRenewalMaster', 'dnssecKeyMaster', 'pkinitEnabled'):
-             try:
--                svc_entry = self.api.Backend.ldap2.get_entry(svc_dn)
-+                svc_entry = self.api.Backend.ldap2.find_entry_by_attr(
-+                    'ipaConfigString', attr_name, 'ipaConfigObject',
-+                    base_dn=self.test_master_dn)
-             except errors.NotFound:
-                 continue
-             else:
--                config_string_val = svc_entry.get('ipaConfigString', [])
-+                original_dns_configs.append(
-+                    (svc_entry.dn, list(svc_entry.get('ipaConfigString', [])))
-+                )
-+                svc_entry[u'ipaConfigString'].remove(attr_name)
-+                self.api.Backend.ldap2.update_entry(svc_entry)
- 
--                if value in config_string_val:
--                    existing_attributes.add(attr_name)
--
--        return existing_attributes
--
--    def _remove_ca_renewal_master(self):
--        if 'ca renewal master' not in self.existing_attributes:
--            return
-+        return original_dns_configs
- 
--        ca_dn = DN(('cn', 'CA'), self.test_master_dn)
--        ca_entry = self.api.Backend.ldap2.get_entry(ca_dn)
--
--        config_string_val = ca_entry.get('ipaConfigString', [])
--        try:
--            config_string_val.remove('caRenewalMaster')
--        except KeyError:
--            return
--
--        ca_entry.update({'ipaConfigString': config_string_val})
--        self.api.Backend.ldap2.update_entry(ca_entry)
--
--    def _restore_ca_renewal_master(self):
--        if 'ca renewal master' not in self.existing_attributes:
--            return
--
--        ca_dn = DN(('cn', 'CA'), self.test_master_dn)
--        ca_entry = self.api.Backend.ldap2.get_entry(ca_dn)
--
--        config_string_val = ca_entry.get('ipaConfigString', [])
--        config_string_val.append('caRenewalMaster')
--
--        ca_entry.update({'ipaConfigString': config_string_val})
--        self.api.Backend.ldap2.update_entry(ca_entry)
-+    def _restore_test_host_attrs(self):
-+        for dn, config in self.original_dns_configs:
-+            try:
-+                svc_entry = self.api.Backend.ldap2.get_entry(dn)
-+                svc_entry['ipaConfigString'] = config
-+                self.api.Backend.ldap2.update_entry(svc_entry)
-+            except (errors.NotFound, errors.EmptyModlist):
-+                continue
- 
-     def setup_data(self):
--        self._remove_ca_renewal_master()
-         for master_data in self.iter_domain_data():
-             # create host
-             self._add_host_entry(master_data.fqdn)
-@@ -449,7 +443,6 @@ class MockMasterTopology(object):
-                     )
- 
-     def teardown_data(self):
--        self._restore_ca_renewal_master()
-         for master_data in self.iter_domain_data():
-             # first remove the master entries and service containers
-             self._remove_svc_master_entries(master_data.dn)
-@@ -466,6 +459,8 @@ class MockMasterTopology(object):
-             # finally remove host entry
-             self._del_host_entry(master_data.fqdn)
- 
-+        self._restore_test_host_attrs()
-+
- 
- @pytest.fixture(scope='module')
- def mock_api(request):
-@@ -665,14 +660,14 @@ class TestServerRoleStatusRetrieval(object):
- 
-     def test_unknown_role_status_raises_notfound(self, mock_api, mock_masters):
-         unknown_role = 'IAP maestr'
--        fqdn = mock_masters.get_fqdn('ca-dns-dnssec-keymaster')
-+        fqdn = mock_masters.get_fqdn('ca-dns-dnssec-keymaster-pkinit-server')
-         with pytest.raises(errors.NotFound):
-             mock_api.Backend.serverroles.server_role_retrieve(
-                 fqdn, unknown_role)
- 
-     def test_no_servrole_queries_all_roles_on_server(self, mock_api,
-                                                      mock_masters):
--        master_name = 'ca-dns-dnssec-keymaster'
-+        master_name = 'ca-dns-dnssec-keymaster-pkinit-server'
-         enabled_roles = master_data[master_name]['expected_roles']['enabled']
-         result = self.find_role(None, mock_api, mock_masters,
-                                 master=master_name)
-@@ -688,7 +683,7 @@ class TestServerRoleStatusRetrieval(object):
-         invalid_substr = 'fwfgbb'
- 
-         assert (not self.find_role(invalid_substr, mock_api, mock_masters,
--                                   'ca-dns-dnssec-keymaster'))
-+                                   'ca-dns-dnssec-keymaster-pkinit-server'))
- 
- 
- class TestServerAttributes(object):
-@@ -706,7 +701,7 @@ class TestServerAttributes(object):
-         actual_attr_masters = self.config_retrieve(
-             assoc_role, mock_api)[attr_name]
- 
--        assert actual_attr_masters == [fqdn]
-+        assert fqdn in actual_attr_masters
- 
-     def test_set_attribute_on_the_same_provider_raises_emptymodlist(
-             self, mock_api, mock_masters):
-@@ -744,10 +739,10 @@ class TestServerAttributes(object):
-         original_renewal_master = self.config_retrieve(
-             role_name, mock_api)[attr_name]
- 
--        other_ca_server = mock_masters.get_fqdn('trust-controller-ca')
-+        other_ca_server = [mock_masters.get_fqdn('trust-controller-ca')]
- 
-         for host in (other_ca_server, original_renewal_master):
--            self.config_update(mock_api, **{attr_name: [host]})
-+            self.config_update(mock_api, **{attr_name: host})
- 
-             assert (
--                self.config_retrieve(role_name, mock_api)[attr_name] == [host])
-+                self.config_retrieve(role_name, mock_api)[attr_name] == host)
--- 
-2.9.4
-
diff --git a/SOURCES/0166-Add-the-list-of-PKINIT-servers-as-a-virtual-attribut.patch b/SOURCES/0166-Add-the-list-of-PKINIT-servers-as-a-virtual-attribut.patch
deleted file mode 100644
index 486d553..0000000
--- a/SOURCES/0166-Add-the-list-of-PKINIT-servers-as-a-virtual-attribut.patch
+++ /dev/null
@@ -1,34 +0,0 @@
-From 095e8387572432749cf4231f7af67b9d5b597440 Mon Sep 17 00:00:00 2001
-From: Martin Babinsky <mbabinsk@redhat.com>
-Date: Fri, 12 May 2017 15:27:36 +0200
-Subject: [PATCH] Add the list of PKINIT servers as a virtual attribute to
- global config
-
-https://pagure.io/freeipa/issue/6937
-
-Reviewed-By: Jan Cholasta <jcholast@redhat.com>
-Reviewed-By: Stanislav Laznicka <slaznick@redhat.com>
----
- ipaserver/plugins/config.py | 6 ++++++
- 1 file changed, 6 insertions(+)
-
-diff --git a/ipaserver/plugins/config.py b/ipaserver/plugins/config.py
-index c88cb99b47ac746f8e18cf189708d457b535416a..df6bd466afa937be96722a570385fb5b3419830d 100644
---- a/ipaserver/plugins/config.py
-+++ b/ipaserver/plugins/config.py
-@@ -256,6 +256,12 @@ class config(LDAPObject):
-             flags={'virtual_attribute', 'no_create'}
-         ),
-         Str(
-+            'pkinit_server_server*',
-+            label=_('IPA master capable of PKINIT'),
-+            doc=_('IPA master which can process PKINIT requests'),
-+            flags={'virtual_attribute', 'no_create', 'no_update'}
-+        ),
-+        Str(
-             'ipadomainresolutionorder?',
-             cli_name='domain_resolution_order',
-             label=_('Domain resolution order'),
--- 
-2.9.4
-
diff --git a/SOURCES/0167-Add-pkinit-status-command.patch b/SOURCES/0167-Add-pkinit-status-command.patch
deleted file mode 100644
index c40c1ef..0000000
--- a/SOURCES/0167-Add-pkinit-status-command.patch
+++ /dev/null
@@ -1,201 +0,0 @@
-From 5012843d350b7a39b78e4eb7cab6cff98cae59d5 Mon Sep 17 00:00:00 2001
-From: Martin Babinsky <mbabinsk@redhat.com>
-Date: Fri, 12 May 2017 17:25:30 +0200
-Subject: [PATCH] Add `pkinit-status` command
-
-This command is a more streamlined reporting tool for PKINIT feature
-status in the FreeIPA topology. It prints out whether PKINIT is enabled
-or disabled on individual masters in a topology. If a`--server` is
-specified, it reports status for an individual server. If `--status` is
-specified, it searches for all servers that have PKINIT enabled or
-disabled.
-
-https://pagure.io/freeipa/issue/6937
-
-Reviewed-By: Jan Cholasta <jcholast@redhat.com>
-Reviewed-By: Stanislav Laznicka <slaznick@redhat.com>
----
- API.txt                     |  15 ++++++
- VERSION.m4                  |   4 +-
- ipaserver/plugins/pkinit.py | 109 +++++++++++++++++++++++++++++++++++++++++++-
- 3 files changed, 125 insertions(+), 3 deletions(-)
-
-diff --git a/API.txt b/API.txt
-index 4e6754afe2deab5c963577f1e1363f1123a31a86..6511ad8d1cb4dc9079628fc058312f31aaec624d 100644
---- a/API.txt
-+++ b/API.txt
-@@ -3736,6 +3736,20 @@ command: ping/1
- args: 0,1,1
- option: Str('version?')
- output: Output('summary', type=[<type 'unicode'>, <type 'NoneType'>])
-+command: pkinit_status/1
-+args: 1,7,4
-+arg: Str('criteria?')
-+option: Flag('all', autofill=True, cli_name='all', default=False)
-+option: Flag('raw', autofill=True, cli_name='raw', default=False)
-+option: Str('server_server?', autofill=False, cli_name='server')
-+option: Int('sizelimit?', autofill=False)
-+option: StrEnum('status?', autofill=False, cli_name='status', values=[u'enabled', u'disabled'])
-+option: Int('timelimit?', autofill=False)
-+option: Str('version?')
-+output: Output('count', type=[<type 'int'>])
-+output: ListOfEntries('result')
-+output: Output('summary', type=[<type 'unicode'>, <type 'NoneType'>])
-+output: Output('truncated', type=[<type 'bool'>])
- command: plugins/1
- args: 0,3,3
- option: Flag('all', autofill=True, cli_name='all', default=True)
-@@ -6798,6 +6812,7 @@ default: permission_remove_member/1
- default: permission_show/1
- default: ping/1
- default: pkinit/1
-+default: pkinit_status/1
- default: plugins/1
- default: privilege/1
- default: privilege_add/1
-diff --git a/VERSION.m4 b/VERSION.m4
-index e10ee3cad6f5a6e023ea3cb9ec20591b7caae0bd..8aa3ef03f352cd176579c5d5848ed9550f22105d 100644
---- a/VERSION.m4
-+++ b/VERSION.m4
-@@ -73,8 +73,8 @@ define(IPA_DATA_VERSION, 20100614120000)
- #                                                      #
- ########################################################
- define(IPA_API_VERSION_MAJOR, 2)
--define(IPA_API_VERSION_MINOR, 226)
--# Last change: Remove the pkinit-anonymous command
-+define(IPA_API_VERSION_MINOR, 227)
-+# Last change: Add `pkinit-status` command
- 
- 
- ########################################################
-diff --git a/ipaserver/plugins/pkinit.py b/ipaserver/plugins/pkinit.py
-index e49b31091d676865fa7f023be8edc3cdef9d6d2c..970f955c54bc489765d2565255e8805138a35307 100644
---- a/ipaserver/plugins/pkinit.py
-+++ b/ipaserver/plugins/pkinit.py
-@@ -3,11 +3,33 @@
- #
- 
- from ipalib import Object
--from ipalib import _
-+from ipalib import _, ngettext
-+from ipalib.crud import Search
-+from ipalib.parameters import Int, Str, StrEnum
- from ipalib.plugable import Registry
- 
- register = Registry()
- 
-+__doc__ = _("""
-+Kerberos PKINIT feature status reporting tools.
-+
-+Report IPA masters on which Kerberos PKINIT is enabled or disabled
-+
-+EXAMPLES:
-+ List PKINIT status on all masters:
-+   ipa pkinit-status
-+
-+ Check PKINIT status on `ipa.example.com`:
-+   ipa pkinit-status --server ipa.example.com
-+
-+ List all IPA masters with disabled PKINIT:
-+   ipa pkinit-status --status='disabled'
-+
-+For more info about PKINIT support see:
-+
-+https://www.freeipa.org/page/V4/Kerberos_PKINIT
-+""")
-+
- 
- @register()
- class pkinit(Object):
-@@ -17,3 +39,88 @@ class pkinit(Object):
-     object_name = _('pkinit')
- 
-     label = _('PKINIT')
-+
-+    takes_params = (
-+        Str(
-+            'server_server?',
-+            cli_name='server',
-+            label=_('Server name'),
-+            doc=_('IPA server hostname'),
-+        ),
-+        StrEnum(
-+            'status?',
-+            cli_name='status',
-+            label=_('PKINIT status'),
-+            doc=_('Whether PKINIT is enabled or disabled'),
-+            values=(u'enabled', u'disabled'),
-+            flags={'virtual_attribute', 'no_create', 'no_update'}
-+        )
-+    )
-+
-+
-+@register()
-+class pkinit_status(Search):
-+    __doc__ = _('Report PKINIT status on the IPA masters')
-+
-+    msg_summary = ngettext('%(count)s server matched',
-+                           '%(count)s servers matched', 0)
-+
-+    takes_options = Search.takes_options + (
-+        Int(
-+            'timelimit?',
-+            label=_('Time Limit'),
-+            doc=_('Time limit of search in seconds (0 is unlimited)'),
-+            flags=['no_display'],
-+            minvalue=0,
-+            autofill=False,
-+        ),
-+        Int(
-+            'sizelimit?',
-+            label=_('Size Limit'),
-+            doc=_('Maximum number of entries returned (0 is unlimited)'),
-+            flags=['no_display'],
-+            minvalue=0,
-+            autofill=False,
-+        ),
-+    )
-+
-+    def get_pkinit_status(self, server, status):
-+        backend = self.api.Backend.serverroles
-+        ipa_master_config = backend.config_retrieve("IPA master")
-+
-+        if server is not None:
-+            servers = [server]
-+        else:
-+            servers = ipa_master_config['ipa_master_server']
-+
-+        pkinit_servers = ipa_master_config['pkinit_server_server']
-+
-+        for s in servers:
-+            pkinit_status = {
-+                u'server_server': s,
-+                u'status': (
-+                    u'enabled' if s in pkinit_servers else u'disabled'
-+                )
-+            }
-+            if status is not None and pkinit_status[u'status'] != status:
-+                continue
-+
-+            yield pkinit_status
-+
-+    def execute(self, *keys, **options):
-+        if keys:
-+            return dict(
-+                result=[],
-+                count=0,
-+                truncated=False
-+            )
-+
-+        server = options.get('server_server', None)
-+        status = options.get('status', None)
-+
-+        if server is not None:
-+            self.api.Object.server_role.ensure_master_exists(server)
-+
-+        result = sorted(self.get_pkinit_status(server, status))
-+
-+        return dict(result=result, count=len(result), truncated=False)
--- 
-2.9.4
-
diff --git a/SOURCES/0168-test_serverroles-Get-rid-of-MockLDAP-and-use-ldap2-i.patch b/SOURCES/0168-test_serverroles-Get-rid-of-MockLDAP-and-use-ldap2-i.patch
deleted file mode 100644
index 5347e9a..0000000
--- a/SOURCES/0168-test_serverroles-Get-rid-of-MockLDAP-and-use-ldap2-i.patch
+++ /dev/null
@@ -1,238 +0,0 @@
-From e0f1082c7664235a298bbb1d574549917a00e8a0 Mon Sep 17 00:00:00 2001
-From: Martin Babinsky <mbabinsk@redhat.com>
-Date: Thu, 18 May 2017 16:20:13 +0200
-Subject: [PATCH] test_serverroles: Get rid of MockLDAP and use ldap2 instead
-
-The test fixture haphazardly intermixed MockLDAP and ldap2 calls in
-setup and teardown code, greatly hampering extension of the code and
-also porting efforts to Python 3. Get rid of MockLDAP and use ldap2 for
-all LDAP operations.
-
-https://pagure.io/freeipa/issue/6937
-
-Reviewed-By: Jan Cholasta <jcholast@redhat.com>
-Reviewed-By: Stanislav Laznicka <slaznick@redhat.com>
----
- ipatests/test_ipaserver/test_serverroles.py | 109 +++++++++++++---------------
- 1 file changed, 51 insertions(+), 58 deletions(-)
-
-diff --git a/ipatests/test_ipaserver/test_serverroles.py b/ipatests/test_ipaserver/test_serverroles.py
-index b373a4d32f60e5ef48bcf07ac29162516113e8a8..985c750b64f109e0a83686f31ddb3b8d4171072d 100644
---- a/ipatests/test_ipaserver/test_serverroles.py
-+++ b/ipatests/test_ipaserver/test_serverroles.py
-@@ -14,40 +14,39 @@ import pytest
- from ipaplatform.paths import paths
- from ipalib import api, create_api, errors
- from ipapython.dn import DN
--from ipatests.util import MockLDAP
- 
- 
--def _make_service_entry_mods(enabled=True, other_config=None):
-+def _make_service_entry(ldap_backend, dn, enabled=True, other_config=None):
-     mods = {
--        b'objectClass': [b'top', b'nsContainer', b'ipaConfigObject'],
-+        'objectClass': ['top', 'nsContainer', 'ipaConfigObject'],
-     }
-     if enabled:
--        mods.update({b'ipaConfigString': [b'enabledService']})
-+        mods.update({'ipaConfigString': ['enabledService']})
- 
-     if other_config is not None:
--        mods.setdefault(b'ipaConfigString', [])
--        mods[b'ipaConfigString'].extend(other_config)
-+        mods.setdefault('ipaConfigString', [])
-+        mods['ipaConfigString'].extend(other_config)
- 
--    return mods
-+    return ldap_backend.make_entry(dn, **mods)
- 
- 
--def _make_master_entry_mods(ca=False):
-+def _make_master_entry(ldap_backend, dn, ca=False):
-     mods = {
--        b'objectClass': [
--            b'top',
--            b'nsContainer',
--            b'ipaReplTopoManagedServer',
--            b'ipaSupportedDomainLevelConfig',
--            b'ipaConfigObject',
-+        'objectClass': [
-+            'top',
-+            'nsContainer',
-+            'ipaReplTopoManagedServer',
-+            'ipaSupportedDomainLevelConfig',
-+            'ipaConfigObject',
-         ],
--        b'ipaMaxDomainLevel': [b'1'],
--        b'ipaMinDomainLevel': [b'0'],
--        b'ipaReplTopoManagedsuffix': [str(api.env.basedn)]
-+        'ipaMaxDomainLevel': ['1'],
-+        'ipaMinDomainLevel': ['0'],
-+        'ipaReplTopoManagedsuffix': [str(api.env.basedn)]
-     }
-     if ca:
--        mods[b'ipaReplTopoManagedsuffix'].append(b'o=ipaca')
-+        mods['ipaReplTopoManagedsuffix'].append('o=ipaca')
- 
--    return mods
-+    return ldap_backend.make_entry(dn, **mods)
- 
- _adtrust_agents = DN(
-     ('cn', 'adtrust agents'),
-@@ -235,7 +234,7 @@ class MockMasterTopology(object):
-             ('cn', self.api.env.host), self.api.env.container_masters,
-             self.api.env.basedn)
- 
--        self.ldap = MockLDAP()
-+        self.ldap = self.api.Backend.ldap2
- 
-         self.existing_masters = {
-             m['cn'][0] for m in self.api.Command.server_find(
-@@ -302,8 +301,9 @@ class MockMasterTopology(object):
-             svc_mods = svc_desc[name]
- 
-             self.ldap.add_entry(
--                str(svc_dn),
--                _make_service_entry_mods(
-+                _make_service_entry(
-+                    self.ldap,
-+                    svc_dn,
-                     enabled=svc_mods['enabled'],
-                     other_config=svc_mods.get('config', None)))
- 
-@@ -311,16 +311,16 @@ class MockMasterTopology(object):
- 
-     def _remove_svc_master_entries(self, master_dn):
-         try:
--            entries = self.ldap.connection.search_s(
--                str(master_dn), ldap.SCOPE_SUBTREE
-+            entries = self.ldap.get_entries(
-+                master_dn, ldap.SCOPE_SUBTREE
-             )
--        except ldap.NO_SUCH_OBJECT:
-+        except errors.NotFound:
-             return
- 
-         if entries:
--            entries.sort(key=lambda x: len(x[0]), reverse=True)
--            for entry_dn, _attrs in entries:
--                self.ldap.del_entry(str(entry_dn))
-+            entries.sort(key=lambda x: len(x.dn), reverse=True)
-+            for entry in entries:
-+                self.ldap.delete_entry(entry)
- 
-     def _add_ipamaster_services(self, master_dn):
-         """
-@@ -329,19 +329,14 @@ class MockMasterTopology(object):
-         for svc_name in self.ipamaster_services:
-             svc_dn = self.get_service_dn(svc_name, master_dn)
-             try:
--                self.api.Backend.ldap2.get_entry(svc_dn)
-+                self.ldap.get_entry(svc_dn)
-             except errors.NotFound:
--                self.ldap.add_entry(
--                    str(svc_dn), _make_service_entry_mods())
-+                self.ldap.add_entry(_make_service_entry(self.ldap, svc_dn))
- 
-     def _add_members(self, dn, fqdn, member_attrs):
--        _entry, attrs = self.ldap.connection.search_s(
--            str(dn), ldap.SCOPE_SUBTREE)[0]
--        mods = []
--        value = attrs.get('member', [])
--        mod_op = ldap.MOD_REPLACE
--        if not value:
--            mod_op = ldap.MOD_ADD
-+        entry_attrs = self.ldap.get_entry(dn)
-+
-+        value = entry_attrs.get('member', [])
- 
-         for a in member_attrs:
- 
-@@ -352,20 +347,18 @@ class MockMasterTopology(object):
-                 result = self._add_service_entry(a, fqdn)['result']
-                 value.append(str(result['dn']))
- 
--        mods.append(
--            (mod_op, 'member', value)
--        )
--
--        self.ldap.connection.modify_s(str(dn), mods)
-+        entry_attrs['member'] = value
-+        self.ldap.update_entry(entry_attrs)
- 
-     def _remove_members(self, dn, fqdn, member_attrs):
--        _entry, attrs = self.ldap.connection.search_s(
--            str(dn), ldap.SCOPE_SUBTREE)[0]
--        mods = []
-+        entry_attrs = self.ldap.get_entry(dn)
-+
-+        value = set(entry_attrs.get('member', []))
-+
-+        if not value:
-+            return
-+
-         for a in member_attrs:
--            value = set(attrs.get('member', []))
--            if not value:
--                continue
- 
-             if a == 'host':
-                 try:
-@@ -382,13 +375,11 @@ class MockMasterTopology(object):
-                     pass
-                 self._del_service_entry(a, fqdn)
- 
--        mods.append(
--            (ldap.MOD_REPLACE, 'member', list(value))
--        )
-+        entry_attrs['member'] = list(value)
- 
-         try:
--            self.ldap.connection.modify_s(str(dn), mods)
--        except (ldap.NO_SUCH_OBJECT, ldap.NO_SUCH_ATTRIBUTE):
-+            self.ldap.update_entry(entry_attrs)
-+        except (errors.NotFound, errors.EmptyModlist):
-             pass
- 
-     def _remove_test_host_attrs(self):
-@@ -397,7 +388,7 @@ class MockMasterTopology(object):
-         for attr_name in (
-                 'caRenewalMaster', 'dnssecKeyMaster', 'pkinitEnabled'):
-             try:
--                svc_entry = self.api.Backend.ldap2.find_entry_by_attr(
-+                svc_entry = self.ldap.find_entry_by_attr(
-                     'ipaConfigString', attr_name, 'ipaConfigObject',
-                     base_dn=self.test_master_dn)
-             except errors.NotFound:
-@@ -407,7 +398,7 @@ class MockMasterTopology(object):
-                     (svc_entry.dn, list(svc_entry.get('ipaConfigString', [])))
-                 )
-                 svc_entry[u'ipaConfigString'].remove(attr_name)
--                self.api.Backend.ldap2.update_entry(svc_entry)
-+                self.ldap.update_entry(svc_entry)
- 
-         return original_dns_configs
- 
-@@ -416,7 +407,7 @@ class MockMasterTopology(object):
-             try:
-                 svc_entry = self.api.Backend.ldap2.get_entry(dn)
-                 svc_entry['ipaConfigString'] = config
--                self.api.Backend.ldap2.update_entry(svc_entry)
-+                self.ldap.update_entry(svc_entry)
-             except (errors.NotFound, errors.EmptyModlist):
-                 continue
- 
-@@ -427,7 +418,9 @@ class MockMasterTopology(object):
- 
-             # create master
-             self.ldap.add_entry(
--                str(master_data.dn), _make_master_entry_mods(
-+                _make_master_entry(
-+                    self.ldap,
-+                    master_data.dn,
-                     ca='CA' in master_data.services))
- 
-             # now add service entries
--- 
-2.9.4
-
diff --git a/SOURCES/0169-only-stop-disable-simple-service-if-it-is-installed.patch b/SOURCES/0169-only-stop-disable-simple-service-if-it-is-installed.patch
deleted file mode 100644
index 46467f9..0000000
--- a/SOURCES/0169-only-stop-disable-simple-service-if-it-is-installed.patch
+++ /dev/null
@@ -1,54 +0,0 @@
-From 2a20fbe381dd8a740e05833dd8d2b5440ce84812 Mon Sep 17 00:00:00 2001
-From: Martin Babinsky <mbabinsk@redhat.com>
-Date: Tue, 23 May 2017 16:35:01 +0200
-Subject: [PATCH] only stop/disable simple service if it is installed
-
-The SimpleServiceInstance uninstaller assument that the service to
-uninstall was always present on the system. This may not be valid in
-some cases (e.g. containerized deployments) and thus we need to change
-the service state only when we know that the unit file exists.
-
-https://pagure.io/freeipa/issue/6977
-
-Reviewed-By: Martin Basti <mbasti@redhat.com>
----
- ipaserver/install/service.py | 19 +++++++++++--------
- 1 file changed, 11 insertions(+), 8 deletions(-)
-
-diff --git a/ipaserver/install/service.py b/ipaserver/install/service.py
-index 1aa49ed25b25366afd2bb17073b4b214c231d54b..0523e914aa7debf6aaa82ddcce9b7b26c1833cd3 100644
---- a/ipaserver/install/service.py
-+++ b/ipaserver/install/service.py
-@@ -674,18 +674,21 @@ class SimpleServiceInstance(Service):
-         else:
-             self.ldap_enable(self.gensvc_name, self.fqdn, None, self.suffix)
- 
-+    def is_installed(self):
-+        return self.service.is_installed()
-+
-     def uninstall(self):
-         if self.is_configured():
-             self.print_msg("Unconfiguring %s" % self.service_name)
- 
--        self.stop()
--        self.disable()
--
-         running = self.restore_state("running")
-         enabled = self.restore_state("enabled")
- 
--        # restore the original state of service
--        if running:
--            self.start()
--        if enabled:
--            self.enable()
-+        if self.is_installed():
-+            self.stop()
-+            self.disable()
-+
-+            if running:
-+                self.start()
-+            if enabled:
-+                self.enable()
--- 
-2.9.4
-
diff --git a/SOURCES/0170-Fix-index-definition-for-ipaAnchorUUID.patch b/SOURCES/0170-Fix-index-definition-for-ipaAnchorUUID.patch
deleted file mode 100644
index 33d73e3..0000000
--- a/SOURCES/0170-Fix-index-definition-for-ipaAnchorUUID.patch
+++ /dev/null
@@ -1,33 +0,0 @@
-From de0ed1b49c84edebb65f31ff18e0b4bb4e0d794c Mon Sep 17 00:00:00 2001
-From: Alexander Bokovoy <abokovoy@redhat.com>
-Date: Wed, 24 May 2017 18:00:14 +0300
-Subject: [PATCH] Fix index definition for ipaAnchorUUID
-
-Fixes https://pagure.io/freeipa/issue/6975
-
-Reviewed-By: Martin Basti <mbasti@redhat.com>
----
- install/updates/20-idoverride_index.update | 5 ++++-
- 1 file changed, 4 insertions(+), 1 deletion(-)
-
-diff --git a/install/updates/20-idoverride_index.update b/install/updates/20-idoverride_index.update
-index bfc9c6e235fb7a4300fd755e53fc2154e01573a2..63d622f1f0fb7d6e49df7fde65a33bc21ab0c4a0 100644
---- a/install/updates/20-idoverride_index.update
-+++ b/install/updates/20-idoverride_index.update
-@@ -11,9 +11,12 @@ only: nsIndexType: eq
- only: nsIndexType: pres
- 
- dn: cn=ipaAnchorUUID,cn=index,cn=userRoot,cn=ldbm database,cn=plugins,cn=config
--default:cn: ipaOriginalUid
-+default:cn: ipaAnchorUUID
- default:ObjectClass: top
- default:ObjectClass: nsIndex
- default:nsSystemIndex: false
- only: nsIndexType: eq
- only: nsIndexType: pres
-+
-+dn: cn=ipaAnchorUUID,cn=index,cn=userRoot,cn=ldbm database,cn=plugins,cn=config
-+remove:cn: ipaOriginalUid
--- 
-2.9.4
-
diff --git a/SOURCES/0171-httpinstance-wait-until-the-service-entry-is-replica.patch b/SOURCES/0171-httpinstance-wait-until-the-service-entry-is-replica.patch
deleted file mode 100644
index 068834e..0000000
--- a/SOURCES/0171-httpinstance-wait-until-the-service-entry-is-replica.patch
+++ /dev/null
@@ -1,126 +0,0 @@
-From 07469b2cc7bd1478836a1c755b301dbf9234d61a Mon Sep 17 00:00:00 2001
-From: Jan Cholasta <jcholast@redhat.com>
-Date: Mon, 22 May 2017 08:15:14 +0000
-Subject: [PATCH] httpinstance: wait until the service entry is replicated
-
-Wait until the local HTTP service entry is replicated to the remote master
-before requesting the server certificate.
-
-This prevents a replication conflict between the service entry added
-locally and service entry added remotely when requesting the certificate.
-
-https://pagure.io/freeipa/issue/6867
-
-Reviewed-By: Martin Babinsky <mbabinsk@redhat.com>
-Reviewed-By: Martin Basti <mbasti@redhat.com>
----
- ipaserver/install/httpinstance.py          | 29 +++++++++++++++++++++++++++--
- ipaserver/install/server/install.py        |  4 ++--
- ipaserver/install/server/replicainstall.py |  5 +++--
- 3 files changed, 32 insertions(+), 6 deletions(-)
-
-diff --git a/ipaserver/install/httpinstance.py b/ipaserver/install/httpinstance.py
-index c76a1a4e484c5777ced92761916c1c586e8b2d5d..12fdddccc26b0c1132bcdca7fe2249a85997892e 100644
---- a/ipaserver/install/httpinstance.py
-+++ b/ipaserver/install/httpinstance.py
-@@ -32,9 +32,11 @@ import six
- from augeas import Augeas
- 
- from ipalib.install import certmonger
-+from ipapython import ipaldap
- from ipapython.certdb import (IPA_CA_TRUST_FLAGS,
-                               EXTERNAL_CA_TRUST_FLAGS,
-                               TRUSTED_PEER_TRUST_FLAGS)
-+from ipaserver.install import replication
- from ipaserver.install import service
- from ipaserver.install import certs
- from ipaserver.install import installutils
-@@ -127,12 +129,15 @@ class HTTPInstance(service.Service):
- 
-     subject_base = ipautil.dn_attribute_property('_subject_base')
- 
--    def create_instance(self, realm, fqdn, domain_name, pkcs12_info=None,
-+    def create_instance(self, realm, fqdn, domain_name, dm_password=None,
-+                        pkcs12_info=None,
-                         subject_base=None, auto_redirect=True, ca_file=None,
--                        ca_is_configured=None, promote=False):
-+                        ca_is_configured=None, promote=False,
-+                        master_fqdn=None):
-         self.fqdn = fqdn
-         self.realm = realm
-         self.domain = domain_name
-+        self.dm_password = dm_password
-         self.suffix = ipautil.realm_to_suffix(self.realm)
-         self.pkcs12_info = pkcs12_info
-         self.dercert = None
-@@ -148,6 +153,7 @@ class HTTPInstance(service.Service):
-         if ca_is_configured is not None:
-             self.ca_is_configured = ca_is_configured
-         self.promote = promote
-+        self.master_fqdn = master_fqdn
- 
-         self.step("stopping httpd", self.__stop)
-         self.step("setting mod_nss port to 443", self.__set_mod_nss_port)
-@@ -577,3 +583,22 @@ class HTTPInstance(service.Service):
-         db = certs.CertDB(self.realm, nssdir=paths.HTTPD_ALIAS_DIR)
-         db.track_server_cert(self.cert_nickname, self.principal,
-                              db.passwd_fname, 'restart_httpd')
-+
-+    def request_service_keytab(self):
-+        super(HTTPInstance, self).request_service_keytab()
-+
-+        if self.master_fqdn is not None:
-+            service_dn = DN(('krbprincipalname', self.principal),
-+                            api.env.container_service,
-+                            self.suffix)
-+
-+            ldap_uri = ipaldap.get_ldap_uri(self.master_fqdn)
-+            with ipaldap.LDAPClient(ldap_uri,
-+                                    start_tls=not self.promote,
-+                                    cacert=paths.IPA_CA_CRT) as remote_ldap:
-+                if self.promote:
-+                    remote_ldap.gssapi_bind()
-+                else:
-+                    remote_ldap.simple_bind(ipaldap.DIRMAN_DN,
-+                                            self.dm_password)
-+                replication.wait_for_entry(remote_ldap, service_dn, timeout=60)
-diff --git a/ipaserver/install/server/install.py b/ipaserver/install/server/install.py
-index 03380b8d0e9150224b014a1a174d7ea81ccdcf00..9dcf903f4582740f007c049fae3ec247ddf52aef 100644
---- a/ipaserver/install/server/install.py
-+++ b/ipaserver/install/server/install.py
-@@ -830,13 +830,13 @@ def install(installer):
-     http = httpinstance.HTTPInstance(fstore)
-     if options.http_cert_files:
-         http.create_instance(
--            realm_name, host_name, domain_name,
-+            realm_name, host_name, domain_name, dm_password,
-             pkcs12_info=http_pkcs12_info, subject_base=options.subject_base,
-             auto_redirect=not options.no_ui_redirect,
-             ca_is_configured=setup_ca)
-     else:
-         http.create_instance(
--            realm_name, host_name, domain_name,
-+            realm_name, host_name, domain_name, dm_password,
-             subject_base=options.subject_base,
-             auto_redirect=not options.no_ui_redirect,
-             ca_is_configured=setup_ca)
-diff --git a/ipaserver/install/server/replicainstall.py b/ipaserver/install/server/replicainstall.py
-index b30133ffa22d410452ae04624d49db209175bed9..20eaf98397101b49c751c325afc0591e0babcc18 100644
---- a/ipaserver/install/server/replicainstall.py
-+++ b/ipaserver/install/server/replicainstall.py
-@@ -163,9 +163,10 @@ def install_http(config, auto_redirect, ca_is_configured, ca_file,
-     http = httpinstance.HTTPInstance()
-     http.create_instance(
-         config.realm_name, config.host_name, config.domain_name,
--        pkcs12_info, auto_redirect=auto_redirect, ca_file=ca_file,
-+        config.dirman_password, pkcs12_info,
-+        auto_redirect=auto_redirect, ca_file=ca_file,
-         ca_is_configured=ca_is_configured, promote=promote,
--        subject_base=config.subject_base)
-+        subject_base=config.subject_base, master_fqdn=config.master_host_name)
- 
-     return http
- 
--- 
-2.9.4
-
diff --git a/SOURCES/0172-kdc.key-should-not-be-visible-to-all.patch b/SOURCES/0172-kdc.key-should-not-be-visible-to-all.patch
deleted file mode 100644
index abb5411..0000000
--- a/SOURCES/0172-kdc.key-should-not-be-visible-to-all.patch
+++ /dev/null
@@ -1,34 +0,0 @@
-From f6cac267e99c6f47ca6b78568182a82d48a6bb4c Mon Sep 17 00:00:00 2001
-From: Stanislav Laznicka <slaznick@redhat.com>
-Date: Wed, 31 May 2017 14:14:34 +0200
-Subject: [PATCH] kdc.key should not be visible to all
-
-While the world certainly is interested in our privates, we
-should not just go ahead and show it to them.
-
-https://pagure.io/freeipa/issue/6973
-
-Reviewed-By: Martin Babinsky <mbabinsk@redhat.com>
-Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
----
- ipalib/install/certmonger.py | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
-diff --git a/ipalib/install/certmonger.py b/ipalib/install/certmonger.py
-index ad031a738f4397d230ed131bde6ac7ddb7ef6fdb..c286996ee2318e241b4af190d1a01f42e28aa9f3 100644
---- a/ipalib/install/certmonger.py
-+++ b/ipalib/install/certmonger.py
-@@ -370,8 +370,8 @@ def request_cert(
-         request_parameters['cert-postsave-command'] = post_command
- 
-     if perms:
--        request_parameters['key-perms'] = perms[0]
--        request_parameters['cert-perms'] = perms[1]
-+        request_parameters['cert-perms'] = perms[0]
-+        request_parameters['key-perms'] = perms[1]
- 
-     result = cm.obj_if.add_request(request_parameters)
-     try:
--- 
-2.9.4
-
diff --git a/SOURCES/0173-ipa-kdb-reload-certificate-mapping-rules-periodicall.patch b/SOURCES/0173-ipa-kdb-reload-certificate-mapping-rules-periodicall.patch
deleted file mode 100644
index 659dcea..0000000
--- a/SOURCES/0173-ipa-kdb-reload-certificate-mapping-rules-periodicall.patch
+++ /dev/null
@@ -1,221 +0,0 @@
-From 3a946e38a911fdfb1575135c41128f41ab44324c Mon Sep 17 00:00:00 2001
-From: Sumit Bose <sbose@redhat.com>
-Date: Fri, 26 May 2017 18:19:48 +0200
-Subject: [PATCH] ipa-kdb: reload certificate mapping rules periodically
-
-With this patch the certificate mapping rules are reloaded every 5
-minutes.
-
-Resolves https://pagure.io/freeipa/issue/6963
-
-Reviewed-By: David Kupka <dkupka@redhat.com>
----
- daemons/ipa-kdb/ipa_kdb_certauth.c | 153 ++++++++++++++++++++-----------------
- 1 file changed, 81 insertions(+), 72 deletions(-)
-
-diff --git a/daemons/ipa-kdb/ipa_kdb_certauth.c b/daemons/ipa-kdb/ipa_kdb_certauth.c
-index a53a2ce4e7ceb06ec8de117cdbca2666fdb5a97a..dbe7a0443700784d2b8dbb1fb9196d6249e5522a 100644
---- a/daemons/ipa-kdb/ipa_kdb_certauth.c
-+++ b/daemons/ipa-kdb/ipa_kdb_certauth.c
-@@ -58,6 +58,8 @@
- #define CERTMAP_FILTER "(&("OBJECTCLASS"="IPA_OC_CERTMAP_RULE")" \
-                               "("IPA_ENABLED_FLAG"="IPA_TRUE_VALUE"))"
- 
-+#define DEFAULT_CERTMAP_LIFETIME 300
-+
- #ifndef discard_const
- #define discard_const(ptr) ((void *)((uintptr_t)(ptr)))
- #endif
-@@ -67,6 +69,7 @@ struct krb5_certauth_moddata_st {
-     char *local_domain;
-     struct sss_certmap_ctx *sss_certmap_ctx;
-     struct ipadb_context *ipactx;
-+    time_t valid_until;
- };
- 
- void ipa_certmap_debug(void *private,
-@@ -133,95 +136,101 @@ static krb5_error_code ipa_get_init_data(krb5_context kcontext,
-     }
- 
-     if (ipactx->certauth_moddata == NULL) {
--        ret = asprintf(&basedn, "cn=certmap,%s", ipactx->base);
--        if (ret == -1) {
--            return ENOMEM;
--        }
-+        ipactx->certauth_moddata = moddata_out;
- 
--        kerr = ipadb_simple_search(ipactx,basedn, LDAP_SCOPE_SUBTREE,
--                                   CERTMAP_FILTER, discard_const(certmap_attrs),
--                                   &result);
--        if (kerr != 0 && kerr != KRB5_KDB_NOENTRY) {
--            goto done;
-+        if (ipactx->realm != NULL) {
-+            ipactx->certauth_moddata->local_domain = strdup(ipactx->realm);
-+            if (ipactx->certauth_moddata->local_domain == NULL) {
-+                free(ipactx->certauth_moddata);
-+                ipactx->certauth_moddata = NULL;
-+                ret = ENOMEM;
-+                goto done;
-+            }
-         }
- 
--        ret = sss_certmap_init(NULL, ipa_certmap_debug, NULL, &ctx);
-+        ipactx->certauth_moddata->ipactx = ipactx;
-+
-+    }
-+
-+    ret = asprintf(&basedn, "cn=certmap,%s", ipactx->base);
-+    if (ret == -1) {
-+        return ENOMEM;
-+    }
-+
-+    kerr = ipadb_simple_search(ipactx,basedn, LDAP_SCOPE_SUBTREE,
-+                               CERTMAP_FILTER, discard_const(certmap_attrs),
-+                               &result);
-+    if (kerr != 0 && kerr != KRB5_KDB_NOENTRY) {
-+        goto done;
-+    }
-+
-+    ret = sss_certmap_init(NULL, ipa_certmap_debug, NULL, &ctx);
-+    if (ret != 0) {
-+        return ret;
-+    }
-+
-+    if (kerr == KRB5_KDB_NOENTRY) {
-+        ret = sss_certmap_add_rule(ctx, SSS_CERTMAP_MIN_PRIO,
-+                                   NULL, NULL, NULL);
-         if (ret != 0) {
--            return ret;
-+            goto done;
-         }
--
--        if (kerr == KRB5_KDB_NOENTRY) {
--            ret = sss_certmap_add_rule(ctx, SSS_CERTMAP_MIN_PRIO,
--                                       NULL, NULL, NULL);
--            if (ret != 0) {
-+    } else {
-+        lc = ipactx->lcontext;
-+
-+        for (le = ldap_first_entry(lc, result); le;
-+                                             le = ldap_next_entry(lc, le)) {
-+            prio = SSS_CERTMAP_MIN_PRIO;
-+            ret = ipadb_ldap_attr_to_uint32(lc, le, IPA_CERTMAP_PRIORITY,
-+                                            &prio);
-+            if (ret != 0 && ret != ENOENT) {
-                 goto done;
-             }
--        } else {
--            lc = ipactx->lcontext;
--
--            for (le = ldap_first_entry(lc, result); le;
--                                                 le = ldap_next_entry(lc, le)) {
--                prio = SSS_CERTMAP_MIN_PRIO;
--                ret = ipadb_ldap_attr_to_uint32(lc, le, IPA_CERTMAP_PRIORITY,
--                                                &prio);
--                if (ret != 0 && ret != ENOENT) {
--                    goto done;
--                }
--
--                free(map_rule);
--                map_rule = NULL;
--                ret = ipadb_ldap_attr_to_str(lc, le, IPA_CERTMAP_MAPRULE,
--                                             &map_rule);
--                if (ret != 0 && ret != ENOENT) {
--                    goto done;
--                }
- 
--                free(match_rule);
--                match_rule = NULL;
--                ret = ipadb_ldap_attr_to_str(lc, le, IPA_CERTMAP_MATCHRULE,
--                                             &match_rule);
--                if (ret != 0 && ret != ENOENT) {
--                    goto done;
--                }
-+            free(map_rule);
-+            map_rule = NULL;
-+            ret = ipadb_ldap_attr_to_str(lc, le, IPA_CERTMAP_MAPRULE,
-+                                         &map_rule);
-+            if (ret != 0 && ret != ENOENT) {
-+                goto done;
-+            }
- 
--                if (domains != NULL) {
--                    for (c = 0; domains[c] != NULL; c++) {
--                        free(domains[c]);
--                    }
--                    free(domains);
--                    domains = NULL;
--                }
--                ret = ipadb_ldap_attr_to_strlist(lc, le, IPA_ASSOCIATED_DOMAIN,
--                                                 &domains);
--                if (ret != 0 && ret != ENOENT) {
--                    goto done;
--                }
-+            free(match_rule);
-+            match_rule = NULL;
-+            ret = ipadb_ldap_attr_to_str(lc, le, IPA_CERTMAP_MATCHRULE,
-+                                         &match_rule);
-+            if (ret != 0 && ret != ENOENT) {
-+                goto done;
-+            }
- 
--                ret = sss_certmap_add_rule(ctx, prio, match_rule, map_rule,
--                                           (const char **) domains);
--                if (ret != 0) {
--                    goto done;
-+            if (domains != NULL) {
-+                for (c = 0; domains[c] != NULL; c++) {
-+                    free(domains[c]);
-                 }
-+                free(domains);
-+                domains = NULL;
-+            }
-+            ret = ipadb_ldap_attr_to_strlist(lc, le, IPA_ASSOCIATED_DOMAIN,
-+                                             &domains);
-+            if (ret != 0 && ret != ENOENT) {
-+                goto done;
-             }
--        }
--
--        ipactx->certauth_moddata = moddata_out;
- 
--        if (ipactx->realm != NULL) {
--            ipactx->certauth_moddata->local_domain = strdup(ipactx->realm);
--            if (ipactx->certauth_moddata->local_domain == NULL) {
--                free(ipactx->certauth_moddata);
--                ipactx->certauth_moddata = NULL;
--                ret = ENOMEM;
-+            ret = sss_certmap_add_rule(ctx, prio, match_rule, map_rule,
-+                                       (const char **) domains);
-+            if (ret != 0) {
-                 goto done;
-             }
-         }
--
--        ipactx->certauth_moddata->sss_certmap_ctx = ctx;
--        ipactx->certauth_moddata->ipactx = ipactx;
--
-     }
- 
-+    sss_certmap_free_ctx(ipactx->certauth_moddata->sss_certmap_ctx);
-+    ipactx->certauth_moddata->sss_certmap_ctx = ctx;
-+    ipactx->certauth_moddata->valid_until = time(NULL)
-+                                                 + DEFAULT_CERTMAP_LIFETIME;
-+    krb5_klog_syslog(LOG_DEBUG,
-+                     "Successfully updates certificate mapping rules.");
-+
-     ret = 0;
- 
- done:
-@@ -266,7 +275,7 @@ static krb5_error_code ipa_certauth_authorize(krb5_context context,
-         return KRB5_PLUGIN_NO_HANDLE;
-     }
- 
--    if (moddata->sss_certmap_ctx == NULL) {
-+    if (moddata->sss_certmap_ctx == NULL || time(NULL) > moddata->valid_until) {
-         kerr = ipa_get_init_data(context, moddata);
-         if (kerr != 0) {
-             krb5_klog_syslog(LOG_ERR, "Failed to init certmapping data");
--- 
-2.9.4
-
diff --git a/SOURCES/0174-Avoid-possible-endless-recursion-in-RPC-call.patch b/SOURCES/0174-Avoid-possible-endless-recursion-in-RPC-call.patch
deleted file mode 100644
index 887f87a..0000000
--- a/SOURCES/0174-Avoid-possible-endless-recursion-in-RPC-call.patch
+++ /dev/null
@@ -1,127 +0,0 @@
-From 0367e6dd66d47a78484e12e76119d9662356bf48 Mon Sep 17 00:00:00 2001
-From: Stanislav Laznicka <slaznick@redhat.com>
-Date: Fri, 26 May 2017 08:37:36 +0200
-Subject: [PATCH] Avoid possible endless recursion in RPC call
-
-This commit removes recursion in RPCClient.forward() which may lack
-end condition.
-
-https://pagure.io/freeipa/issue/6796
-
-Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
----
- ipalib/rpc.py | 95 +++++++++++++++++++++++++++++++++--------------------------
- 1 file changed, 54 insertions(+), 41 deletions(-)
-
-diff --git a/ipalib/rpc.py b/ipalib/rpc.py
-index e23ca3d061645b2695a9e0deaa0b7d666f986e0e..297ed80414fae3d8b27558567425fec704f3e862 100644
---- a/ipalib/rpc.py
-+++ b/ipalib/rpc.py
-@@ -1088,50 +1088,63 @@ class RPCClient(Connectible):
-         :param kw: Keyword arguments to pass to remote command.
-         """
-         server = getattr(context, 'request_url', None)
--        self.log.info("Forwarding '%s' to %s server '%s'",
--                      name, self.protocol, server)
-         command = getattr(self.conn, name)
-         params = [args, kw]
--        try:
--            return self._call_command(command, params)
--        except Fault as e:
--            e = decode_fault(e)
--            self.debug('Caught fault %d from server %s: %s', e.faultCode,
--                server, e.faultString)
--            if e.faultCode in errors_by_code:
--                error = errors_by_code[e.faultCode]
--                raise error(message=e.faultString)
--            raise UnknownError(
--                code=e.faultCode,
--                error=e.faultString,
--                server=server,
--            )
--        except SSLError as e:
--            raise NetworkError(uri=server, error=str(e))
--        except ProtocolError as e:
--            # By catching a 401 here we can detect the case where we have
--            # a single IPA server and the session is invalid. Otherwise
--            # we always have to do a ping().
--            session_cookie = getattr(context, 'session_cookie', None)
--            if session_cookie and e.errcode == 401:
--                # Unauthorized. Remove the session and try again.
--                delattr(context, 'session_cookie')
--                try:
--                    principal = getattr(context, 'principal', None)
--                    delete_persistent_client_session_data(principal)
--                except Exception as e:
--                    # This shouldn't happen if we have a session but it isn't fatal.
--                    pass
- 
--                # Create a new serverproxy with the non-session URI
--                serverproxy = self.create_connection(os.environ.get('KRB5CCNAME'), self.env.verbose, self.env.fallback, self.env.delegate)
--                setattr(context, self.id, Connection(serverproxy, self.disconnect))
--                return self.forward(name, *args, **kw)
--            raise NetworkError(uri=server, error=e.errmsg)
--        except socket.error as e:
--            raise NetworkError(uri=server, error=str(e))
--        except (OverflowError, TypeError) as e:
--            raise XMLRPCMarshallError(error=str(e))
-+        # we'll be trying to connect multiple times with a new session cookie
-+        # each time should we be getting UNAUTHORIZED error from the server
-+        max_tries = 5
-+        for try_num in range(0, max_tries):
-+            self.log.info("[try %d]: Forwarding '%s' to %s server '%s'",
-+                          try_num+1, name, self.protocol, server)
-+            try:
-+                return self._call_command(command, params)
-+            except Fault as e:
-+                e = decode_fault(e)
-+                self.debug('Caught fault %d from server %s: %s', e.faultCode,
-+                           server, e.faultString)
-+                if e.faultCode in errors_by_code:
-+                    error = errors_by_code[e.faultCode]
-+                    raise error(message=e.faultString)
-+                raise UnknownError(
-+                    code=e.faultCode,
-+                    error=e.faultString,
-+                    server=server,
-+                )
-+            except ProtocolError as e:
-+                # By catching a 401 here we can detect the case where we have
-+                # a single IPA server and the session is invalid. Otherwise
-+                # we always have to do a ping().
-+                session_cookie = getattr(context, 'session_cookie', None)
-+                if session_cookie and e.errcode == 401:
-+                    # Unauthorized. Remove the session and try again.
-+                    delattr(context, 'session_cookie')
-+                    try:
-+                        principal = getattr(context, 'principal', None)
-+                        delete_persistent_client_session_data(principal)
-+                    except Exception as e:
-+                        # This shouldn't happen if we have a session
-+                        # but it isn't fatal.
-+                        self.debug("Error trying to remove persisent session "
-+                                   "data: {err}".format(err=e))
-+
-+                    # Create a new serverproxy with the non-session URI
-+                    serverproxy = self.create_connection(
-+                        os.environ.get('KRB5CCNAME'), self.env.verbose,
-+                        self.env.fallback, self.env.delegate)
-+
-+                    setattr(context, self.id,
-+                            Connection(serverproxy, self.disconnect))
-+                    # try to connect again with the new session cookie
-+                    continue
-+                raise NetworkError(uri=server, error=e.errmsg)
-+            except (SSLError, socket.error) as e:
-+                raise NetworkError(uri=server, error=str(e))
-+            except (OverflowError, TypeError) as e:
-+                raise XMLRPCMarshallError(error=str(e))
-+        raise NetworkError(
-+            uri=server,
-+            error=_("Exceeded number of tries to forward a request."))
- 
- 
- class xmlclient(RPCClient):
--- 
-2.9.4
-
diff --git a/SOURCES/0175-rpc-preparations-for-recursion-fix.patch b/SOURCES/0175-rpc-preparations-for-recursion-fix.patch
deleted file mode 100644
index 156557c..0000000
--- a/SOURCES/0175-rpc-preparations-for-recursion-fix.patch
+++ /dev/null
@@ -1,103 +0,0 @@
-From ae8d12b2f764fa49bebf263ec646709900d90a6b Mon Sep 17 00:00:00 2001
-From: Stanislav Laznicka <slaznick@redhat.com>
-Date: Wed, 31 May 2017 15:45:19 +0200
-Subject: [PATCH] rpc: preparations for recursion fix
-
-Made several improvements to coding style:
- - same use of KerberosError throughout the module
- - removed some unused variables
- - moved code from try-except blocks if it didn't have to be there
- - preparations for putting most of RPCClient.create_connection()
-   to loop
-
-https://pagure.io/freeipa/issue/6796
-
-Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
----
- ipalib/rpc.py | 27 +++++++++++++++++----------
- 1 file changed, 17 insertions(+), 10 deletions(-)
-
-diff --git a/ipalib/rpc.py b/ipalib/rpc.py
-index 297ed80414fae3d8b27558567425fec704f3e862..b12ce4c5365299332587ad0d2990ca30070217bf 100644
---- a/ipalib/rpc.py
-+++ b/ipalib/rpc.py
-@@ -52,7 +52,7 @@ from six.moves import urllib
- from ipalib.backend import Connectible
- from ipalib.constants import LDAP_GENERALIZED_TIME_FORMAT
- from ipalib.errors import (public_errors, UnknownError, NetworkError,
--    KerberosError, XMLRPCMarshallError, JSONError)
-+                           XMLRPCMarshallError, JSONError)
- from ipalib import errors, capabilities
- from ipalib.request import context, Connection
- from ipapython.ipa_log_manager import root_logger
-@@ -653,7 +653,7 @@ class KerbTransport(SSLTransport):
-                     except (TypeError, UnicodeError):
-                         pass
-             if not token:
--                raise KerberosError(
-+                raise errors.KerberosError(
-                     message=u"No valid Negotiate header in server response")
-             token = self._sec_context.step(token=token)
-             if self._sec_context.complete:
-@@ -979,8 +979,10 @@ class RPCClient(Connectible):
-             delegate = self.api.env.delegate
-         if ca_certfile is None:
-             ca_certfile = self.api.env.tls_ca_cert
-+        context.ca_certfile = ca_certfile
-+
-+        rpc_uri = self.env[self.env_rpc_uri_key]
-         try:
--            rpc_uri = self.env[self.env_rpc_uri_key]
-             principal = get_principal(ccache_name=ccache)
-             stored_principal = getattr(context, 'principal', None)
-             if principal != stored_principal:
-@@ -996,12 +998,14 @@ class RPCClient(Connectible):
-         except (errors.CCacheError, ValueError):
-             # No session key, do full Kerberos auth
-             pass
--        context.ca_certfile = ca_certfile
-         urls = self.get_url_list(rpc_uri)
-         serverproxy = None
-         for url in urls:
--            kw = dict(allow_none=True, encoding='UTF-8')
--            kw['verbose'] = verbose
-+            kw = {
-+                'allow_none': True,
-+                'encoding': 'UTF-8',
-+                'verbose': verbose
-+            }
-             if url.startswith('https://'):
-                 if delegate:
-                     transport_class = DelegatedKerbTransport
-@@ -1036,21 +1040,24 @@ class RPCClient(Connectible):
-                         )
-                 # We don't care about the response, just that we got one
-                 break
--            except KerberosError as krberr:
-+            except errors.KerberosError:
-                 # kerberos error on one server is likely on all
--                raise errors.KerberosError(message=unicode(krberr))
-+                raise
-             except ProtocolError as e:
-                 if hasattr(context, 'session_cookie') and e.errcode == 401:
-                     # Unauthorized. Remove the session and try again.
-                     delattr(context, 'session_cookie')
-                     try:
-                         delete_persistent_client_session_data(principal)
--                    except Exception as e:
-+                    except Exception:
-                         # This shouldn't happen if we have a session but it isn't fatal.
-                         pass
--                    return self.create_connection(ccache, verbose, fallback, delegate)
-+                    return self.create_connection(
-+                        ccache, verbose, fallback, delegate)
-                 if not fallback:
-                     raise
-+                else:
-+                    self.log.info('Connection to %s failed with %s', url, e)
-                 serverproxy = None
-             except Exception as e:
-                 if not fallback:
--- 
-2.9.4
-
diff --git a/SOURCES/0176-rpc-avoid-possible-recursion-in-create_connection.patch b/SOURCES/0176-rpc-avoid-possible-recursion-in-create_connection.patch
deleted file mode 100644
index 885522f..0000000
--- a/SOURCES/0176-rpc-avoid-possible-recursion-in-create_connection.patch
+++ /dev/null
@@ -1,175 +0,0 @@
-From f5f7cbc63f9235ce040687cdf102aeaef69ab422 Mon Sep 17 00:00:00 2001
-From: Stanislav Laznicka <slaznick@redhat.com>
-Date: Thu, 1 Jun 2017 09:00:15 +0200
-Subject: [PATCH] rpc: avoid possible recursion in create_connection
-
-There was a recursion in RPCClient.create_connection() which under rare
-circumstances would not have an ending condition. This commit removes
-it and cleans up the code a bit as well.
-
-https://pagure.io/freeipa/issue/6796
-
-Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
----
- ipalib/rpc.py | 140 +++++++++++++++++++++++++++++++---------------------------
- 1 file changed, 74 insertions(+), 66 deletions(-)
-
-diff --git a/ipalib/rpc.py b/ipalib/rpc.py
-index b12ce4c5365299332587ad0d2990ca30070217bf..e3b8d67d69c084ad1a43390b5f93061826a27e1d 100644
---- a/ipalib/rpc.py
-+++ b/ipalib/rpc.py
-@@ -999,77 +999,85 @@ class RPCClient(Connectible):
-             # No session key, do full Kerberos auth
-             pass
-         urls = self.get_url_list(rpc_uri)
--        serverproxy = None
-+
-+        proxy_kw = {
-+            'allow_none': True,
-+            'encoding': 'UTF-8',
-+            'verbose': verbose
-+        }
-+
-         for url in urls:
--            kw = {
--                'allow_none': True,
--                'encoding': 'UTF-8',
--                'verbose': verbose
--            }
--            if url.startswith('https://'):
--                if delegate:
--                    transport_class = DelegatedKerbTransport
-+            # should we get ProtocolError (=> error in HTTP response) and
-+            # 401 (=> Unauthorized), we'll be re-trying with new session
-+            # cookies several times
-+            for _try_num in range(0, 5):
-+                if url.startswith('https://'):
-+                    if delegate:
-+                        transport_class = DelegatedKerbTransport
-+                    else:
-+                        transport_class = KerbTransport
-                 else:
--                    transport_class = KerbTransport
--            else:
--                transport_class = LanguageAwareTransport
--            kw['transport'] = transport_class(protocol=self.protocol,
--                                              service='HTTP', ccache=ccache)
--            self.log.info('trying %s' % url)
--            setattr(context, 'request_url', url)
--            serverproxy = self.server_proxy_class(url, **kw)
--            if len(urls) == 1:
--                # if we have only 1 server and then let the
--                # main requester handle any errors. This also means it
--                # must handle a 401 but we save a ping.
--                return serverproxy
--            try:
--                command = getattr(serverproxy, 'ping')
-+                    transport_class = LanguageAwareTransport
-+                proxy_kw['transport'] = transport_class(
-+                    protocol=self.protocol, service='HTTP', ccache=ccache)
-+                self.log.info('trying %s' % url)
-+                setattr(context, 'request_url', url)
-+                serverproxy = self.server_proxy_class(url, **proxy_kw)
-+                if len(urls) == 1:
-+                    # if we have only 1 server and then let the
-+                    # main requester handle any errors. This also means it
-+                    # must handle a 401 but we save a ping.
-+                    return serverproxy
-                 try:
--                    command([], {})
--                except Fault as e:
--                    e = decode_fault(e)
--                    if e.faultCode in errors_by_code:
--                        error = errors_by_code[e.faultCode]
--                        raise error(message=e.faultString)
--                    else:
--                        raise UnknownError(
--                            code=e.faultCode,
--                            error=e.faultString,
--                            server=url,
--                        )
--                # We don't care about the response, just that we got one
--                break
--            except errors.KerberosError:
--                # kerberos error on one server is likely on all
--                raise
--            except ProtocolError as e:
--                if hasattr(context, 'session_cookie') and e.errcode == 401:
--                    # Unauthorized. Remove the session and try again.
--                    delattr(context, 'session_cookie')
-+                    command = getattr(serverproxy, 'ping')
-                     try:
--                        delete_persistent_client_session_data(principal)
--                    except Exception:
--                        # This shouldn't happen if we have a session but it isn't fatal.
--                        pass
--                    return self.create_connection(
--                        ccache, verbose, fallback, delegate)
--                if not fallback:
-+                        command([], {})
-+                    except Fault as e:
-+                        e = decode_fault(e)
-+                        if e.faultCode in errors_by_code:
-+                            error = errors_by_code[e.faultCode]
-+                            raise error(message=e.faultString)
-+                        else:
-+                            raise UnknownError(
-+                                code=e.faultCode,
-+                                error=e.faultString,
-+                                server=url,
-+                            )
-+                    # We don't care about the response, just that we got one
-+                    return serverproxy
-+                except errors.KerberosError:
-+                    # kerberos error on one server is likely on all
-                     raise
--                else:
--                    self.log.info('Connection to %s failed with %s', url, e)
--                serverproxy = None
--            except Exception as e:
--                if not fallback:
--                    raise
--                else:
--                    self.log.info('Connection to %s failed with %s', url, e)
--                serverproxy = None
--
--        if serverproxy is None:
--            raise NetworkError(uri=_('any of the configured servers'),
--                error=', '.join(urls))
--        return serverproxy
-+                except ProtocolError as e:
-+                    if hasattr(context, 'session_cookie') and e.errcode == 401:
-+                        # Unauthorized. Remove the session and try again.
-+                        delattr(context, 'session_cookie')
-+                        try:
-+                            delete_persistent_client_session_data(principal)
-+                        except Exception:
-+                            # This shouldn't happen if we have a session but
-+                            # it isn't fatal.
-+                            pass
-+                        # try the same url once more with a new session cookie
-+                        continue
-+                    if not fallback:
-+                        raise
-+                    else:
-+                        self.log.info(
-+                            'Connection to %s failed with %s', url, e)
-+                    # try the next url
-+                    break
-+                except Exception as e:
-+                    if not fallback:
-+                        raise
-+                    else:
-+                        self.log.info(
-+                            'Connection to %s failed with %s', url, e)
-+                    # try the next url
-+                    break
-+        # finished all tries but no serverproxy was found
-+        raise NetworkError(uri=_('any of the configured servers'),
-+                           error=', '.join(urls))
- 
-     def destroy_connection(self):
-         conn = getattr(context, self.id, None)
--- 
-2.9.4
-
diff --git a/SOURCES/0177-Changing-cert-find-to-do-not-use-only-primary-key-to.patch b/SOURCES/0177-Changing-cert-find-to-do-not-use-only-primary-key-to.patch
deleted file mode 100644
index ee9e062..0000000
--- a/SOURCES/0177-Changing-cert-find-to-do-not-use-only-primary-key-to.patch
+++ /dev/null
@@ -1,102 +0,0 @@
-From d5af6b5e3ee50f97db730a4097c46baf07e09002 Mon Sep 17 00:00:00 2001
-From: Felipe Volpone <felipevolpone@gmail.com>
-Date: Thu, 1 Jun 2017 16:53:11 -0300
-Subject: [PATCH] Changing cert-find to do not use only primary key to search
- in LDAP.
-
-In service.py the primary key is krbCanonicalName, which we
-don't want to use to do searchs. Now, cert-find uses primary
-key or a specified attribute to do searches in LDAP, instead
-of using only a primary key.
-
-https://pagure.io/freeipa/issue/6948
-
-Reviewed-By: Martin Babinsky <mbabinsk@redhat.com>
-Reviewed-By: Jan Cholasta <jcholast@redhat.com>
-Reviewed-By: Fraser Tweedale <ftweedal@redhat.com>
----
- ipaserver/plugins/cert.py | 27 +++++++++++++++++----------
- 1 file changed, 17 insertions(+), 10 deletions(-)
-
-diff --git a/ipaserver/plugins/cert.py b/ipaserver/plugins/cert.py
-index 68402679cf0320e9c664ea89276f6c4332730a15..bb11713317abad55577b1c280253ab5d6d68c508 100644
---- a/ipaserver/plugins/cert.py
-+++ b/ipaserver/plugins/cert.py
-@@ -981,8 +981,8 @@ class cert(BaseCertObject):
-                 param = param.clone(flags=param.flags - {'no_search'})
-             yield param
- 
--        for owner in self._owners():
--            yield owner.primary_key.clone_rename(
-+        for owner, search_key in self._owners():
-+            yield search_key.clone_rename(
-                 'owner_{0}'.format(owner.name),
-                 required=False,
-                 multivalue=True,
-@@ -992,15 +992,22 @@ class cert(BaseCertObject):
-             )
- 
-     def _owners(self):
--        for name in ('user', 'host', 'service'):
--            yield self.api.Object[name]
-+        for obj_name, search_key in [('user', None),
-+                                     ('host', None),
-+                                     ('service', 'krbprincipalname')]:
-+            obj = self.api.Object[obj_name]
-+            if search_key is None:
-+                pkey = obj.primary_key
-+            else:
-+                pkey = obj.params[search_key]
-+            yield obj, pkey
- 
-     def _fill_owners(self, obj):
-         dns = obj.pop('owner', None)
-         if dns is None:
-             return
- 
--        for owner in self._owners():
-+        for owner, _search_key in self._owners():
-             container_dn = DN(owner.container_dn, self.api.env.basedn)
-             name = 'owner_' + owner.name
-             for dn in dns:
-@@ -1264,8 +1271,8 @@ class cert_find(Search, CertMethod):
-                 option = option.clone(default=None, autofill=None)
-             yield option
- 
--        for owner in self.obj._owners():
--            yield owner.primary_key.clone_rename(
-+        for owner, search_key in self.obj._owners():
-+            yield search_key.clone_rename(
-                 '{0}'.format(owner.name),
-                 required=False,
-                 multivalue=True,
-@@ -1276,7 +1283,7 @@ class cert_find(Search, CertMethod):
-                      owner.object_name_plural),
-                 label=owner.object_name,
-             )
--            yield owner.primary_key.clone_rename(
-+            yield search_key.clone_rename(
-                 'no_{0}'.format(owner.name),
-                 required=False,
-                 multivalue=True,
-@@ -1395,7 +1402,7 @@ class cert_find(Search, CertMethod):
-         ldap = self.api.Backend.ldap2
- 
-         filters = []
--        for owner in self.obj._owners():
-+        for owner, search_key in self.obj._owners():
-             for prefix, rule in (('', ldap.MATCH_ALL),
-                                  ('no_', ldap.MATCH_NONE)):
-                 try:
-@@ -1411,7 +1418,7 @@ class cert_find(Search, CertMethod):
-                     filters.append(filter)
- 
-                 filter = ldap.make_filter_from_attr(
--                    owner.primary_key.name,
-+                    search_key.name,
-                     value,
-                     rule)
-                 filters.append(filter)
--- 
-2.9.4
-
diff --git a/SOURCES/0178-ipa-kdb-add-pkinit-authentication-indicator-in-case-.patch b/SOURCES/0178-ipa-kdb-add-pkinit-authentication-indicator-in-case-.patch
deleted file mode 100644
index 3a78753..0000000
--- a/SOURCES/0178-ipa-kdb-add-pkinit-authentication-indicator-in-case-.patch
+++ /dev/null
@@ -1,101 +0,0 @@
-From 5e052107dcb70630c1cccee191ae5317a43ec2cf Mon Sep 17 00:00:00 2001
-From: Alexander Bokovoy <abokovoy@redhat.com>
-Date: Sun, 4 Jun 2017 22:49:13 +0300
-Subject: [PATCH] ipa-kdb: add pkinit authentication indicator in case of a
- successful certauth
-
-We automatically add 'otp' and 'radius' authentication indicators when
-pre-authentication with OTP or RADIUS did succeed. Do the same for
-certauth-based pre-authentication (PKINIT).
-
-A default PKINIT configuration does not add any authentication
-indicators unless 'pkinit_indicator = pkinit' is set in kdc.conf.
-Unfortunately, modifying kdc.conf automatically is a bit more
-complicated than modifying krb5.conf. Given that we have 'otp' and
-'radius' authentication indicators also defined in the code not in the
-kdc.conf, this change is following an established trend.
-
-SSSD certauth interface does not provide additional information about
-which rule(s) succeeded in matching the incoming certificate. Thus,
-there is not much information we can automatically provide in the
-indicator. It would be good to generate indicators that include some
-information from the certmapping rules in future but for now a single
-'pkinit' indicator is enough.
-
-Fixes https://pagure.io/freeipa/issue/6736
-
-Reviewed-By: Simo Sorce <ssorce@redhat.com>
----
- daemons/ipa-kdb/ipa_kdb_certauth.c | 36 ++++++++++++++++++++++++++++++++++--
- 1 file changed, 34 insertions(+), 2 deletions(-)
-
-diff --git a/daemons/ipa-kdb/ipa_kdb_certauth.c b/daemons/ipa-kdb/ipa_kdb_certauth.c
-index dbe7a0443700784d2b8dbb1fb9196d6249e5522a..da9a9cb87feca68ee591da70a3239dc86749bae5 100644
---- a/daemons/ipa-kdb/ipa_kdb_certauth.c
-+++ b/daemons/ipa-kdb/ipa_kdb_certauth.c
-@@ -267,6 +267,7 @@ static krb5_error_code ipa_certauth_authorize(krb5_context context,
-     int ret;
-     size_t c;
-     char *principal = NULL;
-+    char **auth_inds = NULL;
-     LDAPMessage *res = NULL;
-     krb5_error_code kerr;
-     LDAPMessage *lentry;
-@@ -350,6 +351,20 @@ static krb5_error_code ipa_certauth_authorize(krb5_context context,
-         goto done;
-     }
- 
-+    /* Associate authentication indicator "pkinit" with the successful match.
-+     * SSSD interface doesn't give us a clue which rule did match
-+     * so there is nothing more to add here. */
-+    auth_inds = calloc(2, sizeof(char *));
-+    if (auth_inds != NULL) {
-+	ret = asprintf(&auth_inds[0], "pkinit");
-+	if (ret != -1) {
-+            auth_inds[1] = NULL;
-+            *authinds_out = auth_inds;
-+	} else {
-+	    free(auth_inds);
-+        }
-+    }
-+
-     /* TODO: add more tests ? */
- 
-     ret = 0;
-@@ -384,6 +399,24 @@ static void ipa_certauth_fini(krb5_context context,
-     return;
- }
- 
-+static void ipa_certauth_free_indicator(krb5_context context,
-+                                        krb5_certauth_moddata moddata,
-+                                        char **authinds)
-+{
-+    size_t i = 0;
-+
-+    if ((authinds == NULL) || (moddata == NULL)) {
-+	return;
-+    }
-+
-+    for(i=0; authinds[i]; i++) {
-+	free(authinds[i]);
-+	authinds[i] = NULL;
-+    }
-+
-+    free(authinds);
-+}
-+
- 
- krb5_error_code certauth_ipakdb_initvt(krb5_context context,
-                                           int maj_ver, int min_ver,
-@@ -401,7 +434,6 @@ krb5_error_code certauth_ipakdb_initvt(krb5_context context,
-     vt->authorize = ipa_certauth_authorize;
-     vt->init = ipa_certauth_init;
-     vt->fini = ipa_certauth_fini;
--    /* currently we do not return authentication indicators */
--    vt->free_ind = NULL;
-+    vt->free_ind = ipa_certauth_free_indicator;
-     return 0;
- }
--- 
-2.9.4
-
diff --git a/SOURCES/0179-fix-incorrect-suffix-handling-in-topology-checks.patch b/SOURCES/0179-fix-incorrect-suffix-handling-in-topology-checks.patch
deleted file mode 100644
index e42bb98..0000000
--- a/SOURCES/0179-fix-incorrect-suffix-handling-in-topology-checks.patch
+++ /dev/null
@@ -1,49 +0,0 @@
-From 6d44c0c1455442ffd61ad532635c109b92ca96d1 Mon Sep 17 00:00:00 2001
-From: Martin Babinsky <mbabinsk@redhat.com>
-Date: Fri, 26 May 2017 12:23:51 +0200
-Subject: [PATCH] fix incorrect suffix handling in topology checks
-
-When trying to delete a partially removed master entry lacking
-'iparepltopomanagedsuffix' attribute, the code that tries to retrieve
-tha value for further computations passes None and causes unhandled
-internal errors.
-
-If the attribute is empty or not present, we should return empty list
-instead as to not break calling cod attribute, the code that tries to
-retrieve tha value for further computations passes None and causes
-unhandled internal errors. We should return empty list instead.
-
-https://pagure.io/freeipa/issue/6965
-
-Reviewed-By: Felipe Volpone <felipevolpone@gmail.com>
----
- ipaserver/topology.py | 11 +++++++----
- 1 file changed, 7 insertions(+), 4 deletions(-)
-
-diff --git a/ipaserver/topology.py b/ipaserver/topology.py
-index 385da29a66fb7276c55e9aac5c8c266b897721a7..2b6b0835473097eeec673230fab338bef41b8c49 100644
---- a/ipaserver/topology.py
-+++ b/ipaserver/topology.py
-@@ -72,12 +72,15 @@ def get_topology_connection_errors(graph):
- 
- def map_masters_to_suffixes(masters):
-     masters_to_suffix = {}
-+    managed_suffix_attr = 'iparepltopomanagedsuffix_topologysuffix'
- 
-     for master in masters:
--        try:
--            managed_suffixes = master.get(
--                'iparepltopomanagedsuffix_topologysuffix')
--        except KeyError:
-+        if managed_suffix_attr not in master:
-+            continue
-+
-+        managed_suffixes = master[managed_suffix_attr]
-+
-+        if managed_suffixes is None:
-             continue
- 
-         for suffix_name in managed_suffixes:
--- 
-2.9.4
-
diff --git a/SOURCES/0180-server-certinstall-update-KDC-master-entry.patch b/SOURCES/0180-server-certinstall-update-KDC-master-entry.patch
deleted file mode 100644
index 5fa9aca..0000000
--- a/SOURCES/0180-server-certinstall-update-KDC-master-entry.patch
+++ /dev/null
@@ -1,45 +0,0 @@
-From 82af886e17905b8bdaadf8fc2b8214ad85a94470 Mon Sep 17 00:00:00 2001
-From: Jan Cholasta <jcholast@redhat.com>
-Date: Mon, 5 Jun 2017 12:35:52 +0000
-Subject: [PATCH] server certinstall: update KDC master entry
-
-After the KDC certificate is installed, add the PKINIT enabled flag to the
-KDC master entry.
-
-https://pagure.io/freeipa/issue/7000
-
-Reviewed-By: Martin Babinsky <mbabinsk@redhat.com>
----
- ipaserver/install/ipa_server_certinstall.py | 9 ++++++++-
- 1 file changed, 8 insertions(+), 1 deletion(-)
-
-diff --git a/ipaserver/install/ipa_server_certinstall.py b/ipaserver/install/ipa_server_certinstall.py
-index a14a84f188c62170c8ac11f823ebba60609e4cc7..9c8f6e81a802e1a87bab1fd15f729e10676fe3a3 100644
---- a/ipaserver/install/ipa_server_certinstall.py
-+++ b/ipaserver/install/ipa_server_certinstall.py
-@@ -34,7 +34,7 @@ from ipapython.certdb import (get_ca_nickname,
-                               verify_kdc_cert_validity)
- from ipapython.dn import DN
- from ipalib import api, errors
--from ipaserver.install import certs, dsinstance, installutils
-+from ipaserver.install import certs, dsinstance, installutils, krbinstance
- 
- 
- class ServerCertInstall(admintool.AdminTool):
-@@ -223,6 +223,13 @@ class ServerCertInstall(admintool.AdminTool):
-         except RuntimeError as e:
-             raise admintool.ScriptError(str(e))
- 
-+        krb = krbinstance.KrbInstance()
-+        krb.init_info(
-+            realm_name=api.env.realm,
-+            host_name=api.env.host,
-+        )
-+        krb.pkinit_enable()
-+
-     def check_chain(self, pkcs12_filename, pkcs12_pin, nssdb):
-         # create a temp nssdb
-         with NSSDatabase() as tempnssdb:
--- 
-2.9.4
-
diff --git a/SOURCES/0181-pkinit-manage-introduce-ipa-pkinit-manage.patch b/SOURCES/0181-pkinit-manage-introduce-ipa-pkinit-manage.patch
deleted file mode 100644
index 9662a62..0000000
--- a/SOURCES/0181-pkinit-manage-introduce-ipa-pkinit-manage.patch
+++ /dev/null
@@ -1,259 +0,0 @@
-From d224655e4b1e218bac19dff5a10bf3e0d83edcb0 Mon Sep 17 00:00:00 2001
-From: Jan Cholasta <jcholast@redhat.com>
-Date: Mon, 5 Jun 2017 12:41:02 +0000
-Subject: [PATCH] pkinit manage: introduce ipa-pkinit-manage
-
-Add the ipa-pkinit-manage tool to allow enabling / disabling PKINIT after
-the initial server install.
-
-https://pagure.io/freeipa/issue/7000
-
-Reviewed-By: Martin Babinsky <mbabinsk@redhat.com>
----
- freeipa.spec.in                        |  2 +
- install/tools/Makefile.am              |  1 +
- install/tools/ipa-pkinit-manage        |  8 +++
- install/tools/man/Makefile.am          |  1 +
- install/tools/man/ipa-pkinit-manage.1  | 34 +++++++++++++
- ipaserver/install/ipa_pkinit_manage.py | 93 ++++++++++++++++++++++++++++++++++
- ipaserver/install/krbinstance.py       | 24 +++++++++
- 7 files changed, 163 insertions(+)
- create mode 100755 install/tools/ipa-pkinit-manage
- create mode 100644 install/tools/man/ipa-pkinit-manage.1
- create mode 100644 ipaserver/install/ipa_pkinit_manage.py
-
-diff --git a/freeipa.spec.in b/freeipa.spec.in
-index 2cbaa60df0db021a4a1ce10af383cd6a15e1e57c..ae77a9a23645c1490c32195203e2c4f665783a80 100644
---- a/freeipa.spec.in
-+++ b/freeipa.spec.in
-@@ -1184,6 +1184,7 @@ fi
- %{_sbindir}/ipa-advise
- %{_sbindir}/ipa-cacert-manage
- %{_sbindir}/ipa-winsync-migrate
-+%{_sbindir}/ipa-pkinit-manage
- %{_libexecdir}/certmonger/dogtag-ipa-ca-renew-agent-submit
- %{_libexecdir}/certmonger/ipa-server-guard
- %dir %{_libexecdir}/ipa
-@@ -1247,6 +1248,7 @@ fi
- %{_mandir}/man1/ipa-otptoken-import.1*
- %{_mandir}/man1/ipa-cacert-manage.1*
- %{_mandir}/man1/ipa-winsync-migrate.1*
-+%{_mandir}/man1/ipa-pkinit-manage.1*
- 
- 
- %files -n python2-ipaserver
-diff --git a/install/tools/Makefile.am b/install/tools/Makefile.am
-index 493e5ff4a8290be8ef076135104a85f8315b7842..47ecc14d7320336315c16587956c4965387853d9 100644
---- a/install/tools/Makefile.am
-+++ b/install/tools/Makefile.am
-@@ -28,6 +28,7 @@ dist_sbin_SCRIPTS =		\
- 	ipa-advise		\
- 	ipa-cacert-manage	\
- 	ipa-winsync-migrate	\
-+	ipa-pkinit-manage	\
- 	$(NULL)
- 
- appdir = $(libexecdir)/ipa/
-diff --git a/install/tools/ipa-pkinit-manage b/install/tools/ipa-pkinit-manage
-new file mode 100755
-index 0000000000000000000000000000000000000000..5b2413bd7cdc97632f82a77e18f3424a2ff63309
---- /dev/null
-+++ b/install/tools/ipa-pkinit-manage
-@@ -0,0 +1,8 @@
-+#! /usr/bin/python2 -E
-+#
-+# Copyright (C) 2017  FreeIPA Contributors see COPYING for license
-+#
-+
-+from ipaserver.install.ipa_pkinit_manage import PKINITManage
-+
-+PKINITManage.run_cli()
-diff --git a/install/tools/man/Makefile.am b/install/tools/man/Makefile.am
-index 0d06ec7306b0cc1e656dac244bcb2c480b0ae61e..2dac9ac716352847aeb0d1fd3c6375ede956c751 100644
---- a/install/tools/man/Makefile.am
-+++ b/install/tools/man/Makefile.am
-@@ -27,6 +27,7 @@ dist_man1_MANS = 			\
- 	ipa-otptoken-import.1		\
- 	ipa-cacert-manage.1		\
- 	ipa-winsync-migrate.1		\
-+	ipa-pkinit-manage.1		\
-         $(NULL)
- 
- dist_man8_MANS =			\
-diff --git a/install/tools/man/ipa-pkinit-manage.1 b/install/tools/man/ipa-pkinit-manage.1
-new file mode 100644
-index 0000000000000000000000000000000000000000..5018ce8aa3f89470453d9cfc590a0c5f44f78f3c
---- /dev/null
-+++ b/install/tools/man/ipa-pkinit-manage.1
-@@ -0,0 +1,34 @@
-+.\"
-+.\" Copyright (C) 2017  FreeIPA Contributors see COPYING for license
-+.\"
-+.TH "ipa-pkinit-manage" "1" "Jun 05 2017" "FreeIPA" "FreeIPA Manual Pages"
-+.SH "NAME"
-+ipa\-pkinit\-manage \- Enables or disables PKINIT
-+.SH "SYNOPSIS"
-+ipa\-pkinit\-manage [options] <enable|disable|status>
-+.SH "DESCRIPTION"
-+Run the command with the \fBenable\fR option to enable PKINIT.
-+
-+Run the command with the \fBdisable\fR option to disable PKINIT.
-+
-+Run the command with the \fBstatus\fR to determine the current status of PKINIT.
-+.SH "OPTIONS"
-+.TP
-+\fB\-\-version\fR
-+Show the program's version and exit.
-+.TP
-+\fB\-h\fR, \fB\-\-help\fR
-+Show the help for this program.
-+.TP
-+\fB\-v\fR, \fB\-\-verbose\fR
-+Print debugging information.
-+.TP
-+\fB\-q\fR, \fB\-\-quiet\fR
-+Output only errors.
-+.TP
-+\fB\-\-log\-file\fR=\fIFILE\fR
-+Log to the given file.
-+.SH "EXIT STATUS"
-+0 if the command was successful
-+
-+1 if an error occurred
-diff --git a/ipaserver/install/ipa_pkinit_manage.py b/ipaserver/install/ipa_pkinit_manage.py
-new file mode 100644
-index 0000000000000000000000000000000000000000..428c0e3476b4dbd13a9ee5a40a42447f9fa95f2d
---- /dev/null
-+++ b/ipaserver/install/ipa_pkinit_manage.py
-@@ -0,0 +1,93 @@
-+#
-+# Copyright (C) 2017  FreeIPA Contributors see COPYING for license
-+#
-+
-+from __future__ import print_function
-+
-+from ipalib import api
-+from ipaplatform.paths import paths
-+from ipapython.admintool import AdminTool
-+from ipaserver.install.krbinstance import KrbInstance, is_pkinit_enabled
-+
-+
-+class PKINITManage(AdminTool):
-+    command_name = "ipa-pkinit-manage"
-+    usage = "%prog <enable|disable|status>"
-+    description = "Manage PKINIT."
-+
-+    def validate_options(self):
-+        super(PKINITManage, self).validate_options(needs_root=True)
-+
-+        option_parser = self.option_parser
-+
-+        if not self.args:
-+            option_parser.error("action not specified")
-+        elif len(self.args) > 1:
-+            option_parser.error("too many arguments")
-+
-+        action = self.args[0]
-+        if action not in {'enable', 'disable', 'status'}:
-+            option_parser.error("unrecognized action '{}'".format(action))
-+
-+    def run(self):
-+        api.bootstrap(in_server=True, confdir=paths.ETC_IPA)
-+        api.finalize()
-+
-+        api.Backend.ldap2.connect()
-+        try:
-+            action = self.args[0]
-+            if action == 'enable':
-+                self.enable()
-+            elif action == 'disable':
-+                self.disable()
-+            elif action == 'status':
-+                self.status()
-+        finally:
-+            api.Backend.ldap2.disconnect()
-+
-+        return 0
-+
-+    def _setup(self, setup_pkinit):
-+        config = api.Command.config_show()['result']
-+        ca_enabled = api.Command.ca_is_enabled()['result']
-+
-+        krb = KrbInstance()
-+        krb.init_info(
-+            realm_name=api.env.realm,
-+            host_name=api.env.host,
-+            setup_pkinit=setup_pkinit,
-+            subject_base=config['ipacertificatesubjectbase'][0],
-+        )
-+
-+        if bool(is_pkinit_enabled()) is not bool(setup_pkinit):
-+            try:
-+                krb.stop_tracking_certs()
-+            except RuntimeError as e:
-+                if ca_enabled:
-+                    self.log.warning(
-+                        "Failed to stop tracking certificates: %s", e)
-+
-+            krb.enable_ssl()
-+
-+        if setup_pkinit:
-+            krb.pkinit_enable()
-+        else:
-+            krb.pkinit_disable()
-+
-+    def enable(self):
-+        if not api.Command.ca_is_enabled()['result']:
-+            self.log.error("Cannot enable PKINIT in CA-less deployment")
-+            self.log.error("Use ipa-server-certinstall to install KDC "
-+                           "certificate manually")
-+            raise RuntimeError("Cannot enable PKINIT in CA-less deployment")
-+
-+        self._setup(True)
-+
-+    def disable(self):
-+        self._setup(False)
-+
-+    def status(self):
-+        if is_pkinit_enabled():
-+            print("PKINIT is enabled")
-+        else:
-+            print("PKINIT is disabled")
-diff --git a/ipaserver/install/krbinstance.py b/ipaserver/install/krbinstance.py
-index a1053d55ccaae17bef93547c036fb9d08d296f0b..6b51e65d1ec985bfc01f167aea3fe3ca11c7ec29 100644
---- a/ipaserver/install/krbinstance.py
-+++ b/ipaserver/install/krbinstance.py
-@@ -451,6 +451,30 @@ class KrbInstance(service.Service):
-         service.set_service_entry_config(
-             'KDC', self.fqdn, [PKINIT_ENABLED], self.suffix)
- 
-+    def pkinit_disable(self):
-+        """
-+        unadvertise enabled PKINIT feature in master's KDC entry in LDAP
-+        """
-+        ldap = api.Backend.ldap2
-+        dn = DN(('cn', 'KDC'),
-+                ('cn', self.fqdn),
-+                ('cn', 'masters'),
-+                ('cn', 'ipa'),
-+                ('cn', 'etc'),
-+                self.suffix)
-+
-+        entry = ldap.get_entry(dn, ['ipaConfigString'])
-+
-+        config = entry.setdefault('ipaConfigString', [])
-+        config = [value for value in config
-+                  if value.lower() != PKINIT_ENABLED.lower()]
-+        entry['ipaConfigString'][:] = config
-+
-+        try:
-+            ldap.update_entry(entry)
-+        except errors.EmptyModlist:
-+            pass
-+
-     def _install_pkinit_ca_bundle(self):
-         ca_certs = certstore.get_ca_certs(self.api.Backend.ldap2,
-                                           self.api.env.basedn,
--- 
-2.9.4
-
diff --git a/SOURCES/0182-server-upgrade-do-not-enable-PKINIT-by-default.patch b/SOURCES/0182-server-upgrade-do-not-enable-PKINIT-by-default.patch
deleted file mode 100644
index 5d539d4..0000000
--- a/SOURCES/0182-server-upgrade-do-not-enable-PKINIT-by-default.patch
+++ /dev/null
@@ -1,42 +0,0 @@
-From 1ab5b1a4cdcab8b913f42488ae642a9f0ef77d92 Mon Sep 17 00:00:00 2001
-From: Jan Cholasta <jcholast@redhat.com>
-Date: Mon, 5 Jun 2017 12:42:52 +0000
-Subject: [PATCH] server upgrade: do not enable PKINIT by default
-
-Enabling PKINIT often fails during server upgrade when requesting the KDC
-certificate.
-
-Now that PKINIT can be enabled post-install using ipa-pkinit-manage, avoid
-the upgrade failure by not enabling PKINIT by default.
-
-https://pagure.io/freeipa/issue/7000
-
-Reviewed-By: Martin Babinsky <mbabinsk@redhat.com>
----
- ipaserver/install/server/upgrade.py | 10 ++--------
- 1 file changed, 2 insertions(+), 8 deletions(-)
-
-diff --git a/ipaserver/install/server/upgrade.py b/ipaserver/install/server/upgrade.py
-index db86353165809c57d1ac27bf762393721231fefd..b1f59d3e29d69bffc11935ec22d4b5f510293355 100644
---- a/ipaserver/install/server/upgrade.py
-+++ b/ipaserver/install/server/upgrade.py
-@@ -1519,14 +1519,8 @@ def add_default_caacl(ca):
- def setup_pkinit(krb):
-     root_logger.info("[Setup PKINIT]")
- 
--    pkinit_is_enabled = krbinstance.is_pkinit_enabled()
--    ca_is_enabled = api.Command.ca_is_enabled()['result']
--
--    if not pkinit_is_enabled:
--        if ca_is_enabled:
--            krb.issue_ipa_ca_signed_pkinit_certs()
--        else:
--            krb.issue_selfsigned_pkinit_certs()
-+    if not krbinstance.is_pkinit_enabled():
-+        krb.issue_selfsigned_pkinit_certs()
- 
-     aug = Augeas(flags=Augeas.NO_LOAD | Augeas.NO_MODL_AUTOLOAD,
-                  loadpath=paths.USR_SHARE_IPA_DIR)
--- 
-2.9.4
-
diff --git a/SOURCES/0183-Turn-off-OCSP-check.patch b/SOURCES/0183-Turn-off-OCSP-check.patch
deleted file mode 100644
index 6556af5..0000000
--- a/SOURCES/0183-Turn-off-OCSP-check.patch
+++ /dev/null
@@ -1,196 +0,0 @@
-From ea2fc433d3f72364340919345805c667ce0d7524 Mon Sep 17 00:00:00 2001
-From: Pavel Vomacka <pvomacka@redhat.com>
-Date: Thu, 1 Jun 2017 09:56:16 +0200
-Subject: [PATCH] Turn off OCSP check
-
-The OCSP check was previously turned on but it introduced several
-issues. Therefore the check will be turned off by default.
-
-For turning on should be used ipa advise command with correct recipe.
-The solution is tracked here: https://pagure.io/freeipa/issue/6982
-
-Fixes: https://pagure.io/freeipa/issue/6981
-Reviewed-By: Martin Babinsky <mbabinsk@redhat.com>
----
- install/restart_scripts/restart_httpd | 15 +-----------
- ipaserver/install/httpinstance.py     | 43 +++++++++++++++++++----------------
- ipaserver/install/server/upgrade.py   | 25 +++-----------------
- 3 files changed, 28 insertions(+), 55 deletions(-)
-
-diff --git a/install/restart_scripts/restart_httpd b/install/restart_scripts/restart_httpd
-index cd7f12024ea3cab16e9c664687cd854e666c9570..d1684812904a9d32842a0ca548ec6b9df5a5a0b7 100644
---- a/install/restart_scripts/restart_httpd
-+++ b/install/restart_scripts/restart_httpd
-@@ -21,24 +21,11 @@
- 
- import syslog
- import traceback
--from ipalib import api
- from ipaplatform import services
--from ipaplatform.paths import paths
--from ipapython.certdb import TRUSTED_PEER_TRUST_FLAGS
--from ipaserver.install import certs, installutils
-+from ipaserver.install import certs
- 
- 
- def _main():
--
--    api.bootstrap(in_server=True, context='restart', confdir=paths.ETC_IPA)
--    api.finalize()
--
--    db = certs.CertDB(api.env.realm, nssdir=paths.HTTPD_ALIAS_DIR)
--    nickname = installutils.get_directive(paths.HTTPD_NSS_CONF, "NSSNickname")
--
--    # Add trust flag which set certificate trusted for SSL connections.
--    db.trust_root_cert(nickname, TRUSTED_PEER_TRUST_FLAGS)
--
-     syslog.syslog(syslog.LOG_NOTICE, 'certmonger restarted httpd')
- 
-     try:
-diff --git a/ipaserver/install/httpinstance.py b/ipaserver/install/httpinstance.py
-index 12fdddccc26b0c1132bcdca7fe2249a85997892e..f637b97db8f21ddbc00c4f70e18e836d300b2f33 100644
---- a/ipaserver/install/httpinstance.py
-+++ b/ipaserver/install/httpinstance.py
-@@ -34,8 +34,7 @@ from augeas import Augeas
- from ipalib.install import certmonger
- from ipapython import ipaldap
- from ipapython.certdb import (IPA_CA_TRUST_FLAGS,
--                              EXTERNAL_CA_TRUST_FLAGS,
--                              TRUSTED_PEER_TRUST_FLAGS)
-+                              EXTERNAL_CA_TRUST_FLAGS)
- from ipaserver.install import replication
- from ipaserver.install import service
- from ipaserver.install import certs
-@@ -74,6 +73,10 @@ NSS_CIPHER_SUITE = [
- ]
- NSS_CIPHER_REVISION = '20160129'
- 
-+OCSP_DIRECTIVE = 'NSSOCSP'
-+
-+NSS_OCSP_ENABLED = 'nss_ocsp_enabled'
-+
- 
- def httpd_443_configured():
-     """
-@@ -163,7 +166,7 @@ class HTTPInstance(service.Service):
-                   self.set_mod_nss_protocol)
-         self.step("setting mod_nss password file", self.__set_mod_nss_passwordfile)
-         self.step("enabling mod_nss renegotiate", self.enable_mod_nss_renegotiate)
--        self.step("enabling mod_nss OCSP", self.enable_mod_nss_ocsp)
-+        self.step("disabling mod_nss OCSP", self.disable_mod_nss_ocsp)
-         self.step("adding URL rewriting rules", self.__add_include)
-         self.step("configuring httpd", self.__configure_http)
-         self.step("setting up httpd keytab", self.request_service_keytab)
-@@ -270,7 +273,12 @@ class HTTPInstance(service.Service):
-         installutils.set_directive(paths.HTTPD_NSS_CONF, 'NSSRenegotiation', 'on', False)
-         installutils.set_directive(paths.HTTPD_NSS_CONF, 'NSSRequireSafeNegotiation', 'on', False)
- 
--    def enable_mod_nss_ocsp(self):
-+    def disable_mod_nss_ocsp(self):
-+        if sysupgrade.get_upgrade_state('http', NSS_OCSP_ENABLED) is None:
-+            self.__disable_mod_nss_ocsp()
-+            sysupgrade.set_upgrade_state('http', NSS_OCSP_ENABLED, False)
-+
-+    def __disable_mod_nss_ocsp(self):
-         aug = Augeas(flags=Augeas.NO_LOAD | Augeas.NO_MODL_AUTOLOAD)
- 
-         aug.set('/augeas/load/Httpd/lens', 'Httpd.lns')
-@@ -278,22 +286,21 @@ class HTTPInstance(service.Service):
-         aug.load()
- 
-         path = '/files{}/VirtualHost'.format(paths.HTTPD_NSS_CONF)
-+        ocsp_path = '{}/directive[.="{}"]'.format(path, OCSP_DIRECTIVE)
-+        ocsp_arg = '{}/arg'.format(ocsp_path)
-+        ocsp_comment = '{}/#comment[.="{}"]'.format(path, OCSP_DIRECTIVE)
- 
--        ocsp_comment = aug.get(
--                        '{}/#comment[.=~regexp("NSSOCSP .*")]'.format(path))
--        ocsp_dir = aug.get('{}/directive[.="NSSOCSP"]'.format(path))
-+        ocsp_dir = aug.get(ocsp_path)
- 
--        if ocsp_dir is None and ocsp_comment is not None:
--            # Directive is missing, comment is present
--            aug.set('{}/#comment[.=~regexp("NSSOCSP .*")]'.format(path),
--                    'NSSOCSP')
--            aug.rename('{}/#comment[.="NSSOCSP"]'.format(path), 'directive')
--        elif ocsp_dir is None:
--            # Directive is missing and comment is missing
--            aug.set('{}/directive[last()+1]'.format(path), "NSSOCSP")
-+        # there is NSSOCSP directive in nss.conf file, comment it
-+        # otherwise just do nothing
-+        if ocsp_dir is not None:
-+            ocsp_state = aug.get(ocsp_arg)
-+            aug.remove(ocsp_arg)
-+            aug.rename(ocsp_path, '#comment')
-+            aug.set(ocsp_comment, '{} {}'.format(OCSP_DIRECTIVE, ocsp_state))
-+            aug.save()
- 
--        aug.set('{}/directive[. = "NSSOCSP"]/arg'.format(path), 'on')
--        aug.save()
- 
-     def set_mod_nss_cipher_suite(self):
-         ciphers = ','.join(NSS_CIPHER_SUITE)
-@@ -412,8 +419,6 @@ class HTTPInstance(service.Service):
-             self.__set_mod_nss_nickname(nickname)
-             self.add_cert_to_service()
- 
--            db.trust_root_cert(nickname, TRUSTED_PEER_TRUST_FLAGS)
--
-         else:
-             if not self.promote:
-                 ca_args = [
-diff --git a/ipaserver/install/server/upgrade.py b/ipaserver/install/server/upgrade.py
-index b1f59d3e29d69bffc11935ec22d4b5f510293355..732776f2cf513a4bb11d8f3f0dfaac78217e460f 100644
---- a/ipaserver/install/server/upgrade.py
-+++ b/ipaserver/install/server/upgrade.py
-@@ -1395,24 +1395,6 @@ def fix_trust_flags():
-     sysupgrade.set_upgrade_state('http', 'fix_trust_flags', True)
- 
- 
--def fix_server_cert_trust_flags():
--    root_logger.info(
--        '[Fixing server certificate trust flags in %s]' %
--        paths.HTTPD_ALIAS_DIR)
--
--    if sysupgrade.get_upgrade_state('http', 'fix_serv_cert_trust_flags'):
--        root_logger.info("Trust flags already processed")
--        return
--
--    db = certs.CertDB(api.env.realm, nssdir=paths.HTTPD_ALIAS_DIR)
--    sc_nickname = installutils.get_directive(paths.HTTPD_NSS_CONF,
--                                             "NSSNickname")
--    # Add trust flag which set certificate trusted for SSL connections.
--    db.trust_root_cert(sc_nickname, certdb.TRUSTED_PEER_TRUST_FLAGS)
--
--    sysupgrade.set_upgrade_state('http', 'fix_serv_cert_trust_flags', True)
--
--
- def update_mod_nss_protocol(http):
-     root_logger.info('[Updating mod_nss protocol versions]')
- 
-@@ -1425,9 +1407,9 @@ def update_mod_nss_protocol(http):
-     sysupgrade.set_upgrade_state('nss.conf', 'protocol_updated_tls12', True)
- 
- 
--def enable_mod_nss_ocsp(http):
-+def disable_mod_nss_ocsp(http):
-     root_logger.info('[Updating mod_nss enabling OCSP]')
--    http.enable_mod_nss_ocsp()
-+    http.disable_mod_nss_ocsp()
- 
- 
- def update_mod_nss_cipher_suite(http):
-@@ -1721,9 +1703,8 @@ def upgrade_configuration():
-     update_ipa_httpd_service_conf(http)
-     update_mod_nss_protocol(http)
-     update_mod_nss_cipher_suite(http)
--    enable_mod_nss_ocsp(http)
-+    disable_mod_nss_ocsp(http)
-     fix_trust_flags()
--    fix_server_cert_trust_flags()
-     update_http_keytab(http)
-     http.configure_gssproxy()
-     http.start()
--- 
-2.9.4
-
diff --git a/SOURCES/0184-Only-warn-when-specified-server-IP-addresses-don-t-m.patch b/SOURCES/0184-Only-warn-when-specified-server-IP-addresses-don-t-m.patch
deleted file mode 100644
index ae6ebbf..0000000
--- a/SOURCES/0184-Only-warn-when-specified-server-IP-addresses-don-t-m.patch
+++ /dev/null
@@ -1,244 +0,0 @@
-From a04defc43419906675107e483f0f2f3153685c8d Mon Sep 17 00:00:00 2001
-From: Martin Basti <mbasti@redhat.com>
-Date: Wed, 31 May 2017 15:50:05 +0200
-Subject: [PATCH] Only warn when specified server IP addresses don't match intf
-
-In containers local addresses differ from public addresses and we need
-a way to provide only public address to installers.
-
-https://pagure.io/freeipa/issue/2715
-https://pagure.io/freeipa/issue/4317
-
-Reviewed-By: Tomas Krizek <tkrizek@redhat.com>
----
- ipaclient/install/client.py                |  4 +-
- ipalib/install/hostname.py                 |  2 +-
- ipalib/util.py                             | 14 +++++++
- ipapython/ipautil.py                       | 62 ++++++++++++++++--------------
- ipaserver/install/dns.py                   |  1 +
- ipaserver/install/installutils.py          |  4 +-
- ipaserver/install/server/install.py        |  2 +
- ipaserver/install/server/replicainstall.py |  2 +
- 8 files changed, 59 insertions(+), 32 deletions(-)
-
-diff --git a/ipaclient/install/client.py b/ipaclient/install/client.py
-index 6f10f5258747881b9af8c6b70b499f9ff7d577ff..41dae3004d1f4836e79c2048ae0a12f722595ca0 100644
---- a/ipaclient/install/client.py
-+++ b/ipaclient/install/client.py
-@@ -41,6 +41,7 @@ from ipalib.util import (
-     broadcast_ip_address_warning,
-     network_ip_address_warning,
-     normalize_hostname,
-+    no_matching_interface_for_ip_address_warning,
-     verify_host_resolvable,
- )
- from ipaplatform import services
-@@ -1300,6 +1301,7 @@ def update_dns(server, hostname, options):
- 
-     network_ip_address_warning(update_ips)
-     broadcast_ip_address_warning(update_ips)
-+    no_matching_interface_for_ip_address_warning(update_ips)
- 
-     update_txt = "debug\n"
-     update_txt += ipautil.template_str(DELETE_TEMPLATE_A,
-@@ -1445,7 +1447,7 @@ def check_ip_addresses(options):
-     if options.ip_addresses:
-         for ip in options.ip_addresses:
-             try:
--                ipautil.CheckedIPAddress(ip, match_local=True)
-+                ipautil.CheckedIPAddress(ip)
-             except ValueError as e:
-                 root_logger.error(e)
-                 return False
-diff --git a/ipalib/install/hostname.py b/ipalib/install/hostname.py
-index 74c569d972df9975d677762b5769b2bf84dfddf0..5422ba6390ce13aa40f34938ed777d8821e8231b 100644
---- a/ipalib/install/hostname.py
-+++ b/ipalib/install/hostname.py
-@@ -34,7 +34,7 @@ class HostNameInstallInterface(service.ServiceInstallInterface):
-     def ip_addresses(self, values):
-         for value in values:
-             try:
--                CheckedIPAddress(value, match_local=True)
-+                CheckedIPAddress(value)
-             except Exception as e:
-                 raise ValueError("invalid IP address {0}: {1}".format(
-                     value, e))
-diff --git a/ipalib/util.py b/ipalib/util.py
-index 713fc107e9374eefe7805bc4e1abc40b6d150c32..1bd8495a49b010e7a3ac926dad516ab5f8219b39 100644
---- a/ipalib/util.py
-+++ b/ipalib/util.py
-@@ -1128,3 +1128,17 @@ def broadcast_ip_address_warning(addr_list):
-             # print
-             print("WARNING: IP address {} might be broadcast address".format(
-                 ip), file=sys.stderr)
-+
-+
-+def no_matching_interface_for_ip_address_warning(addr_list):
-+    for ip in addr_list:
-+        if not ip.get_matching_interface():
-+            root_logger.warning(
-+                "No network interface matches the IP address %s", ip)
-+            # fixme: once when loggers will be fixed, we can remove this
-+            # print
-+            print(
-+                "WARNING: No network interface matches the IP address "
-+                "{}".format(ip),
-+                file=sys.stderr
-+            )
-diff --git a/ipapython/ipautil.py b/ipapython/ipautil.py
-index 317fc225b722ad3ce2f4b9d92822b4f19d49adb9..a277ed87473f3c591f34fcc00e1159f3bbfe3e9b 100644
---- a/ipapython/ipautil.py
-+++ b/ipapython/ipautil.py
-@@ -161,34 +161,7 @@ class CheckedIPAddress(UnsafeIPAddress):
-             raise ValueError("cannot use multicast IP address {}".format(addr))
- 
-         if match_local:
--            if self.version == 4:
--                family = netifaces.AF_INET
--            elif self.version == 6:
--                family = netifaces.AF_INET6
--            else:
--                raise ValueError(
--                    "Unsupported address family ({})".format(self.version)
--                )
--
--            iface = None
--            for interface in netifaces.interfaces():
--                for ifdata in netifaces.ifaddresses(interface).get(family, []):
--
--                    # link-local addresses contain '%suffix' that causes parse
--                    # errors in IPNetwork
--                    ifaddr = ifdata['addr'].split(u'%', 1)[0]
--
--                    ifnet = netaddr.IPNetwork('{addr}/{netmask}'.format(
--                        addr=ifaddr,
--                        netmask=ifdata['netmask']
--                    ))
--                    if ifnet == self._net or (
--                            self._net is None and ifnet.ip == self):
--                        self._net = ifnet
--                        iface = interface
--                        break
--
--            if iface is None:
-+            if not self.get_matching_interface():
-                 raise ValueError('no network interface matches the IP address '
-                                  'and netmask {}'.format(addr))
- 
-@@ -218,6 +191,39 @@ class CheckedIPAddress(UnsafeIPAddress):
-     def is_broadcast_addr(self):
-         return self.version == 4 and self == self._net.broadcast
- 
-+    def get_matching_interface(self):
-+        """Find matching local interface for address
-+        :return: Interface name or None if no interface has this address
-+        """
-+        if self.version == 4:
-+            family = netifaces.AF_INET
-+        elif self.version == 6:
-+            family = netifaces.AF_INET6
-+        else:
-+            raise ValueError(
-+                "Unsupported address family ({})".format(self.version)
-+            )
-+
-+        iface = None
-+        for interface in netifaces.interfaces():
-+            for ifdata in netifaces.ifaddresses(interface).get(family, []):
-+
-+                # link-local addresses contain '%suffix' that causes parse
-+                # errors in IPNetwork
-+                ifaddr = ifdata['addr'].split(u'%', 1)[0]
-+
-+                ifnet = netaddr.IPNetwork('{addr}/{netmask}'.format(
-+                    addr=ifaddr,
-+                    netmask=ifdata['netmask']
-+                ))
-+                if ifnet == self._net or (
-+                                self._net is None and ifnet.ip == self):
-+                    self._net = ifnet
-+                    iface = interface
-+                    break
-+
-+        return iface
-+
- 
- def valid_ip(addr):
-     return netaddr.valid_ipv4(addr) or netaddr.valid_ipv6(addr)
-diff --git a/ipaserver/install/dns.py b/ipaserver/install/dns.py
-index 0dddf2a6427f3f939171d755bfe2b1f05cfafa67..090b79493652566a433da248fa7fd9e33dd2cb72 100644
---- a/ipaserver/install/dns.py
-+++ b/ipaserver/install/dns.py
-@@ -266,6 +266,7 @@ def install_check(standalone, api, replica, options, hostname):
- 
-     util.network_ip_address_warning(ip_addresses)
-     util.broadcast_ip_address_warning(ip_addresses)
-+    util.no_matching_interface_for_ip_address_warning(ip_addresses)
- 
-     if not options.forward_policy:
-         # user did not specify policy, derive it: default is 'first' but
-diff --git a/ipaserver/install/installutils.py b/ipaserver/install/installutils.py
-index d2283af20485fd5d66bfd3cc49059d08d1802575..3521d555914714351160213df60ed9167ac6e370 100644
---- a/ipaserver/install/installutils.py
-+++ b/ipaserver/install/installutils.py
-@@ -276,7 +276,7 @@ def read_ip_addresses():
-         if not ip:
-             break
-         try:
--            ip_parsed = ipautil.CheckedIPAddress(ip, match_local=True)
-+            ip_parsed = ipautil.CheckedIPAddress(ip)
-         except Exception as e:
-             print("Error: Invalid IP Address %s: %s" % (ip, e))
-             continue
-@@ -585,7 +585,7 @@ def get_server_ip_address(host_name, unattended, setup_dns, ip_addresses):
-     if len(hostaddr):
-         for ha in hostaddr:
-             try:
--                ips.append(ipautil.CheckedIPAddress(ha, match_local=True))
-+                ips.append(ipautil.CheckedIPAddress(ha, match_local=False))
-             except ValueError as e:
-                 root_logger.warning("Invalid IP address %s for %s: %s", ha, host_name, unicode(e))
- 
-diff --git a/ipaserver/install/server/install.py b/ipaserver/install/server/install.py
-index 9dcf903f4582740f007c049fae3ec247ddf52aef..7eb291e07c00e0407ce534c3d4088e6f6378260f 100644
---- a/ipaserver/install/server/install.py
-+++ b/ipaserver/install/server/install.py
-@@ -29,6 +29,7 @@ from ipalib.util import (
-     validate_domain_name,
-     network_ip_address_warning,
-     broadcast_ip_address_warning,
-+    no_matching_interface_for_ip_address_warning,
- )
- import ipaclient.install.ntpconf
- from ipaserver.install import (
-@@ -617,6 +618,7 @@ def install_check(installer):
-         # check addresses here, dns module is doing own check
-         network_ip_address_warning(ip_addresses)
-         broadcast_ip_address_warning(ip_addresses)
-+        no_matching_interface_for_ip_address_warning(ip_addresses)
- 
-     if options.setup_adtrust:
-         adtrust.install_check(False, options, api)
-diff --git a/ipaserver/install/server/replicainstall.py b/ipaserver/install/server/replicainstall.py
-index 20eaf98397101b49c751c325afc0591e0babcc18..6620f0222f9d38112ce0d0fd72381e5673921cba 100644
---- a/ipaserver/install/server/replicainstall.py
-+++ b/ipaserver/install/server/replicainstall.py
-@@ -35,6 +35,7 @@ from ipalib.config import Env
- from ipalib.util import (
-     network_ip_address_warning,
-     broadcast_ip_address_warning,
-+    no_matching_interface_for_ip_address_warning,
- )
- from ipaclient.install.client import configure_krb5_conf, purge_host_keytab
- from ipaserver.install import (
-@@ -1285,6 +1286,7 @@ def promote_check(installer):
-             # check addresses here, dns module is doing own check
-             network_ip_address_warning(config.ips)
-             broadcast_ip_address_warning(config.ips)
-+            no_matching_interface_for_ip_address_warning(config.ips)
- 
-         if options.setup_adtrust:
-             adtrust.install_check(False, options, remote_api)
--- 
-2.9.4
-
diff --git a/SOURCES/0185-ipa-kdb-use-canonical-principal-in-certauth-plugin.patch b/SOURCES/0185-ipa-kdb-use-canonical-principal-in-certauth-plugin.patch
deleted file mode 100644
index 4fa3e14..0000000
--- a/SOURCES/0185-ipa-kdb-use-canonical-principal-in-certauth-plugin.patch
+++ /dev/null
@@ -1,33 +0,0 @@
-From 25033eb499af95f458bd975eddd954c4b6a086ff Mon Sep 17 00:00:00 2001
-From: Sumit Bose <sbose@redhat.com>
-Date: Thu, 1 Jun 2017 18:17:53 +0200
-Subject: [PATCH] ipa-kdb: use canonical principal in certauth plugin
-
-Currently the certauth plugin use the unmodified principal from the
-request to lookup the user. This might fail if e.g. enterprise
-principals are use. With this patch the canonical principal form the kdc
-entry is used.
-
-Resolves https://pagure.io/freeipa/issue/6993
-
-Reviewed-By: David Kupka <dkupka@redhat.com>
----
- daemons/ipa-kdb/ipa_kdb_certauth.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/daemons/ipa-kdb/ipa_kdb_certauth.c b/daemons/ipa-kdb/ipa_kdb_certauth.c
-index da9a9cb87feca68ee591da70a3239dc86749bae5..66c2d08cbb9d23a8891b9cb6ca238925530eb40c 100644
---- a/daemons/ipa-kdb/ipa_kdb_certauth.c
-+++ b/daemons/ipa-kdb/ipa_kdb_certauth.c
-@@ -284,7 +284,7 @@ static krb5_error_code ipa_certauth_authorize(krb5_context context,
-         }
-     }
- 
--    ret = krb5_unparse_name(context, princ, &principal);
-+    ret = krb5_unparse_name(context, db_entry->princ, &principal);
-     if (ret != 0) {
-         ret = KRB5KDC_ERR_CERTIFICATE_MISMATCH;
-         goto done;
--- 
-2.9.4
-
diff --git a/SOURCES/0186-Bump-version-of-python-gssapi.patch b/SOURCES/0186-Bump-version-of-python-gssapi.patch
deleted file mode 100644
index 546067e..0000000
--- a/SOURCES/0186-Bump-version-of-python-gssapi.patch
+++ /dev/null
@@ -1,66 +0,0 @@
-From b117507de5cc68282b156a8e4751ef2cb5db74a9 Mon Sep 17 00:00:00 2001
-From: Pavel Vomacka <pvomacka@redhat.com>
-Date: Wed, 7 Jun 2017 10:11:39 +0200
-Subject: [PATCH] Bump version of python-gssapi
-
-Complete fixing of the bug requires fix on python-gssapi side.
-That fix is included in version 1.2.0-5.
-
-Fixes: https://pagure.io/freeipa/issue/6796
-Reviewed-By: Martin Basti <mbasti@redhat.com>
----
- freeipa.spec.in | 10 +++++-----
- 1 file changed, 5 insertions(+), 5 deletions(-)
-
-diff --git a/freeipa.spec.in b/freeipa.spec.in
-index ae77a9a23645c1490c32195203e2c4f665783a80..d7f8d11ec553cfe299937e1e5f8cc27caed32b08 100644
---- a/freeipa.spec.in
-+++ b/freeipa.spec.in
-@@ -165,7 +165,7 @@ BuildRequires:  python3-wheel
- BuildRequires:  samba-python
- # 1.4: the version where Certificate.serial changed to .serial_number
- BuildRequires:  python2-cryptography >= 1.4
--BuildRequires:  python-gssapi >= 1.2.0
-+BuildRequires:  python-gssapi >= 1.2.0-5
- BuildRequires:  pylint >= 1.6
- # workaround for https://bugzilla.redhat.com/show_bug.cgi?id=1096506
- BuildRequires:  python2-polib
-@@ -282,7 +282,7 @@ Requires: mod_session
- # 0.9.9: https://github.com/adelton/mod_lookup_identity/pull/3
- Requires: mod_lookup_identity >= 0.9.9
- Requires: python-ldap >= 2.4.15
--Requires: python-gssapi >= 1.2.0
-+Requires: python-gssapi >= 1.2.0-5
- Requires: acl
- Requires: systemd-units >= 38
- Requires(pre): shadow-utils
-@@ -349,7 +349,7 @@ Requires: python2-ipaclient = %{version}-%{release}
- Requires: python-custodia >= 0.3.1
- Requires: python-ldap >= 2.4.15
- Requires: python-lxml
--Requires: python-gssapi >= 1.2.0
-+Requires: python-gssapi >= 1.2.0-5
- Requires: python-sssdconfig
- Requires: python-pyasn1
- Requires: dbus-python
-@@ -502,7 +502,7 @@ Requires: certmonger >= 0.78
- Requires: nss-tools
- Requires: bind-utils
- Requires: oddjob-mkhomedir
--Requires: python-gssapi >= 1.2.0
-+Requires: python-gssapi >= 1.2.0-5
- Requires: libsss_autofs
- Requires: autofs
- Requires: libnfsidmap
-@@ -639,7 +639,7 @@ Provides: python2-ipaplatform = %{version}-%{release}
- %{?python_provide:%python_provide python2-ipaplatform}
- %{!?python_provide:Provides: python-ipaplatform = %{version}-%{release}}
- Requires: %{name}-common = %{version}-%{release}
--Requires: python-gssapi >= 1.2.0
-+Requires: python-gssapi >= 1.2.0-5
- Requires: gnupg
- Requires: keyutils
- Requires: pyOpenSSL
--- 
-2.9.4
-
diff --git a/SOURCES/0187-Add-code-to-be-able-to-set-default-kinit-lifetime.patch b/SOURCES/0187-Add-code-to-be-able-to-set-default-kinit-lifetime.patch
deleted file mode 100644
index 438cf23..0000000
--- a/SOURCES/0187-Add-code-to-be-able-to-set-default-kinit-lifetime.patch
+++ /dev/null
@@ -1,84 +0,0 @@
-From 1e37dbe2c41ff0339873cd2347cb90c39a59d8ed Mon Sep 17 00:00:00 2001
-From: Simo Sorce <simo@redhat.com>
-Date: Mon, 5 Jun 2017 09:50:22 -0400
-Subject: [PATCH] Add code to be able to set default kinit lifetime
-
-This is done by setting the kinit_lifetime option in default.conf
-to a value that can be passed in with the -l option syntax of kinit.
-
-https://pagure.io/freeipa/issue/7001
-
-Signed-off-by: Simo Sorce <simo@redhat.com>
-Reviewed-By: Pavel Vomacka <pvomacka@redhat.com>
-Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
----
- ipalib/constants.py     | 1 +
- ipalib/install/kinit.py | 5 ++++-
- ipaserver/rpcserver.py  | 3 ++-
- pylint_plugins.py       | 1 +
- 4 files changed, 8 insertions(+), 2 deletions(-)
-
-diff --git a/ipalib/constants.py b/ipalib/constants.py
-index f8a194c1f559db9aeffef058578d700cde41fd0b..5adff97fbd6ad8ab4cfa5322481be2d9056f925a 100644
---- a/ipalib/constants.py
-+++ b/ipalib/constants.py
-@@ -153,6 +153,7 @@ DEFAULT_CONFIG = (
-     ('session_auth_duration', '20 minutes'),
-     # How a session expiration is computed, see SessionManager.set_session_expiration_time()
-     ('session_duration_type', 'inactivity_timeout'),
-+    ('kinit_lifetime', None),
- 
-     # Debugging:
-     ('verbose', 0),
-diff --git a/ipalib/install/kinit.py b/ipalib/install/kinit.py
-index 73471f103eabfe39580c8fbd0665157f635fa5c5..91ea5132aa1cb1e192af46b4896d55670e375f7a 100644
---- a/ipalib/install/kinit.py
-+++ b/ipalib/install/kinit.py
-@@ -63,7 +63,7 @@ def kinit_keytab(principal, keytab, ccache_name, config=None, attempts=1):
- 
- def kinit_password(principal, password, ccache_name, config=None,
-                    armor_ccache_name=None, canonicalize=False,
--                   enterprise=False):
-+                   enterprise=False, lifetime=None):
-     """
-     perform interactive kinit as principal using password. If using FAST for
-     web-based authentication, use armor_ccache_path to specify http service
-@@ -76,6 +76,9 @@ def kinit_password(principal, password, ccache_name, config=None,
-                           % armor_ccache_name)
-         args.extend(['-T', armor_ccache_name])
- 
-+    if lifetime:
-+        args.extend(['-l', lifetime])
-+
-     if canonicalize:
-         root_logger.debug("Requesting principal canonicalization")
-         args.append('-C')
-diff --git a/ipaserver/rpcserver.py b/ipaserver/rpcserver.py
-index 32f286148bbdf294f941116b4bdca85714a52837..2990df25985eab63d4bcfc8edf7f2b12da3e9832 100644
---- a/ipaserver/rpcserver.py
-+++ b/ipaserver/rpcserver.py
-@@ -969,7 +969,8 @@ class login_password(Backend, KerberosSession):
-                 password,
-                 ccache_name,
-                 armor_ccache_name=armor_path,
--                enterprise=True)
-+                enterprise=True,
-+                lifetime=self.api.env.kinit_lifetime)
- 
-             if armor_path:
-                 self.debug('Cleanup the armor ccache')
-diff --git a/pylint_plugins.py b/pylint_plugins.py
-index db80efeba8824eb221d988bb494400da173675a9..550f269b308b6c5b21cb13404040aa0934381f0e 100644
---- a/pylint_plugins.py
-+++ b/pylint_plugins.py
-@@ -67,6 +67,7 @@ fake_api_env = {'env': [
-     'realm',
-     'session_auth_duration',
-     'session_duration_type',
-+    'kinit_lifetime',
- ]}
- 
- # this is due ipaserver.rpcserver.KerberosSession where api is undefined
--- 
-2.9.4
-
diff --git a/SOURCES/0188-Revert-setting-sessionMaxAge-for-old-clients.patch b/SOURCES/0188-Revert-setting-sessionMaxAge-for-old-clients.patch
deleted file mode 100644
index 4f69baa..0000000
--- a/SOURCES/0188-Revert-setting-sessionMaxAge-for-old-clients.patch
+++ /dev/null
@@ -1,44 +0,0 @@
-From f231d5ceb283723c42f6c15210c76f28324c2e15 Mon Sep 17 00:00:00 2001
-From: Simo Sorce <simo@redhat.com>
-Date: Tue, 6 Jun 2017 09:04:58 -0400
-Subject: [PATCH] Revert setting sessionMaxAge for old clients
-
-Older clients have issues properly parsing cookies and the sessionMaxAge
-setting is one of those that breaks them.
-Comment out the setting and add a comment that explains why it is not
-set by default.
-
-https://pagure.io/freeipa/issue/7001
-
-Signed-off-by: Simo Sorce <simo@redhat.com>
-Reviewed-By: Pavel Vomacka <pvomacka@redhat.com>
-Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
----
- install/conf/ipa.conf | 6 ++++--
- 1 file changed, 4 insertions(+), 2 deletions(-)
-
-diff --git a/install/conf/ipa.conf b/install/conf/ipa.conf
-index a7ca5ce715e55960b8edd307cdbe41dcbd6b29ca..01bf9a4f97fc0cf197c0ad12743affa597b54911 100644
---- a/install/conf/ipa.conf
-+++ b/install/conf/ipa.conf
-@@ -1,5 +1,5 @@
- #
--# VERSION 26 - DO NOT REMOVE THIS LINE
-+# VERSION 27 - DO NOT REMOVE THIS LINE
- #
- # This file may be overwritten on upgrades.
- #
-@@ -77,7 +77,9 @@ WSGIScriptReloading Off
-   Session On
-   SessionCookieName ipa_session path=/ipa;httponly;secure;
-   SessionHeader IPASESSION
--  SessionMaxAge 1800
-+  # Uncomment the following to have shorter sessions, but beware this may break
-+  # old IPA client tols that incorrectly parse cookies.
-+  # SessionMaxAge 1800
-   GssapiSessionKey file:/etc/httpd/alias/ipasession.key
- 
-   GssapiImpersonate On
--- 
-2.9.4
-
diff --git a/SOURCES/0189-Extend-the-advice-printing-code-by-some-useful-abstr.patch b/SOURCES/0189-Extend-the-advice-printing-code-by-some-useful-abstr.patch
deleted file mode 100644
index 71fe9f8..0000000
--- a/SOURCES/0189-Extend-the-advice-printing-code-by-some-useful-abstr.patch
+++ /dev/null
@@ -1,93 +0,0 @@
-From 17f988f0524ff682a95fe6a4be55b49ea7a0a419 Mon Sep 17 00:00:00 2001
-From: Martin Babinsky <mbabinsk@redhat.com>
-Date: Mon, 5 Jun 2017 16:59:25 +0200
-Subject: [PATCH] Extend the advice printing code by some useful abstractions
-
-The advise printing code was augmented by methods that simplify
-generating bash snippets that report errors or failed commands.
-
-https://pagure.io/freeipa/issue/6982
-
-Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
-Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
----
- ipaserver/advise/base.py | 63 ++++++++++++++++++++++++++++++++++++++++++++++--
- 1 file changed, 61 insertions(+), 2 deletions(-)
-
-diff --git a/ipaserver/advise/base.py b/ipaserver/advise/base.py
-index 40dabd0426719c5a791fee5be81a998e1c45854b..ba412b872472580cd32baf2a326a14edb951cab1 100644
---- a/ipaserver/advise/base.py
-+++ b/ipaserver/advise/base.py
-@@ -94,8 +94,67 @@ class _AdviceOutput(object):
-         if self.options.verbose:
-             self.comment('DEBUG: ' + line)
- 
--    def command(self, line):
--        self.content.append(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 echo_error(self, error_message, indent_spaces=0):
-+        self.command(
-+            self._format_error(error_message), indent_spaces=indent_spaces)
-+
-+    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)
-+        self.exit_on_predicate(
-+            '[ "$?" -ne "0" ]',
-+            error_message_lines,
-+            indent_spaces=indent_spaces)
-+
-+    def exit_on_nonroot_euid(self):
-+        self.exit_on_predicate(
-+            '[ "$(id -u)" -ne "0" ]',
-+            ["This script has to be run as root user"]
-+        )
-+
-+    def exit_on_predicate(self, predicate, error_message_lines,
-+                          indent_spaces=0):
-+        commands_to_run = [
-+            self._format_error(error_message_line)
-+            for error_message_line in error_message_lines]
-+
-+        commands_to_run.append('exit 1')
-+        self.commands_on_predicate(
-+            predicate,
-+            commands_to_run,
-+            indent_spaces=indent_spaces)
-+
-+    def commands_on_predicate(self, predicate, commands_to_run_when_true,
-+                              commands_to_run_when_false=None,
-+                              indent_spaces=0):
-+        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
-+
-+        for command_to_run_when_true in commands_to_run_when_true:
-+            self.command(
-+                command_to_run_when_true, indent_spaces=indented_block_spaces)
-+
-+        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('fi', indent_spaces=indent_spaces)
- 
- 
- class Advice(Plugin):
--- 
-2.9.4
-
diff --git a/SOURCES/0190-Prepare-advise-plugin-for-smart-card-auth-configurat.patch b/SOURCES/0190-Prepare-advise-plugin-for-smart-card-auth-configurat.patch
deleted file mode 100644
index b17a1e6..0000000
--- a/SOURCES/0190-Prepare-advise-plugin-for-smart-card-auth-configurat.patch
+++ /dev/null
@@ -1,293 +0,0 @@
-From f16d9533c7917a8a57a9148dee61df3b12a5e767 Mon Sep 17 00:00:00 2001
-From: Martin Babinsky <mbabinsk@redhat.com>
-Date: Fri, 2 Jun 2017 18:36:29 +0200
-Subject: [PATCH] Prepare advise plugin for smart card auth configuration
-
-The plugin contains recipes for configuring Smart Card authentication
-on FreeIPA server and enrolled client.
-
-https://www.freeipa.org/page/V4/Smartcard_authentication_ipa-advise_recipes
-https://pagure.io/freeipa/issue/6982
-
-Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
-Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
----
- ipaserver/advise/plugins/smart_card_auth.py | 266 ++++++++++++++++++++++++++++
- 1 file changed, 266 insertions(+)
- create mode 100644 ipaserver/advise/plugins/smart_card_auth.py
-
-diff --git a/ipaserver/advise/plugins/smart_card_auth.py b/ipaserver/advise/plugins/smart_card_auth.py
-new file mode 100644
-index 0000000000000000000000000000000000000000..5859e350939fdba0a8b258de5285dd10c7b3bc23
---- /dev/null
-+++ b/ipaserver/advise/plugins/smart_card_auth.py
-@@ -0,0 +1,266 @@
-+#
-+# Copyright (C) 2017 FreeIPA Contributors see COPYING for license
-+#
-+
-+from ipalib.plugable import Registry
-+from ipaplatform.paths import paths
-+from ipaserver.advise.base import Advice
-+from ipaserver.install.httpinstance import NSS_OCSP_ENABLED
-+
-+register = Registry()
-+
-+
-+@register()
-+class config_server_for_smart_card_auth(Advice):
-+    """
-+    Configures smart card authentication via Kerberos (PKINIT) and for WebUI
-+    """
-+
-+    description = ("Instructions for enabling Smart Card authentication on "
-+                   " a single FreeIPA server. Includes Apache configuration, "
-+                   "enabling PKINIT on KDC and configuring WebUI to accept "
-+                   "Smart Card auth requests. To enable the feature in the "
-+                   "whole topology you have to run the script on each master")
-+
-+    nss_conf = paths.HTTPD_NSS_CONF
-+    nss_ocsp_directive = 'NSSOCSP'
-+    nss_nickname_directive = 'NSSNickname'
-+
-+    def get_info(self):
-+        self.log.exit_on_nonroot_euid()
-+        self.check_ccache_not_empty()
-+        self.check_hostname_is_in_masters()
-+        self.resolve_ipaca_records()
-+        self.enable_nss_ocsp()
-+        self.mark_httpd_cert_as_trusted()
-+        self.restart_httpd()
-+        self.record_httpd_ocsp_status()
-+        self.check_and_enable_pkinit()
-+        self.enable_ok_to_auth_as_delegate_on_http_principal()
-+
-+    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_hostname_is_in_masters(self):
-+        self.log.comment('Check whether the host is IPA master')
-+        self.log.exit_on_failed_command(
-+            'ipa server-find $(hostname -f)',
-+            ["This script can be run on IPA master only"])
-+
-+    def resolve_ipaca_records(self):
-+        ipa_domain_name = self.api.env.domain
-+
-+        self.log.comment('make sure bind-utils are installed so that we can '
-+                         'dig for ipa-ca records')
-+        self.log.exit_on_failed_command(
-+            'yum install -y bind-utils',
-+            ['Failed to install bind-utils'])
-+
-+        self.log.comment('make sure ipa-ca records are resolvable, '
-+                         'otherwise error out and instruct')
-+        self.log.comment('the user to update the DNS infrastructure')
-+        self.log.command('ipaca_records=$(dig +short '
-+                         'ipa-ca.{})'.format(ipa_domain_name))
-+
-+        self.log.exit_on_predicate(
-+            '[ -z "$ipaca_records" ]',
-+            [
-+                'Can not resolve ipa-ca records for ${domain_name}',
-+                'Please make sure to update your DNS infrastructure with ',
-+                'ipa-ca record pointing to IP addresses of IPA CA masters'
-+            ])
-+
-+    def enable_nss_ocsp(self):
-+        self.log.comment('look for the OCSP directive in nss.conf')
-+        self.log.comment(' if it is present, switch it on')
-+        self.log.comment(
-+            'if it is absent, append it to the end of VirtualHost section')
-+        predicate = self._interpolate_ocsp_directive_file_into_command(
-+            "grep -q '{directive} ' {filename}")
-+
-+        self.log.commands_on_predicate(
-+            predicate,
-+            [
-+                self._interpolate_ocsp_directive_file_into_command(
-+                    "  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' "
-+                    "{filename}")
-+            ]
-+        )
-+
-+    def _interpolate_ocsp_directive_file_into_command(self, fmt_line):
-+        return self._format_command(
-+            fmt_line, self.nss_ocsp_directive, self.nss_conf)
-+
-+    def _format_command(self, fmt_line, directive, filename):
-+        return fmt_line.format(directive=directive, filename=filename)
-+
-+    def mark_httpd_cert_as_trusted(self):
-+        self.log.comment(
-+            'mark the HTTP certificate as trusted peer to avoid '
-+            'chicken-egg startup issue')
-+        self.log.command(
-+            self._interpolate_nssnickname_directive_file_into_command(
-+                "http_cert_nick=$(grep '{directive}' {filename} |"
-+                " 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),
-+            ['Can not set trust flags on HTTP certificate'])
-+
-+    def _interpolate_nssnickname_directive_file_into_command(self, fmt_line):
-+        return self._format_command(
-+            fmt_line, self.nss_nickname_directive, self.nss_conf)
-+
-+    def restart_httpd(self):
-+        self.log.comment('finally restart apache')
-+        self.log.command('systemctl restart httpd')
-+
-+    def record_httpd_ocsp_status(self):
-+        self.log.comment('store the OCSP upgrade state')
-+        self.log.command(
-+            "python -c 'from ipaserver.install import sysupgrade; "
-+            "sysupgrade.set_upgrade_state(\"httpd\", "
-+            "\"{}\", True)'".format(NSS_OCSP_ENABLED))
-+
-+    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'],
-+            indent_spaces=2)
-+        self.log.command('fi')
-+
-+    def enable_ok_to_auth_as_delegate_on_http_principal(self):
-+        self.log.comment('Enable OK-AS-DELEGATE flag on the HTTP principal')
-+        self.log.comment('This enables smart card login to WebUI')
-+        self.log.command(
-+            'output=$(ipa service-mod HTTP/$(hostname -f) '
-+            '--ok-to-auth-as-delegate=True 2>&1)')
-+        self.log.exit_on_predicate(
-+            '[ "$?" -ne "0" -a '
-+            '-z "$(echo $output | grep \'no modifications\')" ]',
-+            ["Failed to set OK_AS_AUTH_AS_DELEGATE flag on HTTP principal"]
-+        )
-+
-+
-+@register()
-+class config_client_for_smart_card_auth(Advice):
-+    """
-+    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, "
-+                   "set the system-wide trust store and configures SSSD to "
-+                   "allow smart card logins to desktop")
-+
-+    opensc_module_name = "OpenSC"
-+    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_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.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(
-+            '[ "$?" -eq "0" ]',
-+            [
-+                'yum remove -y pam_pkcs11'
-+            ]
-+        )
-+
-+    def install_opensc_and_dconf_packages(self):
-+        self.log.comment(
-+            'authconfig often complains about missing dconf, '
-+            'install it explicitly')
-+        self.log.exit_on_failed_command(
-+            'yum install -y {} dconf'.format(self.opensc_module_name.lower()),
-+            ['Could not install OpenSC package']
-+        )
-+
-+    def start_enable_smartcard_daemon(self):
-+        self.log.command(
-+            'systemctl start {service} {socket} '
-+            '&& systemctl enable {service} {socket}'.format(
-+                service=self.smart_card_service_file,
-+                socket=self.smart_card_socket))
-+
-+    def add_pkcs11_module_to_systemwide_db(self):
-+        module_name = self.opensc_module_name
-+        nssdb = self.systemwide_nssdb
-+        shared_lib = self.pkcs11_shared_lib
-+
-+        self.log.commands_on_predicate(
-+            'modutil -dbdir {} -list | grep -q {}'.format(
-+                nssdb, module_name),
-+            [
-+                'echo "{} PKCS#11 module already configured"'.format(
-+                    module_name)
-+            ],
-+            commands_to_run_when_false=[
-+                'echo "" | modutil -dbdir {} -add "{}" -libfile {}'.format(
-+                    nssdb, module_name, shared_lib),
-+            ]
-+        )
-+
-+    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',
-+            [
-+                'Failed to configure Smart Card authentication in SSSD'
-+            ]
-+        )
-+
-+    def restart_sssd(self):
-+        self.log.command('systemctl restart sssd.service')
--- 
-2.9.4
-
diff --git a/SOURCES/0191-trust-mod-allow-modifying-list-of-UPNs-of-a-trusted-.patch b/SOURCES/0191-trust-mod-allow-modifying-list-of-UPNs-of-a-trusted-.patch
deleted file mode 100644
index 80a1388..0000000
--- a/SOURCES/0191-trust-mod-allow-modifying-list-of-UPNs-of-a-trusted-.patch
+++ /dev/null
@@ -1,93 +0,0 @@
-From 4df20255c1738526696ea72af6fc70e9c6aa6694 Mon Sep 17 00:00:00 2001
-From: Alexander Bokovoy <abokovoy@redhat.com>
-Date: Mon, 12 Jun 2017 11:05:06 +0300
-Subject: [PATCH] trust-mod: allow modifying list of UPNs of a trusted forest
-
-There are two ways for maintaining user principal names (UPNs) in Active
-Directory:
- - associate UPN suffixes with the forest root and then allow for each
-   user account to choose UPN suffix for logon
- - directly modify userPrincipalName attribute in LDAP
-
-Both approaches lead to the same result: AD DC accepts user@UPN-Suffix
-as a proper principal in AS-REQ and TGS-REQ.
-
-The latter (directly modify userPrincipalName) case has a consequence
-that this UPN suffix is not visible via netr_DsRGetForestTrustInformation
-DCE RPC call. As result, FreeIPA KDC will not know that a particular UPN
-suffix does belong to a trusted Active Directory forest. As result, SSSD
-will not be able to authenticate and validate this user from a trusted
-Active Directory forest.
-
-This is especially true for one-word UPNs which otherwise wouldn't work
-properly on Kerberos level for both FreeIPA and Active Directory.
-
-Administrators are responsible for amending the list of UPNs associated
-with the forest in this case. With this commit, an option is added to
-'ipa trust-mod' that allows specifying arbitrary UPN suffixes to a
-trusted forest root.
-
-As with all '-mod' commands, the change replaces existing UPNs when
-applied, so administrators are responsible to specify all of them:
-
-  ipa trust-mod ad.test --upn-suffixes={existing.upn,another_upn,new}
-
-Fixes: https://pagure.io/freeipa/issue/7015
-Reviewed-By: Martin Babinsky <mbabinsk@redhat.com>
----
- API.txt                    | 3 ++-
- VERSION.m4                 | 4 ++--
- ipaserver/plugins/trust.py | 3 ++-
- 3 files changed, 6 insertions(+), 4 deletions(-)
-
-diff --git a/API.txt b/API.txt
-index 6511ad8d1cb4dc9079628fc058312f31aaec624d..86229156adfba829a46b6a831ad6843cc1a17d6a 100644
---- a/API.txt
-+++ b/API.txt
-@@ -5769,11 +5769,12 @@ output: ListOfEntries('result')
- output: Output('summary', type=[<type 'unicode'>, <type 'NoneType'>])
- output: Output('truncated', type=[<type 'bool'>])
- command: trust_mod/1
--args: 1,9,3
-+args: 1,10,3
- arg: Str('cn', cli_name='realm')
- option: Str('addattr*', cli_name='addattr')
- option: Flag('all', autofill=True, cli_name='all', default=False)
- option: Str('delattr*', cli_name='delattr')
-+option: Str('ipantadditionalsuffixes*', autofill=False, cli_name='upn_suffixes')
- option: Str('ipantsidblacklistincoming*', autofill=False, cli_name='sid_blacklist_incoming')
- option: Str('ipantsidblacklistoutgoing*', autofill=False, cli_name='sid_blacklist_outgoing')
- option: Flag('raw', autofill=True, cli_name='raw', default=False)
-diff --git a/VERSION.m4 b/VERSION.m4
-index 8aa3ef03f352cd176579c5d5848ed9550f22105d..25aaa1dd0e3c2868e63300dec7fe9228f1ebcb43 100644
---- a/VERSION.m4
-+++ b/VERSION.m4
-@@ -73,8 +73,8 @@ define(IPA_DATA_VERSION, 20100614120000)
- #                                                      #
- ########################################################
- define(IPA_API_VERSION_MAJOR, 2)
--define(IPA_API_VERSION_MINOR, 227)
--# Last change: Add `pkinit-status` command
-+define(IPA_API_VERSION_MINOR, 228)
-+# Last change: Expose ipaNTAdditionalSuffixes in trust-mod
- 
- 
- ########################################################
-diff --git a/ipaserver/plugins/trust.py b/ipaserver/plugins/trust.py
-index 075b39dcc33a79f3e73e8e1e9e31ebbef17618fe..d0bbfbc47ca65c9c5229685fc9d202c293fe41cd 100644
---- a/ipaserver/plugins/trust.py
-+++ b/ipaserver/plugins/trust.py
-@@ -553,8 +553,9 @@ class trust(LDAPObject):
-             flags={'virtual_attribute', 'no_create', 'no_update', 'no_search'},
-         ),
-         Str('ipantadditionalsuffixes*',
-+            cli_name='upn_suffixes',
-             label=_('UPN suffixes'),
--            flags={'no_create', 'no_update', 'no_search'},
-+            flags={'no_create', 'no_search'},
-         ),
-     )
- 
--- 
-2.9.4
-
diff --git a/SOURCES/0192-WebUI-add-support-for-changing-trust-UPN-suffixes.patch b/SOURCES/0192-WebUI-add-support-for-changing-trust-UPN-suffixes.patch
deleted file mode 100644
index 2e188cd..0000000
--- a/SOURCES/0192-WebUI-add-support-for-changing-trust-UPN-suffixes.patch
+++ /dev/null
@@ -1,32 +0,0 @@
-From 4ec1a4fd564bff73c37810bd5326c9382e3a26bf Mon Sep 17 00:00:00 2001
-From: Pavel Vomacka <pvomacka@redhat.com>
-Date: Mon, 12 Jun 2017 13:18:44 +0200
-Subject: [PATCH] WebUI: add support for changing trust UPN suffixes
-
-It is now possible to change UPN suffixes in WebUI. This change
-allows another way to changing UPN suffixes for AD users.
-
-https://pagure.io/freeipa/issue/7015
-
-Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
----
- install/ui/src/freeipa/trust.js | 3 +--
- 1 file changed, 1 insertion(+), 2 deletions(-)
-
-diff --git a/install/ui/src/freeipa/trust.js b/install/ui/src/freeipa/trust.js
-index 39e79ebef1c1fb3cb730d9304c46862ec0d0e651..ff019cab3070312b90e14e08a9070c353b1e7f71 100644
---- a/install/ui/src/freeipa/trust.js
-+++ b/install/ui/src/freeipa/trust.js
-@@ -147,8 +147,7 @@ return {
-                     fields: [
-                         {
-                             $type: 'multivalued',
--                            name: 'ipantadditionalsuffixes',
--                            read_only: true
-+                            name: 'ipantadditionalsuffixes'
-                         }
-                     ]
-                 },
--- 
-2.9.4
-
diff --git a/SOURCES/0193-kra-promote-Get-ticket-before-calling-custodia.patch b/SOURCES/0193-kra-promote-Get-ticket-before-calling-custodia.patch
deleted file mode 100644
index 9e09b32..0000000
--- a/SOURCES/0193-kra-promote-Get-ticket-before-calling-custodia.patch
+++ /dev/null
@@ -1,59 +0,0 @@
-From efd08380bbdda59a63afd584bc4c0ef3426b14ce Mon Sep 17 00:00:00 2001
-From: David Kupka <dkupka@redhat.com>
-Date: Wed, 14 Jun 2017 15:39:58 +0200
-Subject: [PATCH] kra: promote: Get ticket before calling custodia
-
-When installing second (or consequent) KRA instance keys are retrieved
-using custodia. Custodia checks that the keys are synchronized in
-master's directory server and the check uses GSSAPI and therefore fails
-if there's no ticket in ccache.
-
-https://pagure.io/freeipa/issue/7020
-
-Reviewed-By: Stanislav Laznicka <slaznick@redhat.com>
----
- ipaserver/install/kra.py | 21 ++++++++++++++-------
- 1 file changed, 14 insertions(+), 7 deletions(-)
-
-diff --git a/ipaserver/install/kra.py b/ipaserver/install/kra.py
-index f3454061280661d7b0fc2899142da9dc8783841a..3545b301a977f4b7e7801ca1ef87d594bb3ba54f 100644
---- a/ipaserver/install/kra.py
-+++ b/ipaserver/install/kra.py
-@@ -10,6 +10,7 @@ import os
- import shutil
- 
- from ipalib import api
-+from ipalib.install.kinit import kinit_keytab
- from ipaplatform import services
- from ipaplatform.paths import paths
- from ipapython import certdb
-@@ -84,13 +85,19 @@ def install(api, replica_config, options):
-             return
-         krafile = os.path.join(replica_config.dir, 'kracert.p12')
-         if options.promote:
--            custodia = custodiainstance.CustodiaInstance(
--                replica_config.host_name,
--                replica_config.realm_name)
--            custodia.get_kra_keys(
--                replica_config.kra_host_name,
--                krafile,
--                replica_config.dirman_password)
-+            with ipautil.private_ccache():
-+                ccache = os.environ['KRB5CCNAME']
-+                kinit_keytab(
-+                    'host/{env.host}@{env.realm}'.format(env=api.env),
-+                    paths.KRB5_KEYTAB,
-+                    ccache)
-+                custodia = custodiainstance.CustodiaInstance(
-+                    replica_config.host_name,
-+                    replica_config.realm_name)
-+                custodia.get_kra_keys(
-+                    replica_config.kra_host_name,
-+                    krafile,
-+                    replica_config.dirman_password)
-         else:
-             cafile = os.path.join(replica_config.dir, 'cacert.p12')
-             if not ipautil.file_exists(cafile):
--- 
-2.9.4
-
diff --git a/SOURCES/0194-Fix-local-IP-address-validation.patch b/SOURCES/0194-Fix-local-IP-address-validation.patch
deleted file mode 100644
index 154d20c..0000000
--- a/SOURCES/0194-Fix-local-IP-address-validation.patch
+++ /dev/null
@@ -1,45 +0,0 @@
-From 935029c3192221c480c88b870a507cfac4c4b954 Mon Sep 17 00:00:00 2001
-From: Martin Basti <mbasti@redhat.com>
-Date: Tue, 13 Jun 2017 17:03:30 +0200
-Subject: [PATCH] Fix local IP address validation
-
-Previously bf9886a84393d1d1546db7e49b102e08a16a83e7 match_local has
-undesirable side effect that CheckedIPAddress object has set self._net
-from local interface.
-
-However with the recent changes, match_local is usually set to False,
-thus this side effect stops happening and default mask per address class
-is used. This causes validation error because mask on interface and mask
-used for provided IP addresses differ (reporducible only with classless
-masks).
-
-FreeIPA should compare only IP addresses with local addresses without masks
-
-https://pagure.io/freeipa/issue/4317
-
-Reviewed-By: David Kupka <dkupka@redhat.com>
----
- ipapython/ipautil.py | 6 +++---
- 1 file changed, 3 insertions(+), 3 deletions(-)
-
-diff --git a/ipapython/ipautil.py b/ipapython/ipautil.py
-index a277ed87473f3c591f34fcc00e1159f3bbfe3e9b..647ee833ae33f246de6d6b13703fac6e20eef7bc 100644
---- a/ipapython/ipautil.py
-+++ b/ipapython/ipautil.py
-@@ -216,10 +216,10 @@ class CheckedIPAddress(UnsafeIPAddress):
-                     addr=ifaddr,
-                     netmask=ifdata['netmask']
-                 ))
--                if ifnet == self._net or (
--                                self._net is None and ifnet.ip == self):
--                    self._net = ifnet
-+
-+                if ifnet.ip == self:
-                     iface = interface
-+                    self._net = ifnet
-                     break
- 
-         return iface
--- 
-2.9.4
-
diff --git a/SOURCES/0195-ipa-dns-install-remove-check-for-local-ip-address.patch b/SOURCES/0195-ipa-dns-install-remove-check-for-local-ip-address.patch
deleted file mode 100644
index adf7bf9..0000000
--- a/SOURCES/0195-ipa-dns-install-remove-check-for-local-ip-address.patch
+++ /dev/null
@@ -1,32 +0,0 @@
-From 09fad2745b3f49192d6d43550ccb82145f223be0 Mon Sep 17 00:00:00 2001
-From: Martin Basti <mbasti@redhat.com>
-Date: Wed, 14 Jun 2017 14:45:03 +0200
-Subject: [PATCH] ipa-dns-install: remove check for local ip address
-
-This check was forgotten and will be removed now.
-
-https://pagure.io/freeipa/issue/4317
-
-Reviewed-By: David Kupka <dkupka@redhat.com>
----
- install/tools/ipa-dns-install | 4 +++-
- 1 file changed, 3 insertions(+), 1 deletion(-)
-
-diff --git a/install/tools/ipa-dns-install b/install/tools/ipa-dns-install
-index 5bd0ba6d77335d9fa32ea4269422cb3dd1cfca4a..cb6c5d887f101135ca593ea6d4ed0caf51478a4c 100755
---- a/install/tools/ipa-dns-install
-+++ b/install/tools/ipa-dns-install
-@@ -47,7 +47,9 @@ def parse_options():
-                       default=False, help="print debugging information")
-     parser.add_option("--ip-address", dest="ip_addresses", metavar="IP_ADDRESS",
-                       default=[], action="append",
--                      type="ip", ip_local=True, help="Master Server IP Address. This option can be used multiple times")
-+                      type="ip",
-+                      help="Master Server IP Address. This option can be used "
-+                           "multiple times")
-     parser.add_option("--forwarder", dest="forwarders", action="append",
-                       type="ip", help="Add a DNS forwarder. This option can be used multiple times")
-     parser.add_option("--no-forwarders", dest="no_forwarders", action="store_true",
--- 
-2.9.4
-
diff --git a/SOURCES/0196-refactor-CheckedIPAddress-class.patch b/SOURCES/0196-refactor-CheckedIPAddress-class.patch
deleted file mode 100644
index 7c1d745..0000000
--- a/SOURCES/0196-refactor-CheckedIPAddress-class.patch
+++ /dev/null
@@ -1,88 +0,0 @@
-From 8d88b50c3f79e054a039d123fdaf6aa3a5339135 Mon Sep 17 00:00:00 2001
-From: Martin Basti <mbasti@redhat.com>
-Date: Wed, 14 Jun 2017 14:47:23 +0200
-Subject: [PATCH] refactor CheckedIPAddress class
-
-Make methods without side effects (setting mask)
-
-https://pagure.io/freeipa/issue/4317
-
-Reviewed-By: David Kupka <dkupka@redhat.com>
----
- ipapython/ipautil.py | 29 ++++++++++++++++++++++-------
- 1 file changed, 22 insertions(+), 7 deletions(-)
-
-diff --git a/ipapython/ipautil.py b/ipapython/ipautil.py
-index 647ee833ae33f246de6d6b13703fac6e20eef7bc..2c020e3ecbf4d8b969511a6dd9b36ee955ba1f15 100644
---- a/ipapython/ipautil.py
-+++ b/ipapython/ipautil.py
-@@ -62,6 +62,12 @@ PROTOCOL_NAMES = {
-     socket.SOCK_DGRAM: 'udp'
- }
- 
-+InterfaceDetails = collections.namedtuple(
-+    'InterfaceDetails', [
-+        'name',  # interface name
-+        'ifnet'  # network details of interface
-+    ])
-+
- 
- class UnsafeIPAddress(netaddr.IPAddress):
-     """Any valid IP address with or without netmask."""
-@@ -161,9 +167,12 @@ class CheckedIPAddress(UnsafeIPAddress):
-             raise ValueError("cannot use multicast IP address {}".format(addr))
- 
-         if match_local:
--            if not self.get_matching_interface():
-+            intf_details = self.get_matching_interface()
-+            if not intf_details:
-                 raise ValueError('no network interface matches the IP address '
-                                  'and netmask {}'.format(addr))
-+            else:
-+                self.set_ip_net(intf_details.ifnet)
- 
-         if self._net is None:
-             if self.version == 4:
-@@ -193,7 +202,8 @@ class CheckedIPAddress(UnsafeIPAddress):
- 
-     def get_matching_interface(self):
-         """Find matching local interface for address
--        :return: Interface name or None if no interface has this address
-+        :return: InterfaceDetails named tuple or None if no interface has
-+        this address
-         """
-         if self.version == 4:
-             family = netifaces.AF_INET
-@@ -204,7 +214,6 @@ class CheckedIPAddress(UnsafeIPAddress):
-                 "Unsupported address family ({})".format(self.version)
-             )
- 
--        iface = None
-         for interface in netifaces.interfaces():
-             for ifdata in netifaces.ifaddresses(interface).get(family, []):
- 
-@@ -218,11 +227,17 @@ class CheckedIPAddress(UnsafeIPAddress):
-                 ))
- 
-                 if ifnet.ip == self:
--                    iface = interface
--                    self._net = ifnet
--                    break
-+                    return InterfaceDetails(interface, ifnet)
- 
--        return iface
-+    def set_ip_net(self, ifnet):
-+        """Set IP Network details for this address. IPNetwork is valid only
-+        locally, so this should be set only for local IP addresses
-+
-+        :param ifnet: netaddr.IPNetwork object with information about IP
-+        network where particula address belongs locally
-+        """
-+        assert isinstance(ifnet, netaddr.IPNetwork)
-+        self._net = ifnet
- 
- 
- def valid_ip(addr):
--- 
-2.9.4
-
diff --git a/SOURCES/0197-CheckedIPAddress-remove-match_local-param.patch b/SOURCES/0197-CheckedIPAddress-remove-match_local-param.patch
deleted file mode 100644
index 6ed40b5..0000000
--- a/SOURCES/0197-CheckedIPAddress-remove-match_local-param.patch
+++ /dev/null
@@ -1,141 +0,0 @@
-From c4482f0441e610c077d550c10b9525f97ea2f984 Mon Sep 17 00:00:00 2001
-From: Martin Basti <mbasti@redhat.com>
-Date: Wed, 14 Jun 2017 14:54:43 +0200
-Subject: [PATCH] CheckedIPAddress: remove match_local param
-
-This parameter is unused in code. We are no longer testing if IP address
-matches an interface in constructor.
-
-https://pagure.io/freeipa/issue/4317
-
-Reviewed-By: David Kupka <dkupka@redhat.com>
----
- ipapython/config.py                     |  5 ++---
- ipapython/ipautil.py                    | 10 +---------
- ipaserver/install/installutils.py       |  2 +-
- ipaserver/plugins/dns.py                |  4 ++--
- ipaserver/plugins/host.py               |  2 +-
- ipatests/test_ipapython/test_ipautil.py |  3 +--
- 6 files changed, 8 insertions(+), 18 deletions(-)
-
-diff --git a/ipapython/config.py b/ipapython/config.py
-index 9db2dcd4dbf3ed0fbe3e3166c3f0c5bae0f1716b..6349892fe88757629129f464401efce64e30f058 100644
---- a/ipapython/config.py
-+++ b/ipapython/config.py
-@@ -68,10 +68,9 @@ class IPAFormatter(IndentedHelpFormatter):
- def check_ip_option(option, opt, value):
-     from ipapython.ipautil import CheckedIPAddress
- 
--    ip_local = option.ip_local is True
-     ip_netmask = option.ip_netmask is True
-     try:
--        return CheckedIPAddress(value, parse_netmask=ip_netmask, match_local=ip_local)
-+        return CheckedIPAddress(value, parse_netmask=ip_netmask)
-     except Exception as e:
-         raise OptionValueError("option %s: invalid IP address %s: %s" % (opt, value, e))
- 
-@@ -86,7 +85,7 @@ class IPAOption(Option):
-     optparse.Option subclass with support of options labeled as
-     security-sensitive such as passwords.
-     """
--    ATTRS = Option.ATTRS + ["sensitive", "ip_local", "ip_netmask"]
-+    ATTRS = Option.ATTRS + ["sensitive", "ip_netmask"]
-     TYPES = Option.TYPES + ("ip", "dn")
-     TYPE_CHECKER = copy(Option.TYPE_CHECKER)
-     TYPE_CHECKER["ip"] = check_ip_option
-diff --git a/ipapython/ipautil.py b/ipapython/ipautil.py
-index 2c020e3ecbf4d8b969511a6dd9b36ee955ba1f15..5a6bf5a27d5a6e25c51fbaa6e2b1167652e2735d 100644
---- a/ipapython/ipautil.py
-+++ b/ipapython/ipautil.py
-@@ -135,7 +135,7 @@ class CheckedIPAddress(UnsafeIPAddress):
- 
-     Reserved or link-local addresses are never accepted.
-     """
--    def __init__(self, addr, match_local=False, parse_netmask=True,
-+    def __init__(self, addr, parse_netmask=True,
-                  allow_loopback=False, allow_multicast=False):
-         try:
-             super(CheckedIPAddress, self).__init__(addr)
-@@ -166,14 +166,6 @@ class CheckedIPAddress(UnsafeIPAddress):
-         if not allow_multicast and self.is_multicast():
-             raise ValueError("cannot use multicast IP address {}".format(addr))
- 
--        if match_local:
--            intf_details = self.get_matching_interface()
--            if not intf_details:
--                raise ValueError('no network interface matches the IP address '
--                                 'and netmask {}'.format(addr))
--            else:
--                self.set_ip_net(intf_details.ifnet)
--
-         if self._net is None:
-             if self.version == 4:
-                 self._net = netaddr.IPNetwork(
-diff --git a/ipaserver/install/installutils.py b/ipaserver/install/installutils.py
-index 3521d555914714351160213df60ed9167ac6e370..01930c4de6f0edd16b31aeba1c926fe581e9635b 100644
---- a/ipaserver/install/installutils.py
-+++ b/ipaserver/install/installutils.py
-@@ -585,7 +585,7 @@ def get_server_ip_address(host_name, unattended, setup_dns, ip_addresses):
-     if len(hostaddr):
-         for ha in hostaddr:
-             try:
--                ips.append(ipautil.CheckedIPAddress(ha, match_local=False))
-+                ips.append(ipautil.CheckedIPAddress(ha))
-             except ValueError as e:
-                 root_logger.warning("Invalid IP address %s for %s: %s", ha, host_name, unicode(e))
- 
-diff --git a/ipaserver/plugins/dns.py b/ipaserver/plugins/dns.py
-index f0e6c48f06313def57cdd6a4c7114357c9d8de8a..f01baf515525c43824eddf06abc7af9fef228efe 100644
---- a/ipaserver/plugins/dns.py
-+++ b/ipaserver/plugins/dns.py
-@@ -567,7 +567,7 @@ def add_records_for_host_validation(option_name, host, domain, ip_addresses, che
-     for ip_address in ip_addresses:
-         try:
-             ip = CheckedIPAddress(
--                ip_address, match_local=False, allow_multicast=True)
-+                ip_address, allow_multicast=True)
-         except Exception as e:
-             raise errors.ValidationError(name=option_name, error=unicode(e))
- 
-@@ -599,7 +599,7 @@ def add_records_for_host(host, domain, ip_addresses, add_forward=True, add_rever
- 
-     for ip_address in ip_addresses:
-         ip = CheckedIPAddress(
--            ip_address, match_local=False, allow_multicast=True)
-+            ip_address, allow_multicast=True)
- 
-         if add_forward:
-             add_forward_record(domain, host, unicode(ip))
-diff --git a/ipaserver/plugins/host.py b/ipaserver/plugins/host.py
-index 1e1f9d82dfdfcf9e7fef65ce729cd8ee7b76e605..364e5be6002eeb9c5e6b4c594b71f38169598227 100644
---- a/ipaserver/plugins/host.py
-+++ b/ipaserver/plugins/host.py
-@@ -245,7 +245,7 @@ def validate_ipaddr(ugettext, ipaddr):
-     Verify that we have either an IPv4 or IPv6 address.
-     """
-     try:
--        CheckedIPAddress(ipaddr, match_local=False)
-+        CheckedIPAddress(ipaddr)
-     except Exception as e:
-         return unicode(e)
-     return None
-diff --git a/ipatests/test_ipapython/test_ipautil.py b/ipatests/test_ipapython/test_ipautil.py
-index 6427935b162b087c55e069cb2a576a7379cbe7a7..9c351bd0ed9cd96488ac74deadf97996668a75d2 100644
---- a/ipatests/test_ipapython/test_ipautil.py
-+++ b/ipatests/test_ipapython/test_ipautil.py
-@@ -30,11 +30,10 @@ from ipapython import ipautil
- 
- pytestmark = pytest.mark.tier0
- 
--
- def make_ipaddress_checker(addr, words=None, prefixlen=None):
-     def check_ipaddress():
-         try:
--            ip = ipautil.CheckedIPAddress(addr, match_local=False)
-+            ip = ipautil.CheckedIPAddress(addr)
-             assert ip.words == words and ip.prefixlen == prefixlen
-         except Exception:
-             assert words is None and prefixlen is None
--- 
-2.9.4
-
diff --git a/SOURCES/0198-Remove-ip_netmask-from-option-parser.patch b/SOURCES/0198-Remove-ip_netmask-from-option-parser.patch
deleted file mode 100644
index 38924ef..0000000
--- a/SOURCES/0198-Remove-ip_netmask-from-option-parser.patch
+++ /dev/null
@@ -1,44 +0,0 @@
-From dd004f9393f0543c556d417d27b9f652b6fe4c99 Mon Sep 17 00:00:00 2001
-From: Martin Basti <mbasti@redhat.com>
-Date: Wed, 14 Jun 2017 15:02:21 +0200
-Subject: [PATCH] Remove ip_netmask from option parser
-
-ipa-dns-install uses ip_netmask=False --> parse_netmask=False, other installers uses default (parse_netmask=True).
-Use this consistent accross all installers.
-
-Also this option is unused (and shouldn't be used).
-
-https://pagure.io/freeipa/issue/4317
-
-Reviewed-By: David Kupka <dkupka@redhat.com>
----
- ipapython/config.py | 5 ++---
- 1 file changed, 2 insertions(+), 3 deletions(-)
-
-diff --git a/ipapython/config.py b/ipapython/config.py
-index 6349892fe88757629129f464401efce64e30f058..19abfc51ee354d2971be836fa6bad70eea3a6720 100644
---- a/ipapython/config.py
-+++ b/ipapython/config.py
-@@ -68,9 +68,8 @@ class IPAFormatter(IndentedHelpFormatter):
- def check_ip_option(option, opt, value):
-     from ipapython.ipautil import CheckedIPAddress
- 
--    ip_netmask = option.ip_netmask is True
-     try:
--        return CheckedIPAddress(value, parse_netmask=ip_netmask)
-+        return CheckedIPAddress(value)
-     except Exception as e:
-         raise OptionValueError("option %s: invalid IP address %s: %s" % (opt, value, e))
- 
-@@ -85,7 +84,7 @@ class IPAOption(Option):
-     optparse.Option subclass with support of options labeled as
-     security-sensitive such as passwords.
-     """
--    ATTRS = Option.ATTRS + ["sensitive", "ip_netmask"]
-+    ATTRS = Option.ATTRS + ["sensitive"]
-     TYPES = Option.TYPES + ("ip", "dn")
-     TYPE_CHECKER = copy(Option.TYPE_CHECKER)
-     TYPE_CHECKER["ip"] = check_ip_option
--- 
-2.9.4
-
diff --git a/SOURCES/0199-replica-install-add-missing-check-for-non-local-IP-a.patch b/SOURCES/0199-replica-install-add-missing-check-for-non-local-IP-a.patch
deleted file mode 100644
index a47f9c4..0000000
--- a/SOURCES/0199-replica-install-add-missing-check-for-non-local-IP-a.patch
+++ /dev/null
@@ -1,29 +0,0 @@
-From 56c6b8432a50c7b857303ffc4345c75171e0ac92 Mon Sep 17 00:00:00 2001
-From: Martin Basti <mbasti@redhat.com>
-Date: Thu, 15 Jun 2017 10:26:03 +0200
-Subject: [PATCH] replica install: add missing check for non-local IP address
-
-Add missing warning for used non-local IP address.
-
-https://pagure.io/freeipa/issue/4317
-
-Reviewed-By: David Kupka <dkupka@redhat.com>
----
- ipaserver/install/server/replicainstall.py | 1 +
- 1 file changed, 1 insertion(+)
-
-diff --git a/ipaserver/install/server/replicainstall.py b/ipaserver/install/server/replicainstall.py
-index 6620f0222f9d38112ce0d0fd72381e5673921cba..9e328bf83bbdb2883ba823cb098b70eeaa078403 100644
---- a/ipaserver/install/server/replicainstall.py
-+++ b/ipaserver/install/server/replicainstall.py
-@@ -854,6 +854,7 @@ def install_check(installer):
-             # check addresses here, dns module is doing own check
-             network_ip_address_warning(config.ips)
-             broadcast_ip_address_warning(config.ips)
-+            no_matching_interface_for_ip_address_warning(config.ips)
- 
-         if options.setup_adtrust:
-             adtrust.install_check(False, options, remote_api)
--- 
-2.9.4
-
diff --git a/SOURCES/0200-Remove-network-and-broadcast-address-warnings.patch b/SOURCES/0200-Remove-network-and-broadcast-address-warnings.patch
deleted file mode 100644
index c5d440d..0000000
--- a/SOURCES/0200-Remove-network-and-broadcast-address-warnings.patch
+++ /dev/null
@@ -1,146 +0,0 @@
-From 52be5b4d693febdc1fa1fe9d54b1d052a09c347f Mon Sep 17 00:00:00 2001
-From: Martin Basti <mbasti@redhat.com>
-Date: Thu, 15 Jun 2017 10:27:55 +0200
-Subject: [PATCH] Remove network and broadcast address warnings
-
-We cannot reliably determine when an IP Address is network or broadcast.
-We allowed to use non-local IP addresses due container use cases, we
-don't know subnets of used IP addresses.
-
-https://pagure.io/freeipa/issue/4317
-
-Reviewed-By: David Kupka <dkupka@redhat.com>
----
- ipaclient/install/client.py                |  4 ----
- ipalib/util.py                             | 20 --------------------
- ipaserver/install/dns.py                   |  2 --
- ipaserver/install/server/install.py        |  4 ----
- ipaserver/install/server/replicainstall.py | 10 +---------
- 5 files changed, 1 insertion(+), 39 deletions(-)
-
-diff --git a/ipaclient/install/client.py b/ipaclient/install/client.py
-index 41dae3004d1f4836e79c2048ae0a12f722595ca0..6242c19636168a5b2922f6f6f0e8bc8aa9b4bc80 100644
---- a/ipaclient/install/client.py
-+++ b/ipaclient/install/client.py
-@@ -38,8 +38,6 @@ from ipalib.install.kinit import kinit_keytab, kinit_password
- from ipalib.install.service import enroll_only, prepare_only
- from ipalib.rpc import delete_persistent_client_session_data
- from ipalib.util import (
--    broadcast_ip_address_warning,
--    network_ip_address_warning,
-     normalize_hostname,
-     no_matching_interface_for_ip_address_warning,
-     verify_host_resolvable,
-@@ -1299,8 +1297,6 @@ def update_dns(server, hostname, options):
-         root_logger.info("Failed to determine this machine's ip address(es).")
-         return
- 
--    network_ip_address_warning(update_ips)
--    broadcast_ip_address_warning(update_ips)
-     no_matching_interface_for_ip_address_warning(update_ips)
- 
-     update_txt = "debug\n"
-diff --git a/ipalib/util.py b/ipalib/util.py
-index 1bd8495a49b010e7a3ac926dad516ab5f8219b39..31e73230da49a47e8e0fbcba9934f13cef16460e 100644
---- a/ipalib/util.py
-+++ b/ipalib/util.py
-@@ -1110,26 +1110,6 @@ def check_principal_realm_in_trust_namespace(api_instance, *keys):
-                         'namespace'))
- 
- 
--def network_ip_address_warning(addr_list):
--    for ip in addr_list:
--        if ip.is_network_addr():
--            root_logger.warning("IP address %s might be network address", ip)
--            # fixme: once when loggers will be fixed, we can remove this
--            # print
--            print("WARNING: IP address {} might be network address".format(ip),
--                  file=sys.stderr)
--
--
--def broadcast_ip_address_warning(addr_list):
--    for ip in addr_list:
--        if ip.is_broadcast_addr():
--            root_logger.warning("IP address %s might be broadcast address", ip)
--            # fixme: once when loggers will be fixed, we can remove this
--            # print
--            print("WARNING: IP address {} might be broadcast address".format(
--                ip), file=sys.stderr)
--
--
- def no_matching_interface_for_ip_address_warning(addr_list):
-     for ip in addr_list:
-         if not ip.get_matching_interface():
-diff --git a/ipaserver/install/dns.py b/ipaserver/install/dns.py
-index 090b79493652566a433da248fa7fd9e33dd2cb72..1c1aac06a18fe3c1f63b5881c7887f6a4cfc9ac2 100644
---- a/ipaserver/install/dns.py
-+++ b/ipaserver/install/dns.py
-@@ -264,8 +264,6 @@ def install_check(standalone, api, replica, options, hostname):
-     ip_addresses = get_server_ip_address(hostname, options.unattended,
-                                          True, options.ip_addresses)
- 
--    util.network_ip_address_warning(ip_addresses)
--    util.broadcast_ip_address_warning(ip_addresses)
-     util.no_matching_interface_for_ip_address_warning(ip_addresses)
- 
-     if not options.forward_policy:
-diff --git a/ipaserver/install/server/install.py b/ipaserver/install/server/install.py
-index 7eb291e07c00e0407ce534c3d4088e6f6378260f..dced253e7f039dc9d66466bf8bcd777e53919f54 100644
---- a/ipaserver/install/server/install.py
-+++ b/ipaserver/install/server/install.py
-@@ -27,8 +27,6 @@ from ipalib import api, errors, x509
- from ipalib.constants import DOMAIN_LEVEL_0
- from ipalib.util import (
-     validate_domain_name,
--    network_ip_address_warning,
--    broadcast_ip_address_warning,
-     no_matching_interface_for_ip_address_warning,
- )
- import ipaclient.install.ntpconf
-@@ -616,8 +614,6 @@ def install_check(installer):
-                                              options.ip_addresses)
- 
-         # check addresses here, dns module is doing own check
--        network_ip_address_warning(ip_addresses)
--        broadcast_ip_address_warning(ip_addresses)
-         no_matching_interface_for_ip_address_warning(ip_addresses)
- 
-     if options.setup_adtrust:
-diff --git a/ipaserver/install/server/replicainstall.py b/ipaserver/install/server/replicainstall.py
-index 9e328bf83bbdb2883ba823cb098b70eeaa078403..4f28de25bd0adf958187c19edf90de4ba57dd98e 100644
---- a/ipaserver/install/server/replicainstall.py
-+++ b/ipaserver/install/server/replicainstall.py
-@@ -32,11 +32,7 @@ from ipaplatform.tasks import tasks
- from ipaplatform.paths import paths
- from ipalib import api, constants, create_api, errors, rpc, x509
- from ipalib.config import Env
--from ipalib.util import (
--    network_ip_address_warning,
--    broadcast_ip_address_warning,
--    no_matching_interface_for_ip_address_warning,
--)
-+from ipalib.util import no_matching_interface_for_ip_address_warning
- from ipaclient.install.client import configure_krb5_conf, purge_host_keytab
- from ipaserver.install import (
-     adtrust, bindinstance, ca, certs, dns, dsinstance, httpinstance,
-@@ -852,8 +848,6 @@ def install_check(installer):
-                 options.ip_addresses)
- 
-             # check addresses here, dns module is doing own check
--            network_ip_address_warning(config.ips)
--            broadcast_ip_address_warning(config.ips)
-             no_matching_interface_for_ip_address_warning(config.ips)
- 
-         if options.setup_adtrust:
-@@ -1285,8 +1279,6 @@ def promote_check(installer):
-                 False, options.ip_addresses)
- 
-             # check addresses here, dns module is doing own check
--            network_ip_address_warning(config.ips)
--            broadcast_ip_address_warning(config.ips)
-             no_matching_interface_for_ip_address_warning(config.ips)
- 
-         if options.setup_adtrust:
--- 
-2.9.4
-
diff --git a/SOURCES/0201-ipa-sam-replace-encode_nt_key-with-E_md4hash.patch b/SOURCES/0201-ipa-sam-replace-encode_nt_key-with-E_md4hash.patch
deleted file mode 100644
index 06623f1..0000000
--- a/SOURCES/0201-ipa-sam-replace-encode_nt_key-with-E_md4hash.patch
+++ /dev/null
@@ -1,80 +0,0 @@
-From 4504cb10cb7bf489be5ce221358b237afc1e52ca Mon Sep 17 00:00:00 2001
-From: Sumit Bose <sbose@redhat.com>
-Date: Fri, 16 Jun 2017 16:26:41 +0200
-Subject: [PATCH] ipa-sam: replace encode_nt_key() with E_md4hash()
-
-Since ipa-sam is running as part of smbd is it safe to use the
-E_md4hash() from Samba. This way ipa-sam does not depend on other crypto
-libraries which might depend on other rules like e.g. FIPS mode.
-
-Resolves https://pagure.io/freeipa/issue/7026
-
-Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
-Reviewed-By: Stanislav Laznicka <slaznick@redhat.com>
----
- daemons/ipa-sam/ipa_sam.c | 27 ++-------------------------
- 1 file changed, 2 insertions(+), 25 deletions(-)
-
-diff --git a/daemons/ipa-sam/ipa_sam.c b/daemons/ipa-sam/ipa_sam.c
-index 6a29e8e10b4299356b9ead76276eecc8083791a3..59d92f37c9b7104c2fba5bd530b4dbff3ca675db 100644
---- a/daemons/ipa-sam/ipa_sam.c
-+++ b/daemons/ipa-sam/ipa_sam.c
-@@ -110,6 +110,7 @@ char *sid_string_dbg(const struct dom_sid *sid); /* available in libsmbconf.so *
- char *escape_ldap_string(TALLOC_CTX *mem_ctx, const char *s); /* available in libsmbconf.so */
- bool secrets_store(const char *key, const void *data, size_t size); /* available in libpdb.so */
- void idmap_cache_set_sid2unixid(const struct dom_sid *sid, struct unixid *unix_id); /* available in libsmbconf.so */
-+bool E_md4hash(const char *passwd, uint8_t p16[16]); /* available in libcliauth-samba4.so */
- 
- #define LDAP_OBJ_SAMBASAMACCOUNT "ipaNTUserAttrs"
- #define LDAP_OBJ_TRUSTED_DOMAIN "ipaNTTrustedDomain"
-@@ -2836,11 +2837,7 @@ static bool init_sam_from_td(struct samu *user, struct pdb_trusted_domain *td,
- 	struct dom_sid *g_sid;
- 	char *name;
- 	char *trustpw = NULL;
--	char *trustpw_utf8 = NULL;
--	char *tmp_str = NULL;
--	int ret;
- 	uint8_t nt_key[16];
--	size_t converted_size;
- 	bool res;
- 	char *sid_str;
- 	enum idmap_error_code err;
-@@ -2899,19 +2896,7 @@ static bool init_sam_from_td(struct samu *user, struct pdb_trusted_domain *td,
- 		return false;
- 	}
- 
--	if (!push_utf8_talloc(user, &trustpw_utf8, trustpw, &converted_size)) {
--		res = false;
--		goto done;
--	}
--
--	tmp_str = talloc_strdup_upper(user, trustpw);
--	if (tmp_str == NULL) {
--		res = false;
--		goto done;
--	}
--
--	ret = encode_nt_key(trustpw_utf8, nt_key);
--	if (ret != 0) {
-+	if (!E_md4hash(trustpw, nt_key)) {
- 		res = false;
- 		goto done;
- 	}
-@@ -2927,14 +2912,6 @@ done:
- 		memset(trustpw, 0, strlen(trustpw));
- 		talloc_free(trustpw);
- 	}
--	if (trustpw_utf8 != NULL) {
--		memset(trustpw_utf8, 0, strlen(trustpw_utf8));
--		talloc_free(trustpw_utf8);
--	}
--	if (tmp_str != NULL) {
--		memset(tmp_str, 0, strlen(tmp_str));
--		talloc_free(tmp_str);
--	}
- 
- 	return res;
- }
--- 
-2.9.4
-
diff --git a/SOURCES/0202-ipa_pwd_extop-do-not-generate-NT-hashes-in-FIPS-mode.patch b/SOURCES/0202-ipa_pwd_extop-do-not-generate-NT-hashes-in-FIPS-mode.patch
deleted file mode 100644
index 32a5ffe..0000000
--- a/SOURCES/0202-ipa_pwd_extop-do-not-generate-NT-hashes-in-FIPS-mode.patch
+++ /dev/null
@@ -1,102 +0,0 @@
-From 84be5dc9e72fbf4c85b6f061da94a4316c90d65e Mon Sep 17 00:00:00 2001
-From: Sumit Bose <sbose@redhat.com>
-Date: Fri, 16 Jun 2017 17:49:44 +0200
-Subject: [PATCH] ipa_pwd_extop: do not generate NT hashes in FIPS mode
-
-In FIPS mode NT hashes (aka md4) are not allowed. If FIPS more is
-detected we disable NT hashes even is the are allowed by IPA
-configuration.
-
-Resolves https://pagure.io/freeipa/issue/7026
-
-Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
-Reviewed-By: Stanislav Laznicka <slaznick@redhat.com>
----
- daemons/ipa-slapi-plugins/ipa-pwd-extop/common.c | 53 ++++++++++++++++++------
- 1 file changed, 40 insertions(+), 13 deletions(-)
-
-diff --git a/daemons/ipa-slapi-plugins/ipa-pwd-extop/common.c b/daemons/ipa-slapi-plugins/ipa-pwd-extop/common.c
-index 761f7a8e3e9ee539f97797c98b8719ad752bdcf1..5efadac5b1fd57e5f91a886224fa2f1ab88305ac 100644
---- a/daemons/ipa-slapi-plugins/ipa-pwd-extop/common.c
-+++ b/daemons/ipa-slapi-plugins/ipa-pwd-extop/common.c
-@@ -46,6 +46,8 @@
- /* Type of connection for this operation;*/
- #define LDAP_EXTOP_PASSMOD_CONN_SECURE
- 
-+#define PROC_SYS_FIPS "/proc/sys/crypto/fips_enabled"
-+
- /* Uncomment the following #undef FOR TESTING:
-  * allows non-SSL connections to use the password change extended op */
- /* #undef LDAP_EXTOP_PASSMOD_CONN_SECURE */
-@@ -62,6 +64,27 @@ static const char *ipapwd_def_encsalts[] = {
-     NULL
- };
- 
-+static bool fips_enabled(void)
-+{
-+    int fd;
-+    ssize_t len;
-+    char buf[8];
-+
-+    fd = open(PROC_SYS_FIPS, O_RDONLY);
-+    if (fd != -1) {
-+        len = read(fd, buf, sizeof(buf));
-+        close(fd);
-+        /* Assume FIPS in enabled if PROC_SYS_FIPS contains a non-0 value
-+         * similar to the is_fips_enabled() check in
-+         * ipaplatform/redhat/tasks.py */
-+        if (!(len == 2 && buf[0] == '0' && buf[1] == '\n')) {
-+            return true;
-+        }
-+    }
-+
-+    return false;
-+}
-+
- static struct ipapwd_krbcfg *ipapwd_getConfig(void)
- {
-     krb5_error_code krberr;
-@@ -232,23 +255,27 @@ static struct ipapwd_krbcfg *ipapwd_getConfig(void)
- 
-     /* get the ipa etc/ipaConfig entry */
-     config->allow_nt_hash = false;
--    ret = ipapwd_getEntry(ipa_etc_config_dn, &config_entry, NULL);
--    if (ret != LDAP_SUCCESS) {
--        LOG_FATAL("No config Entry?\n");
--        goto free_and_error;
-+    if (fips_enabled()) {
-+        LOG("FIPS mode is enabled, NT hashes are not allowed.\n");
-     } else {
--        tmparray = slapi_entry_attr_get_charray(config_entry,
--                                                "ipaConfigString");
--        for (i = 0; tmparray && tmparray[i]; i++) {
--            if (strcasecmp(tmparray[i], "AllowNThash") == 0) {
--                config->allow_nt_hash = true;
--                continue;
-+        ret = ipapwd_getEntry(ipa_etc_config_dn, &config_entry, NULL);
-+        if (ret != LDAP_SUCCESS) {
-+            LOG_FATAL("No config Entry?\n");
-+            goto free_and_error;
-+        } else {
-+            tmparray = slapi_entry_attr_get_charray(config_entry,
-+                                                    "ipaConfigString");
-+            for (i = 0; tmparray && tmparray[i]; i++) {
-+                if (strcasecmp(tmparray[i], "AllowNThash") == 0) {
-+                    config->allow_nt_hash = true;
-+                    continue;
-+                }
-             }
-+            if (tmparray) slapi_ch_array_free(tmparray);
-         }
--        if (tmparray) slapi_ch_array_free(tmparray);
--    }
- 
--    slapi_entry_free(config_entry);
-+        slapi_entry_free(config_entry);
-+    }
- 
-     return config;
- 
--- 
-2.9.4
-
diff --git a/SOURCES/0203-Make-sure-we-check-ccaches-in-all-rpcserver-paths.patch b/SOURCES/0203-Make-sure-we-check-ccaches-in-all-rpcserver-paths.patch
deleted file mode 100644
index c246344..0000000
--- a/SOURCES/0203-Make-sure-we-check-ccaches-in-all-rpcserver-paths.patch
+++ /dev/null
@@ -1,126 +0,0 @@
-From 8c6cafb9d331d15cb224820c3bc254c84b49a0c7 Mon Sep 17 00:00:00 2001
-From: Simo Sorce <simo@redhat.com>
-Date: Thu, 22 Jun 2017 10:57:25 -0400
-Subject: [PATCH] Make sure we check ccaches in all rpcserver paths
-
-We need to verify the ccache is avcailable in all cases or finalize
-will cause us to acquire creds with the keytab which is not what we
-want.
-
-Ticket #7037
-
-Signed-off-by: Simo Sorce <simo@redhat.com>
-Reviewed-By: Stanislav Laznicka <slaznick@redhat.com>
----
- ipaserver/rpcserver.py | 72 +++++++++++++++++++++++++++-----------------------
- 1 file changed, 39 insertions(+), 33 deletions(-)
-
-diff --git a/ipaserver/rpcserver.py b/ipaserver/rpcserver.py
-index 2990df25985eab63d4bcfc8edf7f2b12da3e9832..9efe3c1f4b9e0114a02e8e04aafc76c3bc04c6f1 100644
---- a/ipaserver/rpcserver.py
-+++ b/ipaserver/rpcserver.py
-@@ -592,6 +592,41 @@ class KerberosSession(HTTP_Status):
-     needing this do not share a common base class.
-     '''
- 
-+    def need_login(self, start_response):
-+        status = '401 Unauthorized'
-+        headers = []
-+        response = b''
-+
-+        self.debug('%s need login', status)
-+
-+        start_response(status, headers)
-+        return [response]
-+
-+    def get_environ_creds(self, environ):
-+        # If we have a ccache ...
-+        ccache_name = environ.get('KRB5CCNAME')
-+        if ccache_name is None:
-+            self.debug('no ccache, need login')
-+            return
-+
-+        # ... make sure we have a name ...
-+        principal = environ.get('GSS_NAME')
-+        if principal is None:
-+            self.debug('no Principal Name, need login')
-+            return
-+
-+        # ... and use it to resolve the ccache name (Issue: 6972 )
-+        gss_name = gssapi.Name(principal, gssapi.NameType.kerberos_principal)
-+
-+        # Fail if Kerberos credentials are expired or missing
-+        creds = get_credentials_if_valid(name=gss_name,
-+                                         ccache_name=ccache_name)
-+        if not creds:
-+            self.debug('ccache expired or invalid, deleting session, need login')
-+            return
-+
-+        return ccache_name
-+
- 
-     def finalize_kerberos_acquisition(self, who, ccache_name, environ, start_response, headers=None):
-         if headers is None:
-@@ -754,43 +789,15 @@ class jsonserver_session(jsonserver, KerberosSession):
-     def _on_finalize(self):
-         super(jsonserver_session, self)._on_finalize()
- 
--    def need_login(self, start_response):
--        status = '401 Unauthorized'
--        headers = []
--        response = b''
--
--        self.debug('jsonserver_session: %s need login', status)
--
--        start_response(status, headers)
--        return [response]
--
-     def __call__(self, environ, start_response):
-         '''
-         '''
- 
-         self.debug('WSGI jsonserver_session.__call__:')
- 
--        ccache_name = environ.get('KRB5CCNAME')
--
-         # Redirect to login if no Kerberos credentials
-+        ccache_name = self.get_environ_creds(environ)
-         if ccache_name is None:
--            self.debug('no ccache, need login')
--            return self.need_login(start_response)
--
--        # If we have a ccache, make sure we have a GSS_NAME and use
--        # it to resolve the ccache name (Issue: 6972 )
--        principal = environ.get('GSS_NAME')
--        if principal is None:
--            self.debug('no GSS Name, need login')
--            return self.need_login(start_response)
--        gss_name = gssapi.Name(principal, gssapi.NameType.kerberos_principal)
--
--        # Redirect to login if Kerberos credentials are expired
--        creds = get_credentials_if_valid(name=gss_name,
--                                         ccache_name=ccache_name)
--        if not creds:
--            self.debug('ccache expired, deleting session, need login')
--            # The request is finished with the ccache, destroy it.
-             return self.need_login(start_response)
- 
-         # Store the ccache name in the per-thread context
-@@ -828,11 +835,10 @@ class KerberosLogin(Backend, KerberosSession):
-     def __call__(self, environ, start_response):
-         self.debug('WSGI KerberosLogin.__call__:')
- 
--        # Get the ccache created by mod_auth_gssapi
--        user_ccache_name=environ.get('KRB5CCNAME')
-+        # Redirect to login if no Kerberos credentials
-+        user_ccache_name = self.get_environ_creds(environ)
-         if user_ccache_name is None:
--            return self.internal_error(environ, start_response,
--                                       'login_kerberos: KRB5CCNAME not defined in HTTP request environment')
-+            return self.need_login(start_response)
- 
-         return self.finalize_kerberos_acquisition('login_kerberos', user_ccache_name, environ, start_response)
- 
--- 
-2.9.4
-
diff --git a/SOURCES/0204-replica-install-drop-in-IPA-specific-config-to-tmpfi.patch b/SOURCES/0204-replica-install-drop-in-IPA-specific-config-to-tmpfi.patch
deleted file mode 100644
index 4e27e7f..0000000
--- a/SOURCES/0204-replica-install-drop-in-IPA-specific-config-to-tmpfi.patch
+++ /dev/null
@@ -1,34 +0,0 @@
-From 9c70e00901ed1453767d085ea4c5496b2341c212 Mon Sep 17 00:00:00 2001
-From: Martin Babinsky <mbabinsk@redhat.com>
-Date: Tue, 11 Jul 2017 12:41:38 +0200
-Subject: [PATCH] replica install: drop-in IPA specific config to tmpfiles.d
-
-While server installation and upgrade code configures the IPA specific
-tmpfiles location and creates relevant directories, the replica
-installer code path is covered incompletely and one step is missing.
-
-https://pagure.io/freeipa/issue/7053
-
-Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
-Reviewed-By: Stanislav Laznicka <slaznick@redhat.com>
----
- ipaserver/install/server/replicainstall.py | 3 +++
- 1 file changed, 3 insertions(+)
-
-diff --git a/ipaserver/install/server/replicainstall.py b/ipaserver/install/server/replicainstall.py
-index 4f28de25bd0adf958187c19edf90de4ba57dd98e..814925de152809808f726c60ae7f35a24bc32a4a 100644
---- a/ipaserver/install/server/replicainstall.py
-+++ b/ipaserver/install/server/replicainstall.py
-@@ -1515,6 +1515,9 @@ def install(installer):
-         # remove the extracted replica file
-         remove_replica_info_dir(installer)
- 
-+    # Make sure the files we crated in /var/run are recreated at startup
-+    tasks.configure_tmpfiles()
-+
-     # Everything installed properly, activate ipa service.
-     services.knownservices.ipa.enable()
- 
--- 
-2.9.4
-
diff --git a/SOURCES/0205-Add-CommonNameToSANDefault-to-default-cert-profile.patch b/SOURCES/0205-Add-CommonNameToSANDefault-to-default-cert-profile.patch
deleted file mode 100644
index 73b0c6d..0000000
--- a/SOURCES/0205-Add-CommonNameToSANDefault-to-default-cert-profile.patch
+++ /dev/null
@@ -1,62 +0,0 @@
-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
deleted file mode 100644
index f83b0f2..0000000
--- a/SOURCES/0206-smart-card-advises-configure-systemwide-NSS-DB-also-.patch
+++ /dev/null
@@ -1,131 +0,0 @@
-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
deleted file mode 100644
index 344a96c..0000000
--- a/SOURCES/0207-smart-card-advises-add-steps-to-store-smart-card-sig.patch
+++ /dev/null
@@ -1,125 +0,0 @@
-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
deleted file mode 100644
index 612e334..0000000
--- a/SOURCES/0208-Allow-to-pass-in-multiple-CA-cert-paths-to-the-smart.patch
+++ /dev/null
@@ -1,150 +0,0 @@
-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
deleted file mode 100644
index e6ac4ed..0000000
--- a/SOURCES/0209-add-a-class-that-tracks-the-indentation-in-the-gener.patch
+++ /dev/null
@@ -1,77 +0,0 @@
-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
deleted file mode 100644
index 901dd54..0000000
--- a/SOURCES/0210-delegate-the-indentation-handling-in-advises-to-dedi.patch
+++ /dev/null
@@ -1,267 +0,0 @@
-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
deleted file mode 100644
index 297b114..0000000
--- a/SOURCES/0211-advise-add-an-infrastructure-for-formatting-Bash-com.patch
+++ /dev/null
@@ -1,104 +0,0 @@
-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
deleted file mode 100644
index 59b6b5b..0000000
--- a/SOURCES/0212-delegate-formatting-of-compound-Bash-statements-to-d.patch
+++ /dev/null
@@ -1,93 +0,0 @@
-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
deleted file mode 100644
index 452b7df..0000000
--- a/SOURCES/0213-Fix-indentation-of-statements-in-Smart-card-advises.patch
+++ /dev/null
@@ -1,36 +0,0 @@
-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
deleted file mode 100644
index 6c24663..0000000
--- a/SOURCES/0214-Use-the-compound-statement-formatting-API-for-config.patch
+++ /dev/null
@@ -1,48 +0,0 @@
-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
deleted file mode 100644
index 7102db1..0000000
--- a/SOURCES/0215-smart-card-advises-use-a-wrapper-around-Bash-for-loo.patch
+++ /dev/null
@@ -1,121 +0,0 @@
-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
deleted file mode 100644
index c49524c..0000000
--- a/SOURCES/0216-smart-card-advise-use-password-when-changing-trust-f.patch
+++ /dev/null
@@ -1,54 +0,0 @@
-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
deleted file mode 100644
index 66e090e..0000000
--- a/SOURCES/0217-smart-card-advises-ensure-that-krb5-pkinit-is-instal.patch
+++ /dev/null
@@ -1,46 +0,0 @@
-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
deleted file mode 100644
index d4ac0c7..0000000
--- a/SOURCES/0218-NULL-LDAP-context-in-call-to-ldap_search_ext_s-durin.patch
+++ /dev/null
@@ -1,33 +0,0 @@
-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
deleted file mode 100644
index 0c35b69..0000000
--- a/SOURCES/0219-Restore-old-version-of-caIPAserviceCert-for-upgrade-.patch
+++ /dev/null
@@ -1,187 +0,0 @@
-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/0220-ipa-otptoken-import-Make-PBKDF2-refer-to-the-pkcs5-n.patch b/SOURCES/0220-ipa-otptoken-import-Make-PBKDF2-refer-to-the-pkcs5-n.patch
deleted file mode 100644
index b56a901..0000000
--- a/SOURCES/0220-ipa-otptoken-import-Make-PBKDF2-refer-to-the-pkcs5-n.patch
+++ /dev/null
@@ -1,84 +0,0 @@
-From 92f450a4b6eacb7950e5414d40d9949076cb096e Mon Sep 17 00:00:00 2001
-From: Nathaniel McCallum <npmccallum@redhat.com>
-Date: Tue, 20 Jun 2017 10:31:15 -0400
-Subject: [PATCH] ipa-otptoken-import: Make PBKDF2 refer to the pkcs5 namespace
-
-For some unknown reason, when I wrote the ipa-otptoken-import script
-I used bad input data which had the PBKDF2 parameters in the wrong
-XML namespace. I have corrected this input data to match RFC 6030.
-
-https://pagure.io/freeipa/issue/7035
-
-Signed-off-by: Nathaniel McCallum <npmccallum@redhat.com>
-Reviewed-By: Martin Basti <mbasti@redhat.com>
-Reviewed-By: Stanislav Laznicka <slaznick@redhat.com>
----
- ipaserver/install/ipa_otptoken_import.py      | 15 ++++++---------
- ipatests/test_ipaserver/data/pskc-figure7.xml | 16 ++++++++--------
- 2 files changed, 14 insertions(+), 17 deletions(-)
-
-diff --git a/ipaserver/install/ipa_otptoken_import.py b/ipaserver/install/ipa_otptoken_import.py
-index 2580e2cfc97f4960af68a5eae407a7ebe3c7a257..31225e96b55c20bd78e9a8650848a28cf9feef63 100644
---- a/ipaserver/install/ipa_otptoken_import.py
-+++ b/ipaserver/install/ipa_otptoken_import.py
-@@ -52,6 +52,7 @@ class ValidationError(Exception):
- 
- def fetchAll(element, xpath, conv=lambda x: x):
-     return [conv(e) for e in element.xpath(xpath, namespaces={
-+        "pkcs5": "http://www.rsasecurity.com/rsalabs/pkcs/schemas/pkcs-5v2-0#",
-         "pskc": "urn:ietf:params:xml:ns:keyprov:pskc",
-         "xenc11": "http://www.w3.org/2009/xmlenc11#",
-         "xenc": "http://www.w3.org/2001/04/xmlenc#",
-@@ -175,18 +176,14 @@ class XMLKeyDerivation(six.with_metaclass(abc.ABCMeta, object)):
- 
- class PBKDF2KeyDerivation(XMLKeyDerivation):
-     def __init__(self, enckey):
--        params = fetch(enckey, "./xenc11:DerivedKey/xenc11:KeyDerivationMethod/xenc11:PBKDF2-params")
-+        params = fetch(enckey, "./xenc11:DerivedKey/xenc11:KeyDerivationMethod/pkcs5:PBKDF2-params")
-         if params is None:
-             raise ValueError("XML file is missing PBKDF2 parameters!")
- 
--        salt = fetch(
--            params, "./xenc11:Salt/xenc11:Specified/text()", base64.b64decode)
--        itrs = fetch(
--            params, "./xenc11:IterationCount/text()", int)
--        klen = fetch(
--            params, "./xenc11:KeyLength/text()", int)
--        hmod = fetch(
--            params, "./xenc11:PRF/@Algorithm", convertHMACType, hashes.SHA1)
-+        salt = fetch(params, "./Salt/Specified/text()", base64.b64decode)
-+        itrs = fetch(params, "./IterationCount/text()", int)
-+        klen = fetch(params, "./KeyLength/text()", int)
-+        hmod = fetch(params, "./PRF/@Algorithm", convertHMACType, hashes.SHA1)
-
-         if salt is None:
-             raise ValueError("XML file is missing PBKDF2 salt!")
-diff --git a/ipatests/test_ipaserver/data/pskc-figure7.xml b/ipatests/test_ipaserver/data/pskc-figure7.xml
-index 1fb04fc319d7572d9d25ff34a0ce3378a939dfc6..808e272a5469a1c9eb4087ed53e0907bb80b39ad 100644
---- a/ipatests/test_ipaserver/data/pskc-figure7.xml
-+++ b/ipatests/test_ipaserver/data/pskc-figure7.xml
-@@ -8,14 +8,14 @@
-     <xenc11:DerivedKey>
-       <xenc11:KeyDerivationMethod
- 	  Algorithm="http://www.rsasecurity.com/rsalabs/pkcs/schemas/pkcs-5v2-0#pbkdf2">
--        <xenc11:PBKDF2-params>
--          <xenc11:Salt>
--            <xenc11:Specified>Ej7/PEpyEpw=</xenc11:Specified>
--          </xenc11:Salt>
--          <xenc11:IterationCount>1000</xenc11:IterationCount>
--          <xenc11:KeyLength>16</xenc11:KeyLength>
--          <xenc11:PRF/>
--        </xenc11:PBKDF2-params>
-+        <pkcs5:PBKDF2-params>
-+          <Salt>
-+            <Specified>Ej7/PEpyEpw=</Specified>
-+          </Salt>
-+          <IterationCount>1000</IterationCount>
-+          <KeyLength>16</KeyLength>
-+          <PRF/>
-+        </pkcs5:PBKDF2-params>
-       </xenc11:KeyDerivationMethod>
-       <xenc:ReferenceList>
-         <xenc:DataReference URI="#ED"/>
---
-2.13.5
\ No newline at end of file
diff --git a/SOURCES/0221-Adds-whoami-DS-plugin-in-case-that-plugin-is-missing.patch b/SOURCES/0221-Adds-whoami-DS-plugin-in-case-that-plugin-is-missing.patch
deleted file mode 100644
index e247dd1..0000000
--- a/SOURCES/0221-Adds-whoami-DS-plugin-in-case-that-plugin-is-missing.patch
+++ /dev/null
@@ -1,59 +0,0 @@
-From d06b29772609d14dccfe0d556fdb83140fcb2b3f Mon Sep 17 00:00:00 2001
-From: Pavel Vomacka <pvomacka@redhat.com>
-Date: Mon, 28 Aug 2017 10:51:53 +0200
-Subject: [PATCH] Adds whoami DS plugin in case that plugin is missing
-
-When first installation of IPA has been done when whoami
-plugin was not enabled in DS by default and then IPA was
-upgraded to newer versions, then after upgrade to IPA 4.5
-WebUI stops working. This is caused by new requirement on
-whoami DS plugin which is used to obtain information about
-logged in entity.
-
-This fix adds the whoami plugin during update in case that the plugin
-is not enabled.
-
-https://pagure.io/freeipa/issue/7126
-
-Reviewed-By: Tibor Dudlak <tdudlak@redhat.com>
-Reviewed-By: Rob Crittenden <rcritten@redhat.com>
----
- install/updates/20-whoami.update | 14 ++++++++++++++
- install/updates/Makefile.am      |  1 +
- 2 files changed, 15 insertions(+)
- create mode 100644 install/updates/20-whoami.update
-
-diff --git a/install/updates/20-whoami.update b/install/updates/20-whoami.update
-new file mode 100644
-index 0000000000000000000000000000000000000000..ed2c6cbd772ec1c2b664e450463bb64d61b1ceab
---- /dev/null
-+++ b/install/updates/20-whoami.update
-@@ -0,0 +1,14 @@
-+dn: cn=whoami,cn=plugins,cn=config
-+default:objectClass: top
-+default:objectClass: nsSlapdPlugin
-+default:objectClass: extensibleObject
-+default:cn: whoami
-+default:nsslapd-plugin-depends-on-type: database
-+default:nsslapd-pluginDescription: whoami extended operation plugin
-+default:nsslapd-pluginEnabled: on
-+default:nsslapd-pluginId: whoami-plugin
-+default:nsslapd-pluginInitfunc: whoami_init
-+default:nsslapd-pluginPath: libwhoami-plugin
-+default:nsslapd-pluginType: extendedop
-+default:nsslapd-pluginVendor: 389 Project
-+default:nsslapd-pluginVersion: 1.0
-diff --git a/install/updates/Makefile.am b/install/updates/Makefile.am
-index e18d01127b592a6c7941729d6160d10fb2d3e76c..ae3d3e0528929a30922f0395d7092654dd753a64 100644
---- a/install/updates/Makefile.am
-+++ b/install/updates/Makefile.am
-@@ -24,6 +24,7 @@ app_DATA =				\
- 	20-idoverride_index.update	\
- 	20-uuid.update  \
- 	20-default_password_policy.update \
-+	20-whoami.update	\
- 	21-replicas_container.update	\
- 	21-ca_renewal_container.update	\
- 	21-certstore_container.update	\
---
-2.13.5
\ No newline at end of file
diff --git a/SOURCES/0222-Fix-ipa-config-mod-ca-renewal-master.patch b/SOURCES/0222-Fix-ipa-config-mod-ca-renewal-master.patch
deleted file mode 100644
index b4778ba..0000000
--- a/SOURCES/0222-Fix-ipa-config-mod-ca-renewal-master.patch
+++ /dev/null
@@ -1,88 +0,0 @@
-From 9a8352637aeb32ddffd83f4477695ec290da8429 Mon Sep 17 00:00:00 2001
-From: Florence Blanc-Renaud <flo@redhat.com>
-Date: Wed, 23 Aug 2017 16:31:18 +0200
-Subject: [PATCH] Fix ipa config-mod --ca-renewal-master
-
-commit bddb90f38a3505a2768862d2f814c5e749a7dcde added the support for
-multivalued server attributes (for pkinit_server_server), but this
-introduced an API change where the setter and getter of ServerAttribute
-are expecting list of values.
-
-When a SingleValuedServerAttribute is used, we need to convert one elem
-into a list containing this elem and vice-versa, so that the ipa config-mod
-and ipa config_show APIs are not modified.
-
-https://pagure.io/freeipa/issue/7120
-
-Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
-Reviewed-By: Fraser Tweedale <ftweedal@redhat.com>
----
- ipaserver/plugins/serverroles.py            | 16 +++++++++++++++-
- ipatests/test_ipaserver/test_serverroles.py |  4 ++--
- 2 files changed, 17 insertions(+), 3 deletions(-)
-
-diff --git a/ipaserver/plugins/serverroles.py b/ipaserver/plugins/serverroles.py
-index e81635c3315cc3fca84450f43fb7df883aae57d9..04e21090657197b9267f2ffc05048399a7ce3d38 100644
---- a/ipaserver/plugins/serverroles.py
-+++ b/ipaserver/plugins/serverroles.py
-@@ -46,6 +46,7 @@ from ipalib import errors, _
- from ipalib.backend import Backend
- from ipalib.plugable import Registry
- from ipaserver.servroles import (attribute_instances, ENABLED, role_instances)
-+from ipaserver.servroles import SingleValuedServerAttribute
- 
- 
- if six.PY3:
-@@ -136,13 +137,26 @@ class serverroles(Backend):
- 
-         for name, attr in assoc_attributes.items():
-             attr_value = attr.get(self.api)
--            result.update({name: attr_value})
-+
-+            if attr_value:
-+                # attr can be a SingleValuedServerAttribute
-+                # in this case, the API expects a value, not a list of values
-+                if isinstance(attr, SingleValuedServerAttribute):
-+                    attr_value = attr_value[0]
-+                result.update({name: attr_value})
- 
-         return result
- 
-     def config_update(self, **attrs_values):
-         for attr, value in attrs_values.items():
-             try:
-+                # when the attribute is single valued, it will be stored
-+                # in a SingleValuedServerAttribute. The set method expects
-+                # a list containing a single value.
-+                # We need to convert value to a list containing value
-+                if isinstance(self.attributes[attr],
-+                              SingleValuedServerAttribute):
-+                    value = [value]
-                 self.attributes[attr].set(self.api, value)
-             except KeyError:
-                 raise errors.NotFound(
-diff --git a/ipatests/test_ipaserver/test_serverroles.py b/ipatests/test_ipaserver/test_serverroles.py
-index 985c750b64f109e0a83686f31ddb3b8d4171072d..e8967517d0c65fb6e3daebf220cae7df38bfe044 100644
---- a/ipatests/test_ipaserver/test_serverroles.py
-+++ b/ipatests/test_ipaserver/test_serverroles.py
-@@ -715,7 +715,7 @@ class TestServerAttributes(object):
-         non_ca_fqdn = mock_masters.get_fqdn('trust-controller-dns')
- 
-         with pytest.raises(errors.ValidationError):
--            self.config_update(mock_api, **{attr_name: [non_ca_fqdn]})
-+            self.config_update(mock_api, **{attr_name: non_ca_fqdn})
- 
-     def test_set_unknown_attribute_on_master_raises_notfound(
-             self, mock_api, mock_masters):
-@@ -732,7 +732,7 @@ class TestServerAttributes(object):
-         original_renewal_master = self.config_retrieve(
-             role_name, mock_api)[attr_name]
- 
--        other_ca_server = [mock_masters.get_fqdn('trust-controller-ca')]
-+        other_ca_server = mock_masters.get_fqdn('trust-controller-ca')
- 
-         for host in (other_ca_server, original_renewal_master):
-             self.config_update(mock_api, **{attr_name: host})
--- 
-2.13.5
-
diff --git a/SOURCES/0223-Backport-PR-988-to-ipa-4-5-Fix-Certificate-renewal-w.patch b/SOURCES/0223-Backport-PR-988-to-ipa-4-5-Fix-Certificate-renewal-w.patch
deleted file mode 100644
index db614e2..0000000
--- a/SOURCES/0223-Backport-PR-988-to-ipa-4-5-Fix-Certificate-renewal-w.patch
+++ /dev/null
@@ -1,60 +0,0 @@
-From 21b0fdb48179e6060eff0ecb11ce6522983ccc00 Mon Sep 17 00:00:00 2001
-From: Florence Blanc-Renaud <flo@redhat.com>
-Date: Fri, 18 Aug 2017 18:02:57 +0200
-Subject: [PATCH] Backport PR 988 to ipa-4-5 Fix Certificate renewal (with ext
- ca)
-
-Fix certificate renewal scripts that use IPACertificate object:
-- renew_ca_cert adds the C flag to the trust flags and needs to
-be adapted to IPACertificate object
-- ipa-cacert-manage: fix python3 encoding issue
-
-https://pagure.io/freeipa/issue/7106
-
-Reviewed-By: Fraser Tweedale <ftweedal@redhat.com>
-Reviewed-By: Stanislav Laznicka <slaznick@redhat.com>
----
- install/restart_scripts/renew_ca_cert  | 7 ++++++-
- ipaserver/install/ipa_cacert_manage.py | 2 +-
- 2 files changed, 7 insertions(+), 2 deletions(-)
-
-diff --git a/install/restart_scripts/renew_ca_cert b/install/restart_scripts/renew_ca_cert
-index bb31defc0e2bdca044e68ae067f42fb3bd41a57f..3bbf003bad47a189fd26df19e6ab137fcbb67ed0 100644
---- a/install/restart_scripts/renew_ca_cert
-+++ b/install/restart_scripts/renew_ca_cert
-@@ -35,6 +35,7 @@ from ipaserver.install import certs, cainstance, installutils
- from ipaserver.plugins.ldap2 import ldap2
- from ipaplatform import services
- from ipaplatform.paths import paths
-+from ipapython.certdb import TrustFlags
-
-
- def _main():
-@@ -180,7 +181,11 @@ def _main():
-                 # Pass Dogtag's self-tests
-                 for ca_nick in db.find_root_cert(nickname)[-2:-1]:
-                     ca_flags = dict(cc[1:] for cc in ca_certs)[ca_nick]
--                    db.trust_root_cert(ca_nick, 'C' + ca_flags)
-+                    usages = ca_flags.usages or set()
-+                    ca_flags_modified = TrustFlags(ca_flags.has_key,
-+                        True, True,
-+                        usages | {x509.EKU_SERVER_AUTH})
-+                    db.trust_root_cert(ca_nick, ca_flags_modified)
-             finally:
-                 if conn is not None and conn.isconnected():
-                     conn.disconnect()
-diff --git a/ipaserver/install/ipa_cacert_manage.py b/ipaserver/install/ipa_cacert_manage.py
-index e88e8b63ae94759ac835f3b3b31b0735d68a67b0..fcbf09155a3abc9ce9481aa2519ed39aaa6aa9bb 100644
---- a/ipaserver/install/ipa_cacert_manage.py
-+++ b/ipaserver/install/ipa_cacert_manage.py
-@@ -218,7 +218,7 @@ class CACertManage(admintool.AdminTool):
-         cert_file, ca_file = installutils.load_external_cert(
-             options.external_cert_files, DN(old_cert_obj.subject))
- 
--        with open(cert_file.name) as f:
-+        with open(cert_file.name, 'rb') as f:
-             new_cert_data = f.read()
-         new_cert_der = x509.normalize_certificate(new_cert_data)
-         new_cert_obj = x509.load_certificate(new_cert_der, x509.DER)
---
-2.13.5
\ No newline at end of file
diff --git a/SOURCES/0224-Backport-PR-1008-to-ipa-4-5-Fix-ipa-server-upgrade-T.patch b/SOURCES/0224-Backport-PR-1008-to-ipa-4-5-Fix-ipa-server-upgrade-T.patch
deleted file mode 100644
index 7de886b..0000000
--- a/SOURCES/0224-Backport-PR-1008-to-ipa-4-5-Fix-ipa-server-upgrade-T.patch
+++ /dev/null
@@ -1,213 +0,0 @@
-From c9fb09190ac243bcf45622693944d7e6785141b4 Mon Sep 17 00:00:00 2001
-From: Florence Blanc-Renaud <flo@redhat.com>
-Date: Mon, 28 Aug 2017 10:50:58 +0200
-Subject: [PATCH] Backport PR 1008 to ipa-4-5 Fix ipa-server-upgrade: This
- entry already exists
-
-ipa-server-upgrade fails when running the ipaload_cacrt plugin. The plugin
-finds all CA certificates in /etc/httpd/alias and uploads them in LDAP
-below cn=certificates,cn=ipa,cn=etc,$BASEDN.
-The issue happens because there is already an entry in LDAP for IPA CA, but
-with a different DN. The nickname in /etc/httpd/alias can differ from
-$DOMAIN IPA CA.
-
-To avoid the issue:
-1/ during upgrade, run a new plugin that removes duplicates and restarts ldap
-(to make sure that uniqueness attr plugin is working after the new plugin)
-2/ modify upload_cacert plugin so that it is using $DOMAIN IPA CA instead of
-cn=$nickname,cn=ipa,cn=etc,$BASEDN when uploading IPA CA.
-
-https://pagure.io/freeipa/issue/7125
-
-Reviewed-By: Fraser Tweedale <ftweedal@redhat.com>
----
- install/updates/90-post_upgrade_plugins.update     |  1 +
- ipalib/install/certstore.py                        | 19 +++++
- .../plugins/update_fix_duplicate_cacrt_in_ldap.py  | 84 ++++++++++++++++++++++
- ipaserver/install/plugins/upload_cacrt.py          | 19 ++++-
- 4 files changed, 120 insertions(+), 3 deletions(-)
- create mode 100644 ipaserver/install/plugins/update_fix_duplicate_cacrt_in_ldap.py
-
-diff --git a/install/updates/90-post_upgrade_plugins.update b/install/updates/90-post_upgrade_plugins.update
-index 8477199e07d6729d5847e58bfa67d061bd1410c2..bbc3e29422fc0f139c2ca68a7033863e4c25f8cf 100644
---- a/install/updates/90-post_upgrade_plugins.update
-+++ b/install/updates/90-post_upgrade_plugins.update
-@@ -15,6 +15,7 @@ plugin: update_ca_renewal_master
- plugin: update_idrange_type
- plugin: update_pacs
- plugin: update_service_principalalias
-+plugin: update_fix_duplicate_cacrt_in_ldap
- plugin: update_upload_cacrt
- # update_ra_cert_store has to be executed after update_ca_renewal_master
- plugin: update_ra_cert_store
-diff --git a/ipalib/install/certstore.py b/ipalib/install/certstore.py
-index bc2079fb12873444cbe6796eebfdfcfebd0e284d..76181fe47de585974f3fb33ec586f5c576adebb5 100644
---- a/ipalib/install/certstore.py
-+++ b/ipalib/install/certstore.py
-@@ -27,6 +27,7 @@ from pyasn1.error import PyAsn1Error
- from ipapython.dn import DN
- from ipapython.certdb import get_ca_nickname, TrustFlags
- from ipalib import errors, x509
-+from ipalib.constants import IPA_CA_CN
- 
- def _parse_cert(dercert):
-     try:
-@@ -381,3 +382,21 @@ def get_ca_certs_nss(ldap, base_dn, compat_realm, compat_ipa_ca,
-         nss_certs.append((cert, nickname, trust_flags))
- 
-     return nss_certs
-+
-+
-+def get_ca_subject(ldap, container_ca, base_dn):
-+    """
-+    Look for the IPA CA certificate subject.
-+    """
-+    dn = DN(('cn', IPA_CA_CN), container_ca, base_dn)
-+    try:
-+        cacert_subject = ldap.get_entry(dn)['ipacasubjectdn'][0]
-+    except errors.NotFound:
-+        # if the entry doesn't exist, we are dealing with a pre-v4.4
-+        # installation, where the default CA subject was always based
-+        # on the subject_base.
-+        attrs = ldap.get_ipa_config()
-+        subject_base = attrs.get('ipacertificatesubjectbase')[0]
-+        cacert_subject = DN(('CN', 'Certificate Authority'), subject_base)
-+
-+    return cacert_subject
-diff --git a/ipaserver/install/plugins/update_fix_duplicate_cacrt_in_ldap.py b/ipaserver/install/plugins/update_fix_duplicate_cacrt_in_ldap.py
-new file mode 100644
-index 0000000000000000000000000000000000000000..cd4f13a8eb6b5bc9e04fcdd407907497528f8be1
---- /dev/null
-+++ b/ipaserver/install/plugins/update_fix_duplicate_cacrt_in_ldap.py
-@@ -0,0 +1,84 @@
-+# Authors:
-+#   Florence Blanc-Renaud <flo@redhat.com>
-+#
-+# Copyright (C) 2017  Red Hat
-+# see file 'COPYING' for use and warranty information
-+#
-+# This program is free software; you can redistribute it and/or modify
-+# it under the terms of the GNU General Public License as published by
-+# the Free Software Foundation, either version 3 of the License, or
-+# (at your option) any later version.
-+#
-+# This program is distributed in the hope that it will be useful,
-+# but WITHOUT ANY WARRANTY; without even the implied warranty of
-+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+# GNU General Public License for more details.
-+#
-+# You should have received a copy of the GNU General Public License
-+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
-+
-+import logging
-+
-+from ipalib import Registry, errors
-+from ipalib import Updater
-+from ipalib.install import certstore
-+from ipapython.dn import DN
-+from ipapython.certdb import get_ca_nickname
-+
-+logger = logging.getLogger(__name__)
-+
-+register = Registry()
-+
-+
-+@register()
-+class update_fix_duplicate_cacrt_in_ldap(Updater):
-+    """
-+    When multiple entries exist for IPA CA cert in ldap, remove the duplicate
-+
-+    After this plugin, ds needs to be restarted. This ensures that
-+    the attribute uniqueness plugin is working and prevents
-+    other plugins from adding duplicates.
-+    """
-+
-+    def execute(self, **options):
-+        # If CA is disabled, no need to check for duplicates of IPA CA
-+        ca_enabled = self.api.Command.ca_is_enabled()['result']
-+        if not ca_enabled:
-+            return True, []
-+
-+        # Look for the IPA CA cert subject
-+        ldap = self.api.Backend.ldap2
-+        cacert_subject = certstore.get_ca_subject(
-+            ldap,
-+            self.api.env.container_ca,
-+            self.api.env.basedn)
-+
-+        # Find if there are other certificates with the same subject
-+        # They are duplicates resulting of BZ 1480102
-+        base_dn = DN(('cn', 'certificates'), ('cn', 'ipa'), ('cn', 'etc'),
-+                     self.api.env.basedn)
-+        try:
-+            filter = ldap.make_filter({'ipaCertSubject': cacert_subject})
-+            result, _truncated = ldap.find_entries(
-+                base_dn=base_dn,
-+                filter=filter,
-+                attrs_list=[])
-+        except errors.NotFound:
-+            # No duplicate, we're good
-+            logger.debug("No duplicates for IPA CA in LDAP")
-+            return True, []
-+
-+        logger.debug("Found %d entrie(s) for IPA CA in LDAP", len(result))
-+        cacert_dn = DN(('cn', get_ca_nickname(self.api.env.realm)), base_dn)
-+        for entry in result:
-+            if entry.dn == cacert_dn:
-+                continue
-+            # Remove the duplicate
-+            try:
-+                ldap.delete_entry(entry)
-+                logger.debug("Removed the duplicate %s", entry.dn)
-+            except Exception as e:
-+                logger.warning("Failed to remove the duplicate %s: %s",
-+                               entry.dn, e)
-+
-+        return True, []
-diff --git a/ipaserver/install/plugins/upload_cacrt.py b/ipaserver/install/plugins/upload_cacrt.py
-index a1957ca5b675b86f0df36dc820ee31305f54f863..985b74c06e80a3620eb6454c0bd9c7590b04184d 100644
---- a/ipaserver/install/plugins/upload_cacrt.py
-+++ b/ipaserver/install/plugins/upload_cacrt.py
-@@ -20,7 +20,7 @@
- from ipalib.install import certstore
- from ipaplatform.paths import paths
- from ipaserver.install import certs
--from ipalib import Registry, errors
-+from ipalib import Registry, errors, x509
- from ipalib import Updater
- from ipapython import certdb
- from ipapython.dn import DN
-@@ -41,6 +41,10 @@ class update_upload_cacrt(Updater):
-         ca_enabled = self.api.Command.ca_is_enabled()['result']
-         if ca_enabled:
-             ca_nickname = certdb.get_ca_nickname(self.api.env.realm)
-+            ca_subject = certstore.get_ca_subject(
-+                self.api.Backend.ldap2,
-+                self.api.env.container_ca,
-+                self.api.env.basedn)
-         else:
-             ca_nickname = None
-             server_certs = db.find_server_certs()
-@@ -54,9 +58,18 @@ class update_upload_cacrt(Updater):
-         for nickname, trust_flags in db.list_certs():
-             if trust_flags.has_key:
-                 continue
--            if nickname == ca_nickname and ca_enabled:
--                trust_flags = certdb.IPA_CA_TRUST_FLAGS
-             cert = db.get_cert_from_db(nickname, pem=False)
-+            subject = DN(
-+                x509.load_certificate(cert, datatype=x509.DER).subject)
-+            if ca_enabled and subject == ca_subject:
-+                # When ca is enabled, we can have the IPA CA cert stored
-+                # in the nss db with a different nickname (for instance
-+                # when the server was installed with --subject to
-+                # customize the CA cert subject), but it must always be
-+                # stored in LDAP with the DN cn=$DOMAIN IPA CA
-+                # This is why we check the subject instead of the nickname here
-+                nickname = ca_nickname
-+                trust_flags = certdb.IPA_CA_TRUST_FLAGS
-             trust, _ca, eku = certstore.trust_flags_to_key_policy(trust_flags)
- 
-             dn = DN(('cn', nickname), ('cn', 'certificates'), ('cn', 'ipa'),
---
-2.13.5
\ No newline at end of file
diff --git a/SOURCES/0225-Fixing-how-sssd.conf-is-updated-when-promoting-a-cli.patch b/SOURCES/0225-Fixing-how-sssd.conf-is-updated-when-promoting-a-cli.patch
deleted file mode 100644
index 28455ee..0000000
--- a/SOURCES/0225-Fixing-how-sssd.conf-is-updated-when-promoting-a-cli.patch
+++ /dev/null
@@ -1,92 +0,0 @@
-From c8fcaa5dc792e7b87c8f21c7c322ddfabe219980 Mon Sep 17 00:00:00 2001
-From: Felipe Volpone <fbarreto@redhat.com>
-Date: Wed, 13 Sep 2017 09:26:41 -0300
-Subject: [PATCH] Fixing how sssd.conf is updated when promoting a client to
- replica
-
-When promoting a client to a replica we have to change sssd.conf,
-deleting _srv_ part from 'ipa_server' property and setting
-'ipa_server_mode' to true.
-
-Previously, the wrong domain could be updated since the ipa_domain
-variable was not being used properly.
-
-https://pagure.io/freeipa/issue/7127
-
-Reviewed-By: Stanislav Laznicka <slaznick@redhat.com>
-Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
-Reviewed-By: Rob Crittenden <rcritten@redhat.com>
----
- ipaserver/install/server/replicainstall.py | 27 ++++++++++++---------------
- ipaserver/install/server/upgrade.py        |  4 ++++
- 2 files changed, 16 insertions(+), 15 deletions(-)
-
-diff --git a/ipaserver/install/server/replicainstall.py b/ipaserver/install/server/replicainstall.py
-index 814925de152809808f726c60ae7f35a24bc32a4a..326daf708f091d9d2c56ad399e46aef659dbba2e 100644
---- a/ipaserver/install/server/replicainstall.py
-+++ b/ipaserver/install/server/replicainstall.py
-@@ -432,30 +432,27 @@ def promote_sssd(host_name):
-     sssdconfig.import_config()
-     domains = sssdconfig.list_active_domains()
-
--    ipa_domain = None
--
-     for name in domains:
-         domain = sssdconfig.get_domain(name)
-         try:
-             hostname = domain.get_option('ipa_hostname')
-             if hostname == host_name:
--                ipa_domain = domain
-+                break
-         except SSSDConfig.NoOptionError:
-             continue
--
--    if ipa_domain is None:
--        raise RuntimeError("Couldn't find IPA domain in sssd.conf")
-     else:
--        domain.set_option('ipa_server', host_name)
--        domain.set_option('ipa_server_mode', True)
--        sssdconfig.save_domain(domain)
--        sssdconfig.write()
-+        raise RuntimeError("Couldn't find IPA domain in sssd.conf")
-
--        sssd = services.service('sssd', api)
--        try:
--            sssd.restart()
--        except CalledProcessError:
--            root_logger.warning("SSSD service restart was unsuccessful.")
-+    domain.set_option('ipa_server', host_name)
-+    domain.set_option('ipa_server_mode', True)
-+    sssdconfig.save_domain(domain)
-+    sssdconfig.write()
-+
-+    sssd = services.service('sssd', api)
-+    try:
-+        sssd.restart()
-+    except CalledProcessError:
-+        root_logger.warning("SSSD service restart was unsuccessful.")
-
-
- def promote_openldap_conf(hostname, master):
-diff --git a/ipaserver/install/server/upgrade.py b/ipaserver/install/server/upgrade.py
-index 732776f2cf513a4bb11d8f3f0dfaac78217e460f..109e922e3a3ea25f882fdd81765788a3881e87bd 100644
---- a/ipaserver/install/server/upgrade.py
-+++ b/ipaserver/install/server/upgrade.py
-@@ -1816,11 +1816,15 @@ def upgrade_configuration():
-         cainstance.ensure_ipa_authority_entry()
-
-     set_sssd_domain_option('ipa_server_mode', 'True')
-+    set_sssd_domain_option('ipa_server', api.env.host)
- 
-     sssdconfig = SSSDConfig.SSSDConfig()
-     sssdconfig.import_config()
-     sssd_enable_service(sssdconfig, 'ifp')
- 
-+    sssd = services.service('sssd', api)
-+    sssd.restart()
-+
-     krb = krbinstance.KrbInstance(fstore)
-     krb.fqdn = fqdn
-     krb.realm = api.env.realm
---
-2.13.5
\ No newline at end of file
diff --git a/SOURCES/0226-Backport-4-5-Fix-ipa-server-upgrade-with-server-cert.patch b/SOURCES/0226-Backport-4-5-Fix-ipa-server-upgrade-with-server-cert.patch
deleted file mode 100644
index 27b8c70..0000000
--- a/SOURCES/0226-Backport-4-5-Fix-ipa-server-upgrade-with-server-cert.patch
+++ /dev/null
@@ -1,199 +0,0 @@
-From 8c576e8c3640b84869abacc43a74aa250df5a8e9 Mon Sep 17 00:00:00 2001
-From: Florence Blanc-Renaud <flo@redhat.com>
-Date: Tue, 5 Sep 2017 16:17:31 +0200
-Subject: [PATCH] Backport 4-5: Fix ipa-server-upgrade with server cert
- tracking
-
-ipa-server-upgrade fails with Server-Cert not found, when trying to
-track httpd/ldap server certificates. There are 2 issues in the upgrade:
-- the certificates should be tracked only if they were issued by IPA CA
-(it is possible to have CA configured but 3rd part certs)
-- the certificate nickname can be different from Server-Cert
-
-The fix provides methods to find the server crt nickname for http and ldap,
-and a method to check if the server certs are issued by IPA and need to be
-tracked by certmonger.
-
-https://pagure.io/freeipa/issue/7141
-
-Reviewed-By: Stanislav Laznicka <slaznick@redhat.com>
-Reviewed-By: Fraser Tweedale <ftweedal@redhat.com>
----
- ipaserver/install/certs.py          | 27 ++++++++++++++++++++++
- ipaserver/install/dsinstance.py     | 45 +++++++++++++++++++++++++++++++++----
- ipaserver/install/httpinstance.py   | 16 ++++++++++---
- ipaserver/install/server/upgrade.py |  4 ++--
- 4 files changed, 83 insertions(+), 9 deletions(-)
-
-diff --git a/ipaserver/install/certs.py b/ipaserver/install/certs.py
-index 02c479d92511fcf4043e7d6798c85cf8256c3299..de96318db51b03f2515814d574cfebf1b242b6a6 100644
---- a/ipaserver/install/certs.py
-+++ b/ipaserver/install/certs.py
-@@ -42,6 +42,7 @@ from ipapython.certdb import get_ca_nickname, find_cert_from_txt, NSSDatabase
- from ipapython.dn import DN
- from ipalib import pkcs10, x509, api
- from ipalib.errors import CertificateOperationError
-+from ipalib.install import certstore
- from ipalib.text import _
- from ipaplatform.paths import paths
-
-@@ -669,6 +670,32 @@ class CertDB(object):
-                                              subject=host,
-                                              passwd_fname=self.passwd_fname)
-
-+    def is_ipa_issued_cert(self, api, nickname):
-+        """
-+        Return True if the certificate contained in the CertDB with the
-+        provided nickname has been issued by IPA.
-+
-+        Note that this method can only be executed if api has been initialized
-+        """
-+        # This method needs to compare the cert issuer (from the NSS DB
-+        # and the subject from the CA (from LDAP), because nicknames are not
-+        # always aligned.
-+
-+        cacert_subject = certstore.get_ca_subject(
-+            api.Backend.ldap2,
-+            api.env.container_ca,
-+            api.env.basedn)
-+
-+        # The cert can be issued directly by IPA. In this case, the cert
-+        # issuer is IPA CA subject.
-+        cert = self.get_cert_from_db(nickname)
-+        if cert is None:
-+            raise RuntimeError("Could not find the cert %s in %s"
-+                               % (nickname, self.secdir))
-+        issuer = DN(x509.load_certificate(cert).issuer)
-+
-+        return issuer == cacert_subject
-+
-
- class _CrossProcessLock(object):
-     _DATETIME_FORMAT = '%Y%m%d%H%M%S%f'
-diff --git a/ipaserver/install/dsinstance.py b/ipaserver/install/dsinstance.py
-index 39248edb285ee4d792b4500d83d88b24f5732d10..c9db8ac28c3ca10539b745ca09f4d8aaece02e0c 100644
---- a/ipaserver/install/dsinstance.py
-+++ b/ipaserver/install/dsinstance.py
-@@ -1028,22 +1028,59 @@ class DsInstance(service.Service):
-                 root_logger.error(
-                     'Unable to restart DS instance %s: %s', ds_instance, e)
-
-+    def get_server_cert_nickname(self, serverid=None):
-+        """
-+        Retrieve the nickname of the server cert used by dirsrv.
-+
-+        The method directly reads the dse.ldif to find the attribute
-+        nsSSLPersonalitySSL of cn=RSA,cn=encryption,cn=config because
-+        LDAP is not always accessible when we need to get the nickname
-+        (for instance during uninstall).
-+        """
-+        if serverid is None:
-+            serverid = self.get_state("serverid")
-+        if serverid is not None:
-+            dirname = config_dirname(serverid)
-+            config_file = os.path.join(dirname, "dse.ldif")
-+            rsa_dn = "cn=RSA,cn=encryption,cn=config"
-+            with open(config_file, "r") as in_file:
-+                parser = upgradeinstance.GetEntryFromLDIF(
-+                    in_file,
-+                    entries_dn=[rsa_dn])
-+                parser.parse()
-+                try:
-+                    config_entry = parser.get_results()[rsa_dn]
-+                    nickname = config_entry["nsSSLPersonalitySSL"][0]
-+                    return nickname.decode('utf-8')
-+                except (KeyError, IndexError):
-+                    root_logger.error("Unable to find server cert nickname in "
-+                                      "%s", config_file)
-+
-+        root_logger.debug("Falling back to nickname Server-Cert")
-+        return 'Server-Cert'
-+
-     def stop_tracking_certificates(self, serverid=None):
-         if serverid is None:
-             serverid = self.get_state("serverid")
-         if not serverid is None:
-+            nickname = self.get_server_cert_nickname(serverid)
-             # drop the trailing / off the config_dirname so the directory
-             # will match what is in certmonger
-             dirname = config_dirname(serverid)[:-1]
-             dsdb = certs.CertDB(self.realm, nssdir=dirname)
--            dsdb.untrack_server_cert(self.nickname)
-+            dsdb.untrack_server_cert(nickname)
-
-     def start_tracking_certificates(self, serverid):
-+        nickname = self.get_server_cert_nickname(serverid)
-         dirname = config_dirname(serverid)[:-1]
-         dsdb = certs.CertDB(self.realm, nssdir=dirname)
--        dsdb.track_server_cert(self.nickname, self.principal,
--                               dsdb.passwd_fname,
--                               'restart_dirsrv %s' % serverid)
-+        if dsdb.is_ipa_issued_cert(api, nickname):
-+            dsdb.track_server_cert(nickname, self.principal,
-+                                   dsdb.passwd_fname,
-+                                   'restart_dirsrv %s' % serverid)
-+        else:
-+            root_logger.debug("Will not track DS server certificate %s as it "
-+                              "is not issued by IPA", nickname)
-
-     # we could probably move this function into the service.Service
-     # class - it's very generic - all we need is a way to get an
-diff --git a/ipaserver/install/httpinstance.py b/ipaserver/install/httpinstance.py
-index f637b97db8f21ddbc00c4f70e18e836d300b2f33..e55edebc5d4e45d7cb4cb66d28a270e6d6a56e33 100644
---- a/ipaserver/install/httpinstance.py
-+++ b/ipaserver/install/httpinstance.py
-@@ -266,6 +266,11 @@ class HTTPInstance(service.Service):
-         installutils.set_directive(
-             paths.HTTPD_NSS_CONF, 'NSSNickname', quoted_nickname, quotes=False)
-
-+    def get_mod_nss_nickname(self):
-+        cert = installutils.get_directive(paths.HTTPD_NSS_CONF, 'NSSNickname')
-+        nickname = installutils.unquote_directive_value(cert, quote_char="'")
-+        return nickname
-+
-     def set_mod_nss_protocol(self):
-         installutils.set_directive(paths.HTTPD_NSS_CONF, 'NSSProtocol', 'TLSv1.0,TLSv1.1,TLSv1.2', False)
-
-@@ -582,12 +587,17 @@ class HTTPInstance(service.Service):
-
-     def stop_tracking_certificates(self):
-         db = certs.CertDB(api.env.realm, nssdir=paths.HTTPD_ALIAS_DIR)
--        db.untrack_server_cert(self.cert_nickname)
-+        db.untrack_server_cert(self.get_mod_nss_nickname())
-
-     def start_tracking_certificates(self):
-         db = certs.CertDB(self.realm, nssdir=paths.HTTPD_ALIAS_DIR)
--        db.track_server_cert(self.cert_nickname, self.principal,
--                             db.passwd_fname, 'restart_httpd')
-+        nickname = self.get_mod_nss_nickname()
-+        if db.is_ipa_issued_cert(api, nickname):
-+            db.track_server_cert(nickname, self.principal,
-+                                 db.passwd_fname, 'restart_httpd')
-+        else:
-+            root_logger.debug("Will not track HTTP server cert %s as it is "
-+                              "not issued by IPA", nickname)
-
-     def request_service_keytab(self):
-         super(HTTPInstance, self).request_service_keytab()
-diff --git a/ipaserver/install/server/upgrade.py b/ipaserver/install/server/upgrade.py
-index 109e922e3a3ea25f882fdd81765788a3881e87bd..0947766c076251e7608241803d3a1eabee65ae11 100644
---- a/ipaserver/install/server/upgrade.py
-+++ b/ipaserver/install/server/upgrade.py
-@@ -957,13 +957,13 @@ def certificate_renewal_update(ca, ds, http):
-         },
-         {
-             'cert-database': paths.HTTPD_ALIAS_DIR,
--            'cert-nickname': 'Server-Cert',
-+            'cert-nickname': http.get_mod_nss_nickname(),
-             'ca': 'IPA',
-             'cert-postsave-command': template % 'restart_httpd',
-         },
-         {
-             'cert-database': dsinstance.config_dirname(serverid),
--            'cert-nickname': 'Server-Cert',
-+            'cert-nickname': ds.get_server_cert_nickname(serverid),
-             'ca': 'IPA',
-             'cert-postsave-command':
-                 '%s %s' % (template % 'restart_dirsrv', serverid),
---
-2.13.5
\ No newline at end of file
diff --git a/SOURCES/0227-Always-check-peer-has-keys-before-connecting.patch b/SOURCES/0227-Always-check-peer-has-keys-before-connecting.patch
deleted file mode 100644
index 684f4a0..0000000
--- a/SOURCES/0227-Always-check-peer-has-keys-before-connecting.patch
+++ /dev/null
@@ -1,73 +0,0 @@
-From 82e860ae81b9e34fc6a326be4183f37a21ac1564 Mon Sep 17 00:00:00 2001
-From: Simo Sorce <simo@redhat.com>
-Date: Fri, 23 Jun 2017 04:48:41 -0400
-Subject: [PATCH] Always check peer has keys before connecting
-
-When pulling the DM password we may have the same issues reported in
-ticket #6838 for CA keys.
-This commit makes sure we always check the peer has keys before any
-client operation.
-
-Ticket #6838
-
-Signed-off-by: Simo Sorce <simo@redhat.com>
-Reviewed-By: Stanislav Laznicka <slaznick@redhat.com>
-Reviewed-By: Michal Reznik <mreznik@redhat.com>
----
- ipaserver/install/custodiainstance.py | 20 ++++++++------------
- 1 file changed, 8 insertions(+), 12 deletions(-)
-
-diff --git a/ipaserver/install/custodiainstance.py b/ipaserver/install/custodiainstance.py
-index 390576bc0c0edfb7d8f8895eca9df30079526aa8..bc3cea7063dff183c85b4f6e8ced7567f691001d 100644
---- a/ipaserver/install/custodiainstance.py
-+++ b/ipaserver/install/custodiainstance.py
-@@ -13,7 +13,6 @@ from ipaserver.install import ldapupdate
- from ipaserver.install import sysupgrade
- from base64 import b64decode
- from jwcrypto.common import json_decode
--import functools
- import shutil
- import os
- import stat
-@@ -31,13 +30,6 @@ class CustodiaInstance(SimpleServiceInstance):
-         self.ldap_uri = None
-         self.fqdn = host_name
-         self.realm = realm
--        self.__CustodiaClient = functools.partial(
--            CustodiaClient,
--            client_service='host@%s' % self.fqdn,
--            keyfile=self.server_keys,
--            keytab=paths.KRB5_KEYTAB,
--            realm=realm,
--        )
-
-     def __config_file(self):
-         template_file = os.path.basename(self.config_file) + '.template'
-@@ -144,6 +136,14 @@ class CustodiaInstance(SimpleServiceInstance):
-                     raise RuntimeError("Timed out trying to obtain keys.")
-                 time.sleep(1)
-
-+    def __CustodiaClient(self, server):
-+        # Before we attempt to fetch keys from this host, make sure our public
-+        # keys have been replicated there.
-+        self.__wait_keys(server)
-+
-+        return CustodiaClient('host@%s' % self.fqdn, self.server_keys,
-+                              paths.KRB5_KEYTAB, server, realm=self.realm)
-+
-     def __get_keys(self, ca_host, cacerts_file, cacerts_pwd, data):
-         # Fecth all needed certs one by one, then combine them in a single
-         # p12 file
-@@ -151,10 +151,6 @@ class CustodiaInstance(SimpleServiceInstance):
-         prefix = data['prefix']
-         certlist = data['list']
-
--        # Before we attempt to fetch keys from this host, make sure our public
--        # keys have been replicated there.
--        self.__wait_keys(ca_host)
--
-         cli = self.__CustodiaClient(server=ca_host)
-
-         # Temporary nssdb
---
-2.13.5
\ No newline at end of file
diff --git a/SOURCES/0228-Make-sure-upgrade-also-checks-for-IPv6-stack.patch b/SOURCES/0228-Make-sure-upgrade-also-checks-for-IPv6-stack.patch
deleted file mode 100644
index 600401d..0000000
--- a/SOURCES/0228-Make-sure-upgrade-also-checks-for-IPv6-stack.patch
+++ /dev/null
@@ -1,61 +0,0 @@
-From 010f6405288b1ca519d684d85ca25ce86de60b66 Mon Sep 17 00:00:00 2001
-From: Alexander Bokovoy <abokovoy@redhat.com>
-Date: Tue, 19 Sep 2017 12:06:39 +0300
-Subject: [PATCH] Make sure upgrade also checks for IPv6 stack
-
- - Add check for IPv6 stack to upgrade process
- - Change IPv6 checker to also check that localhost resolves to ::1
-
-Part of fixes https://pagure.io/freeipa/issue/7083
-
-Reviewed-By: Tomas Krizek <tkrizek@redhat.com>
----
- ipaplatform/redhat/tasks.py         | 19 ++++++++++++++++---
- ipaserver/install/server/upgrade.py |  1 +
- 2 files changed, 17 insertions(+), 3 deletions(-)
-
-diff --git a/ipaplatform/redhat/tasks.py b/ipaplatform/redhat/tasks.py
-index 07efebab97eabcf2dc39bd345920a1c7be56e9f5..94d1863c5cc20ec6c2399f339ce19498976553bc 100644
---- a/ipaplatform/redhat/tasks.py
-+++ b/ipaplatform/redhat/tasks.py
-@@ -153,9 +153,22 @@ class RedHatTaskNamespace(BaseTaskNamespace):
-         """
-         if not os.path.exists(paths.IF_INET6):
-             raise RuntimeError(
--                "IPv6 kernel module has to be enabled. If you do not wish to "
--                "use IPv6, please disable it on the interfaces in "
--                "sysctl.conf and enable the IPv6 kernel module.")
-+                "IPv6 stack has to be enabled in the kernel and some "
-+                "interface has to have ::1 address assigned. Typically "
-+                "this is 'lo' interface. If you do not wish to use IPv6 "
-+                "globally, disable it on the specific interfaces in "
-+                "sysctl.conf except 'lo' interface.")
-+
-+        try:
-+            localhost6 = ipautil.CheckedIPAddress('::1', allow_loopback=True)
-+            if localhost6.get_matching_interface() is None:
-+                raise ValueError("no interface for ::1 address found")
-+        except ValueError:
-+            raise RuntimeError(
-+                 "IPv6 stack is enabled in the kernel but there is no "
-+                 "interface that has ::1 address assigned. Add ::1 address "
-+                 "resolution to 'lo' interface. You might need to enable IPv6 "
-+                 "on the interface 'lo' in sysctl.conf.")
- 
-     def restore_pre_ipa_client_configuration(self, fstore, statestore,
-                                              was_sssd_installed,
-diff --git a/ipaserver/install/server/upgrade.py b/ipaserver/install/server/upgrade.py
-index 0947766c076251e7608241803d3a1eabee65ae11..1c4b2357d5d016b8a7501f46380d5e0a61dc21a0 100644
---- a/ipaserver/install/server/upgrade.py
-+++ b/ipaserver/install/server/upgrade.py
-@@ -1860,6 +1860,7 @@ def upgrade_configuration():
- def upgrade_check(options):
-     try:
-         installutils.check_server_configuration()
-+        tasks.check_ipv6_stack_enabled()
-     except RuntimeError as e:
-         root_logger.error(e)
-         sys.exit(1)
--- 
-2.13.5
-
diff --git a/SOURCES/0229-control-logging-of-host_port_open-from-caller.patch b/SOURCES/0229-control-logging-of-host_port_open-from-caller.patch
deleted file mode 100644
index 951e7c2..0000000
--- a/SOURCES/0229-control-logging-of-host_port_open-from-caller.patch
+++ /dev/null
@@ -1,103 +0,0 @@
-From fbaa55fbe8447745a20c99a68d62790f5dd5a0f7 Mon Sep 17 00:00:00 2001
-From: Petr Vobornik <pvoborni@redhat.com>
-Date: Thu, 3 Aug 2017 15:48:33 +0200
-Subject: [PATCH] control logging of host_port_open from caller
-
-host_port_open copied logging behavior of ipa-replica-conncheck utility
-which doesn't make it much reusable.
-
-Now log level can be controlled from caller so other callers might use
-other logging level without host_port_open guessing what was the
-intention.
-
-https://pagure.io/freeipa/issue/7083
-
-Reviewed-By: Tomas Krizek <tkrizek@redhat.com>
----
- install/tools/ipa-replica-conncheck |  9 ++++++++-
- ipapython/ipautil.py                | 17 ++++++-----------
- 2 files changed, 14 insertions(+), 12 deletions(-)
-
-diff --git a/install/tools/ipa-replica-conncheck b/install/tools/ipa-replica-conncheck
-index 528242268f9992e903781b76a379039d533853c0..f10b7e3d2f94540dba3956bf460c4b9f38da90da 100755
---- a/install/tools/ipa-replica-conncheck
-+++ b/install/tools/ipa-replica-conncheck
-@@ -46,6 +46,8 @@ import distutils.spawn
- from ipaplatform.paths import paths
- import gssapi
- from cryptography.hazmat.primitives import serialization
-+import logging
-+
- 
- CONNECT_TIMEOUT = 5
- RESPONDER = None
-@@ -379,11 +381,16 @@ class PortResponder(threading.Thread):
- def port_check(host, port_list):
-     ports_failed = []
-     ports_udp_warning = []  # conncheck could not verify that port is open
-+    log_level = {
-+        SOCK_DGRAM: logging.WARNING,
-+        SOCK_STREAM: logging.ERROR
-+    }
-     for port in port_list:
-         try:
-             port_open = ipautil.host_port_open(
-                 host, port.port, port.port_type,
--                socket_timeout=CONNECT_TIMEOUT, log_errors=True)
-+                socket_timeout=CONNECT_TIMEOUT, log_errors=True,
-+                log_level=log_level[port.port_type])
-         except socket.gaierror:
-             raise RuntimeError("Port check failed! Unable to resolve host name '%s'" % host)
-         if port_open:
-diff --git a/ipapython/ipautil.py b/ipapython/ipautil.py
-index 5a6bf5a27d5a6e25c51fbaa6e2b1167652e2735d..e1e6e32b15559486caecb070627db82e14a57bdf 100644
---- a/ipapython/ipautil.py
-+++ b/ipapython/ipautil.py
-@@ -42,6 +42,7 @@ from contextlib import contextmanager
- import locale
- import collections
- from subprocess import CalledProcessError
-+import logging
- 
- from dns import resolver, reversename
- from dns.exception import DNSException
-@@ -948,7 +949,8 @@ def user_input(prompt, default = None, allow_empty = True):
- 
- 
- def host_port_open(host, port, socket_type=socket.SOCK_STREAM,
--                   socket_timeout=None, log_errors=False):
-+                   socket_timeout=None, log_errors=False,
-+                   log_level=logging.DEBUG):
-     """
-     host: either hostname or IP address;
-           if hostname is provided, port MUST be open on ALL resolved IPs
-@@ -970,23 +972,16 @@ def host_port_open(host, port, socket_type=socket.SOCK_STREAM,
-             s.connect(sa)
- 
-             if socket_type == socket.SOCK_DGRAM:
--                s.send('')
-+                s.send(b'')
-                 s.recv(512)
-         except socket.error:
-             port_open = False
--
-             if log_errors:
--                msg = ('Failed to connect to port %(port)d %(proto)s on '
-+                msg = ('Failed to connect to port %(port)s %(proto)s on '
-                        '%(addr)s' % dict(port=port,
-                                          proto=PROTOCOL_NAMES[socket_type],
-                                          addr=sa[0]))
--
--                # Do not log udp failures as errors (to be consistent with
--                # the rest of the code that checks for open ports)
--                if socket_type == socket.SOCK_DGRAM:
--                    root_logger.warning(msg)
--                else:
--                    root_logger.error(msg)
-+                root_logger.log(log_level, msg)
-         finally:
-             if s is not None:
-                 s.close()
--- 
-2.13.5
-
diff --git a/SOURCES/0230-log-progress-of-wait_for_open_ports.patch b/SOURCES/0230-log-progress-of-wait_for_open_ports.patch
deleted file mode 100644
index 480be17..0000000
--- a/SOURCES/0230-log-progress-of-wait_for_open_ports.patch
+++ /dev/null
@@ -1,44 +0,0 @@
-From 647e23eb307e09597f355fb10abfd4c74a4b6f84 Mon Sep 17 00:00:00 2001
-From: Petr Vobornik <pvoborni@redhat.com>
-Date: Thu, 3 Aug 2017 16:03:29 +0200
-Subject: [PATCH] log progress of wait_for_open_ports
-
-To know what to focus on when some check fail. E.g. to detect that
-IPv6 address or its resolution for localhost is misconfigured.
-
-https://pagure.io/freeipa/issue/7083
-
-Reviewed-By: Tomas Krizek <tkrizek@redhat.com>
----
- ipapython/ipautil.py | 7 ++++++-
- 1 file changed, 6 insertions(+), 1 deletion(-)
-
-diff --git a/ipapython/ipautil.py b/ipapython/ipautil.py
-index e1e6e32b15559486caecb070627db82e14a57bdf..59ea84da4ac667a39bdaa9a6fd7d87ab1b6e658d 100644
---- a/ipapython/ipautil.py
-+++ b/ipapython/ipautil.py
-@@ -1213,15 +1213,20 @@ def wait_for_open_ports(host, ports, timeout=0):
-     op_timeout = time.time() + timeout
- 
-     for port in ports:
-+        root_logger.debug('waiting for port: %s', port)
-+        log_error = True
-         while True:
--            port_open = host_port_open(host, port)
-+            port_open = host_port_open(host, port, log_errors=log_error)
-+            log_error = False  # Log only first err so that the log is readable
- 
-             if port_open:
-+                root_logger.debug('SUCCESS: port: %s', port)
-                 break
-             if timeout and time.time() > op_timeout: # timeout exceeded
-                 raise socket.timeout("Timeout exceeded")
-             time.sleep(1)
- 
-+
- def wait_for_open_socket(socket_name, timeout=0):
-     """
-     Wait until the specified socket on the local host is open. Timeout
--- 
-2.13.5
-
diff --git a/SOURCES/0231-Store-help-in-Schema-before-writing-to-disk.patch b/SOURCES/0231-Store-help-in-Schema-before-writing-to-disk.patch
deleted file mode 100644
index b336e43..0000000
--- a/SOURCES/0231-Store-help-in-Schema-before-writing-to-disk.patch
+++ /dev/null
@@ -1,39 +0,0 @@
-From 5693c0fe6dfe998fa5ea3f86f477dc9dcbfab881 Mon Sep 17 00:00:00 2001
-From: David Kreitschmann <david@kreitschmann.de>
-Date: Fri, 7 Apr 2017 18:22:25 +0200
-Subject: [PATCH] Store help in Schema before writing to disk
-
-Signed-off-by: David Kreitschmann <david@kreitschmann.de>
-Reviewed-By: David Kupka <dkupka@redhat.com>
-Reviewed-By: Martin Babinsky <mbabinsk@redhat.com>
-Reviewed-By: David Kupka <dkupka@redhat.com>
-Reviewed-By: Martin Babinsky <mbabinsk@redhat.com>
-Reviewed-By: Rob Crittenden <rcritten@redhat.com>
----
- ipaclient/remote_plugins/schema.py | 3 ++-
- 1 file changed, 2 insertions(+), 1 deletion(-)
-
-diff --git a/ipaclient/remote_plugins/schema.py b/ipaclient/remote_plugins/schema.py
-index 3ecd608f96e336df57739db380a00c2d95b2ece5..9b6668d26352a24d7249bac5e304277563ee450f 100644
---- a/ipaclient/remote_plugins/schema.py
-+++ b/ipaclient/remote_plugins/schema.py
-@@ -383,6 +383,7 @@ class Schema(object):
- 
-         if fingerprint is None:
-             fingerprint, ttl = self._fetch(client, ignore_cache=read_failed)
-+            self._help = self._generate_help(self._dict)
-             try:
-                 self._write_schema(fingerprint)
-             except Exception as e:
-@@ -498,7 +499,7 @@ class Schema(object):
- 
-             schema.writestr(
-                 '_help',
--                json.dumps(self._generate_help(self._dict)).encode('utf-8')
-+                json.dumps(self._help).encode('utf-8')
-             )
- 
-     def read_namespace_member(self, namespace, member):
--- 
-2.13.5
-
diff --git a/SOURCES/0232-Disable-pylint-in-get_help-function-because-of-type-.patch b/SOURCES/0232-Disable-pylint-in-get_help-function-because-of-type-.patch
deleted file mode 100644
index 6d97395..0000000
--- a/SOURCES/0232-Disable-pylint-in-get_help-function-because-of-type-.patch
+++ /dev/null
@@ -1,33 +0,0 @@
-From df9933a8cbc5c6cf4041709ed61c589adaae7a08 Mon Sep 17 00:00:00 2001
-From: David Kreitschmann <david@kreitschmann.de>
-Date: Fri, 9 Jun 2017 17:59:35 +0200
-Subject: [PATCH] Disable pylint in get_help function because of type
- confusion.
-
-Reviewed-By: David Kupka <dkupka@redhat.com>
-Reviewed-By: Martin Babinsky <mbabinsk@redhat.com>
-Reviewed-By: David Kupka <dkupka@redhat.com>
-Reviewed-By: Martin Babinsky <mbabinsk@redhat.com>
-Reviewed-By: Rob Crittenden <rcritten@redhat.com>
----
- ipaclient/remote_plugins/schema.py | 4 +++-
- 1 file changed, 3 insertions(+), 1 deletion(-)
-
-diff --git a/ipaclient/remote_plugins/schema.py b/ipaclient/remote_plugins/schema.py
-index 9b6668d26352a24d7249bac5e304277563ee450f..2892ab9ec7c6fb092ef470b7e5bd2b9c0760c2af 100644
---- a/ipaclient/remote_plugins/schema.py
-+++ b/ipaclient/remote_plugins/schema.py
-@@ -516,7 +516,9 @@ class Schema(object):
- 
-     def get_help(self, namespace, member):
-         if isinstance(self._help, bytes):
--            self._help = json.loads(self._help.decode('utf-8'))
-+            self._help = json.loads(
-+                self._help.decode('utf-8')  # pylint: disable=no-member
-+            )
- 
-         return self._help[namespace][member]
- 
--- 
-2.13.5
-
diff --git a/SOURCES/0233-Less-confusing-message-for-PKINIT-configuration-duri.patch b/SOURCES/0233-Less-confusing-message-for-PKINIT-configuration-duri.patch
deleted file mode 100644
index 6cbca7b..0000000
--- a/SOURCES/0233-Less-confusing-message-for-PKINIT-configuration-duri.patch
+++ /dev/null
@@ -1,50 +0,0 @@
-From ad0f85945daa0b0bfbddbcde992c5388c170518f Mon Sep 17 00:00:00 2001
-From: Aleksei Slaikovskii <aslaikov@redhat.com>
-Date: Wed, 18 Oct 2017 09:52:08 +0200
-Subject: [PATCH] Less confusing message for PKINIT configuration during
- install
-
-The message about an error during replica setup was causing the
-users to think the installation gone wrong even though this was
-an expected behavior when ipa-replica-install was ran without
---no-pkinit flag and CA somehow is not reachable which defines
-that there is something wrong in a topology but does not lead
-to failure of the replica's installation. So now installation
-will not print error messages to stdout but rather will give a
-recomendation to user and write the old error message to log
-as a warning so it still will be easy to find if needed.
-
-https://pagure.io/freeipa/issue/7179
-
-Reviewed-By: Tomas Krizek <tkrizek@redhat.com>
----
- ipaserver/install/krbinstance.py | 13 +++++++++++--
- 1 file changed, 11 insertions(+), 2 deletions(-)
-
-diff --git a/ipaserver/install/krbinstance.py b/ipaserver/install/krbinstance.py
-index 6b51e65d1ec985bfc01f167aea3fe3ca11c7ec29..34fe46aa8ef297bf69eb74953c956ad9c3d30def 100644
---- a/ipaserver/install/krbinstance.py
-+++ b/ipaserver/install/krbinstance.py
-@@ -494,8 +494,17 @@ class KrbInstance(service.Service):
-             self._install_pkinit_ca_bundle()
-             self.pkinit_enable()
-         except RuntimeError as e:
--            root_logger.error("PKINIT certificate request failed: %s", e)
--            root_logger.error("Failed to configure PKINIT")
-+            root_logger.warning("PKINIT certificate request failed: %s", e)
-+            root_logger.warning("Failed to configure PKINIT")
-+
-+            self.print_msg("Full PKINIT configuration did not succeed")
-+            self.print_msg(
-+                "The setup will only install bits "
-+                "essential to the server functionality")
-+            self.print_msg(
-+                "You can enable PKINIT after the "
-+                "setup completed using 'ipa-pkinit-manage'")
-+
-             self.stop_tracking_certs()
-             self.issue_selfsigned_pkinit_certs()
- 
--- 
-2.13.5
-
diff --git a/SOURCES/0234-server.py-Removes-dns-server-configuration-from-ldap.patch b/SOURCES/0234-server.py-Removes-dns-server-configuration-from-ldap.patch
deleted file mode 100644
index fe12f23..0000000
--- a/SOURCES/0234-server.py-Removes-dns-server-configuration-from-ldap.patch
+++ /dev/null
@@ -1,45 +0,0 @@
-From d71488fd450615ade6c10978af38d0dda27ec859 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Tibor=20Dudl=C3=A1k?= <tdudlak@redhat.com>
-Date: Tue, 6 Jun 2017 15:13:26 +0200
-Subject: [PATCH] server.py: Removes dns-server configuration from ldap
-
-After invocation of the ipa server-del <hostname>
-command there was still record in ldap if DNS
-was installed on the <hostname> server.
-
-Fixes: https://pagure.io/freeipa/issue/6572
-Reviewed-By: Martin Basti <mbasti@redhat.com>
----
- ipaserver/plugins/server.py | 9 +++++++++
- 1 file changed, 9 insertions(+)
-
-diff --git a/ipaserver/plugins/server.py b/ipaserver/plugins/server.py
-index b1ee4722841509f4614c688ac39095c723aff167..e0dc953a1ef870c95fdcdb629fb6ab3103e8f999 100644
---- a/ipaserver/plugins/server.py
-+++ b/ipaserver/plugins/server.py
-@@ -692,6 +692,12 @@ class server_del(LDAPDelete):
-                     message=_("You may need to manually remove them from the "
-                               "tree")))
- 
-+    def _cleanup_server_dns_config(self, hostname):
-+        try:
-+            self.api.Command.dnsserver_del(hostname)
-+        except errors.NotFound:
-+            pass
-+
-     def pre_callback(self, ldap, dn, *keys, **options):
-         pkey = self.obj.get_primary_key_from_dn(dn)
- 
-@@ -731,6 +737,9 @@ class server_del(LDAPDelete):
-         # try to clean up the leftover DNS entries
-         self._cleanup_server_dns_records(pkey)
- 
-+        # try to clean up the DNS config from ldap
-+        self._cleanup_server_dns_config(pkey)
-+
-         return dn
- 
-     def exc_callback(self, keys, options, exc, call_func, *call_args,
--- 
-2.13.5
-
diff --git a/SOURCES/0235-Include-the-CA-basic-constraint-in-CSRs-when-renewin.patch b/SOURCES/0235-Include-the-CA-basic-constraint-in-CSRs-when-renewin.patch
deleted file mode 100644
index 2ff94ff..0000000
--- a/SOURCES/0235-Include-the-CA-basic-constraint-in-CSRs-when-renewin.patch
+++ /dev/null
@@ -1,75 +0,0 @@
-From a6b7f433c1c8c30e455f345fcd97e7428ae63322 Mon Sep 17 00:00:00 2001
-From: Rob Crittenden <rcritten@redhat.com>
-Date: Wed, 9 Aug 2017 17:28:35 -0400
-Subject: [PATCH] Include the CA basic constraint in CSRs when renewing a CA
-
-The CSR generated by `ipa-cacert-manage renew --external-ca` did
-not include the CA basic constraint:
-
-  X509v3 Basic Constraints: critical
-      CA:TRUE
-
-Add a flag to certmonger::resubmit_request to specify that a
-CA is being requested.
-
-Note that this also sets pathlen to -1 which means an unlimited
-pathlen. Leave it up to the issuing CA to set this.
-
-https://pagure.io/freeipa/issue/7088
-
-Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
-Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
----
- ipalib/install/certmonger.py           | 13 +++++++++++--
- ipaserver/install/ipa_cacert_manage.py |  3 ++-
- 2 files changed, 13 insertions(+), 3 deletions(-)
-
-diff --git a/ipalib/install/certmonger.py b/ipalib/install/certmonger.py
-index c286996ee2318e241b4af190d1a01f42e28aa9f3..d2b782ddb0c746a3dfd96d0222bb31c6a960fdff 100644
---- a/ipalib/install/certmonger.py
-+++ b/ipalib/install/certmonger.py
-@@ -519,16 +519,25 @@ def modify(request_id, ca=None, profile=None):
-         request.obj_if.modify(update)
- 
- 
--def resubmit_request(request_id, ca=None, profile=None):
-+def resubmit_request(request_id, ca=None, profile=None, is_ca=False):
-+    """
-+    :param request_id: the certmonger numeric request ID
-+    :param ca: the nickname for the certmonger CA, e.g. IPA or SelfSign
-+    :param profile: the dogtag template profile to use, e.g. SubCA
-+    :param is_ca: boolean that if True adds the CA basic constraint
-+    """
-     request = _get_request({'nickname': request_id})
-     if request:
--        if ca or profile:
-+        if ca or profile or is_ca:
-             update = {}
-             if ca is not None:
-                 cm = _certmonger()
-                 update['CA'] = cm.obj_if.find_ca_by_nickname(ca)
-             if profile is not None:
-                 update['template-profile'] = profile
-+            if is_ca:
-+                update['template-is-ca'] = True
-+                update['template-ca-path-length'] = -1  # no path length
-             request.obj_if.modify(update)
-         request.obj_if.resubmit()
- 
-diff --git a/ipaserver/install/ipa_cacert_manage.py b/ipaserver/install/ipa_cacert_manage.py
-index fcbf09155a3abc9ce9481aa2519ed39aaa6aa9bb..9607620d6c3e63b70b9e586f94282bf478c8c53e 100644
---- a/ipaserver/install/ipa_cacert_manage.py
-+++ b/ipaserver/install/ipa_cacert_manage.py
-@@ -310,7 +310,8 @@ class CACertManage(admintool.AdminTool):
-         timeout = api.env.startup_timeout + 60
- 
-         self.log.debug("resubmitting certmonger request '%s'", self.request_id)
--        certmonger.resubmit_request(self.request_id, ca=ca, profile=profile)
-+        certmonger.resubmit_request(self.request_id, ca=ca, profile=profile,
-+                                    is_ca=True)
-         try:
-             state = certmonger.wait_for_request(self.request_id, timeout)
-         except RuntimeError:
--- 
-2.13.5
-
diff --git a/SOURCES/0236-Checks-if-replica-s4u2proxy.ldif-should-be-applied.patch b/SOURCES/0236-Checks-if-replica-s4u2proxy.ldif-should-be-applied.patch
deleted file mode 100644
index 54a13e6..0000000
--- a/SOURCES/0236-Checks-if-replica-s4u2proxy.ldif-should-be-applied.patch
+++ /dev/null
@@ -1,51 +0,0 @@
-From f6ce0099adc7c8508b3bf2f82102c1dd70fa08dc Mon Sep 17 00:00:00 2001
-From: Felipe Barreto <fbarreto@redhat.com>
-Date: Fri, 13 Oct 2017 09:19:43 +0200
-Subject: [PATCH] Checks if replica-s4u2proxy.ldif should be applied
-
-Before applying replica-s3u2proxy.ldif, we check
-if the values are already there. The values can be
-there if a replica installation was done in the past
-and some info was left behind. Also, the code checks
-the values independently.
-
-https://pagure.io/freeipa/issue/7174
-
-Reviewed-By: Rob Crittenden <rcritten@redhat.com>
----
- ipaserver/install/dsinstance.py | 19 ++++++++++++++++++-
- 1 file changed, 18 insertions(+), 1 deletion(-)
-
-diff --git a/ipaserver/install/dsinstance.py b/ipaserver/install/dsinstance.py
-index c9db8ac28c3ca10539b745ca09f4d8aaece02e0c..f7edcffc5904d8c9ce46f5862d496a4df3ad8d75 100644
---- a/ipaserver/install/dsinstance.py
-+++ b/ipaserver/install/dsinstance.py
-@@ -930,7 +930,24 @@ class DsInstance(service.Service):
-         self._ldap_mod("replica-acis.ldif", self.sub_dict)
- 
-     def __setup_s4u2proxy(self):
--        self._ldap_mod("replica-s4u2proxy.ldif", self.sub_dict)
-+
-+        def __add_principal(last_cn, principal, self):
-+            dn = DN(('cn', last_cn), ('cn', 's4u2proxy'),
-+                    ('cn', 'etc'), self.suffix)
-+
-+            value = '{principal}/{fqdn}@{realm}'.format(fqdn=self.fqdn,
-+                                                        realm=self.realm,
-+                                                        principal=principal)
-+
-+            entry = api.Backend.ldap2.get_entry(dn, ['memberPrincipal'])
-+            try:
-+                entry['memberPrincipal'].append(value)
-+                api.Backend.ldap2.update_entry(entry)
-+            except errors.EmptyModlist:
-+                pass
-+
-+        __add_principal('ipa-http-delegation', 'HTTP', self)
-+        __add_principal('ipa-ldap-delegation-targets', 'ldap', self)
- 
-     def __create_indices(self):
-         self._ldap_mod("indices.ldif")
--- 
-2.13.5
-
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 24c8cb4..a577d73 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 7a5799402ddfbe2704afa4449bb597f2feeea6c2 Mon Sep 17 00:00:00 2001
+From 70850c65eaefffc73d4f39cd9cc5490a6a5bb785 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
@@ -34,6 +34,7 @@ Subject: [PATCH] Change branding to IPA and Identity Management
  install/tools/man/ipa-managed-entries.1    |   2 +-
  install/tools/man/ipa-nis-manage.1         |   2 +-
  install/tools/man/ipa-otptoken-import.1    |   2 +-
+ install/tools/man/ipa-pkinit-manage.1      |   2 +-
  install/tools/man/ipa-replica-conncheck.1  |   2 +-
  install/tools/man/ipa-replica-install.1    |   6 +-
  install/tools/man/ipa-replica-manage.1     |   2 +-
@@ -42,6 +43,7 @@ Subject: [PATCH] Change branding to IPA and Identity Management
  install/tools/man/ipa-server-certinstall.1 |   2 +-
  install/tools/man/ipa-server-install.1     |   4 +-
  install/tools/man/ipa-server-upgrade.1     |   2 +-
+ install/tools/man/ipa-winsync-migrate.1    |   2 +-
  install/tools/man/ipactl.8                 |   2 +-
  install/ui/css/patternfly.css              |   2 +-
  install/ui/index.html                      |   2 +-
@@ -55,7 +57,8 @@ Subject: [PATCH] Change branding to IPA and Identity Management
  ipaserver/install/ipa_kra_install.py       |   4 +-
  ipaserver/install/server/install.py        |   2 +-
  ipaserver/install/server/replicainstall.py |   2 +-
- 51 files changed, 163 insertions(+), 118 deletions(-)
+ ipaserver/plugins/sudorule.py              |   4 +-
+ 54 files changed, 167 insertions(+), 122 deletions(-)
 
 diff --git a/client/man/default.conf.5 b/client/man/default.conf.5
 index 35ce6bb9f871365ffbc74b66be46d49fdcb3f7ad..b519d15bca9b7ddf8d22a776fa4f4a8c7fac0ca8 100644
@@ -318,10 +321,10 @@ index 1484598adba5b1237f00cc55e95167d45a6b40d7..5aa9233ff3c8b811fa96eba8b34b0b02
      # print "  * Add a SID to all users and Posix groups"
      print("")
 diff --git a/install/tools/ipa-replica-conncheck b/install/tools/ipa-replica-conncheck
-index 528242268f9992e903781b76a379039d533853c0..d51103803d6a2a9e05fcc5ac35f4f6d11b84df44 100755
+index 545cdf00ca74289e6532a40de4c9abad5af4cee0..3741b87f7eb9bb9fe0a01ef1369ac934f288f939 100755
 --- a/install/tools/ipa-replica-conncheck
 +++ b/install/tools/ipa-replica-conncheck
-@@ -288,7 +288,7 @@ class PortResponder(threading.Thread):
+@@ -289,7 +289,7 @@ class PortResponder(threading.Thread):
          self._sockets = []
          self._close = False
          self._close_lock = threading.Lock()
@@ -377,15 +380,15 @@ index ff9759ec77d54f32532c4ececfa5081daab9ec15..476f9b534d514b03200369212807fc6d
  ipa\-backup \- Back up an IPA master
  .SH "SYNOPSIS"
 diff --git a/install/tools/man/ipa-ca-install.1 b/install/tools/man/ipa-ca-install.1
-index 76ce11524e88202740626cb00ce9c1c3b774f659..f5f6522d6780411125e668453c0d4c4293a81a8a 100644
+index 79703a47c0d1f72151926565085c8943fcf311a4..895805296f45ba6effd58e196f1ee5cb73ff986e 100644
 --- a/install/tools/man/ipa-ca-install.1
 +++ b/install/tools/man/ipa-ca-install.1
 @@ -16,7 +16,7 @@
  .\"
  .\" Author: Rob Crittenden <rcritten@redhat.com>
  .\"
--.TH "ipa-ca-install" "1" "Jun 17 2011" "FreeIPA" "FreeIPA Manual Pages"
-+.TH "ipa-ca-install" "1" "Jun 17 2011" "IPA" "IPA Manual Pages"
+-.TH "ipa-ca-install" "1" "Mar 30 2017" "FreeIPA" "FreeIPA Manual Pages"
++.TH "ipa-ca-install" "1" "Mar 30 2017" "IPA" "IPA Manual Pages"
  .SH "NAME"
  ipa\-ca\-install \- Install a CA on a server
  .SH "SYNOPSIS"
@@ -515,6 +518,19 @@ index 920a08ca2c2f996d6281483f5c65bac6b412d6d5..fe91040fabd1cad7c395aafd6afc68ed
  .SH "NAME"
  ipa\-otptoken\-import \- Imports OTP tokens from RFC 6030 XML file
  .SH "SYNOPSIS"
+diff --git a/install/tools/man/ipa-pkinit-manage.1 b/install/tools/man/ipa-pkinit-manage.1
+index 5018ce8aa3f89470453d9cfc590a0c5f44f78f3c..50d63e9213c6e0a279c4de3c6a92024c90db0a0f 100644
+--- a/install/tools/man/ipa-pkinit-manage.1
++++ b/install/tools/man/ipa-pkinit-manage.1
+@@ -1,7 +1,7 @@
+ .\"
+ .\" Copyright (C) 2017  FreeIPA Contributors see COPYING for license
+ .\"
+-.TH "ipa-pkinit-manage" "1" "Jun 05 2017" "FreeIPA" "FreeIPA Manual Pages"
++.TH "ipa-pkinit-manage" "1" "Jun 05 2017" "IPA" "IPA Manual Pages"
+ .SH "NAME"
+ ipa\-pkinit\-manage \- Enables or disables PKINIT
+ .SH "SYNOPSIS"
 diff --git a/install/tools/man/ipa-replica-conncheck.1 b/install/tools/man/ipa-replica-conncheck.1
 index 4fc55e8bf585f3612310f31282e9d3705c824dd1..6c4d94b7d67da016ec37a89b040ec8192dabe3dc 100644
 --- a/install/tools/man/ipa-replica-conncheck.1
@@ -646,6 +662,19 @@ index cbbdc590171bff0a88b67bcf1de961fd783ac35c..3db19b0f13da1f5a36bd6e8df23fc916
  .SH "NAME"
  ipa\-server\-upgrade \- upgrade IPA server
  .SH "SYNOPSIS"
+diff --git a/install/tools/man/ipa-winsync-migrate.1 b/install/tools/man/ipa-winsync-migrate.1
+index 88702bad6fca66206dcbc1a90fce495eb33598fb..1812f6348d704adeda00325a0a9e7ddb6fe400d3 100644
+--- a/install/tools/man/ipa-winsync-migrate.1
++++ b/install/tools/man/ipa-winsync-migrate.1
+@@ -16,7 +16,7 @@
+ .\"
+ .\" Author: Tomas Babej <tbabej@redhat.com>
+ .\"
+-.TH "ipa-winsync-migrate" "1" "Mar 10 2015" "FreeIPA" "FreeIPA Manual Pages"
++.TH "ipa-winsync-migrate" "1" "Mar 10 2015" "IPA" "IPA Manual Pages"
+ .SH "NAME"
+ ipa\-winsync\-migrate \- Seamless migration of AD users created by winsync to native AD users.
+ .SH "SYNOPSIS"
 diff --git a/install/tools/man/ipactl.8 b/install/tools/man/ipactl.8
 index fb533aae2009628473654a85e3a9b006e4f17b1f..d7aaaf8edab49b3e763fb3d73f69b97bc75a2202 100644
 --- a/install/tools/man/ipactl.8
@@ -947,7 +976,7 @@ index 1c1aac06a18fe3c1f63b5881c7887f6a4cfc9ac2..c4c1bbb5ab073e4a9b357fd12018fd7e
          print("This includes:")
          print("  * Configure DNS (bind)")
 diff --git a/ipaserver/install/ipa_kra_install.py b/ipaserver/install/ipa_kra_install.py
-index 8369d2f4082d35b453487ee0f17c9ce050188daf..4688e78c581825472c61693ea1ab7efad37634bc 100644
+index 3e08f4da94651b49876e1427daddbd957f0027ae..c2af9f8462d776d452e4b90d9779f38c47040baf 100644
 --- a/ipaserver/install/ipa_kra_install.py
 +++ b/ipaserver/install/ipa_kra_install.py
 @@ -86,7 +86,7 @@ class KRAInstall(admintool.AdminTool):
@@ -969,7 +998,7 @@ index 8369d2f4082d35b453487ee0f17c9ce050188daf..4688e78c581825472c61693ea1ab7efa
      '''
  
 diff --git a/ipaserver/install/server/install.py b/ipaserver/install/server/install.py
-index dced253e7f039dc9d66466bf8bcd777e53919f54..2906cad2f4535a5f4aace1e24397314fcad198d5 100644
+index 97cbc6d8c84ee8fc21b6f8983c7897dc5d30c42d..eb42d1aa905a30ddc83de5a145d4e8d1348fbab9 100644
 --- a/ipaserver/install/server/install.py
 +++ b/ipaserver/install/server/install.py
 @@ -373,7 +373,7 @@ def install_check(installer):
@@ -982,7 +1011,7 @@ index dced253e7f039dc9d66466bf8bcd777e53919f54..2906cad2f4535a5f4aace1e24397314f
      print("This includes:")
      if setup_ca:
 diff --git a/ipaserver/install/server/replicainstall.py b/ipaserver/install/server/replicainstall.py
-index 326daf708f091d9d2c56ad399e46aef659dbba2e..0d3fc5a24dcd55aab420db4a6565809dbe8e70a9 100644
+index 6aa1157133423e854514de61a69810433e436d2f..1b3fdb238db46e6cd15dccb7d8d88b08f70d3066 100644
 --- a/ipaserver/install/server/replicainstall.py
 +++ b/ipaserver/install/server/replicainstall.py
 @@ -601,7 +601,7 @@ def check_domain_level_is_supported(current):
@@ -994,6 +1023,28 @@ index 326daf708f091d9d2c56ad399e46aef659dbba2e..0d3fc5a24dcd55aab420db4a6565809d
                     "the Domain Level which is currently set for "
                     "this domain. The Domain Level needs to be "
                     "raised before installing a replica with "
+diff --git a/ipaserver/plugins/sudorule.py b/ipaserver/plugins/sudorule.py
+index 28c3f21f113fd14160abd518663f2d582f8653fd..f70943576d861ce7b3a8bc4c29e9ded86b098e81 100644
+--- a/ipaserver/plugins/sudorule.py
++++ b/ipaserver/plugins/sudorule.py
+@@ -47,7 +47,7 @@ give certain users (or groups of users) the ability to run some (or all)
+ commands as root or another user while providing an audit trail of the
+ commands and their arguments.
+ """) + _("""
+-FreeIPA provides a means to configure the various aspects of Sudo:
++IPA provides a means to configure the various aspects of Sudo:
+    Users: The user(s)/group(s) allowed to invoke Sudo.
+    Hosts: The host(s)/hostgroup(s) which the user is allowed to to invoke Sudo.
+    Allow Command: The specific command(s) permitted to be run via Sudo.
+@@ -60,7 +60,7 @@ An order can be added to a sudorule to control the order in which they
+ are evaluated (if the client supports it). This order is an integer and
+ must be unique.
+ """) + _("""
+-FreeIPA provides a designated binddn to use with Sudo located at:
++IPA provides a designated binddn to use with Sudo located at:
+ uid=sudo,cn=sysaccounts,cn=etc,dc=example,dc=com
+ """) + _("""
+ To enable the binddn run the following command to set the password:
 -- 
-2.13.5
+2.9.5
 
diff --git a/SOURCES/1002-Package-copy-schema-to-ca.py.patch b/SOURCES/1002-Package-copy-schema-to-ca.py.patch
index f8d9079..744cd83 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 6013929e6ae2ea5cce4437281b3ee019b33ec151 Mon Sep 17 00:00:00 2001
+From 0cb701b1b4492b8e7234991eef30b5ac77dbd328 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,10 +10,10 @@ This reverts commit f4c7f1dd8a9ce530a8291219a904686ee47e59c7.
  2 files changed, 5 insertions(+), 2 deletions(-)
 
 diff --git a/freeipa.spec.in b/freeipa.spec.in
-index 721e512039a4d7f9d2ed94d7620b083732c56304..99e69d81dd4104063ac68a9429eeb53ee1d36245 100644
+index a8b5ce81fcf9bdb61cd3707e6b68b6f2196e0776..5fc0982188da4f7a3a1438bd5c67aac7bed195a8 100644
 --- a/freeipa.spec.in
 +++ b/freeipa.spec.in
-@@ -1285,6 +1285,7 @@ fi
+@@ -1293,6 +1293,7 @@ fi
  # END
  %dir %{_usr}/share/ipa
  %{_usr}/share/ipa/wsgi.py*
@@ -40,5 +40,5 @@ index 62f79b28000b015edb66f4c39a270097ab3ed666..d876c5b385a250f3bd9c2689f9794ef7
  
  
 -- 
-2.13.5
+2.9.5
 
diff --git a/SOURCES/1003-Revert-Increased-mod_wsgi-socket-timeout.patch b/SOURCES/1003-Revert-Increased-mod_wsgi-socket-timeout.patch
index 45987ae..d4638ad 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 3faf68ad37710c6650fdb12fc1b5751896a6e7e0 Mon Sep 17 00:00:00 2001
+From cf83189d36e1615444b83dc2bf3b27fad215b322 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"
@@ -24,5 +24,5 @@ index 01bf9a4f97fc0cf197c0ad12743affa597b54911..d3389ec5d34dba6429986b1c2a6dfb21
  WSGIScriptAlias /ipa /usr/share/ipa/wsgi.py
  WSGIScriptReloading Off
 -- 
-2.13.5
+2.9.5
 
diff --git a/SOURCES/1004-Remove-csrgen.patch b/SOURCES/1004-Remove-csrgen.patch
index 5707809..dabefc9 100644
--- a/SOURCES/1004-Remove-csrgen.patch
+++ b/SOURCES/1004-Remove-csrgen.patch
@@ -1,4 +1,4 @@
-From f0851afdf0abd516dcd707e6e3ec0086f09f6090 Mon Sep 17 00:00:00 2001
+From f6463c332aebb40be39bcfdf458f20f1dc3d2bbe 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
@@ -35,7 +35,7 @@ https://bugzilla.redhat.com/show_bug.cgi?id=1432630
  ipaclient/csrgen/templates/openssl_macros.tmpl     |  29 --
  ipaclient/plugins/cert.py                          |  96 +----
  ipaclient/plugins/csrgen.py                        | 120 -------
- ipaclient/setup.py                                 |  11 +-
+ ipaclient/setup.py                                 |   7 -
  ipalib/errors.py                                   |  28 --
  ipatests/setup.py                                  |   2 -
  ipatests/test_ipaclient/__init__.py                |   7 -
@@ -48,7 +48,7 @@ https://bugzilla.redhat.com/show_bug.cgi?id=1432630
  .../data/test_csrgen/scripts/userCert_openssl.sh   |  34 --
  .../data/test_csrgen/templates/identity_base.tmpl  |   1 -
  ipatests/test_ipaclient/test_csrgen.py             | 298 ---------------
- 29 files changed, 2 insertions(+), 1316 deletions(-)
+ 29 files changed, 1 insertion(+), 1313 deletions(-)
  delete mode 100644 ipaclient/csrgen.py
  delete mode 100644 ipaclient/csrgen/profiles/caIPAserviceCert.json
  delete mode 100644 ipaclient/csrgen/profiles/userCert.json
@@ -75,10 +75,10 @@ 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 99e69d81dd4104063ac68a9429eeb53ee1d36245..3892e502c0c64cca25e2e50a0ff53a15a556d2f3 100644
+index 5fc0982188da4f7a3a1438bd5c67aac7bed195a8..03ab5d374279ad62d536ac5da636b7654671bcb9 100644
 --- a/freeipa.spec.in
 +++ b/freeipa.spec.in
-@@ -194,7 +194,6 @@ BuildRequires:  python-sssdconfig
+@@ -198,7 +198,6 @@ BuildRequires:  python-sssdconfig
  BuildRequires:  python-nose
  BuildRequires:  python-paste
  BuildRequires:  systemd-python
@@ -86,7 +86,7 @@ index 99e69d81dd4104063ac68a9429eeb53ee1d36245..3892e502c0c64cca25e2e50a0ff53a15
  BuildRequires:  python-augeas
  
  %if 0%{?with_python3}
-@@ -232,7 +231,6 @@ BuildRequires:  python3-libsss_nss_idmap
+@@ -236,7 +235,6 @@ BuildRequires:  python3-libsss_nss_idmap
  BuildRequires:  python3-nose
  BuildRequires:  python3-paste
  BuildRequires:  python3-systemd
@@ -94,7 +94,7 @@ index 99e69d81dd4104063ac68a9429eeb53ee1d36245..3892e502c0c64cca25e2e50a0ff53a15
  BuildRequires:  python3-augeas
  %endif # with_python3
  %endif # with_lint
-@@ -541,7 +539,6 @@ Requires: %{name}-client-common = %{version}-%{release}
+@@ -545,7 +543,6 @@ Requires: %{name}-client-common = %{version}-%{release}
  Requires: %{name}-common = %{version}-%{release}
  Requires: python2-ipalib = %{version}-%{release}
  Requires: python-dns >= 1.15
@@ -102,7 +102,7 @@ index 99e69d81dd4104063ac68a9429eeb53ee1d36245..3892e502c0c64cca25e2e50a0ff53a15
  
  %description -n python2-ipaclient
  IPA is an integrated solution to provide centrally managed Identity (users,
-@@ -564,7 +561,6 @@ Requires: %{name}-client-common = %{version}-%{release}
+@@ -568,7 +565,6 @@ Requires: %{name}-client-common = %{version}-%{release}
  Requires: %{name}-common = %{version}-%{release}
  Requires: python3-ipalib = %{version}-%{release}
  Requires: python3-dns >= 1.15
@@ -110,9 +110,9 @@ index 99e69d81dd4104063ac68a9429eeb53ee1d36245..3892e502c0c64cca25e2e50a0ff53a15
  
  %description -n python3-ipaclient
  IPA is an integrated solution to provide centrally managed Identity (users,
-@@ -1425,13 +1421,6 @@ fi
- %dir %{python_sitelib}/ipaclient/remote_plugins
+@@ -1434,13 +1430,6 @@ fi
  %{python_sitelib}/ipaclient/remote_plugins/*.py*
+ %dir %{python_sitelib}/ipaclient/remote_plugins/2_*
  %{python_sitelib}/ipaclient/remote_plugins/2_*/*.py*
 -%dir %{python_sitelib}/ipaclient/csrgen
 -%dir %{python_sitelib}/ipaclient/csrgen/profiles
@@ -124,8 +124,8 @@ index 99e69d81dd4104063ac68a9429eeb53ee1d36245..3892e502c0c64cca25e2e50a0ff53a15
  %{python_sitelib}/ipaclient-*.egg-info
  
  
-@@ -1455,13 +1444,6 @@ fi
- %{python3_sitelib}/ipaclient/remote_plugins/__pycache__/*.py*
+@@ -1465,13 +1454,6 @@ fi
+ %dir %{python3_sitelib}/ipaclient/remote_plugins/2_*
  %{python3_sitelib}/ipaclient/remote_plugins/2_*/*.py
  %{python3_sitelib}/ipaclient/remote_plugins/2_*/__pycache__/*.py*
 -%dir %{python3_sitelib}/ipaclient/csrgen
@@ -1078,10 +1078,10 @@ index a0d99ef06445de268cd1872a025d0613e245ae6c..00000000000000000000000000000000
 -            result=result
 -        )
 diff --git a/ipaclient/setup.py b/ipaclient/setup.py
-index f5be7ea61f554f04d7bde46c84182f6148820600..e3f31d2b9c46a2668a0e9264ea0cfda06aeeaa2e 100644
+index d39235ab237fb2dbf902866ddcc5e92f8767bcc8..9c6a1558a2d2eace9afbc008a4cb86939fb0047f 100644
 --- a/ipaclient/setup.py
 +++ b/ipaclient/setup.py
-@@ -43,18 +43,10 @@ if __name__ == '__main__':
+@@ -42,13 +42,6 @@ if __name__ == '__main__':
              "ipaclient.remote_plugins.2_156",
              "ipaclient.remote_plugins.2_164",
          ],
@@ -1095,19 +1095,6 @@ index f5be7ea61f554f04d7bde46c84182f6148820600..e3f31d2b9c46a2668a0e9264ea0cfda0
          install_requires=[
              "cryptography",
              "ipalib",
-             "ipapython",
--            "jinja2",
-             "python-yubico",
-             "pyusb",
-             "qrcode",
-@@ -63,6 +55,5 @@ if __name__ == '__main__':
-         extras_require={
-             "install": ["ipaplatform"],
-             "otptoken_yubikey": ["yubico", "usb"]
--        },
--        zip_safe=False,
-+        }
-     )
 diff --git a/ipalib/errors.py b/ipalib/errors.py
 index 6aaca708a02e609f11c4aa5ef5fe2b4a8ae8a941..88707ac313fa7c5ec247b3f9b71f96925f5627e2 100644
 --- a/ipalib/errors.py
@@ -1148,10 +1135,10 @@ index 6aaca708a02e609f11c4aa5ef5fe2b4a8ae8a941..88707ac313fa7c5ec247b3f9b71f9692
      """
      **4100** Base class for builtin execution errors (*4100 - 4199*).
 diff --git a/ipatests/setup.py b/ipatests/setup.py
-index 46d51ff1ccdec7b2288955b8e5abdc2b971d3d17..fe65626ec7fe09701810a99a5fb8a8ede9697f46 100644
+index c6c9cb69dbed0561365a10a08061ccc6fe0f372e..712576be6c7a523d3c23a23bdf55289e21ac8867 100644
 --- a/ipatests/setup.py
 +++ b/ipatests/setup.py
-@@ -38,7 +38,6 @@ if __name__ == '__main__':
+@@ -39,7 +39,6 @@ if __name__ == '__main__':
              "ipatests.test_cmdline",
              "ipatests.test_install",
              "ipatests.test_integration",
@@ -1159,7 +1146,7 @@ index 46d51ff1ccdec7b2288955b8e5abdc2b971d3d17..fe65626ec7fe09701810a99a5fb8a8ed
              "ipatests.test_ipalib",
              "ipatests.test_ipapython",
              "ipatests.test_ipaserver",
-@@ -52,7 +51,6 @@ if __name__ == '__main__':
+@@ -53,7 +52,6 @@ if __name__ == '__main__':
          package_data={
              'ipatests.test_install': ['*.update'],
              'ipatests.test_integration': ['scripts/*'],
@@ -1662,5 +1649,5 @@ index 556f8e096976387d24057084c06d53bcb9998a69..00000000000000000000000000000000
 -            _script = generator.csr_script(
 -                principal, {}, 'example', 'identity')
 -- 
-2.13.5
+2.9.5
 
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 f82a3c8..af85707 100644
--- a/SPECS/ipa.spec
+++ b/SPECS/ipa.spec
@@ -37,14 +37,18 @@
 # 1.15.1-7: certauth (http://krbdev.mit.edu/rt/Ticket/Display.html?id=8561)
 %global krb5_version 1.15.1-4
 # Require 4.6.0-4 which brings RC4 for FIPS + trust fixes to priv. separation
-%global samba_version 4.6.0-4
+%global samba_version 4.7.0
+# 0.7.16: https://github.com/drkjam/netaddr/issues/71
+%global python_netaddr_version 0.7.5-9
 %global selinux_policy_version 3.13.1-70
 %global slapi_nis_version 0.56.0-4
 %else
 # 1.15.1-7: certauth (http://krbdev.mit.edu/rt/Ticket/Display.html?id=8561)
 %global krb5_version 1.15.1-7
 # Require 4.6.0-4 which brings RC4 for FIPS + trust fixes to priv. separation
-%global samba_version 2:4.6.0-4
+%global samba_version 2:4.7.0
+# 0.7.16: https://github.com/drkjam/netaddr/issues/71
+%global python_netaddr_version 0.7.16
 %global selinux_policy_version 3.13.1-158.4
 %global slapi_nis_version 0.56.1
 %endif
@@ -59,7 +63,7 @@
 
 # Work-around fact that RPM SPEC parser does not accept
 # "Version: @VERSION@" in freeipa.spec.in used for Autoconf string replacement
-%define IPA_VERSION 4.5.0
+%define IPA_VERSION 4.5.4
 %define AT_SIGN @
 # redefine IPA_VERSION only if its value matches the Autoconf placeholder
 %if "%{IPA_VERSION}" == "%{AT_SIGN}VERSION%{AT_SIGN}"
@@ -68,7 +72,7 @@
 
 Name:           ipa
 Version:        %{IPA_VERSION}
-Release:        22%{?dist}
+Release:        10%{?dist}
 Summary:        The Identity, Policy and Audit system
 
 Group:          System Environment/Base
@@ -76,258 +80,59 @@ 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)
 
 # RHEL spec file only: START
-Patch0001:      0001-Add-options-to-allow-ticket-caching.patch
-Patch0002:      0002-Use-connection-keep-alive.patch
-Patch0003:      0003-Add-debug-logging-for-keep-alive.patch
-Patch0004:      0004-Increase-Apache-HTTPD-s-default-keep-alive-timeout.patch
-Patch0005:      0005-ipapython.ipautil.nolog_replace-Do-not-replace-empty.patch
-Patch0006:      0006-tasks-run-systemctl-daemon-reload-after-httpd.servic.patch
-Patch0007:      0007-man-ipa-cacert-manage-install-needs-clarification.patch
-Patch0008:      0008-certs-do-not-implicitly-create-DS-pin.txt.patch
-Patch0009:      0009-httpinstance-clean-up-etc-httpd-alias-on-uninstall.patch
-Patch0010:      0010-Fixing-replica-install-fix-ldap-connection-in-domlvl.patch
-Patch0011:      0011-replica-prepare-fix-wrong-IPA-CA-nickname-in-replica.patch
-Patch0012:      0012-ldap2-use-LDAP-whoami-operation-to-retrieve-bind-DN-.patch
-Patch0013:      0013-Backup-ipa-specific-httpd-unit-file.patch
-Patch0014:      0014-WebUI-check-principals-in-lowercase.patch
-Patch0015:      0015-WebUI-add-method-for-disabling-item-in-user-dropdown.patch
-Patch0016:      0016-WebUI-Add-support-for-login-for-AD-users.patch
-Patch0017:      0017-cert-do-not-limit-internal-searches-in-cert-find.patch
-Patch0018:      0018-ipa-kdb-add-ipadb_fetch_principals_with_extra_filter.patch
-Patch0019:      0019-IPA-certauth-plugin.patch
-Patch0020:      0020-configure-fix-disable-server-with-certauth-plugin.patch
-Patch0021:      0021-ipa-kdb-do-not-depend-on-certauth_plugin.h.patch
-Patch0022:      0022-WebUI-Add-support-for-suppressing-warnings.patch
-Patch0023:      0023-WebUI-suppress-truncation-warning-in-select-widget.patch
-Patch0024:      0024-WebUI-Fix-showing-vault-in-selfservice-view.patch
-Patch0025:      0025-Set-KDC-Disable-Last-Success-by-default.patch
-Patch0026:      0026-WebUI-Allow-to-add-certs-to-certmapping-with-CERT-LI.patch
-Patch0027:      0027-Bump-samba-version-for-FIPS-and-priv.-separation.patch
-Patch0028:      0028-Reworked-the-renaming-mechanism.patch
-Patch0029:      0029-Allow-renaming-of-the-HBAC-rule-objects.patch
-Patch0030:      0030-Allow-renaming-of-the-sudorule-objects.patch
-Patch0031:      0031-Create-temporaty-directories-at-the-begining-of-unin.patch
-Patch0032:      0032-dogtag-ipa-ca-renew-agent-submit-fix-the-is_replicat.patch
-Patch0033:      0033-Simplify-KRA-transport-cert-cache.patch
-Patch0034:      0034-rpcserver.login_x509-Actually-return-reply-from-__ca.patch
-Patch0035:      0035-Backup-CA-cert-from-kerberos-folder.patch
-Patch0036:      0036-spec-file-Bump-requires-to-make-Certificate-Login-in.patch
-Patch0037:      0037-Use-Custodia-0.3.1-features.patch
-Patch0038:      0038-spec-file-bump-krb5-devel-BuildRequires-for-certauth.patch
-Patch0039:      0039-Avoid-growing-FILE-ccaches-unnecessarily.patch
-Patch0040:      0040-Handle-failed-authentication-via-cookie.patch
-Patch0041:      0041-Work-around-issues-fetching-session-data.patch
-Patch0042:      0042-Prevent-churn-on-ccaches.patch
-Patch0043:      0043-Generate-PIN-for-PKI-to-help-Dogtag-in-FIPS.patch
-Patch0044:      0044-httpinstance.disable_system_trust-Don-t-fail-if-modu.patch
-Patch0045:      0045-extdom-do-reverse-search-for-domain-separator.patch
-Patch0046:      0046-extdom-improve-cert-request.patch
-Patch0047:      0047-spec-file-bump-libsss_nss_idmap-devel-BuildRequires.patch
-Patch0048:      0048-server-make-sure-we-test-for-sss_nss_getlistbycert.patch
-Patch0049:      0049-Upgrade-configure-PKINIT-after-adding-anonymous-prin.patch
-Patch0050:      0050-Remove-unused-variable-from-failed-anonymous-PKINIT-.patch
-Patch0051:      0051-Split-out-anonymous-PKINIT-test-to-a-separate-method.patch
-Patch0052:      0052-Ensure-KDC-is-propery-configured-after-upgrade.patch
-Patch0053:      0053-adtrust-make-sure-that-runtime-hostname-result-is-co.patch
-Patch0054:      0054-Allow-erasing-ipaDomainResolutionOrder-attribute.patch
-Patch0055:      0055-Always-check-and-create-anonymous-principal-during-K.patch
-Patch0056:      0056-Remove-duplicate-functionality-in-upgrade.patch
-Patch0057:      0057-Fix-the-order-of-cert-files-check.patch
-Patch0058:      0058-Don-t-allow-setting-pkinit-related-options-on-DL0.patch
-Patch0059:      0059-replica-prepare-man-remove-pkinit-option-refs.patch
-Patch0060:      0060-Remove-redundant-option-check-for-cert-files.patch
-Patch0061:      0061-Hide-request_type-doc-string-in-cert-request-help.patch
-Patch0062:      0062-Get-correct-CA-cert-nickname-in-CA-less.patch
-Patch0063:      0063-Remove-publish_ca_cert-method-from-NSSDatabase.patch
-Patch0064:      0064-httpinstance-make-sure-NSS-database-is-backed-up.patch
-Patch0065:      0065-IPA-KDB-use-relative-path-in-ipa-certmap-config-snip.patch
-Patch0066:      0066-Add-pki_pin-only-when-needed.patch
-Patch0067:      0067-idrange-add-properly-handle-empty-dom-name-option.patch
-Patch0068:      0068-ipa-sam-create-the-gidNumber-attribute-in-the-truste.patch
-Patch0069:      0069-Upgrade-add-gidnumber-to-trusted-domain-entry.patch
-Patch0070:      0070-dsinstance-reconnect-ldap2-after-DS-is-restarted-by-.patch
-Patch0071:      0071-httpinstance-avoid-httpd-restart-during-certificate-.patch
-Patch0072:      0072-dsinstance-httpinstance-consolidate-certificate-requ.patch
-Patch0073:      0073-install-request-service-certs-after-host-keytab-is-s.patch
-Patch0074:      0074-renew-agent-revert-to-host-keytab-authentication.patch
-Patch0075:      0075-renew-agent-restart-scripts-connect-to-LDAP-after-ki.patch
-Patch0076:      0076-ipaserver-dcerpc-unify-error-processing.patch
-Patch0077:      0077-trust-always-use-oddjobd-helper-for-fetching-trust-i.patch
-Patch0078:      0078-WebUI-cert-login-Configure-name-of-parameter-used-to.patch
-Patch0079:      0079-Create-system-users-for-FreeIPA-services-during-pack.patch
-Patch0080:      0080-Fix-s4u2self-with-adtrust.patch
-Patch0081:      0081-Add-debug-log-in-case-cookie-retrieval-went-wrong.patch
-Patch0082:      0082-server-install-remove-broken-no-pkinit-check.patch
-Patch0083:      0083-Add-the-force-join-option-to-replica-install.patch
-Patch0084:      0084-replicainstall-better-client-install-exception-handl.patch
-Patch0085:      0085-Fix-CA-less-to-CA-full-upgrade.patch
-Patch0086:      0086-cert-defer-cert-find-result-post-processing.patch
-Patch0087:      0087-server-install-No-double-Kerberos-install.patch
-Patch0088:      0088-ext.-CA-correctly-write-the-cert-chain.patch
-Patch0089:      0089-Fix-RA-cert-import-during-DL0-replication.patch
-Patch0090:      0090-configure-fix-AC_CHECK_LIB-usage.patch
-Patch0091:      0091-Fix-CAInstance.import_ra_cert-for-empty-passwords.patch
-Patch0092:      0092-upgrade-adtrust-update_tdo_gidnumber-plugin-must-che.patch
-Patch0093:      0093-compat-manage-behave-the-same-for-all-users.patch
-Patch0094:      0094-Move-the-compat-plugin-setup-at-the-end-of-install.patch
-Patch0095:      0095-compat-ignore-cn-topology-cn-ipa-cn-etc-subtree.patch
-Patch0096:      0096-spec-file-bump-krb5-Requires-for-certauth-fixes.patch
-Patch0097:      0097-Hide-PKI-Client-database-password-in-log-file.patch
-Patch0098:      0098-Vault-Explicitly-default-to-3DES-CBC.patch
-Patch0099:      0099-separate-function-to-set-ipaConfigString-values-on-s.patch
-Patch0100:      0100-Allow-for-configuration-of-all-three-PKINIT-variants.patch
-Patch0101:      0101-API-for-retrieval-of-master-s-PKINIT-status-and-publ.patch
-Patch0102:      0102-Use-only-anonymous-PKINIT-to-fetch-armor-ccache.patch
-Patch0103:      0103-Stop-requesting-anonymous-keytab-and-purge-all-refer.patch
-Patch0104:      0104-Use-local-anchor-when-armoring-password-requests.patch
-Patch0105:      0105-Upgrade-configure-local-full-PKINIT-depending-on-the.patch
-Patch0106:      0106-Do-not-test-anonymous-PKINIT-after-install-upgrade.patch
-Patch0107:      0107-vault-piped-input-for-ipa-vault-add-fails.patch
-Patch0108:      0108-automount-install-fix-checking-of-SSSD-functionality.patch
-Patch0109:      0109-Fix-CA-server-cert-validation-in-FIPS.patch
-Patch0110:      0110-restore-restart-reload-gssproxy-after-restore.patch
-Patch0111:      0111-kerberos-session-use-CA-cert-with-full-cert-chain-fo.patch
-Patch0112:      0112-ipa-client-install-remove-extra-space-in-pkinit_anch.patch
-Patch0113:      0113-Refresh-Dogtag-RestClient.ca_host-property.patch
-Patch0114:      0114-Remove-the-cachedproperty-class.patch
-Patch0115:      0115-ipa-server-install-with-external-CA-fix-pkinit-cert-.patch
-Patch0116:      0116-kra-install-update-installation-failure-message.patch
-Patch0117:      0117-Make-sure-remote-hosts-have-our-keys.patch
-Patch0118:      0118-Use-proper-SELinux-context-with-http.keytab.patch
-Patch0119:      0119-ipa-kra-install-fix-check_host_keys.patch
-Patch0120:      0120-python2-ipalib-add-missing-python-dependency.patch
-Patch0121:      0121-installer-service-fix-typo-in-service-entry.patch
-Patch0122:      0122-upgrade-add-missing-suffix-to-http-instance.patch
-Patch0123:      0123-Turn-on-NSSOCSP-check-in-mod_nss-conf.patch
-Patch0124:      0124-cert-show-writable-files-does-not-mean-dirs.patch
-Patch0125:      0125-Bump-version-of-ipa.conf-file.patch
-Patch0126:      0126-ipa-kra-install-manpage-document-domain-level-1.patch
-Patch0127:      0127-renew-agent-respect-CA-renewal-master-setting.patch
-Patch0128:      0128-server-upgrade-always-fix-certmonger-tracking-reques.patch
-Patch0129:      0129-cainstance-use-correct-profile-for-lightweight-CA-ce.patch
-Patch0130:      0130-renew-agent-allow-reusing-existing-certs.patch
-Patch0131:      0131-renew-agent-always-export-CSR-on-IPA-CA-certificate-.patch
-Patch0132:      0132-renew-agent-get-rid-of-virtual-profiles.patch
-Patch0133:      0133-ipa-cacert-manage-add-external-ca-type.patch
-Patch0134:      0134-Fixing-adding-authenticator-indicators-to-host.patch
-Patch0135:      0135-Added-plugins-directory-to-ipaclient-subpackages.patch
-Patch0136:      0136-ipaclient-fix-missing-RPM-ownership.patch
-Patch0137:      0137-otptoken-add-yubikey-When-digits-not-provided-use-de.patch
-Patch0138:      0138-ipa-server-install-fix-uninstall.patch
-Patch0139:      0139-ca-install-merge-duplicated-code-for-DM-password.patch
-Patch0140:      0140-installutils-add-DM-password-validator.patch
-Patch0141:      0141-ca-kra-install-validate-DM-password.patch
-Patch0142:      0142-ipa-kra-install-fix-pkispawn-setting-for-pki_securit.patch
-Patch0143:      0143-certdb-add-named-trust-flag-constants.patch
-Patch0144:      0144-certdb-certs-make-trust-flags-argument-mandatory.patch
-Patch0145:      0145-certdb-use-custom-object-for-trust-flags.patch
-Patch0146:      0146-install-trust-IPA-CA-for-PKINIT.patch
-Patch0147:      0147-client-install-fix-client-PKINIT-configuration.patch
-Patch0148:      0148-install-introduce-generic-Kerberos-Augeas-lens.patch
-Patch0149:      0149-server-install-fix-KDC-PKINIT-configuration.patch
-Patch0150:      0150-ipapython.ipautil.run-Add-option-to-set-umask-before.patch
-Patch0151:      0151-certs-do-not-export-keys-world-readable-in-install_k.patch
-Patch0152:      0152-certs-do-not-export-CA-certs-in-install_pem_from_p12.patch
-Patch0153:      0153-server-install-fix-KDC-certificate-validation-in-CA-.patch
-Patch0154:      0154-replica-install-respect-pkinit-cert-file.patch
-Patch0155:      0155-cacert-manage-support-PKINIT.patch
-Patch0156:      0156-server-certinstall-support-PKINIT.patch
-Patch0157:      0157-ipa-ca-install-append-CA-cert-chain-into-etc-ipa-ca..patch
-Patch0158:      0158-ca-cert-show-check-certificate_out-in-options.patch
-Patch0159:      0159-Fix-rare-race-condition-with-missing-ccache-file.patch
-Patch0160:      0160-Remove-pkinit-anonymous-command.patch
-Patch0161:      0161-krb5-make-sure-KDC-certificate-is-readable.patch
-Patch0162:      0162-Change-python-cryptography-to-python2-cryptography.patch
-Patch0163:      0163-Allow-for-multivalued-server-attributes.patch
-Patch0164:      0164-Refactor-the-role-attribute-member-reporting-code.patch
-Patch0165:      0165-Add-an-attribute-reporting-client-PKINIT-capable-ser.patch
-Patch0166:      0166-Add-the-list-of-PKINIT-servers-as-a-virtual-attribut.patch
-Patch0167:      0167-Add-pkinit-status-command.patch
-Patch0168:      0168-test_serverroles-Get-rid-of-MockLDAP-and-use-ldap2-i.patch
-Patch0169:      0169-only-stop-disable-simple-service-if-it-is-installed.patch
-Patch0170:      0170-Fix-index-definition-for-ipaAnchorUUID.patch
-Patch0171:      0171-httpinstance-wait-until-the-service-entry-is-replica.patch
-Patch0172:      0172-kdc.key-should-not-be-visible-to-all.patch
-Patch0173:      0173-ipa-kdb-reload-certificate-mapping-rules-periodicall.patch
-Patch0174:      0174-Avoid-possible-endless-recursion-in-RPC-call.patch
-Patch0175:      0175-rpc-preparations-for-recursion-fix.patch
-Patch0176:      0176-rpc-avoid-possible-recursion-in-create_connection.patch
-Patch0177:      0177-Changing-cert-find-to-do-not-use-only-primary-key-to.patch
-Patch0178:      0178-ipa-kdb-add-pkinit-authentication-indicator-in-case-.patch
-Patch0179:      0179-fix-incorrect-suffix-handling-in-topology-checks.patch
-Patch0180:      0180-server-certinstall-update-KDC-master-entry.patch
-Patch0181:      0181-pkinit-manage-introduce-ipa-pkinit-manage.patch
-Patch0182:      0182-server-upgrade-do-not-enable-PKINIT-by-default.patch
-Patch0183:      0183-Turn-off-OCSP-check.patch
-Patch0184:      0184-Only-warn-when-specified-server-IP-addresses-don-t-m.patch
-Patch0185:      0185-ipa-kdb-use-canonical-principal-in-certauth-plugin.patch
-Patch0186:      0186-Bump-version-of-python-gssapi.patch
-Patch0187:      0187-Add-code-to-be-able-to-set-default-kinit-lifetime.patch
-Patch0188:      0188-Revert-setting-sessionMaxAge-for-old-clients.patch
-Patch0189:      0189-Extend-the-advice-printing-code-by-some-useful-abstr.patch
-Patch0190:      0190-Prepare-advise-plugin-for-smart-card-auth-configurat.patch
-Patch0191:      0191-trust-mod-allow-modifying-list-of-UPNs-of-a-trusted-.patch
-Patch0192:      0192-WebUI-add-support-for-changing-trust-UPN-suffixes.patch
-Patch0193:      0193-kra-promote-Get-ticket-before-calling-custodia.patch
-Patch0194:      0194-Fix-local-IP-address-validation.patch
-Patch0195:      0195-ipa-dns-install-remove-check-for-local-ip-address.patch
-Patch0196:      0196-refactor-CheckedIPAddress-class.patch
-Patch0197:      0197-CheckedIPAddress-remove-match_local-param.patch
-Patch0198:      0198-Remove-ip_netmask-from-option-parser.patch
-Patch0199:      0199-replica-install-add-missing-check-for-non-local-IP-a.patch
-Patch0200:      0200-Remove-network-and-broadcast-address-warnings.patch
-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
-Patch0220:      0220-ipa-otptoken-import-Make-PBKDF2-refer-to-the-pkcs5-n.patch
-Patch0221:      0221-Adds-whoami-DS-plugin-in-case-that-plugin-is-missing.patch
-Patch0222:      0222-Fix-ipa-config-mod-ca-renewal-master.patch
-Patch0223:      0223-Backport-PR-988-to-ipa-4-5-Fix-Certificate-renewal-w.patch
-Patch0224:      0224-Backport-PR-1008-to-ipa-4-5-Fix-ipa-server-upgrade-T.patch
-Patch0225:      0225-Fixing-how-sssd.conf-is-updated-when-promoting-a-cli.patch
-Patch0226:      0226-Backport-4-5-Fix-ipa-server-upgrade-with-server-cert.patch
-Patch0227:      0227-Always-check-peer-has-keys-before-connecting.patch
-Patch0228:      0228-Make-sure-upgrade-also-checks-for-IPv6-stack.patch
-Patch0229:      0229-control-logging-of-host_port_open-from-caller.patch
-Patch0230:      0230-log-progress-of-wait_for_open_ports.patch
-Patch0231:      0231-Store-help-in-Schema-before-writing-to-disk.patch
-Patch0232:      0232-Disable-pylint-in-get_help-function-because-of-type-.patch
-Patch0233:      0233-Less-confusing-message-for-PKINIT-configuration-duri.patch
-Patch0234:      0234-server.py-Removes-dns-server-configuration-from-ldap.patch
-Patch0235:      0235-Include-the-CA-basic-constraint-in-CSRs-when-renewin.patch
-Patch0236:      0236-Checks-if-replica-s4u2proxy.ldif-should-be-applied.patch
+Patch0001:      0001-ds-ignore-time-skew-during-initial-replication-step.patch
+Patch0002:      0002-ipa-replica-manage-implicitly-ignore-initial-time-sk.patch
+Patch0003:      0003-Checks-if-replica-s4u2proxy.ldif-should-be-applied.patch
+Patch0004:      0004-ldap-limit-the-retro-changelog-to-dns-subtree.patch
+Patch0005:      0005-Fix-ipa-replica-conncheck-when-called-with-principal.patch
+Patch0006:      0006-Include-the-CA-basic-constraint-in-CSRs-when-renewin.patch
+Patch0007:	0007-ipa-extdom-extop-refactor-nsswitch-operations.patch
+Patch0008:	0008-Add-the-sub-operation-for-fqdn-index-config.patch
+Patch0009:	0009-Add-indexing-to-improve-host-find-performance.patch
+Patch0010:	0010-ipa-getkeytab-man-page-add-more-details-about-the-r-.patch
+Patch0011:	0011-Don-t-allow-OTP-or-RADIUS-in-FIPS-mode.patch
+Patch0012:	0012-Fix-cert-find-for-CA-less-installations.patch
+Patch0013:	0013-Fix-ipa-restore-python2.patch
+Patch0014:	0014-Backup-ipa-custodia-conf-and-keys.patch
+Patch0015:	0015-adtrust-filter-out-subdomains-when-defining-our-topo.patch
+Patch0016:	0016-Fix-ca-less-IPA-install-on-fips-mode.patch
+Patch0017:	0017-trust-detect-and-error-out-when-non-AD-trust-with-IP.patch
+Patch0018:	0018-ipaserver-plugins-trust.py-fix-some-indenting-issues.patch
+Patch0019:	0019-ipaserver-plugins-trust.py-pep8-compliance.patch
+Patch0020:	0020-Don-t-use-admin-cert-during-KRA-installation.patch
+Patch0021:	0021-389-ds-base-crashed-as-part-of-ipa-server-intall-in-.patch
+Patch0022:	0022-Prevent-set_directive-from-clobbering-other-keys.patch
+Patch0023:	0023-pep8-reduce-line-lengths-in-CAInstance.__enable_crl_.patch
+Patch0024:	0024-installutils-refactor-set_directive.patch
+Patch0025:	0025-Add-tests-for-installutils.set_directive.patch
+Patch0026:	0026-Add-safe-DirectiveSetter-context-manager.patch
+Patch0027:	0027-Old-pylint-doesn-t-support-bad-python3-option.patch
+Patch0028:	0028-WebUI-make-keytab-tables-on-service-and-host-pages-w.patch
+Patch0029:	0029-Idviews-fix-objectclass-violation-on-idview-add.patch
+Patch0030:	0030-Fixing-the-cert-request-comparing-whole-email-addres.patch
+Patch0031:	0031-Add-force-join-into-ipa-replica-install-manpage.patch
+Patch0032:	0032-Changed-ownership-of-ldiffile-to-DS_USER.patch
+Patch0033:	0033-Checks-if-Dir-Server-is-installed-and-running-before.patch
+Patch0034:	0034-WebUI-Add-positive-number-validator.patch
+Patch0035:	0035-WebUI-change-validator-of-page-size-settings.patch
+Patch0036:	0036-WebUI-fix-jslint-error.patch
+Patch0037:	0037-ipa-advise-for-smartcards-updated.patch 
 
 Patch1001:      1001-Change-branding-to-IPA-and-Identity-Management.patch
 Patch1002:      1002-Package-copy-schema-to-ca.py.patch
 Patch1003:      1003-Revert-Increased-mod_wsgi-socket-timeout.patch
 Patch1004:      1004-Remove-csrgen.patch
-Patch1005:      ipa-centos-branding.patch
 # RHEL spec file only: END
 
+BuildRequires: libtool, automake, autoconf
 BuildRequires:  openldap-devel
 # For KDB DAL version, make explicit dependency so that increase of version
 # will cause the build to fail due to unsatisfied dependencies.
@@ -363,13 +168,16 @@ BuildRequires:  cyrus-sasl-devel
 BuildRequires:  diffstat
 # RHEL spec file only: END
 %if ! %{ONLY_CLIENT}
+
+BuildRequires: java-1.7.0-openjdk-devel
+
 # 1.3.3.9: DS_Sleep (https://fedorahosted.org/389/ticket/48005)
 BuildRequires:  389-ds-base-devel >= 1.3.3.9
 BuildRequires:  svrcore-devel
 %if 0%{?rhel}
-BuildRequires:  samba-devel >= 4.0.0
+BuildRequires:  samba-devel >= 4.7.0
 %else
-BuildRequires:  samba-devel >= 2:4.0.0
+BuildRequires:  samba-devel >= 2:4.7.0
 %endif
 BuildRequires:  libtalloc-devel
 BuildRequires:  libtevent-devel
@@ -377,7 +185,9 @@ BuildRequires:  libuuid-devel
 BuildRequires:  libsss_idmap-devel
 BuildRequires:  libsss_certmap-devel
 # 1.15.3: sss_nss_getlistbycert (https://pagure.io/SSSD/sssd/issue/3050)
-BuildRequires:  libsss_nss_idmap-devel >= 1.15.2-2
+# 1.16.0-3: sss_nss_getpwnam_timeout (https://pagure.io/SSSD/sssd/issue/2478)
+# provided in both RHEL 7.5 and Fedora 27+ as of 1.16.0-3
+BuildRequires:  libsss_nss_idmap-devel >= 1.16.0-3
 BuildRequires:  rhino
 BuildRequires:  libverto-devel
 BuildRequires:  libunistring-devel
@@ -497,7 +307,6 @@ BuildRequires:  python3-augeas >= 0.5
 #
 %if ! %{ONLY_CLIENT}
 BuildRequires:  libcmocka-devel
-BuildRequires:  nss_wrapper
 # Required by ipa_kdb_tests
 BuildRequires:  %{_libdir}/krb5/plugins/kdb/db2.so
 %endif # ONLY_CLIENT
@@ -919,7 +728,7 @@ Requires: pyOpenSSL
 Requires: python >= 2.7.5-24
 Requires: python-nss >= 0.16
 Requires: python2-cryptography >= 1.4
-Requires: python-netaddr
+Requires: python-netaddr >= %{python_netaddr_version}
 Requires: python-libipa_hbac
 Requires: python-qrcode-core >= 5.0.0
 Requires: python-pyasn1
@@ -968,7 +777,7 @@ Requires: keyutils
 Requires: python3-pyOpenSSL
 Requires: python3-nss >= 0.16
 Requires: python3-cryptography >= 1.4
-Requires: python3-netaddr
+Requires: python3-netaddr >= %{python_netaddr_version}
 Requires: python3-libipa_hbac
 Requires: python3-qrcode-core >= 5.0.0
 Requires: python3-pyasn1
@@ -1122,10 +931,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
 
 
@@ -1164,6 +973,9 @@ find \
 	! -name '*.pyo' -a \
 	-type f -exec grep -qsm1 '^#!.*\bpython' {} \; \
 	-exec sed -i -e '1 s|^#!.*\bpython[^ ]*|#!%{__python3}|' {} \;
+
+# Rebuild configure because Patch1005 adds new configure checks
+./autogen.sh
 %configure --with-vendor-suffix=-%{release} \
            %{enable_server_option} \
            %{with_ipatests_option} \
@@ -1733,6 +1545,7 @@ fi
 %{python_sitelib}/ipaclient/plugins/*.py*
 %dir %{python_sitelib}/ipaclient/remote_plugins
 %{python_sitelib}/ipaclient/remote_plugins/*.py*
+%dir %{python_sitelib}/ipaclient/remote_plugins/2_*
 %{python_sitelib}/ipaclient/remote_plugins/2_*/*.py*
 # RHEL spec file only: DELETED: Remove csrgen
 %{python_sitelib}/ipaclient-*.egg-info
@@ -1756,6 +1569,7 @@ fi
 %dir %{python3_sitelib}/ipaclient/remote_plugins
 %{python3_sitelib}/ipaclient/remote_plugins/*.py
 %{python3_sitelib}/ipaclient/remote_plugins/__pycache__/*.py*
+%dir %{python3_sitelib}/ipaclient/remote_plugins/2_*
 %{python3_sitelib}/ipaclient/remote_plugins/2_*/*.py
 %{python3_sitelib}/ipaclient/remote_plugins/2_*/__pycache__/*.py*
 # RHEL spec file only: DELETED: Remove csrgen
@@ -1873,69 +1687,196 @@ fi
 
 
 %changelog
-* Thu Nov 30 2017 CentOS Sources <bugs@centos.org> - 4.5.0-22.el7.centos
-- Roll in CentOS Branding
-
-* Fri Oct 27 2017 Felipe Barreto <fbarreto@redhat.com> - 4.5.0-22.el7
-- Resolves: #1506528 In case full PKINIT configuration is failing during
-  server/replica install the error message should be more meaningful.
-    - Less confusing message for PKINIT configuration during install
-- Resolves: #1506526 Use X509v3 Basic Constraints "CA:TRUE" instead of
-  "CA:FALSE" IPA CA CSR
-    - Include the CA basic constraint in CSRs when renewing a CA
-- Resolves: #1506913 ipa-replica-install might fail because of an already
+* Wed Feb 07 2018 Florence Blanc-Renaud <frenaud@redhat.com> - 4.5.4-10.el7
+- Resolves: #1540361 ipa-advise for smartcards is out-of-date
+  - ipa-advise for smartcards updated
+
+* Mon Jan 15 2018 Florence Blanc-Renaud <frenaud@redhat.com> - 4.5.4-9.el7
+- Resolves: #1458169 --force-join option is not mentioned in ipa-replica-install man page
+  - Add --force-join into ipa-replica-install manpage
+- Resolves: #1457876 ipa-backup fails silently
+  - Changed ownership of ldiffile to DS_USER
+- Resolves: #1409786 Second phase of --external-ca ipa-server-install setup fails when dirsrv is not running
+  - Checks if Dir Server is installed and running before IPA installation
+- Resolves: #1452086 Pagination Size under Customization in IPA WebUI accepts negative values
+  - WebUI: Add positive number validator
+  - WebUI: change validator of page size settings
+  - WebUI: fix jslint error
+
+* Wed Jan 10 2018 Florence Blanc-Renaud <frenaud@redhat.com> - 4.5.4-8.el7
+- Resolves: #1477531 Incorrect attribute level rights (ipaallowedtoperform) of service object
+  - WebUI: make keytab tables on service and host pages writable
+- Resolves: #1529444 ObjectclassViolation seen while adding idview with domain-resolution-order option
+  - Idviews: fix objectclass violation on idview-add
+- Resolves: #1451576 ipa cert-request failed to generate certificate from csr
+  - Fixing the cert-request comparing whole email address case-sensitively.
+
+* Wed Dec 13 2017 Florence Blanc-Renaud <frenaud@redhat.com> - 4.5.4-7.el7
+- Resolves: #1421869 Unable to re-add broken AD trust - Unexpected Information received
+  - adtrust: filter out subdomains when defining our topology to AD
+- Resolves: #1486286 IPA failing to authenticate via password+OTP on RHEL7.4 with fips enabled
+  - Don't allow OTP or RADIUS in FIPS mode
+- Resolves: #1494226 IPA User Details not being displayed in WebUI
+  - Fix cert-find for CA-less installations
+- Resolves: #1498387 389-ds-base crashed as part of ipa-server-intall in ipa-uuid
+  - 389-ds-base crashed as part of ipa-server-intall in ipa-uuid
+- Resolves: #1503022 ipa-getkeytab man page should have more details about consequences of krb5 key renewal
+  - ipa-getkeytab man page: add more details about the -r option
+- Resolves: #1509288 IPA trust-add internal error (expected security.dom_sid got None)
+  - ipaserver/plugins/trust.py; fix some indenting issues
+  - trust: detect and error out when non-AD trust with IPA domain name exists
+  - ipaserver/plugins/trust.py: pep8 compliance
+- Resolves: #1511019 ipa-restore broken with python2
+  - Fix ipa-restore (python2)
+- Resolves: #1511607 ipa-backup does not backup Custodia keys and files
+  - Backup ipa-custodia conf and keys
+- Resolves: #1512482 kra install fails after ipa cert renewed
+  - Don't use admin cert during KRA installation
+  - Prevent set_directive from clobbering other keys
+  - pep8: reduce line lengths in CAInstance.__enable_crl_publish
+  - installutils: refactor set_directive
+  - Add tests for installutils.set_directive
+  - Add safe DirectiveSetter context manager
+  - Old pylint doesn't support bad python3 option
+- Resolves: #1514163 CA less IPA install with external certificates fails on RHEL 7 in FIPS mode
+  - Fix ca less IPA install on fips mode
+
+* Mon Dec 04 2017 Alexander Bokovoy <abokovoy@redhat.com> - 4.5.4-6.el7
+- Resolves: #1520279 - rebuild against samba 4.7
+
+* Thu Nov 30 2017 Alexander Bokovoy <abokovoy@redhat.com> - 4.5.4-5.el7
+- Resolves: #1415162 ipa-exdom-extop plugin can exhaust DS worker threads
+- Resolves: #1378892 host-find slowness caused by missing host attributes in index
+
+* Fri Nov 3 2017 Pavel Vomacka <pvomacka@redhat.com> - 4.5.4-4.el7
+- Resolves: #1388135 [RFE] limit the retro changelog to dns subtree.
+  - ldap: limit the retro changelog to dns subtree
+- Resolves: #1427798 Use X509v3 Basic Constraints "CA:TRUE" instead
+  of "CA:FALSE" IPA CA CSR
+  - Include the CA basic constraint in CSRs when renewing a CA
+- Resolves: #1493145 ipa-replica-install might fail because of an already
   existing entry cn=ipa-http-delegation,cn=s4u2proxy,cn=etc,$SUFFIX
-    - Checks if replica-s4u2proxy.ldif should be applied
-- Resolves: #1506525 server-del doesn't remove dns-server configuration
+  - Checks if replica-s4u2proxy.ldif should be applied
+- Resolves: #1493150 [RFE] set nsslapd-ignore-time-skew: on by default
+  - ds: ignore time skew during initial replication step
+  - ipa-replica-manage: implicitly ignore initial time skew in force-sync 
+- Resolves: #1500218 Replica installation at domain-level 0 fails against
+  upgraded ipa-server
+  - Fix ipa-replica-conncheck when called with --principal
+- Resolves: #1506188 server-del doesn't remove dns-server configuration
   from ldap
-    - server.py: Removes dns-server configuration from ldap
+
+* Thu Oct 26 2017 Rob Crittenden <rcritten@redhat.com> - 4.5.4-3.el7
+- Drop workaround for building on AArch64 (#1482244)
+- Temporarily reduce Requires on python-netaddr to 0.7.5-7 (#1506485)
+
+* Tue Oct 24 2017 Felipe Barreto <fbarreto@redhat.com> - 4.5.4-2.el7
+- Resolves: #1461177 ipa-otptoken-import  - XML file is missing PBKDF2
+  parameters!
+- Resolves: #1464205 NULL LDAP context in call to ldap_search_ext_s during
+  search in cn=ad, cn=trusts,dc=example,dc=com
+- Resolves: #1467887 iommu platform support for ipxe
+- Resolves: #1477178 [ipa-replica-install] - 406 Client Error: Failed to
+  validate message: Incorrect number of results (0) searching forpublic key for
+  host
+- Resolves: #1478251 IPA WebUI does not work after upgrade from IPA 4.4 to
+  4.5
+- Resolves: #1480102 ipa-server-upgrade failes with "This entry already
+  exists"
+- Resolves: #1482802 Unable to set ca renewal master on replica
+- Resolves: #1484428 Updating from RHEL 7.3 fails with Server-Cert not found
+  (ipa-server-upgrade)
+- Resolves: #1484826 FreeIPA/IdM installations which were upgraded from
+  versions with 389 DS prior to 1.3.3.0 doesn't have whomai plugin enabled and
+  thus startup of Web UI fails
+- Resolves: #1486283 TypeError in renew_ca_cert prevents from swiching back
+  to self-signed CA
+- Resolves: #1469246 Replica install fails to configure IPA-specific
+  temporary files/directories
+- Resolves: #1469480 bind package is not automatically updated during
+  ipa-server upgrade process
+- Resolves: #1475238 Use CommonNameToSANDefault in default profile (new
+  installs only)
+- Resolves: #1477703 IPA upgrade fails for latest ipa package
+
+* Fri Oct 20 2017 Pavel Vomacka <pvomacka@redhat.com> - 4.5.4-1.el7
+- Use OpenJDK 8 to bootstrap on AArch64 until RH1482244 is resolved in
+  buildroot
+- Resolves: #1470177 - Rebase IPA to latest 4.5.x version
+- Resolves: #1398594 ipa topologysuffix-verify should only warn about 
+  maximum number of replication agreements. 
+- Resolves: #1404236 Web UI: Change "Host Based" and "Role Based" 
+  to "Host-Based" and "Role-Based" 
+- Resolves: #1409786 Second phase of --external-ca ipa-server-install
+  setup fails when dirsrv is not running
+- Resolves: #1451576 ipa cert-request failed to generate certificate from csr 
+- Resolves: #1452086 Pagination Size under Customization in IPA WebUI 
+  accepts negative values
+- Resolves: #1458169 --force-join option is not mentioned in 
+  ipa-replica-install man page 
+- Resolves: #1463186 IPA shouldn't allow objectclass if not all in lower case 
+- Resolves: #1478322 user-show command fails when sizelimit is configured 
+  to number <= number of entity which is user member of 
+- Resolves: #1496775 Enterprise principals should be able to trigger
+  a refresh of the trusted domain data in the KDC
+- Resolves: #1502533 Changing cert-find to go through the proxy 
+  instead of using the port 8080
+- Resolves: #1502663 pkinit-status command fails after an upgrade from
+  a pre-4.5 IPA
+- Resolves: #1498168 Error when trying to modify a PTR record
+- Resolves: #1457876 ipa-backup fails silently
+- Resolves: #1493531 In case full PKINIT configuration is failing during 
+  server/replica install the error message should be more meaningful.
+- Resolves: #1449985 Suggest CA installation command in KRA installation
+  warning
 
 * Wed Sep 20 2017 Felipe Barreto <fbarreto@redhat.com> - 4.5.0-21.el7.2.2
-- Resolves: #1493410 ipa-server-upgrade timeouts on wait_for_open ports
+- Resolves: #1477367 ipa-server-upgrade timeouts on wait_for_open ports
   expecting IPA services listening on IPv6 ports
     - Make sure upgrade also checks for IPv6 stack
     - control logging of host_port_open from caller
     - log progress of wait_for_open_ports
-- Resolves: #1493411 ipa help command returns traceback when no cache
+- Resolves: #1477243 ipa help command returns traceback when no cache
   is present
     - Store help in Schema before writing to disk
     - Disable pylint in get_help function because of type confusion.
 
 * Tue Sep 19 2017 Felipe Barreto <fbarreto@redhat.com> - 4.5.0-21.el7.2
-- Resolves: #1486794 - [ipa-replica-install] - 406 Client Error: Failed to
+- Resolves: #1477178 - [ipa-replica-install] - 406 Client Error: Failed to
   validate message: Incorrect number of results (0) searching forpublic
   key for host
     - Always check peer has keys before connecting
-- Resolves: #1489300 - Unable to set ca renewal master on replica
+- Resolves: #1482802 - Unable to set ca renewal master on replica
     - Fix ipa config-mod --ca-renewal-master
-- Resolves: #1489815 - TypeError in renew_ca_cert prevents from swiching
+- Resolves: #1486283 - TypeError in renew_ca_cert prevents from swiching
   back to self-signed CA
     - Backport PR 988 to ipa-4-5 Fix Certificate renewal (with ext ca)
-- Resolves: #1489817 - ipa-server-upgrade failes with "This entry already exists"
+- Resolves: #1480102 - ipa-server-upgrade failes with "This entry already exists"
     - Backport PR 1008 to ipa-4-5 Fix ipa-server-upgrade: This entry already exists
-- Resolves: #1490331 - FreeIPA/IdM installations which were upgraded from
+- Resolves: #1484826 - FreeIPA/IdM installations which were upgraded from
   versions with 389 DS prior to 1.3.3.0 doesn't have whomai plugin enabled and
   thus startup of Web UI fails
     - Adds whoami DS plugin in case that plugin is missing
-- Resolves: #1491545 - IPA WebUI does not work after upgrade from IPA 4.4 to 4.5
+- Resolves: #1478251 - IPA WebUI does not work after upgrade from IPA 4.4 to 4.5
     - Fixing how sssd.conf is updated when promoting a client to replica
-- Resolves: #1492616 - ipa-otptoken-import - XML file is missing PBKDF2
+- Resolves: #1461177 - ipa-otptoken-import - XML file is missing PBKDF2
   parameters!
     - ipa-otptoken-import: Make PBKDF2 refer to the pkcs5 namespace
-- Resolves: #1493153 - Updating from RHEL 7.3 fails with Server-Cert not found
+- Resolves: #1484428 - Updating from RHEL 7.3 fails with Server-Cert not found
   (ipa-server-upgrade)
     - Backport 4-5: Fix ipa-server-upgrade with server cert tracking
 
-* Wed Aug 16 2017 Pavel Vomacka <pvomacka@redhat.com> - 4.5.0-21.el7.1.2
-- Fixing issues reported by Errata tool
+* Thu Aug 17 2017 Pavel Vomacka <pvomacka@redhat.com> - 4.5.0-21.el7.1.2
+- Resolves: #1477703 IPA upgrade fails for latest ipa package
+    - Restore old version of caIPAserviceCert for upgrade only
 
 * Tue Aug 15 2017 Pavel Vomacka <pvomacka@redhat.com> - 4.5.0-21.el7.1.1
-- Resolves: #1477046 Use CommonNameToSANDefault in default profile
+- Resolves: #1475238 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
+* Fri Jul 28 2017 Pavel Vomacka <pvomacka@redhat.com> - 4.5.0-21.el7.1
+- Resolves: #1455946 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
@@ -1949,18 +1890,18 @@ fi
   - 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 
+- Resolves: #1475238 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
+- Resolves: #1464205 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
+- Resolves: #1469246 Replica install fails to configure IPA-specific
   temporary files/directories
   - replica install: drop-in IPA specific config to tmpfiles.d
-- Resolves: #1469978 bind package is not automatically updated during
+- Resolves: #1469480 bind package is not automatically updated during
   ipa-server upgrade process
   - Bumped Required version of bind-dyndb-ldap and bind package