From 403b09ab980c02ef36095973349a13e0181c794a Mon Sep 17 00:00:00 2001
From: CentOS Sources <bugs@centos.org>
Date: Thu, 03 Nov 2016 06:01:28 +0000
Subject: [PATCH] import ipa-4.4.0-12.el7

---
 SOURCES/0005-ipa-advise-correct-handling-of-plugin-namespace-iter.patch |   40 
 SOURCES/0032-Create-indexes-for-krbCanonicalName-attribute.patch        |   54 
 SOURCES/0128-WebUI-add-support-for-sub-CAs-while-revoking-certifi.patch |  252 +
 SOURCES/0035-client-fix-hiding-of-commands-which-lack-server-supp.patch |   93 
 SOURCES/0088-cert-revoke-fix-permission-check-bypass-CVE-2016-540.patch |  132 
 SOURCES/0070-cert-do-not-crash-on-invalid-data-in-cert-find.patch       |   81 
 SOURCES/0096-Handled-empty-hostname-in-server-del-command.patch         |   42 
 SOURCES/0019-Show-full-error-message-for-selinuxusermap-add-hostg.patch |  152 
 SOURCES/0103-Raise-DuplicatedEnrty-error-when-user-exists-in-dele.patch |   61 
 SOURCES/0001-Fix-incorrect-check-for-principal-type-when-evaluati.patch |   34 
 SOURCES/0009-caacl-expand-plugin-documentation.patch                    |   66 
 SOURCES/1010-WebUI-add-API-browser-is-tech-preview-warning.patch        |   41 
 SOURCES/0120-Track-lightweight-CAs-on-replica-installation.patch        |  208 
 SOURCES/0086-Added-new-authentication-method.patch                      |   79 
 SOURCES/0030-Use-copy-when-replacing-files-to-keep-SELinux-contex.patch |   38 
 SPECS/ipa.spec                                                          | 1866 +++++--
 SOURCES/0064-help-Do-not-create-instances-to-get-information-abou.patch |   77 
 SOURCES/0057-client-add-missing-output-params-to-client-side-comm.patch |   95 
 SOURCES/0059-install-Call-hostnamectl-set-hostname-only-if-hostna.patch |  148 
 SOURCES/0101-custodia-include-known-CA-certs-in-the-PKCS-12-file-.patch |   43 
 SOURCES/0084-service-add-flag-to-allow-S4U2Self.patch                   |  122 
 SOURCES/0039-idrange-fix-unassigned-global-variable.patch               |   33 
 SOURCES/0075-Access-data-for-help-separately.patch                      |  121 
 SOURCES/0100-support-multiple-uid-values-in-schema-compatibility-.patch |   53 
 SOURCES/0077-schema-cache-Read-server-info-only-once.patch              |   50 
 SOURCES/1004-Change-branding-to-IPA-and-Identity-Management.patch       |  330 
 SOURCES/0082-Fail-on-topology-disconnect-last-role-removal.patch        |   51 
 SOURCES/0116-Always-fetch-forest-info-from-root-DCs-when-establis.patch |   67 
 SOURCES/0040-re-set-canonical-principal-name-on-migrated-users.patch    |   86 
 SOURCES/0020-allow-value-output-param-in-commands-without-primary.patch |  157 
 SOURCES/0049-Update-ipa-replica-install-documentation.patch             |   45 
 SOURCES/0052-Revert-spec-add-conflict-with-bind-chroot-to-freeipa.patch |   35 
 SOURCES/0050-ipa-kdb-Fix-unit-test-after-packaging-changes-in-krb.patch |   29 
 SOURCES/0038-replica-install-Fix-domain.patch                           |   71 
 SOURCES/0051-Improvements-for-the-ipa-cacert-manage-man-and-help.patch  |  117 
 SOURCES/0044-Increase-default-length-of-auto-generated-passwords.patch  |  138 
 SOURCES/0018-frontend-copy-command-arguments-to-output-params-on-.patch |   39 
 SOURCES/0118-Use-RSA-OAEP-instead-of-RSA-PKCS-1-v1.5.patch              |   33 
 SOURCES/0016-Heap-corruption-in-ipapwd-plugin.patch                     |   41 
 SOURCES/0092-trust-make-sure-external-trust-topology-is-correctly.patch |   90 
 SOURCES/0025-unite-log-file-name-of-ipa-ca-install.patch                |   54 
 SOURCES/0056-parameters-move-the-confirm-kwarg-to-Param.patch           |   89 
 SOURCES/0080-schema-cache-Read-schema-instead-of-rewriting-it-whe.patch |  104 
 SOURCES/0089-Fix-container-owner-should-be-able-to-add-vault.patch      |   34 
 SOURCES/1008-RCUE.patch                                                 |    4 
 SOURCES/0008-vault-add-set-the-default-vault-type-on-the-client-s.patch |   38 
 SOURCES/0055-client-RPM-require-initscripts-to-get-domainname.ser.patch |   28 
 SOURCES/0073-schema-cache-Do-not-reset-ServerInfo-dirty-flag.patch      |   32 
 SOURCES/1003-Remove-pkinit-references-from-tool-man-pages.patch         |   47 
 SOURCES/0099-Fix-ipa-server-install-in-pure-IPv6-environment.patch      |   34 
 SOURCES/0126-Add-support-for-additional-options-taken-from-table-.patch |  104 
 SOURCES/0024-trust-add-handle-all-raw-options-properly.patch            |   89 
 SOURCES/0083-server-install-do-not-prompt-for-cert-file-PIN-repea.patch |   98 
 SOURCES/0085-Add-trusted-to-auth-as-user-checkbox.patch                 |   50 
 SOURCES/0119-Fix-ipa-certupdate-for-CA-less-installation.patch          |   44 
 SOURCES/0041-Do-not-initialize-API-in-ipa-client-automount-uninst.patch |   41 
 SOURCES/0045-vault-add-missing-salt-option-to-vault_mod.patch           |   31 
 SOURCES/0012-Preserve-user-principal-aliases-during-rename-operat.patch |   92 
 SOURCES/0069-cert-speed-up-cert-find.patch                              |  479 +
 SOURCES/0053-Fix-unicode-characters-in-ca-and-domain-adders.patch       |   41 
 SOURCES/0123-dns-fix-crash-in-interactive-mode-against-old-server.patch |  106 
 SOURCES/0071-Add-warning-about-only-one-existing-CA-server.patch        |  151 
 SOURCES/0010-host-find-do-not-show-SSH-key-by-default.patch             |   30 
 SOURCES/0097-Secure-permissions-of-Custodia-server.keys.patch           |   69 
 SOURCES/1002-Remove-pkinit-plugin.patch                                 |   47 
 SOURCES/0034-Revert-Enable-vault-commands-on-client.patch               |   65 
 SOURCES/0131-Fix-regression-introduced-in-ipa-certupdate.patch          |   33 
 SOURCES/0072-Set-servers-list-as-default-facet-in-topology-facet-.patch |   32 
 SOURCES/0033-harden-the-check-for-trust-namespace-overlap-in-new-.patch |   43 
 SOURCES/0067-DNS-server-upgrade-do-not-fail-when-DNS-server-did-n.patch |   62 
 SOURCES/0091-trust-automatically-resolve-DNS-trust-conflicts-for-.patch |  382 +
 .ipa.metadata                                                           |    2 
 SOURCES/0021-server-uninstall-fails-to-remove-krb-principals.patch      |   51 
 SOURCES/1001-Hide-pkinit-functionality-from-production-version.patch    |  172 
 SOURCES/0109-compat-Fix-ping-command-call.patch                         |   30 
 SOURCES/0115-factor-out-populate_remote_domain-method-into-module.patch |  132 
 SOURCES/1005-Remove-pylint-from-build-process.patch                     |   37 
 SOURCES/0006-kdb-check-for-local-realm-in-enterprise-principals.patch   |   89 
 SOURCES/0129-cert-fix-cert-find-certificate-when-the-cert-is-not-.patch |   46 
 SOURCES/0074-schema-cache-Do-not-read-fingerprint-and-format-from.patch |   86 
 SOURCES/0105-rpcserver-assume-version-1-for-unversioned-command-c.patch |  130 
 SOURCES/0007-Enable-vault-commands-on-client.patch                      |   70 
 SOURCES/0058-server-install-Fix-hostname-option-to-always-overrid.patch |   52 
 SOURCES/0023-prevent-search-for-RADIUS-proxy-servers-by-secret.patch    |   37 
 SOURCES/0043-vault-Catch-correct-exception-in-decrypt.patch             |   30 
 SOURCES/0127-WebUI-Fix-showing-certificates-issued-by-sub-CA.patch      |   57 
 SOURCES/0047-install-fix-external-CA-cert-validation.patch              |   31 
 SOURCES/0066-Don-t-show-force-ntpd-option-in-replica-install.patch      |   42 
 SOURCES/0112-Fix-CA-ACL-Check-on-SubjectAltNames.patch                  |   55 
 SOURCES/0094-ipa-kdb-simplify-trusted-domain-parent-search.patch        |   87 
 SOURCES/0130-Make-host-service-cert-revocation-aware-of-lightweig.patch |  184 
 SOURCES/1006-Remove-i18test-from-build-process.patch                    |   10 
 SOURCES/0013-messages-specify-message-type-for-ResultFormattingEr.patch |   31 
 SOURCES/0068-DNS-allow-to-add-forward-zone-to-already-broken-sub-.patch |   32 
 SOURCES/0114-Always-fetch-forest-info-from-root-DCs-when-establis.patch |   85 
 SOURCES/0078-schema-cache-Store-API-schema-cache-in-memory.patch        |  125 
 SOURCES/1007-Do-not-build-tests.patch                                   |   14 
 SOURCES/0081-schema-check-Check-current-client-language-against-c.patch |   57 
 SOURCES/0110-Fix-man-page-ipa-replica-manage-remove-duplicate-c-o.patch |   36 
 SOURCES/0121-dns-normalize-record-type-read-interactively-in-dnsr.patch |   36 
 SOURCES/0028-DNS-Locations-fix-update-system-records-unpacking-er.patch |   35 
 SOURCES/0108-compat-Save-server-s-API-version-in-for-pre-schema-s.patch |  346 +
 SOURCES/1009-Revert-Increased-mod_wsgi-socket-timeout.patch             |   29 
 SOURCES/0027-help-Add-dnsserver-commands-to-help-topic-dns.patch        |   67 
 SOURCES/0031-baseldap-Fix-MidairCollision-instantiation-during-en.patch |   38 
 SOURCES/0122-dns-prompt-for-missing-record-parts-in-CLI.patch           |  201 
 SOURCES/0134-trust-fetch-domains-contact-forest-DCs-when-fetching.patch |   60 
 SOURCES/0003-ipa-nis-manage-Use-server-API-to-retrieve-plugin-sta.patch |   28 
 SOURCES/0022-expose-secret-option-in-radiusproxy-commands.patch         |   32 
 SOURCES/0063-schema-Generate-bits-for-help-load-them-on-request.patch   |  162 
 SOURCES/0093-trust-make-sure-ID-range-is-created-for-the-child-do.patch |   71 
 SOURCES/0048-caacl-fix-regression-in-rule-instantiation.patch           |   52 
 SOURCES/0046-Fix-ipa-hbactest-output.patch                              |   46 
 SOURCES/0060-schema-Speed-up-schema-cache.patch                         |  415 +
 SOURCES/0106-custodia-force-reconnect-before-retrieving-CA-certs-.patch |   34 
 SOURCES/0042-Correct-path-to-HTTPD-s-systemd-service-directory.patch    |   37 
 SOURCES/0104-cert-add-missing-param-values-to-cert-find-output.patch    |   32 
 SOURCES/0029-Fix-session-cookies.patch                                  |  136 
 .gitignore                                                              |    2 
 SOURCES/0125-Fix-parse-errors-with-link-local-addresses.patch           |   38 
 SOURCES/0098-Require-httpd-2.4.6-31-with-mod_proxy-Unix-socket-su.patch |   45 
 SOURCES/0014-schema-Fix-subtopic-topic-mapping.patch                    |   29 
 SOURCES/0095-Remove-Custodia-server-keys-from-LDAP.patch                |   78 
 SOURCES/0062-schema-Introduce-schema-cache-format.patch                 |   48 
 SOURCES/0065-Fix-ipa-caalc-add-service-error-message.patch              |   31 
 SOURCES/0087-schema-cache-Fallback-to-en_us-when-locale-is-not-av.patch |   39 
 SOURCES/0054-ipa-backup-backup-etc-tmpfiles.d-dirsrv-instance-.co.patch |   52 
 SOURCES/0004-ipa-compat-manage-use-server-API-to-retrieve-plugin-.patch |   28 
 SOURCES/0015-DNS-install-Ensure-that-DNS-servers-container-exists.patch |   93 
 SOURCES/0113-do-not-use-trusted-forest-name-to-construct-domain-a.patch |   37 
 SOURCES/0111-cert-include-CA-name-in-cert-command-output.patch          |  112 
 SOURCES/0036-Minor-fix-in-ipa-replica-manage-MAN-page.patch             |   51 
 SOURCES/0117-cli-use-full-name-when-executing-a-command.patch           |   31 
 SOURCES/0076-frontent-Add-summary-class-property-to-CommandOverri.patch |   34 
 SOURCES/0079-client-Do-not-create-instance-just-to-check-isinstan.patch |   97 
 SOURCES/0124-schema-cache-Store-and-check-info-for-pre-schema-ser.patch |  393 +
 SOURCES/0107-rpcserver-fix-crash-in-XML-RPC-system-commands.patch       |   59 
 SOURCES/0002-uninstall-untrack-lightweight-CA-certs.patch               |   31 
 SOURCES/0090-ipaserver-dcerpc-reformat-to-make-the-code-closer-to.patch | 1005 ++++
 SOURCES/0061-frontend-Change-doc-summary-topic-and-NO_CLI-to-clas.patch |  378 +
 SOURCES/0133-Catch-DNS-exceptions-during-emptyzones-named.conf-up.patch |   54 
 SOURCES/0026-Host-del-fix-behavior-of-updatedns-and-PTR-records.patch   |   95 
 /dev/null                                                               |   38 
 SOURCES/0011-Removed-unused-method-parameter-from-migrate-ds.patch      |   31 
 SOURCES/0037-compat-fix-ping-call.patch                                 |   31 
 SOURCES/0132-Start-named-during-configuration-upgrade.patch             |   48 
 SOURCES/0102-otptoken-permission-Convert-custom-type-parameters-o.patch |   46 
 SOURCES/0017-Use-server-API-in-com.redhat.idm.trust-fetch-domains.patch |   29 
 148 files changed, 13,731 insertions(+), 882 deletions(-)

diff --git a/.gitignore b/.gitignore
index bcfe5f9..e66632a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,4 @@
-SOURCES/freeipa-4.2.0.tar.gz
+SOURCES/freeipa-4.4.0.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 3f16db3..97596a6 100644
--- a/.ipa.metadata
+++ b/.ipa.metadata
@@ -1,4 +1,4 @@
-40a1587de7d78f4e01bfb3775ab3f4e264c56e4c SOURCES/freeipa-4.2.0.tar.gz
+441ef8cb2b0ac103723d03b0478da641d697e104 SOURCES/freeipa-4.4.0.tar.gz
 77c318cf1f4fc25cf847de0692a77859a767c0e3 SOURCES/header-logo.png
 8727245558422bf966d60677568925f081b8e299 SOURCES/login-screen-background.jpg
 24a29d79efbd0906777be4639957abda111fca4b SOURCES/login-screen-logo.png
diff --git a/SOURCES/0001-Fix-incorrect-check-for-principal-type-when-evaluati.patch b/SOURCES/0001-Fix-incorrect-check-for-principal-type-when-evaluati.patch
new file mode 100644
index 0000000..46921fd
--- /dev/null
+++ b/SOURCES/0001-Fix-incorrect-check-for-principal-type-when-evaluati.patch
@@ -0,0 +1,34 @@
+From 808772d7426dae6924c62ca327116c3152729a8e Mon Sep 17 00:00:00 2001
+From: Martin Babinsky <mbabinsk@redhat.com>
+Date: Fri, 1 Jul 2016 11:55:47 +0200
+Subject: [PATCH] Fix incorrect check for principal type when evaluating CA
+ ACLs
+
+This error prevented hosts to request certificates for themselves.
+
+https://fedorahosted.org/freeipa/ticket/3864
+
+Reviewed-By: Petr Spacek <pspacek@redhat.com>
+---
+ ipaserver/plugins/caacl.py | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/ipaserver/plugins/caacl.py b/ipaserver/plugins/caacl.py
+index 3f813a7efb9e554abcb8dd2946eea73065c93414..9a60f7e27809c4f41b160647efafde94dbe90bf0 100644
+--- a/ipaserver/plugins/caacl.py
++++ b/ipaserver/plugins/caacl.py
+@@ -64,8 +64,10 @@ def _acl_make_request(principal_type, principal, ca_id, profile_id):
+     req = pyhbac.HbacRequest()
+     req.targethost.name = ca_id
+     req.service.name = profile_id
+-    if principal_type == 'user' or principal_type == 'host':
++    if principal_type == 'user':
+         req.user.name = principal.username
++    elif principal_type == 'host':
++        req.user.name = principal.hostname
+     elif principal_type == 'service':
+         req.user.name = unicode(principal)
+     groups = []
+-- 
+2.9.0
+
diff --git a/SOURCES/0001-Start-dirsrv-for-kdcproxy-upgrade.patch b/SOURCES/0001-Start-dirsrv-for-kdcproxy-upgrade.patch
deleted file mode 100644
index 305ea1a..0000000
--- a/SOURCES/0001-Start-dirsrv-for-kdcproxy-upgrade.patch
+++ /dev/null
@@ -1,72 +0,0 @@
-From 5e1ff6ef5fa35715a5b9995388c6d7b16375ac23 Mon Sep 17 00:00:00 2001
-From: Christian Heimes <cheimes@redhat.com>
-Date: Fri, 10 Jul 2015 18:18:29 +0200
-Subject: [PATCH] Start dirsrv for kdcproxy upgrade
-
-The kdcproxy upgrade step in ipa-server-upgrade needs a running dirsrv
-instance. Under some circumstances the dirsrv isn't running. The patch
-rearranges some upgrade steps and starts DS before enable_kdcproxy().
-
-https://fedorahosted.org/freeipa/ticket/5113
-
-Reviewed-By: Martin Basti <mbasti@redhat.com>
----
- ipaserver/install/server/upgrade.py | 35 +++++++++++++++++++----------------
- 1 file changed, 19 insertions(+), 16 deletions(-)
-
-diff --git a/ipaserver/install/server/upgrade.py b/ipaserver/install/server/upgrade.py
-index 84a5b06accb10663eaa4d995f66796366040e9c8..f295655dc2aa592e0215f15017c9b65af49eef80 100644
---- a/ipaserver/install/server/upgrade.py
-+++ b/ipaserver/install/server/upgrade.py
-@@ -1396,22 +1396,6 @@ def upgrade_configuration():
-     http.change_mod_nss_port_from_http()
-     http.configure_certmonger_renewal_guard()
- 
--    if not http.is_kdcproxy_configured():
--        root_logger.info('[Enabling KDC Proxy]')
--        if http.admin_conn is None:
--            http.ldapi = True
--            http.fqdn = fqdn
--            http.realm = api.env.realm
--            http.suffix = ipautil.realm_to_suffix(api.env.realm)
--            http.ldap_connect()
--        http.create_kdcproxy_conf()
--        http.enable_kdcproxy()
--
--    http.stop()
--    update_mod_nss_protocol(http)
--    fix_trust_flags()
--    http.start()
--
-     ds = dsinstance.DsInstance()
-     ds.configure_dirsrv_ccache()
- 
-@@ -1433,6 +1417,25 @@ def upgrade_configuration():
-     ds.suffix = ipautil.realm_to_suffix(api.env.realm)
-     ds_enable_sidgen_extdom_plugins(ds)
- 
-+    # Now 389-ds is available, run the remaining http tasks
-+    if not http.is_kdcproxy_configured():
-+        root_logger.info('[Enabling KDC Proxy]')
-+        if http.admin_conn is None:
-+             # 389-ds needs to be running
-+            ds.start()
-+            http.ldapi = True
-+            http.fqdn = fqdn
-+            http.realm = api.env.realm
-+            http.suffix = ipautil.realm_to_suffix(api.env.realm)
-+            http.ldap_connect()
-+        http.create_kdcproxy_conf()
-+        http.enable_kdcproxy()
-+
-+    http.stop()
-+    update_mod_nss_protocol(http)
-+    fix_trust_flags()
-+    http.start()
-+
-     uninstall_selfsign(ds, http)
- 
-     simple_service_list = (
--- 
-2.1.0
-
diff --git a/SOURCES/0002-Fix-DNS-records-installation-for-replicas.patch b/SOURCES/0002-Fix-DNS-records-installation-for-replicas.patch
deleted file mode 100644
index 1fa91fa..0000000
--- a/SOURCES/0002-Fix-DNS-records-installation-for-replicas.patch
+++ /dev/null
@@ -1,33 +0,0 @@
-From 8610ddbee7025286881c1b470e13f0a5ff6a4452 Mon Sep 17 00:00:00 2001
-From: Simo Sorce <simo@redhat.com>
-Date: Fri, 10 Jul 2015 12:58:19 -0400
-Subject: [PATCH] Fix DNS records installation for replicas
-
-Ticket: https:/fedorahosted.org/freeipa/ticket/5116
-
-Signed-off-by: Simo Sorce <simo@redhat.com>
-Reviewed-By: Martin Basti <mbasti@redhat.com>
----
- ipaserver/install/server/replicainstall.py | 6 +++---
- 1 file changed, 3 insertions(+), 3 deletions(-)
-
-diff --git a/ipaserver/install/server/replicainstall.py b/ipaserver/install/server/replicainstall.py
-index a78eeb331c1f3f4f2233abb9e65bdde79eee4000..1ad291a1eada080361031a5723a0ea61679fc72e 100644
---- a/ipaserver/install/server/replicainstall.py
-+++ b/ipaserver/install/server/replicainstall.py
-@@ -503,9 +503,9 @@ def install_check(installer):
-     if options.setup_dns:
-         dns.install_check(False, True, options, config.host_name)
-     else:
--        installutils.get_server_ip_address(config.host_name, fstore,
--                                           not installer.interactive, False,
--                                           options.ip_addresses)
-+        config.ips = installutils.get_server_ip_address(
-+            config.host_name, fstore, not installer.interactive, False,
-+            options.ip_addresses)
- 
-     # check connection
-     if not options.skip_conncheck:
--- 
-2.1.0
-
diff --git a/SOURCES/0002-uninstall-untrack-lightweight-CA-certs.patch b/SOURCES/0002-uninstall-untrack-lightweight-CA-certs.patch
new file mode 100644
index 0000000..21fa9ec
--- /dev/null
+++ b/SOURCES/0002-uninstall-untrack-lightweight-CA-certs.patch
@@ -0,0 +1,31 @@
+From 8235b85d6960356fd49affca40b1b609f3cae827 Mon Sep 17 00:00:00 2001
+From: Fraser Tweedale <ftweedal@redhat.com>
+Date: Mon, 4 Jul 2016 13:05:28 +1000
+Subject: [PATCH] uninstall: untrack lightweight CA certs
+
+Fixes: https://fedorahosted.org/freeipa/ticket/6020
+Reviewed-By: Martin Babinsky <mbabinsk@redhat.com>
+---
+ ipaserver/install/cainstance.py | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/ipaserver/install/cainstance.py b/ipaserver/install/cainstance.py
+index 5e3e8c7f9a1845b82d23de589f804aa065387b38..070498fe8a394802ea55f848a268e2b6563ec472 100644
+--- a/ipaserver/install/cainstance.py
++++ b/ipaserver/install/cainstance.py
+@@ -1127,6 +1127,12 @@ class CAInstance(DogtagInstance):
+         """
+         super(CAInstance, self).stop_tracking_certificates(False)
+ 
++        # stop tracking lightweight CA signing certs
++        for request_id in certmonger.get_requests_for_dir(self.nss_db):
++            nickname = certmonger.get_request_value(request_id, 'key-nickname')
++            if nickname.startswith('caSigningCert cert-pki-ca '):
++                certmonger.stop_tracking(self.nss_db, nickname=nickname)
++
+         try:
+             certmonger.stop_tracking(paths.HTTPD_ALIAS_DIR, nickname='ipaCert')
+         except RuntimeError as e:
+-- 
+2.4.3
+
diff --git a/SOURCES/0003-Prevent-to-rename-certprofile-profile-id.patch b/SOURCES/0003-Prevent-to-rename-certprofile-profile-id.patch
deleted file mode 100644
index 5127951..0000000
--- a/SOURCES/0003-Prevent-to-rename-certprofile-profile-id.patch
+++ /dev/null
@@ -1,29 +0,0 @@
-From 51f03f45f6cdab9da0479f48093951ccdd7cdab0 Mon Sep 17 00:00:00 2001
-From: Martin Basti <mbasti@redhat.com>
-Date: Thu, 9 Jul 2015 17:17:21 +0200
-Subject: [PATCH] Prevent to rename certprofile profile id
-
-https://fedorahosted.org/freeipa/ticket/5074
-
-Reviewed-By: Jan Cholasta <jcholast@redhat.com>
----
- ipalib/plugins/certprofile.py | 3 +++
- 1 file changed, 3 insertions(+)
-
-diff --git a/ipalib/plugins/certprofile.py b/ipalib/plugins/certprofile.py
-index 6f9a41875b2a276b521219156e630817a9c41fdc..5550ed942521dbab2e783fba1570520268f9b378 100644
---- a/ipalib/plugins/certprofile.py
-+++ b/ipalib/plugins/certprofile.py
-@@ -291,6 +291,9 @@ class certprofile_mod(LDAPUpdate):
- 
-     def pre_callback(self, ldap, dn, entry_attrs, attrs_list, *keys, **options):
-         ca_enabled_check()
-+        # Once a profile id is set it cannot be changed
-+        if 'cn' in entry_attrs:
-+            raise errors.ACIError(info=_('cn is immutable'))
-         if 'file' in options:
-             with self.api.Backend.ra_certprofile as profile_api:
-                 profile_api.disable_profile(keys[0])
--- 
-2.1.0
-
diff --git a/SOURCES/0003-ipa-nis-manage-Use-server-API-to-retrieve-plugin-sta.patch b/SOURCES/0003-ipa-nis-manage-Use-server-API-to-retrieve-plugin-sta.patch
new file mode 100644
index 0000000..b0e8ae3
--- /dev/null
+++ b/SOURCES/0003-ipa-nis-manage-Use-server-API-to-retrieve-plugin-sta.patch
@@ -0,0 +1,28 @@
+From db7950c119f71df018ae1759933c0a8dca1072df Mon Sep 17 00:00:00 2001
+From: Martin Babinsky <mbabinsk@redhat.com>
+Date: Mon, 4 Jul 2016 13:33:10 +0200
+Subject: [PATCH] ipa-nis-manage: Use server API to retrieve plugin status
+
+https://fedorahosted.org/freeipa/ticket/6027
+
+Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
+---
+ install/tools/ipa-nis-manage | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/install/tools/ipa-nis-manage b/install/tools/ipa-nis-manage
+index f70961309c34e48ea1b4c1b144c9c0df5860f667..64de9e848ff7c382ddaea0729352da2584be6031 100755
+--- a/install/tools/ipa-nis-manage
++++ b/install/tools/ipa-nis-manage
+@@ -116,7 +116,7 @@ def main():
+     if not dirman_password:
+         sys.exit("No password supplied")
+ 
+-    api.bootstrap(context='cli', debug=options.debug)
++    api.bootstrap(context='cli', debug=options.debug, in_server=True)
+     api.finalize()
+ 
+     conn = None
+-- 
+2.4.3
+
diff --git a/SOURCES/0004-Stageusedr-activate-show-username-instead-of-DN.patch b/SOURCES/0004-Stageusedr-activate-show-username-instead-of-DN.patch
deleted file mode 100644
index 4d29df8..0000000
--- a/SOURCES/0004-Stageusedr-activate-show-username-instead-of-DN.patch
+++ /dev/null
@@ -1,36 +0,0 @@
-From 5fb2c0f8c7237214f870d341cc10a2ccda48d117 Mon Sep 17 00:00:00 2001
-From: Martin Basti <mbasti@redhat.com>
-Date: Fri, 10 Jul 2015 14:47:59 +0200
-Subject: [PATCH] Stageusedr-activate: show username instead of DN
-
-If activate user already exists, show name of this user in error message
-instead of user DN.
-Error message reworder to keep the same format as stageuser-add,
-user-add.
-
-https://fedorahosted.org/freeipa/ticket/5038
-
-Reviewed-By: David Kupka <dkupka@redhat.com>
----
- ipalib/plugins/stageuser.py | 5 +++--
- 1 file changed, 3 insertions(+), 2 deletions(-)
-
-diff --git a/ipalib/plugins/stageuser.py b/ipalib/plugins/stageuser.py
-index 35e636ded4474b00ad635c60340aaf66e6b41752..6cbc8f4ab07f2c1172f2b2c45bfe8f30a74938b3 100644
---- a/ipalib/plugins/stageuser.py
-+++ b/ipalib/plugins/stageuser.py
-@@ -682,8 +682,9 @@ class stageuser_activate(LDAPQuery):
-                 active_dn, ['dn']
-             )
-             assert isinstance(staging_dn, DN)
--            raise errors.DuplicateEntry(message=_('Active user %(user)s already exists') % dict(
--                            user=test_entry_attrs.dn))
-+            raise errors.DuplicateEntry(
-+                message=_('active user with name "%(user)s" already exists') %
-+                dict(user=args[-1]))
-         except errors.NotFound:
-             pass
- 
--- 
-2.1.0
-
diff --git a/SOURCES/0004-ipa-compat-manage-use-server-API-to-retrieve-plugin-.patch b/SOURCES/0004-ipa-compat-manage-use-server-API-to-retrieve-plugin-.patch
new file mode 100644
index 0000000..a74f4d0
--- /dev/null
+++ b/SOURCES/0004-ipa-compat-manage-use-server-API-to-retrieve-plugin-.patch
@@ -0,0 +1,28 @@
+From 5d699a0bff0c42220d68fac54d08fbcdd2daae67 Mon Sep 17 00:00:00 2001
+From: Martin Babinsky <mbabinsk@redhat.com>
+Date: Mon, 11 Jul 2016 10:46:34 +0200
+Subject: [PATCH] ipa-compat-manage: use server API to retrieve plugin status
+
+https://fedorahosted.org/freeipa/ticket/6033
+
+Reviewed-By: Stanislav Laznicka <slaznick@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 2b13c4a68531c7b6261465399b59225db094aba2..178cef9792c703f868fa3639a3a570b963dc7ed6 100755
+--- a/install/tools/ipa-compat-manage
++++ b/install/tools/ipa-compat-manage
+@@ -103,7 +103,7 @@ def main():
+         if dirman_password is None:
+             sys.exit("Directory Manager password required")
+ 
+-    api.bootstrap(context='cli', debug=options.debug)
++    api.bootstrap(context='cli', in_server=True, debug=options.debug)
+     api.finalize()
+ 
+     conn = None
+-- 
+2.4.3
+
diff --git a/SOURCES/0005-copy-schema-to-ca-allow-to-overwrite-schema-files.patch b/SOURCES/0005-copy-schema-to-ca-allow-to-overwrite-schema-files.patch
deleted file mode 100644
index 2181d76..0000000
--- a/SOURCES/0005-copy-schema-to-ca-allow-to-overwrite-schema-files.patch
+++ /dev/null
@@ -1,72 +0,0 @@
-From 7919e3c6b245adb0f6d6743edaf03da704259b5d Mon Sep 17 00:00:00 2001
-From: Martin Basti <mbasti@redhat.com>
-Date: Fri, 10 Jul 2015 14:17:02 +0200
-Subject: [PATCH] copy-schema-to-ca: allow to overwrite schema files
-
-If content of source and target file differs, the script will ask user
-for permission to overwrite target file.
-
-https://fedorahosted.org/freeipa/ticket/5034
-
-Reviewed-By: David Kupka <dkupka@redhat.com>
----
- install/share/copy-schema-to-ca.py | 29 ++++++++++++++++++++++++++---
- 1 file changed, 26 insertions(+), 3 deletions(-)
-
-diff --git a/install/share/copy-schema-to-ca.py b/install/share/copy-schema-to-ca.py
-index 1614e11636c2f52e231ea2ff40d882209194c60a..ff6c3568586f9f4b3fac7f848869e74d0db0df34 100755
---- a/install/share/copy-schema-to-ca.py
-+++ b/install/share/copy-schema-to-ca.py
-@@ -15,6 +15,8 @@ import sys
- import pwd
- import shutil
- 
-+from hashlib import sha1
-+
- from ipapython import ipautil, dogtag
- from ipapython.ipa_log_manager import root_logger, standard_logging_setup
- from ipaserver.install.dsinstance import DS_USER, schema_dirname
-@@ -42,6 +44,11 @@ SCHEMA_FILENAMES = (
- )
- 
- 
-+def _sha1_file(filename):
-+    with open(filename, 'rb') as f:
-+        return sha1(f.read()).hexdigest()
-+
-+
- def add_ca_schema():
-     """Copy IPA schema files into the CA DS instance
-     """
-@@ -54,9 +61,25 @@ def add_ca_schema():
-             root_logger.debug('File does not exist: %s', source_fname)
-             continue
-         if os.path.exists(target_fname):
--            root_logger.info(
--                'Target exists, not overwriting: %s', target_fname)
--            continue
-+            target_sha1 = _sha1_file(target_fname)
-+            source_sha1 = _sha1_file(source_fname)
-+            if target_sha1 != source_sha1:
-+                target_size = os.stat(target_fname).st_size
-+                source_size = os.stat(source_fname).st_size
-+                root_logger.info('Target file %s exists but the content is '
-+                                 'different', target_fname)
-+                root_logger.info('\tTarget file: sha1: %s, size: %s B',
-+                                 target_sha1, target_size)
-+                root_logger.info('\tSource file: sha1: %s, size: %s B',
-+                                 source_sha1, source_size)
-+                if not ipautil.user_input("Do you want replace %s file?" %
-+                                          target_fname, True):
-+                    continue
-+
-+            else:
-+                root_logger.info(
-+                    'Target exists, not overwriting: %s', target_fname)
-+                continue
-         try:
-             shutil.copyfile(source_fname, target_fname)
-         except IOError, e:
--- 
-2.1.0
-
diff --git a/SOURCES/0005-ipa-advise-correct-handling-of-plugin-namespace-iter.patch b/SOURCES/0005-ipa-advise-correct-handling-of-plugin-namespace-iter.patch
new file mode 100644
index 0000000..e55904e
--- /dev/null
+++ b/SOURCES/0005-ipa-advise-correct-handling-of-plugin-namespace-iter.patch
@@ -0,0 +1,40 @@
+From c4d5331ec5361a5f607eca7bb576d5d387bf3824 Mon Sep 17 00:00:00 2001
+From: Martin Babinsky <mbabinsk@redhat.com>
+Date: Mon, 11 Jul 2016 14:03:36 +0200
+Subject: [PATCH] ipa-advise: correct handling of plugin namespace iteration
+
+The API object namespace iterators now yield plugin classes themselves
+instead of their names as strings. The method enumerating through available
+plugins needs to be made aware of this change.
+
+https://fedorahosted.org/freeipa/ticket/6044
+
+Reviewed-By: Stanislav Laznicka <slaznick@redhat.com>
+---
+ ipaserver/advise/base.py | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/ipaserver/advise/base.py b/ipaserver/advise/base.py
+index d083a3c506074f0adbb49e7a6d9935b8d338e941..a2dc9ccee93811da415c1e1eb0b57f47ac817a3f 100644
+--- a/ipaserver/advise/base.py
++++ b/ipaserver/advise/base.py
+@@ -167,12 +167,12 @@ class IpaAdvise(admintool.AdminTool):
+     def print_config_list(self):
+         self.print_header('List of available advices')
+ 
+-        max_keyword_len = max((len(keyword) for keyword in advise_api.Advice))
++        max_keyword_len = max(
++            (len(advice.__name__) for advice in advise_api.Advice))
+ 
+-        for keyword in advise_api.Advice:
+-            advice = getattr(advise_api.Advice, keyword, '')
++        for advice in advise_api.Advice:
+             description = getattr(advice, 'description', '')
+-            keyword = keyword.replace('_', '-')
++            keyword = advice.__name__.replace('_', '-')
+ 
+             # Compute the number of spaces needed for the table to be aligned
+             offset = max_keyword_len - len(keyword)
+-- 
+2.4.3
+
diff --git a/SOURCES/0006-kdb-check-for-local-realm-in-enterprise-principals.patch b/SOURCES/0006-kdb-check-for-local-realm-in-enterprise-principals.patch
new file mode 100644
index 0000000..fd02aa9
--- /dev/null
+++ b/SOURCES/0006-kdb-check-for-local-realm-in-enterprise-principals.patch
@@ -0,0 +1,89 @@
+From ed178aad6751ea7673d8e730bd5a6709921a1ff0 Mon Sep 17 00:00:00 2001
+From: Sumit Bose <sbose@redhat.com>
+Date: Wed, 6 Jul 2016 17:29:37 +0200
+Subject: [PATCH] kdb: check for local realm in enterprise principals
+
+Reviewed-By: Martin Babinsky <mbabinsk@redhat.com>
+Reviewed-By: Jakub Hrozek <jhrozek@redhat.com>
+---
+ daemons/ipa-kdb/ipa_kdb_principals.c | 52 +++++++++++++++++++++++++++---------
+ 1 file changed, 40 insertions(+), 12 deletions(-)
+
+diff --git a/daemons/ipa-kdb/ipa_kdb_principals.c b/daemons/ipa-kdb/ipa_kdb_principals.c
+index 6cdfa909452a4b55912b2a5a74648abd2053482a..5b80909475565d6bb4fa8cba67629094daf51eb3 100644
+--- a/daemons/ipa-kdb/ipa_kdb_principals.c
++++ b/daemons/ipa-kdb/ipa_kdb_principals.c
+@@ -1198,30 +1198,58 @@ krb5_error_code ipadb_get_principal(krb5_context kcontext,
+             /* skip '@' and use part after '@' as an enterprise realm for comparison */
+             realm++;
+ 
+-            kerr = ipadb_is_princ_from_trusted_realm(kcontext,
+-                                                     realm,
+-                                                     upn->length - (realm - upn->data),
+-                                                     &trusted_realm);
+-            if (kerr == 0) {
+-                kentry = calloc(1, sizeof(krb5_db_entry));
+-                if (!kentry) {
++            /* check for our realm */
++            if (strncasecmp(ipactx->realm, realm,
++                            upn->length - (realm - upn->data)) == 0) {
++                /* it looks like it is ok to use malloc'ed strings as principal */
++                krb5_free_unparsed_name(kcontext, principal);
++                principal = strndup((const char *) upn->data, upn->length);
++                if (principal == NULL) {
+                     kerr = ENOMEM;
+                     goto done;
+                 }
+-                kerr = krb5_parse_name(kcontext, principal,
+-                                       &kentry->princ);
++
++                ldap_msgfree(res);
++                res = NULL;
++                kerr = ipadb_fetch_principals(ipactx, flags, principal, &res);
+                 if (kerr != 0) {
+                     goto done;
+                 }
+ 
+-                kerr = krb5_set_principal_realm(kcontext, kentry->princ, trusted_realm);
++                kerr = ipadb_find_principal(kcontext, flags, res, &principal,
++                                            &lentry);
+                 if (kerr != 0) {
+                     goto done;
+                 }
+-                *entry = kentry;
++            } else {
++
++                kerr = ipadb_is_princ_from_trusted_realm(kcontext,
++                                                         realm,
++                                                         upn->length - (realm - upn->data),
++                                                         &trusted_realm);
++                if (kerr == 0) {
++                    kentry = calloc(1, sizeof(krb5_db_entry));
++                    if (!kentry) {
++                        kerr = ENOMEM;
++                        goto done;
++                    }
++                    kerr = krb5_parse_name(kcontext, principal,
++                                           &kentry->princ);
++                    if (kerr != 0) {
++                        goto done;
++                    }
++
++                    kerr = krb5_set_principal_realm(kcontext, kentry->princ, trusted_realm);
++                    if (kerr != 0) {
++                        goto done;
++                    }
++                    *entry = kentry;
++                }
++                goto done;
+             }
++        } else {
++            goto done;
+         }
+-        goto done;
+     }
+ 
+     kerr = ipadb_parse_ldap_entry(kcontext, principal, lentry, entry, &pol);
+-- 
+2.4.3
+
diff --git a/SOURCES/0006-spec-file-Update-minimum-required-version-of-krb5.patch b/SOURCES/0006-spec-file-Update-minimum-required-version-of-krb5.patch
deleted file mode 100644
index 8bf286e..0000000
--- a/SOURCES/0006-spec-file-Update-minimum-required-version-of-krb5.patch
+++ /dev/null
@@ -1,48 +0,0 @@
-From 6bc5c6e1d7af6229e8c6f547951b0b3314ca5f12 Mon Sep 17 00:00:00 2001
-From: Jan Cholasta <jcholast@redhat.com>
-Date: Wed, 15 Jul 2015 08:45:53 +0000
-Subject: [PATCH] spec file: Update minimum required version of krb5
-
-Automatically require the krb5 version used at build time.
-
-https://fedorahosted.org/freeipa/ticket/5132
-
-Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
----
- freeipa.spec.in | 6 ++++--
- 1 file changed, 4 insertions(+), 2 deletions(-)
-
-diff --git a/freeipa.spec.in b/freeipa.spec.in
-index e78ad1a0851186c7fdb5ab0a4649b64b2b1e010f..a819710b2bad16a5c17b77670cdb29cb4b09ad8f 100644
---- a/freeipa.spec.in
-+++ b/freeipa.spec.in
-@@ -11,6 +11,8 @@
- %global selinux_policy_version 3.12.1-179
- %endif
- 
-+%define krb5_base_version %(LC_ALL=C rpm -q --qf '%%{VERSION}' krb5-devel | grep -Eo '^[^.]+\.[^.]+')
-+
- %global plugin_dir %{_libdir}/dirsrv/plugins
- %global etc_systemd_dir %{_sysconfdir}/systemd/system
- %global gettext_domain ipa
-@@ -52,7 +54,7 @@ BuildRequires:  nspr-devel
- BuildRequires:  nss-devel
- BuildRequires:  openssl-devel
- BuildRequires:  openldap-devel
--BuildRequires:  krb5-devel >= 1.11
-+BuildRequires:  krb5-devel >= 1.13
- BuildRequires:  krb5-workstation
- BuildRequires:  libuuid-devel
- BuildRequires:  libcurl-devel >= 7.21.7-2
-@@ -119,7 +121,7 @@ Requires: 389-ds-base >= 1.3.4.0
- Requires: openldap-clients > 2.4.35-4
- Requires: nss >= 3.14.3-12.0
- Requires: nss-tools >= 3.14.3-12.0
--Requires: krb5-server >= 1.11.5-5
-+Requires(post): krb5-server >= %{krb5_base_version}, krb5-server < %{krb5_base_version}.100
- Requires: krb5-pkinit-openssl
- Requires: cyrus-sasl-gssapi%{?_isa}
- Requires: ntp
--- 
-2.1.0
-
diff --git a/SOURCES/0007-Enable-vault-commands-on-client.patch b/SOURCES/0007-Enable-vault-commands-on-client.patch
new file mode 100644
index 0000000..59fd755
--- /dev/null
+++ b/SOURCES/0007-Enable-vault-commands-on-client.patch
@@ -0,0 +1,70 @@
+From 0d3f6f147382625fc326a6f84bb6a950dd4386b1 Mon Sep 17 00:00:00 2001
+From: Martin Basti <mbasti@redhat.com>
+Date: Fri, 8 Jul 2016 15:53:25 +0200
+Subject: [PATCH] Enable vault-* commands on client
+
+Client plugins fot vault commands were disabled by NO_CLI=True,
+inherited from vault_add_interal, that is always NO_CLI=True.
+Introduced by this commit 8278da6967dbe425b4e0c6cf37dc1c53052525b2
+
+Removed NO_CLI=True from client side plugins for vault.
+
+https://fedorahosted.org/freeipa/ticket/6035
+
+Reviewed-By: Martin Babinsky <mbabinsk@redhat.com>
+Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
+---
+ ipaclient/plugins/vault.py | 16 ----------------
+ 1 file changed, 16 deletions(-)
+
+diff --git a/ipaclient/plugins/vault.py b/ipaclient/plugins/vault.py
+index 11210d6e1339f42598b39bcf599d3e6eacb5b9d8..bf0242fc4290bb94f29faf9c787dd7454a8921bf 100644
+--- a/ipaclient/plugins/vault.py
++++ b/ipaclient/plugins/vault.py
+@@ -202,10 +202,6 @@ class vault_add(Local):
+         ),
+     )
+ 
+-    @property
+-    def NO_CLI(self):
+-        return self.api.Command.vault_add_internal.NO_CLI
+-
+     def get_args(self):
+         for arg in self.api.Command.vault_add_internal.args():
+             yield arg
+@@ -394,10 +390,6 @@ class vault_mod(Local):
+         ),
+     )
+ 
+-    @property
+-    def NO_CLI(self):
+-        return self.api.Command.vault_mod_internal.NO_CLI
+-
+     def get_args(self):
+         for arg in self.api.Command.vault_mod_internal.args():
+             yield arg
+@@ -572,10 +564,6 @@ class vault_archive(Local):
+         ),
+     )
+ 
+-    @property
+-    def NO_CLI(self):
+-        return self.api.Command.vault_archive_internal.NO_CLI
+-
+     def get_args(self):
+         for arg in self.api.Command.vault_archive_internal.args():
+             yield arg
+@@ -820,10 +808,6 @@ class vault_retrieve(Local):
+         ),
+     )
+ 
+-    @property
+-    def NO_CLI(self):
+-        return self.api.Command.vault_retrieve_internal.NO_CLI
+-
+     def get_args(self):
+         for arg in self.api.Command.vault_retrieve_internal.args():
+             yield arg
+-- 
+2.4.3
+
diff --git a/SOURCES/0007-do-not-import-memcache-on-client.patch b/SOURCES/0007-do-not-import-memcache-on-client.patch
deleted file mode 100644
index cbdcfb0..0000000
--- a/SOURCES/0007-do-not-import-memcache-on-client.patch
+++ /dev/null
@@ -1,41 +0,0 @@
-From 0def5f5e160f6ebdf766d956721b70c26372a0b6 Mon Sep 17 00:00:00 2001
-From: Petr Vobornik <pvoborni@redhat.com>
-Date: Thu, 16 Jul 2015 10:17:26 +0200
-Subject: [PATCH] do not import memcache on client
-
-Fixes regression caused by cd3ca94ff2ef738cb3a9eae502193413058f976d.
-
-Which caused:
-* client installation failure (missing memcache)
-* invalid warning in CLI on server
-
-https://fedorahosted.org/freeipa/ticket/5133
-
-Reviewed-By: Tomas Babej <tbabej@redhat.com>
----
- ipalib/plugins/session.py | 6 ++++--
- 1 file changed, 4 insertions(+), 2 deletions(-)
-
-diff --git a/ipalib/plugins/session.py b/ipalib/plugins/session.py
-index 3fd566d3224a13b5fbaa4450f02855329a13bc4c..b03b6b41032ab7f00ff9b75e23b5f998353a7ea5 100644
---- a/ipalib/plugins/session.py
-+++ b/ipalib/plugins/session.py
-@@ -2,11 +2,13 @@
- # Copyright (C) 2015  FreeIPA Contributors see COPYING for license
- #
- 
--from ipalib import Command
-+from ipalib import api, Command
- from ipalib.request import context
--from ipalib.session import session_mgr
- from ipalib.plugable import Registry
- 
-+if api.env.in_server:
-+    from ipalib.session import session_mgr
-+
- register = Registry()
- 
- 
--- 
-2.4.3
-
diff --git a/SOURCES/0008-selinux-enable-httpd_run_ipa-to-allow-communicating-.patch b/SOURCES/0008-selinux-enable-httpd_run_ipa-to-allow-communicating-.patch
deleted file mode 100644
index c36d10a..0000000
--- a/SOURCES/0008-selinux-enable-httpd_run_ipa-to-allow-communicating-.patch
+++ /dev/null
@@ -1,49 +0,0 @@
-From aad359de280a0c28e9a9305fd93b48cd40ddddd8 Mon Sep 17 00:00:00 2001
-From: Alexander Bokovoy <abokovoy@redhat.com>
-Date: Tue, 14 Jul 2015 11:11:36 +0000
-Subject: [PATCH] selinux: enable httpd_run_ipa to allow communicating with
- oddjobd services
-
-A new SELinux policy allows communication between IPA framework running
-under Apache with oddjobd-based services via DBus.
-
-This communication is crucial for one-way trust support and also is required
-for any out of band tools which may be executed by IPA framework.
-
-Details of out of band communication and SELinux policy can be found in a bug
-https://bugzilla.redhat.com/show_bug.cgi?id=1238165
-
-Reviewed-By: Tomas Babej <tbabej@redhat.com>
----
- freeipa.spec.in                   | 2 +-
- ipaserver/install/httpinstance.py | 1 +
- 2 files changed, 2 insertions(+), 1 deletion(-)
-
-diff --git a/freeipa.spec.in b/freeipa.spec.in
-index a819710b2bad16a5c17b77670cdb29cb4b09ad8f..5790f7941d2117ed95d3c99556f1579c27917270 100644
---- a/freeipa.spec.in
-+++ b/freeipa.spec.in
-@@ -8,7 +8,7 @@
- %global selinux_policy_version 3.12.1-153
- %else
- %global samba_version 2:4.0.5-1
--%global selinux_policy_version 3.12.1-179
-+%global selinux_policy_version 3.13.1-128.6
- %endif
- 
- %define krb5_base_version %(LC_ALL=C rpm -q --qf '%%{VERSION}' krb5-devel | grep -Eo '^[^.]+\.[^.]+')
-diff --git a/ipaserver/install/httpinstance.py b/ipaserver/install/httpinstance.py
-index f5f2a86fca3a1ff3e9123d08052a7e57b50a94fe..792825621f68844a2b0b1265eeeb37e4247d66f8 100644
---- a/ipaserver/install/httpinstance.py
-+++ b/ipaserver/install/httpinstance.py
-@@ -46,6 +46,7 @@ from ipaplatform import services
- SELINUX_BOOLEAN_SETTINGS = dict(
-     httpd_can_network_connect='on',
-     httpd_manage_ipa='on',
-+    httpd_run_ipa='on',
- )
- 
- 
--- 
-2.4.3
-
diff --git a/SOURCES/0008-vault-add-set-the-default-vault-type-on-the-client-s.patch b/SOURCES/0008-vault-add-set-the-default-vault-type-on-the-client-s.patch
new file mode 100644
index 0000000..5045dea
--- /dev/null
+++ b/SOURCES/0008-vault-add-set-the-default-vault-type-on-the-client-s.patch
@@ -0,0 +1,38 @@
+From 5754f00a924bd74079fbf8dc386437ef671547b0 Mon Sep 17 00:00:00 2001
+From: Martin Babinsky <mbabinsk@redhat.com>
+Date: Tue, 12 Jul 2016 13:44:49 +0200
+Subject: [PATCH] vault-add: set the default vault type on the client side if
+ none was given
+
+`vault-add` commands does much processing depending on the vault type even
+before the request is forwarded to remote server. Since default values for
+parameters are now filled only on server side, the client-side logic would
+fail if the vault type was not explicitly given. In this case we have to
+retrieve and use the default vault type from schema.
+
+https://fedorahosted.org/freeipa/ticket/6047
+
+Reviewed-By: Stanislav Laznicka <slaznick@redhat.com>
+---
+ ipaclient/plugins/vault.py | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/ipaclient/plugins/vault.py b/ipaclient/plugins/vault.py
+index bf0242fc4290bb94f29faf9c787dd7454a8921bf..a3ce6fecbfd38b342f826d8d27940d991d821e90 100644
+--- a/ipaclient/plugins/vault.py
++++ b/ipaclient/plugins/vault.py
+@@ -221,6 +221,11 @@ class vault_add(Local):
+     def forward(self, *args, **options):
+ 
+         vault_type = options.get('ipavaulttype')
++
++        if vault_type is None:
++            internal_cmd = self.api.Command.vault_add_internal
++            vault_type = internal_cmd.params.ipavaulttype.default
++
+         password = options.get('password')
+         password_file = options.get('password_file')
+         public_key = options.get('ipavaultpublickey')
+-- 
+2.4.3
+
diff --git a/SOURCES/0009-caacl-expand-plugin-documentation.patch b/SOURCES/0009-caacl-expand-plugin-documentation.patch
new file mode 100644
index 0000000..3b5a6c2
--- /dev/null
+++ b/SOURCES/0009-caacl-expand-plugin-documentation.patch
@@ -0,0 +1,66 @@
+From 39fdccd9216c7a58ba48ed2226a5588a4f19da51 Mon Sep 17 00:00:00 2001
+From: Fraser Tweedale <ftweedal@redhat.com>
+Date: Tue, 12 Jul 2016 15:11:11 +1000
+Subject: [PATCH] caacl: expand plugin documentation
+
+Expand the 'caacl' plugin documentation to explain some common
+confusions including the fact that CA ACLs apply to the target
+subject principal (not necessarily the principal requesting the
+cert), and the fact that CA-less CA ACL implies the 'ipa' CA.
+
+Fixes: https://fedorahosted.org/freeipa/ticket/6002
+Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
+---
+ ipaserver/plugins/caacl.py | 34 ++++++++++++++++++++++++++++------
+ 1 file changed, 28 insertions(+), 6 deletions(-)
+
+diff --git a/ipaserver/plugins/caacl.py b/ipaserver/plugins/caacl.py
+index 3f813a7efb9e554abcb8dd2946eea73065c93414..1461c4814727e5774219ac206bab3d078f2daa7d 100644
+--- a/ipaserver/plugins/caacl.py
++++ b/ipaserver/plugins/caacl.py
+@@ -23,14 +23,36 @@ if six.PY3:
+ __doc__ = _("""
+ Manage CA ACL rules.
+ 
+-This plugin is used to define rules governing which principals are
+-permitted to have certificates issued using a given certificate
+-profile.
++This plugin is used to define rules governing which CAs and profiles
++may be used to issue certificates to particular principals or groups
++of principals.
+ 
+-PROFILE ID SYNTAX:
++SUBJECT PRINCIPAL SCOPE:
+ 
+-A Profile ID is a string without spaces or punctuation starting with a letter
+-and followed by a sequence of letters, digits or underscore ("_").
++For a certificate request to be allowed, the principal(s) that are
++the subject of a certificate request (not necessarily the principal
++actually requesting the certificate) must be included in the scope
++of a CA ACL that also includes the target CA and profile.
++
++Users can be included by name, group or the "all users" category.
++Hosts can be included by name, hostgroup or the "all hosts"
++category.  Services can be included by service name or the "all
++services" category.  CA ACLs may be associated with a single type of
++principal, or multiple types.
++
++CERTIFICATE AUTHORITY SCOPE:
++
++A CA ACL can be associated with one or more CAs by name, or by the
++"all CAs" category.  For compatibility reasons, a CA ACL with no CA
++association implies an association with the 'ipa' CA (and only this
++CA).
++
++PROFILE SCOPE:
++
++A CA ACL can be associated with one or more profiles by Profile ID.
++The Profile ID is a string without spaces or punctuation starting
++with a letter and followed by a sequence of letters, digits or
++underscore ("_").
+ 
+ EXAMPLES:
+ 
+-- 
+2.4.3
+
diff --git a/SOURCES/0009-oddjob-avoid-chown-keytab-to-sssd-if-sssd-user-does-.patch b/SOURCES/0009-oddjob-avoid-chown-keytab-to-sssd-if-sssd-user-does-.patch
deleted file mode 100644
index 34ece69..0000000
--- a/SOURCES/0009-oddjob-avoid-chown-keytab-to-sssd-if-sssd-user-does-.patch
+++ /dev/null
@@ -1,50 +0,0 @@
-From cc4f00b7fcbd01dcdfd920feda39cdd0344e7cd7 Mon Sep 17 00:00:00 2001
-From: Alexander Bokovoy <abokovoy@redhat.com>
-Date: Thu, 16 Jul 2015 14:11:26 +0300
-Subject: [PATCH] oddjob: avoid chown keytab to sssd if sssd user does not
- exist
-
-If sssd user does not exist, it means SSSD does not run as sssd user.
-
-Currently SSSD has too tight check for keytab permissions and ownership.
-It assumes the keytab has to be owned by the same user it runs under
-and has to have 0600 permissions. ipa-getkeytab creates the file with
-right permissions and 'root:root' ownership.
-
-Jakub Hrozek promised to enhance SSSD keytab permissions check so that
-both sssd:sssd and root:root ownership is possible and then when SSSD
-switches to 'sssd' user, the former becomes the default. Since right now
-SSSD 1.13 is capable to run as 'sssd' user but doesn't create 'sssd'
-user in Fedora 22 / RHEL 7 environments, we can use its presence as a
-version trigger.
-
-https://fedorahosted.org/freeipa/ticket/5136
-
-Reviewed-By: Tomas Babej <tbabej@redhat.com>
----
- install/oddjob/com.redhat.idm.trust-fetch-domains | 9 +++++++--
- 1 file changed, 7 insertions(+), 2 deletions(-)
-
-diff --git a/install/oddjob/com.redhat.idm.trust-fetch-domains b/install/oddjob/com.redhat.idm.trust-fetch-domains
-index 85e3cc993b28f983f7e7ae068d9f9f135bab876e..e50c81e50e73b258bf08737c2d9a13a8832eb69f 100755
---- a/install/oddjob/com.redhat.idm.trust-fetch-domains
-+++ b/install/oddjob/com.redhat.idm.trust-fetch-domains
-@@ -45,8 +45,13 @@ def retrieve_keytab(api, ccache_name, oneway_keytab_name, oneway_principal):
-                                             env={'KRB5CCNAME': ccache_name, 'LANG': 'C'},
-                                             raiseonerr=False)
-     # Make sure SSSD is able to read the keytab
--    sssd = pwd.getpwnam('sssd')
--    os.chown(oneway_keytab_name, sssd[2], sssd[3])
-+    try:
-+        sssd = pwd.getpwnam('sssd')
-+        os.chown(oneway_keytab_name, sssd[2], sssd[3])
-+    except KeyError as e:
-+        # If user 'sssd' does not exist, we don't need to chown from root to sssd
-+        # because it means SSSD does not run as sssd user
-+        pass
- 
- 
- def parse_options():
--- 
-2.4.3
-
diff --git a/SOURCES/0010-host-find-do-not-show-SSH-key-by-default.patch b/SOURCES/0010-host-find-do-not-show-SSH-key-by-default.patch
new file mode 100644
index 0000000..387dc4d
--- /dev/null
+++ b/SOURCES/0010-host-find-do-not-show-SSH-key-by-default.patch
@@ -0,0 +1,30 @@
+From 058e260ac530f09f5fb5566a14a87614c4bdff63 Mon Sep 17 00:00:00 2001
+From: Martin Basti <mbasti@redhat.com>
+Date: Fri, 8 Jul 2016 13:40:02 +0200
+Subject: [PATCH] host-find: do not show SSH key by default
+
+Only function 'remove_sshpubkey_from_output_list_post' should be used in
+postcallbacks of *-find, otherwise only one entry will be cleaned up
+
+https://fedorahosted.org/freeipa/ticket/6043
+
+Reviewed-By: Stanislav Laznicka <slaznick@redhat.com>
+---
+ ipaserver/plugins/host.py | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/ipaserver/plugins/host.py b/ipaserver/plugins/host.py
+index 2c5cf48cb80c6a49b6577836231a19cd13d824e2..f342b05c87b936ab7b99009cfb0f6d3acde4ef93 100644
+--- a/ipaserver/plugins/host.py
++++ b/ipaserver/plugins/host.py
+@@ -1077,7 +1077,6 @@ class host_find(LDAPSearch):
+                 entry_attrs['managing'] = self.obj.get_managed_hosts(entry_attrs.dn)
+ 
+             convert_sshpubkey_post(entry_attrs)
+-            remove_sshpubkey_from_output_post(self.context, entry_attrs)
+             convert_ipaassignedidview_post(entry_attrs, options)
+ 
+         remove_sshpubkey_from_output_list_post(self.context, entries)
+-- 
+2.4.3
+
diff --git a/SOURCES/0010-webui-fix-user-reset-password-dialog.patch b/SOURCES/0010-webui-fix-user-reset-password-dialog.patch
deleted file mode 100644
index a94134f..0000000
--- a/SOURCES/0010-webui-fix-user-reset-password-dialog.patch
+++ /dev/null
@@ -1,61 +0,0 @@
-From 29bc4045aebbe06c9c4dc6985749b809b12d785e Mon Sep 17 00:00:00 2001
-From: Petr Vobornik <pvoborni@redhat.com>
-Date: Tue, 14 Jul 2015 17:55:48 +0200
-Subject: [PATCH] webui: fix user reset password dialog
-
-Could not open user password dialog.
-
-regression introduced in ed78dcfa3acde7aeb1f381f49988c6911c5277ee
-
-https://fedorahosted.org/freeipa/ticket/5131
-
-Reviewed-By: Martin Basti <mbasti@redhat.com>
----
- install/ui/src/freeipa/dialogs/password.js | 1 -
- install/ui/src/freeipa/user.js             | 5 +++--
- 2 files changed, 3 insertions(+), 3 deletions(-)
-
-diff --git a/install/ui/src/freeipa/dialogs/password.js b/install/ui/src/freeipa/dialogs/password.js
-index f25f7ac60477b1c85b5a6ede23cd93724a89e642..aa9bf44fc49b890fb5393119335b13c622f48879 100644
---- a/install/ui/src/freeipa/dialogs/password.js
-+++ b/install/ui/src/freeipa/dialogs/password.js
-@@ -48,7 +48,6 @@ dialogs.password.default_fields_pre_op =  function(spec) {
- 
-     spec.title = spec.title || '@i18n:password.reset_password';
-     spec.width = spec.width || 400;
--    spec.method = spec.method || 'mod';
-     spec.success_message = spec.success_message || '@i18n:password.password_change_complete';
-     spec.confirm_button_label = spec.confirm_button_label || '@i18n:password.reset_password';
-     spec.sections = spec.sections || [
-diff --git a/install/ui/src/freeipa/user.js b/install/ui/src/freeipa/user.js
-index e30311bbf0763d9efbc38fdb19e80e114e7636c9..0e828c16b999ffd58504bc4e53d2748bcd16b042 100644
---- a/install/ui/src/freeipa/user.js
-+++ b/install/ui/src/freeipa/user.js
-@@ -29,13 +29,14 @@ define([
-         './reg',
-         './rpc',
-         './text',
-+        './dialog',
-         './dialogs/password',
-         './details',
-         './search',
-         './association',
-         './entity',
-         './certificate'],
--    function(builder, IPA, $, phases, reg, rpc, text, password_dialog) {
-+    function(builder, IPA, $, phases, reg, rpc, text, dialogs) {
- 
- /**
-  * User module
-@@ -638,7 +639,7 @@ IPA.user.password_dialog_pre_op = function(spec) {
- 
- IPA.user.password_dialog = function(spec) {
- 
--    var that = password_dialog.dialog(spec);
-+    var that = dialogs.command_dialog(spec);
- 
-     that.is_self_service = function() {
-         var self_service = that.args[0] === IPA.whoami.uid[0];
--- 
-2.4.3
-
diff --git a/SOURCES/0011-Removed-unused-method-parameter-from-migrate-ds.patch b/SOURCES/0011-Removed-unused-method-parameter-from-migrate-ds.patch
new file mode 100644
index 0000000..97510ab
--- /dev/null
+++ b/SOURCES/0011-Removed-unused-method-parameter-from-migrate-ds.patch
@@ -0,0 +1,31 @@
+From 4132b63a5e02b019826053a07b2be79c879c1f6e Mon Sep 17 00:00:00 2001
+From: Stanislav Laznicka <slaznick@redhat.com>
+Date: Mon, 11 Jul 2016 12:31:39 +0200
+Subject: [PATCH] Removed unused method parameter from migrate-ds
+
+An extra parameter on client side command override of migrate-ds output
+was causing errors.
+
+https://fedorahosted.org/freeipa/ticket/6034
+
+Reviewed-By: Martin Babinsky <mbabinsk@redhat.com>
+---
+ ipaclient/plugins/migration.py | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/ipaclient/plugins/migration.py b/ipaclient/plugins/migration.py
+index 8ac5f66bf1440b245c1268cd97d5a3e0dc2e6226..cf8d461bfa144f1287ef36a231f553fd9cd102b3 100644
+--- a/ipaclient/plugins/migration.py
++++ b/ipaclient/plugins/migration.py
+@@ -50,7 +50,7 @@ can use their Kerberos accounts.''')
+                 option = option.clone_retype(option.name, File)
+             yield option
+ 
+-    def output_for_cli(self, textui, result, ldapuri, bindpw, **options):
++    def output_for_cli(self, textui, result, ldapuri, **options):
+         textui.print_name(self.name)
+         if not result['enabled']:
+             textui.print_plain(self.migration_disabled_msg)
+-- 
+2.4.3
+
diff --git a/SOURCES/0011-fix-hbac-rule-search-for-non-admin-users.patch b/SOURCES/0011-fix-hbac-rule-search-for-non-admin-users.patch
deleted file mode 100644
index a71a9ae..0000000
--- a/SOURCES/0011-fix-hbac-rule-search-for-non-admin-users.patch
+++ /dev/null
@@ -1,35 +0,0 @@
-From f8a4727b7e77e377e4c63c0ebd98a67f4f84bdb4 Mon Sep 17 00:00:00 2001
-From: Petr Vobornik <pvoborni@redhat.com>
-Date: Tue, 14 Jul 2015 18:04:33 +0200
-Subject: [PATCH] fix hbac rule search for non-admin users
-
-hbacrule has it default attributes (which are used in search) attribute
-'memberhostgroup'. This attr is not in ACI nor in schema. If the search
-contains an attribute which can't be read then the search won't return
-anything.
-
-Therefore all searches with filter set fail.
-
-https://fedorahosted.org/freeipa/ticket/5130
-
-Reviewed-By: Martin Basti <mbasti@redhat.com>
----
- ipalib/plugins/hbacrule.py | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/ipalib/plugins/hbacrule.py b/ipalib/plugins/hbacrule.py
-index 34bdc9bdfe03f01662851bd5aea9daf9e28823d0..82a52bd80f58ede43249264db69acd193233448d 100644
---- a/ipalib/plugins/hbacrule.py
-+++ b/ipalib/plugins/hbacrule.py
-@@ -124,7 +124,7 @@ class hbacrule(LDAPObject):
-         'description', 'usercategory', 'hostcategory',
-         'servicecategory', 'ipaenabledflag',
-         'memberuser', 'sourcehost', 'memberhost', 'memberservice',
--        'memberhostgroup', 'externalhost',
-+        'externalhost',
-     ]
-     uuid_attribute = 'ipauniqueid'
-     rdn_attribute = 'ipauniqueid'
--- 
-2.4.3
-
diff --git a/SOURCES/0012-Preserve-user-principal-aliases-during-rename-operat.patch b/SOURCES/0012-Preserve-user-principal-aliases-during-rename-operat.patch
new file mode 100644
index 0000000..b897bc3
--- /dev/null
+++ b/SOURCES/0012-Preserve-user-principal-aliases-during-rename-operat.patch
@@ -0,0 +1,92 @@
+From 07ff43d198055bc5b95a0acdf516216d00a85cc3 Mon Sep 17 00:00:00 2001
+From: Martin Babinsky <mbabinsk@redhat.com>
+Date: Fri, 1 Jul 2016 18:09:04 +0200
+Subject: [PATCH] Preserve user principal aliases during rename operation
+
+When a MODRDN is performed on the user entry, the MODRDN plugin resets both
+krbPrincipalName and krbCanonicalName to the value constructed from uid. In
+doing so, hovewer, any principal aliases added to the krbPrincipalName are
+wiped clean. In this patch old aliases are fetched before the MODRDN operation
+takes place and inserted back after it is performed.
+
+This also preserves previous user logins which can be used further for
+authentication as aliases.
+
+https://fedorahosted.org/freeipa/ticket/6028
+
+Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
+Reviewed-By: Simo Sorce <ssorce@redhat.com>
+---
+ ipaserver/plugins/baseuser.py | 46 +++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 46 insertions(+)
+
+diff --git a/ipaserver/plugins/baseuser.py b/ipaserver/plugins/baseuser.py
+index 0052e718afe639bcc1c0a698ded39ea8407a0551..e4288a5a131157815ffb2452692a7edb342f6ac3 100644
+--- a/ipaserver/plugins/baseuser.py
++++ b/ipaserver/plugins/baseuser.py
+@@ -498,6 +498,50 @@ class baseuser_mod(LDAPUpdate):
+                             len = int(config.get('ipamaxusernamelength')[0])
+                         )
+                     )
++
++    def preserve_krbprincipalname_pre(self, ldap, entry_attrs, *keys, **options):
++        """
++        preserve user principal aliases during rename operation. This is the
++        pre-callback part of this. Another method called during post-callback
++        shall insert the principals back
++        """
++        if options.get('rename', None) is None:
++            return
++
++        try:
++            old_entry = ldap.get_entry(
++                entry_attrs.dn, attrs_list=(
++                    'krbprincipalname', 'krbcanonicalname'))
++
++            if 'krbcanonicalname' not in old_entry:
++                return
++        except errors.NotFound:
++            self.obj.handle_not_found(*keys)
++
++        self.context.krbprincipalname = old_entry.get(
++            'krbprincipalname', [])
++
++    def preserve_krbprincipalname_post(self, ldap, entry_attrs, **options):
++        """
++        Insert the preserved aliases back to the user entry during rename
++        operation
++        """
++        if options.get('rename', None) is None or not hasattr(
++                self.context, 'krbprincipalname'):
++            return
++
++        obj_pkey = self.obj.get_primary_key_from_dn(entry_attrs.dn)
++        canonical_name = entry_attrs['krbcanonicalname'][0]
++
++        principals_to_add = tuple(p for p in self.context.krbprincipalname if
++                                  p != canonical_name)
++
++        if principals_to_add:
++            result = self.api.Command.user_add_principal(
++                obj_pkey, principals_to_add)['result']
++
++            entry_attrs['krbprincipalname'] = result.get('krbprincipalname', [])
++
+     def check_mail(self, entry_attrs):
+         if 'mail' in entry_attrs:
+             entry_attrs['mail'] = self.obj.normalize_and_validate_email(entry_attrs['mail'])
+@@ -557,9 +601,11 @@ class baseuser_mod(LDAPUpdate):
+ 
+         self.check_objectclass(ldap, dn, entry_attrs)
+         self.obj.convert_usercertificate_pre(entry_attrs)
++        self.preserve_krbprincipalname_pre(ldap, entry_attrs, *keys, **options)
+ 
+     def post_common_callback(self, ldap, dn, entry_attrs, *keys, **options):
+         assert isinstance(dn, DN)
++        self.preserve_krbprincipalname_post(ldap, entry_attrs, **options)
+         if options.get('random', False):
+             try:
+                 entry_attrs['randompassword'] = unicode(getattr(context, 'randompassword'))
+-- 
+2.7.4
+
diff --git a/SOURCES/0012-fix-selinuxusermap-search-for-non-admin-users.patch b/SOURCES/0012-fix-selinuxusermap-search-for-non-admin-users.patch
deleted file mode 100644
index e108873..0000000
--- a/SOURCES/0012-fix-selinuxusermap-search-for-non-admin-users.patch
+++ /dev/null
@@ -1,30 +0,0 @@
-From d234274f7e99a7eeff89e4039cf176a4b15147ec Mon Sep 17 00:00:00 2001
-From: Martin Basti <mbasti@redhat.com>
-Date: Thu, 16 Jul 2015 15:07:05 +0200
-Subject: [PATCH] fix selinuxusermap search for non-admin users
-
-Remove nonexistent attribute 'hostmembergroup' that is not in ACI nor schema.
-
-Related to https://fedorahosted.org/freeipa/ticket/5130
-
-Reviewed-By: Petr Vobornik <pvoborni@redhat.com>
----
- ipalib/plugins/selinuxusermap.py | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/ipalib/plugins/selinuxusermap.py b/ipalib/plugins/selinuxusermap.py
-index 76668b4692d4374fd09a83d6c28cb6cb2b20c958..e1a16af5004a5f4fd01166230ddd586068b6b556 100644
---- a/ipalib/plugins/selinuxusermap.py
-+++ b/ipalib/plugins/selinuxusermap.py
-@@ -143,7 +143,7 @@ class selinuxusermap(LDAPObject):
-         'cn', 'ipaenabledflag',
-         'description', 'usercategory', 'hostcategory',
-         'ipaenabledflag', 'memberuser', 'memberhost',
--        'memberhostgroup', 'seealso', 'ipaselinuxuser',
-+        'seealso', 'ipaselinuxuser',
-     ]
-     uuid_attribute = 'ipauniqueid'
-     rdn_attribute = 'ipauniqueid'
--- 
-2.4.3
-
diff --git a/SOURCES/0013-Validate-adding-privilege-to-a-permission.patch b/SOURCES/0013-Validate-adding-privilege-to-a-permission.patch
deleted file mode 100644
index 69f0992..0000000
--- a/SOURCES/0013-Validate-adding-privilege-to-a-permission.patch
+++ /dev/null
@@ -1,113 +0,0 @@
-From 8ad2b5d6b81986235d0da6aa9349cfefaec06fcb Mon Sep 17 00:00:00 2001
-From: Martin Basti <mbasti@redhat.com>
-Date: Thu, 9 Jul 2015 16:48:36 +0200
-Subject: [PATCH] Validate adding privilege to a permission
-
-Adding priviledge to a permission via webUI allowed to avoid check and to add permission
-with improper type.
-
-https://fedorahosted.org/freeipa/ticket/5075
-
-Reviewed-By: Jan Cholasta <jcholast@redhat.com>
----
- ipalib/plugins/permission.py |  7 ++++++
- ipalib/plugins/privilege.py  | 51 ++++++++++++++++++++++----------------------
- 2 files changed, 33 insertions(+), 25 deletions(-)
-
-diff --git a/ipalib/plugins/permission.py b/ipalib/plugins/permission.py
-index f2e896935cc777801ec3a70262372f296b1ea2b8..7d2a4dd156693d9d9b7d6f042488856274fb3f64 100644
---- a/ipalib/plugins/permission.py
-+++ b/ipalib/plugins/permission.py
-@@ -21,6 +21,7 @@ import re
- import traceback
- 
- from ipalib.plugins import baseldap
-+from ipalib.plugins.privilege import validate_permission_to_privilege
- from ipalib import errors
- from ipalib.parameters import Str, StrEnum, DNParam, Flag
- from ipalib import api, _, ngettext
-@@ -1377,6 +1378,12 @@ class permission_add_member(baseldap.LDAPAddMember):
-     """Add members to a permission."""
-     NO_CLI = True
- 
-+    def pre_callback(self, ldap, dn, member_dns, failed, *keys, **options):
-+        # We can only add permissions with bind rule type set to
-+        # "permission" (or old-style permissions)
-+        validate_permission_to_privilege(self.api, keys[-1])
-+        return dn
-+
- 
- @register()
- class permission_remove_member(baseldap.LDAPRemoveMember):
-diff --git a/ipalib/plugins/privilege.py b/ipalib/plugins/privilege.py
-index 867544359f76fdcb44cd3015f7466a46ba492bec..ffb903e03dbfaafbe2bb7135038494ae49a7d8a8 100644
---- a/ipalib/plugins/privilege.py
-+++ b/ipalib/plugins/privilege.py
-@@ -45,6 +45,31 @@ See role and permission for additional information.
- register = Registry()
- 
- 
-+def validate_permission_to_privilege(api, permission):
-+    ldap = api.Backend.ldap2
-+    ldapfilter = ldap.combine_filters(rules='&', filters=[
-+        '(objectClass=ipaPermissionV2)', '(!(ipaPermBindRuleType=permission))',
-+        ldap.make_filter_from_attr('cn', permission, rules='|')])
-+    try:
-+        entries, truncated = ldap.find_entries(
-+            filter=ldapfilter,
-+            attrs_list=['cn', 'ipapermbindruletype'],
-+            base_dn=DN(api.env.container_permission, api.env.basedn),
-+            size_limit=1)
-+    except errors.NotFound:
-+        pass
-+    else:
-+        entry = entries[0]
-+        message = _('cannot add permission "%(perm)s" with bindtype '
-+                    '"%(bindtype)s" to a privilege')
-+        raise errors.ValidationError(
-+            name='permission',
-+            error=message % {
-+                'perm': entry.single_value['cn'],
-+                'bindtype': entry.single_value.get(
-+                    'ipapermbindruletype', 'permission')})
-+
-+
- @register()
- class privilege(LDAPObject):
-     """
-@@ -185,31 +210,7 @@ class privilege_add_permission(LDAPAddReverseMember):
-         if options.get('permission'):
-             # We can only add permissions with bind rule type set to
-             # "permission" (or old-style permissions)
--            ldapfilter = ldap.combine_filters(rules='&', filters=[
--                '(objectClass=ipaPermissionV2)',
--                '(!(ipaPermBindRuleType=permission))',
--                ldap.make_filter_from_attr('cn', options['permission'],
--                                           rules='|'),
--            ])
--            try:
--                entries, truncated = ldap.find_entries(
--                    filter=ldapfilter,
--                    attrs_list=['cn', 'ipapermbindruletype'],
--                    base_dn=DN(self.api.env.container_permission,
--                               self.api.env.basedn),
--                    size_limit=1)
--            except errors.NotFound:
--                pass
--            else:
--                entry = entries[0]
--                message = _('cannot add permission "%(perm)s" with bindtype '
--                            '"%(bindtype)s" to a privilege')
--                raise errors.ValidationError(
--                    name='permission',
--                    error=message % {
--                        'perm': entry.single_value['cn'],
--                        'bindtype': entry.single_value.get(
--                            'ipapermbindruletype', 'permission')})
-+            validate_permission_to_privilege(self.api, options['permission'])
-         return dn
- 
- 
--- 
-2.4.3
-
diff --git a/SOURCES/0013-messages-specify-message-type-for-ResultFormattingEr.patch b/SOURCES/0013-messages-specify-message-type-for-ResultFormattingEr.patch
new file mode 100644
index 0000000..3f77ffa
--- /dev/null
+++ b/SOURCES/0013-messages-specify-message-type-for-ResultFormattingEr.patch
@@ -0,0 +1,31 @@
+From 0d5962e52aa9418ec0285f202aa786083aec67c3 Mon Sep 17 00:00:00 2001
+From: Martin Babinsky <mbabinsk@redhat.com>
+Date: Wed, 13 Jul 2016 18:22:04 +0200
+Subject: [PATCH] messages: specify message type for ResultFormattingError
+
+the ResultFormattingError message class was missing a `type` member which
+could cause `otptoken-add` command to crash during QR image rendering using
+suboptimal TTY settings
+
+https://fedorahosted.org/freeipa/ticket/6081
+
+Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
+---
+ ipalib/messages.py | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/ipalib/messages.py b/ipalib/messages.py
+index 7288606f6ac923c2c87fadba5f2a6a2d9dadb7f5..6abad64a8259a8e164db60f63e75bbb9c230e7bf 100644
+--- a/ipalib/messages.py
++++ b/ipalib/messages.py
+@@ -363,6 +363,7 @@ class ResultFormattingError(PublicMessage):
+     """
+     **13019** Unable to correctly format some part of the result
+     """
++    type = "warning"
+     errno = 13019
+ 
+ 
+-- 
+2.7.4
+
diff --git a/SOURCES/0014-migration-Use-api.env-variables.patch b/SOURCES/0014-migration-Use-api.env-variables.patch
deleted file mode 100644
index 420edaa..0000000
--- a/SOURCES/0014-migration-Use-api.env-variables.patch
+++ /dev/null
@@ -1,85 +0,0 @@
-From c626fcb564404d41cd06db83a299e97959fa3c4e Mon Sep 17 00:00:00 2001
-From: David Kupka <dkupka@redhat.com>
-Date: Thu, 16 Jul 2015 10:15:36 +0200
-Subject: [PATCH] migration: Use api.env variables.
-
-Use api.env.basedn instead of anonymously accessing LDAP to get base DN.
-Use api.env.basedn instead of searching filesystem for ldapi socket.
-
-https://fedorahosted.org/freeipa/ticket/4953
-
-Reviewed-By: Jan Cholasta <jcholast@redhat.com>
-Reviewed-By: Petr Vobornik <pvoborni@redhat.com>
-Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
----
- install/migration/migration.py | 33 +++++----------------------------
- 1 file changed, 5 insertions(+), 28 deletions(-)
-
-diff --git a/install/migration/migration.py b/install/migration/migration.py
-index b629b1c9ff7bd58f1ea64e4c2b2433428a939f28..8c440175a0358b01acba227ea3179318af50fa32 100644
---- a/install/migration/migration.py
-+++ b/install/migration/migration.py
-@@ -22,14 +22,13 @@ Password migration script
- 
- import cgi
- import errno
--import glob
- from wsgiref.util import request_uri
- 
- from ipapython.ipa_log_manager import root_logger
- from ipapython.ipautil import get_ipa_basedn
- from ipapython.dn import DN
- from ipapython.ipaldap import IPAdmin
--from ipalib import errors
-+from ipalib import errors, create_api
- from ipaplatform.paths import paths
- 
- 
-@@ -45,23 +44,6 @@ def get_ui_url(environ):
-     return full_url[:index] + "/ipa/ui"
- 
- 
--def get_base_dn(ldap_uri):
--    """
--    Retrieve LDAP server base DN.
--    """
--    try:
--        conn = IPAdmin(ldap_uri=ldap_uri)
--        conn.do_simple_bind(DN(), '')
--        base_dn = get_ipa_basedn(conn)
--    except Exception, e:
--        root_logger.error('migration context search failed: %s' % e)
--        return ''
--    finally:
--        conn.unbind()
--
--    return base_dn
--
--
- def bind(ldap_uri, base_dn, username, password):
-     if not base_dn:
-         root_logger.error('migration unable to get base dn')
-@@ -90,16 +72,11 @@ def application(environ, start_response):
-     if not form_data.has_key('username') or not form_data.has_key('password'):
-         return wsgi_redirect(start_response, 'invalid.html')
- 
--    slapd_sockets = glob.glob(paths.ALL_SLAPD_INSTANCE_SOCKETS)
--    if slapd_sockets:
--        ldap_uri = 'ldapi://%s' % slapd_sockets[0].replace('/', '%2f')
--    else:
--        ldap_uri = 'ldaps://localhost:636'
--
--    base_dn = get_base_dn(ldap_uri)
--
-+    # API object only for configuration, finalize() not needed
-+    api = create_api(mode=None)
-+    api.bootstrap(context='server', in_server=True)
-     try:
--        bind(ldap_uri, base_dn,
-+        bind(api.env.ldap_uri, api.env.basedn,
-              form_data['username'].value, form_data['password'].value)
-     except IOError as err:
-         if err.errno == errno.EPERM:
--- 
-2.4.3
-
diff --git a/SOURCES/0014-schema-Fix-subtopic-topic-mapping.patch b/SOURCES/0014-schema-Fix-subtopic-topic-mapping.patch
new file mode 100644
index 0000000..2f95e8a
--- /dev/null
+++ b/SOURCES/0014-schema-Fix-subtopic-topic-mapping.patch
@@ -0,0 +1,29 @@
+From a48b8aa5e4d45b238551c122f88dfc8151314c93 Mon Sep 17 00:00:00 2001
+From: David Kupka <dkupka@redhat.com>
+Date: Thu, 14 Jul 2016 10:15:59 +0200
+Subject: [PATCH] schema: Fix subtopic -> topic mapping
+
+https://fedorahosted.org/freeipa/ticket/6069
+
+Reviewed-By: Martin Babinsky <mbabinsk@redhat.com>
+---
+ ipaserver/plugins/schema.py | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/ipaserver/plugins/schema.py b/ipaserver/plugins/schema.py
+index a82b357899a483fd3b3dc9f7407bd26a4c03aada..8fd7c6ba1c4ed8cd6e27cb8b1b04f48694a4f1ff 100644
+--- a/ipaserver/plugins/schema.py
++++ b/ipaserver/plugins/schema.py
+@@ -399,7 +399,8 @@ class topic_(MetaObject):
+                         continue
+                     if topic_value is not None:
+                         topic_name = unicode(topic_value)
+-                        topic['topic_topic'] = topic_full_name
++                        topic['topic_topic'] = '{}/{}'.format(topic_name,
++                                                              topic_version)
+                     else:
+                         topic.pop('topic_topic', None)
+ 
+-- 
+2.7.4
+
diff --git a/SOURCES/0015-DNS-install-Ensure-that-DNS-servers-container-exists.patch b/SOURCES/0015-DNS-install-Ensure-that-DNS-servers-container-exists.patch
new file mode 100644
index 0000000..b0dd7fc
--- /dev/null
+++ b/SOURCES/0015-DNS-install-Ensure-that-DNS-servers-container-exists.patch
@@ -0,0 +1,93 @@
+From caceb3a08644dae0ecae05a5b1f18b91a522356d Mon Sep 17 00:00:00 2001
+From: Martin Babinsky <mbabinsk@redhat.com>
+Date: Thu, 14 Jul 2016 17:14:59 +0200
+Subject: [PATCH] DNS install: Ensure that DNS servers container exists
+
+during DNS installation it is assumed that the cn=servers,cn=dns container is
+always present in LDAP backend when migrating DNS server info to LDAP.
+
+This may not always be the case (e.g. when a new replica is set up against
+older master) so the code must take additional steps to ensure this container
+is present.
+
+https://fedorahosted.org/freeipa/ticket/6083
+
+Reviewed-By: Stanislav Laznicka <slaznick@redhat.com>
+---
+ ipaserver/install/bindinstance.py | 21 +++++++++++++++++++++
+ ipaserver/install/plugins/dns.py  | 13 ++-----------
+ 2 files changed, 23 insertions(+), 11 deletions(-)
+
+diff --git a/ipaserver/install/bindinstance.py b/ipaserver/install/bindinstance.py
+index f4ed63141cf25dfcfdc72d37d6ff4563e4acccf1..844fb04a9d9feca936211964b75a0b3468ba663b 100644
+--- a/ipaserver/install/bindinstance.py
++++ b/ipaserver/install/bindinstance.py
+@@ -546,6 +546,26 @@ def remove_master_dns_records(hostname, realm):
+     bind.remove_server_ns_records(hostname)
+ 
+ 
++def ensure_dnsserver_container_exists(ldap, api_instance, logger=None):
++    """
++    Create cn=servers,cn=dns,$SUFFIX container. If logger is not None, emit a
++    message that the container already exists when DuplicateEntry is raised
++    """
++
++    entry = ldap.make_entry(
++        DN(api_instance.env.container_dnsservers, api_instance.env.basedn),
++        {
++            u'objectclass': [u'top', u'nsContainer'],
++            u'cn': [u'servers']
++        }
++    )
++    try:
++        ldap.add_entry(entry)
++    except errors.DuplicateEntry:
++        if logger is not None:
++            logger.debug('cn=servers,cn=dns container already exists')
++
++
+ class DnsBackup(object):
+     def __init__(self, service):
+         self.service = service
+@@ -942,6 +962,7 @@ class BindInstance(service.Service):
+         )
+ 
+     def __setup_server_configuration(self):
++        ensure_dnsserver_container_exists(self.admin_conn, self.api)
+         try:
+             self.api.Command.dnsserver_add(
+                 self.fqdn, idnssoamname=DNSName(self.fqdn).make_absolute(),
+diff --git a/ipaserver/install/plugins/dns.py b/ipaserver/install/plugins/dns.py
+index 4fa30661e40748cd32cb25c232168191db20c461..32247eedbac7fc7e00c7277ef0bc593a74cd22e4 100644
+--- a/ipaserver/install/plugins/dns.py
++++ b/ipaserver/install/plugins/dns.py
+@@ -29,6 +29,7 @@ from ipapython.dn import DN
+ from ipapython import dnsutil
+ from ipapython.ipa_log_manager import root_logger
+ from ipaserver.install import sysupgrade
++from ipaserver.install.bindinstance import ensure_dnsserver_container_exists
+ from ipaserver.plugins.dns import dns_container_exists
+ 
+ register = Registry()
+@@ -521,17 +522,7 @@ class update_dnsserver_configuration_into_ldap(DNSUpdater):
+             return False, []
+ 
+         # create container first, if doesn't exist
+-        entry = ldap.make_entry(
+-            DN(self.api.env.container_dnsservers, self.api.env.basedn),
+-            {
+-                u'objectclass': [u'top', u'nsContainer'],
+-                u'cn': [u'servers']
+-            }
+-        )
+-        try:
+-            ldap.add_entry(entry)
+-        except errors.DuplicateEntry:
+-            self.log.debug('cn=dnsservers container already exists')
++        ensure_dnsserver_container_exists(ldap, self.api, logger=self.log)
+ 
+         try:
+             self.api.Command.dnsserver_add(self.api.env.host)
+-- 
+2.7.4
+
diff --git a/SOURCES/0015-sysrestore-copy-files-instead-of-moving-them-to-avoi.patch b/SOURCES/0015-sysrestore-copy-files-instead-of-moving-them-to-avoi.patch
deleted file mode 100644
index 330d314..0000000
--- a/SOURCES/0015-sysrestore-copy-files-instead-of-moving-them-to-avoi.patch
+++ /dev/null
@@ -1,44 +0,0 @@
-From 630a9b60995e2d6eb02281a3dd176f0252f632db Mon Sep 17 00:00:00 2001
-From: Martin Basti <mbasti@redhat.com>
-Date: Wed, 15 Jul 2015 16:20:59 +0200
-Subject: [PATCH] sysrestore: copy files instead of moving them to avoind
- SELinux issues
-
-Copying files restores SELinux context.
-
-https://fedorahosted.org/freeipa/ticket/4923
-
-Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
----
- ipapython/sysrestore.py | 8 ++++++--
- 1 file changed, 6 insertions(+), 2 deletions(-)
-
-diff --git a/ipapython/sysrestore.py b/ipapython/sysrestore.py
-index 580df9a4fd6d0fae35602dad1f81d498fa8f0173..1a111258bc0f6dd503673028d3a990821f077fef 100644
---- a/ipapython/sysrestore.py
-+++ b/ipapython/sysrestore.py
-@@ -187,7 +187,9 @@ class FileStore:
-         if new_path is not None:
-             path = new_path
- 
--        shutil.move(backup_path, path)
-+        shutil.copy(backup_path, path)  # SELinux needs copy
-+        os.remove(backup_path)
-+
-         os.chown(path, int(uid), int(gid))
-         os.chmod(path, int(mode))
- 
-@@ -218,7 +220,9 @@ class FileStore:
-                 root_logger.debug("  -> Not restoring - '%s' doesn't exist", backup_path)
-                 continue
- 
--            shutil.move(backup_path, path)
-+            shutil.copy(backup_path, path)  # SELinux needs copy
-+            os.remove(backup_path)
-+
-             os.chown(path, int(uid), int(gid))
-             os.chmod(path, int(mode))
- 
--- 
-2.4.3
-
diff --git a/SOURCES/0016-Allow-value-no-for-replica-certify-all-attr-in-abort.patch b/SOURCES/0016-Allow-value-no-for-replica-certify-all-attr-in-abort.patch
deleted file mode 100644
index f241c55..0000000
--- a/SOURCES/0016-Allow-value-no-for-replica-certify-all-attr-in-abort.patch
+++ /dev/null
@@ -1,68 +0,0 @@
-From c2b5f7b164268ec8d15916031260c87dc6c9ffd5 Mon Sep 17 00:00:00 2001
-From: Martin Basti <mbasti@redhat.com>
-Date: Thu, 16 Jul 2015 16:26:55 +0200
-Subject: [PATCH] Allow value 'no' for replica-certify-all attr in
- abort-clean-ruv subcommand
-
---force option set replica-certify-all to 'no' during abort-clean-ruv
-subcommand
-
-https://fedorahosted.org/freeipa/ticket/4988
-
-Reviewed-By: Petr Vobornik <pvoborni@redhat.com>
----
- install/tools/ipa-replica-manage       | 2 +-
- install/tools/man/ipa-replica-manage.1 | 2 +-
- ipaserver/install/replication.py       | 3 ++-
- 3 files changed, 4 insertions(+), 3 deletions(-)
-
-diff --git a/install/tools/ipa-replica-manage b/install/tools/ipa-replica-manage
-index e525a02f4c60350b7a943abab4b4aedd957e984a..50a57f70ec452c0df5bf2ea55d2a136e8149aa41 100755
---- a/install/tools/ipa-replica-manage
-+++ b/install/tools/ipa-replica-manage
-@@ -470,7 +470,7 @@ def abort_clean_ruv(realm, ruv, options):
-     print
-     thisrepl = replication.ReplicationManager(realm, options.host,
-                                               options.dirman_passwd)
--    thisrepl.abortcleanallruv(ruv)
-+    thisrepl.abortcleanallruv(ruv, options.force)
- 
-     print "Cleanup task stopped"
- 
-diff --git a/install/tools/man/ipa-replica-manage.1 b/install/tools/man/ipa-replica-manage.1
-index 8a7c78f39eeb6c7902ed99e7bed37e32eb0e92dc..c09ed362f3143e6e38716e1b3a96e90001a64674 100644
---- a/install/tools/man/ipa-replica-manage.1
-+++ b/install/tools/man/ipa-replica-manage.1
-@@ -49,7 +49,7 @@ Manages the replication agreements of an IPA server. The available commands are:
- \- Run the CLEANALLRUV task to remove a replication ID.
- .TP
- \fBabort\-clean\-ruv\fR [REPLICATION_ID]
--\- Abort a running CLEANALLRUV task.
-+\- Abort a running CLEANALLRUV task. With \-\-force option the task does not wait for all the replica servers to have been sent the abort task, or be online, before completing.
- .TP
- \fBlist\-clean\-ruv\fR
- \- List all running CLEANALLRUV and abort CLEANALLRUV tasks.
-diff --git a/ipaserver/install/replication.py b/ipaserver/install/replication.py
-index 0f420106e093e8a7a277016857d27aaa48daa4dc..e9af88dc4356d4fd5495f4fea399ab09c75db953 100644
---- a/ipaserver/install/replication.py
-+++ b/ipaserver/install/replication.py
-@@ -1451,7 +1451,7 @@ class ReplicationManager(object):
- 
-         wait_for_task(self.conn, dn)
- 
--    def abortcleanallruv(self, replicaId):
-+    def abortcleanallruv(self, replicaId, force=False):
-         """
-         Create a task to abort a CLEANALLRUV operation.
-         """
-@@ -1465,6 +1465,7 @@ class ReplicationManager(object):
-                 'replica-id': [replicaId],
-                 'objectclass': ['top', 'extensibleObject'],
-                 'cn': ['abort %d' % replicaId],
-+                'replica-certify-all': ['no'] if force else ['yes'],
-             }
-         )
-         try:
--- 
-2.4.3
-
diff --git a/SOURCES/0016-Heap-corruption-in-ipapwd-plugin.patch b/SOURCES/0016-Heap-corruption-in-ipapwd-plugin.patch
new file mode 100644
index 0000000..59d2c6e
--- /dev/null
+++ b/SOURCES/0016-Heap-corruption-in-ipapwd-plugin.patch
@@ -0,0 +1,41 @@
+From 98bdf4755d5c0256d26ba6a6aed6b9e649adf941 Mon Sep 17 00:00:00 2001
+From: Thierry Bordaz <tbordaz@redhat.com>
+Date: Mon, 18 Jul 2016 15:00:02 +0200
+Subject: [PATCH] Heap corruption in ipapwd plugin
+
+ipapwd_encrypt_encode_key allocates 'kset' on the heap but
+with num_keys and keys not being initialized.
+Then ipa_krb5_generate_key_data initializes them with the
+generated keys.
+If ipa_krb5_generate_key_data fails (here EINVAL meaning no
+principal->realm.data), num_keys and keys are left uninitialized.
+Upon failure, ipapwd_keyset_free is called to free 'kset'
+that contains random num_keys and keys.
+
+allocates kset with calloc so that kset->num_keys==0 and
+kset->keys==NULL
+
+https://fedorahosted.org/freeipa/ticket/6030
+
+Reviewed-By: Simo Sorce <ssorce@redhat.com>
+Reviewed-By: Lukas Slebodnik <lslebodn@redhat.com>
+---
+ daemons/ipa-slapi-plugins/ipa-pwd-extop/encoding.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/daemons/ipa-slapi-plugins/ipa-pwd-extop/encoding.c b/daemons/ipa-slapi-plugins/ipa-pwd-extop/encoding.c
+index 9c62f0560aa999b2179a7767040047dfa89288e0..7b2f341229b4f3bf48105c3856c0d6778da154a5 100644
+--- a/daemons/ipa-slapi-plugins/ipa-pwd-extop/encoding.c
++++ b/daemons/ipa-slapi-plugins/ipa-pwd-extop/encoding.c
+@@ -157,7 +157,7 @@ Slapi_Value **ipapwd_encrypt_encode_key(struct ipapwd_krbcfg *krbcfg,
+         pwd.length = strlen(data->password);
+     }
+ 
+-    kset = malloc(sizeof(struct ipapwd_keyset));
++    kset = (struct ipapwd_keyset *) calloc(1, sizeof(struct ipapwd_keyset));
+     if (!kset) {
+         LOG_OOM();
+         goto enc_error;
+-- 
+2.7.4
+
diff --git a/SOURCES/0017-Use-server-API-in-com.redhat.idm.trust-fetch-domains.patch b/SOURCES/0017-Use-server-API-in-com.redhat.idm.trust-fetch-domains.patch
new file mode 100644
index 0000000..52f2eae
--- /dev/null
+++ b/SOURCES/0017-Use-server-API-in-com.redhat.idm.trust-fetch-domains.patch
@@ -0,0 +1,29 @@
+From c5f48cd10b9aa3f0dd226aacab8abd8af996c861 Mon Sep 17 00:00:00 2001
+From: Martin Babinsky <mbabinsk@redhat.com>
+Date: Thu, 14 Jul 2016 09:31:22 +0200
+Subject: [PATCH] Use server API in com.redhat.idm.trust-fetch-domains oddjob
+ helper
+
+https://fedorahosted.org/freeipa/ticket/6082
+
+Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
+---
+ install/oddjob/com.redhat.idm.trust-fetch-domains | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/install/oddjob/com.redhat.idm.trust-fetch-domains b/install/oddjob/com.redhat.idm.trust-fetch-domains
+index a6b87cde917cfa5bfedf28442a6d1b2b512706f9..7c948fd53bd54bf3638ef3cc4407576b9011f4fb 100755
+--- a/install/oddjob/com.redhat.idm.trust-fetch-domains
++++ b/install/oddjob/com.redhat.idm.trust-fetch-domains
+@@ -76,7 +76,7 @@ env._bootstrap(debug=options.debug, log=None)
+ env._finalize_core(**dict(DEFAULT_CONFIG))
+ 
+ # Initialize the API with the proper debug level
+-api.bootstrap(debug=env.debug, log=None)
++api.bootstrap(in_server=True, debug=env.debug, log=None)
+ api.finalize()
+ 
+ # Only import trust plugin after api is initialized or internal imports
+-- 
+2.7.4
+
diff --git a/SOURCES/0017-trusts-Check-for-AD-root-domain-among-our-trusted-do.patch b/SOURCES/0017-trusts-Check-for-AD-root-domain-among-our-trusted-do.patch
deleted file mode 100644
index b0593e2..0000000
--- a/SOURCES/0017-trusts-Check-for-AD-root-domain-among-our-trusted-do.patch
+++ /dev/null
@@ -1,68 +0,0 @@
-From eb8651626099df8df14e12b905aace0be5c37ded Mon Sep 17 00:00:00 2001
-From: Tomas Babej <tbabej@redhat.com>
-Date: Wed, 15 Jul 2015 14:22:48 +0200
-Subject: [PATCH] trusts: Check for AD root domain among our trusted domains
-
-Check for the presence of the forest root DNS domain of the AD realm
-among the IPA realm domains prior to esablishing the trust.
-
-This prevents creation of a failing setup, as trusts would not work
-properly in this case.
-
-https://fedorahosted.org/freeipa/ticket/4799
-
-Reviewed-By: Petr Vobornik <pvoborni@redhat.com>
-Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
----
- ipalib/plugins/trust.py | 21 ++++++++++++++++++++-
- 1 file changed, 20 insertions(+), 1 deletion(-)
-
-diff --git a/ipalib/plugins/trust.py b/ipalib/plugins/trust.py
-index 196df5926e7965dc1f0165f301bd5ac11528d1cd..6232e4fe9d3d5e957d22a3557cdcf4bb12cec0ea 100644
---- a/ipalib/plugins/trust.py
-+++ b/ipalib/plugins/trust.py
-@@ -640,6 +640,8 @@ sides.
-                            self.params['realm_passwd'].label, confirm=False)
- 
-     def validate_options(self, *keys, **options):
-+        trusted_realm_domain = keys[-1]
-+
-         if not _bindings_installed:
-             raise errors.NotFound(
-                 name=_('AD Trust setup'),
-@@ -692,6 +694,23 @@ sides.
-                 )
-             )
- 
-+        # Obtain a list of IPA realm domains
-+        result = self.api.Command.realmdomains_show()['result']
-+        realm_domains = result['associateddomain']
-+
-+        # Do not allow the AD's trusted realm domain in the list
-+        # of our realm domains
-+        if trusted_realm_domain.lower() in realm_domains:
-+            raise errors.ValidationError(
-+                name=_('AD Trust setup'),
-+                error=_(
-+                    'Trusted domain %(domain)s is included among '
-+                    'IPA realm domains. It needs to be removed '
-+                    'prior to establishing the trust. See the '
-+                    '"ipa realmdomains-mod --del-domain" command.'
-+                ) % dict(domain=trusted_realm_domain)
-+            )
-+
-         self.realm_server = options.get('realm_server')
-         self.realm_admin = options.get('realm_admin')
-         self.realm_passwd = options.get('realm_passwd')
-@@ -702,7 +721,7 @@ sides.
-             if len(names) > 1:
-                 # realm admin name is in UPN format, user@realm, check that
-                 # realm is the same as the one that we are attempting to trust
--                if keys[-1].lower() != names[-1].lower():
-+                if trusted_realm_domain.lower() != names[-1].lower():
-                     raise errors.ValidationError(
-                         name=_('AD Trust setup'),
-                         error=_(
--- 
-2.4.3
-
diff --git a/SOURCES/0018-enable-debugging-of-ntpd-during-client-installation.patch b/SOURCES/0018-enable-debugging-of-ntpd-during-client-installation.patch
deleted file mode 100644
index 5dce4b2..0000000
--- a/SOURCES/0018-enable-debugging-of-ntpd-during-client-installation.patch
+++ /dev/null
@@ -1,71 +0,0 @@
-From 941941733a9a2af27ae4fd73714a87a08931e76a Mon Sep 17 00:00:00 2001
-From: Martin Babinsky <mbabinsk@redhat.com>
-Date: Mon, 30 Mar 2015 12:29:04 +0200
-Subject: [PATCH] enable debugging of ntpd during client installation
-
-When installing IPA client in debug mode, the ntpd command spawned during
-initial time-sync with master KDC will also run in debug mode.
-
-https://fedorahosted.org/freeipa/ticket/4931
-
-Reviewed-By: Jan Cholasta <jcholast@redhat.com>
-Reviewed-By: Martin Basti <mbasti@redhat.com>
----
- ipa-client/ipa-install/ipa-client-install | 5 +++--
- ipa-client/ipaclient/ntpconf.py           | 7 +++++--
- 2 files changed, 8 insertions(+), 4 deletions(-)
-
-diff --git a/ipa-client/ipa-install/ipa-client-install b/ipa-client/ipa-install/ipa-client-install
-index a1564583ca2d461413da7ea5929b91851cd3f3e1..96b30b486585bc60b0882263cff58292a3538df9 100755
---- a/ipa-client/ipa-install/ipa-client-install
-+++ b/ipa-client/ipa-install/ipa-client-install
-@@ -2388,12 +2388,13 @@ def install(options, env, fstore, statestore):
-             ntp_servers = options.ntp_servers
- 
-         for s in ntp_servers:
--            synced_ntp = ipaclient.ntpconf.synconce_ntp(s)
-+            synced_ntp = ipaclient.ntpconf.synconce_ntp(s, options.debug)
-             if synced_ntp:
-                 break
- 
-         if not synced_ntp and not options.ntp_servers:
--            synced_ntp = ipaclient.ntpconf.synconce_ntp(cli_server[0])
-+            synced_ntp = ipaclient.ntpconf.synconce_ntp(cli_server[0],
-+                                                        options.debug)
-         if not synced_ntp:
-             root_logger.warning("Unable to sync time with NTP " +
-                 "server, assuming the time is in sync. Please check " +
-diff --git a/ipa-client/ipaclient/ntpconf.py b/ipa-client/ipaclient/ntpconf.py
-index c22fba401d33009b3b95d1418dc7c8a03328d569..9a7db6544b54288569dc7699e67ddc865bb88db4 100644
---- a/ipa-client/ipaclient/ntpconf.py
-+++ b/ipa-client/ipaclient/ntpconf.py
-@@ -137,7 +137,7 @@ def config_ntp(ntp_servers, fstore = None, sysstore = None):
-     services.knownservices.ntpd.restart()
- 
- 
--def synconce_ntp(server_fqdn):
-+def synconce_ntp(server_fqdn, debug=False):
-     """
-     Syncs time with specified server using ntpd.
-     Primarily designed to be used before Kerberos setup
-@@ -150,13 +150,16 @@ def synconce_ntp(server_fqdn):
-         return False
- 
-     tmp_ntp_conf = ipautil.write_tmp_file('server %s' % server_fqdn)
-+    args = [ntpd, '-qgc', tmp_ntp_conf.name]
-+    if debug:
-+        args.append('-d')
-     try:
-         # The ntpd command will never exit if it is unable to reach the
-         # server, so timeout after 15 seconds.
-         timeout = 15
-         root_logger.info('Attempting to sync time using ntpd.  '
-                          'Will timeout after %d seconds' % timeout)
--        ipautil.run([ntpd, '-qgc', tmp_ntp_conf.name], timeout=timeout)
-+        ipautil.run(args, timeout=timeout)
-         return True
-     except ipautil.CalledProcessError:
-         return False
--- 
-2.4.3
-
diff --git a/SOURCES/0018-frontend-copy-command-arguments-to-output-params-on-.patch b/SOURCES/0018-frontend-copy-command-arguments-to-output-params-on-.patch
new file mode 100644
index 0000000..64f030e
--- /dev/null
+++ b/SOURCES/0018-frontend-copy-command-arguments-to-output-params-on-.patch
@@ -0,0 +1,39 @@
+From 1297d5f1ba731e81b03a2fca997487813a2e962a Mon Sep 17 00:00:00 2001
+From: Jan Cholasta <jcholast@redhat.com>
+Date: Mon, 18 Jul 2016 07:37:31 +0200
+Subject: [PATCH] frontend: copy command arguments to output params on client
+
+In commit f554078291d682d59956998af97f7d3066fbe7e7 we stopped copying
+command arguments to output params in order to remove redundancies and
+reduce API schema in size. Since then, output params were removed from
+API schema completely and are reconstructed on the client.
+
+Not including arguments in output params hides failed members from member
+commands' CLI output. To fix this, copy arguments to output params again,
+but only on the client side.
+
+https://fedorahosted.org/freeipa/ticket/6026
+
+Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
+---
+ ipaclient/frontend.py | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/ipaclient/frontend.py b/ipaclient/frontend.py
+index e8eacc068f4bec5ccdb21228b32a88aea24424df..1525c88b3dfeadccd8115cb4b6ba149caef22103 100644
+--- a/ipaclient/frontend.py
++++ b/ipaclient/frontend.py
+@@ -95,6 +95,10 @@ class ClientMethod(ClientCommand, Method):
+ 
+     def get_output_params(self):
+         seen = set()
++        for param in self.params():
++            if param.name not in self.obj.params:
++                seen.add(param.name)
++                yield param
+         for output_param in super(ClientMethod, self).get_output_params():
+             seen.add(output_param.name)
+             yield output_param
+-- 
+2.7.4
+
diff --git a/SOURCES/0019-Show-full-error-message-for-selinuxusermap-add-hostg.patch b/SOURCES/0019-Show-full-error-message-for-selinuxusermap-add-hostg.patch
new file mode 100644
index 0000000..ea161af
--- /dev/null
+++ b/SOURCES/0019-Show-full-error-message-for-selinuxusermap-add-hostg.patch
@@ -0,0 +1,152 @@
+From b79d70c9977a9b5026f8976e172122bf78885dd8 Mon Sep 17 00:00:00 2001
+From: Florence Blanc-Renaud <flo@redhat.com>
+Date: Wed, 20 Jul 2016 11:02:30 +0200
+Subject: [PATCH] Show full error message for selinuxusermap-add-hostgroup
+
+While investigating the issue for selinuxusermap-add-hostgroup,
+we discovered that other commands were missing output.
+A first patch fixes most of the issues:
+freeipa-jcholast-677-frontend-copy-command-arguments-to-output-params-on-.patch
+
+This patch fixes servicedelegation CLI, where
+servicedelegation.takes_params was missing
+ipaallowedtarget_servicedelegationtarget, ipaallowedtoimpersonate and
+memberprincipal
+
+https://fedorahosted.org/freeipa/ticket/6026
+
+Reviewed-By: Jan Cholasta <jcholast@redhat.com>
+---
+ ipaserver/plugins/servicedelegation.py | 53 ++++++++++------------------------
+ 1 file changed, 15 insertions(+), 38 deletions(-)
+
+diff --git a/ipaserver/plugins/servicedelegation.py b/ipaserver/plugins/servicedelegation.py
+index 958c3b739a2dd465c2b685672c3deb1af8c36e4e..6f38c36a30363755c80081d02bf4c86d829eae34 100644
+--- a/ipaserver/plugins/servicedelegation.py
++++ b/ipaserver/plugins/servicedelegation.py
+@@ -96,30 +96,6 @@ PROTECTED_CONSTRAINT_TARGETS = (
+ )
+ 
+ 
+-output_params = (
+-    Str(
+-        'ipaallowedtarget_servicedelegationtarget',
+-        label=_('Allowed Target'),
+-    ),
+-    Str(
+-        'ipaallowedtoimpersonate',
+-        label=_('Allowed to Impersonate'),
+-    ),
+-    Str(
+-        'memberprincipal',
+-        label=_('Member principals'),
+-    ),
+-    Str(
+-        'failed_memberprincipal',
+-        label=_('Failed members'),
+-    ),
+-    Str(
+-        'ipaallowedtarget',
+-        label=_('Failed targets'),
+-    ),
+-)
+-
+-
+ class servicedelegation(LDAPObject):
+     """
+     Service Constrained Delegation base object.
+@@ -175,6 +151,21 @@ class servicedelegation(LDAPObject):
+             label=_('Delegation name'),
+             primary_key=True,
+         ),
++        Str(
++            'ipaallowedtarget_servicedelegationtarget',
++            label=_('Allowed Target'),
++            flags={'virtual_attribute', 'no_create', 'no_update', 'no_search'},
++        ),
++        Str(
++            'ipaallowedtoimpersonate',
++            label=_('Allowed to Impersonate'),
++            flags={'no_create', 'no_update', 'no_search'},
++        ),
++        Str(
++            'memberprincipal',
++            label=_('Member principals'),
++            flags={'no_create', 'no_update', 'no_search'},
++        ),
+     )
+ 
+ 
+@@ -186,8 +177,6 @@ class servicedelegation_add_member(LDAPAddMember):
+     principal_attr = 'memberprincipal'
+     principal_failedattr = 'failed_memberprincipal'
+ 
+-    has_output_params = LDAPAddMember.has_output_params + output_params
+-
+     def get_options(self):
+         for option in super(servicedelegation_add_member, self).get_options():
+             yield option
+@@ -268,8 +257,6 @@ class servicedelegation_remove_member(LDAPRemoveMember):
+     principal_attr = 'memberprincipal'
+     principal_failedattr = 'failed_memberprincipal'
+ 
+-    has_output_params = LDAPRemoveMember.has_output_params + output_params
+-
+     def get_options(self):
+         for option in super(
+                 servicedelegation_remove_member, self).get_options():
+@@ -397,8 +384,6 @@ class servicedelegationrule_del(LDAPDelete):
+ class servicedelegationrule_find(LDAPSearch):
+     __doc__ = _('Search for service delegations rule.')
+ 
+-    has_output_params = LDAPSearch.has_output_params + output_params
+-
+     msg_summary = ngettext(
+         '%(count)d service delegation rule matched',
+         '%(count)d service delegation rules matched', 0
+@@ -409,8 +394,6 @@ class servicedelegationrule_find(LDAPSearch):
+ class servicedelegationrule_show(LDAPRetrieve):
+     __doc__ = _('Display information about a named service delegation rule.')
+ 
+-    has_output_params = LDAPRetrieve.has_output_params + output_params
+-
+ 
+ @register()
+ class servicedelegationrule_add_member(servicedelegation_add_member):
+@@ -437,7 +420,6 @@ class servicedelegationrule_add_target(LDAPAddMember):
+     attribute_members = {
+         'ipaallowedtarget': ['servicedelegationtarget'],
+     }
+-    has_output_params = LDAPAddMember.has_output_params + output_params
+ 
+ 
+ @register()
+@@ -447,7 +429,6 @@ class servicedelegationrule_remove_target(LDAPRemoveMember):
+     attribute_members = {
+         'ipaallowedtarget': ['servicedelegationtarget'],
+     }
+-    has_output_params = LDAPRemoveMember.has_output_params + output_params
+ 
+ 
+ @register()
+@@ -492,8 +473,6 @@ class servicedelegationtarget_del(LDAPDelete):
+ class servicedelegationtarget_find(LDAPSearch):
+     __doc__ = _('Search for service delegation target.')
+ 
+-    has_output_params = LDAPSearch.has_output_params + output_params
+-
+     msg_summary = ngettext(
+         '%(count)d service delegation target matched',
+         '%(count)d service delegation targets matched', 0
+@@ -530,8 +509,6 @@ class servicedelegationtarget_find(LDAPSearch):
+ class servicedelegationtarget_show(LDAPRetrieve):
+     __doc__ = _('Display information about a named service delegation target.')
+ 
+-    has_output_params = LDAPRetrieve.has_output_params + output_params
+-
+ 
+ @register()
+ class servicedelegationtarget_add_member(servicedelegation_add_member):
+-- 
+2.7.4
+
diff --git a/SOURCES/0019-cermonger-Use-private-unix-socket-when-DBus-SystemBu.patch b/SOURCES/0019-cermonger-Use-private-unix-socket-when-DBus-SystemBu.patch
deleted file mode 100644
index 364e464..0000000
--- a/SOURCES/0019-cermonger-Use-private-unix-socket-when-DBus-SystemBu.patch
+++ /dev/null
@@ -1,288 +0,0 @@
-From 3cec31570b04fa9ece1f3d02768a676c6c2f35ff Mon Sep 17 00:00:00 2001
-From: David Kupka <dkupka@redhat.com>
-Date: Tue, 7 Jul 2015 15:49:27 +0200
-Subject: [PATCH] cermonger: Use private unix socket when DBus SystemBus is not
- available.
-
-https://fedorahosted.org/freeipa/ticket/5095
-
-Reviewed-By: Jan Cholasta <jcholast@redhat.com>
----
- ipaplatform/base/paths.py |   4 ++
- ipapython/certmonger.py   | 137 +++++++++++++++++++++++++++++++---------------
- 2 files changed, 98 insertions(+), 43 deletions(-)
-
-diff --git a/ipaplatform/base/paths.py b/ipaplatform/base/paths.py
-index 9fef3e7a1351dd42895fe560bb3c1bc5a1c852b4..5756040172126438d42275b734f4d766d53048fe 100644
---- a/ipaplatform/base/paths.py
-+++ b/ipaplatform/base/paths.py
-@@ -348,3 +348,7 @@ class BasePathNamespace(object):
-     BAK2DB = '/usr/sbin/bak2db'
-     DB2BAK = '/usr/sbin/db2bak'
-     KDCPROXY_CONFIG = '/etc/ipa/kdcproxy/kdcproxy.conf'
-+    CERTMONGER = '/usr/sbin/certmonger'
-+
-+
-+path_namespace = BasePathNamespace
-diff --git a/ipapython/certmonger.py b/ipapython/certmonger.py
-index 4baaaa85da08bb943d6b9f0091a1d2acc36b18d6..b37676872a8b983636c7b2dc5590e83c8b08ea98 100644
---- a/ipapython/certmonger.py
-+++ b/ipapython/certmonger.py
-@@ -27,6 +27,8 @@ import sys
- import time
- import dbus
- import shlex
-+import subprocess
-+import tempfile
- from ipapython import ipautil
- from ipapython import dogtag
- from ipapython.ipa_log_manager import *
-@@ -35,6 +37,7 @@ from ipaplatform import services
- 
- DBUS_CM_PATH = '/org/fedorahosted/certmonger'
- DBUS_CM_IF = 'org.fedorahosted.certmonger'
-+DBUS_CM_NAME = 'org.fedorahosted.certmonger'
- DBUS_CM_REQUEST_IF = 'org.fedorahosted.certmonger.request'
- DBUS_CM_CA_IF = 'org.fedorahosted.certmonger.ca'
- DBUS_PROPERTY_IF = 'org.freedesktop.DBus.Properties'
-@@ -44,7 +47,7 @@ class _cm_dbus_object(object):
-     """
-     Auxiliary class for convenient DBus object handling.
-     """
--    def __init__(self, bus, object_path, object_dbus_interface,
-+    def __init__(self, bus, parent, object_path, object_dbus_interface,
-                  parent_dbus_interface=None, property_interface=False):
-         """
-         bus - DBus bus object, result of dbus.SystemBus() or dbus.SessionBus()
-@@ -60,6 +63,7 @@ class _cm_dbus_object(object):
-         if parent_dbus_interface is None:
-             parent_dbus_interface = object_dbus_interface
-         self.bus = bus
-+        self.parent = parent
-         self.path = object_path
-         self.obj_dbus_if = object_dbus_interface
-         self.parent_dbus_if = parent_dbus_interface
-@@ -69,36 +73,83 @@ class _cm_dbus_object(object):
-             self.prop_if = dbus.Interface(self.obj, DBUS_PROPERTY_IF)
- 
- 
--def _start_certmonger():
--    """
--    Start certmonger daemon. If it's already running systemctl just ignores
--    the command.
--    """
--    if not services.knownservices.certmonger.is_running():
-+class _certmonger(_cm_dbus_object):
-+    """
-+    Create a connection to certmonger.
-+    By default use SystemBus. When not available use private connection
-+    over Unix socket.
-+    This solution is really ugly and should be removed as soon as DBus
-+    SystemBus is available at system install time.
-+    """
-+    timeout = 300
-+
-+    def _start_private_conn(self):
-+        sock_filename = os.path.join(tempfile.mkdtemp(), 'certmonger')
-+        self._proc = subprocess.Popen([paths.CERTMONGER, '-n', '-L', '-P',
-+                                       sock_filename])
-+        for t in range(0, self.timeout, 5):
-+            if os.path.exists(sock_filename):
-+                return "unix:path=%s" % sock_filename
-+            time.sleep(5)
-+        self._stop_private_conn()
-+        raise RuntimeError("Failed to start certmonger: Timed out")
-+
-+    def _stop_private_conn(self):
-+        if self._proc:
-+            retcode = self._proc.poll()
-+            if retcode is not None:
-+                return
-+            self._proc.terminate()
-+            for t in range(0, self.timeout, 5):
-+                retcode = self._proc.poll()
-+                if retcode is not None:
-+                    return
-+                time.sleep(5)
-+            root_logger.error("Failed to stop certmonger.")
-+
-+    def __del__(self):
-+        self._stop_private_conn()
-+
-+    def __init__(self):
-+        self._proc = None
-+        self._bus = None
-         try:
--            services.knownservices.certmonger.start()
--        except Exception, e:
--            root_logger.error('Failed to start certmonger: %s' % e)
--            raise
--
--
--def _connect_to_certmonger():
--    """
--    Start certmonger daemon and connect to it via DBus.
--    """
--    try:
--        _start_certmonger()
--    except (KeyboardInterrupt, OSError), e:
--        root_logger.error('Failed to start certmonger: %s' % e)
--        raise
--
--    try:
--        bus = dbus.SystemBus()
--        cm = _cm_dbus_object(bus, DBUS_CM_PATH, DBUS_CM_IF)
--    except dbus.DBusException, e:
--        root_logger.error("Failed to access certmonger over DBus: %s", e)
--        raise
--    return cm
-+            self._bus = dbus.SystemBus()
-+        except dbus.DBusException as e:
-+            err_name = e.get_dbus_name()
-+            if err_name not in ['org.freedesktop.DBus.Error.NoServer',
-+                                'org.freedesktop.DBus.Error.FileNotFound']:
-+                root_logger.error("Failed to connect to certmonger over "
-+                                  "SystemBus: %s" % e)
-+                raise
-+            try:
-+                self._private_sock = self._start_private_conn()
-+                self._bus = dbus.connection.Connection(self._private_sock)
-+            except dbus.DBusException as e:
-+                root_logger.error("Failed to connect to certmonger over "
-+                                  "private socket: %s" % e)
-+                raise
-+        else:
-+            try:
-+                self._bus.get_name_owner(DBUS_CM_NAME)
-+            except dbus.DBusException:
-+                try:
-+                    services.knownservices.certmonger.start()
-+                except Exception as e:
-+                    root_logger.error("Failed to start certmonger: %s" % e)
-+                    raise
-+
-+                for t in range(0, self.timeout, 5):
-+                    try:
-+                        self._bus.get_name_owner(DBUS_CM_NAME)
-+                        break
-+                    except dbus.DBusException:
-+                        pass
-+                    time.sleep(5)
-+                    raise RuntimeError('Failed to start certmonger')
-+
-+        super(_certmonger, self).__init__(self._bus, None, DBUS_CM_PATH,
-+                                          DBUS_CM_IF)
- 
- 
- def _get_requests(criteria=dict()):
-@@ -108,7 +159,7 @@ def _get_requests(criteria=dict()):
-     if not isinstance(criteria, dict):
-         raise TypeError('"criteria" must be dict.')
- 
--    cm = _connect_to_certmonger()
-+    cm = _certmonger()
-     requests = []
-     requests_paths = []
-     if 'nickname' in criteria:
-@@ -119,12 +170,12 @@ def _get_requests(criteria=dict()):
-         requests_paths = cm.obj_if.get_requests()
- 
-     for request_path in requests_paths:
--        request = _cm_dbus_object(cm.bus, request_path, DBUS_CM_REQUEST_IF,
-+        request = _cm_dbus_object(cm.bus, cm, request_path, DBUS_CM_REQUEST_IF,
-                                   DBUS_CM_IF, True)
-         for criterion in criteria:
-             if criterion == 'ca-name':
-                 ca_path = request.obj_if.get_ca()
--                ca = _cm_dbus_object(cm.bus, ca_path, DBUS_CM_CA_IF,
-+                ca = _cm_dbus_object(cm.bus, cm, ca_path, DBUS_CM_CA_IF,
-                                      DBUS_CM_IF)
-                 value = ca.obj_if.get_nickname()
-             else:
-@@ -133,6 +184,7 @@ def _get_requests(criteria=dict()):
-                 break
-         else:
-             requests.append(request)
-+
-     return requests
- 
- 
-@@ -166,7 +218,7 @@ def get_request_value(request_id, directive):
-     if request:
-         if directive == 'ca-name':
-             ca_path = request.obj_if.get_ca()
--            ca = _cm_dbus_object(request.bus, ca_path, DBUS_CM_CA_IF,
-+            ca = _cm_dbus_object(request.bus, request, ca_path, DBUS_CM_CA_IF,
-                                  DBUS_CM_IF)
-             return ca.obj_if.get_nickname()
-         else:
-@@ -250,7 +302,7 @@ def request_cert(nssdb, nickname, subject, principal, passwd_fname=None):
-     """
-     Execute certmonger to request a server certificate.
-     """
--    cm = _connect_to_certmonger()
-+    cm = _certmonger()
-     ca_path = cm.obj_if.find_ca_by_nickname('IPA')
-     if not ca_path:
-         raise RuntimeError('IPA CA not found')
-@@ -264,7 +316,7 @@ def request_cert(nssdb, nickname, subject, principal, passwd_fname=None):
-     result = cm.obj_if.add_request(request_parameters)
-     try:
-         if result[0]:
--            request = _cm_dbus_object(cm.bus, result[1], DBUS_CM_REQUEST_IF,
-+            request = _cm_dbus_object(cm.bus, cm, result[1], DBUS_CM_REQUEST_IF,
-                                       DBUS_CM_IF, True)
-     except TypeError:
-         root_logger.error('Failed to get create new request.')
-@@ -283,7 +335,7 @@ def start_tracking(nickname, secdir, password_file=None, command=None):
- 
-     Returns certificate nickname.
-     """
--    cm = _connect_to_certmonger()
-+    cm = _certmonger()
-     params = {'TRACK': True}
-     params['cert-nickname'] = nickname
-     params['cert-database'] = os.path.abspath(secdir)
-@@ -302,7 +354,7 @@ def start_tracking(nickname, secdir, password_file=None, command=None):
-     result = cm.obj_if.add_request(params)
-     try:
-         if result[0]:
--            request = _cm_dbus_object(cm.bus, result[1], DBUS_CM_REQUEST_IF,
-+            request = _cm_dbus_object(cm.bus, cm, result[1], DBUS_CM_REQUEST_IF,
-                                       DBUS_CM_IF, True)
-     except TypeError, e:
-         root_logger.error('Failed to add new request.')
-@@ -330,8 +382,7 @@ def stop_tracking(secdir, request_id=None, nickname=None):
-         root_logger.error('Failed to get request: %s' % e)
-         raise
-     if request:
--        cm = _connect_to_certmonger()
--        cm.obj_if.remove_request(request.path)
-+        request.parent.obj_if.remove_request(request.path)
- 
- 
- def modify(request_id, profile=None):
-@@ -357,9 +408,9 @@ def _find_IPA_ca():
-     We can use find_request_value because the ca files have the
-     same file format.
-     """
--    cm = _connect_to_certmonger()
-+    cm = _certmonger()
-     ca_path = cm.obj_if.find_ca_by_nickname('IPA')
--    return _cm_dbus_object(cm.bus, ca_path, DBUS_CM_CA_IF, DBUS_CM_IF, True)
-+    return _cm_dbus_object(cm.bus, cm, ca_path, DBUS_CM_CA_IF, DBUS_CM_IF, True)
- 
- 
- def add_principal_to_cas(principal):
-@@ -423,7 +474,7 @@ def dogtag_start_tracking(ca, nickname, pin, pinfile, secdir, pre_command,
-     Both commands can be None.
-     """
- 
--    cm = _connect_to_certmonger()
-+    cm = _certmonger()
-     certmonger_cmd_template = paths.CERTMONGER_COMMAND_TEMPLATE
- 
-     params = {'TRACK': True}
--- 
-2.4.3
-
diff --git a/SOURCES/0020-allow-value-output-param-in-commands-without-primary.patch b/SOURCES/0020-allow-value-output-param-in-commands-without-primary.patch
new file mode 100644
index 0000000..6c91a7f
--- /dev/null
+++ b/SOURCES/0020-allow-value-output-param-in-commands-without-primary.patch
@@ -0,0 +1,157 @@
+From 829e708bf22e80373f1af167fbfb3e6b6bf8655e Mon Sep 17 00:00:00 2001
+From: Martin Babinsky <mbabinsk@redhat.com>
+Date: Mon, 18 Jul 2016 13:18:44 +0200
+Subject: [PATCH] allow 'value' output param in commands without primary key
+
+`PrimaryKey` output param works only for API objects that have primary keys,
+otherwise it expects None (nothing is associated with this param). Since the
+validation of command output was tightened durng thin client effort, some
+commands not honoring this contract began to fail output validation.
+
+A custom output was implemented for them to restore their functionality. It
+should however be considered as a fix for broken commands and not used
+further.
+
+https://fedorahosted.org/freeipa/ticket/6037
+https://fedorahosted.org/freeipa/ticket/6061
+
+Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
+Reviewed-By: Jan Cholasta <jcholast@redhat.com>
+---
+ API.txt                         | 10 +++++-----
+ VERSION                         |  4 ++--
+ ipalib/output.py                | 10 ++++++++++
+ ipaserver/plugins/automember.py |  3 +++
+ ipaserver/plugins/trust.py      |  2 ++
+ 5 files changed, 22 insertions(+), 7 deletions(-)
+
+diff --git a/API.txt b/API.txt
+index eb33c1fb7f94f5af45ec0b38fc7e45e484a1044e..535d8ec9a4990395207e2455a09a8c1bdef5529a 100644
+--- a/API.txt
++++ b/API.txt
+@@ -144,7 +144,7 @@ option: StrEnum('type', values=[u'group', u'hostgroup'])
+ option: Str('version?')
+ output: Entry('result')
+ output: Output('summary', type=[<type 'unicode'>, <type 'NoneType'>])
+-output: PrimaryKey('value')
++output: Output('value', type=[<type 'unicode'>])
+ command: automember_default_group_set/1
+ args: 0,6,3
+ option: Flag('all', autofill=True, cli_name='all', default=False)
+@@ -155,7 +155,7 @@ option: StrEnum('type', values=[u'group', u'hostgroup'])
+ option: Str('version?')
+ output: Entry('result')
+ output: Output('summary', type=[<type 'unicode'>, <type 'NoneType'>])
+-output: PrimaryKey('value')
++output: Output('value', type=[<type 'unicode'>])
+ command: automember_default_group_show/1
+ args: 0,4,3
+ option: Flag('all', autofill=True, cli_name='all', default=False)
+@@ -164,7 +164,7 @@ option: StrEnum('type', values=[u'group', u'hostgroup'])
+ option: Str('version?')
+ output: Entry('result')
+ output: Output('summary', type=[<type 'unicode'>, <type 'NoneType'>])
+-output: PrimaryKey('value')
++output: Output('value', type=[<type 'unicode'>])
+ command: automember_del/1
+ args: 1,2,3
+ arg: Str('cn+', cli_name='automember_rule')
+@@ -5574,7 +5574,7 @@ option: StrEnum('trust_type', autofill=True, cli_name='type', default=u'ad', val
+ option: Str('version?')
+ output: Entry('result')
+ output: Output('summary', type=[<type 'unicode'>, <type 'NoneType'>])
+-output: PrimaryKey('value')
++output: Output('value', type=[<type 'unicode'>])
+ command: trustconfig_show/1
+ args: 0,5,3
+ option: Flag('all', autofill=True, cli_name='all', default=False)
+@@ -5584,7 +5584,7 @@ option: StrEnum('trust_type', autofill=True, cli_name='type', default=u'ad', val
+ option: Str('version?')
+ output: Entry('result')
+ output: Output('summary', type=[<type 'unicode'>, <type 'NoneType'>])
+-output: PrimaryKey('value')
++output: Output('value', type=[<type 'unicode'>])
+ command: trustdomain_add/1
+ args: 2,8,3
+ arg: Str('trustcn', cli_name='trust')
+diff --git a/VERSION b/VERSION
+index 0559741451a858dd0adfa99a8bf653261d771601..ca489965050f32d2d8987dfd251ec2b2a0ba1768 100644
+--- a/VERSION
++++ b/VERSION
+@@ -90,5 +90,5 @@ IPA_DATA_VERSION=20100614120000
+ #                                                      #
+ ########################################################
+ IPA_API_VERSION_MAJOR=2
+-IPA_API_VERSION_MINOR=210
+-# Last change: Add --ca option to cert-status
++IPA_API_VERSION_MINOR=211
++# Last change: mbabinsk: allow 'value' output param in commands without primary key
+diff --git a/ipalib/output.py b/ipalib/output.py
+index 19dd9adadeb8521caf9f0dc52981ce57a7f0c8b6..b104584631629f33280164dd1d23922d21ddea49 100644
+--- a/ipalib/output.py
++++ b/ipalib/output.py
+@@ -217,3 +217,13 @@ simple_value = (
+     Output('result', bool, _('True means the operation was successful')),
+     Output('value', unicode, flags=['no_display']),
+ )
++
++# custom shim for commands like `trustconfig-show`,
++# `automember-default-group-*` which put stuff into output['value'] despite not
++# having primary key themselves. Designing commands like this is not a very
++# good practice, so please do not use this for new code.
++simple_entry = (
++    summary,
++    Entry('result'),
++    Output('value', unicode, flags=['no_display']),
++)
+diff --git a/ipaserver/plugins/automember.py b/ipaserver/plugins/automember.py
+index dfa8498a6bd44352d854bff7f8eedaba8f731eef..8e9356a9d30c98b7c72735ffb9ac05c672546a0d 100644
+--- a/ipaserver/plugins/automember.py
++++ b/ipaserver/plugins/automember.py
+@@ -586,6 +586,7 @@ class automember_default_group_set(LDAPUpdate):
+         ),
+     ) + group_type
+     msg_summary = _('Set default (fallback) group for automember "%(value)s"')
++    has_output = output.simple_entry
+ 
+     def pre_callback(self, ldap, dn, entry_attrs, attrs_list, *keys, **options):
+         dn = DN(('cn', options['type']), api.env.container_automember,
+@@ -609,6 +610,7 @@ class automember_default_group_remove(LDAPUpdate):
+ 
+     takes_options = group_type
+     msg_summary = _('Removed default (fallback) group for automember "%(value)s"')
++    has_output = output.simple_entry
+ 
+     def pre_callback(self, ldap, dn, entry_attrs, attrs_list, *keys, **options):
+         dn = DN(('cn', options['type']), api.env.container_automember,
+@@ -644,6 +646,7 @@ class automember_default_group_show(LDAPRetrieve):
+     obj_name = 'automember_default_group'
+ 
+     takes_options = group_type
++    has_output = output.simple_entry
+ 
+     def pre_callback(self, ldap, dn, attrs_list, *keys, **options):
+         dn = DN(('cn', options['type']), api.env.container_automember,
+diff --git a/ipaserver/plugins/trust.py b/ipaserver/plugins/trust.py
+index 8536202b9b785507bd27b3c7b1896b721f8c5927..d4676bd57054043edd07da5ec3321d755babf35c 100644
+--- a/ipaserver/plugins/trust.py
++++ b/ipaserver/plugins/trust.py
+@@ -1288,6 +1288,7 @@ class trustconfig_mod(LDAPUpdate):
+ 
+     takes_options = LDAPUpdate.takes_options + (_trust_type_option,)
+     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)
+@@ -1310,6 +1311,7 @@ class trustconfig_show(LDAPRetrieve):
+     __doc__ = _('Show global trust configuration.')
+ 
+     takes_options = LDAPRetrieve.takes_options + (_trust_type_option,)
++    has_output = output.simple_entry
+ 
+     def execute(self, *keys, **options):
+         result = super(trustconfig_show, self).execute(*keys, **options)
+-- 
+2.7.4
+
diff --git a/SOURCES/0020-ipa-client-install-Do-not-re-start-certmonger-and-DB.patch b/SOURCES/0020-ipa-client-install-Do-not-re-start-certmonger-and-DB.patch
deleted file mode 100644
index 5e5ef43..0000000
--- a/SOURCES/0020-ipa-client-install-Do-not-re-start-certmonger-and-DB.patch
+++ /dev/null
@@ -1,138 +0,0 @@
-From 42353682a3d9e92f4053877d66f54e44f516bb53 Mon Sep 17 00:00:00 2001
-From: David Kupka <dkupka@redhat.com>
-Date: Tue, 7 Jul 2015 15:49:51 +0200
-Subject: [PATCH] ipa-client-install: Do not (re)start certmonger and DBus
- daemons.
-
-When DBus is present in the system it is always running.
-
-Starting of certmomger is handled in ipapython/certmonger.py module if
-necessary. Restarting is no longer needed since freeipa is not changing
-certmonger's files.
-
-https://fedorahosted.org/freeipa/ticket/5095
-
-Reviewed-By: Jan Cholasta <jcholast@redhat.com>
----
- ipa-client/ipa-install/ipa-client-install | 71 +++++++------------------------
- 1 file changed, 15 insertions(+), 56 deletions(-)
-
-diff --git a/ipa-client/ipa-install/ipa-client-install b/ipa-client/ipa-install/ipa-client-install
-index 96b30b486585bc60b0882263cff58292a3538df9..91323ae115a27d221bcbc43fee887c56d99c8635 100755
---- a/ipa-client/ipa-install/ipa-client-install
-+++ b/ipa-client/ipa-install/ipa-client-install
-@@ -522,20 +522,7 @@ def uninstall(options, env):
-     ipa_db = certdb.NSSDatabase(paths.IPA_NSSDB_DIR)
-     sys_db = certdb.NSSDatabase(paths.NSS_DB_DIR)
- 
--    # Always start certmonger. We can't untrack something if it isn't
--    # running
--    messagebus = services.knownservices.messagebus
--    try:
--        messagebus.start()
--    except Exception, e:
--        log_service_error(messagebus.service_name, 'start', e)
--
-     cmonger = services.knownservices.certmonger
--    try:
--        cmonger.start()
--    except Exception, e:
--        log_service_error(cmonger.service_name, 'start', e)
--
-     if ipa_db.has_nickname('Local IPA host'):
-         try:
-             certmonger.stop_tracking(paths.IPA_NSSDB_DIR,
-@@ -576,14 +563,14 @@ def uninstall(options, env):
-                                   nickname, sys_db.secdir, e)
-                 break
- 
-+    # Remove any special principal names we added to the IPA CA helper
-+    certmonger.remove_principal_from_cas()
-+
-     try:
-         cmonger.stop()
-     except Exception, e:
-         log_service_error(cmonger.service_name, 'stop', e)
- 
--    # Remove any special principal names we added to the IPA CA helper
--    certmonger.remove_principal_from_cas()
--
-     try:
-         cmonger.disable()
-     except Exception, e:
-@@ -1138,41 +1125,14 @@ def configure_certmonger(fstore, subject_base, cli_realm, hostname, options,
-             "Not requesting host certificate.")
-         return
- 
--    started = True
-     principal = 'host/%s@%s' % (hostname, cli_realm)
- 
--    messagebus = services.knownservices.messagebus
--    try:
--        messagebus.start()
--    except Exception, e:
--        log_service_error(messagebus.service_name, 'start', e)
--
--    # Ensure that certmonger has been started at least once to generate the
--    # cas files in /var/lib/certmonger/cas.
--    cmonger = services.knownservices.certmonger
--    try:
--        cmonger.restart()
--    except Exception, e:
--        log_service_error(cmonger.service_name, 'restart', e)
--
-     if options.hostname:
--        # It needs to be stopped if we touch them
--        try:
--            cmonger.stop()
--        except Exception, e:
--            log_service_error(cmonger.service_name, 'stop', e)
-         # If the hostname is explicitly set then we need to tell certmonger
-         # which principal name to use when requesting certs.
-         certmonger.add_principal_to_cas(principal)
- 
--    try:
--        cmonger.restart()
--    except Exception, e:
--        log_service_error(cmonger.service_name, 'restart', e)
--        root_logger.warning(
--            "Automatic certificate management will not be available")
--        started = False
--
-+    cmonger = services.knownservices.certmonger
-     try:
-         cmonger.enable()
-     except Exception, e:
-@@ -1183,18 +1143,17 @@ def configure_certmonger(fstore, subject_base, cli_realm, hostname, options,
-             "Automatic certificate management will not be available")
- 
-     # Request our host cert
--    if started:
--        subject = str(DN(('CN', hostname), subject_base))
--        passwd_fname = os.path.join(paths.IPA_NSSDB_DIR, 'pwdfile.txt')
--        try:
--            certmonger.request_cert(nssdb=paths.IPA_NSSDB_DIR,
--                                    nickname='Local IPA host',
--                                    subject=subject,
--                                    principal=principal,
--                                    passwd_fname=passwd_fname)
--        except Exception:
--            root_logger.error("%s request for host certificate failed",
--                              cmonger.service_name)
-+    subject = str(DN(('CN', hostname), subject_base))
-+    passwd_fname = os.path.join(paths.IPA_NSSDB_DIR, 'pwdfile.txt')
-+    try:
-+        certmonger.request_cert(nssdb=paths.IPA_NSSDB_DIR,
-+                                nickname='Local IPA host',
-+                                subject=subject,
-+                                principal=principal,
-+                                passwd_fname=passwd_fname)
-+    except Exception:
-+        root_logger.error("%s request for host certificate failed",
-+                          cmonger.service_name)
- 
- def configure_sssd_conf(fstore, cli_realm, cli_domain, cli_server, options, client_domain, client_hostname):
-     try:
--- 
-2.4.3
-
diff --git a/SOURCES/0021-DNS-Consolidate-DNS-RR-types-in-API-and-schema.patch b/SOURCES/0021-DNS-Consolidate-DNS-RR-types-in-API-and-schema.patch
deleted file mode 100644
index 5aa37bd..0000000
--- a/SOURCES/0021-DNS-Consolidate-DNS-RR-types-in-API-and-schema.patch
+++ /dev/null
@@ -1,503 +0,0 @@
-From eeec6dd88ea1e6f2c24ee87d70a8d6aa98cbd0e4 Mon Sep 17 00:00:00 2001
-From: Martin Basti <mbasti@redhat.com>
-Date: Wed, 15 Jul 2015 09:44:07 +0200
-Subject: [PATCH] DNS: Consolidate DNS RR types in API and schema
-
-* Remove NSEC3, DNSKEY, TSIG, TKEY, TA records from API:
-    These records never worked, they dont have attributes in schema.
-    TSIG and TKEY are meta-RR should not be in LDAP
-    TA is not supported by BIND
-    NSEC3, DNSKEY are DNSSEC records generated by BIND, should not be
-    in LDAP.
-    *! SIG, NSEC are already defined in schema, must stay in API.
-
-* Add HINFO, MINFO, MD, NXT records to API as unsupported records
-    These records are already defined in LDAP schema
-
-* Add schema for RP, APL, IPSEC, DHCID, HIP, SPF records
-    These records were defined in IPA API as unsupported, but schema definition was
-    missing. This causes that ACI cannot be created for these records
-    and dnszone-find failed. (#5055)
-
-https://fedorahosted.org/freeipa/ticket/4934
-https://fedorahosted.org/freeipa/ticket/5055
-
-Reviewed-By: Martin Babinsky <mbabinsk@redhat.com>
-Reviewed-By: Petr Spacek <pspacek@redhat.com>
----
- ACI.txt                       |   4 +-
- API.txt                       |  28 ++----------
- VERSION                       |   4 +-
- install/share/60ipadns.ldif   |   8 +++-
- install/share/dns.ldif        |   2 +-
- install/updates/40-dns.update |   4 +-
- ipalib/plugins/dns.py         | 101 ++++++++++++++++++++++--------------------
- 7 files changed, 71 insertions(+), 80 deletions(-)
-
-diff --git a/ACI.txt b/ACI.txt
-index 76a7ff70e27c032bdd8fa26e076271e02b23d3b3..60607b98deb74d0b7f45d24ee9359b0cf8162b0d 100644
---- a/ACI.txt
-+++ b/ACI.txt
-@@ -61,13 +61,13 @@ aci: (targetattr = "ipaprivatekey || ipapublickey || ipasecretkey || ipasecretke
- dn: dc=ipa,dc=example
- aci: (targetattr = "cn || idnssecalgorithm || idnsseckeyactivate || idnsseckeycreated || idnsseckeydelete || idnsseckeyinactive || idnsseckeypublish || idnsseckeyref || idnsseckeyrevoke || idnsseckeysep || idnsseckeyzone || objectclass")(target = "ldap:///cn=dns,dc=ipa,dc=example")(targetfilter = "(objectclass=idnsSecKey)")(version 3.0;acl "permission:System: Manage DNSSEC metadata";allow (all) groupdn = "ldap:///cn=System: Manage DNSSEC metadata,cn=permissions,cn=pbac,dc=ipa,dc=example";)
- dn: dc=ipa,dc=example
--aci: (targetattr = "a6record || aaaarecord || afsdbrecord || arecord || certrecord || cn || cnamerecord || createtimestamp || dlvrecord || dnamerecord || dnsclass || dnsttl || dsrecord || entryusn || hinforecord || idnsallowdynupdate || idnsallowquery || idnsallowsyncptr || idnsallowtransfer || idnsforwarders || idnsforwardpolicy || idnsname || idnssecinlinesigning || idnssoaexpire || idnssoaminimum || idnssoamname || idnssoarefresh || idnssoaretry || idnssoarname || idnssoaserial || idnsupdatepolicy || idnszoneactive || keyrecord || kxrecord || locrecord || managedby || mdrecord || minforecord || modifytimestamp || mxrecord || naptrrecord || nsec3paramrecord || nsecrecord || nsrecord || nxtrecord || objectclass || ptrrecord || rrsigrecord || sigrecord || srvrecord || sshfprecord || tlsarecord || txtrecord || unknownrecord")(target = "ldap:///idnsname=*,cn=dns,dc=ipa,dc=example")(version 3.0;acl "permission:System: Read DNS Entries";allow (compare,read,search) groupdn = "ldap:///cn=System: Read DNS Entries,cn=permissions,cn=pbac,dc=ipa,dc=example";)
-+aci: (targetattr = "a6record || aaaarecord || afsdbrecord || aplrecord || arecord || certrecord || cn || cnamerecord || createtimestamp || dhcidrecord || dlvrecord || dnamerecord || dnsclass || dnsttl || dsrecord || entryusn || hinforecord || hiprecord || idnsallowdynupdate || idnsallowquery || idnsallowsyncptr || idnsallowtransfer || idnsforwarders || idnsforwardpolicy || idnsname || idnssecinlinesigning || idnssoaexpire || idnssoaminimum || idnssoamname || idnssoarefresh || idnssoaretry || idnssoarname || idnssoaserial || idnsupdatepolicy || idnszoneactive || ipseckeyrecord || keyrecord || kxrecord || locrecord || managedby || mdrecord || minforecord || modifytimestamp || mxrecord || naptrrecord || nsec3paramrecord || nsecrecord || nsrecord || nxtrecord || objectclass || ptrrecord || rprecord || rrsigrecord || sigrecord || spfrecord || srvrecord || sshfprecord || tlsarecord || txtrecord || unknownrecord")(target = "ldap:///idnsname=*,cn=dns,dc=ipa,dc=example")(version 3.0;acl "permission:System: Read DNS Entries";allow (compare,read,search) groupdn = "ldap:///cn=System: Read DNS Entries,cn=permissions,cn=pbac,dc=ipa,dc=example";)
- dn: dc=ipa,dc=example
- aci: (targetattr = "cn || createtimestamp || entryusn || idnssecalgorithm || idnsseckeyactivate || idnsseckeycreated || idnsseckeydelete || idnsseckeyinactive || idnsseckeypublish || idnsseckeyref || idnsseckeyrevoke || idnsseckeysep || idnsseckeyzone || modifytimestamp || objectclass")(target = "ldap:///cn=dns,dc=ipa,dc=example")(targetfilter = "(objectclass=idnsSecKey)")(version 3.0;acl "permission:System: Read DNSSEC metadata";allow (compare,read,search) groupdn = "ldap:///cn=System: Read DNSSEC metadata,cn=permissions,cn=pbac,dc=ipa,dc=example";)
- dn: dc=ipa,dc=example
- aci: (target = "ldap:///idnsname=*,cn=dns,dc=ipa,dc=example")(version 3.0;acl "permission:System: Remove DNS Entries";allow (delete) groupdn = "ldap:///cn=System: Remove DNS Entries,cn=permissions,cn=pbac,dc=ipa,dc=example";)
- dn: dc=ipa,dc=example
--aci: (targetattr = "a6record || aaaarecord || afsdbrecord || arecord || certrecord || cn || cnamerecord || dlvrecord || dnamerecord || dnsclass || dnsttl || dsrecord || hinforecord || idnsallowdynupdate || idnsallowquery || idnsallowsyncptr || idnsallowtransfer || idnsforwarders || idnsforwardpolicy || idnsname || idnssecinlinesigning || idnssoaexpire || idnssoaminimum || idnssoamname || idnssoarefresh || idnssoaretry || idnssoarname || idnssoaserial || idnsupdatepolicy || idnszoneactive || keyrecord || kxrecord || locrecord || managedby || mdrecord || minforecord || mxrecord || naptrrecord || nsec3paramrecord || nsecrecord || nsrecord || nxtrecord || ptrrecord || rrsigrecord || sigrecord || srvrecord || sshfprecord || tlsarecord || txtrecord || unknownrecord")(target = "ldap:///idnsname=*,cn=dns,dc=ipa,dc=example")(version 3.0;acl "permission:System: Update DNS Entries";allow (write) groupdn = "ldap:///cn=System: Update DNS Entries,cn=permissions,cn=pbac,dc=ipa,dc=example";)
-+aci: (targetattr = "a6record || aaaarecord || afsdbrecord || aplrecord || arecord || certrecord || cn || cnamerecord || dhcidrecord || dlvrecord || dnamerecord || dnsclass || dnsttl || dsrecord || hinforecord || hiprecord || idnsallowdynupdate || idnsallowquery || idnsallowsyncptr || idnsallowtransfer || idnsforwarders || idnsforwardpolicy || idnsname || idnssecinlinesigning || idnssoaexpire || idnssoaminimum || idnssoamname || idnssoarefresh || idnssoaretry || idnssoarname || idnssoaserial || idnsupdatepolicy || idnszoneactive || ipseckeyrecord || keyrecord || kxrecord || locrecord || managedby || mdrecord || minforecord || mxrecord || naptrrecord || nsec3paramrecord || nsecrecord || nsrecord || nxtrecord || ptrrecord || rprecord || rrsigrecord || sigrecord || spfrecord || srvrecord || sshfprecord || tlsarecord || txtrecord || unknownrecord")(target = "ldap:///idnsname=*,cn=dns,dc=ipa,dc=example")(version 3.0;acl "permission:System: Update DNS Entries";allow (write) groupdn = "ldap:///cn=System: Update DNS Entries,cn=permissions,cn=pbac,dc=ipa,dc=example";)
- dn: cn=groups,cn=accounts,dc=ipa,dc=example
- aci: (targetfilter = "(|(objectclass=ipausergroup)(objectclass=posixgroup))")(version 3.0;acl "permission:System: Add Groups";allow (add) groupdn = "ldap:///cn=System: Add Groups,cn=permissions,cn=pbac,dc=ipa,dc=example";)
- dn: cn=groups,cn=accounts,dc=ipa,dc=example
-diff --git a/API.txt b/API.txt
-index c68bee94e3a9ed6182f6bd2152070222e32c7532..6ab30ddab41715fdbccb4f37aa1852621bca62b4 100644
---- a/API.txt
-+++ b/API.txt
-@@ -1054,7 +1054,7 @@ output: Entry('result', <type 'dict'>, Gettext('A dictionary representing an LDA
- output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
- output: PrimaryKey('value', None, None)
- command: dnsrecord_add
--args: 2,100,3
-+args: 2,95,3
- arg: DNSNameParam('dnszoneidnsname', cli_name='dnszone', multivalue=False, only_absolute=True, primary_key=True, query=True, required=True)
- arg: DNSNameParam('idnsname', attribute=True, cli_name='name', multivalue=False, primary_key=True, required=True)
- option: Str('a6_part_data', attribute=False, cli_name='a6_data', multivalue=False, option_group=u'A6 Record', required=False)
-@@ -1087,7 +1087,6 @@ option: DLVRecord('dlvrecord', attribute=True, cli_name='dlv_rec', csv=True, mul
- option: DNSNameParam('dname_part_target', attribute=False, cli_name='dname_target', multivalue=False, option_group=u'DNAME Record', required=False)
- option: DNAMERecord('dnamerecord', attribute=True, cli_name='dname_rec', csv=True, multivalue=True, option_group=u'DNAME Record', required=False)
- option: StrEnum('dnsclass', attribute=True, cli_name='class', multivalue=False, required=False, values=(u'IN', u'CS', u'CH', u'HS'))
--option: DNSKEYRecord('dnskeyrecord', attribute=True, cli_name='dnskey_rec', csv=True, multivalue=True, option_group=u'DNSKEY Record', required=False)
- option: Int('dnsttl', attribute=True, cli_name='ttl', multivalue=False, required=False)
- option: Int('ds_part_algorithm', attribute=False, cli_name='ds_algorithm', maxvalue=255, minvalue=0, multivalue=False, option_group=u'DS Record', required=False)
- option: Str('ds_part_digest', attribute=False, cli_name='ds_digest', multivalue=False, option_group=u'DS Record', pattern='^[0-9a-fA-F]+$', required=False)
-@@ -1125,7 +1124,6 @@ option: Str('naptr_part_replacement', attribute=False, cli_name='naptr_replaceme
- option: Str('naptr_part_service', attribute=False, cli_name='naptr_service', multivalue=False, option_group=u'NAPTR Record', required=False)
- option: NAPTRRecord('naptrrecord', attribute=True, cli_name='naptr_rec', csv=True, multivalue=True, option_group=u'NAPTR Record', required=False)
- option: DNSNameParam('ns_part_hostname', attribute=False, cli_name='ns_hostname', multivalue=False, option_group=u'NS Record', required=False)
--option: NSEC3Record('nsec3record', attribute=True, cli_name='nsec3_rec', csv=True, multivalue=True, option_group=u'NSEC3 Record', required=False)
- option: NSECRecord('nsecrecord', attribute=True, cli_name='nsec_rec', csv=True, multivalue=True, option_group=u'NSEC Record', required=False)
- option: NSRecord('nsrecord', attribute=True, cli_name='ns_rec', csv=True, multivalue=True, option_group=u'NS Record', required=False)
- option: DNSNameParam('ptr_part_hostname', attribute=False, cli_name='ptr_hostname', multivalue=False, option_group=u'PTR Record', required=False)
-@@ -1146,14 +1144,11 @@ option: Str('sshfp_part_fingerprint', attribute=False, cli_name='sshfp_fingerpri
- option: Int('sshfp_part_fp_type', attribute=False, cli_name='sshfp_fp_type', maxvalue=255, minvalue=0, multivalue=False, option_group=u'SSHFP Record', required=False)
- option: SSHFPRecord('sshfprecord', attribute=True, cli_name='sshfp_rec', csv=True, multivalue=True, option_group=u'SSHFP Record', required=False)
- option: Flag('structured', autofill=True, default=False)
--option: TARecord('tarecord', attribute=True, cli_name='ta_rec', csv=True, multivalue=True, option_group=u'TA Record', required=False)
--option: TKEYRecord('tkeyrecord', attribute=True, cli_name='tkey_rec', csv=True, multivalue=True, option_group=u'TKEY Record', required=False)
- option: Str('tlsa_part_cert_association_data', attribute=False, cli_name='tlsa_cert_association_data', multivalue=False, option_group=u'TLSA Record', required=False)
- option: Int('tlsa_part_cert_usage', attribute=False, cli_name='tlsa_cert_usage', maxvalue=255, minvalue=0, multivalue=False, option_group=u'TLSA Record', required=False)
- option: Int('tlsa_part_matching_type', attribute=False, cli_name='tlsa_matching_type', maxvalue=255, minvalue=0, multivalue=False, option_group=u'TLSA Record', required=False)
- option: Int('tlsa_part_selector', attribute=False, cli_name='tlsa_selector', maxvalue=255, minvalue=0, multivalue=False, option_group=u'TLSA Record', required=False)
- option: TLSARecord('tlsarecord', attribute=True, cli_name='tlsa_rec', csv=True, multivalue=True, option_group=u'TLSA Record', required=False)
--option: TSIGRecord('tsigrecord', attribute=True, cli_name='tsig_rec', csv=True, multivalue=True, option_group=u'TSIG Record', required=False)
- option: Str('txt_part_data', attribute=False, cli_name='txt_data', multivalue=False, option_group=u'TXT Record', required=False)
- option: TXTRecord('txtrecord', attribute=True, cli_name='txt_rec', csv=True, multivalue=True, option_group=u'TXT Record', required=False)
- option: Str('version?', exclude='webui')
-@@ -1161,7 +1156,7 @@ output: Entry('result', <type 'dict'>, Gettext('A dictionary representing an LDA
- output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
- output: PrimaryKey('value', None, None)
- command: dnsrecord_del
--args: 2,39,3
-+args: 2,34,3
- arg: DNSNameParam('dnszoneidnsname', cli_name='dnszone', multivalue=False, only_absolute=True, primary_key=True, query=True, required=True)
- arg: DNSNameParam('idnsname', attribute=True, cli_name='name', multivalue=False, primary_key=True, query=True, required=True)
- option: A6Record('a6record', attribute=True, autofill=False, cli_name='a6_rec', csv=True, multivalue=True, option_group=None, required=False)
-@@ -1176,7 +1171,6 @@ option: DHCIDRecord('dhcidrecord', attribute=True, autofill=False, cli_name='dhc
- option: DLVRecord('dlvrecord', attribute=True, autofill=False, cli_name='dlv_rec', csv=True, multivalue=True, option_group=None, required=False)
- option: DNAMERecord('dnamerecord', attribute=True, autofill=False, cli_name='dname_rec', csv=True, multivalue=True, option_group=None, required=False)
- option: StrEnum('dnsclass', attribute=True, autofill=False, cli_name='class', multivalue=False, required=False, values=(u'IN', u'CS', u'CH', u'HS'))
--option: DNSKEYRecord('dnskeyrecord', attribute=True, autofill=False, cli_name='dnskey_rec', csv=True, multivalue=True, option_group=None, required=False)
- option: Int('dnsttl', attribute=True, autofill=False, cli_name='ttl', multivalue=False, required=False)
- option: DSRecord('dsrecord', attribute=True, autofill=False, cli_name='ds_rec', csv=True, multivalue=True, option_group=None, required=False)
- option: HIPRecord('hiprecord', attribute=True, autofill=False, cli_name='hip_rec', csv=True, multivalue=True, option_group=None, required=False)
-@@ -1186,7 +1180,6 @@ option: KXRecord('kxrecord', attribute=True, autofill=False, cli_name='kx_rec',
- option: LOCRecord('locrecord', attribute=True, autofill=False, cli_name='loc_rec', csv=True, multivalue=True, option_group=None, required=False)
- option: MXRecord('mxrecord', attribute=True, autofill=False, cli_name='mx_rec', csv=True, multivalue=True, option_group=None, required=False)
- option: NAPTRRecord('naptrrecord', attribute=True, autofill=False, cli_name='naptr_rec', csv=True, multivalue=True, option_group=None, required=False)
--option: NSEC3Record('nsec3record', attribute=True, autofill=False, cli_name='nsec3_rec', csv=True, multivalue=True, option_group=None, required=False)
- option: NSECRecord('nsecrecord', attribute=True, autofill=False, cli_name='nsec_rec', csv=True, multivalue=True, option_group=None, required=False)
- option: NSRecord('nsrecord', attribute=True, autofill=False, cli_name='ns_rec', csv=True, multivalue=True, option_group=None, required=False)
- option: PTRRecord('ptrrecord', attribute=True, autofill=False, cli_name='ptr_rec', csv=True, multivalue=True, option_group=None, required=False)
-@@ -1197,10 +1190,7 @@ option: SPFRecord('spfrecord', attribute=True, autofill=False, cli_name='spf_rec
- option: SRVRecord('srvrecord', attribute=True, autofill=False, cli_name='srv_rec', csv=True, multivalue=True, option_group=None, required=False)
- option: SSHFPRecord('sshfprecord', attribute=True, autofill=False, cli_name='sshfp_rec', csv=True, multivalue=True, option_group=None, required=False)
- option: Flag('structured', autofill=True, default=False)
--option: TARecord('tarecord', attribute=True, autofill=False, cli_name='ta_rec', csv=True, multivalue=True, option_group=None, required=False)
--option: TKEYRecord('tkeyrecord', attribute=True, autofill=False, cli_name='tkey_rec', csv=True, multivalue=True, option_group=None, required=False)
- option: TLSARecord('tlsarecord', attribute=True, autofill=False, cli_name='tlsa_rec', csv=True, multivalue=True, option_group=None, required=False)
--option: TSIGRecord('tsigrecord', attribute=True, autofill=False, cli_name='tsig_rec', csv=True, multivalue=True, option_group=None, required=False)
- option: TXTRecord('txtrecord', attribute=True, autofill=False, cli_name='txt_rec', csv=True, multivalue=True, option_group=None, required=False)
- option: Str('version?', exclude='webui')
- output: Output('result', <type 'dict'>, None)
-@@ -1216,7 +1206,7 @@ output: Output('result', <type 'dict'>, None)
- output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
- output: ListOfPrimaryKeys('value', None, None)
- command: dnsrecord_find
--args: 2,44,4
-+args: 2,39,4
- arg: DNSNameParam('dnszoneidnsname', cli_name='dnszone', multivalue=False, only_absolute=True, primary_key=True, query=True, required=True)
- arg: Str('criteria?', noextrawhitespace=False)
- option: A6Record('a6record', attribute=True, autofill=False, cli_name='a6_rec', csv=True, multivalue=True, option_group=None, query=True, required=False)
-@@ -1231,7 +1221,6 @@ option: DHCIDRecord('dhcidrecord', attribute=True, autofill=False, cli_name='dhc
- option: DLVRecord('dlvrecord', attribute=True, autofill=False, cli_name='dlv_rec', csv=True, multivalue=True, option_group=None, query=True, required=False)
- option: DNAMERecord('dnamerecord', attribute=True, autofill=False, cli_name='dname_rec', csv=True, multivalue=True, option_group=None, query=True, required=False)
- option: StrEnum('dnsclass', attribute=True, autofill=False, cli_name='class', multivalue=False, query=True, required=False, values=(u'IN', u'CS', u'CH', u'HS'))
--option: DNSKEYRecord('dnskeyrecord', attribute=True, autofill=False, cli_name='dnskey_rec', csv=True, multivalue=True, option_group=None, query=True, required=False)
- option: Int('dnsttl', attribute=True, autofill=False, cli_name='ttl', multivalue=False, query=True, required=False)
- option: DSRecord('dsrecord', attribute=True, autofill=False, cli_name='ds_rec', csv=True, multivalue=True, option_group=None, query=True, required=False)
- option: HIPRecord('hiprecord', attribute=True, autofill=False, cli_name='hip_rec', csv=True, multivalue=True, option_group=None, query=True, required=False)
-@@ -1242,7 +1231,6 @@ option: KXRecord('kxrecord', attribute=True, autofill=False, cli_name='kx_rec',
- option: LOCRecord('locrecord', attribute=True, autofill=False, cli_name='loc_rec', csv=True, multivalue=True, option_group=None, query=True, required=False)
- option: MXRecord('mxrecord', attribute=True, autofill=False, cli_name='mx_rec', csv=True, multivalue=True, option_group=None, query=True, required=False)
- option: NAPTRRecord('naptrrecord', attribute=True, autofill=False, cli_name='naptr_rec', csv=True, multivalue=True, option_group=None, query=True, required=False)
--option: NSEC3Record('nsec3record', attribute=True, autofill=False, cli_name='nsec3_rec', csv=True, multivalue=True, option_group=None, query=True, required=False)
- option: NSECRecord('nsecrecord', attribute=True, autofill=False, cli_name='nsec_rec', csv=True, multivalue=True, option_group=None, query=True, required=False)
- option: NSRecord('nsrecord', attribute=True, autofill=False, cli_name='ns_rec', csv=True, multivalue=True, option_group=None, query=True, required=False)
- option: Flag('pkey_only?', autofill=True, default=False)
-@@ -1256,11 +1244,8 @@ option: SPFRecord('spfrecord', attribute=True, autofill=False, cli_name='spf_rec
- option: SRVRecord('srvrecord', attribute=True, autofill=False, cli_name='srv_rec', csv=True, multivalue=True, option_group=None, query=True, required=False)
- option: SSHFPRecord('sshfprecord', attribute=True, autofill=False, cli_name='sshfp_rec', csv=True, multivalue=True, option_group=None, query=True, required=False)
- option: Flag('structured', autofill=True, default=False)
--option: TARecord('tarecord', attribute=True, autofill=False, cli_name='ta_rec', csv=True, multivalue=True, option_group=None, query=True, required=False)
- option: Int('timelimit?', autofill=False, minvalue=0)
--option: TKEYRecord('tkeyrecord', attribute=True, autofill=False, cli_name='tkey_rec', csv=True, multivalue=True, option_group=None, query=True, required=False)
- option: TLSARecord('tlsarecord', attribute=True, autofill=False, cli_name='tlsa_rec', csv=True, multivalue=True, option_group=None, query=True, required=False)
--option: TSIGRecord('tsigrecord', attribute=True, autofill=False, cli_name='tsig_rec', csv=True, multivalue=True, option_group=None, query=True, required=False)
- option: TXTRecord('txtrecord', attribute=True, autofill=False, cli_name='txt_rec', csv=True, multivalue=True, option_group=None, query=True, required=False)
- option: Str('version?', exclude='webui')
- output: Output('count', <type 'int'>, None)
-@@ -1268,7 +1253,7 @@ output: ListOfEntries('result', (<type 'list'>, <type 'tuple'>), Gettext('A list
- output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
- output: Output('truncated', <type 'bool'>, None)
- command: dnsrecord_mod
--args: 2,100,3
-+args: 2,95,3
- arg: DNSNameParam('dnszoneidnsname', cli_name='dnszone', multivalue=False, only_absolute=True, primary_key=True, query=True, required=True)
- arg: DNSNameParam('idnsname', attribute=True, cli_name='name', multivalue=False, primary_key=True, query=True, required=True)
- option: Str('a6_part_data', attribute=False, autofill=False, cli_name='a6_data', multivalue=False, option_group=u'A6 Record', required=False)
-@@ -1300,7 +1285,6 @@ option: DLVRecord('dlvrecord', attribute=True, autofill=False, cli_name='dlv_rec
- option: DNSNameParam('dname_part_target', attribute=False, autofill=False, cli_name='dname_target', multivalue=False, option_group=u'DNAME Record', required=False)
- option: DNAMERecord('dnamerecord', attribute=True, autofill=False, cli_name='dname_rec', csv=True, multivalue=True, option_group=u'DNAME Record', required=False)
- option: StrEnum('dnsclass', attribute=True, autofill=False, cli_name='class', multivalue=False, required=False, values=(u'IN', u'CS', u'CH', u'HS'))
--option: DNSKEYRecord('dnskeyrecord', attribute=True, autofill=False, cli_name='dnskey_rec', csv=True, multivalue=True, option_group=u'DNSKEY Record', required=False)
- option: Int('dnsttl', attribute=True, autofill=False, cli_name='ttl', multivalue=False, required=False)
- option: Int('ds_part_algorithm', attribute=False, autofill=False, cli_name='ds_algorithm', maxvalue=255, minvalue=0, multivalue=False, option_group=u'DS Record', required=False)
- option: Str('ds_part_digest', attribute=False, autofill=False, cli_name='ds_digest', multivalue=False, option_group=u'DS Record', pattern='^[0-9a-fA-F]+$', required=False)
-@@ -1337,7 +1321,6 @@ option: Str('naptr_part_replacement', attribute=False, autofill=False, cli_name=
- option: Str('naptr_part_service', attribute=False, autofill=False, cli_name='naptr_service', multivalue=False, option_group=u'NAPTR Record', required=False)
- option: NAPTRRecord('naptrrecord', attribute=True, autofill=False, cli_name='naptr_rec', csv=True, multivalue=True, option_group=u'NAPTR Record', required=False)
- option: DNSNameParam('ns_part_hostname', attribute=False, autofill=False, cli_name='ns_hostname', multivalue=False, option_group=u'NS Record', required=False)
--option: NSEC3Record('nsec3record', attribute=True, autofill=False, cli_name='nsec3_rec', csv=True, multivalue=True, option_group=u'NSEC3 Record', required=False)
- option: NSECRecord('nsecrecord', attribute=True, autofill=False, cli_name='nsec_rec', csv=True, multivalue=True, option_group=u'NSEC Record', required=False)
- option: NSRecord('nsrecord', attribute=True, autofill=False, cli_name='ns_rec', csv=True, multivalue=True, option_group=u'NS Record', required=False)
- option: DNSNameParam('ptr_part_hostname', attribute=False, autofill=False, cli_name='ptr_hostname', multivalue=False, option_group=u'PTR Record', required=False)
-@@ -1360,14 +1343,11 @@ option: Str('sshfp_part_fingerprint', attribute=False, autofill=False, cli_name=
- option: Int('sshfp_part_fp_type', attribute=False, autofill=False, cli_name='sshfp_fp_type', maxvalue=255, minvalue=0, multivalue=False, option_group=u'SSHFP Record', required=False)
- option: SSHFPRecord('sshfprecord', attribute=True, autofill=False, cli_name='sshfp_rec', csv=True, multivalue=True, option_group=u'SSHFP Record', required=False)
- option: Flag('structured', autofill=True, default=False)
--option: TARecord('tarecord', attribute=True, autofill=False, cli_name='ta_rec', csv=True, multivalue=True, option_group=u'TA Record', required=False)
--option: TKEYRecord('tkeyrecord', attribute=True, autofill=False, cli_name='tkey_rec', csv=True, multivalue=True, option_group=u'TKEY Record', required=False)
- option: Str('tlsa_part_cert_association_data', attribute=False, autofill=False, cli_name='tlsa_cert_association_data', multivalue=False, option_group=u'TLSA Record', required=False)
- option: Int('tlsa_part_cert_usage', attribute=False, autofill=False, cli_name='tlsa_cert_usage', maxvalue=255, minvalue=0, multivalue=False, option_group=u'TLSA Record', required=False)
- option: Int('tlsa_part_matching_type', attribute=False, autofill=False, cli_name='tlsa_matching_type', maxvalue=255, minvalue=0, multivalue=False, option_group=u'TLSA Record', required=False)
- option: Int('tlsa_part_selector', attribute=False, autofill=False, cli_name='tlsa_selector', maxvalue=255, minvalue=0, multivalue=False, option_group=u'TLSA Record', required=False)
- option: TLSARecord('tlsarecord', attribute=True, autofill=False, cli_name='tlsa_rec', csv=True, multivalue=True, option_group=u'TLSA Record', required=False)
--option: TSIGRecord('tsigrecord', attribute=True, autofill=False, cli_name='tsig_rec', csv=True, multivalue=True, option_group=u'TSIG Record', required=False)
- option: Str('txt_part_data', attribute=False, autofill=False, cli_name='txt_data', multivalue=False, option_group=u'TXT Record', required=False)
- option: TXTRecord('txtrecord', attribute=True, autofill=False, cli_name='txt_rec', csv=True, multivalue=True, option_group=u'TXT Record', required=False)
- option: Str('version?', exclude='webui')
-diff --git a/VERSION b/VERSION
-index b2f7a9a3e73b5f38741f7266054e3429803d7036..678d1f8a7e588d480b16441e12e4d527d9c1cd98 100644
---- a/VERSION
-+++ b/VERSION
-@@ -90,5 +90,5 @@ IPA_DATA_VERSION=20100614120000
- #                                                      #
- ########################################################
- IPA_API_VERSION_MAJOR=2
--IPA_API_VERSION_MINOR=146
--# Last change: pvoborni - move session_logout to ipalib/plugins
-+IPA_API_VERSION_MINOR=147
-+# Last change: mbasti - Consolidate DNS RR in API and schema
-diff --git a/install/share/60ipadns.ldif b/install/share/60ipadns.ldif
-index 9e5b7feb2ee1809fb67b23cb2017a536d1bacb0a..e0ed0ab869cea0478d9640bb509c6267abed1a01 100644
---- a/install/share/60ipadns.ldif
-+++ b/install/share/60ipadns.ldif
-@@ -10,6 +10,7 @@ attributeTypes: (1.3.6.1.4.1.2428.20.1.12 NAME 'pTRRecord' DESC 'domain name poi
- attributeTypes: (1.3.6.1.4.1.2428.20.1.13 NAME 'hInfoRecord' DESC 'host information, RFC 1035' EQUALITY caseIgnoreIA5Match SUBSTR caseIgnoreIA5SubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
- attributeTypes: (1.3.6.1.4.1.2428.20.1.14 NAME 'mInfoRecord' DESC 'mailbox or mail list information, RFC 1035' EQUALITY caseIgnoreIA5Match SUBSTR caseIgnoreIA5SubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
- attributeTypes: (1.3.6.1.4.1.2428.20.1.16 NAME 'tXTRecord' DESC 'text string, RFC 1035' EQUALITY caseIgnoreIA5Match SUBSTR caseIgnoreIA5SubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
-+attributeTypes: (1.3.6.1.4.1.2428.20.1.17 NAME 'RPRecord' DESC 'Responsible Person, RFC 1183' EQUALITY caseIgnoreIA5Match SUBSTR caseIgnoreIA5SubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
- attributeTypes: (1.3.6.1.4.1.2428.20.1.18 NAME 'aFSDBRecord' DESC 'for AFS Data Base location, RFC 1183' EQUALITY caseIgnoreIA5Match SUBSTR caseIgnoreIA5SubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
- attributeTypes: (1.3.6.1.4.1.2428.20.1.24 NAME 'SigRecord' DESC 'Signature, RFC 2535' EQUALITY caseIgnoreIA5Match SUBSTR caseIgnoreIA5SubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
- attributeTypes: (1.3.6.1.4.1.2428.20.1.25 NAME 'KeyRecord' DESC 'Key, RFC 2535' EQUALITY caseIgnoreIA5Match SUBSTR caseIgnoreIA5SubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
-@@ -22,12 +23,17 @@ attributeTypes: (1.3.6.1.4.1.2428.20.1.36 NAME 'kXRecord' DESC 'Key Exchange Del
- attributeTypes: (1.3.6.1.4.1.2428.20.1.37 NAME 'certRecord' DESC 'certificate, RFC 2538' EQUALITY caseIgnoreIA5Match SUBSTR caseIgnoreIA5SubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
- attributeTypes: (1.3.6.1.4.1.2428.20.1.38 NAME 'a6Record' DESC 'A6 Record Type, RFC 2874' EQUALITY caseIgnoreIA5Match SUBSTR caseIgnoreIA5SubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
- attributeTypes: (1.3.6.1.4.1.2428.20.1.39 NAME 'dNameRecord' DESC 'Non-Terminal DNS Name Redirection, RFC 2672' EQUALITY caseIgnoreIA5Match SUBSTR caseIgnoreIA5SubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
-+attributeTypes: (1.3.6.1.4.1.2428.20.1.42 NAME 'APLRecord' DESC 'Lists of Address Prefixes, RFC 3132' EQUALITY caseIgnoreIA5Match SUBSTR caseIgnoreIA5SubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
- attributeTypes: (1.3.6.1.4.1.2428.20.1.43 NAME 'dSRecord' DESC 'Delegation Signer, RFC 3658' EQUALITY caseIgnoreIA5Match SUBSTR caseIgnoreIA5SubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
- attributeTypes: (1.3.6.1.4.1.2428.20.1.44 NAME 'sSHFPRecord' DESC 'SSH Key Fingerprint, draft-ietf-secsh-dns-05.txt' EQUALITY caseIgnoreIA5Match SUBSTR caseIgnoreIA5SubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
-+attributeTypes: (1.3.6.1.4.1.2428.20.1.45 NAME 'IPSECKEYRecord' DESC 'IPSECKEY, RFC 4025' EQUALITY caseIgnoreIA5Match SUBSTR caseIgnoreIA5SubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
- attributeTypes: (1.3.6.1.4.1.2428.20.1.46 NAME 'rRSIGRecord' DESC 'RRSIG, RFC 3755' EQUALITY caseIgnoreIA5Match SUBSTR caseIgnoreIA5SubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
- attributeTypes: (1.3.6.1.4.1.2428.20.1.47 NAME 'nSECRecord' DESC 'NSEC, RFC 3755' EQUALITY caseIgnoreIA5Match SUBSTR caseIgnoreIA5SubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
-+attributeTypes: (1.3.6.1.4.1.2428.20.1.49 NAME 'DHCIDRecord' DESC 'Dynamic Host Configuration Protocol (DHCP) Information, RFC 4701' EQUALITY caseIgnoreIA5Match SUBSTR caseIgnoreIA5SubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
- attributeTypes: (1.3.6.1.4.1.2428.20.1.51 NAME 'nSEC3PARAMRecord' DESC 'RFC 5155' EQUALITY caseIgnoreIA5Match SUBSTR caseIgnoreIA5SubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
- attributeTypes: (1.3.6.1.4.1.2428.20.1.52 NAME 'TLSARecord' DESC 'DNS-Based Authentication of Named Entities - Transport Layer Security Protocol, RFC 6698' EQUALITY caseIgnoreIA5Match SUBSTR caseIgnoreIA5SubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
-+attributeTypes: (1.3.6.1.4.1.2428.20.1.55 NAME 'HIPRecord' DESC 'Host Identity Protocol (HIP) Domain Name System (DNS) Extension, RFC 5205' EQUALITY caseIgnoreIA5Match SUBSTR caseIgnoreIA5SubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
-+attributeTypes: (1.3.6.1.4.1.2428.20.1.99 NAME 'SPFRecord' DESC 'Sender Policy Framework (SPF) for Authorizing Use of Domains in Email, RFC 7208' EQUALITY caseIgnoreIA5Match SUBSTR caseIgnoreIA5SubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
- attributeTypes: (1.3.6.1.4.1.2428.20.1.32769 NAME 'DLVRecord' DESC 'DNSSEC Lookaside Validation, RFC 4431' EQUALITY caseIgnoreIA5Match SUBSTR caseIgnoreIA5SubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
- attributeTypes: (1.3.6.1.4.1.2428.20.4 NAME 'UnknownRecord' DESC 'unknown DNS record, RFC 3597' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 EQUALITY caseIgnoreIA5Match  SUBSTR caseIgnoreIA5SubstringsMatch )
- attributeTypes: (0.9.2342.19200300.100.1.26 NAME 'aRecord' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
-@@ -64,7 +70,7 @@ attributeTypes: ( 2.16.840.1.113730.3.8.5.25 NAME 'idnsSecKeyRevoke' DESC 'DNSKE
- attributeTypes: ( 2.16.840.1.113730.3.8.5.26 NAME 'idnsSecKeySep' DESC 'DNSKEY SEP flag (equivalent to bit 15): RFC 4035' EQUALITY booleanMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-ORIGIN 'IPA v4.1' )
- attributeTypes: ( 2.16.840.1.113730.3.8.5.27 NAME 'idnsSecAlgorithm' DESC 'DNSKEY algorithm: string used as mnemonic' EQUALITY caseIgnoreIA5Match SUBSTR caseIgnoreIA5SubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE X-ORIGIN 'IPA v4.1' )
- attributeTypes: ( 2.16.840.1.113730.3.8.5.28 NAME 'idnsSecKeyRef' DESC 'PKCS#11 URI of the key' EQUALITY caseExactMatch SINGLE-VALUE SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'IPA v4.1' )
--objectClasses: ( 2.16.840.1.113730.3.8.6.0 NAME 'idnsRecord' DESC 'dns Record, usually a host' SUP top STRUCTURAL MUST idnsName MAY ( cn $ idnsAllowDynUpdate $ dNSTTL $ dNSClass $ aRecord $ aAAARecord $ a6Record $ nSRecord $ cNAMERecord $ pTRRecord $ sRVRecord $ tXTRecord $ mXRecord $ mDRecord $ hInfoRecord $ mInfoRecord $ aFSDBRecord $ SigRecord $ KeyRecord $ LocRecord $ nXTRecord $ nAPTRRecord $ kXRecord $ certRecord $ dNameRecord $ dSRecord $ sSHFPRecord $ rRSIGRecord $ nSECRecord $ DLVRecord $ TLSARecord $ UnknownRecord ) )
-+objectClasses: ( 2.16.840.1.113730.3.8.6.0 NAME 'idnsRecord' DESC 'dns Record, usually a host' SUP top STRUCTURAL MUST idnsName MAY ( cn $ idnsAllowDynUpdate $ dNSTTL $ dNSClass $ aRecord $ aAAARecord $ a6Record $ nSRecord $ cNAMERecord $ pTRRecord $ sRVRecord $ tXTRecord $ mXRecord $ mDRecord $ hInfoRecord $ mInfoRecord $ aFSDBRecord $ SigRecord $ KeyRecord $ LocRecord $ nXTRecord $ nAPTRRecord $ kXRecord $ certRecord $ dNameRecord $ dSRecord $ sSHFPRecord $ rRSIGRecord $ nSECRecord $ DLVRecord $ TLSARecord $ UnknownRecord $ RPRecord $ APLRecord $ IPSECKEYRecord $ DHCIDRecord $ HIPRecord $ SPFRecord ) )
- objectClasses: ( 2.16.840.1.113730.3.8.6.1 NAME 'idnsZone' DESC 'Zone class' SUP idnsRecord STRUCTURAL MUST ( idnsZoneActive $ idnsSOAmName $ idnsSOArName $ idnsSOAserial $ idnsSOArefresh $ idnsSOAretry $ idnsSOAexpire $ idnsSOAminimum ) MAY ( idnsUpdatePolicy $ idnsAllowQuery $ idnsAllowTransfer $ idnsAllowSyncPTR $ idnsForwardPolicy $ idnsForwarders $ idnsSecInlineSigning $ nSEC3PARAMRecord ) )
- objectClasses: ( 2.16.840.1.113730.3.8.6.2 NAME 'idnsConfigObject' DESC 'DNS global config options' STRUCTURAL MAY ( idnsForwardPolicy $ idnsForwarders $ idnsAllowSyncPTR $ idnsZoneRefresh $ idnsPersistentSearch ) )
- objectClasses: ( 2.16.840.1.113730.3.8.12.18 NAME 'ipaDNSZone' SUP top AUXILIARY MUST idnsName MAY managedBy X-ORIGIN 'IPA v3' )
-diff --git a/install/share/dns.ldif b/install/share/dns.ldif
-index c9e368677006b55d0e748f54d297d83bdd69e205..42b41a8d706a8a3fd826320aff6c9333264128fc 100644
---- a/install/share/dns.ldif
-+++ b/install/share/dns.ldif
-@@ -9,7 +9,7 @@ ipaConfigString: DNSVersion 1
- aci: (targetattr = "*")(version 3.0; acl "Allow read access"; allow (read,search,compare) groupdn = "ldap:///cn=Read DNS Entries,cn=permissions,cn=pbac,$SUFFIX" or userattr = "parent[0,1].managedby#GROUPDN";)
- aci: (target = "ldap:///idnsname=*,cn=dns,$SUFFIX")(version 3.0;acl "Add DNS entries in a zone";allow (add) userattr = "parent[1].managedby#GROUPDN";)
- aci: (target = "ldap:///idnsname=*,cn=dns,$SUFFIX")(version 3.0;acl "Remove DNS entries from a zone";allow (delete) userattr = "parent[1].managedby#GROUPDN";)
--aci: (targetattr = "idnsname || cn || idnsallowdynupdate || dnsttl || dnsclass || arecord || aaaarecord || a6record || nsrecord || cnamerecord || ptrrecord || srvrecord || txtrecord || mxrecord || mdrecord || hinforecord || minforecord || afsdbrecord || sigrecord || keyrecord || locrecord || nxtrecord || naptrrecord || kxrecord || certrecord || dnamerecord || dsrecord || sshfprecord || rrsigrecord || nsecrecord || idnsname || idnszoneactive || idnssoamname || idnssoarname || idnssoaserial || idnssoarefresh || idnssoaretry || idnssoaexpire || idnssoaminimum || idnsupdatepolicy || idnsallowquery || idnsallowtransfer || idnsallowsyncptr || idnsforwardpolicy || idnsforwarders || dlvrecord || idnssecinlinesigning || nsec3paramrecord || tlsarecord || unknownrecord ")(target = "ldap:///idnsname=*,cn=dns,$SUFFIX")(version 3.0;acl "Update DNS entries in a zone";allow (write) userattr = "parent[0,1].managedby#GROUPDN";)
-+aci: (targetattr = "a6record || aaaarecord || afsdbrecord || aplrecord || arecord || certrecord || cn || cnamerecord || dhcidrecord || dlvrecord || dnamerecord || dnsclass || dnsttl || dsrecord || hinforecord || hiprecord || idnsallowdynupdate || idnsallowquery || idnsallowsyncptr || idnsallowtransfer || idnsforwarders || idnsforwardpolicy || idnsname || idnssecinlinesigning || idnssoaexpire || idnssoaminimum || idnssoamname || idnssoarefresh || idnssoaretry || idnssoarname || idnssoaserial || idnsupdatepolicy || idnszoneactive || ipseckeyrecord || keyrecord || kxrecord || locrecord || mdrecord || minforecord || mxrecord || naptrrecord || nsecrecord || nsec3paramrecord || nsrecord || nxtrecord || ptrrecord || rprecord || rrsigrecord || sigrecord || spfrecord || srvrecord || sshfprecord || tlsarecord || txtrecord || unknownrecord ")(target = "ldap:///idnsname=*,cn=dns,$SUFFIX")(version 3.0;acl "Update DNS entries in a zone";allow (write) userattr = "parent[0,1].managedby#GROUPDN";)
- 
- dn: cn=DNS Administrators,cn=privileges,cn=pbac,$SUFFIX
- changetype: add
-diff --git a/install/updates/40-dns.update b/install/updates/40-dns.update
-index c06d8158d85fd811be0253ac0f1146a623fae2b2..9f64a2f707db5cb0e3503259a0e64d9831ae92f2 100644
---- a/install/updates/40-dns.update
-+++ b/install/updates/40-dns.update
-@@ -5,7 +5,8 @@ addifexist: objectClass: idnsConfigObject
- addifexist: objectClass: ipaConfigObject
- addifexist: aci:(target = "ldap:///idnsname=*,cn=dns,$SUFFIX")(version 3.0;acl "Add DNS entries in a zone";allow (add) userattr = "parent[1].managedby#GROUPDN";)
- addifexist: aci:(target = "ldap:///idnsname=*,cn=dns,$SUFFIX")(version 3.0;acl "Remove DNS entries from a zone";allow (delete) userattr = "parent[1].managedby#GROUPDN";)
--addifexist: aci:(targetattr = "idnsname || cn || idnsallowdynupdate || dnsttl || dnsclass || arecord || aaaarecord || a6record || nsrecord || cnamerecord || ptrrecord || srvrecord || txtrecord || mxrecord || mdrecord || hinforecord || minforecord || afsdbrecord || sigrecord || keyrecord || locrecord || nxtrecord || naptrrecord || kxrecord || certrecord || dnamerecord || dsrecord || sshfprecord || rrsigrecord || nsecrecord || idnsname || idnszoneactive || idnssoamname || idnssoarname || idnssoaserial || idnssoarefresh || idnssoaretry || idnssoaexpire || idnssoaminimum || idnsupdatepolicy || idnsallowquery || idnsallowtransfer || idnsallowsyncptr || idnsforwardpolicy || idnsforwarders || dlvrecord || idnssecinlinesigning || nsec3paramrecord || tlsarecord || unknownrecord ")(target = "ldap:///idnsname=*,cn=dns,$SUFFIX")(version 3.0;acl "Update DNS entries in a zone";allow (write) userattr = "parent[0,1].managedby#GROUPDN";)
-+addifexist: aci:(targetattr = "a6record || aaaarecord || afsdbrecord || aplrecord || arecord || certrecord || cn || cnamerecord || dhcidrecord || dlvrecord || dnamerecord || dnsclass || dnsttl || dsrecord || hinforecord || hiprecord || idnsallowdynupdate || idnsallowquery || idnsallowsyncptr || idnsallowtransfer || idnsforwarders || idnsforwardpolicy || idnsname || idnssecinlinesigning || idnssoaexpire || idnssoaminimum || idnssoamname || idnssoarefresh || idnssoaretry || idnssoarname || idnssoaserial || idnsupdatepolicy || idnszoneactive || ipseckeyrecord || keyrecord || kxrecord || locrecord || mdrecord || minforecord || mxrecord || naptrrecord || nsecrecord || nsec3paramrecord || nsrecord || nxtrecord || ptrrecord || rprecord || rrsigrecord || sigrecord || spfrecord || srvrecord || sshfprecord || tlsarecord || txtrecord || unknownrecord ")(target = "ldap:///idnsname=*,cn=dns,$SUFFIX")(version 3.0;acl "Update DNS entries in a zone";allow (write) userattr = "parent[0,1].managedby#GROUPDN";)
-+
- 
- # replace DNS tree deny rule with managedBy enhanced allow rule
- dn: cn=dns, $SUFFIX
-@@ -16,6 +17,7 @@ replace:aci:(targetattr = "*")(version 3.0; acl "Allow read access"; allow (read
- dn: cn=dns, $SUFFIX
- remove:aci:(targetattr = "idnsname || cn || idnsallowdynupdate || dnsttl || dnsclass || arecord || aaaarecord || a6record || nsrecord || cnamerecord || ptrrecord || srvrecord || txtrecord || mxrecord || mdrecord || hinforecord || minforecord || afsdbrecord || sigrecord || keyrecord || locrecord || nxtrecord || naptrrecord || kxrecord || certrecord || dnamerecord || dsrecord || sshfprecord || rrsigrecord || nsecrecord || idnsname || idnszoneactive || idnssoamname || idnssoarname || idnssoaserial || idnssoarefresh || idnssoaretry || idnssoaexpire || idnssoaminimum || idnsupdatepolicy || idnsallowquery || idnsallowtransfer || idnsallowsyncptr || idnsforwardpolicy || idnsforwarders")(target = "ldap:///idnsname=*,cn=dns,$SUFFIX")(version 3.0;acl "Update DNS entries in a zone";allow (write) userattr = "parent[0,1].managedby#GROUPDN";)
- remove:aci:(targetattr = "idnsname || cn || idnsallowdynupdate || dnsttl || dnsclass || arecord || aaaarecord || a6record || nsrecord || cnamerecord || ptrrecord || srvrecord || txtrecord || mxrecord || mdrecord || hinforecord || minforecord || afsdbrecord || sigrecord || keyrecord || locrecord || nxtrecord || naptrrecord || kxrecord || certrecord || dnamerecord || dsrecord || sshfprecord || rrsigrecord || nsecrecord || idnsname || idnszoneactive || idnssoamname || idnssoarname || idnssoaserial || idnssoarefresh || idnssoaretry || idnssoaexpire || idnssoaminimum || idnsupdatepolicy || idnsallowquery || idnsallowtransfer || idnsallowsyncptr || idnsforwardpolicy || idnsforwarders || dlvrecord || idnssecinlinesigning || nsec3paramrecord || tlsarecord ")(target = "ldap:///idnsname=*,cn=dns,$SUFFIX")(version 3.0;acl "Update DNS entries in a zone";allow (write) userattr = "parent[0,1].managedby#GROUPDN";)
-+remove:aci:(targetattr = "idnsname || cn || idnsallowdynupdate || dnsttl || dnsclass || arecord || aaaarecord || a6record || nsrecord || cnamerecord || ptrrecord || srvrecord || txtrecord || mxrecord || mdrecord || hinforecord || minforecord || afsdbrecord || sigrecord || keyrecord || locrecord || nxtrecord || naptrrecord || kxrecord || certrecord || dnamerecord || dsrecord || sshfprecord || rrsigrecord || nsecrecord || idnsname || idnszoneactive || idnssoamname || idnssoarname || idnssoaserial || idnssoarefresh || idnssoaretry || idnssoaexpire || idnssoaminimum || idnsupdatepolicy || idnsallowquery || idnsallowtransfer || idnsallowsyncptr || idnsforwardpolicy || idnsforwarders || dlvrecord || idnssecinlinesigning || nsec3paramrecord || tlsarecord || unknownrecord ")(target = "ldap:///idnsname=*,cn=dns,$SUFFIX")(version 3.0;acl "Update DNS entries in a zone";allow (write) userattr = "parent[0,1].managedby#GROUPDN";)
- 
- # add DNS plugin
- dn: cn=IPA DNS,cn=plugins,cn=config
-diff --git a/ipalib/plugins/dns.py b/ipalib/plugins/dns.py
-index a7a4100db6de1956b8d0468e03214abc227386d5..512a653c3cc8ee641debec0d20f58e17eff08266 100644
---- a/ipalib/plugins/dns.py
-+++ b/ipalib/plugins/dns.py
-@@ -281,10 +281,9 @@ register = Registry()
- # supported resource record types
- _record_types = (
-     u'A', u'AAAA', u'A6', u'AFSDB', u'APL', u'CERT', u'CNAME', u'DHCID', u'DLV',
--    u'DNAME', u'DNSKEY', u'DS', u'HIP', u'IPSECKEY', u'KEY', u'KX', u'LOC',
--    u'MX', u'NAPTR', u'NS', u'NSEC', u'NSEC3', u'PTR',
--    u'RRSIG', u'RP', u'SIG', u'SPF', u'SRV', u'SSHFP', u'TA', u'TKEY',
--    u'TLSA', u'TSIG', u'TXT',
-+    u'DNAME', u'DS', u'HIP', u'HINFO', u'IPSECKEY', u'KEY', u'KX', u'LOC',
-+    u'MD', u'MINFO', u'MX', u'NAPTR', u'NS', u'NSEC', u'NXT', u'PTR', u'RRSIG',
-+    u'RP', u'SIG', u'SPF', u'SRV', u'SSHFP', u'TLSA', u'TXT',
- )
- 
- # DNS zone record identificator
-@@ -1092,9 +1091,6 @@ class DNAMERecord(DNSRecord):
-         ),
-     )
- 
--class DNSKEYRecord(UnsupportedDNSRecord):
--    rrtype = 'DNSKEY'
--    rfc = 4034
- 
- class DSRecord(DNSRecord):
-     rrtype = 'DS'
-@@ -1129,6 +1125,11 @@ class DLVRecord(DSRecord):
-     rfc = 4431
- 
- 
-+class HINFORecord(UnsupportedDNSRecord):
-+    rrtype = 'HINFO'
-+    rfc = 1035
-+
-+
- class HIPRecord(UnsupportedDNSRecord):
-     rrtype = 'HIP'
-     rfc = 5205
-@@ -1287,6 +1288,18 @@ class LOCRecord(DNSRecord):
-                                              name=target_cli_name)
-                     raise errors.ValidationError(name=self.name, error=error)
- 
-+
-+class MDRecord(UnsupportedDNSRecord):
-+    # obsoleted, use MX instead
-+    rrtype = 'MD'
-+    rfc = 1035
-+
-+
-+class MINFORecord(UnsupportedDNSRecord):
-+    rrtype = 'MINFO'
-+    rfc = 1035
-+
-+
- class MXRecord(DNSRecord):
-     rrtype = 'MX'
-     rfc = 1035
-@@ -1318,9 +1331,6 @@ class NSECRecord(UnsupportedDNSRecord):
-     rrtype = 'NSEC'
-     rfc = 4034
- 
--class NSEC3Record(UnsupportedDNSRecord):
--    rrtype = 'NSEC3'
--    rfc = 5155
- 
- def _validate_naptr_flags(ugettext, flags):
-     allowed_flags = u'SAUP'
-@@ -1361,6 +1371,12 @@ class NAPTRRecord(DNSRecord):
-         ),
-     )
- 
-+
-+class NXTRecord(UnsupportedDNSRecord):
-+    rrtype = 'NXT'
-+    rfc = 2535
-+
-+
- class PTRRecord(DNSRecord):
-     rrtype = 'PTR'
-     rfc = 1035
-@@ -1450,10 +1466,6 @@ class SSHFPRecord(DNSRecord):
-         return tuple(values)
- 
- 
--class TARecord(UnsupportedDNSRecord):
--    rrtype = 'TA'
--
--
- class TLSARecord(DNSRecord):
-     rrtype = 'TLSA'
-     rfc = 6698
-@@ -1479,12 +1491,6 @@ class TLSARecord(DNSRecord):
-     )
- 
- 
--class TKEYRecord(UnsupportedDNSRecord):
--    rrtype = 'TKEY'
--
--class TSIGRecord(UnsupportedDNSRecord):
--    rrtype = 'TSIG'
--
- class TXTRecord(DNSRecord):
-     rrtype = 'TXT'
-     rfc = 1035
-@@ -1509,7 +1515,6 @@ _dns_records = (
-     DHCIDRecord(),
-     DLVRecord(),
-     DNAMERecord(),
--    DNSKEYRecord(),
-     DSRecord(),
-     HIPRecord(),
-     IPSECKEYRecord(),
-@@ -1520,7 +1525,6 @@ _dns_records = (
-     NAPTRRecord(),
-     NSRecord(),
-     NSECRecord(),
--    NSEC3Record(),
-     PTRRecord(),
-     RRSIGRecord(),
-     RPRecord(),
-@@ -1528,10 +1532,7 @@ _dns_records = (
-     SPFRecord(),
-     SRVRecord(),
-     SSHFPRecord(),
--    TARecord(),
-     TLSARecord(),
--    TKEYRecord(),
--    TSIGRecord(),
-     TXTRecord(),
- )
- 
-@@ -2500,20 +2501,21 @@ class dnszone(DNSZoneBase):
-             'ipapermtarget': DN('idnsname=*', 'cn=dns', api.env.basedn),
-             'ipapermdefaultattr': {
-                 'objectclass',
--                'a6record', 'aaaarecord', 'afsdbrecord', 'arecord',
--                'certrecord', 'cn', 'cnamerecord', 'dlvrecord', 'dnamerecord',
--                'dnsclass', 'dnsttl', 'dsrecord', 'hinforecord',
--                'idnsallowdynupdate', 'idnsallowquery', 'idnsallowsyncptr',
--                'idnsallowtransfer', 'idnsforwarders', 'idnsforwardpolicy',
--                'idnsname', 'idnssecinlinesigning', 'idnssoaexpire',
--                'idnssoaminimum', 'idnssoamname', 'idnssoarefresh',
--                'idnssoaretry', 'idnssoarname', 'idnssoaserial',
--                'idnsupdatepolicy', 'idnszoneactive', 'keyrecord', 'kxrecord',
-+                'a6record', 'aaaarecord', 'afsdbrecord', 'aplrecord', 'arecord',
-+                'certrecord', 'cn', 'cnamerecord', 'dhcidrecord', 'dlvrecord',
-+                'dnamerecord', 'dnsclass', 'dnsttl', 'dsrecord',
-+                'hinforecord', 'hiprecord', 'idnsallowdynupdate',
-+                'idnsallowquery', 'idnsallowsyncptr', 'idnsallowtransfer',
-+                'idnsforwarders', 'idnsforwardpolicy', 'idnsname',
-+                'idnssecinlinesigning', 'idnssoaexpire', 'idnssoaminimum',
-+                'idnssoamname', 'idnssoarefresh', 'idnssoaretry',
-+                'idnssoarname', 'idnssoaserial', 'idnsupdatepolicy',
-+                'idnszoneactive', 'ipseckeyrecord','keyrecord', 'kxrecord',
-                 'locrecord', 'managedby', 'mdrecord', 'minforecord',
-                 'mxrecord', 'naptrrecord', 'nsecrecord', 'nsec3paramrecord',
--                'nsrecord', 'nxtrecord', 'ptrrecord', 'rrsigrecord',
--                'sigrecord', 'srvrecord', 'sshfprecord', 'tlsarecord',
--                'txtrecord', 'unknownrecord',
-+                'nsrecord', 'nxtrecord', 'ptrrecord', 'rprecord', 'rrsigrecord',
-+                'sigrecord', 'spfrecord', 'srvrecord', 'sshfprecord',
-+                'tlsarecord', 'txtrecord', 'unknownrecord',
-             },
-             'replaces_system': ['Read DNS Entries'],
-             'default_privileges': {'DNS Administrators', 'DNS Servers'},
-@@ -2534,20 +2536,21 @@ class dnszone(DNSZoneBase):
-             'ipapermlocation': api.env.basedn,
-             'ipapermtarget': DN('idnsname=*', 'cn=dns', api.env.basedn),
-             'ipapermdefaultattr': {
--                'a6record', 'aaaarecord', 'afsdbrecord', 'arecord',
--                'certrecord', 'cn', 'cnamerecord', 'dlvrecord', 'dnamerecord',
--                'dnsclass', 'dnsttl', 'dsrecord', 'hinforecord',
--                'idnsallowdynupdate', 'idnsallowquery', 'idnsallowsyncptr',
--                'idnsallowtransfer', 'idnsforwarders', 'idnsforwardpolicy',
--                'idnsname', 'idnssecinlinesigning', 'idnssoaexpire',
--                'idnssoaminimum', 'idnssoamname', 'idnssoarefresh',
--                'idnssoaretry', 'idnssoarname', 'idnssoaserial',
--                'idnsupdatepolicy', 'idnszoneactive', 'keyrecord', 'kxrecord',
-+                'a6record', 'aaaarecord', 'afsdbrecord', 'aplrecord', 'arecord',
-+                'certrecord', 'cn', 'cnamerecord', 'dhcidrecord', 'dlvrecord',
-+                'dnamerecord', 'dnsclass', 'dnsttl', 'dsrecord',
-+                'hinforecord', 'hiprecord', 'idnsallowdynupdate',
-+                'idnsallowquery', 'idnsallowsyncptr', 'idnsallowtransfer',
-+                'idnsforwarders', 'idnsforwardpolicy', 'idnsname',
-+                'idnssecinlinesigning', 'idnssoaexpire', 'idnssoaminimum',
-+                'idnssoamname', 'idnssoarefresh', 'idnssoaretry',
-+                'idnssoarname', 'idnssoaserial', 'idnsupdatepolicy',
-+                'idnszoneactive', 'ipseckeyrecord','keyrecord', 'kxrecord',
-                 'locrecord', 'managedby', 'mdrecord', 'minforecord',
-                 'mxrecord', 'naptrrecord', 'nsecrecord', 'nsec3paramrecord',
--                'nsrecord', 'nxtrecord', 'ptrrecord', 'rrsigrecord',
--                'sigrecord', 'srvrecord', 'sshfprecord', 'tlsarecord',
--                'txtrecord', 'unknownrecord',
-+                'nsrecord', 'nxtrecord', 'ptrrecord', 'rprecord', 'rrsigrecord',
-+                'sigrecord', 'spfrecord', 'srvrecord', 'sshfprecord',
-+                'tlsarecord', 'txtrecord', 'unknownrecord',
-             },
-             'replaces': [
-                 '(targetattr = "idnsname || cn || idnsallowdynupdate || dnsttl || dnsclass || arecord || aaaarecord || a6record || nsrecord || cnamerecord || ptrrecord || srvrecord || txtrecord || mxrecord || mdrecord || hinforecord || minforecord || afsdbrecord || sigrecord || keyrecord || locrecord || nxtrecord || naptrrecord || kxrecord || certrecord || dnamerecord || dsrecord || sshfprecord || rrsigrecord || nsecrecord || idnsname || idnszoneactive || idnssoamname || idnssoarname || idnssoaserial || idnssoarefresh || idnssoaretry || idnssoaexpire || idnssoaminimum || idnsupdatepolicy")(target = "ldap:///idnsname=*,cn=dns,$SUFFIX")(version 3.0;acl "permission:update dns entries";allow (write) groupdn = "ldap:///cn=update dns entries,cn=permissions,cn=pbac,$SUFFIX";)',
--- 
-2.4.3
-
diff --git a/SOURCES/0021-server-uninstall-fails-to-remove-krb-principals.patch b/SOURCES/0021-server-uninstall-fails-to-remove-krb-principals.patch
new file mode 100644
index 0000000..cdcb725
--- /dev/null
+++ b/SOURCES/0021-server-uninstall-fails-to-remove-krb-principals.patch
@@ -0,0 +1,51 @@
+From 028ae66827085960cdfa9861c413a7aeccea5221 Mon Sep 17 00:00:00 2001
+From: Florence Blanc-Renaud <frenaud@redhat.com>
+Date: Mon, 11 Jul 2016 09:00:44 +0200
+Subject: [PATCH] server uninstall fails to remove krb principals
+
+This patch fixes the 3rd issue of ticket 6012:
+ipa-server-install --uninstall -U
+complains while removing Kerberos service principals from /etc/krb5.keytab
+----
+Failed to remove Kerberos service principals: Command '/usr/sbin/ipa-rmkeytab -k /etc/krb5.keytab -r DOM-221.ABC.IDM.LAB.ENG.BRQ.REDHAT.COM' returned non-zero exit status 5
+----
+
+This happens because the uninstaller performs the following sequence:
+1/ restore pre-install files, including /etc/krb5.keytab
+At this point /etc/krb5.keytab does not contain any principal for
+IPA domain
+2/ call ipa-client-install --uninstall, which in turns runs
+ipa-rmkeytab -k /etc/krb5.keytab -r <domain>
+to remove the principals.
+
+The fix ignores ipa-rmkeytab's exit code 5 (Principal name or realm not
+found in keytab)
+
+https://fedorahosted.org/freeipa/ticket/6012
+
+Reviewed-By: Martin Basti <mbasti@redhat.com>
+---
+ client/ipa-client-install | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/client/ipa-client-install b/client/ipa-client-install
+index cee202f89e0f40f4b7ee77e5c38a2c7d50e0dee9..45185d44feb43a8b8d30e412a26dd63121be4ad1 100755
+--- a/client/ipa-client-install
++++ b/client/ipa-client-install
+@@ -614,6 +614,13 @@ def uninstall(options, env):
+             fp.close()
+             realm = parser.get('global', 'realm')
+             run([paths.IPA_RMKEYTAB, "-k", paths.KRB5_KEYTAB, "-r", realm])
++        except CalledProcessError as err:
++            if err.returncode != 5:
++                # 5 means Principal name or realm not found in keytab
++                # and can be ignored
++                root_logger.error(
++                    "Failed to remove Kerberos service principals: %s",
++                    str(err))
+         except Exception as e:
+             root_logger.error(
+                 "Failed to remove Kerberos service principals: %s", str(e))
+-- 
+2.7.4
+
diff --git a/SOURCES/0022-expose-secret-option-in-radiusproxy-commands.patch b/SOURCES/0022-expose-secret-option-in-radiusproxy-commands.patch
new file mode 100644
index 0000000..dd10fc1
--- /dev/null
+++ b/SOURCES/0022-expose-secret-option-in-radiusproxy-commands.patch
@@ -0,0 +1,32 @@
+From a9914cc13e0b04fbe8637214970c99b2328a2dfa Mon Sep 17 00:00:00 2001
+From: Martin Babinsky <mbabinsk@redhat.com>
+Date: Mon, 18 Jul 2016 10:45:48 +0200
+Subject: [PATCH] expose `--secret` option in radiusproxy-* commands
+
+Option `--secret` was hidden from radiusproxy CLI preventing setting a secret
+on existing server or searching by secret. Since thin client implementation it
+was also not recognized by the interactive prompt code in CLI frontend since
+it never got there.
+
+https://fedorahosted.org/freeipa/ticket/6078
+
+Reviewed-By: Jan Cholasta <jcholast@redhat.com>
+---
+ ipaserver/plugins/radiusproxy.py | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/ipaserver/plugins/radiusproxy.py b/ipaserver/plugins/radiusproxy.py
+index 44d87b9ae1337278bb6237d471f64693b0eac3db..5657e002c1ce66335b7697b98f95a49207c61d87 100644
+--- a/ipaserver/plugins/radiusproxy.py
++++ b/ipaserver/plugins/radiusproxy.py
+@@ -126,7 +126,6 @@ class radiusproxy(LDAPObject):
+             label=_('Secret'),
+             doc=_('The secret used to encrypt data'),
+             confirm=True,
+-            flags=['no_option'],
+         ),
+         Int('ipatokenradiustimeout?',
+             cli_name='timeout',
+-- 
+2.7.4
+
diff --git a/SOURCES/0022-ipaplatform-Add-constants-submodule.patch b/SOURCES/0022-ipaplatform-Add-constants-submodule.patch
deleted file mode 100644
index 418c4f2..0000000
--- a/SOURCES/0022-ipaplatform-Add-constants-submodule.patch
+++ /dev/null
@@ -1,147 +0,0 @@
-From 9e5c97ffdc7a42f6f76affbc9a791496ba245557 Mon Sep 17 00:00:00 2001
-From: Tomas Babej <tbabej@redhat.com>
-Date: Thu, 2 Jul 2015 12:38:43 +0200
-Subject: [PATCH] ipaplatform: Add constants submodule
-
-Introduce a ipaplatform/constants.py file to store platform related
-constants, which are not paths.
-
-Reviewed-By: Martin Basti <mbasti@redhat.com>
-Reviewed-By: Petr Spacek <pspacek@redhat.com>
----
- Makefile                        |  3 ++-
- freeipa.spec.in                 |  2 ++
- ipaplatform/base/constants.py   | 11 +++++++++++
- ipaplatform/fedora/constants.py | 16 ++++++++++++++++
- ipaplatform/redhat/constants.py | 17 +++++++++++++++++
- ipaplatform/rhel/constants.py   | 16 ++++++++++++++++
- 6 files changed, 64 insertions(+), 1 deletion(-)
- create mode 100644 ipaplatform/base/constants.py
- create mode 100644 ipaplatform/fedora/constants.py
- create mode 100644 ipaplatform/redhat/constants.py
- create mode 100644 ipaplatform/rhel/constants.py
-
-diff --git a/Makefile b/Makefile
-index abf58382960099a54b8920dd0e741b9fda17682f..3c81466d3728022c1d9cf5bb216990f14a59b7e5 100644
---- a/Makefile
-+++ b/Makefile
-@@ -159,10 +159,11 @@ version-update: release-update
- 	if [ "$(SUPPORTED_PLATFORM)" != "" ]; then \
- 		sed -e s/__PLATFORM__/$(SUPPORTED_PLATFORM)/ \
- 			ipaplatform/__init__.py.in > ipaplatform/__init__.py; \
--		rm -f ipaplatform/paths.py ipaplatform/services.py ipaplatform/tasks.py; \
-+		rm -f ipaplatform/paths.py ipaplatform/services.py ipaplatform/tasks.py ipaplatform/constants.py; \
- 		ln -s $(SUPPORTED_PLATFORM)/paths.py ipaplatform/paths.py; \
- 		ln -s $(SUPPORTED_PLATFORM)/services.py ipaplatform/services.py; \
- 		ln -s $(SUPPORTED_PLATFORM)/tasks.py ipaplatform/tasks.py; \
-+		ln -s $(SUPPORTED_PLATFORM)/constants.py ipaplatform/constants.py; \
- 	fi
- 
- 	if [ "$(SKIP_API_VERSION_CHECK)" != "yes" ]; then \
-diff --git a/freeipa.spec.in b/freeipa.spec.in
-index 5790f7941d2117ed95d3c99556f1579c27917270..e9ba596fec1f8d179d4f834485e35a4814db898d 100644
---- a/freeipa.spec.in
-+++ b/freeipa.spec.in
-@@ -363,6 +363,7 @@ rm -f ipapython/version.py
- rm -f ipaplatform/services.py
- rm -f ipaplatform/tasks.py
- rm -f ipaplatform/paths.py
-+rm -f ipaplatform/constants.py
- make version-update
- cd ipa-client; ../autogen.sh --prefix=%{_usr} --sysconfdir=%{_sysconfdir} --localstatedir=%{_localstatedir} --libdir=%{_libdir} --mandir=%{_mandir}; cd ..
- %if ! %{ONLY_CLIENT}
-@@ -385,6 +386,7 @@ rm -f ipapython/version.py
- rm -f ipaplatform/services.py
- rm -f ipaplatform/tasks.py
- rm -f ipaplatform/paths.py
-+rm -f ipaplatform/constants.py
- make version-update
- %if ! %{ONLY_CLIENT}
- make install DESTDIR=%{buildroot}
-diff --git a/ipaplatform/base/constants.py b/ipaplatform/base/constants.py
-new file mode 100644
-index 0000000000000000000000000000000000000000..70485055fa5a12fac878ace3dea11ea442ebe6be
---- /dev/null
-+++ b/ipaplatform/base/constants.py
-@@ -0,0 +1,11 @@
-+#
-+# Copyright (C) 2015  FreeIPA Contributors see COPYING for license
-+#
-+
-+'''
-+This base platform module exports platform dependant constants.
-+'''
-+
-+
-+class BaseConstantsNamespace(object):
-+    pass
-diff --git a/ipaplatform/fedora/constants.py b/ipaplatform/fedora/constants.py
-new file mode 100644
-index 0000000000000000000000000000000000000000..ce03f58cf95be1a72a9ce3da65e6d21ef193cefe
---- /dev/null
-+++ b/ipaplatform/fedora/constants.py
-@@ -0,0 +1,16 @@
-+#
-+# Copyright (C) 2015  FreeIPA Contributors see COPYING for license
-+#
-+
-+'''
-+This Fedora base platform module exports platform related constants.
-+'''
-+
-+# Fallback to default constant definitions
-+from ipaplatform.redhat.constants import RedHatConstantsNamespace
-+
-+
-+class FedoraConstantsNamespace(RedHatConstantsNamespace):
-+    pass
-+
-+constants = FedoraConstantsNamespace()
-diff --git a/ipaplatform/redhat/constants.py b/ipaplatform/redhat/constants.py
-new file mode 100644
-index 0000000000000000000000000000000000000000..7209947f8afbd688b02c8b134d33185e497befe0
---- /dev/null
-+++ b/ipaplatform/redhat/constants.py
-@@ -0,0 +1,17 @@
-+#
-+# Copyright (C) 2015  FreeIPA Contributors see COPYING for license
-+#
-+
-+'''
-+This Red Hat OS family base platform module exports default platform
-+related constants for the Red Hat OS family-based systems.
-+'''
-+
-+# Fallback to default path definitions
-+from ipaplatform.base.constants import BaseConstantsNamespace
-+
-+
-+class RedHatConstantsNamespace(BaseConstantsNamespace):
-+    pass
-+
-+constants = RedHatConstantsNamespace()
-diff --git a/ipaplatform/rhel/constants.py b/ipaplatform/rhel/constants.py
-new file mode 100644
-index 0000000000000000000000000000000000000000..eaca48030fa28804c70c161b07228646a95fc1a3
---- /dev/null
-+++ b/ipaplatform/rhel/constants.py
-@@ -0,0 +1,16 @@
-+#
-+# Copyright (C) 2015  FreeIPA Contributors see COPYING for license
-+#
-+
-+'''
-+This RHEL base platform module exports platform related constants.
-+'''
-+
-+# Fallback to default constant definitions
-+from ipaplatform.redhat.constants import RedHatConstantsNamespace
-+
-+
-+class RHELConstantsNamespace(RedHatConstantsNamespace):
-+    pass
-+
-+constants = RHELConstantsNamespace()
--- 
-2.4.3
-
diff --git a/SOURCES/0023-DNS-check-if-DNS-package-is-installed.patch b/SOURCES/0023-DNS-check-if-DNS-package-is-installed.patch
deleted file mode 100644
index cd483f2..0000000
--- a/SOURCES/0023-DNS-check-if-DNS-package-is-installed.patch
+++ /dev/null
@@ -1,170 +0,0 @@
-From 9bf3e3efe51ccda418afd2340a113f39144851c3 Mon Sep 17 00:00:00 2001
-From: Martin Basti <mbasti@redhat.com>
-Date: Wed, 1 Jul 2015 15:05:45 +0200
-Subject: [PATCH] DNS: check if DNS package is installed
-
-Instead of separate checking of DNS required packages, we need just
-check if IPA DNS package is installed.
-
-https://fedorahosted.org/freeipa/ticket/4058
-
-Reviewed-By: Martin Babinsky <mbabinsk@redhat.com>
-Reviewed-By: Petr Spacek <pspacek@redhat.com>
-Reviewed-By: Tomas Babej <tbabej@redhat.com>
----
- ipaplatform/base/constants.py           |  2 +-
- ipaplatform/base/paths.py               |  1 +
- ipaplatform/rhel/constants.py           |  2 +-
- ipaserver/install/bindinstance.py       | 19 +------------------
- ipaserver/install/dns.py                | 11 ++++++-----
- ipaserver/install/dnskeysyncinstance.py |  6 ------
- ipaserver/install/opendnssecinstance.py |  8 --------
- 7 files changed, 10 insertions(+), 39 deletions(-)
-
-diff --git a/ipaplatform/base/constants.py b/ipaplatform/base/constants.py
-index 70485055fa5a12fac878ace3dea11ea442ebe6be..cef829e2d3886db00ae6d0299ddcf325d1add80e 100644
---- a/ipaplatform/base/constants.py
-+++ b/ipaplatform/base/constants.py
-@@ -8,4 +8,4 @@ This base platform module exports platform dependant constants.
- 
- 
- class BaseConstantsNamespace(object):
--    pass
-+    IPA_DNS_PACKAGE_NAME = "freeipa-server-dns"
-diff --git a/ipaplatform/base/paths.py b/ipaplatform/base/paths.py
-index 5756040172126438d42275b734f4d766d53048fe..4c93c1f7162b0aeb4f798ef84e1ac8db4573518b 100644
---- a/ipaplatform/base/paths.py
-+++ b/ipaplatform/base/paths.py
-@@ -218,6 +218,7 @@ class BasePathNamespace(object):
-     GROUPADD = "/usr/sbin/groupadd"
-     HTTPD = "/usr/sbin/httpd"
-     IPA_CLIENT_INSTALL = "/usr/sbin/ipa-client-install"
-+    IPA_DNS_INSTALL = "/usr/sbin/ipa-dns-install"
-     SBIN_IPA_JOIN = "/usr/sbin/ipa-join"
-     IPA_REPLICA_CONNCHECK = "/usr/sbin/ipa-replica-conncheck"
-     IPA_RMKEYTAB = "/usr/sbin/ipa-rmkeytab"
-diff --git a/ipaplatform/rhel/constants.py b/ipaplatform/rhel/constants.py
-index eaca48030fa28804c70c161b07228646a95fc1a3..17abde1f861778bec83067cb01e9a1faae325527 100644
---- a/ipaplatform/rhel/constants.py
-+++ b/ipaplatform/rhel/constants.py
-@@ -11,6 +11,6 @@ from ipaplatform.redhat.constants import RedHatConstantsNamespace
- 
- 
- class RHELConstantsNamespace(RedHatConstantsNamespace):
--    pass
-+    IPA_DNS_PACKAGE_NAME = "ipa-server-dns"
- 
- constants = RHELConstantsNamespace()
-diff --git a/ipaserver/install/bindinstance.py b/ipaserver/install/bindinstance.py
-index 2228342dc40ee415d1adf2687a7ae91a5963d3c7..9705e845a76191a252bfa963b54d9c31d83ad18e 100644
---- a/ipaserver/install/bindinstance.py
-+++ b/ipaserver/install/bindinstance.py
-@@ -62,25 +62,8 @@ named_conf_arg_options_template_nonstr = "%(indent)s%(name)s %(value)s;\n"
- named_conf_include_re = re.compile(r'\s*include\s+"(?P<path>)"\s*;')
- named_conf_include_template = "include \"%(path)s\";\n"
- 
--def check_inst(unattended):
--    has_bind = True
--    named = services.knownservices.named
--    if not os.path.exists(named.get_binary_path()):
--        print "BIND was not found on this system"
--        print ("Please install the '%s' package and start the installation again"
--              % named.get_package_name())
--        has_bind = False
--
--    # Also check for the LDAP BIND plug-in
--    if not os.path.exists(paths.BIND_LDAP_SO) and \
--       not os.path.exists(paths.BIND_LDAP_SO_64):
--        print "The BIND LDAP plug-in was not found on this system"
--        print "Please install the 'bind-dyndb-ldap' package and start the installation again"
--        has_bind = False
--
--    if not has_bind:
--        return False
- 
-+def check_inst(unattended):
-     if not unattended and os.path.exists(NAMED_CONF):
-         msg = "Existing BIND configuration detected, overwrite?"
-         return ipautil.user_input(msg, False)
-diff --git a/ipaserver/install/dns.py b/ipaserver/install/dns.py
-index d22bce7a7cd2e0e8a7ffe0ab4aa496634465903b..9430d189978b0984b0b71d7d754516a4135053fb 100644
---- a/ipaserver/install/dns.py
-+++ b/ipaserver/install/dns.py
-@@ -9,6 +9,7 @@ from subprocess import CalledProcessError
- from ipalib import api
- from ipalib import errors
- from ipaplatform.paths import paths
-+from ipaplatform.constants import constants
- from ipaplatform import services
- from ipapython import ipautil
- from ipapython import sysrestore
-@@ -96,6 +97,10 @@ def install_check(standalone, replica, options, hostname):
-     global reverse_zones
-     fstore = sysrestore.FileStore(paths.SYSRESTORE)
- 
-+    if not ipautil.file_exists(paths.IPA_DNS_INSTALL):
-+        raise RuntimeError("Integrated DNS requires '%s' package" %
-+                           constants.IPA_DNS_PACKAGE_NAME)
-+
-     if standalone:
-         print "=============================================================================="
-         print "This program will setup DNS for the FreeIPA Server."
-@@ -141,8 +146,7 @@ def install_check(standalone, replica, options, hostname):
-         sys.exit("Aborted")
- 
-     # Check bind packages are installed
--    if not (bindinstance.check_inst(options.unattended) and
--            dnskeysyncinstance.check_inst()):
-+    if not bindinstance.check_inst(options.unattended):
-         sys.exit("Aborting installation.")
- 
-     if options.disable_dnssec_master:
-@@ -177,9 +181,6 @@ def install_check(standalone, replica, options, hostname):
-             sys.exit("Only one DNSSEC key master is supported in current "
-                      "version.")
- 
--        # check opendnssec packages are installed
--        if not opendnssecinstance.check_inst():
--            sys.exit("Aborting installation")
-         if options.kasp_db_file:
-             dnskeysyncd = services.service('ipa-dnskeysyncd')
- 
-diff --git a/ipaserver/install/dnskeysyncinstance.py b/ipaserver/install/dnskeysyncinstance.py
-index eb6d07f014bce296a5b094f499194286c31c2489..7d1351ccc57a5dbd7d537741545ad44d0dcd5eb1 100644
---- a/ipaserver/install/dnskeysyncinstance.py
-+++ b/ipaserver/install/dnskeysyncinstance.py
-@@ -30,12 +30,6 @@ softhsm_token_label = u'ipaDNSSEC'
- softhsm_slot = 0
- replica_keylabel_template = u"dnssec-replica:%s"
- 
--def check_inst():
--    if not os.path.exists(paths.DNSSEC_KEYFROMLABEL):
--        print ("Please install the 'bind-pkcs11-utils' package and start "
--               "the installation again")
--        return False
--    return True
- 
- def dnssec_container_exists(fqdn, suffix, dm_password=None, ldapi=False,
-                             realm=None, autobind=ipaldap.AUTOBIND_DISABLED):
-diff --git a/ipaserver/install/opendnssecinstance.py b/ipaserver/install/opendnssecinstance.py
-index d68691fa32f135c7527ce28ed771757eadab4831..0f1af828ea245046330fdfab77db130ca14faba3 100644
---- a/ipaserver/install/opendnssecinstance.py
-+++ b/ipaserver/install/opendnssecinstance.py
-@@ -55,14 +55,6 @@ def get_dnssec_key_masters(conn):
-     return keymasters_list
- 
- 
--def check_inst():
--    if not os.path.exists(paths.ODS_KSMUTIL):
--        print ("Please install the 'opendnssec' package and start "
--               "the installation again")
--        return False
--    return True
--
--
- class OpenDNSSECInstance(service.Service):
-     def __init__(self, fstore=None, dm_password=None, ldapi=False,
-                  start_tls=False, autobind=ipaldap.AUTOBIND_ENABLED):
--- 
-2.4.3
-
diff --git a/SOURCES/0023-prevent-search-for-RADIUS-proxy-servers-by-secret.patch b/SOURCES/0023-prevent-search-for-RADIUS-proxy-servers-by-secret.patch
new file mode 100644
index 0000000..915e307
--- /dev/null
+++ b/SOURCES/0023-prevent-search-for-RADIUS-proxy-servers-by-secret.patch
@@ -0,0 +1,37 @@
+From 57e8d1c6ff58bc58d50d0b1d501820f55a6f2837 Mon Sep 17 00:00:00 2001
+From: Martin Babinsky <mbabinsk@redhat.com>
+Date: Thu, 21 Jul 2016 09:42:01 +0200
+Subject: [PATCH] prevent search for RADIUS proxy servers by secret
+
+radiusproxy-find should not allow search by proxy secret even for privileged
+users so we should hide it from CLI.
+
+https://fedorahosted.org/freeipa/ticket/6078
+
+Reviewed-By: Jan Cholasta <jcholast@redhat.com>
+---
+ ipaserver/plugins/radiusproxy.py | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/ipaserver/plugins/radiusproxy.py b/ipaserver/plugins/radiusproxy.py
+index 5657e002c1ce66335b7697b98f95a49207c61d87..3391b8aed77205fb1a586d5472d8cfdbc9fd1cd5 100644
+--- a/ipaserver/plugins/radiusproxy.py
++++ b/ipaserver/plugins/radiusproxy.py
+@@ -169,6 +169,14 @@ class radiusproxy_find(LDAPSearch):
+         '%(count)d RADIUS proxy server matched', '%(count)d RADIUS proxy servers matched', 0
+     )
+ 
++    def get_options(self):
++        for option in super(radiusproxy_find, self).get_options():
++            if option.name == 'ipatokenradiussecret':
++                option = option.clone(flags={'no_option'})
++
++            yield option
++
++
+ @register()
+ class radiusproxy_show(LDAPRetrieve):
+     __doc__ = _('Display information about a RADIUS proxy server.')
+-- 
+2.7.4
+
diff --git a/SOURCES/0024-dcerpc-Expand-explanation-for-WERR_ACCESS_DENIED.patch b/SOURCES/0024-dcerpc-Expand-explanation-for-WERR_ACCESS_DENIED.patch
deleted file mode 100644
index b400a03..0000000
--- a/SOURCES/0024-dcerpc-Expand-explanation-for-WERR_ACCESS_DENIED.patch
+++ /dev/null
@@ -1,76 +0,0 @@
-From c4859813a5fd89082c9c05a3808f9b6cb97ca5d0 Mon Sep 17 00:00:00 2001
-From: Tomas Babej <tbabej@redhat.com>
-Date: Wed, 15 Jul 2015 15:38:50 +0200
-Subject: [PATCH] dcerpc: Expand explanation for WERR_ACCESS_DENIED
-
-It's possible for AD to contact a wrong IPA server in case the DNS
-SRV records on the AD sides are not properly configured.
-
-Mention this case in the error message as well.
-
-https://fedorahosted.org/freeipa/ticket/5013
-
-Reviewed-By: Petr Vobornik <pvoborni@redhat.com>
----
- ipaserver/dcerpc.py | 36 +++++++++++++++++++++++++++++-------
- 1 file changed, 29 insertions(+), 7 deletions(-)
-
-diff --git a/ipaserver/dcerpc.py b/ipaserver/dcerpc.py
-index a1da0a641064f59a79639d97489ff73181787a4a..97f6c1694c20f26af0861b86a1ae1adf7a970a59 100644
---- a/ipaserver/dcerpc.py
-+++ b/ipaserver/dcerpc.py
-@@ -1084,22 +1084,44 @@ class TrustDomainInstance(object):
-         result = retrieve_netlogon_info_2(None, self,
-                                           netlogon.NETLOGON_CONTROL_TC_VERIFY,
-                                           another_domain.info['dns_domain'])
--        if (result and (result.flags and netlogon.NETLOGON_VERIFY_STATUS_RETURNED)):
--            if (result.pdc_connection_status[0] != 0) and (result.tc_connection_status[0] != 0):
-+
-+        if result and result.flags and netlogon.NETLOGON_VERIFY_STATUS_RETURNED:
-+            if result.pdc_connection_status[0] != 0 and result.tc_connection_status[0] != 0:
-                 if result.pdc_connection_status[1] == "WERR_ACCESS_DENIED":
-                     # Most likely AD DC hit another IPA replica which yet has no trust secret replicated
-+
-                     # Sleep and repeat again
-                     self.validation_attempts += 1
-                     if self.validation_attempts < 10:
-                         sleep(5)
-                         return self.verify_trust(another_domain)
--                    raise errors.ACIError(
--                            info=_('IPA master denied trust validation requests from AD DC '
--                                   '%(count)d times. Most likely AD DC contacted a replica '
--                                   'that has no trust information replicated yet.')
--                                   % dict(count=self.validation_attempts))
-+
-+                    # If we get here, we already failed 10 times
-+                    srv_record_templates = (
-+                        '_ldap._tcp.%s',
-+                        '_ldap._tcp.Default-First-Site-Name._sites.dc._msdcs.%s'
-+                    )
-+
-+                    srv_records = ', '.join(
-+                        [srv_record % api.env.domain
-+                         for srv_record in srv_record_templates]
-+                    )
-+
-+                    error_message = _(
-+                        'IPA master denied trust validation requests from AD '
-+                        'DC %(count)d times. Most likely AD DC contacted a '
-+                        'replica that has no trust information replicated '
-+                        'yet. Additionally, please check that AD DNS is able '
-+                        'to resolve %(records)s SRV records to the correct '
-+                        'IPA server.') % dict(count=self.validation_attempts,
-+                                              records=srv_records)
-+
-+                    raise errors.ACIError(info=error_message)
-+
-                 raise assess_dcerpc_exception(*result.pdc_connection_status)
-+
-             return True
-+
-         return False
- 
- 
--- 
-2.4.3
-
diff --git a/SOURCES/0024-trust-add-handle-all-raw-options-properly.patch b/SOURCES/0024-trust-add-handle-all-raw-options-properly.patch
new file mode 100644
index 0000000..dd90e03
--- /dev/null
+++ b/SOURCES/0024-trust-add-handle-all-raw-options-properly.patch
@@ -0,0 +1,89 @@
+From b18c50fb6f596896b35b80178368762d8b9d4a56 Mon Sep 17 00:00:00 2001
+From: Martin Babinsky <mbabinsk@redhat.com>
+Date: Fri, 15 Jul 2016 12:38:00 +0200
+Subject: [PATCH] trust-add: handle `--all/--raw` options properly
+
+`trust-add` command did not handle these options correctly often resulting in
+internal errors or mangled output. This patch implements a behavior which is
+more in-line with the rest of the API commands.
+
+https://fedorahosted.org/freeipa/ticket/6059
+
+Reviewed-By: Jan Cholasta <jcholast@redhat.com>
+---
+ ipaserver/plugins/trust.py | 41 +++++++++++++++++++++++++++--------------
+ 1 file changed, 27 insertions(+), 14 deletions(-)
+
+diff --git a/ipaserver/plugins/trust.py b/ipaserver/plugins/trust.py
+index d4676bd57054043edd07da5ec3321d755babf35c..f2e0b1ee4b261ddc4f29477f46b7f4027af18892 100644
+--- a/ipaserver/plugins/trust.py
++++ b/ipaserver/plugins/trust.py
+@@ -710,6 +710,25 @@ sides.
+     msg_summary = _('Added Active Directory trust for realm "%(value)s"')
+     msg_summary_existing = _('Re-established trust to domain "%(value)s"')
+ 
++    def _format_trust_attrs(self, result, **options):
++
++        # Format the output into human-readable values
++        attributes = int(result['result'].get('ipanttrustattributes', [0])[0])
++
++        if not options.get('raw', False):
++            result['result']['trusttype'] = [trust_type_string(
++                result['result']['ipanttrusttype'][0], attributes)]
++            result['result']['trustdirection'] = [trust_direction_string(
++                result['result']['ipanttrustdirection'][0])]
++            result['result']['truststatus'] = [trust_status_string(
++                result['verified'])]
++
++        if attributes:
++            result['result'].pop('ipanttrustattributes', None)
++
++        result['result'].pop('ipanttrustauthoutgoing', None)
++        result['result'].pop('ipanttrustauthincoming', None)
++
+     def execute(self, *keys, **options):
+         ldap = self.obj.backend
+ 
+@@ -729,10 +748,15 @@ sides.
+         else:
+             created_range_type = old_range['result']['iparangetype'][0]
+ 
++        attrs_list = self.obj.default_attributes
++        if options.get('all', False):
++            attrs_list.append('*')
++
+         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)
++                         filter=trust_filter,
++                         attrs_list=attrs_list)
+ 
+         result['result'] = entry_to_dict(trusts[0], **options)
+ 
+@@ -761,20 +785,9 @@ sides.
+                 # add_new_domains_from_trust() on its own.
+                 fetch_trusted_domains_over_dbus(self.api, self.log, result['value'])
+ 
+-        # Format the output into human-readable values
+-        attributes = int(result['result'].get('ipanttrustattributes', [0])[0])
+-        result['result']['trusttype'] = [trust_type_string(
+-            result['result']['ipanttrusttype'][0], attributes)]
+-        result['result']['trustdirection'] = [trust_direction_string(
+-            result['result']['ipanttrustdirection'][0])]
+-        result['result']['truststatus'] = [trust_status_string(
+-            result['verified'])]
+-        if attributes:
+-            result['result'].pop('ipanttrustattributes', None)
+-
++        # Format the output into human-readable values unless `--raw` is given
++        self._format_trust_attrs(result, **options)
+         del result['verified']
+-        result['result'].pop('ipanttrustauthoutgoing', None)
+-        result['result'].pop('ipanttrustauthincoming', None)
+ 
+         return result
+ 
+-- 
+2.7.4
+
diff --git a/SOURCES/0025-dcerpc-Fix-UnboundLocalError-for-ccache_name.patch b/SOURCES/0025-dcerpc-Fix-UnboundLocalError-for-ccache_name.patch
deleted file mode 100644
index 27e23ca..0000000
--- a/SOURCES/0025-dcerpc-Fix-UnboundLocalError-for-ccache_name.patch
+++ /dev/null
@@ -1,26 +0,0 @@
-From 45cbe4b94e59bcfa3d8968595a780bdb9f3af2f2 Mon Sep 17 00:00:00 2001
-From: Tomas Babej <tbabej@redhat.com>
-Date: Wed, 22 Jul 2015 14:29:35 +0200
-Subject: [PATCH] dcerpc: Fix UnboundLocalError for ccache_name
-
-Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
----
- ipaserver/dcerpc.py | 2 ++
- 1 file changed, 2 insertions(+)
-
-diff --git a/ipaserver/dcerpc.py b/ipaserver/dcerpc.py
-index 97f6c1694c20f26af0861b86a1ae1adf7a970a59..c0aa322c5d59e7d17a4ceb90448b397613284e38 100644
---- a/ipaserver/dcerpc.py
-+++ b/ipaserver/dcerpc.py
-@@ -644,6 +644,8 @@ class DomainValidator(object):
-         Returns LDAP result or None.
-         """
- 
-+        ccache_name = None
-+
-         if self._admin_creds:
-             (ccache_name, principal) = self.kinit_as_administrator(info['dns_domain'])
- 
--- 
-2.4.3
-
diff --git a/SOURCES/0025-unite-log-file-name-of-ipa-ca-install.patch b/SOURCES/0025-unite-log-file-name-of-ipa-ca-install.patch
new file mode 100644
index 0000000..0e10ba9
--- /dev/null
+++ b/SOURCES/0025-unite-log-file-name-of-ipa-ca-install.patch
@@ -0,0 +1,54 @@
+From 41b85da8629e69efcc9acf65ba81ab79d38dc609 Mon Sep 17 00:00:00 2001
+From: Petr Vobornik <pvoborni@redhat.com>
+Date: Fri, 15 Jul 2016 16:25:36 +0200
+Subject: [PATCH] unite log file name of ipa-ca-install
+
+ipa-ca-install said that it used
+  /var/log/ipareplica-ca-install.log
+but in fact it used
+  /var/log/ipaserver-ca-install.log
+
+This patch unites it to ipareplica-ca-install.log
+
+It was chosen because of backwards compatibility - ipareplica-ca-install
+was more commonly used. ipaserver-ca-install.log was used only in rare
+CA less -> CA installation.
+
+https://fedorahosted.org/freeipa/ticket/6086
+
+Reviewed-By: Martin Babinsky <mbabinsk@redhat.com>
+Reviewed-By: Jan Cholasta <jcholast@redhat.com>
+Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
+---
+ install/tools/ipa-ca-install | 2 +-
+ ipaplatform/base/paths.py    | 1 -
+ 2 files changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/install/tools/ipa-ca-install b/install/tools/ipa-ca-install
+index ed685920cbadb9cd3fc80865afb1610ca42f8b13..985e7413aa06900976934c329757ce45da5ff12d 100755
+--- a/install/tools/ipa-ca-install
++++ b/install/tools/ipa-ca-install
+@@ -285,7 +285,7 @@ def main():
+             cainstance.is_ca_installed_locally()):
+         sys.exit("CA is already installed on this host.")
+ 
+-    standard_logging_setup(paths.IPASERVER_CA_INSTALL_LOG, debug=options.debug)
++    standard_logging_setup(log_file_name, debug=options.debug)
+     root_logger.debug("%s was invoked with options: %s,%s",
+                       sys.argv[0], safe_options, filename)
+     root_logger.debug("IPA version %s", version.VENDOR_VERSION)
+diff --git a/ipaplatform/base/paths.py b/ipaplatform/base/paths.py
+index d6fbe32f6839a5db40148777132ba1454cbc3382..1507ac36da5b40447c951ee608053a09b2db2fc3 100644
+--- a/ipaplatform/base/paths.py
++++ b/ipaplatform/base/paths.py
+@@ -307,7 +307,6 @@ class BasePathNamespace(object):
+     IPAREPLICA_CONNCHECK_LOG = "/var/log/ipareplica-conncheck.log"
+     IPAREPLICA_INSTALL_LOG = "/var/log/ipareplica-install.log"
+     IPARESTORE_LOG = "/var/log/iparestore.log"
+-    IPASERVER_CA_INSTALL_LOG = "/var/log/ipaserver-ca-install.log"
+     IPASERVER_INSTALL_LOG = "/var/log/ipaserver-install.log"
+     IPASERVER_KRA_INSTALL_LOG = "/var/log/ipaserver-kra-install.log"
+     IPASERVER_KRA_UNINSTALL_LOG = "/var/log/ipaserver-kra-uninstall.log"
+-- 
+2.7.4
+
diff --git a/SOURCES/0026-Host-del-fix-behavior-of-updatedns-and-PTR-records.patch b/SOURCES/0026-Host-del-fix-behavior-of-updatedns-and-PTR-records.patch
new file mode 100644
index 0000000..0f2f5ff
--- /dev/null
+++ b/SOURCES/0026-Host-del-fix-behavior-of-updatedns-and-PTR-records.patch
@@ -0,0 +1,95 @@
+From 57b757807a53400b8addb19d323f5691122c3ebb Mon Sep 17 00:00:00 2001
+From: Martin Basti <mbasti@redhat.com>
+Date: Thu, 21 Jul 2016 13:18:34 +0200
+Subject: [PATCH] Host-del: fix behavior of --updatedns and PTR records
+
+* target for ptr record must be absolute domain name
+* zone is detected using DNS system instead of random splitting of
+hostname
+
+https://fedorahosted.org/freeipa/ticket/6060
+
+Reviewed-By: Petr Spacek <pspacek@redhat.com>
+---
+ ipaserver/plugins/host.py | 26 +++++++++++++++-----------
+ 1 file changed, 15 insertions(+), 11 deletions(-)
+
+diff --git a/ipaserver/plugins/host.py b/ipaserver/plugins/host.py
+index f342b05c87b936ab7b99009cfb0f6d3acde4ef93..413dcf15e0423170d8334902b9dcf8fb5aa14de6 100644
+--- a/ipaserver/plugins/host.py
++++ b/ipaserver/plugins/host.py
+@@ -18,6 +18,9 @@
+ # 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 __future__ import absolute_import
++
++import dns.resolver
+ import string
+ 
+ import six
+@@ -134,7 +137,7 @@ register = Registry()
+ host_pwd_chars = string.digits + string.ascii_letters + '_,.@+-='
+ 
+ 
+-def remove_ptr_rec(ipaddr, host, domain):
++def remove_ptr_rec(ipaddr, fqdn):
+     """
+     Remove PTR record of IP address (ipaddr)
+     :return: True if PTR record was removed, False if record was not found
+@@ -143,13 +146,12 @@ def remove_ptr_rec(ipaddr, host, domain):
+     try:
+         revzone, revname = get_reverse_zone(ipaddr)
+ 
+-        # in case domain is in FQDN form with a trailing dot, we needn't add
+-        # another one, in case it has no trailing dot, dnsrecord-del will
+-        # normalize the entry
+-        delkw = {'ptrrecord': "%s.%s" % (host, domain)}
++        # assume that target in PTR record is absolute name (otherwise it is
++        # non-standard configuration)
++        delkw = {'ptrrecord': u"%s" % fqdn.make_absolute()}
+ 
+         api.Command['dnsrecord_del'](revzone, revname, **delkw)
+-    except errors.NotFound:
++    except (errors.NotFound, errors.AttrValueNotFound):
+         api.log.debug('PTR record of ipaddr %s not found', ipaddr)
+         return False
+ 
+@@ -794,13 +796,15 @@ class host_del(LDAPDelete):
+ 
+         if updatedns:
+             # Remove A, AAAA, SSHFP and PTR records of the host
+-            parts = fqdn.split('.')
+-            domain = unicode('.'.join(parts[1:]))
++            fqdn_dnsname = DNSName(fqdn).make_absolute()
++            zone = DNSName(dns.resolver.zone_for_name(fqdn_dnsname))
++            relative_hostname = fqdn_dnsname.relativize(zone)
++
+             # Get all resources for this host
+             rec_removed = False
+             try:
+                 record = api.Command['dnsrecord_show'](
+-                    domain, parts[0])['result']
++                    zone, relative_hostname)['result']
+             except errors.NotFound:
+                 pass
+             else:
+@@ -808,13 +812,13 @@ class host_del(LDAPDelete):
+                 for attr in ('arecord', 'aaaarecord'):
+                     for val in record.get(attr, []):
+                         rec_removed = (
+-                            remove_ptr_rec(val, parts[0], domain) or
++                            remove_ptr_rec(val, fqdn_dnsname) or
+                             rec_removed
+                         )
+                 try:
+                     # remove all A, AAAA, SSHFP records of the host
+                     api.Command['dnsrecord_mod'](
+-                        domain,
++                        zone,
+                         record['idnsname'][0],
+                         arecord=[],
+                         aaaarecord=[],
+-- 
+2.7.4
+
diff --git a/SOURCES/0026-fix-broken-search-for-users-by-their-manager.patch b/SOURCES/0026-fix-broken-search-for-users-by-their-manager.patch
deleted file mode 100644
index be8fffb..0000000
--- a/SOURCES/0026-fix-broken-search-for-users-by-their-manager.patch
+++ /dev/null
@@ -1,72 +0,0 @@
-From 29d63aa08fc648c3dfbc9ae4cc74991eba2fb7a0 Mon Sep 17 00:00:00 2001
-From: Martin Babinsky <mbabinsk@redhat.com>
-Date: Thu, 23 Jul 2015 10:44:08 +0200
-Subject: [PATCH] fix broken search for users by their manager
-
-The patch fixes incorrect construction of search filter when using `ipa
-user-find` with '--manager' option.
-
-https://fedorahosted.org/freeipa/ticket/5146
-
-Reviewed-By: Tomas Babej <tbabej@redhat.com>
----
- ipalib/plugins/baseuser.py  | 8 ++++++++
- ipalib/plugins/stageuser.py | 7 -------
- ipalib/plugins/user.py      | 4 ----
- 3 files changed, 8 insertions(+), 11 deletions(-)
-
-diff --git a/ipalib/plugins/baseuser.py b/ipalib/plugins/baseuser.py
-index 9068ef0fd266a4460697ee45f29c80b74662fab2..bd66cf5a3e3a4e6c18d1a54408f969668c834fab 100644
---- a/ipalib/plugins/baseuser.py
-+++ b/ipalib/plugins/baseuser.py
-@@ -561,6 +561,14 @@ class baseuser_find(LDAPSearch):
-     """
-     Prototype command plugin to be implemented by real plugin
-     """
-+    def args_options_2_entry(self, *args, **options):
-+        newoptions = {}
-+        self.common_enhance_options(newoptions, **options)
-+        options.update(newoptions)
-+
-+        return super(baseuser_find, self).args_options_2_entry(
-+            *args, **options)
-+
-     def common_enhance_options(self, newoptions, **options):
-         # assure the manager attr is a dn, not just a bare uid
-         manager = options.get('manager')
-diff --git a/ipalib/plugins/stageuser.py b/ipalib/plugins/stageuser.py
-index 6cbc8f4ab07f2c1172f2b2c45bfe8f30a74938b3..49a762a922b21bd6d0824787d9305417f5e47ee6 100644
---- a/ipalib/plugins/stageuser.py
-+++ b/ipalib/plugins/stageuser.py
-@@ -449,13 +449,6 @@ class stageuser_find(baseuser_find):
-     member_attributes = ['memberof']
-     has_output_params = baseuser_find.has_output_params + stageuser_output_params
- 
--    def execute(self, *args, **options):
--        newoptions = {}
--        self.common_enhance_options(newoptions, **options)
--        options.update(newoptions)
--
--        return super(stageuser_find, self).execute(self, *args, **options)
--
-     def pre_callback(self, ldap, filter, attrs_list, base_dn, scope, *keys, **options):
-         assert isinstance(base_dn, DN)
- 
-diff --git a/ipalib/plugins/user.py b/ipalib/plugins/user.py
-index 9bd7bf7e5242234ead4c39a6346e57865b2e2124..206b380efb6472fb040dde33ac80e3f66c00c138 100644
---- a/ipalib/plugins/user.py
-+++ b/ipalib/plugins/user.py
-@@ -730,10 +730,6 @@ class user_find(baseuser_find):
-             return ("(&(objectclass=posixaccount)(krbprincipalname=%s))"%\
-                         getattr(context, 'principal'), base_dn, scope)
- 
--        newoptions = {}
--        self.common_enhance_options(newoptions, **options)
--        options.update(newoptions)
--
-         preserved = options.get('preserved', False)
-         if preserved is None:
-             base_dn = self.api.env.basedn
--- 
-2.4.3
-
diff --git a/SOURCES/0027-dcerpc-Add-get_trusted_domain_object_type-method.patch b/SOURCES/0027-dcerpc-Add-get_trusted_domain_object_type-method.patch
deleted file mode 100644
index d9aaad1..0000000
--- a/SOURCES/0027-dcerpc-Add-get_trusted_domain_object_type-method.patch
+++ /dev/null
@@ -1,62 +0,0 @@
-From c21bb52f339a38aaf7d5b4285447e5a166fb4fcf Mon Sep 17 00:00:00 2001
-From: Tomas Babej <tbabej@redhat.com>
-Date: Wed, 22 Jul 2015 14:00:37 +0200
-Subject: [PATCH] dcerpc: Add get_trusted_domain_object_type method
-
-https://fedorahosted.org/freeipa/ticket/5029
-
-Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
----
- ipaserver/dcerpc.py | 29 +++++++++++++++++++++++++++++
- 1 file changed, 29 insertions(+)
-
-diff --git a/ipaserver/dcerpc.py b/ipaserver/dcerpc.py
-index c0aa322c5d59e7d17a4ceb90448b397613284e38..c604fa3eae4cf94d719190a5a3e3de15d3841d24 100644
---- a/ipaserver/dcerpc.py
-+++ b/ipaserver/dcerpc.py
-@@ -107,6 +107,14 @@ dcerpc_error_messages = {
-          errors.RequirementError(name=_('At least the domain or IP address should be specified')),
- }
- 
-+pysss_type_key_translation_dict = {
-+    pysss_nss_idmap.ID_USER: 'user',
-+    pysss_nss_idmap.ID_GROUP: 'group',
-+    # Used for users with magic private groups
-+    pysss_nss_idmap.ID_BOTH: 'both',
-+}
-+
-+
- def assess_dcerpc_exception(num=None,message=None):
-     """
-     Takes error returned by Samba bindings and converts it into
-@@ -368,6 +376,27 @@ class DomainValidator(object):
-             raise errors.ValidationError(name=_('trusted domain object'),
-                error= _('Trusted domain did not return a valid SID for the object'))
- 
-+    def get_trusted_domain_object_type(self, name_or_sid):
-+        """
-+        Return the type of the object corresponding to the given name in
-+        the trusted domain, which is either 'user', 'group' or 'both'.
-+        The 'both' types is used for users with magic private groups.
-+        """
-+
-+        object_type = None
-+
-+        if is_sid_valid(name_or_sid):
-+            result = pysss_nss_idmap.getnamebysid(name_or_sid)
-+        else:
-+            result = pysss_nss_idmap.getsidbyname(name_or_sid)
-+
-+        if name_or_sid in result:
-+            object_type = result[name_or_sid].get(pysss_nss_idmap.TYPE_KEY)
-+
-+        # Do the translation to hide pysss_nss_idmap constants
-+        # from higher-level code
-+        return pysss_type_key_translation_dict.get(object_type)
-+
-     def get_trusted_domain_object_from_sid(self, sid):
-         root_logger.debug("Converting SID to object name: %s" % sid)
- 
--- 
-2.4.3
-
diff --git a/SOURCES/0027-help-Add-dnsserver-commands-to-help-topic-dns.patch b/SOURCES/0027-help-Add-dnsserver-commands-to-help-topic-dns.patch
new file mode 100644
index 0000000..a0b00c8
--- /dev/null
+++ b/SOURCES/0027-help-Add-dnsserver-commands-to-help-topic-dns.patch
@@ -0,0 +1,67 @@
+From a7c1e25d3d1c065d0a56e63741c8e5b05ee880a6 Mon Sep 17 00:00:00 2001
+From: David Kupka <dkupka@redhat.com>
+Date: Fri, 15 Jul 2016 11:55:19 +0200
+Subject: [PATCH] help: Add dnsserver commands to help topic 'dns'
+
+https://fedorahosted.org/freeipa/ticket/6069
+
+Reviewed-By: Petr Spacek <pspacek@redhat.com>
+---
+ ipaserver/plugins/dnsserver.py | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/ipaserver/plugins/dnsserver.py b/ipaserver/plugins/dnsserver.py
+index beddec04230d810479fff9612721cf12260bbb3a..d635722a6b6aaea942d49456a04f5d0480d344c9 100644
+--- a/ipaserver/plugins/dnsserver.py
++++ b/ipaserver/plugins/dnsserver.py
+@@ -48,6 +48,8 @@ EXAMPLES:
+ 
+ register = Registry()
+ 
++topic = None
++
+ dnsserver_object_class = ['top', 'idnsServerConfigObject']
+ 
+ @register()
+@@ -149,6 +151,7 @@ class dnsserver(LDAPObject):
+ @register()
+ class dnsserver_mod(LDAPUpdate):
+     __doc__ = _('Modify DNS server configuration')
++    topic = 'dns'
+ 
+     msg_summary = _('Modified DNS server "%(value)s"')
+ 
+@@ -156,6 +159,7 @@ class dnsserver_mod(LDAPUpdate):
+ @register()
+ class dnsserver_find(LDAPSearch):
+     __doc__ = _('Search for DNS servers.')
++    topic = 'dns'
+ 
+     msg_summary = ngettext(
+         '%(count)d DNS server matched',
+@@ -166,6 +170,7 @@ class dnsserver_find(LDAPSearch):
+ @register()
+ class dnsserver_show(LDAPRetrieve):
+     __doc__=_('Display configuration of a DNS server.')
++    topic = 'dns'
+ 
+ 
+ @register()
+@@ -175,6 +180,7 @@ class dnsserver_add(LDAPCreate, Local):
+     Be careful in future this will be transformed to public API call
+     """
+     __doc__ = _('Add a new DNS server.')
++    topic = 'dns'
+ 
+     msg_summary = _('Added new DNS server "%(value)s"')
+ 
+@@ -186,5 +192,6 @@ class dnsserver_del(LDAPDelete, Local):
+     Be careful in future this will be transformed to public API call
+     """
+     __doc__ = _('Delete a DNS server')
++    topic = 'dns'
+ 
+     msg_summary = _('Deleted DNS server "%(value)s"')
+-- 
+2.7.4
+
diff --git a/SOURCES/0028-DNS-Locations-fix-update-system-records-unpacking-er.patch b/SOURCES/0028-DNS-Locations-fix-update-system-records-unpacking-er.patch
new file mode 100644
index 0000000..dc26a25
--- /dev/null
+++ b/SOURCES/0028-DNS-Locations-fix-update-system-records-unpacking-er.patch
@@ -0,0 +1,35 @@
+From 0f655b619eae8320757cd6d18f9f1dda6ab2c6ed Mon Sep 17 00:00:00 2001
+From: Martin Basti <mbasti@redhat.com>
+Date: Fri, 22 Jul 2016 13:32:31 +0200
+Subject: [PATCH] DNS Locations: fix update-system-records unpacking error
+
+Method IPASystemRecords.records_list_from_node returns only list
+consists only from record names not tuple, which caused unpacking error
+
+https://fedorahosted.org/freeipa/ticket/6117
+
+Reviewed-By: Nikhil Dehadrai <ndehadra@redhat.com>
+---
+ ipaserver/install/bindinstance.py | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/ipaserver/install/bindinstance.py b/ipaserver/install/bindinstance.py
+index 844fb04a9d9feca936211964b75a0b3468ba663b..7538e145cbe37dfc21963d97dea0e835e3bd5072 100644
+--- a/ipaserver/install/bindinstance.py
++++ b/ipaserver/install/bindinstance.py
+@@ -1139,10 +1139,10 @@ class BindInstance(service.Service):
+                 root_logger.error("Update of following records failed:")
+                 for attr in (failed_ipa_rec, failed_loc_rec):
+                     for rname, node, error in attr:
+-                        for record, e in IPASystemRecords.records_list_from_node(
++                        for record in IPASystemRecords.records_list_from_node(
+                                 rname, node
+                         ):
+-                            root_logger.error("%s (%s)", record, e)
++                            root_logger.error("%s (%s)", record, error)
+ 
+     def check_global_configuration(self):
+         """
+-- 
+2.7.4
+
diff --git a/SOURCES/0028-idviews-Restrict-anchor-to-name-and-name-to-anchor-c.patch b/SOURCES/0028-idviews-Restrict-anchor-to-name-and-name-to-anchor-c.patch
deleted file mode 100644
index 21dea02..0000000
--- a/SOURCES/0028-idviews-Restrict-anchor-to-name-and-name-to-anchor-c.patch
+++ /dev/null
@@ -1,98 +0,0 @@
-From 964bce5fd60bbb52be1dcc67e628a6c1ab62e356 Mon Sep 17 00:00:00 2001
-From: Tomas Babej <tbabej@redhat.com>
-Date: Thu, 23 Jul 2015 12:36:53 +0200
-Subject: [PATCH] idviews: Restrict anchor to name and name to anchor
- conversions
-
-When converting the ID override anchor from AD SID representation to
-the object name, we need to properly restrict the type of the object
-that is being resolved.
-
-The same restriction applies for the opposite direction, when
-converting the object name to it's SID.
-
-https://fedorahosted.org/freeipa/ticket/5029
-
-Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
----
- ipalib/plugins/idviews.py | 50 +++++++++++++++++++++++++++++++++++++++++++----
- 1 file changed, 46 insertions(+), 4 deletions(-)
-
-diff --git a/ipalib/plugins/idviews.py b/ipalib/plugins/idviews.py
-index 67f52f886f0e19288a829616603c7aef6768f8db..c4f748132642f8702dcd12d38367dc36f4bc4a3c 100644
---- a/ipalib/plugins/idviews.py
-+++ b/ipalib/plugins/idviews.py
-@@ -432,6 +432,36 @@ class idview_unapply(baseidview_apply):
- 
- 
- # ID overrides helper methods
-+def verify_trusted_domain_object_type(validator, desired_type, name_or_sid):
-+
-+    object_type = validator.get_trusted_domain_object_type(name_or_sid)
-+
-+    if object_type == desired_type:
-+        # In case SSSD returns the same type as the type being
-+        # searched, no problems here.
-+        return True
-+
-+    elif desired_type == 'user' and object_type == 'both':
-+        # Type both denotes users with magic private groups.
-+        # Overriding attributes for such users is OK.
-+        return True
-+
-+    elif desired_type == 'group' and object_type == 'both':
-+        # However, overriding attributes for magic private groups
-+        # does not make sense. One should override the GID of
-+        # the user itself.
-+
-+        raise errors.ConversionError(
-+            name='identifier',
-+            error=_('You are trying to reference a magic private group '
-+                    'which is not allowed to be overriden. '
-+                    'Try overriding the GID attribute of the '
-+                    'corresponding user instead.')
-+            )
-+
-+    return False
-+
-+
- def resolve_object_to_anchor(ldap, obj_type, obj, fallback_to_ldap):
-     """
-     Resolves the user/group name to the anchor uuid:
-@@ -482,9 +512,15 @@ def resolve_object_to_anchor(ldap, obj_type, obj, fallback_to_ldap):
-                 sid = domain_validator.get_trusted_domain_object_sid(obj,
-                         fallback_to_ldap=fallback_to_ldap)
- 
--                # There is no domain prefix since SID contains information
--                # about the domain
--                return SID_ANCHOR_PREFIX + sid
-+                # We need to verify that the object type is correct
-+                type_correct = verify_trusted_domain_object_type(
-+                        domain_validator, obj_type, sid)
-+
-+                if type_correct:
-+                    # There is no domain prefix since SID contains information
-+                    # about the domain
-+                    return SID_ANCHOR_PREFIX + sid
-+
-     except errors.ValidationError:
-         # Domain validator raises Validation Error if object name does not
-         # contain domain part (either NETBIOS\ prefix or @domain.name suffix)
-@@ -539,7 +575,13 @@ def resolve_anchor_to_object_name(ldap, obj_type, anchor):
-             domain_validator = ipaserver.dcerpc.DomainValidator(api)
-             if domain_validator.is_configured():
-                 name = domain_validator.get_trusted_domain_object_from_sid(sid)
--                return name
-+
-+                # We need to verify that the object type is correct
-+                type_correct = verify_trusted_domain_object_type(
-+                        domain_validator, obj_type, name)
-+
-+                if type_correct:
-+                    return name
- 
-     # No acceptable object was found
-     raise errors.NotFound(
--- 
-2.4.3
-
diff --git a/SOURCES/0029-Fix-session-cookies.patch b/SOURCES/0029-Fix-session-cookies.patch
new file mode 100644
index 0000000..dc2dd2c
--- /dev/null
+++ b/SOURCES/0029-Fix-session-cookies.patch
@@ -0,0 +1,136 @@
+From 059ced75270c681144462dba3772812901495054 Mon Sep 17 00:00:00 2001
+From: Florence Blanc-Renaud <flo@redhat.com>
+Date: Thu, 21 Jul 2016 16:54:43 +0200
+Subject: [PATCH] Fix session cookies
+
+The CLI was not using session cookies for communication with IPA API.
+The kernel_keyring code was expecting the keyname to be a string, but
+in python 2 a unicode was supplied (the key is built using
+ipa_session_cookie:%principal and principal is a unicode).
+
+The patch fixes the assertions, allowing to store and retrieve the cookie.
+It also adds a test with unicode key name.
+
+https://fedorahosted.org/freeipa/ticket/5984
+
+Reviewed-By: Petr Spacek <pspacek@redhat.com>
+---
+ ipapython/kernel_keyring.py             | 15 ++++++++-------
+ ipatests/test_ipapython/test_keyring.py | 15 +++++++++++++++
+ 2 files changed, 23 insertions(+), 7 deletions(-)
+
+diff --git a/ipapython/kernel_keyring.py b/ipapython/kernel_keyring.py
+index ed4868a9d8eaffdae6f717928663296bd20c762e..651fd708667420d1769e3601a8fa0b6c52604a10 100644
+--- a/ipapython/kernel_keyring.py
++++ b/ipapython/kernel_keyring.py
+@@ -18,6 +18,7 @@
+ #
+ 
+ import os
++import six
+ 
+ from ipapython.ipautil import run
+ 
+@@ -45,7 +46,7 @@ def get_real_key(key):
+     One cannot request a key based on the description it was created with
+     so find the one we're looking for.
+     """
+-    assert isinstance(key, str)
++    assert isinstance(key, six.string_types)
+     result = run(['keyctl', 'search', KEYRING, KEYTYPE, key],
+                  raiseonerr=False, capture_output=True)
+     if result.returncode:
+@@ -53,7 +54,7 @@ def get_real_key(key):
+     return result.raw_output.rstrip()
+ 
+ def get_persistent_key(key):
+-    assert isinstance(key, str)
++    assert isinstance(key, six.string_types)
+     result = run(['keyctl', 'get_persistent', KEYRING, key],
+                  raiseonerr=False, capture_output=True)
+     if result.returncode:
+@@ -73,7 +74,7 @@ def has_key(key):
+     """
+     Returns True/False whether the key exists in the keyring.
+     """
+-    assert isinstance(key, str)
++    assert isinstance(key, six.string_types)
+     try:
+         get_real_key(key)
+         return True
+@@ -86,7 +87,7 @@ def read_key(key):
+ 
+     Use pipe instead of print here to ensure we always get the raw data.
+     """
+-    assert isinstance(key, str)
++    assert isinstance(key, six.string_types)
+     real_key = get_real_key(key)
+     result = run(['keyctl', 'pipe', real_key], raiseonerr=False,
+                  capture_output=True)
+@@ -99,7 +100,7 @@ def update_key(key, value):
+     """
+     Update the keyring data. If they key doesn't exist it is created.
+     """
+-    assert isinstance(key, str)
++    assert isinstance(key, six.string_types)
+     assert isinstance(value, bytes)
+     if has_key(key):
+         real_key = get_real_key(key)
+@@ -114,7 +115,7 @@ def add_key(key, value):
+     """
+     Add a key to the kernel keyring.
+     """
+-    assert isinstance(key, str)
++    assert isinstance(key, six.string_types)
+     assert isinstance(value, bytes)
+     if has_key(key):
+         raise ValueError('key %s already exists' % key)
+@@ -127,7 +128,7 @@ def del_key(key):
+     """
+     Remove a key from the keyring
+     """
+-    assert isinstance(key, str)
++    assert isinstance(key, six.string_types)
+     real_key = get_real_key(key)
+     result = run(['keyctl', 'unlink', real_key, KEYRING],
+                  raiseonerr=False)
+diff --git a/ipatests/test_ipapython/test_keyring.py b/ipatests/test_ipapython/test_keyring.py
+index e22841c8f5d229d17cdd05ab9c4248eeffaab249..c81e6d95f7ebdf585ee37ecf71151c01e0001912 100644
+--- a/ipatests/test_ipapython/test_keyring.py
++++ b/ipatests/test_ipapython/test_keyring.py
+@@ -28,6 +28,7 @@ import pytest
+ pytestmark = pytest.mark.tier0
+ 
+ TEST_KEY = 'ipa_test'
++TEST_UNICODEKEY = u'ipa_unicode'
+ TEST_VALUE = b'abc123'
+ UPDATE_VALUE = b'123abc'
+ 
+@@ -49,6 +50,10 @@ class test_keyring(object):
+             kernel_keyring.del_key(SIZE_256)
+         except ValueError:
+             pass
++        try:
++            kernel_keyring.del_key(TEST_UNICODEKEY)
++        except ValueError:
++            pass
+ 
+     def test_01(self):
+         """
+@@ -150,3 +155,13 @@ class test_keyring(object):
+         assert(result == SIZE_1024.encode('ascii'))
+ 
+         kernel_keyring.del_key(TEST_KEY)
++
++    def test_10(self):
++        """
++        Test a unicode key
++        """
++        kernel_keyring.add_key(TEST_UNICODEKEY, TEST_VALUE)
++        result = kernel_keyring.read_key(TEST_UNICODEKEY)
++        assert(result == TEST_VALUE)
++
++        kernel_keyring.del_key(TEST_UNICODEKEY)
+-- 
+2.7.4
+
diff --git a/SOURCES/0029-idviews-Enforce-objectclass-check-in-idoverride-del.patch b/SOURCES/0029-idviews-Enforce-objectclass-check-in-idoverride-del.patch
deleted file mode 100644
index be14df0..0000000
--- a/SOURCES/0029-idviews-Enforce-objectclass-check-in-idoverride-del.patch
+++ /dev/null
@@ -1,52 +0,0 @@
-From 9fedf58eb1282560957edc1f36356602b55a736d Mon Sep 17 00:00:00 2001
-From: Tomas Babej <tbabej@redhat.com>
-Date: Thu, 23 Jul 2015 14:00:06 +0200
-Subject: [PATCH] idviews: Enforce objectclass check in idoverride*-del
-
-Even with anchor to sid type checking, it would be still
-possible to delete a user ID override by specifying a group
-raw anchor and vice versa.
-
-This patch introduces a objectclass check in idoverride*-del
-commands to prevent that.
-
-https://fedorahosted.org/freeipa/ticket/5029
-
-Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
----
- ipalib/plugins/idviews.py | 19 +++++++++++++++++++
- 1 file changed, 19 insertions(+)
-
-diff --git a/ipalib/plugins/idviews.py b/ipalib/plugins/idviews.py
-index c4f748132642f8702dcd12d38367dc36f4bc4a3c..2e6e84510d3caa3636d3f0c08c56403866ff54f9 100644
---- a/ipalib/plugins/idviews.py
-+++ b/ipalib/plugins/idviews.py
-@@ -716,6 +716,25 @@ class baseidoverride_del(LDAPDelete):
- 
-     takes_options = LDAPDelete.takes_options + (fallback_to_ldap_option,)
- 
-+    def pre_callback(self, ldap, dn, *keys, **options):
-+        assert isinstance(dn, DN)
-+
-+        # Make sure the entry we're deleting has all the objectclasses
-+        # this object requires
-+        try:
-+            entry = ldap.get_entry(dn, ['objectclass'])
-+        except errors.NotFound:
-+            self.obj.handle_not_found(*keys)
-+
-+        required_object_classes = set(self.obj.object_class)
-+        actual_object_classes = set(entry['objectclass'])
-+
-+        # If not, treat it as a failed search
-+        if not required_object_classes.issubset(actual_object_classes):
-+            self.obj.handle_not_found(*keys)
-+
-+        return dn
-+
- 
- class baseidoverride_mod(LDAPUpdate):
-     __doc__ = _('Modify an ID override.')
--- 
-2.4.3
-
diff --git a/SOURCES/0030-Use-copy-when-replacing-files-to-keep-SELinux-contex.patch b/SOURCES/0030-Use-copy-when-replacing-files-to-keep-SELinux-contex.patch
new file mode 100644
index 0000000..ac00108
--- /dev/null
+++ b/SOURCES/0030-Use-copy-when-replacing-files-to-keep-SELinux-contex.patch
@@ -0,0 +1,38 @@
+From 602d1c5190cfb879f81ced19e60d1eb08bd559f0 Mon Sep 17 00:00:00 2001
+From: Martin Basti <mbasti@redhat.com>
+Date: Thu, 21 Jul 2016 18:49:57 +0200
+Subject: [PATCH] Use copy when replacing files to keep SELinux context
+
+When installer replaces any file with newer, it must use 'copy' instead of
+'mv' to keep SELinux context valid.
+
+https://fedorahosted.org/freeipa/ticket/6111
+
+Reviewed-By: Petr Spacek <pspacek@redhat.com>
+---
+ ipapython/ipautil.py | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/ipapython/ipautil.py b/ipapython/ipautil.py
+index 763a99c117e22a4ac49d8d34b38230f3da7c8435..9964fba4f694b57242b3bd3065a418917d977533 100644
+--- a/ipapython/ipautil.py
++++ b/ipapython/ipautil.py
+@@ -528,10 +528,14 @@ def dir_exists(filename):
+     except Exception:
+         return False
+ 
++
+ def install_file(fname, dest):
++    # SELinux: use copy to keep the right context
+     if file_exists(dest):
+         os.rename(dest, dest + ".orig")
+-    shutil.move(fname, dest)
++    shutil.copy(fname, dest)
++    os.remove(fname)
++
+ 
+ def backup_file(fname):
+     if file_exists(fname):
+-- 
+2.7.4
+
diff --git a/SOURCES/0030-idviews-Check-for-the-Default-Trust-View-only-if-app.patch b/SOURCES/0030-idviews-Check-for-the-Default-Trust-View-only-if-app.patch
deleted file mode 100644
index 2f74590..0000000
--- a/SOURCES/0030-idviews-Check-for-the-Default-Trust-View-only-if-app.patch
+++ /dev/null
@@ -1,50 +0,0 @@
-From f12e0e81f1cc6af2034c535866c3bfeddce8321d Mon Sep 17 00:00:00 2001
-From: Tomas Babej <tbabej@redhat.com>
-Date: Tue, 21 Jul 2015 12:44:37 +0200
-Subject: [PATCH] idviews: Check for the Default Trust View only if applying
- the view
-
-Currently, the code wrongly validates the idview-unapply command. Move
-check for the forbidden application of the Default Trust View into
-the correct logical branch.
-
-https://fedorahosted.org/freeipa/ticket/4969
-
-Reviewed-By: Martin Basti <mbasti@redhat.com>
----
- ipalib/plugins/idviews.py | 14 ++++++++------
- 1 file changed, 8 insertions(+), 6 deletions(-)
-
-diff --git a/ipalib/plugins/idviews.py b/ipalib/plugins/idviews.py
-index 2e6e84510d3caa3636d3f0c08c56403866ff54f9..ceb277020d1325bfd1607bcd4b05f4069ae9508d 100644
---- a/ipalib/plugins/idviews.py
-+++ b/ipalib/plugins/idviews.py
-@@ -256,17 +256,19 @@ class baseidview_apply(LDAPQuery):
-         if not options.get('clear_view', False):
-             view_dn = self.api.Object['idview'].get_dn_if_exists(view)
-             assert isinstance(view_dn, DN)
-+
-+            # Check that we're not applying the Default Trust View
-+            if view.lower() == DEFAULT_TRUST_VIEW_NAME:
-+                raise errors.ValidationError(
-+                    name=_('ID View'),
-+                    error=_('Default Trust View cannot be applied on hosts')
-+                )
-+
-         else:
-             # In case we are removing assigned view, we modify the host setting
-             # the ipaAssignedIDView to None
-             view_dn = None
- 
--        if view.lower() == DEFAULT_TRUST_VIEW_NAME:
--            raise errors.ValidationError(
--                name=_('ID View'),
--                error=_('Default Trust View cannot be applied on hosts')
--            )
--
-         completed = 0
-         succeeded = {'host': []}
-         failed = {
--- 
-2.4.3
-
diff --git a/SOURCES/0031-baseldap-Fix-MidairCollision-instantiation-during-en.patch b/SOURCES/0031-baseldap-Fix-MidairCollision-instantiation-during-en.patch
new file mode 100644
index 0000000..9b87f51
--- /dev/null
+++ b/SOURCES/0031-baseldap-Fix-MidairCollision-instantiation-during-en.patch
@@ -0,0 +1,38 @@
+From 25b1fb956cc8029d5030d93cf48faed823778c5e Mon Sep 17 00:00:00 2001
+From: Martin Babinsky <mbabinsk@redhat.com>
+Date: Mon, 25 Jul 2016 14:05:08 +0200
+Subject: [PATCH] baseldap: Fix MidairCollision instantiation during entry
+ modification
+
+https://fedorahosted.org/freeipa/ticket/6097
+
+Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
+---
+ ipaserver/plugins/baseldap.py | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/ipaserver/plugins/baseldap.py b/ipaserver/plugins/baseldap.py
+index 6107e43a6ee17d9b9a63d9dc109664d8b232069f..f7844e3e7c59c259b9c8367d135b2dbefc3f0016 100644
+--- a/ipaserver/plugins/baseldap.py
++++ b/ipaserver/plugins/baseldap.py
+@@ -1466,7 +1466,7 @@ class LDAPUpdate(LDAPQuery, crud.Update):
+                 entry_attrs.dn, attrs_list)
+         except errors.NotFound:
+             raise errors.MidairCollision(
+-                format=_('the entry was deleted while being modified')
++                message=_('the entry was deleted while being modified')
+             )
+ 
+         self.obj.get_indirect_members(entry_attrs, attrs_list)
+@@ -2344,7 +2344,7 @@ class BaseLDAPModAttribute(LDAPQuery):
+                 entry_attrs.dn, attrs_list)
+         except errors.NotFound:
+             raise errors.MidairCollision(
+-                format=_('the entry was deleted while being modified')
++                message=_('the entry was deleted while being modified')
+             )
+ 
+         for callback in self.get_callbacks('post'):
+-- 
+2.7.4
+
diff --git a/SOURCES/0031-replication-Fix-incorrect-exception-invocation.patch b/SOURCES/0031-replication-Fix-incorrect-exception-invocation.patch
deleted file mode 100644
index 8ae1032..0000000
--- a/SOURCES/0031-replication-Fix-incorrect-exception-invocation.patch
+++ /dev/null
@@ -1,26 +0,0 @@
-From e3925cac13a3daca4880e789a139bad265c21798 Mon Sep 17 00:00:00 2001
-From: Tomas Babej <tbabej@redhat.com>
-Date: Fri, 24 Jul 2015 11:26:33 +0200
-Subject: [PATCH] replication: Fix incorrect exception invocation
-
-Reviewed-By: Tomas Babej <tbabej@redhat.com>
----
- ipaserver/install/replication.py | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/ipaserver/install/replication.py b/ipaserver/install/replication.py
-index e9af88dc4356d4fd5495f4fea399ab09c75db953..2b36a5eb9287bf1789009a3198e540e333869e98 100644
---- a/ipaserver/install/replication.py
-+++ b/ipaserver/install/replication.py
-@@ -1171,7 +1171,7 @@ class ReplicationManager(object):
-         entry = self.get_replication_agreement(hostname)
-         if not entry:
-             raise errors.NotFound(
--                "Replication agreement for %s not found" % hostname)
-+                reason="Replication agreement for %s not found" % hostname)
-         objectclass = entry.get("objectclass")
- 
-         for o in objectclass:
--- 
-2.4.3
-
diff --git a/SOURCES/0032-Create-indexes-for-krbCanonicalName-attribute.patch b/SOURCES/0032-Create-indexes-for-krbCanonicalName-attribute.patch
new file mode 100644
index 0000000..7a008f3
--- /dev/null
+++ b/SOURCES/0032-Create-indexes-for-krbCanonicalName-attribute.patch
@@ -0,0 +1,54 @@
+From 1eed28c173336da828ac60b64b09a8b01d79fab4 Mon Sep 17 00:00:00 2001
+From: Martin Babinsky <mbabinsk@redhat.com>
+Date: Fri, 22 Jul 2016 13:02:38 +0200
+Subject: [PATCH] Create indexes for krbCanonicalName attribute
+
+krbCanonicalName is for a long time among the attributes guarded by uniqueness
+plugins, but there was never an index for it. Now that the attribute is really
+used to store canonical principal names we need to add index for it to avoid
+performance regressions.
+
+https://fedorahosted.org/freeipa/ticket/6100
+
+Reviewed-By: Thierry Bordaz <tbordaz@redhat.com>
+---
+ install/share/indices.ldif        | 9 +++++++++
+ install/updates/20-indices.update | 8 ++++++++
+ 2 files changed, 17 insertions(+)
+
+diff --git a/install/share/indices.ldif b/install/share/indices.ldif
+index 642c2f7aee78b684b3e451c2595e4f18950e449e..d853266025ae350dd7de83e11e463c6bb1ab9429 100644
+--- a/install/share/indices.ldif
++++ b/install/share/indices.ldif
+@@ -269,3 +269,12 @@ ObjectClass: nsIndex
+ nsSystemIndex: false
+ nsIndexType: eq
+ nsIndexType: pres
++
++dn: cn=krbCanonicalName,cn=index,cn=userRoot,cn=ldbm database,cn=plugins,cn=config
++changetype: add
++cn: krbCanonicalName
++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 445eda5ab6939f21654335ea4dd50d7b2cab008f..74961d77875515d680f34af739c984a6533eb252 100644
+--- a/install/updates/20-indices.update
++++ b/install/updates/20-indices.update
+@@ -251,3 +251,11 @@ only: nsMatchingRule: caseIgnoreIA5Match
+ only: nsMatchingRule: caseExactIA5Match
+ only:nsIndexType: eq
+ only:nsIndexType: sub
++
++dn: cn=krbCanonicalName,cn=index,cn=userRoot,cn=ldbm database,cn=plugins,cn=config
++default: cn: krbCanonicalName
++default: objectClass: top
++default: objectClass: nsIndex
++only: nsSystemIndex: false
++only: nsIndexType: eq
++only: nsIndexType: sub
+-- 
+2.7.4
+
diff --git a/SOURCES/0032-webui-add-Kerberos-configuration-instructions-for-Ch.patch b/SOURCES/0032-webui-add-Kerberos-configuration-instructions-for-Ch.patch
deleted file mode 100644
index 4693fb7..0000000
--- a/SOURCES/0032-webui-add-Kerberos-configuration-instructions-for-Ch.patch
+++ /dev/null
@@ -1,149 +0,0 @@
-From dc0d09f6e6a5681fa4c4146e6df6872dccc40b68 Mon Sep 17 00:00:00 2001
-From: Petr Vobornik <pvoborni@redhat.com>
-Date: Fri, 17 Jul 2015 15:57:30 +0200
-Subject: [PATCH] webui: add Kerberos configuration instructions for Chrome
-
-* IE section moved at the end
-* Chrome section added
-* FF and IE icons removed
-
-https://fedorahosted.org/freeipa/ticket/823
-
-Reviewed-By: Martin Basti <mbasti@redhat.com>
----
- install/html/ssbrowser.html | 111 +++++++++++++++++++++++++++++++-------------
- 1 file changed, 80 insertions(+), 31 deletions(-)
-
-diff --git a/install/html/ssbrowser.html b/install/html/ssbrowser.html
-index d90103228150a60bd49e91ea8c64891d53d75d7b..685800e16e6e77c70adf905acfca2996513d1e1d 100644
---- a/install/html/ssbrowser.html
-+++ b/install/html/ssbrowser.html
-@@ -54,38 +54,8 @@
-     <div class="col-sm-12">
-     <div class="ssbrowser">
-         <h1>Browser Kerberos Setup</h1>
--        <h2><img alt="Internet Explorer" src="../ui/images/ie-icon.png">Internet Explorer Configuration</h2>
--        <p>
--            Once you are able to log into the workstation with your kerberos key you are now able to use that ticket in Internet Explorer.
--        </p>
--        <p>
--            <strong>Login to the Windows machine using an account of your Kerberos realm (administrative domain)</strong>
--        </p>
--        <p>
--            <strong>In Internet Explorer, click Tools, and then click Internet Options.</strong>
--        </p>
--        <div>
--            <ol>
--                <li>Click the Security tab</li>
--                <li>Click Local intranet</li>
--                <li>Click Sites </li>
--                <li>Click Advanced </li>
--                <li>Add your domain to the list</li>
--            </ol>
--            <ol>
--                <li>Click the Security tab</li>
--                <li>Click Local intranet</li>
--                <li>Click Custom Level</li>
--                <li>Select Automatic logon only in Intranet zone</li>
--            </ol>
--
--            <ol>
--                <li> Visit a kerberized web site using IE (You must use the fully-qualified Domain Name in the URL)</li>
--                <li><strong> You are all set.</strong></li>
--            </ol>
--        </div>
- 
--        <h2><img alt="Firefox" src="../ui/images/firefox-icon.png">Firefox Configuration</h2>
-+        <h2>Firefox</h2>
- 
-         <p>
-             You can configure Firefox to use Kerberos for Single Sign-on. The following instructions will guide you in configuring your web browser to send your Kerberos credentials to the appropriate Key Distribution Center which enables Single Sign-on.
-@@ -117,6 +87,85 @@
-             </li>
-         </ol>
- 
-+        <h2>Chrome</h2>
-+
-+        <p>
-+            You can configure Chrome to use Kerberos for Single Sign-on. The following instructions will guide you in configuring your web browser to send your Kerberos credentials to the appropriate Key Distribution Center which enables Single Sign-on.
-+        </p>
-+
-+        <h3>Import CA Certificate</h3>
-+        <ol>
-+            <li>
-+                Download the <a href="ca.crt">CA certificate</a>. Alternatively, if the host is also an IdM client, you can find the certificate in /etc/ipa/ca.crt.
-+            </li>
-+            <li>
-+                Click the menu button with the <em>Customize and control Google Chrome</em> tooltip, which is by default in the top right-hand corner of Chrome, and click <em>Settings</em>.
-+            </li>
-+            <li>
-+                Click <em>Show advanced settings</em> to display more options, and then click the <em>Manage certificates</em> button located under the HTTPS/SSL heading.
-+            </li>
-+            <li>
-+                In the <em>Authorities</em> tab, click the <em>Import</em> button at the bottom.
-+            </li>
-+            <li>Select the CA certificate file that you downloaded in the first step.</li>
-+        </ol>
-+
-+        <h3>
-+            Enable SPNEGO (Simple and Protected GSSAPI Negotiation Mechanism) to Use Kerberos Authentication
-+            in Chrome
-+        </h3>
-+        <ol>
-+            <li>
-+                Make sure you have the necessary directory created by running:
-+                <div><code>
-+                    [root@client]# mkdir -p /etc/opt/chrome/policies/managed/
-+                </code></div>
-+            </li>
-+            <li>
-+                Create a new <code>/etc/opt/chrome/policies/managed/mydomain.json</code> file with write privileges limited to the system administrator or root, and include the following line:
-+                <div><code>
-+                    { "AuthServerWhitelist": "*<span class="example-domain">.example.com.</span>" }
-+                </code></div>
-+                <div>
-+                    You can do this by running:
-+                </div>
-+                <div><code>
-+                    [root@server]# echo '{ "AuthServerWhitelist": "*<span class="example-domain">.example.com.</span>" }' > /etc/opt/chrome/policies/managed/mydomain.json
-+                </code></div>
-+            </li>
-+        </ol>
-+
-+        <h2>Internet Explorer</h2>
-+        <p>
-+            Once you are able to log into the workstation with your kerberos key you are now able to use that ticket in Internet Explorer.
-+        </p>
-+        <p>
-+            <strong>Login to the Windows machine using an account of your Kerberos realm (administrative domain)</strong>
-+        </p>
-+        <p>
-+            <strong>In Internet Explorer, click Tools, and then click Internet Options.</strong>
-+        </p>
-+        <div>
-+            <ol>
-+                <li>Click the Security tab</li>
-+                <li>Click Local intranet</li>
-+                <li>Click Sites </li>
-+                <li>Click Advanced </li>
-+                <li>Add your domain to the list</li>
-+            </ol>
-+            <ol>
-+                <li>Click the Security tab</li>
-+                <li>Click Local intranet</li>
-+                <li>Click Custom Level</li>
-+                <li>Select Automatic logon only in Intranet zone</li>
-+            </ol>
-+
-+            <ol>
-+                <li> Visit a kerberized web site using IE (You must use the fully-qualified Domain Name in the URL)</li>
-+                <li><strong> You are all set.</strong></li>
-+            </ol>
-+        </div>
-+
-     </div>
-     </div>
-     </div>
--- 
-2.4.3
-
diff --git a/SOURCES/0033-Remove-ico-files-from-Makefile.patch b/SOURCES/0033-Remove-ico-files-from-Makefile.patch
deleted file mode 100644
index 620acff..0000000
--- a/SOURCES/0033-Remove-ico-files-from-Makefile.patch
+++ /dev/null
@@ -1,32 +0,0 @@
-From 56cdac487c35623b89881df4dd39713fdd36cb7c Mon Sep 17 00:00:00 2001
-From: Martin Basti <mbasti@redhat.com>
-Date: Mon, 27 Jul 2015 16:06:39 +0200
-Subject: [PATCH] Remove ico files from Makefile
-
-Icons were removed in a4be844809179ff0a05286606df1487d81a70022 but still
-persist in Makefile. This patch fixes Makefile.
-
-https://fedorahosted.org/freeipa/ticket/823
-
-Reviewed-By: Martin Babinsky <mbabinsk@redhat.com>
----
- install/ui/images/Makefile.am | 2 --
- 1 file changed, 2 deletions(-)
-
-diff --git a/install/ui/images/Makefile.am b/install/ui/images/Makefile.am
-index e74d747b79ad14ef2f5b9e539c348670796fec8a..7d85d7e8203ca54f5b8fddeb55d86e106f077140 100644
---- a/install/ui/images/Makefile.am
-+++ b/install/ui/images/Makefile.am
-@@ -4,9 +4,7 @@ appdir = $(IPA_DATA_DIR)/ui/images
- app_DATA =                              \
- 	facet-tab-off.png		\
- 	facet-tab-on.png		\
--	firefox-icon.png		\
- 	header-logo.png			\
--	ie-icon.png 			\
- 	login-screen-background.jpg	\
- 	login-screen-logo.png	\
- 	product-name.png		\
--- 
-2.4.3
-
diff --git a/SOURCES/0033-harden-the-check-for-trust-namespace-overlap-in-new-.patch b/SOURCES/0033-harden-the-check-for-trust-namespace-overlap-in-new-.patch
new file mode 100644
index 0000000..8bf5ee6
--- /dev/null
+++ b/SOURCES/0033-harden-the-check-for-trust-namespace-overlap-in-new-.patch
@@ -0,0 +1,43 @@
+From 843d21620c118f283f53db77b1114d15d26dc176 Mon Sep 17 00:00:00 2001
+From: Martin Babinsky <mbabinsk@redhat.com>
+Date: Wed, 20 Jul 2016 15:46:22 +0200
+Subject: [PATCH] harden the check for trust namespace overlap in new
+ principals
+
+This check must handle the possibility of optional attributes
+(ipantadditionalsuffixes and ipantflatname) missing in the trusted domain
+entry.
+
+https://fedorahosted.org/freeipa/ticket/6099
+
+Reviewed-By: David Kupka <dkupka@redhat.com>
+---
+ ipalib/util.py | 10 +++++++---
+ 1 file changed, 7 insertions(+), 3 deletions(-)
+
+diff --git a/ipalib/util.py b/ipalib/util.py
+index d101514cad4f35fd9a09d84b549ffa86de432f70..e0fc178c4af2056d04ad88a3923daa7d127fe307 100644
+--- a/ipalib/util.py
++++ b/ipalib/util.py
+@@ -968,11 +968,15 @@ def check_principal_realm_in_trust_namespace(api_instance, *keys):
+     trust_suffix_namespace = set()
+ 
+     for obj in trust_objects:
+-        trust_suffix_namespace.update(
+-            set(upn.lower() for upn in obj['ipantadditionalsuffixes']))
++        nt_suffixes = obj.get('ipantadditionalsuffixes', [])
+ 
+         trust_suffix_namespace.update(
+-            set((obj['cn'][0].lower(), obj['ipantflatname'][0].lower())))
++            set(upn.lower() for upn in nt_suffixes))
++
++        if 'ipantflatname' in obj:
++            trust_suffix_namespace.add(obj['ipantflatname'][0].lower())
++
++        trust_suffix_namespace.add(obj['cn'][0].lower())
+ 
+     for principal in keys[-1]:
+         realm = principal.realm
+-- 
+2.7.4
+
diff --git a/SOURCES/0034-ACI-plugin-correctly-parse-bind-rules-enclosed-in-pa.patch b/SOURCES/0034-ACI-plugin-correctly-parse-bind-rules-enclosed-in-pa.patch
deleted file mode 100644
index 2268504..0000000
--- a/SOURCES/0034-ACI-plugin-correctly-parse-bind-rules-enclosed-in-pa.patch
+++ /dev/null
@@ -1,47 +0,0 @@
-From c00b3fac15439828ce0ecffa181d1b263ad505a7 Mon Sep 17 00:00:00 2001
-From: Martin Babinsky <mbabinsk@redhat.com>
-Date: Thu, 23 Jul 2015 15:45:35 +0200
-Subject: [PATCH] ACI plugin: correctly parse bind rules enclosed in
- parentheses
-
-Since bind rule such as `(userdn = "ldap:///anyone")` is also a valid
-statement, the ipalib ACI parser was updated to handle this case.
-
-https://fedorahosted.org/freeipa/ticket/5037
-
-Reviewed-By: Martin Basti <mbasti@redhat.com>
----
- ipalib/aci.py | 8 ++++++--
- 1 file changed, 6 insertions(+), 2 deletions(-)
-
-diff --git a/ipalib/aci.py b/ipalib/aci.py
-index a55732bf19e58d8a4b36fa18bee2725d5b6584da..f78c5327dbe659240f046ae15622e798c8552829 100755
---- a/ipalib/aci.py
-+++ b/ipalib/aci.py
-@@ -26,10 +26,11 @@ import re
- ACIPat = re.compile(r'\(version\s+3.0\s*;\s*ac[li]\s+\"([^\"]*)\"\s*;\s*([^;]*);\s*\)', re.UNICODE)
- 
- # Break the permissions/bind_rules out
--PermPat = re.compile(r'(\w+)\s*\((.*)\)\s+(.*)', re.UNICODE)
-+PermPat = re.compile(r'(\w+)\s*\(([^()]*)\)\s*(.*)', re.UNICODE)
- 
- # Break the bind rule out
--BindPat = re.compile(r'([a-zA-Z0-9;\.]+)\s*(\!?=)\s*(.*)', re.UNICODE)
-+BindPat = re.compile(r'\(?([a-zA-Z0-9;\.]+)\s*(\!?=)\s*\"(.*)\"\)?',
-+                     re.UNICODE)
- 
- ACTIONS = ["allow", "deny"]
- 
-@@ -193,6 +194,9 @@ class ACI:
-         self.target['target']['operator'] = operator
- 
-     def set_bindrule(self, bindrule):
-+        if bindrule.startswith('(') != bindrule.endswith(')'):
-+            raise SyntaxError("non-matching parentheses in bindrule")
-+
-         match = BindPat.match(bindrule)
-         if not match or len(match.groups()) < 3:
-             raise SyntaxError, "malformed bind rule"
--- 
-2.4.3
-
diff --git a/SOURCES/0034-Revert-Enable-vault-commands-on-client.patch b/SOURCES/0034-Revert-Enable-vault-commands-on-client.patch
new file mode 100644
index 0000000..9b74d02
--- /dev/null
+++ b/SOURCES/0034-Revert-Enable-vault-commands-on-client.patch
@@ -0,0 +1,65 @@
+From 872e67c0121250dd41e2d6953810582f1e5dda27 Mon Sep 17 00:00:00 2001
+From: Jan Cholasta <jcholast@redhat.com>
+Date: Mon, 25 Jul 2016 14:00:08 +0200
+Subject: [PATCH] Revert "Enable vault-* commands on client"
+
+This reverts commit 9feeaca9fb552229638ce98086aa75905a45b48d.
+
+https://fedorahosted.org/freeipa/ticket/6089
+
+Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
+---
+ ipaclient/plugins/vault.py | 16 ++++++++++++++++
+ 1 file changed, 16 insertions(+)
+
+diff --git a/ipaclient/plugins/vault.py b/ipaclient/plugins/vault.py
+index a3ce6fecbfd38b342f826d8d27940d991d821e90..b7e0cfffb2fff62fdbbf438964d124fc2dd8ac36 100644
+--- a/ipaclient/plugins/vault.py
++++ b/ipaclient/plugins/vault.py
+@@ -202,6 +202,10 @@ class vault_add(Local):
+         ),
+     )
+ 
++    @property
++    def NO_CLI(self):
++        return self.api.Command.vault_add_internal.NO_CLI
++
+     def get_args(self):
+         for arg in self.api.Command.vault_add_internal.args():
+             yield arg
+@@ -395,6 +399,10 @@ class vault_mod(Local):
+         ),
+     )
+ 
++    @property
++    def NO_CLI(self):
++        return self.api.Command.vault_mod_internal.NO_CLI
++
+     def get_args(self):
+         for arg in self.api.Command.vault_mod_internal.args():
+             yield arg
+@@ -569,6 +577,10 @@ class vault_archive(Local):
+         ),
+     )
+ 
++    @property
++    def NO_CLI(self):
++        return self.api.Command.vault_archive_internal.NO_CLI
++
+     def get_args(self):
+         for arg in self.api.Command.vault_archive_internal.args():
+             yield arg
+@@ -813,6 +825,10 @@ class vault_retrieve(Local):
+         ),
+     )
+ 
++    @property
++    def NO_CLI(self):
++        return self.api.Command.vault_retrieve_internal.NO_CLI
++
+     def get_args(self):
+         for arg in self.api.Command.vault_retrieve_internal.args():
+             yield arg
+-- 
+2.7.4
+
diff --git a/SOURCES/0035-ULC-Fix-stageused-add-from-delete-command.patch b/SOURCES/0035-ULC-Fix-stageused-add-from-delete-command.patch
deleted file mode 100644
index 5927ccb..0000000
--- a/SOURCES/0035-ULC-Fix-stageused-add-from-delete-command.patch
+++ /dev/null
@@ -1,46 +0,0 @@
-From c899fa3f5b404e9e28a149cc55684591482344f9 Mon Sep 17 00:00:00 2001
-From: Martin Basti <mbasti@redhat.com>
-Date: Thu, 23 Jul 2015 10:52:54 +0200
-Subject: [PATCH] ULC: Fix stageused-add --from-delete command
-
-Nonexistent method was used to move deleted user to staged area.
-Minor fixes added:
- * handle not found error
- * return new DN
-
-https://fedorahosted.org/freeipa/ticket/5145
-
-Reviewed-By: David Kupka <dkupka@redhat.com>
----
- ipalib/plugins/stageuser.py | 9 +++++----
- 1 file changed, 5 insertions(+), 4 deletions(-)
-
-diff --git a/ipalib/plugins/stageuser.py b/ipalib/plugins/stageuser.py
-index 49a762a922b21bd6d0824787d9305417f5e47ee6..41844712042c4456fc515afd316af60b612f164f 100644
---- a/ipalib/plugins/stageuser.py
-+++ b/ipalib/plugins/stageuser.py
-@@ -377,16 +377,17 @@ class stageuser_add(baseuser_add):
- 
-             staging_dn = self.obj.get_dn(*keys, **options)
-             delete_dn = DN(staging_dn[0], self.obj.delete_container_dn, api.env.basedn)
--
-+            new_dn = DN(staging_dn[0], self.obj.stage_container_dn, api.env.basedn)
-             # Check that this value is a Active user
-             try:
-                 entry_attrs = self._exc_wrapper(keys, options, ldap.get_entry)(delete_dn, ['dn'])
-             except errors.NotFound:
--                raise
--            self._exc_wrapper(keys, options, ldap.move_entry_newsuperior)(delete_dn, str(DN(self.obj.stage_container_dn, api.env.basedn)))
-+                self.obj.handle_not_found(*keys)
- 
-+            self._exc_wrapper(keys, options, ldap.move_entry)(
-+                delete_dn, new_dn)
-             entry_attrs = entry_to_dict(entry_attrs, **options)
--            entry_attrs['dn'] = delete_dn
-+            entry_attrs['dn'] = new_dn
- 
-             if self.obj.primary_key and keys[-1] is not None:
-                 return dict(result=entry_attrs, value=keys[-1])
--- 
-2.4.3
-
diff --git a/SOURCES/0035-client-fix-hiding-of-commands-which-lack-server-supp.patch b/SOURCES/0035-client-fix-hiding-of-commands-which-lack-server-supp.patch
new file mode 100644
index 0000000..6b2b1cd
--- /dev/null
+++ b/SOURCES/0035-client-fix-hiding-of-commands-which-lack-server-supp.patch
@@ -0,0 +1,93 @@
+From a23b8fd488ca33f3e6ffa42530debd6d5d3430ac Mon Sep 17 00:00:00 2001
+From: Jan Cholasta <jcholast@redhat.com>
+Date: Mon, 18 Jul 2016 09:37:24 +0200
+Subject: [PATCH] client: fix hiding of commands which lack server support
+
+Rather than checking the server counterpart's NO_CLI, which may be False
+even for commands supported on the server, check wheter the server
+counterpart is a command defined on the server or a local placeholder.
+
+https://fedorahosted.org/freeipa/ticket/6089
+
+Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
+---
+ ipaclient/plugins/automount.py        |  3 ++-
+ ipaclient/plugins/otptoken_yubikey.py |  3 ++-
+ ipaclient/plugins/vault.py            | 12 ++++++++----
+ 3 files changed, 12 insertions(+), 6 deletions(-)
+
+diff --git a/ipaclient/plugins/automount.py b/ipaclient/plugins/automount.py
+index 8405f9f4fe283d9c068d51e10717fb1396fa44bf..c6537bc6c24b905a8e1f7fb6a7e2c931b95374c7 100644
+--- a/ipaclient/plugins/automount.py
++++ b/ipaclient/plugins/automount.py
+@@ -54,7 +54,8 @@ class _fake_automountlocation_show(Method):
+ class automountlocation_tofiles(MethodOverride):
+     @property
+     def NO_CLI(self):
+-        return self.api.Command.automountlocation_show.NO_CLI
++        return isinstance(self.api.Command.automountlocation_show,
++                          _fake_automountlocation_show)
+ 
+     def output_for_cli(self, textui, result, *keys, **options):
+         maps = result['result']['maps']
+diff --git a/ipaclient/plugins/otptoken_yubikey.py b/ipaclient/plugins/otptoken_yubikey.py
+index 5e0d994628ab997853a80d1f1118ba8ada9993d9..423b670de15dd7f803db1dcbb759bd0254827072 100644
+--- a/ipaclient/plugins/otptoken_yubikey.py
++++ b/ipaclient/plugins/otptoken_yubikey.py
+@@ -76,7 +76,8 @@ class otptoken_add_yubikey(Command):
+ 
+     @property
+     def NO_CLI(self):
+-        return self.api.Command.otptoken_add.NO_CLI
++        return isinstance(self.api.Command.otptoken_add,
++                          _fake_otptoken_add)
+ 
+     def get_args(self):
+         for arg in self.api.Command.otptoken_add.args():
+diff --git a/ipaclient/plugins/vault.py b/ipaclient/plugins/vault.py
+index b7e0cfffb2fff62fdbbf438964d124fc2dd8ac36..e3a1ae3a0ad767bcee843b7fa3743a934e02d18b 100644
+--- a/ipaclient/plugins/vault.py
++++ b/ipaclient/plugins/vault.py
+@@ -204,7 +204,8 @@ class vault_add(Local):
+ 
+     @property
+     def NO_CLI(self):
+-        return self.api.Command.vault_add_internal.NO_CLI
++        return isinstance(self.api.Command.vault_add_internal,
++                          _fake_vault_add_internal)
+ 
+     def get_args(self):
+         for arg in self.api.Command.vault_add_internal.args():
+@@ -401,7 +402,8 @@ class vault_mod(Local):
+ 
+     @property
+     def NO_CLI(self):
+-        return self.api.Command.vault_mod_internal.NO_CLI
++        return isinstance(self.api.Command.vault_mod_internal,
++                          _fake_vault_mod_internal)
+ 
+     def get_args(self):
+         for arg in self.api.Command.vault_mod_internal.args():
+@@ -579,7 +581,8 @@ class vault_archive(Local):
+ 
+     @property
+     def NO_CLI(self):
+-        return self.api.Command.vault_archive_internal.NO_CLI
++        return isinstance(self.api.Command.vault_archive_internal,
++                          _fake_vault_archive_internal)
+ 
+     def get_args(self):
+         for arg in self.api.Command.vault_archive_internal.args():
+@@ -827,7 +830,8 @@ class vault_retrieve(Local):
+ 
+     @property
+     def NO_CLI(self):
+-        return self.api.Command.vault_retrieve_internal.NO_CLI
++        return isinstance(self.api.Command.vault_retrieve_internal,
++                          _fake_vault_retrieve_internal)
+ 
+     def get_args(self):
+         for arg in self.api.Command.vault_retrieve_internal.args():
+-- 
+2.7.4
+
diff --git a/SOURCES/0036-Minor-fix-in-ipa-replica-manage-MAN-page.patch b/SOURCES/0036-Minor-fix-in-ipa-replica-manage-MAN-page.patch
new file mode 100644
index 0000000..76b1fca
--- /dev/null
+++ b/SOURCES/0036-Minor-fix-in-ipa-replica-manage-MAN-page.patch
@@ -0,0 +1,51 @@
+From 1087492c74ed4f823c49314454b9db8bddf29ed2 Mon Sep 17 00:00:00 2001
+From: Abhijeet Kasurde <akasurde@redhat.com>
+Date: Tue, 12 Jul 2016 17:08:06 +0530
+Subject: [PATCH] Minor fix in ipa-replica-manage MAN page
+
+Fixes: https://fedorahosted.org/freeipa/ticket/6058
+
+Signed-off-by: Abhijeet Kasurde <akasurde@redhat.com>
+Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
+---
+ install/tools/man/ipa-replica-manage.1 | 14 +++++++-------
+ 1 file changed, 7 insertions(+), 7 deletions(-)
+
+diff --git a/install/tools/man/ipa-replica-manage.1 b/install/tools/man/ipa-replica-manage.1
+index 68be0232fae9309b108e69f9144501be3277f503..34cd314a517ae2f74da7bc87d6336e62d7b57118 100644
+--- a/install/tools/man/ipa-replica-manage.1
++++ b/install/tools/man/ipa-replica-manage.1
+@@ -16,7 +16,7 @@
+ .\"
+ .\" Author: Rob Crittenden <rcritten@redhat.com>
+ .\"
+-.TH "ipa-replica-manage" "1" "Mar 1 2013" "FreeIPA" "FreeIPA Manual Pages"
++.TH "ipa-replica-manage" "1" "Jul 12 2016" "FreeIPA" "FreeIPA Manual Pages"
+ .SH "NAME"
+ ipa\-replica\-manage \- Manage an IPA replica
+ .SH "SYNOPSIS"
+@@ -163,15 +163,15 @@ Performing range changes as a delegated administrator (e.g. not using the Direct
+ .TP
+ List all masters:
+  # ipa\-replica\-manage list
+- srv1.example.com
+- srv2.example.com
+- srv3.example.com
+- srv4.example.com
++ srv1.example.com: master
++ srv2.example.com: master
++ srv3.example.com: master
++ srv4.example.com: master
+ .TP
+ List a server's replication agreements.
+  # ipa\-replica\-manage list srv1.example.com
+- srv2.example.com
+- srv3.example.com
++ srv2.example.com: replica
++ srv3.example.com: replica
+ .TP
+ Re\-initialize a replica:
+  # ipa\-replica\-manage re\-initialize \-\-from srv2.example.com
+-- 
+2.7.4
+
diff --git a/SOURCES/0036-webui-fix-regressions-failed-auth-messages.patch b/SOURCES/0036-webui-fix-regressions-failed-auth-messages.patch
deleted file mode 100644
index ea69c48..0000000
--- a/SOURCES/0036-webui-fix-regressions-failed-auth-messages.patch
+++ /dev/null
@@ -1,79 +0,0 @@
-From 4c1b511fbcdca211c913a4db409c66469cdc3a4f Mon Sep 17 00:00:00 2001
-From: Petr Vobornik <pvoborni@redhat.com>
-Date: Tue, 28 Jul 2015 14:01:34 +0200
-Subject: [PATCH] webui: fix regressions failed auth messages
-
-1. after logout, krb auth no longer shows "session expired" but correct
-"Authentication with Kerberos failed".
-
-2. "The password or username you entered is incorrect." is showed on
-failed forms-based auth.
-
-https://fedorahosted.org/freeipa/ticket/5163
-
-Reviewed-By: Martin Basti <mbasti@redhat.com>
----
- install/ui/src/freeipa/ipa.js                 | 8 ++++----
- install/ui/src/freeipa/widgets/LoginScreen.js | 2 +-
- 2 files changed, 5 insertions(+), 5 deletions(-)
-
-diff --git a/install/ui/src/freeipa/ipa.js b/install/ui/src/freeipa/ipa.js
-index 75dd73c379815a0e0e1dc2c4d786fdcf3be7c1b0..eaaaaf7fcfaee873d97d96630b72365ecffe6b08 100644
---- a/install/ui/src/freeipa/ipa.js
-+++ b/install/ui/src/freeipa/ipa.js
-@@ -32,6 +32,7 @@ define([
-         './json2',
-         './_base/i18n',
-         './auth',
-+        './config',
-         './datetime',
-         './metadata',
-         './builder',
-@@ -41,7 +42,8 @@ define([
-         './util',
-         'exports'
-     ], function(declare, Deferred, Evented, keys, topic, $, JSON, i18n, auth,
--        datetime, metadata_provider, builder, reg, rpc, text, util, exports) {
-+        config, datetime, metadata_provider, builder, reg, rpc, text,
-+        util, exports) {
- 
- /**
-  * @class
-@@ -127,11 +129,9 @@ var IPA = function () {
-         // if current path matches live server path, use live data
-         if (that.url && window.location.pathname.substring(0, that.url.length) === that.url) {
-             that.json_url = params.url || '/ipa/session/json';
--            that.login_url = params.url || '/ipa/session/login_kerberos';
- 
-         } else { // otherwise use fixtures
-             that.json_path = params.url || "test/data";
--            // that.login_url is not needed for fixtures
-         }
- 
-         $.ajaxSetup(that.ajax_options);
-@@ -377,7 +377,7 @@ IPA.get_credentials = function() {
-     }
- 
-     var request = {
--        url: IPA.login_url,
-+        url: config.krb_login_url,
-         cache: false,
-         type: "GET",
-         success: success_handler,
-diff --git a/install/ui/src/freeipa/widgets/LoginScreen.js b/install/ui/src/freeipa/widgets/LoginScreen.js
-index fb7ccccc6c34d9c1c7115dd95809f3a39de488eb..eb95b9161f05eeac1ec9aed286c9730dada85d59 100644
---- a/install/ui/src/freeipa/widgets/LoginScreen.js
-+++ b/install/ui/src/freeipa/widgets/LoginScreen.js
-@@ -232,8 +232,8 @@ define(['dojo/_base/declare',
-                     this.set('view', 'reset');
-                     val_summary.add_info('login', this.password_expired);
-                 } else {
--                    val_summary.add_error('login', this.form_auth_failed);
-                     password_f.set_value('');
-+                    val_summary.add_error('login', this.form_auth_failed);
-                 }
-             }));
-         },
--- 
-2.4.3
-
diff --git a/SOURCES/0037-Validate-vault-s-file-parameters.patch b/SOURCES/0037-Validate-vault-s-file-parameters.patch
deleted file mode 100644
index c6b18d3..0000000
--- a/SOURCES/0037-Validate-vault-s-file-parameters.patch
+++ /dev/null
@@ -1,139 +0,0 @@
-From f5cf88337d6f775df4a311469b869921bbc90f05 Mon Sep 17 00:00:00 2001
-From: Christian Heimes <cheimes@redhat.com>
-Date: Thu, 30 Jul 2015 15:48:40 +0200
-Subject: [PATCH] Validate vault's file parameters
-
-A user can pass file names for password, public and private key files to
-the vault plugin. The plugin attempts to read from these files. If any
-file can't be, an internal error was raised. The patch wraps all reads
-and turns any IOError and UnicodeError into a ValidationError.
-
-https://fedorahosted.org/freeipa/ticket/5155
-
-Reviewed-By: Martin Basti <mbasti@redhat.com>
----
- ipalib/plugins/vault.py | 59 +++++++++++++++++++++++++++++++++++++++----------
- 1 file changed, 47 insertions(+), 12 deletions(-)
-
-diff --git a/ipalib/plugins/vault.py b/ipalib/plugins/vault.py
-index 37a32282e7a4e87889eea90d987b737f98fd82c3..fe4eec325dde4a9ecd8a7ce5af1a124fc5c6a9ae 100644
---- a/ipalib/plugins/vault.py
-+++ b/ipalib/plugins/vault.py
-@@ -19,6 +19,7 @@
- 
- import base64
- import getpass
-+import io
- import json
- import os
- import sys
-@@ -210,6 +211,33 @@ EXAMPLES:
-    ipa vault-remove-member <name> --users <usernames>
- """)
- 
-+
-+def validated_read(argname, filename, mode='r', encoding=None):
-+    """Read file and catch errors
-+
-+    IOError and UnicodeError (for text files) are turned into a
-+    ValidationError
-+    """
-+    try:
-+        with io.open(filename, mode=mode, encoding=encoding) as f:
-+            data = f.read()
-+    except IOError as exc:
-+        raise errors.ValidationError(
-+            name=argname,
-+            error=_("Cannot read file '%(filename)s': %(exc)s") % {
-+                'filename': filename, 'exc': exc[1]
-+                }
-+        )
-+    except UnicodeError as exc:
-+        raise errors.ValidationError(
-+            name=argname,
-+            error=_("Cannot decode file '%(filename)s': %(exc)s") % {
-+                'filename': filename, 'exc': exc
-+                }
-+        )
-+    return data
-+
-+
- register = Registry()
- 
- 
-@@ -591,8 +619,10 @@ class vault_add(PKQuery, Local):
-                 pass
- 
-             elif password_file:
--                with open(password_file, 'rb') as f:
--                    password = f.read().rstrip('\n').decode('utf-8')
-+                password = validated_read('password-file',
-+                                          password_file,
-+                                          encoding='utf-8')
-+                password = password.rstrip('\n')
- 
-             else:
-                 password = self.obj.get_new_password()
-@@ -611,8 +641,9 @@ class vault_add(PKQuery, Local):
-                 pass
- 
-             elif public_key_file:
--                with open(public_key_file, 'rb') as f:
--                    public_key = f.read()
-+                public_key = validated_read('public-key-file',
-+                                            public_key_file,
-+                                            mode='rb')
- 
-                 # store vault public key
-                 options['ipavaultpublickey'] = public_key
-@@ -904,8 +935,7 @@ class vault_archive(PKQuery, Local):
-                 reason=_('Input data specified multiple times'))
- 
-         elif input_file:
--            with open(input_file, 'rb') as f:
--                data = f.read()
-+            data = validated_read('in', input_file, mode='rb')
- 
-         elif not data:
-             data = ''
-@@ -937,8 +967,10 @@ class vault_archive(PKQuery, Local):
-                 pass
- 
-             elif password_file:
--                with open(password_file) as f:
--                    password = f.read().rstrip('\n').decode('utf-8')
-+                password = validated_read('password-file',
-+                                          password_file,
-+                                          encoding='utf-8')
-+                password = password.rstrip('\n')
- 
-             else:
-                 password = self.obj.get_existing_password()
-@@ -1254,8 +1286,10 @@ class vault_retrieve(PKQuery, Local):
-                 pass
- 
-             elif password_file:
--                with open(password_file) as f:
--                    password = f.read().rstrip('\n').decode('utf-8')
-+                password = validated_read('password-file',
-+                                          password_file,
-+                                          encoding='utf-8')
-+                password = password.rstrip('\n')
- 
-             else:
-                 password = self.obj.get_existing_password()
-@@ -1277,8 +1311,9 @@ class vault_retrieve(PKQuery, Local):
-                 pass
- 
-             elif private_key_file:
--                with open(private_key_file, 'rb') as f:
--                    private_key = f.read()
-+                private_key = validated_read('private-key-file',
-+                                             private_key_file,
-+                                             mode='rb')
- 
-             else:
-                 raise errors.ValidationError(
--- 
-2.4.3
-
diff --git a/SOURCES/0037-compat-fix-ping-call.patch b/SOURCES/0037-compat-fix-ping-call.patch
new file mode 100644
index 0000000..ce000c1
--- /dev/null
+++ b/SOURCES/0037-compat-fix-ping-call.patch
@@ -0,0 +1,31 @@
+From f557f7487d9aae0c901a740b9a446568677b8bb3 Mon Sep 17 00:00:00 2001
+From: Jan Cholasta <jcholast@redhat.com>
+Date: Mon, 25 Jul 2016 15:58:20 +0200
+Subject: [PATCH] compat: fix ping call
+
+Copy & paste accident caused the ping command to be called with an unwanted
+argument, which results in an exception.
+
+Remove the argument to fix it.
+
+https://fedorahosted.org/freeipa/ticket/6129
+---
+ ipaclient/remote_plugins/compat.py | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/ipaclient/remote_plugins/compat.py b/ipaclient/remote_plugins/compat.py
+index 40521af450aafca83f33d1723b4fd9e27ef8d96f..aef5718fcaade157487c0e65562c3bc8a11ad7de 100644
+--- a/ipaclient/remote_plugins/compat.py
++++ b/ipaclient/remote_plugins/compat.py
+@@ -39,7 +39,7 @@ def get_package(api, client):
+     try:
+         server_version = env['result']['api_version']
+     except KeyError:
+-        ping = client.forward(u'ping', u'api_version', version=u'2.0')
++        ping = client.forward(u'ping', version=u'2.0')
+         try:
+             match = re.search(u'API version (2\.[0-9]+)', ping['summary'])
+         except KeyError:
+-- 
+2.7.4
+
diff --git a/SOURCES/0038-certprofile-import-do-not-require-profileId-in-profi.patch b/SOURCES/0038-certprofile-import-do-not-require-profileId-in-profi.patch
deleted file mode 100644
index 57f8aa1..0000000
--- a/SOURCES/0038-certprofile-import-do-not-require-profileId-in-profi.patch
+++ /dev/null
@@ -1,58 +0,0 @@
-From ae5939600d367172a1e830c87254d2fc1bb56fe8 Mon Sep 17 00:00:00 2001
-From: Christian Heimes <cheimes@redhat.com>
-Date: Thu, 23 Jul 2015 17:48:56 +0200
-Subject: [PATCH] certprofile-import: do not require profileId in profile data
-
-certprofile-import no longer requires profileId in profile data. Instead
-the profile ID from the command line is taken and added to the profile
-data internally.
-
-If profileId is set in the profile, then it still has to match the CLI
-option.
-
-https://fedorahosted.org/freeipa/ticket/5090
-
-Reviewed-By: Martin Basti <mbasti@redhat.com>
----
- ipalib/plugins/certprofile.py | 8 +++++---
- 1 file changed, 5 insertions(+), 3 deletions(-)
-
-diff --git a/ipalib/plugins/certprofile.py b/ipalib/plugins/certprofile.py
-index 5550ed942521dbab2e783fba1570520268f9b378..b0b76ca8e78f2482b5c08dad21d9161fd4c2c2d0 100644
---- a/ipalib/plugins/certprofile.py
-+++ b/ipalib/plugins/certprofile.py
-@@ -11,6 +11,7 @@ from ipalib.plugins.virtual import VirtualCommand
- from ipalib.plugins.baseldap import (
-     LDAPObject, LDAPSearch, LDAPCreate,
-     LDAPDelete, LDAPUpdate, LDAPRetrieve)
-+from ipalib.request import context
- from ipalib import ngettext
- from ipalib.text import _
- from ipapython.version import API_VERSION
-@@ -230,11 +231,12 @@ class certprofile_import(LDAPCreate):
- 
-     def pre_callback(self, ldap, dn, entry, entry_attrs, *keys, **options):
-         ca_enabled_check()
-+        context.profile = options['file']
- 
-         match = self.PROFILE_ID_PATTERN.search(options['file'])
-         if match is None:
--            raise errors.ValidationError(name='file',
--                error=_("Profile ID is not present in profile data"))
-+            # no profileId found, use CLI value as profileId.
-+            context.profile = u'profileId=%s\n%s' % (keys[0], context.profile)
-         elif keys[0] != match.group(1):
-             raise errors.ValidationError(name='file',
-                 error=_("Profile ID '%(cli_value)s' does not match profile data '%(file_value)s'")
-@@ -250,7 +252,7 @@ class certprofile_import(LDAPCreate):
-         """
-         try:
-             with self.api.Backend.ra_certprofile as profile_api:
--                profile_api.create_profile(options['file'])
-+                profile_api.create_profile(context.profile)
-                 profile_api.enable_profile(keys[0])
-         except:
-             # something went wrong ; delete entry
--- 
-2.4.3
-
diff --git a/SOURCES/0038-replica-install-Fix-domain.patch b/SOURCES/0038-replica-install-Fix-domain.patch
new file mode 100644
index 0000000..20d2325
--- /dev/null
+++ b/SOURCES/0038-replica-install-Fix-domain.patch
@@ -0,0 +1,71 @@
+From 42c09751aedf6289f983d4238ae1ff3b44b5f572 Mon Sep 17 00:00:00 2001
+From: Petr Spacek <pspacek@redhat.com>
+Date: Mon, 25 Jul 2016 15:54:43 +0200
+Subject: [PATCH] replica-install: Fix --domain
+
+Replica installation must not check existence of --domain - the domain
+must (logically) exist.
+
+https://fedorahosted.org/freeipa/ticket/6130
+
+Reviewed-By: Jan Cholasta <jcholast@redhat.com>
+---
+ ipaserver/install/server/common.py  |  5 -----
+ ipaserver/install/server/install.py | 14 +++++++++++---
+ 2 files changed, 11 insertions(+), 8 deletions(-)
+
+diff --git a/ipaserver/install/server/common.py b/ipaserver/install/server/common.py
+index 45fb2dc17976a08acab16783584524721411fb4e..e6093d15cd1067a83ed89945c4a9c983c66ec06f 100644
+--- a/ipaserver/install/server/common.py
++++ b/ipaserver/install/server/common.py
+@@ -284,11 +284,6 @@ class BaseServer(common.Installable, common.Interactive, core.Composite):
+     @domain_name.validator
+     def domain_name(self, value):
+         validate_domain_name(value)
+-        if (self.setup_dns and
+-                not self.dns.allow_zone_overlap):  # pylint: disable=no-member
+-            print("Checking DNS domain %s, please wait ..." % value)
+-            check_zone_overlap(value, False)
+-
+ 
+     dm_password = Knob(
+         str, None,
+diff --git a/ipaserver/install/server/install.py b/ipaserver/install/server/install.py
+index c0c676b870b481696ae75742c7bf88074b0ecf9c..65f9318201e648b30a3c13626e807ac6f3a9416d 100644
+--- a/ipaserver/install/server/install.py
++++ b/ipaserver/install/server/install.py
+@@ -17,6 +17,7 @@ import six
+ 
+ from ipapython import certmonger, ipaldap, ipautil, sysrestore
+ from ipapython.dn import DN
++from ipapython.dnsutil import check_zone_overlap
+ from ipapython.install import core
+ from ipapython.install.common import step
+ from ipapython.install.core import Knob
+@@ -1199,13 +1200,20 @@ class ServerCA(BaseServerCA):
+ 
+ 
+ class Server(BaseServer):
+-    realm_name = Knob(BaseServer.realm_name)
+-    domain_name = Knob(BaseServer.domain_name)
+-
+     setup_ca = None
+     setup_kra = None
+     setup_dns = Knob(BaseServer.setup_dns)
+ 
++    realm_name = Knob(BaseServer.realm_name)
++    domain_name = Knob(BaseServer.domain_name)
++
++    @domain_name.validator
++    def domain_name(self, value):
++        if (self.setup_dns and
++                not self.dns.allow_zone_overlap):  # pylint: disable=no-member
++            print("Checking DNS domain %s, please wait ..." % value)
++            check_zone_overlap(value, False)
++
+     dm_password = Knob(
+         BaseServer.dm_password,
+         description="Directory Manager password",
+-- 
+2.7.4
+
diff --git a/SOURCES/0039-idrange-fix-unassigned-global-variable.patch b/SOURCES/0039-idrange-fix-unassigned-global-variable.patch
new file mode 100644
index 0000000..731295d
--- /dev/null
+++ b/SOURCES/0039-idrange-fix-unassigned-global-variable.patch
@@ -0,0 +1,33 @@
+From 89bfc7c0a4b08c873e5c8b8dfad54cf895b742cd Mon Sep 17 00:00:00 2001
+From: Martin Basti <mbasti@redhat.com>
+Date: Fri, 29 Jul 2016 16:46:09 +0200
+Subject: [PATCH] idrange: fix unassigned global variable
+
+Global variable '_dcerpc_bindings_installed' is in some cases used
+before assigment. This patch ensures that _dcerpc_bindings_installed is
+always initialized.
+
+https://fedorahosted.org/freeipa/ticket/6082
+
+Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
+---
+ ipaserver/plugins/idrange.py | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/ipaserver/plugins/idrange.py b/ipaserver/plugins/idrange.py
+index ccd67995e5b42634387e1064e7c819b711f3ef99..3e9db0b6b734513547423901a8b3212b3cee9147 100644
+--- a/ipaserver/plugins/idrange.py
++++ b/ipaserver/plugins/idrange.py
+@@ -35,6 +35,9 @@ if api.env.in_server and api.env.context in ['lite', 'server']:
+         _dcerpc_bindings_installed = True
+     except ImportError:
+         _dcerpc_bindings_installed = False
++else:
++    _dcerpc_bindings_installed = False
++
+ 
+ ID_RANGE_VS_DNA_WARNING = """=======
+ WARNING:
+-- 
+2.7.4
+
diff --git a/SOURCES/0039-user-show-add-out-option-to-save-certificates-to-fil.patch b/SOURCES/0039-user-show-add-out-option-to-save-certificates-to-fil.patch
deleted file mode 100644
index 94d2fb8..0000000
--- a/SOURCES/0039-user-show-add-out-option-to-save-certificates-to-fil.patch
+++ /dev/null
@@ -1,109 +0,0 @@
-From 52ddaafcac7ace012535ac7044b301ad3a7d7b9a Mon Sep 17 00:00:00 2001
-From: Fraser Tweedale <ftweedal@redhat.com>
-Date: Fri, 24 Jul 2015 09:31:26 -0400
-Subject: [PATCH] user-show: add --out option to save certificates to file
-
-Add the --out option to user-show, bringing it into line with
-host-show and service-show with the ability to save the user's
-certificate(s) to a file.
-
-https://fedorahosted.org/freeipa/ticket/5171
-
-Reviewed-By: Martin Basti <mbasti@redhat.com>
----
- API.txt                |  3 ++-
- VERSION                |  4 ++--
- ipalib/plugins/user.py | 27 ++++++++++++++++++++++++++-
- 3 files changed, 30 insertions(+), 4 deletions(-)
-
-diff --git a/API.txt b/API.txt
-index 6ab30ddab41715fdbccb4f37aa1852621bca62b4..2e19d6b2f1e16cc1c89d71ed7d443145426a28e3 100644
---- a/API.txt
-+++ b/API.txt
-@@ -5360,10 +5360,11 @@ output: Entry('result', <type 'dict'>, Gettext('A dictionary representing an LDA
- output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
- output: PrimaryKey('value', None, None)
- command: user_show
--args: 1,5,3
-+args: 1,6,3
- arg: Str('uid', attribute=True, cli_name='login', maxlength=255, multivalue=False, pattern='^[a-zA-Z0-9_.][a-zA-Z0-9_.-]{0,252}[a-zA-Z0-9_.$-]?$', primary_key=True, query=True, required=True)
- option: Flag('all', autofill=True, cli_name='all', default=False, exclude='webui')
- option: Flag('no_members', autofill=True, default=False, exclude='webui')
-+option: Str('out?')
- option: Flag('raw', autofill=True, cli_name='raw', default=False, exclude='webui')
- option: Flag('rights', autofill=True, default=False)
- option: Str('version?', exclude='webui')
-diff --git a/VERSION b/VERSION
-index 678d1f8a7e588d480b16441e12e4d527d9c1cd98..ca43f3e0c06880d355c068514134187c5edda175 100644
---- a/VERSION
-+++ b/VERSION
-@@ -90,5 +90,5 @@ IPA_DATA_VERSION=20100614120000
- #                                                      #
- ########################################################
- IPA_API_VERSION_MAJOR=2
--IPA_API_VERSION_MINOR=147
--# Last change: mbasti - Consolidate DNS RR in API and schema
-+IPA_API_VERSION_MINOR=148
-+# Last change: ftweedal - add --out option to user-show
-diff --git a/ipalib/plugins/user.py b/ipalib/plugins/user.py
-index 206b380efb6472fb040dde33ac80e3f66c00c138..0209b29b130f2377c04f497f95c8ad39e98f2587 100644
---- a/ipalib/plugins/user.py
-+++ b/ipalib/plugins/user.py
-@@ -23,7 +23,7 @@ import string
- import posixpath
- import os
- 
--from ipalib import api, errors
-+from ipalib import api, errors, util
- from ipalib import Flag, Int, Password, Str, Bool, StrEnum, DateTime
- from ipalib.plugins.baseuser import baseuser, baseuser_add, baseuser_del, \
-     baseuser_mod, baseuser_find, baseuser_show, \
-@@ -38,6 +38,7 @@ from ipalib.plugins import baseldap
- from ipalib.request import context
- from ipalib import _, ngettext
- from ipalib import output
-+from ipalib import x509
- from ipaplatform.paths import paths
- from ipapython.ipautil import ipa_generate_password
- from ipapython.ipavalidate import Email
-@@ -765,6 +766,11 @@ class user_show(baseuser_show):
-     __doc__ = _('Display information about a user.')
- 
-     has_output_params = baseuser_show.has_output_params + user_output_params
-+    takes_options = baseuser_show.takes_options + (
-+        Str('out?',
-+            doc=_('file to store certificate in'),
-+        ),
-+    )
- 
-     def post_callback(self, ldap, dn, entry_attrs, *keys, **options):
-         convert_nsaccountlock(entry_attrs)
-@@ -772,6 +778,25 @@ class user_show(baseuser_show):
-         self.obj.get_preserved_attribute(entry_attrs, options)
-         return dn
- 
-+    def forward(self, *keys, **options):
-+        if 'out' in options:
-+            util.check_writable_file(options['out'])
-+            result = super(user_show, self).forward(*keys, **options)
-+            if 'usercertificate' in result['result']:
-+                x509.write_certificate_list(
-+                    result['result']['usercertificate'],
-+                    options['out']
-+                )
-+                result['summary'] = (
-+                    _('Certificate(s) stored in file \'%(file)s\'')
-+                    % dict(file=options['out'])
-+                )
-+                return result
-+            else:
-+                raise errors.NoCertificateError(entry=keys[-1])
-+        else:
-+            return super(user_show, self).forward(*keys, **options)
-+
- @register()
- class user_undel(LDAPQuery):
-     __doc__ = _('Undelete a delete user account.')
--- 
-2.4.3
-
diff --git a/SOURCES/0040-re-set-canonical-principal-name-on-migrated-users.patch b/SOURCES/0040-re-set-canonical-principal-name-on-migrated-users.patch
new file mode 100644
index 0000000..bc6f486
--- /dev/null
+++ b/SOURCES/0040-re-set-canonical-principal-name-on-migrated-users.patch
@@ -0,0 +1,86 @@
+From 1dfba16f6d46a2811d0230f28abf0ea4621bfde2 Mon Sep 17 00:00:00 2001
+From: Martin Babinsky <mbabinsk@redhat.com>
+Date: Thu, 28 Jul 2016 10:42:58 +0200
+Subject: [PATCH] re-set canonical principal name on migrated users
+
+The migration procedure has been updated to re-set `krbcanonicalname`
+attribute on migrated users as well as `krbprincipalname` so that migration
+from FreeIPA versions supporting principal aliases does not break subsequent
+authentication of migrated users.
+
+https://fedorahosted.org/freeipa/ticket/6101
+
+Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
+---
+ ipaserver/plugins/migration.py | 41 ++++++++++++++++++++++++++++-------------
+ 1 file changed, 28 insertions(+), 13 deletions(-)
+
+diff --git a/ipaserver/plugins/migration.py b/ipaserver/plugins/migration.py
+index 7f634a7ccf8c49a4c8e0cc3fe2b2dce84b5cadff..404c4aeb08ff2ee018799af3a9224bec93c26f82 100644
+--- a/ipaserver/plugins/migration.py
++++ b/ipaserver/plugins/migration.py
+@@ -36,6 +36,7 @@ if api.env.in_server and api.env.context in ['lite', 'server']:
+ from ipalib import _
+ from ipapython.dn import DN
+ from ipapython.ipautil import write_tmp_file
++from ipapython.kerberos import Principal
+ import datetime
+ from ipaplatform.paths import paths
+ 
+@@ -152,6 +153,32 @@ _supported_scopes = {u'base': SCOPE_BASE, u'onelevel': SCOPE_ONELEVEL, u'subtree
+ _default_scope = u'onelevel'
+ 
+ 
++def _create_kerberos_principals(ldap, pkey, entry_attrs, failed):
++    """
++    Create 'krbprincipalname' and 'krbcanonicalname' attributes for incoming
++    user entry or skip it if there already is a user with such principal name.
++    The code does not search for `krbcanonicalname` since we assume that the
++    canonical principal name is always contained among values of
++    `krbprincipalname` attribute.Both `krbprincipalname` and `krbcanonicalname`
++    are set to default value generated from uid and realm.
++
++    Note: the migration does not currently preserve principal aliases
++    """
++    principal = Principal((pkey,), realm=api.env.realm)
++    try:
++        ldap.find_entry_by_attr(
++            'krbprincipalname', principal, 'krbprincipalaux', [''],
++            DN(api.env.container_user, api.env.basedn)
++        )
++    except errors.NotFound:
++        entry_attrs['krbprincipalname'] = principal
++        entry_attrs['krbcanonicalname'] = principal
++    except errors.LimitsExceeded:
++        failed[pkey] = unicode(_krb_failed_msg % unicode(principal))
++    else:
++        failed[pkey] = unicode(_krb_err_msg % unicode(principal))
++
++
+ def _pre_migrate_user(ldap, pkey, dn, entry_attrs, failed, config, ctx, **kwargs):
+     assert isinstance(dn, DN)
+     attr_blacklist = ['krbprincipalkey','memberofindirect','memberindirect']
+@@ -217,19 +244,7 @@ def _pre_migrate_user(ldap, pkey, dn, entry_attrs, failed, config, ctx, **kwargs
+             except ValueError:  # object class not present
+                 pass
+ 
+-    # generate a principal name and check if it isn't already taken
+-    principal = u'%s@%s' % (pkey, api.env.realm)
+-    try:
+-        ldap.find_entry_by_attr(
+-            'krbprincipalname', principal, 'krbprincipalaux', [''],
+-            DN(api.env.container_user, api.env.basedn)
+-        )
+-    except errors.NotFound:
+-        entry_attrs['krbprincipalname'] = principal
+-    except errors.LimitsExceeded:
+-        failed[pkey] = unicode(_krb_failed_msg % principal)
+-    else:
+-        failed[pkey] = unicode(_krb_err_msg % principal)
++    _create_kerberos_principals(ldap, pkey, entry_attrs, failed)
+ 
+     # Fix any attributes with DN syntax that point to entries in the old
+     # tree
+-- 
+2.7.4
+
diff --git a/SOURCES/0040-store-certificates-issued-for-user-entries-as-userCe.patch b/SOURCES/0040-store-certificates-issued-for-user-entries-as-userCe.patch
deleted file mode 100644
index c284618..0000000
--- a/SOURCES/0040-store-certificates-issued-for-user-entries-as-userCe.patch
+++ /dev/null
@@ -1,158 +0,0 @@
-From 180f571e60aaedaacdaa272d2a34719ce0ce0565 Mon Sep 17 00:00:00 2001
-From: Martin Babinsky <mbabinsk@redhat.com>
-Date: Mon, 3 Aug 2015 13:36:29 +0200
-Subject: [PATCH] store certificates issued for user entries as
- userCertificate;binary
-
-This patch forces the user management CLI command to store certificates as
-userCertificate;binary attribute. The code to retrieve of user information was
-modified to enable outputting of userCertificate;binary attribute to the
-command line.
-
-The modification also fixes https://fedorahosted.org/freeipa/ticket/5173
-
-Reviewed-By: Jan Cholasta <jcholast@redhat.com>
----
- ipalib/plugins/baseuser.py | 23 ++++++++++++++++++++++-
- ipalib/plugins/user.py     | 21 +++++++++------------
- 2 files changed, 31 insertions(+), 13 deletions(-)
-
-diff --git a/ipalib/plugins/baseuser.py b/ipalib/plugins/baseuser.py
-index bd66cf5a3e3a4e6c18d1a54408f969668c834fab..5eede7a98e7e6d9bf31a6d553b0ce60c7cf3527c 100644
---- a/ipalib/plugins/baseuser.py
-+++ b/ipalib/plugins/baseuser.py
-@@ -187,7 +187,7 @@ class baseuser(LDAPObject):
-         'telephonenumber', 'title', 'memberof', 'nsaccountlock',
-         'memberofindirect', 'ipauserauthtype', 'userclass',
-         'ipatokenradiusconfiglink', 'ipatokenradiususername',
--        'krbprincipalexpiration', 'usercertificate',
-+        'krbprincipalexpiration', 'usercertificate;binary',
-     ]
-     search_display_attributes = [
-         'uid', 'givenname', 'sn', 'homedirectory', 'loginshell',
-@@ -465,10 +465,27 @@ class baseuser(LDAPObject):
-         assert isinstance(user, DN)
-         return self._user_status(user, DN(self.delete_container_dn, api.env.basedn))
- 
-+    def convert_usercertificate_pre(self, entry_attrs):
-+        if 'usercertificate' in entry_attrs:
-+            entry_attrs['usercertificate;binary'] = entry_attrs.pop(
-+                'usercertificate')
-+
-+    def convert_usercertificate_post(self, entry_attrs, **options):
-+        if 'usercertificate;binary' in entry_attrs:
-+            entry_attrs['usercertificate'] = entry_attrs.pop(
-+                'usercertificate;binary')
-+
- class baseuser_add(LDAPCreate):
-     """
-     Prototype command plugin to be implemented by real plugin
-     """
-+    def pre_common_callback(self, ldap, dn, entry_attrs, **options):
-+        assert isinstance(dn, DN)
-+        self.obj.convert_usercertificate_pre(entry_attrs)
-+
-+    def post_common_callback(self, ldap, dn, entry_attrs, **options):
-+        assert isinstance(dn, DN)
-+        self.obj.convert_usercertificate_post(entry_attrs, **options)
- 
- class baseuser_del(LDAPDelete):
-     """
-@@ -542,6 +559,7 @@ class baseuser_mod(LDAPUpdate):
-         self.check_userpassword(entry_attrs, **options)
- 
-         self.check_objectclass(ldap, dn, entry_attrs)
-+        self.obj.convert_usercertificate_pre(entry_attrs)
- 
-     def post_common_callback(self, ldap, dn, entry_attrs, **options):
-         assert isinstance(dn, DN)
-@@ -554,6 +572,7 @@ class baseuser_mod(LDAPUpdate):
-         convert_nsaccountlock(entry_attrs)
-         self.obj.convert_manager(entry_attrs, **options)
-         self.obj.get_password_attributes(ldap, dn, entry_attrs)
-+        self.obj.convert_usercertificate_post(entry_attrs, **options)
-         convert_sshpubkey_post(ldap, dn, entry_attrs)
-         radius_dn2pk(self.api, entry_attrs)
- 
-@@ -584,6 +603,7 @@ class baseuser_find(LDAPSearch):
-         for attrs in entries:
-             self.obj.convert_manager(attrs, **options)
-             self.obj.get_password_attributes(ldap, attrs.dn, attrs)
-+            self.obj.convert_usercertificate_post(attrs, **options)
-             if (lockout):
-                 attrs['nsaccountlock'] = True
-             else:
-@@ -598,5 +618,6 @@ class baseuser_show(LDAPRetrieve):
-         assert isinstance(dn, DN)
-         self.obj.convert_manager(entry_attrs, **options)
-         self.obj.get_password_attributes(ldap, dn, entry_attrs)
-+        self.obj.convert_usercertificate_post(entry_attrs, **options)
-         convert_sshpubkey_post(ldap, dn, entry_attrs)
-         radius_dn2pk(self.api, entry_attrs)
-diff --git a/ipalib/plugins/user.py b/ipalib/plugins/user.py
-index 0209b29b130f2377c04f497f95c8ad39e98f2587..859939205f903fa4832524c8d2601141f3674bb5 100644
---- a/ipalib/plugins/user.py
-+++ b/ipalib/plugins/user.py
-@@ -510,6 +510,8 @@ class user_add(baseuser_add):
-             answer = self.api.Object['radiusproxy'].get_dn_if_exists(rcl)
-             entry_attrs['ipatokenradiusconfiglink'] = answer
- 
-+        self.pre_common_callback(ldap, dn, entry_attrs, **options)
-+
-         return dn
- 
-     def post_callback(self, ldap, dn, entry_attrs, *keys, **options):
-@@ -557,6 +559,9 @@ class user_add(baseuser_add):
-         convert_sshpubkey_post(ldap, dn, entry_attrs)
-         radius_dn2pk(self.api, entry_attrs)
-         self.obj.get_preserved_attribute(entry_attrs, options)
-+
-+        self.post_common_callback(ldap, dn, entry_attrs, **options)
-+
-         return dn
- 
- 
-@@ -1034,18 +1039,14 @@ class user_add_cert(LDAPAddAttribute):
-                      **options):
-         assert isinstance(dn, DN)
- 
--        new_attr_name = '%s;binary' % self.attribute
--        if self.attribute in entry_attrs:
--            entry_attrs[new_attr_name] = entry_attrs.pop(self.attribute)
-+        self.obj.convert_usercertificate_pre(entry_attrs)
- 
-         return dn
- 
-     def post_callback(self, ldap, dn, entry_attrs, *keys, **options):
-         assert isinstance(dn, DN)
- 
--        old_attr_name = '%s;binary' % self.attribute
--        if old_attr_name in entry_attrs:
--            entry_attrs[self.attribute] = entry_attrs.pop(old_attr_name)
-+        self.obj.convert_usercertificate_post(entry_attrs, **options)
- 
-         return dn
- 
-@@ -1060,17 +1061,13 @@ class user_remove_cert(LDAPRemoveAttribute):
-                      **options):
-         assert isinstance(dn, DN)
- 
--        new_attr_name = '%s;binary' % self.attribute
--        if self.attribute in entry_attrs:
--            entry_attrs[new_attr_name] = entry_attrs.pop(self.attribute)
-+        self.obj.convert_usercertificate_pre(entry_attrs)
- 
-         return dn
- 
-     def post_callback(self, ldap, dn, entry_attrs, *keys, **options):
-         assert isinstance(dn, DN)
- 
--        old_attr_name = '%s;binary' % self.attribute
--        if old_attr_name in entry_attrs:
--            entry_attrs[self.attribute] = entry_attrs.pop(old_attr_name)
-+        self.obj.convert_usercertificate_post(entry_attrs, **options)
- 
-         return dn
--- 
-2.4.3
-
diff --git a/SOURCES/0041-Do-not-initialize-API-in-ipa-client-automount-uninst.patch b/SOURCES/0041-Do-not-initialize-API-in-ipa-client-automount-uninst.patch
new file mode 100644
index 0000000..8d2cb7f
--- /dev/null
+++ b/SOURCES/0041-Do-not-initialize-API-in-ipa-client-automount-uninst.patch
@@ -0,0 +1,41 @@
+From c92d242a215c7fb312aaeb07dd02f5783aec1817 Mon Sep 17 00:00:00 2001
+From: Martin Basti <mbasti@redhat.com>
+Date: Thu, 28 Jul 2016 09:47:39 +0200
+Subject: [PATCH] Do not initialize API in ipa-client-automount uninstall
+
+API is not needed in uninstallation, it may only produce errors.
+
+https://fedorahosted.org/freeipa/ticket/6072
+
+Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
+---
+ client/ipa-client-automount | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/client/ipa-client-automount b/client/ipa-client-automount
+index f06aa7f8d53ba2528bc2c023792771d5fd341e7c..08209c849f155a8394acddc6bb961be8fa68073c 100755
+--- a/client/ipa-client-automount
++++ b/client/ipa-client-automount
+@@ -378,6 +378,9 @@ 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',
+         in_server=False,
+@@ -392,9 +395,6 @@ def main():
+     if os.path.exists(paths.IPA_CA_CRT):
+         ca_cert_path = paths.IPA_CA_CRT
+ 
+-    if options.uninstall:
+-        return uninstall(fstore, statestore)
+-
+     if statestore.has_state('autofs'):
+         sys.exit('automount is already configured on this system.\n')
+ 
+-- 
+2.7.4
+
diff --git a/SOURCES/0041-Fix-incorrect-type-comparison-in-trust-fetch-domains.patch b/SOURCES/0041-Fix-incorrect-type-comparison-in-trust-fetch-domains.patch
deleted file mode 100644
index 3e06394..0000000
--- a/SOURCES/0041-Fix-incorrect-type-comparison-in-trust-fetch-domains.patch
+++ /dev/null
@@ -1,30 +0,0 @@
-From 8233849dd703e964f6abb70d2a4f37377d5bb7f0 Mon Sep 17 00:00:00 2001
-From: Tomas Babej <tbabej@redhat.com>
-Date: Wed, 5 Aug 2015 17:31:47 +0200
-Subject: [PATCH] Fix incorrect type comparison in trust-fetch-domains
-
-Value needs to be unpacked from the list and converted before comparison.
-
-https://fedorahosted.org/freeipa/ticket/5182
-
-Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
----
- ipalib/plugins/trust.py | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/ipalib/plugins/trust.py b/ipalib/plugins/trust.py
-index 6232e4fe9d3d5e957d22a3557cdcf4bb12cec0ea..0bb5e6558b680ac1acad44461d78a571098c7b25 100644
---- a/ipalib/plugins/trust.py
-+++ b/ipalib/plugins/trust.py
-@@ -1487,7 +1487,7 @@ class trust_fetch_domains(LDAPRetrieve):
-         result['truncated'] = False
- 
-         # For one-way trust fetch over DBus. we don't get the list in this case.
--        if trust['ipanttrustdirection'] & TRUST_BIDIRECTIONAL != TRUST_BIDIRECTIONAL:
-+        if int(trust['ipanttrustdirection'][0]) != TRUST_BIDIRECTIONAL:
-             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.4.3
-
diff --git a/SOURCES/0042-Correct-path-to-HTTPD-s-systemd-service-directory.patch b/SOURCES/0042-Correct-path-to-HTTPD-s-systemd-service-directory.patch
new file mode 100644
index 0000000..1f2a798
--- /dev/null
+++ b/SOURCES/0042-Correct-path-to-HTTPD-s-systemd-service-directory.patch
@@ -0,0 +1,37 @@
+From 0a0f32622b06234deb64a01376b0706a03650681 Mon Sep 17 00:00:00 2001
+From: Christian Heimes <cheimes@redhat.com>
+Date: Tue, 2 Aug 2016 16:58:07 +0200
+Subject: [PATCH] Correct path to HTTPD's systemd service directory
+
+Ticket #5681 and commit 586fee293f42388510fa5436af19460bbe1fdec5 changed
+the location of the ipa.conf for Apache HTTPD. The variables
+SYSTEMD_SYSTEM_HTTPD_D_DIR and SYSTEMD_SYSTEM_HTTPD_IPA_CONF point to
+the wrong directory /etc/systemd/system/httpd.d/. The path is corrected
+to  /etc/systemd/system/httpd.service.d/.
+
+https://fedorahosted.org/freeipa/ticket/6158
+https://bugzilla.redhat.com/show_bug.cgi?id=1362537
+Signed-off-by: Christian Heimes <cheimes@redhat.com>
+Reviewed-By: Abhijeet Kasurde <akasurde@redhat.com>
+---
+ ipaplatform/base/paths.py | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/ipaplatform/base/paths.py b/ipaplatform/base/paths.py
+index 1507ac36da5b40447c951ee608053a09b2db2fc3..9c8eaf951df89d373796be3f354bd3c51a329902 100644
+--- a/ipaplatform/base/paths.py
++++ b/ipaplatform/base/paths.py
+@@ -126,8 +126,8 @@ class BasePathNamespace(object):
+     SYSCONFIG_PKI_TOMCAT = "/etc/sysconfig/pki-tomcat"
+     SYSCONFIG_PKI_TOMCAT_PKI_TOMCAT_DIR = "/etc/sysconfig/pki/tomcat/pki-tomcat"
+     ETC_SYSTEMD_SYSTEM_DIR = "/etc/systemd/system/"
+-    SYSTEMD_SYSTEM_HTTPD_D_DIR = "/etc/systemd/system/httpd.d/"
+-    SYSTEMD_SYSTEM_HTTPD_IPA_CONF = "/etc/systemd/system/httpd.d/ipa.conf"
++    SYSTEMD_SYSTEM_HTTPD_D_DIR = "/etc/systemd/system/httpd.service.d/"
++    SYSTEMD_SYSTEM_HTTPD_IPA_CONF = "/etc/systemd/system/httpd.service.d/ipa.conf"
+     SYSTEMD_CERTMONGER_SERVICE = "/etc/systemd/system/multi-user.target.wants/certmonger.service"
+     SYSTEMD_IPA_SERVICE = "/etc/systemd/system/multi-user.target.wants/ipa.service"
+     SYSTEMD_SSSD_SERVICE = "/etc/systemd/system/multi-user.target.wants/sssd.service"
+-- 
+2.7.4
+
diff --git a/SOURCES/0042-Fix-selector-of-protocol-for-LSA-RPC-binding-string.patch b/SOURCES/0042-Fix-selector-of-protocol-for-LSA-RPC-binding-string.patch
deleted file mode 100644
index 42548b9..0000000
--- a/SOURCES/0042-Fix-selector-of-protocol-for-LSA-RPC-binding-string.patch
+++ /dev/null
@@ -1,37 +0,0 @@
-From 2585d6d6455d7c9257a8bbc65cc489d4a424a08e Mon Sep 17 00:00:00 2001
-From: Alexander Bokovoy <abokovoy@redhat.com>
-Date: Wed, 5 Aug 2015 21:33:45 +0300
-Subject: [PATCH] Fix selector of protocol for LSA RPC binding string
-
-For Windows Server 2012R2 and others which force SMB2 protocol use
-we have to specify right DCE RPC binding options.
-
-For using SMB1 protocol we have to omit specifying SMB2 protocol and
-anything else or otherwise SMB1 would be considered a pipe to connect
-to. This is by design of a binding string format.
-
-https://fedorahosted.org/freeipa/ticket/5183
-
-Reviewed-By: Tomas Babej <tbabej@redhat.com>
----
- ipaserver/dcerpc.py | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
-diff --git a/ipaserver/dcerpc.py b/ipaserver/dcerpc.py
-index c604fa3eae4cf94d719190a5a3e3de15d3841d24..74b4743d4bfb9c4950f441f1aa3561fc7a81391c 100644
---- a/ipaserver/dcerpc.py
-+++ b/ipaserver/dcerpc.py
-@@ -854,8 +854,8 @@ class TrustDomainInstance(object):
-         We try NCACN_NP before NCACN_IP_TCP and use SMB2 before SMB1 or defaults.
-         """
-         transports = (u'ncacn_np', u'ncacn_ip_tcp')
--        options = ( u'smb2', u'smb1', u'')
--        binding_template=lambda x,y,z: u'%s:%s[%s,print]' % (x, y, z)
-+        options = ( u'smb2,print', u'print')
-+        binding_template=lambda x,y,z: u'%s:%s[%s]' % (x, y, z)
-         return [binding_template(t, remote_host, o) for t in transports for o in options]
- 
-     def retrieve_anonymously(self, remote_host, discover_srv=False, search_pdc=False):
--- 
-2.4.3
-
diff --git a/SOURCES/0043-dcerpc-Simplify-generation-of-LSA-RPC-binding-string.patch b/SOURCES/0043-dcerpc-Simplify-generation-of-LSA-RPC-binding-string.patch
deleted file mode 100644
index 1edd83d..0000000
--- a/SOURCES/0043-dcerpc-Simplify-generation-of-LSA-RPC-binding-string.patch
+++ /dev/null
@@ -1,29 +0,0 @@
-From 47e9c9cacdc189ac87983ed1596db3d48f45e089 Mon Sep 17 00:00:00 2001
-From: Tomas Babej <tbabej@redhat.com>
-Date: Fri, 7 Aug 2015 18:03:48 +0200
-Subject: [PATCH] dcerpc: Simplify generation of LSA-RPC binding strings
-
-https://fedorahosted.org/freeipa/ticket/5183
-
-Reviewed-By: Tomas Babej <tbabej@redhat.com>
----
- ipaserver/dcerpc.py | 3 +--
- 1 file changed, 1 insertion(+), 2 deletions(-)
-
-diff --git a/ipaserver/dcerpc.py b/ipaserver/dcerpc.py
-index 74b4743d4bfb9c4950f441f1aa3561fc7a81391c..71106b6a804b8445e5c266a92a30ac7557dcf853 100644
---- a/ipaserver/dcerpc.py
-+++ b/ipaserver/dcerpc.py
-@@ -855,8 +855,7 @@ class TrustDomainInstance(object):
-         """
-         transports = (u'ncacn_np', u'ncacn_ip_tcp')
-         options = ( u'smb2,print', u'print')
--        binding_template=lambda x,y,z: u'%s:%s[%s]' % (x, y, z)
--        return [binding_template(t, remote_host, o) for t in transports for o in options]
-+        return [u'%s:%s[%s]' % (t, remote_host, o) for t in transports for o in options]
- 
-     def retrieve_anonymously(self, remote_host, discover_srv=False, search_pdc=False):
-         """
--- 
-2.4.3
-
diff --git a/SOURCES/0043-vault-Catch-correct-exception-in-decrypt.patch b/SOURCES/0043-vault-Catch-correct-exception-in-decrypt.patch
new file mode 100644
index 0000000..25eb903
--- /dev/null
+++ b/SOURCES/0043-vault-Catch-correct-exception-in-decrypt.patch
@@ -0,0 +1,30 @@
+From cc92fe8badfe32f4c55abfa8b249dc1f94936d7c Mon Sep 17 00:00:00 2001
+From: David Kupka <dkupka@redhat.com>
+Date: Wed, 3 Aug 2016 10:35:40 +0200
+Subject: [PATCH] vault: Catch correct exception in decrypt
+
+ValueError is raised when decryption fails.
+
+https://fedorahosted.org/freeipa/ticket/6160
+
+Reviewed-By: David Kupka <dkupka@redhat.com>
+---
+ ipaclient/plugins/vault.py | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/ipaclient/plugins/vault.py b/ipaclient/plugins/vault.py
+index e3a1ae3a0ad767bcee843b7fa3743a934e02d18b..73ad09b38316d55b466b7973dbeffefc1b7bb528 100644
+--- a/ipaclient/plugins/vault.py
++++ b/ipaclient/plugins/vault.py
+@@ -164,7 +164,7 @@ def decrypt(data, symmetric_key=None, private_key=None):
+                     label=None
+                 )
+             )
+-        except AssertionError:
++        except ValueError:
+             raise errors.AuthenticationError(
+                 message=_('Invalid credentials'))
+ 
+-- 
+2.7.4
+
diff --git a/SOURCES/0044-Fixed-missing-KRA-agent-cert-on-replica.patch b/SOURCES/0044-Fixed-missing-KRA-agent-cert-on-replica.patch
deleted file mode 100644
index 826d8b5..0000000
--- a/SOURCES/0044-Fixed-missing-KRA-agent-cert-on-replica.patch
+++ /dev/null
@@ -1,53 +0,0 @@
-From 9d1657b3527e423e489a25fd7ee31692181f9f5b Mon Sep 17 00:00:00 2001
-From: "Endi S. Dewata" <edewata@redhat.com>
-Date: Sat, 1 Aug 2015 02:46:26 +0200
-Subject: [PATCH] Fixed missing KRA agent cert on replica.
-
-The code that exports the KRA agent certificate has been moved
-such that it will be executed both on master and replica.
-
-https://fedorahosted.org/freeipa/ticket/5174
-
-Reviewed-By: Jan Cholasta <jcholast@redhat.com>
----
- ipaserver/install/krainstance.py | 17 +++++++++--------
- 1 file changed, 9 insertions(+), 8 deletions(-)
-
-diff --git a/ipaserver/install/krainstance.py b/ipaserver/install/krainstance.py
-index 50ab424b0e59becfea9e7af4b8d43a32ccbdc823..fa50c3dec897d63b9d3522d196054163f7b3369a 100644
---- a/ipaserver/install/krainstance.py
-+++ b/ipaserver/install/krainstance.py
-@@ -256,6 +256,15 @@ class KRAInstance(DogtagInstance):
-             os.remove(cfg_file)
- 
-         shutil.move(paths.KRA_BACKUP_KEYS_P12, paths.KRACERT_P12)
-+
-+        # export ipaCert with private key for client authentication
-+        args = ["/usr/bin/pki",
-+            "-d", paths.HTTPD_ALIAS_DIR,
-+            "-C", paths.ALIAS_PWDFILE_TXT,
-+            "client-cert-show", "ipaCert",
-+            "--client-cert", paths.KRA_AGENT_PEM]
-+        ipautil.run(args)
-+
-         self.log.debug("completed creating KRA instance")
- 
-     def __add_ra_user_to_agent_group(self):
-@@ -330,14 +339,6 @@ class KRAInstance(DogtagInstance):
-         finally:
-             os.remove(filename)
- 
--        # export ipaCert with private key for client authentication
--        args = ["/usr/bin/pki",
--            "-d", paths.HTTPD_ALIAS_DIR,
--            "-C", paths.ALIAS_PWDFILE_TXT,
--            "client-cert-show", "ipaCert",
--            "--client-cert", paths.KRA_AGENT_PEM]
--        ipautil.run(args)
--
-     def __add_vault_container(self):
-         sub_dict = {
-             'SUFFIX': self.suffix,
--- 
-2.4.3
-
diff --git a/SOURCES/0044-Increase-default-length-of-auto-generated-passwords.patch b/SOURCES/0044-Increase-default-length-of-auto-generated-passwords.patch
new file mode 100644
index 0000000..1814e3c
--- /dev/null
+++ b/SOURCES/0044-Increase-default-length-of-auto-generated-passwords.patch
@@ -0,0 +1,138 @@
+From 0d2e4dae80eb4140ea605ca88d9130b8bf3ec269 Mon Sep 17 00:00:00 2001
+From: Martin Basti <mbasti@redhat.com>
+Date: Fri, 22 Jul 2016 16:41:29 +0200
+Subject: [PATCH] Increase default length of auto generated passwords
+
+Installer/IPA generates passwords for warious purpose:
+* KRA
+* kerberos master key
+* NSSDB password
+* temporary passwords during installation
+
+Length of passwords should be increased to 22, ~128bits of entropy, to
+be safe nowadays.
+
+https://fedorahosted.org/freeipa/ticket/6116
+
+Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
+---
+ ipapython/ipautil.py           | 3 ++-
+ ipaserver/plugins/baseuser.py  | 5 +++--
+ ipaserver/plugins/host.py      | 9 +++++++--
+ ipaserver/plugins/stageuser.py | 5 +++--
+ ipaserver/plugins/user.py      | 5 +++--
+ 5 files changed, 18 insertions(+), 9 deletions(-)
+
+diff --git a/ipapython/ipautil.py b/ipapython/ipautil.py
+index 9964fba4f694b57242b3bd3065a418917d977533..fdfebb65ecb8b62108852f6517b5ffb22fd7eedc 100644
+--- a/ipapython/ipautil.py
++++ b/ipapython/ipautil.py
+@@ -57,7 +57,8 @@ from ipapython.dn import DN
+ SHARE_DIR = paths.USR_SHARE_IPA_DIR
+ PLUGINS_SHARE_DIR = paths.IPA_PLUGINS
+ 
+-GEN_PWD_LEN = 12
++GEN_PWD_LEN = 22
++GEN_TMP_PWD_LEN = 12  # only for OTP password that is manually retyped by user
+ 
+ # Having this in krb_utils would cause circular import
+ KRB5_KDC_UNREACH = 2529639068 # Cannot contact any KDC for requested realm
+diff --git a/ipaserver/plugins/baseuser.py b/ipaserver/plugins/baseuser.py
+index e4288a5a131157815ffb2452692a7edb342f6ac3..5e36a6620295351d4745bfc035f24349f8fb8295 100644
+--- a/ipaserver/plugins/baseuser.py
++++ b/ipaserver/plugins/baseuser.py
+@@ -34,7 +34,7 @@ from ipaserver.plugins.service import (
+ from ipalib.request import context
+ from ipalib import _
+ from ipapython import kerberos
+-from ipapython.ipautil import ipa_generate_password
++from ipapython.ipautil import ipa_generate_password, GEN_TMP_PWD_LEN
+ from ipapython.ipavalidate import Email
+ from ipalib.util import (
+     normalize_sshpubkey,
+@@ -552,7 +552,8 @@ class baseuser_mod(LDAPUpdate):
+ 
+     def check_userpassword(self, entry_attrs, **options):
+         if 'userpassword' not in entry_attrs and options.get('random'):
+-            entry_attrs['userpassword'] = ipa_generate_password(baseuser_pwdchars)
++            entry_attrs['userpassword'] = ipa_generate_password(
++                baseuser_pwdchars, pwd_len=GEN_TMP_PWD_LEN)
+             # save the password so it can be displayed in post_callback
+             setattr(context, 'randompassword', entry_attrs['userpassword'])
+ 
+diff --git a/ipaserver/plugins/host.py b/ipaserver/plugins/host.py
+index 413dcf15e0423170d8334902b9dcf8fb5aa14de6..03c64c637cbba0aee1b6569f3b5dbe200953bff8 100644
+--- a/ipaserver/plugins/host.py
++++ b/ipaserver/plugins/host.py
+@@ -59,7 +59,11 @@ from ipalib.util import (normalize_sshpubkey, validate_sshpubkey_no_options,
+     hostname_validator,
+     set_krbcanonicalname
+ )
+-from ipapython.ipautil import ipa_generate_password, CheckedIPAddress
++from ipapython.ipautil import (
++    ipa_generate_password,
++    CheckedIPAddress,
++    GEN_TMP_PWD_LEN
++)
+ from ipapython.dnsutil import DNSName
+ from ipapython.ssh import SSHPublicKey
+ from ipapython.dn import DN
+@@ -683,7 +687,8 @@ class host_add(LDAPCreate):
+             if 'krbprincipal' in entry_attrs['objectclass']:
+                 entry_attrs['objectclass'].remove('krbprincipal')
+         if options.get('random'):
+-            entry_attrs['userpassword'] = ipa_generate_password(characters=host_pwd_chars)
++            entry_attrs['userpassword'] = ipa_generate_password(
++                characters=host_pwd_chars, pwd_len=GEN_TMP_PWD_LEN)
+             # save the password so it can be displayed in post_callback
+             setattr(context, 'randompassword', entry_attrs['userpassword'])
+         certs = options.get('usercertificate', [])
+diff --git a/ipaserver/plugins/stageuser.py b/ipaserver/plugins/stageuser.py
+index 3b9388f6020b9a6c40caedd36f3640a05a13da65..a219e3dace6da5e9c036122e9710b2acaaa42ebf 100644
+--- a/ipaserver/plugins/stageuser.py
++++ b/ipaserver/plugins/stageuser.py
+@@ -47,7 +47,7 @@ from ipalib.util import set_krbcanonicalname
+ from ipalib import _, ngettext
+ from ipalib import output
+ from ipaplatform.paths import paths
+-from ipapython.ipautil import ipa_generate_password
++from ipapython.ipautil import ipa_generate_password, GEN_TMP_PWD_LEN
+ from ipalib.capabilities import client_has_capability
+ 
+ if six.PY3:
+@@ -339,7 +339,8 @@ class stageuser_add(baseuser_add):
+ 
+         # If requested, generate a userpassword
+         if 'userpassword' not in entry_attrs and options.get('random'):
+-            entry_attrs['userpassword'] = ipa_generate_password(baseuser_pwdchars)
++            entry_attrs['userpassword'] = ipa_generate_password(
++                baseuser_pwdchars, pwd_len=GEN_TMP_PWD_LEN)
+             # save the password so it can be displayed in post_callback
+             setattr(context, 'randompassword', entry_attrs['userpassword'])
+ 
+diff --git a/ipaserver/plugins/user.py b/ipaserver/plugins/user.py
+index b3ae7646fdcfa1dce10d90063dae2a24c091e8ee..935ea892cde9e2cb5b21f4714fd93e73c3fa53d5 100644
+--- a/ipaserver/plugins/user.py
++++ b/ipaserver/plugins/user.py
+@@ -63,7 +63,7 @@ from ipalib import _, ngettext
+ from ipalib import output
+ from ipaplatform.paths import paths
+ from ipapython.dn import DN
+-from ipapython.ipautil import ipa_generate_password
++from ipapython.ipautil import ipa_generate_password, GEN_TMP_PWD_LEN
+ from ipalib.capabilities import client_has_capability
+ 
+ if api.env.in_server:
+@@ -517,7 +517,8 @@ class user_add(baseuser_add):
+                 entry_attrs['gidnumber'] = group_attrs['gidnumber']
+ 
+         if 'userpassword' not in entry_attrs and options.get('random'):
+-            entry_attrs['userpassword'] = ipa_generate_password(baseuser_pwdchars)
++            entry_attrs['userpassword'] = ipa_generate_password(
++                baseuser_pwdchars, pwd_len=GEN_TMP_PWD_LEN)
+             # save the password so it can be displayed in post_callback
+             setattr(context, 'randompassword', entry_attrs['userpassword'])
+ 
+-- 
+2.7.4
+
diff --git a/SOURCES/0045-vault-add-missing-salt-option-to-vault_mod.patch b/SOURCES/0045-vault-add-missing-salt-option-to-vault_mod.patch
new file mode 100644
index 0000000..802353a
--- /dev/null
+++ b/SOURCES/0045-vault-add-missing-salt-option-to-vault_mod.patch
@@ -0,0 +1,31 @@
+From 001abcdca2026d0e1f51ca4e4e9d2cff052eadd7 Mon Sep 17 00:00:00 2001
+From: Jan Cholasta <jcholast@redhat.com>
+Date: Thu, 4 Aug 2016 14:14:15 +0200
+Subject: [PATCH] vault: add missing salt option to vault_mod
+
+The option was accidentally removed in commit
+4b119e21a2f93ca16c5edf3d1058552b44feeaf8.
+
+https://fedorahosted.org/freeipa/ticket/6154
+
+Reviewed-By: Jan Cholasta <jcholast@redhat.com>
+---
+ ipaclient/plugins/vault.py | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/ipaclient/plugins/vault.py b/ipaclient/plugins/vault.py
+index 73ad09b38316d55b466b7973dbeffefc1b7bb528..9026cbb0829a7557584df27a4262dfde640b4f28 100644
+--- a/ipaclient/plugins/vault.py
++++ b/ipaclient/plugins/vault.py
+@@ -413,7 +413,7 @@ class vault_mod(Local):
+ 
+     def get_options(self):
+         for option in self.api.Command.vault_mod_internal.options():
+-            if option.name not in ('ipavaultsalt', 'version'):
++            if option.name != 'version':
+                 yield option
+         for option in super(vault_mod, self).get_options():
+             yield option
+-- 
+2.7.4
+
diff --git a/SOURCES/0045-webui-add-LDAP-vs-Kerberos-behavior-description-to-u.patch b/SOURCES/0045-webui-add-LDAP-vs-Kerberos-behavior-description-to-u.patch
deleted file mode 100644
index 0457ec3..0000000
--- a/SOURCES/0045-webui-add-LDAP-vs-Kerberos-behavior-description-to-u.patch
+++ /dev/null
@@ -1,89 +0,0 @@
-From f169531c4b4fec3485015a9673e5b0d3b76e30d6 Mon Sep 17 00:00:00 2001
-From: Petr Vobornik <pvoborni@redhat.com>
-Date: Mon, 10 Aug 2015 12:58:14 +0200
-Subject: [PATCH] webui: add LDAP vs Kerberos behavior description to user auth
- types
-
-https://fedorahosted.org/freeipa/ticket/4935
-
-Reviewed-By: David Kupka <dkupka@redhat.com>
----
- install/ui/src/freeipa/serverconfig.js | 5 ++++-
- install/ui/src/freeipa/user.js         | 5 ++++-
- install/ui/test/data/ipa_init.json     | 4 ++--
- ipalib/plugins/internal.py             | 4 ++--
- 4 files changed, 12 insertions(+), 6 deletions(-)
-
-diff --git a/install/ui/src/freeipa/serverconfig.js b/install/ui/src/freeipa/serverconfig.js
-index efe1805698372b45afae38d1f9dd883034ee03c6..70bb9574b8368d6a294dc171fdea2d03dfe56cab 100644
---- a/install/ui/src/freeipa/serverconfig.js
-+++ b/install/ui/src/freeipa/serverconfig.js
-@@ -83,7 +83,10 @@ return {
-                                 { label: '@i18n:authtype.type_radius', value: 'radius' },
-                                 { label: '@i18n:authtype.type_otp', value: 'otp' }
-                             ],
--                            tooltip: '@i18n:authtype.config_tooltip'
-+                            tooltip: {
-+                                title: '@i18n:authtype.config_tooltip',
-+                                html: true
-+                            }
-                         },
-                         {
-                             $type: 'checkbox',
-diff --git a/install/ui/src/freeipa/user.js b/install/ui/src/freeipa/user.js
-index 0e828c16b999ffd58504bc4e53d2748bcd16b042..a920e088aacd02585cd131dce725272f47e4cf1c 100644
---- a/install/ui/src/freeipa/user.js
-+++ b/install/ui/src/freeipa/user.js
-@@ -188,7 +188,10 @@ return {
-                                 { label: '@i18n:authtype.type_radius', value: 'radius' },
-                                 { label: '@i18n:authtype.type_otp', value: 'otp' }
-                             ],
--                            tooltip: '@i18n:authtype.user_tooltip'
-+                            tooltip: {
-+                                title: '@i18n:authtype.user_tooltip',
-+                                html: true
-+                            }
-                         },
-                         {
-                             $type: 'entity_select',
-diff --git a/install/ui/test/data/ipa_init.json b/install/ui/test/data/ipa_init.json
-index ef172950527512e71c28916274153036f17212fe..b80e44ffe8ead3d0b29196ca3af18e00d72a9f04 100644
---- a/install/ui/test/data/ipa_init.json
-+++ b/install/ui/test/data/ipa_init.json
-@@ -49,12 +49,12 @@
-                         "show_results": "Show Results"
-                     },
-                     "authtype": {
--                        "config_tooltip": "Implicit method (password) will be used if no method is chosen.",
-+                        "config_tooltip": "<p>Implicit method (password) will be used if no method is chosen.</p><p><strong>Password + Two-factor:</strong> LDAP and Kerberos allow authentication with either one of the authentication types but Kerberos uses pre-authentication method which requires to use armor ccache.</p><p><strong>RADIUS with another type:</strong> Kerberos always use RADIUS, but LDAP never does. LDAP only recognize the password and two-factor authentication options.</p>",
-                         "type_otp": "Two factor authentication (password + OTP)",
-                         "type_password": "Password",
-                         "type_radius": "Radius",
-                         "type_disabled": "Disable per-user override",
--                        "user_tooltip": "Per-user setting, overwrites the global setting if any option is checked."
-+                        "user_tooltip": "<p>Per-user setting, overwrites the global setting if any option is checked.</p><p><strong>Password + Two-factor:</strong> LDAP and Kerberos allow authentication with either one of the authentication types but Kerberos uses pre-authentication method which requires to use armor ccache.</p><p><strong>RADIUS with another type:</strong> Kerberos always use RADIUS, but LDAP never does. LDAP only recognize the password and two-factor authentication options.</p>",
-                     },
-                     "buttons": {
-                         "about": "About",
-diff --git a/ipalib/plugins/internal.py b/ipalib/plugins/internal.py
-index f97885ceae8f3c0913a16c281c2faa8a918541e7..e1904d2d3d1e1523895554b8d8e58b1dfd070366 100644
---- a/ipalib/plugins/internal.py
-+++ b/ipalib/plugins/internal.py
-@@ -191,12 +191,12 @@ class i18n_messages(Command):
-             "show_results": _("Show Results"),
-         },
-         "authtype": {
--            "config_tooltip": _("Implicit method (password) will be used if no method is chosen."),
-+            "config_tooltip": _("<p>Implicit method (password) will be used if no method is chosen.</p><p><strong>Password + Two-factor:</strong> LDAP and Kerberos allow authentication with either one of the authentication types but Kerberos uses pre-authentication method which requires to use armor ccache.</p><p><strong>RADIUS with another type:</strong> Kerberos always use RADIUS, but LDAP never does. LDAP only recognize the password and two-factor authentication options.</p>"),
-             "type_otp": _("Two factor authentication (password + OTP)"),
-             "type_password": _("Password"),
-             "type_radius": _("Radius"),
-             "type_disabled": _("Disable per-user override"),
--            "user_tooltip": _("Per-user setting, overwrites the global setting if any option is checked."),
-+            "user_tooltip": _("<p>Per-user setting, overwrites the global setting if any option is checked.</p><p><strong>Password + Two-factor:</strong> LDAP and Kerberos allow authentication with either one of the authentication types but Kerberos uses pre-authentication method which requires to use armor ccache.</p><p><strong>RADIUS with another type:</strong> Kerberos always use RADIUS, but LDAP never does. LDAP only recognize the password and two-factor authentication options.</p>"),
-         },
-         "buttons": {
-             "about": _("About"),
--- 
-2.4.3
-
diff --git a/SOURCES/0046-Fix-ipa-hbactest-output.patch b/SOURCES/0046-Fix-ipa-hbactest-output.patch
new file mode 100644
index 0000000..252279e
--- /dev/null
+++ b/SOURCES/0046-Fix-ipa-hbactest-output.patch
@@ -0,0 +1,46 @@
+From 56f6fe1df44bc9d3f434b0bccd44bc11cda89999 Mon Sep 17 00:00:00 2001
+From: Florence Blanc-Renaud <flo@redhat.com>
+Date: Tue, 2 Aug 2016 10:40:54 +0200
+Subject: [PATCH] Fix ipa hbactest output
+
+ipa hbactest command produces a Traceback (TypeError: cannot concatenate
+'str' and 'bool' objects)
+This happens because hbactest overrides output_for_cli but does not
+properly handle the output for 'value' field. 'value' contains a boolean
+but it should not be displayed (refer to ipalib/frontend.py,
+Command.output_for_cli()).
+
+Note that the issue did not appear before because the 'value' field
+had a flag no_display.
+
+https://fedorahosted.org/freeipa/ticket/6157
+
+Reviewed-By: Martin Basti <mbasti@redhat.com>
+---
+ ipaclient/plugins/hbactest.py | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/ipaclient/plugins/hbactest.py b/ipaclient/plugins/hbactest.py
+index 2518719522c4eddff2e6bc341ee9a7c34b431938..1b54530b236cf654bc8ece7ab4e329850f5a6815 100644
+--- a/ipaclient/plugins/hbactest.py
++++ b/ipaclient/plugins/hbactest.py
+@@ -39,13 +39,15 @@ class hbactest(CommandOverride):
+         # to be printed as our execute() method will return None for corresponding
+         # entries and None entries will be skipped.
+         for o in self.output:
++            if o == 'value':
++                continue
+             outp = self.output[o]
+             if 'no_display' in outp.flags:
+                 continue
+             result = output[o]
+             if isinstance(result, (list, tuple)):
+                 textui.print_attribute(unicode(outp.doc), result, '%s: %s', 1, True)
+-            elif isinstance(result, (unicode, bool)):
++            elif isinstance(result, unicode):
+                 if o == 'summary':
+                     textui.print_summary(result)
+                 else:
+-- 
+2.7.4
+
diff --git a/SOURCES/0046-Fix-upgrade-of-sidgen-and-extdom-plugins.patch b/SOURCES/0046-Fix-upgrade-of-sidgen-and-extdom-plugins.patch
deleted file mode 100644
index c16440a..0000000
--- a/SOURCES/0046-Fix-upgrade-of-sidgen-and-extdom-plugins.patch
+++ /dev/null
@@ -1,99 +0,0 @@
-From 0df0907537d53f731e5ffc833a7c8d2e2d1a51f7 Mon Sep 17 00:00:00 2001
-From: Martin Basti <mbasti@redhat.com>
-Date: Mon, 10 Aug 2015 10:53:28 +0200
-Subject: [PATCH] Fix upgrade of sidgen and extdom plugins
-
-If configuration entries already exist, upgrade will not add them
-again.
-
-https://fedorahosted.org/freeipa/ticket/5151
-
-Reviewed-By: Martin Babinsky <mbabinsk@redhat.com>
----
- ipaserver/install/dsinstance.py     | 28 +++++++++++++++++++++++++---
- ipaserver/install/server/upgrade.py |  9 ++++++---
- 2 files changed, 31 insertions(+), 6 deletions(-)
-
-diff --git a/ipaserver/install/dsinstance.py b/ipaserver/install/dsinstance.py
-index b2558024f0b345700bc544757e0eecd8b1052a1d..f33a9e03a4148dde69fc61441c878f5126f8e455 100644
---- a/ipaserver/install/dsinstance.py
-+++ b/ipaserver/install/dsinstance.py
-@@ -925,20 +925,42 @@ class DsInstance(service.Service):
-     def __add_range_check_plugin(self):
-         self._ldap_mod("range-check-conf.ldif", self.sub_dict)
- 
--    # These two methods are not local, they are also called from the upgrade code
-     def _add_sidgen_plugin(self):
-         """
-         Add sidgen directory server plugin configuration if it does not already exist.
-         """
-         self._ldap_mod('ipa-sidgen-conf.ldif', self.sub_dict)
- 
-+    def add_sidgen_plugin(self):
-+        """
-+        Add sidgen plugin configuration only if it does not already exist.
-+        """
-+        dn = DN('cn=IPA SIDGEN,cn=plugins,cn=config')
-+        try:
-+            self.admin_conn.get_entry(dn)
-+        except errors.NotFound:
-+            self._add_sidgen_plugin()
-+        else:
-+            root_logger.debug("sidgen plugin is already configured")
-+
-     def _add_extdom_plugin(self):
-         """
--        Add directory server configuration for the extdom extended operation
--        if it does not already exist.
-+        Add directory server configuration for the extdom extended operation.
-         """
-         self._ldap_mod('ipa-extdom-extop-conf.ldif', self.sub_dict)
- 
-+    def add_extdom_plugin(self):
-+        """
-+        Add extdom configuration if it does not already exist.
-+        """
-+        dn = DN('cn=ipa_extdom_extop,cn=plugins,cn=config')
-+        try:
-+            self.admin_conn.get_entry(dn)
-+        except errors.NotFound:
-+            self._add_extdom_plugin()
-+        else:
-+            root_logger.debug("extdom plugin is already configured")
-+
-     def replica_populate(self):
-         self.ldap_connect()
- 
-diff --git a/ipaserver/install/server/upgrade.py b/ipaserver/install/server/upgrade.py
-index f295655dc2aa592e0215f15017c9b65af49eef80..037127918cb4c205c5049446989bfdaa674967a4 100644
---- a/ipaserver/install/server/upgrade.py
-+++ b/ipaserver/install/server/upgrade.py
-@@ -1261,11 +1261,11 @@ def ds_enable_sidgen_extdom_plugins(ds):
-     root_logger.info('[Enable sidgen and extdom plugins by default]')
- 
-     if sysupgrade.get_upgrade_state('ds', 'enable_ds_sidgen_extdom_plugins'):
--        root_logger.info('sidgen and extdom plugins are enabled already')
-+        root_logger.debug('sidgen and extdom plugins are enabled already')
-         return
- 
--    ds._add_sidgen_plugin()
--    ds._add_extdom_plugin()
-+    ds.add_sidgen_plugin()
-+    ds.add_extdom_plugin()
-     sysupgrade.set_upgrade_state('ds', 'enable_ds_sidgen_extdom_plugins', True)
- 
- def ca_upgrade_schema(ca):
-@@ -1415,7 +1415,10 @@ def upgrade_configuration():
-     ds.fqdn = fqdn
-     ds.realm = api.env.realm
-     ds.suffix = ipautil.realm_to_suffix(api.env.realm)
-+
-+    ds.ldap_connect()
-     ds_enable_sidgen_extdom_plugins(ds)
-+    ds.ldap_disconnect()
- 
-     # Now 389-ds is available, run the remaining http tasks
-     if not http.is_kdcproxy_configured():
--- 
-2.4.3
-
diff --git a/SOURCES/0047-Give-more-info-on-virtual-command-access-denial.patch b/SOURCES/0047-Give-more-info-on-virtual-command-access-denial.patch
deleted file mode 100644
index 8c25117..0000000
--- a/SOURCES/0047-Give-more-info-on-virtual-command-access-denial.patch
+++ /dev/null
@@ -1,30 +0,0 @@
-From 7416358e95e69a517424319ac31dfcc68bda2878 Mon Sep 17 00:00:00 2001
-From: Fraser Tweedale <ftweedal@redhat.com>
-Date: Sun, 9 Aug 2015 01:54:41 -0400
-Subject: [PATCH] Give more info on virtual command access denial
-
-The current error message upon a virutal command access denial does
-not give any information about the virtual operation that was
-prohibited.  Add more information to the ACIError message.
-
-Reviewed-By: Martin Babinsky <mbabinsk@redhat.com>
----
- ipalib/plugins/virtual.py | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/ipalib/plugins/virtual.py b/ipalib/plugins/virtual.py
-index 414de4c0011b4ae49083d7820a3cb3708e3e16b1..3bbe32e538ab108d7abc71785e27664fea5ea248 100644
---- a/ipalib/plugins/virtual.py
-+++ b/ipalib/plugins/virtual.py
-@@ -62,7 +62,7 @@ class VirtualCommand(Command):
-         try:
-             if not ldap.can_write(operationdn, "objectclass"):
-                 raise errors.ACIError(
--                    info=_('not allowed to perform this command'))
-+                    info=_('not allowed to perform operation: %s') % operation)
-         except errors.NotFound:
-             raise errors.ACIError(info=_('No such virtual command'))
- 
--- 
-2.4.3
-
diff --git a/SOURCES/0047-install-fix-external-CA-cert-validation.patch b/SOURCES/0047-install-fix-external-CA-cert-validation.patch
new file mode 100644
index 0000000..0e6980c
--- /dev/null
+++ b/SOURCES/0047-install-fix-external-CA-cert-validation.patch
@@ -0,0 +1,31 @@
+From fdcaf9f8437fcd12220af125a4fe0871c6d33f47 Mon Sep 17 00:00:00 2001
+From: Jan Cholasta <jcholast@redhat.com>
+Date: Thu, 4 Aug 2016 09:58:38 +0200
+Subject: [PATCH] install: fix external CA cert validation
+
+The code which loads the external CA cert chain was never executed because
+of an incorrect usage of an iterator (iterating over it twice).
+
+https://fedorahosted.org/freeipa/ticket/6166
+
+Reviewed-By: Jan Cholasta <jcholast@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 25f48aed1eeaa03353465bc40abf3484ec19bf3b..66ba33326adcdb47c2ba77c573ba9b66a82b365e 100644
+--- a/ipaserver/install/installutils.py
++++ b/ipaserver/install/installutils.py
+@@ -1038,7 +1038,7 @@ def load_external_cert(files, subject_base):
+             raise ScriptError(
+                 "IPA CA certificate not found in %s" % (", ".join(files)))
+ 
+-        trust_chain = reversed(nssdb.get_trust_chain(ca_nickname))
++        trust_chain = list(reversed(nssdb.get_trust_chain(ca_nickname)))
+         ca_cert_chain = []
+         for nickname in trust_chain:
+             cert, subject, issuer = cache[nickname]
+-- 
+2.7.4
+
diff --git a/SOURCES/0048-Allow-SAN-extension-for-cert-request-self-service.patch b/SOURCES/0048-Allow-SAN-extension-for-cert-request-self-service.patch
deleted file mode 100644
index 5de2f41..0000000
--- a/SOURCES/0048-Allow-SAN-extension-for-cert-request-self-service.patch
+++ /dev/null
@@ -1,33 +0,0 @@
-From a7532af44e518994b8124b09e32fb3f494150ba6 Mon Sep 17 00:00:00 2001
-From: Fraser Tweedale <ftweedal@redhat.com>
-Date: Sun, 9 Aug 2015 03:25:58 -0400
-Subject: [PATCH] Allow SAN extension for cert-request self-service
-
-Users cannot self-issue a certificate with a subjectAltName
-extension (e.g. with rfc822Name altNames).  Suppress the
-cert-request "request certificate with subjectaltname" permission
-check when the bind principal is the target principal (i.e.
-cert-request self-service).
-
-Fixes: https://fedorahosted.org/freeipa/ticket/5190
-Reviewed-By: Martin Babinsky <mbabinsk@redhat.com>
----
- ipalib/plugins/cert.py | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/ipalib/plugins/cert.py b/ipalib/plugins/cert.py
-index 341bdd01766d50ba18ce7147d4408851e6f95487..d612e9d38da44e4fd4768d286f930e51c71a1031 100644
---- a/ipalib/plugins/cert.py
-+++ b/ipalib/plugins/cert.py
-@@ -369,7 +369,7 @@ class cert_request(VirtualCommand):
-                 error=_("Failure decoding Certificate Signing Request: %s") % e)
- 
-         # host principals may bypass allowed ext check
--        if bind_principal_type != HOST:
-+        if bind_principal != principal and bind_principal_type != HOST:
-             for ext in extensions:
-                 operation = self._allowed_extensions.get(ext)
-                 if operation:
--- 
-2.4.3
-
diff --git a/SOURCES/0048-caacl-fix-regression-in-rule-instantiation.patch b/SOURCES/0048-caacl-fix-regression-in-rule-instantiation.patch
new file mode 100644
index 0000000..beeb795
--- /dev/null
+++ b/SOURCES/0048-caacl-fix-regression-in-rule-instantiation.patch
@@ -0,0 +1,52 @@
+From c27595371bfe1f4fe12125e053cb7ec3ad08ebf6 Mon Sep 17 00:00:00 2001
+From: Fraser Tweedale <ftweedal@redhat.com>
+Date: Thu, 28 Jul 2016 10:55:45 +1000
+Subject: [PATCH] caacl: fix regression in rule instantiation
+
+The Principal refactor causes service collections
+('memberservice_service' attribute) to return Principal objects
+where previously it returned strings, but the HBAC machinery used
+for CA ACL enforcement only handles strings.  Update the code to
+stringify service Principal objects when adding them to HBAC rules.
+
+Fixes: https://fedorahosted.org/freeipa/ticket/6146
+Reviewed-By: Martin Basti <mbasti@redhat.com>
+---
+ ipaserver/plugins/caacl.py | 17 +++++++++++------
+ 1 file changed, 11 insertions(+), 6 deletions(-)
+
+diff --git a/ipaserver/plugins/caacl.py b/ipaserver/plugins/caacl.py
+index d316cc7c48cf2997d6be6b052dc1efa6d6fcdb6a..a7817c4cf64f070c74557f52e9f26c9013a4963c 100644
+--- a/ipaserver/plugins/caacl.py
++++ b/ipaserver/plugins/caacl.py
+@@ -132,16 +132,21 @@ def _acl_make_rule(principal_type, obj):
+         rule.services.names = obj.get(attr, [])
+ 
+     # add principals and principal's groups
+-    m = {'user': 'group', 'host': 'hostgroup', 'service': None}
+     category_attr = '{}category'.format(principal_type)
+     if category_attr in obj and obj[category_attr][0].lower() == 'all':
+         rule.users.category = {pyhbac.HBAC_CATEGORY_ALL}
+     else:
+-        principal_attr = 'member{}_{}'.format(principal_type, principal_type)
+-        rule.users.names = obj.get(principal_attr, [])
+-        if m[principal_type] is not None:
+-            group_attr = 'member{}_{}'.format(principal_type, m[principal_type])
+-            rule.users.groups = obj.get(group_attr, [])
++        if principal_type == 'user':
++            rule.users.names = obj.get('memberuser_user', [])
++            rule.users.groups = obj.get('memberuser_group', [])
++        elif principal_type == 'host':
++            rule.users.names = obj.get('memberhost_host', [])
++            rule.users.groups = obj.get('memberhost_hostgroup', [])
++        elif principal_type == 'service':
++            rule.users.names = [
++                unicode(principal)
++                for principal in obj.get('memberservice_service', [])
++            ]
+ 
+     return rule
+ 
+-- 
+2.7.4
+
diff --git a/SOURCES/0049-Add-profile-for-DNP3-IEC-62351-8-certificates.patch b/SOURCES/0049-Add-profile-for-DNP3-IEC-62351-8-certificates.patch
deleted file mode 100644
index 89d69ff..0000000
--- a/SOURCES/0049-Add-profile-for-DNP3-IEC-62351-8-certificates.patch
+++ /dev/null
@@ -1,180 +0,0 @@
-From cfd3cbe627870f6a575e1fbdc52896c22bce4dcd Mon Sep 17 00:00:00 2001
-From: Fraser Tweedale <ftweedal@redhat.com>
-Date: Fri, 24 Jul 2015 09:32:51 -0400
-Subject: [PATCH] Add profile for DNP3 / IEC 62351-8 certificates
-
-The DNP3 smart-grid standard uses certificate with the IEC 62351-8
-IECUserRoles extension.  Add a profile for DNP3 certificates which
-copies the IECUserRoles extension from the CSR, if present.
-
-Also update cert-request to accept CSRs containing this extension.
-
-Fixes: https://fedorahosted.org/freeipa/ticket/4752
-Reviewed-By: Martin Babinsky <mbabinsk@redhat.com>
----
- install/share/profiles/IECUserRoles.cfg | 114 ++++++++++++++++++++++++++++++++
- install/share/profiles/Makefile.am      |   1 +
- ipalib/plugins/cert.py                  |   1 +
- ipapython/dogtag.py                     |   1 +
- 4 files changed, 117 insertions(+)
- create mode 100644 install/share/profiles/IECUserRoles.cfg
-
-diff --git a/install/share/profiles/IECUserRoles.cfg b/install/share/profiles/IECUserRoles.cfg
-new file mode 100644
-index 0000000000000000000000000000000000000000..9d2b4bb7932db42f6fc1f4e8edbc2bb741d8d8b6
---- /dev/null
-+++ b/install/share/profiles/IECUserRoles.cfg
-@@ -0,0 +1,114 @@
-+profileId=IECUserRoles
-+classId=caEnrollImpl
-+desc=Enroll user certificates with IECUserRoles extension via 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,12
-+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
-+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
-+policyset.serverCertSet.12.constraint.class_id=noConstraintImpl
-+policyset.serverCertSet.12.constraint.name=No Constraint
-+policyset.serverCertSet.12.default.class_id=userExtensionDefaultImpl
-+policyset.serverCertSet.12.default.name=IECUserRoles Extension Default
-+policyset.serverCertSet.12.default.params.userExtOID=1.2.840.10070.8.1
-diff --git a/install/share/profiles/Makefile.am b/install/share/profiles/Makefile.am
-index 4e6cf975a0f51d02ec29bd07ac8cb9ccc8320818..b5ccb6e9317a93c040b7de0e0bc1ca5cb88c33fc 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		\
-+	IECUserRoles.cfg		\
- 	$(NULL)
- 
- EXTRA_DIST =				\
-diff --git a/ipalib/plugins/cert.py b/ipalib/plugins/cert.py
-index d612e9d38da44e4fd4768d286f930e51c71a1031..b6e6d7981846778896eabce1a29a88fdf9a639e1 100644
---- a/ipalib/plugins/cert.py
-+++ b/ipalib/plugins/cert.py
-@@ -312,6 +312,7 @@ class cert_request(VirtualCommand):
-         '2.5.29.17': 'request certificate with subjectaltname',
-         '2.5.29.19': None,      # Basic Constraints
-         '2.5.29.37': None,      # Extended Key Usage
-+        '1.2.840.10070.8.1': None, # IECUserRoles (DNP3 / IEC 62351-8)
-     }
- 
-     def execute(self, csr, **kw):
-diff --git a/ipapython/dogtag.py b/ipapython/dogtag.py
-index 53085f7762fc828ed9fc6621fbf3a0c67ec6a656..0782d360ccf2ce2c90c4e9cfa66b5159e437e77c 100644
---- a/ipapython/dogtag.py
-+++ b/ipapython/dogtag.py
-@@ -45,6 +45,7 @@ from ipapython.ipa_log_manager import *
- INCLUDED_PROFILES = {
-     # ( profile_id    ,         description      ,      store_issued)
-     (u'caIPAserviceCert', u'Standard profile for network services', True),
-+    (u'IECUserRoles', u'User profile that includes IECUserRoles extension from request', True),
-     }
- 
- DEFAULT_PROFILE = u'caIPAserviceCert'
--- 
-2.4.3
-
diff --git a/SOURCES/0049-Update-ipa-replica-install-documentation.patch b/SOURCES/0049-Update-ipa-replica-install-documentation.patch
new file mode 100644
index 0000000..eb68a96
--- /dev/null
+++ b/SOURCES/0049-Update-ipa-replica-install-documentation.patch
@@ -0,0 +1,45 @@
+From 2c82ea7bd562c34fd6ea9476b3b9b25f399bb0f1 Mon Sep 17 00:00:00 2001
+From: Tomas Krizek <tkrizek@redhat.com>
+Date: Fri, 5 Aug 2016 09:25:05 +0200
+Subject: [PATCH] Update ipa-replica-install documentation
+
+Update the ipa-replica-install man page and help to reflect that replica_file
+is optional instead of mandatory.
+
+https://fedorahosted.org/freeipa/ticket/6164
+
+Reviewed-By: Martin Basti <mbasti@redhat.com>
+---
+ install/tools/ipa-replica-install       | 2 +-
+ install/tools/man/ipa-replica-install.1 | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/install/tools/ipa-replica-install b/install/tools/ipa-replica-install
+index 17fc957a583739bbda386676f44209e196282a9a..b3f0361c6577cb693dcc0d81d8ca95b0c220679e 100755
+--- a/install/tools/ipa-replica-install
++++ b/install/tools/ipa-replica-install
+@@ -27,7 +27,7 @@ ReplicaInstall = cli.install_tool(
+     Replica,
+     command_name='ipa-replica-install',
+     positional_arguments=['replica_file'],
+-    usage='%prog [options] REPLICA_FILE',
++    usage='%prog [options] [REPLICA_FILE]',
+     log_file_name=paths.IPAREPLICA_INSTALL_LOG,
+     debug_option=True,
+ )
+diff --git a/install/tools/man/ipa-replica-install.1 b/install/tools/man/ipa-replica-install.1
+index 55bae2cb77e1a1c520e0598983b8939a919a9ee9..af37b07956691aeb676bb8e41e90f6ce783a5270 100644
+--- a/install/tools/man/ipa-replica-install.1
++++ b/install/tools/man/ipa-replica-install.1
+@@ -22,7 +22,7 @@ ipa\-replica\-install \- Create an IPA replica
+ .SH "SYNOPSIS"
+ .SS "DOMAIN LEVEL 0"
+ .TP
+-ipa\-replica\-install [\fIOPTION\fR]... replica_file
++ipa\-replica\-install [\fIOPTION\fR]... [replica_file]
+ .SS "DOMAIN LEVEL 1"
+ .TP
+ ipa\-replica\-install [\fIOPTION\fR]...
+-- 
+2.7.4
+
diff --git a/SOURCES/0050-Work-around-python-nss-bug-on-unrecognised-OIDs.patch b/SOURCES/0050-Work-around-python-nss-bug-on-unrecognised-OIDs.patch
deleted file mode 100644
index afa5653..0000000
--- a/SOURCES/0050-Work-around-python-nss-bug-on-unrecognised-OIDs.patch
+++ /dev/null
@@ -1,50 +0,0 @@
-From 688660a0545f5a29b6f4f2f06bbef23d3dbef688 Mon Sep 17 00:00:00 2001
-From: Fraser Tweedale <ftweedal@redhat.com>
-Date: Fri, 24 Jul 2015 09:23:07 -0400
-Subject: [PATCH] Work around python-nss bug on unrecognised OIDs
-
-A bug in python-nss causes an error to be thrown when converting an
-unrecognised OID to a string.  If cert-request receives a PKCS #10
-CSR with an unknown extension, the error is thrown.
-
-Work around this error by first checking if the OID is recognised
-and, if it is not, using a different method to obtain its string
-representation.
-
-Once the python-nss bug is fixed, this workaround should be
-reverted.  https://bugzilla.redhat.com/show_bug.cgi?id=1246729
-
-Reviewed-By: Martin Babinsky <mbabinsk@redhat.com>
----
- ipalib/pkcs10.py | 15 ++++++++++++++-
- 1 file changed, 14 insertions(+), 1 deletion(-)
-
-diff --git a/ipalib/pkcs10.py b/ipalib/pkcs10.py
-index 6299dfea43b7a3f4104f0b0ec78c4f105d9daf62..64670835127e96f1d724c5f32ed7a939d37b7f16 100644
---- a/ipalib/pkcs10.py
-+++ b/ipalib/pkcs10.py
-@@ -53,7 +53,20 @@ def get_extensions(csr, datatype=PEM):
-     The return value is a tuple of strings
-     """
-     request = load_certificate_request(csr, datatype)
--    return tuple(nss.oid_dotted_decimal(ext.oid_tag)[4:]
-+
-+    # Work around a bug in python-nss where nss.oid_dotted_decimal
-+    # errors on unrecognised OIDs
-+    #
-+    # https://bugzilla.redhat.com/show_bug.cgi?id=1246729
-+    #
-+    def get_prefixed_oid_str(ext):
-+        """Returns a string like 'OID.1.2...'."""
-+        if ext.oid_tag == 0:
-+            return repr(ext)
-+        else:
-+            return nss.oid_dotted_decimal(ext.oid)
-+
-+    return tuple(get_prefixed_oid_str(ext)[4:]
-                  for ext in request.extensions)
- 
- class _PrincipalName(univ.Sequence):
--- 
-2.4.3
-
diff --git a/SOURCES/0050-ipa-kdb-Fix-unit-test-after-packaging-changes-in-krb.patch b/SOURCES/0050-ipa-kdb-Fix-unit-test-after-packaging-changes-in-krb.patch
new file mode 100644
index 0000000..28a3b5d
--- /dev/null
+++ b/SOURCES/0050-ipa-kdb-Fix-unit-test-after-packaging-changes-in-krb.patch
@@ -0,0 +1,29 @@
+From 92c1f960cd31417d898230f9cb538dc2336ba590 Mon Sep 17 00:00:00 2001
+From: Lukas Slebodnik <lslebodn@redhat.com>
+Date: Fri, 5 Aug 2016 08:34:23 +0200
+Subject: [PATCH] ipa-kdb: Fix unit test after packaging changes in krb5
+
+Resolves:
+https://fedorahosted.org/freeipa/ticket/6173
+
+Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
+---
+ freeipa.spec.in | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/freeipa.spec.in b/freeipa.spec.in
+index ff27a32eebcc640cdbc8895f47732f06a90c4a1b..e1d98a44d04804a6bb2d4b17206aa7c280d64eb9 100644
+--- a/freeipa.spec.in
++++ b/freeipa.spec.in
+@@ -108,6 +108,8 @@ BuildRequires:  python-netifaces >= 0.10.4
+ # Build dependencies for unit tests
+ BuildRequires:  libcmocka-devel
+ BuildRequires:  nss_wrapper
++# Required by ipa_kdb_tests
++BuildRequires:  %{_libdir}/krb5/plugins/kdb/db2.so
+ 
+ %if 0%{?with_python3}
+ BuildRequires:  python3-devel
+-- 
+2.7.4
+
diff --git a/SOURCES/0051-Improvements-for-the-ipa-cacert-manage-man-and-help.patch b/SOURCES/0051-Improvements-for-the-ipa-cacert-manage-man-and-help.patch
new file mode 100644
index 0000000..9945b12
--- /dev/null
+++ b/SOURCES/0051-Improvements-for-the-ipa-cacert-manage-man-and-help.patch
@@ -0,0 +1,117 @@
+From 57f643fa5ba0382bbe8a35bd3cc6fe7bec721064 Mon Sep 17 00:00:00 2001
+From: Stanislav Laznicka <slaznick@redhat.com>
+Date: Fri, 15 Jul 2016 14:04:59 +0200
+Subject: [PATCH] Improvements for the ipa-cacert-manage man and help
+
+The man page for ipa-cacert-manage didn't mention that some
+options are only applicable to the install some to the renew
+subcommand.
+
+Also fixed a few missing articles.
+
+https://fedorahosted.org/freeipa/ticket/6013
+
+Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
+---
+ install/tools/man/ipa-cacert-manage.1  | 38 ++++++++++++++++++++++------------
+ ipaserver/install/ipa_cacert_manage.py |  2 +-
+ 2 files changed, 26 insertions(+), 14 deletions(-)
+
+diff --git a/install/tools/man/ipa-cacert-manage.1 b/install/tools/man/ipa-cacert-manage.1
+index 1f37788336048e412eee71757f236c9944860514..f0a1033ab372c2f923a883b385c0e3304b98f56f 100644
+--- a/install/tools/man/ipa-cacert-manage.1
++++ b/install/tools/man/ipa-cacert-manage.1
+@@ -20,7 +20,9 @@
+ .SH "NAME"
+ ipa\-cacert\-manage \- Manage CA certificates in IPA
+ .SH "SYNOPSIS"
+-\fBipa\-cacert\-manage\fR [\fIOPTIONS\fR...] \fICOMMAND\fR
++\fBipa\-cacert\-manage\fR [\fIOPTIONS\fR...] renew
++.RE
++\fBipa\-cacert\-manage\fR [\fIOPTIONS\fR...] install \fICERTFILE\fR
+ .SH "DESCRIPTION"
+ \fBipa\-cacert\-manage\fR can be used to manage CA certificates in IPA.
+ .SH "COMMANDS"
+@@ -29,7 +31,7 @@ ipa\-cacert\-manage \- Manage CA certificates in IPA
+ \- Renew the IPA CA certificate
+ .sp
+ .RS
+-This command can be used to manually renew CA certificate of the IPA CA.
++This command can be used to manually renew the CA certificate of the IPA CA.
+ .sp
+ When the IPA CA is the root CA (the default), it is not usually necessary to manually renew the CA certificate, as it will be renewed automatically when it is about to expire, but you can do so if you wish.
+ .sp
+@@ -42,13 +44,30 @@ When the IPA CA is not configured, this command is not available.
+ \- Install a CA certificate
+ .sp
+ .RS
+-This command can be used to install new CA certificate to IPA.
++This command can be used to install the certificate contained in \fICERTFILE\fR as a new CA certificate to IPA.
+ .RE
+-.SH "OPTIONS"
++.SH "COMMON 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\-p\fR \fIDM_PASSWORD\fR, \fB\-\-password\fR=\fIDM_PASSWORD\fR
+ The Directory Manager password to use for authentication.
+ .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.
++.RE
++.SH "RENEW OPTIONS"
++.TP
+ \fB\-\-self\-signed\fR
+ Sign the renewed certificate by itself.
+ .TP
+@@ -57,6 +76,8 @@ Sign the renewed certificate by external CA.
+ .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
++.SH "INSTALL OPTIONS"
+ .TP
+ \fB\-n\fR \fINICKNAME\fR, \fB\-\-nickname\fR=\fINICKNAME\fR
+ Nickname for the certificate.
+@@ -73,15 +94,6 @@ T \- CA trusted to issue client certificates
+ .IP
+ p \- not trusted
+ .RE
+-.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
+ 
+diff --git a/ipaserver/install/ipa_cacert_manage.py b/ipaserver/install/ipa_cacert_manage.py
+index de13ad39397ae5e9b924b0621521e5fc6016c8e6..32ef25c7aac3e57d27955b6a2608adb6a1626019 100644
+--- a/ipaserver/install/ipa_cacert_manage.py
++++ b/ipaserver/install/ipa_cacert_manage.py
+@@ -35,7 +35,7 @@ from ipaserver.install import certs, cainstance, installutils
+ class CACertManage(admintool.AdminTool):
+     command_name = 'ipa-cacert-manage'
+ 
+-    usage = "%prog {renew|install} [options]"
++    usage = "%prog renew [options]\n%prog install [options] CERTFILE"
+ 
+     description = "Manage CA certificates."
+ 
+-- 
+2.7.4
+
diff --git a/SOURCES/0051-adtrust-install-Correctly-determine-4.2-FreeIPA-serv.patch b/SOURCES/0051-adtrust-install-Correctly-determine-4.2-FreeIPA-serv.patch
deleted file mode 100644
index 6c46e62..0000000
--- a/SOURCES/0051-adtrust-install-Correctly-determine-4.2-FreeIPA-serv.patch
+++ /dev/null
@@ -1,35 +0,0 @@
-From 6cc7d00a8d6966b4be24fa9b3df12dcba094b6ef Mon Sep 17 00:00:00 2001
-From: Tomas Babej <tbabej@redhat.com>
-Date: Tue, 11 Aug 2015 16:05:32 +0200
-Subject: [PATCH] adtrust-install: Correctly determine 4.2 FreeIPA servers
-
-We need to detect a list of FreeIPA 4.2 (and above) servers, since
-only there is the required version of SSSD present.
-
-Since the maximum domain level for 4.2 is 0 (and not 1), we can filter
-for any value of ipaMaxDomainLevel / ipaMinDomainLevel attributes
-to generate the list.
-
-https://fedorahosted.org/freeipa/ticket/5199
-
-Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
----
- install/tools/ipa-adtrust-install | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/install/tools/ipa-adtrust-install b/install/tools/ipa-adtrust-install
-index 5340c31d16ed78da0cb39725d9ae93c76470b698..21e58dd9f25e82429ce8d0c776d1b512c2661809 100755
---- a/install/tools/ipa-adtrust-install
-+++ b/install/tools/ipa-adtrust-install
-@@ -396,7 +396,7 @@ def main():
-             # Search only masters which have support for domain levels
-             # because only these masters will have SSSD recent enough to support AD trust agents
-             (entries_m, truncated) = smb.admin_conn.find_entries(
--                filter="(&(objectclass=ipaSupportedDomainLevelConfig)(!(ipaMaxDomainLevel=0)))",
-+                filter="(&(objectclass=ipaSupportedDomainLevelConfig)(ipaMaxDomainLevel=*)(ipaMinDomainLevel=*))",
-                 base_dn=masters_dn, attrs_list=['cn'], scope=ldap.SCOPE_ONELEVEL)
-         except errors.NotFound:
-             pass
--- 
-2.4.3
-
diff --git a/SOURCES/0052-Revert-spec-add-conflict-with-bind-chroot-to-freeipa.patch b/SOURCES/0052-Revert-spec-add-conflict-with-bind-chroot-to-freeipa.patch
new file mode 100644
index 0000000..98c97b7
--- /dev/null
+++ b/SOURCES/0052-Revert-spec-add-conflict-with-bind-chroot-to-freeipa.patch
@@ -0,0 +1,35 @@
+From 61746b75a7b10115633df2f9dce075c0bbdf161e Mon Sep 17 00:00:00 2001
+From: Jan Cholasta <jcholast@redhat.com>
+Date: Tue, 9 Aug 2016 14:12:50 +0200
+Subject: [PATCH] Revert "spec: add conflict with bind-chroot to
+ freeipa-server-dns"
+
+Remove the conflict, as bind-chroot caused issue only on systems with older
+bind and bind-chroot - e.g. RHEL 6.
+
+This reverts commit 3ab63fa6ba60947b1452c2108c4cf7637f4aacdb.
+
+https://fedorahosted.org/freeipa/ticket/5696
+
+Reviewed-By: Petr Spacek <pspacek@redhat.com>
+---
+ freeipa.spec.in | 3 ---
+ 1 file changed, 3 deletions(-)
+
+diff --git a/freeipa.spec.in b/freeipa.spec.in
+index e1d98a44d04804a6bb2d4b17206aa7c280d64eb9..77fca24ef0e1e244e53d203a228931b4a444fb5a 100644
+--- a/freeipa.spec.in
++++ b/freeipa.spec.in
+@@ -274,9 +274,6 @@ Obsoletes: %{alt_name}-server-dns < %{version}
+ # upgrade path from monolithic -server to -server + -server-dns
+ Obsoletes: %{name}-server <= 4.2.0
+ 
+-# FreeIPA does not support running integrated BIND in chroot jail
+-Conflicts: bind-chroot
+-
+ %description server-dns
+ IPA integrated DNS server with support for automatic DNSSEC signing.
+ Integrated DNS server is BIND 9. OpenDNSSEC provides key management.
+-- 
+2.7.4
+
diff --git a/SOURCES/0052-certprofile-import-improve-profile-format-documentat.patch b/SOURCES/0052-certprofile-import-improve-profile-format-documentat.patch
deleted file mode 100644
index e5e3287..0000000
--- a/SOURCES/0052-certprofile-import-improve-profile-format-documentat.patch
+++ /dev/null
@@ -1,31 +0,0 @@
-From c6c3ee0658fcda223bd98fed8d696bdb26add4ac Mon Sep 17 00:00:00 2001
-From: Christian Heimes <cheimes@redhat.com>
-Date: Thu, 23 Jul 2015 18:22:19 +0200
-Subject: [PATCH] certprofile-import: improve profile format documentation
-
-The certprofile-import plugin expects a raw Dogtag config file. The XML
-format is not supported. --help gives a hint about the correct file format.
-
-https://fedorahosted.org/freeipa/ticket/5089
-
-Reviewed-By: Fraser Tweedale <ftweedal@redhat.com>
----
- ipalib/plugins/certprofile.py | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/ipalib/plugins/certprofile.py b/ipalib/plugins/certprofile.py
-index b0b76ca8e78f2482b5c08dad21d9161fd4c2c2d0..658fbca3b4eb851eb5a22190c443044f6ceb8491 100644
---- a/ipalib/plugins/certprofile.py
-+++ b/ipalib/plugins/certprofile.py
-@@ -221,7 +221,7 @@ class certprofile_import(LDAPCreate):
-     msg_summary = _('Imported profile "%(value)s"')
-     takes_options = (
-         File('file',
--            label=_('Filename'),
-+            label=_('Filename of a raw profile. The XML format is not supported.'),
-             cli_name='file',
-             flags=('virtual_attribute',),
-         ),
--- 
-2.4.3
-
diff --git a/SOURCES/0053-Fix-default-CA-ACL-added-during-upgrade.patch b/SOURCES/0053-Fix-default-CA-ACL-added-during-upgrade.patch
deleted file mode 100644
index 7aa2975..0000000
--- a/SOURCES/0053-Fix-default-CA-ACL-added-during-upgrade.patch
+++ /dev/null
@@ -1,31 +0,0 @@
-From 3e8d1d09e5a1b19c64a0356d2b19dac74c20ad73 Mon Sep 17 00:00:00 2001
-From: Fraser Tweedale <ftweedal@redhat.com>
-Date: Fri, 7 Aug 2015 03:21:43 -0400
-Subject: [PATCH] Fix default CA ACL added during upgrade
-
-The upgrade script is adding the default CA ACL with incorrect
-attributes - usercategory=all instead of servicecategory=all.  Fix
-it to create the correct object.
-
-Fixes: https://fedorahosted.org/freeipa/ticket/5185
-Reviewed-By: Martin Babinsky <mbabinsk@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 037127918cb4c205c5049446989bfdaa674967a4..692d0c77e0683f4ad35ebbc14d5a34decc098deb 100644
---- a/ipaserver/install/server/upgrade.py
-+++ b/ipaserver/install/server/upgrade.py
-@@ -1306,7 +1306,7 @@ def add_default_caacl(ca):
- 
-         if not api.Command.caacl_find()['result']:
-             api.Command.caacl_add(u'hosts_services_caIPAserviceCert',
--                hostcategory=u'all', usercategory=u'all')
-+                hostcategory=u'all', servicecategory=u'all')
-             api.Command.caacl_add_profile(u'hosts_services_caIPAserviceCert',
-                 certprofile=(u'caIPAserviceCert',))
- 
--- 
-2.4.3
-
diff --git a/SOURCES/0053-Fix-unicode-characters-in-ca-and-domain-adders.patch b/SOURCES/0053-Fix-unicode-characters-in-ca-and-domain-adders.patch
new file mode 100644
index 0000000..f32cb64
--- /dev/null
+++ b/SOURCES/0053-Fix-unicode-characters-in-ca-and-domain-adders.patch
@@ -0,0 +1,41 @@
+From 8163981ec3296c6768cacad2ac7382ae2c706853 Mon Sep 17 00:00:00 2001
+From: Pavel Vomacka <pvomacka@redhat.com>
+Date: Fri, 5 Aug 2016 14:04:03 +0200
+Subject: [PATCH] Fix unicode characters in ca and domain adders
+
+Topology graph didn't show plus icons correctly.
+
+There is a problem with uglifying of javascript code. It does not leave unicode character
+written in hexadecimal format unchanged. Therefore this workaround which inserts
+needed character using Javascript function and uglifiyng does not affect it.
+
+https://fedorahosted.org/freeipa/ticket/6175
+
+Reviewed-By: Martin Basti <mbasti@redhat.com>
+---
+ install/ui/src/freeipa/topology_graph.js | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/install/ui/src/freeipa/topology_graph.js b/install/ui/src/freeipa/topology_graph.js
+index ce2ebeaff611987ae27f2655b5da80bdcd1b4f8a..4bc3668647979c77719efa78b7a663d0e899216e 100644
+--- a/install/ui/src/freeipa/topology_graph.js
++++ b/install/ui/src/freeipa/topology_graph.js
+@@ -530,12 +530,14 @@ topology_graph.TopoGraph = declare([Evented], {
+ 
+         function add_labels(type, color, adder_group) {
+             var label_radius = 3;
++            var decimal_plus = parseInt('f067', 16); // Converts hexadecimal
++            // code of plus icon to decimal.
+ 
+             var plus = adder_group
+                 .append('text')
+                 .classed('plus', true)
+                 .classed(type + '_plus', true)
+-                .text('\uf067');
++                .text(String.fromCharCode(decimal_plus));
+ 
+             var label = adder_group.append('path')
+                     .attr('id', type + '_label');
+-- 
+2.7.4
+
diff --git a/SOURCES/0054-Fix-KRB5PrincipalName-UPN-SAN-comparison.patch b/SOURCES/0054-Fix-KRB5PrincipalName-UPN-SAN-comparison.patch
deleted file mode 100644
index c17d7cf..0000000
--- a/SOURCES/0054-Fix-KRB5PrincipalName-UPN-SAN-comparison.patch
+++ /dev/null
@@ -1,35 +0,0 @@
-From 34be9a7cd6eb4f379f09fd40d723fa83317f2b61 Mon Sep 17 00:00:00 2001
-From: Fraser Tweedale <ftweedal@redhat.com>
-Date: Sun, 9 Aug 2015 05:55:04 -0400
-Subject: [PATCH] Fix KRB5PrincipalName / UPN SAN comparison
-
-Depending on how the target principal name is conveyed to the
-command (i.e. with / without realm), the KRB5PrincipalName / UPN
-subjectAltName validation could be comparing unequal strings and
-erroneously rejecting a valid request.
-
-Normalise both side of the comparison to ensure that the principal
-names contain realm information.
-
-Fixes: https://fedorahosted.org/freeipa/ticket/5191
-Reviewed-By: Martin Babinsky <mbabinsk@redhat.com>
----
- ipalib/plugins/cert.py | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/ipalib/plugins/cert.py b/ipalib/plugins/cert.py
-index b6e6d7981846778896eabce1a29a88fdf9a639e1..610f2149363eaa74180e9de5c9ee1439446ef409 100644
---- a/ipalib/plugins/cert.py
-+++ b/ipalib/plugins/cert.py
-@@ -474,7 +474,7 @@ class cert_request(VirtualCommand):
-                         principal_type, alt_principal_string, ca, profile_id)
-             elif name_type in (pkcs10.SAN_OTHERNAME_KRB5PRINCIPALNAME,
-                                pkcs10.SAN_OTHERNAME_UPN):
--                if name != principal_string:
-+                if split_any_principal(name) != principal:
-                     raise errors.ACIError(
-                         info=_("Principal '%s' in subject alt name does not "
-                                "match requested principal") % name)
--- 
-2.4.3
-
diff --git a/SOURCES/0054-ipa-backup-backup-etc-tmpfiles.d-dirsrv-instance-.co.patch b/SOURCES/0054-ipa-backup-backup-etc-tmpfiles.d-dirsrv-instance-.co.patch
new file mode 100644
index 0000000..f54e563
--- /dev/null
+++ b/SOURCES/0054-ipa-backup-backup-etc-tmpfiles.d-dirsrv-instance-.co.patch
@@ -0,0 +1,52 @@
+From 7422ad189f90d596fcda93da97ae1cd152df4df3 Mon Sep 17 00:00:00 2001
+From: Martin Basti <mbasti@redhat.com>
+Date: Fri, 5 Aug 2016 17:35:49 +0200
+Subject: [PATCH] ipa-backup: backup /etc/tmpfiles.d/dirsrv-<instance>.conf
+
+This file allows daemon tmpfiles.d to re-create the dirs in volatile
+directories like /var/run or /var/lock. Without this file Dirsrv will
+not start.
+
+https://fedorahosted.org/freeipa/ticket/6165
+
+Reviewed-By: Petr Spacek <pspacek@redhat.com>
+---
+ ipaplatform/base/paths.py       | 1 +
+ ipaserver/install/ipa_backup.py | 9 ++++++---
+ 2 files changed, 7 insertions(+), 3 deletions(-)
+
+diff --git a/ipaplatform/base/paths.py b/ipaplatform/base/paths.py
+index 9c8eaf951df89d373796be3f354bd3c51a329902..5ffe689950792a40c179533c8baf2794c2388696 100644
+--- a/ipaplatform/base/paths.py
++++ b/ipaplatform/base/paths.py
+@@ -132,6 +132,7 @@ class BasePathNamespace(object):
+     SYSTEMD_IPA_SERVICE = "/etc/systemd/system/multi-user.target.wants/ipa.service"
+     SYSTEMD_SSSD_SERVICE = "/etc/systemd/system/multi-user.target.wants/sssd.service"
+     SYSTEMD_PKI_TOMCAT_SERVICE = "/etc/systemd/system/pki-tomcatd.target.wants/pki-tomcatd@pki-tomcat.service"
++    ETC_TMPFILESD_DIRSRV = "/etc/tmpfiles.d/dirsrv-%s.conf"
+     DNSSEC_TRUSTED_KEY = "/etc/trusted-key.key"
+     HOME_DIR = "/home"
+     PROC_FIPS_ENABLED = "/proc/sys/crypto/fips_enabled"
+diff --git a/ipaserver/install/ipa_backup.py b/ipaserver/install/ipa_backup.py
+index 18a60ecd13c7e7f5381b61ec70ea308a1931b7ec..9b09f4293028c3e560337ba082164b528cf76d80 100644
+--- a/ipaserver/install/ipa_backup.py
++++ b/ipaserver/install/ipa_backup.py
+@@ -337,9 +337,12 @@ class Backup(admintool.AdminTool):
+             if os.path.exists(dir):
+                 self.dirs.append(dir)
+ 
+-        file = paths.SYSCONFIG_DIRSRV_INSTANCE % serverid
+-        if os.path.exists(file):
+-            self.files.append(file)
++        for file in (
++            paths.SYSCONFIG_DIRSRV_INSTANCE % serverid,
++            paths.ETC_TMPFILESD_DIRSRV % serverid,
++        ):
++            if os.path.exists(file):
++                self.files.append(file)
+ 
+         self.logs.append(paths.VAR_LOG_DIRSRV_INSTANCE_TEMPLATE % serverid)
+ 
+-- 
+2.7.4
+
diff --git a/SOURCES/0055-adjust-search-so-that-it-works-for-non-admin-users.patch b/SOURCES/0055-adjust-search-so-that-it-works-for-non-admin-users.patch
deleted file mode 100644
index 26d1181..0000000
--- a/SOURCES/0055-adjust-search-so-that-it-works-for-non-admin-users.patch
+++ /dev/null
@@ -1,95 +0,0 @@
-From 6c1ae29831a5fdea5a81412042ea73cc5df9f397 Mon Sep 17 00:00:00 2001
-From: Petr Vobornik <pvoborni@redhat.com>
-Date: Wed, 12 Aug 2015 10:35:38 +0200
-Subject: [PATCH] adjust search so that it works for non-admin users
-
-Non-admin user can now search for:
-- hosts
-- hostgroups
-- netgroups
-- servers
-- services
-
-(Fixes ACI issue where search returns nothing when user does't have
-read rights for an attribute in search_attributes.
-
-https://fedorahosted.org/freeipa/ticket/5167
-
-Reviewed-By: Tomas Babej <tbabej@redhat.com>
----
- ipalib/plugins/host.py      | 2 +-
- ipalib/plugins/hostgroup.py | 1 +
- ipalib/plugins/netgroup.py  | 4 ++++
- ipalib/plugins/server.py    | 1 +
- ipalib/plugins/service.py   | 3 +--
- 5 files changed, 8 insertions(+), 3 deletions(-)
-
-diff --git a/ipalib/plugins/host.py b/ipalib/plugins/host.py
-index 410b4bd120743a6ad5787fbd2a55534b4f108601..3e882aefd210df73b7ffd15b5a4c1d2fc4173536 100644
---- a/ipalib/plugins/host.py
-+++ b/ipalib/plugins/host.py
-@@ -292,7 +292,7 @@ class host(LDAPObject):
-     # object_class_config = 'ipahostobjectclasses'
-     search_attributes = [
-         'fqdn', 'description', 'l', 'nshostlocation', 'krbprincipalname',
--        'nshardwareplatform', 'nsosversion', 'managedby', 'ipaallowedtoperform'
-+        'nshardwareplatform', 'nsosversion', 'managedby',
-     ]
-     default_attributes = [
-         'fqdn', 'description', 'l', 'nshostlocation', 'krbprincipalname',
-diff --git a/ipalib/plugins/hostgroup.py b/ipalib/plugins/hostgroup.py
-index fafe40ad9a8d1693505b7d90e5d8fd12202a894b..30d474d80905f02c4f88742a2677220c150b3c7f 100644
---- a/ipalib/plugins/hostgroup.py
-+++ b/ipalib/plugins/hostgroup.py
-@@ -78,6 +78,7 @@ class hostgroup(LDAPObject):
-     object_name_plural = _('host groups')
-     object_class = ['ipaobject', 'ipahostgroup']
-     permission_filter_objectclasses = ['ipahostgroup']
-+    search_attributes = ['cn', 'description', 'member', 'memberof']
-     default_attributes = ['cn', 'description', 'member', 'memberof',
-         'memberindirect', 'memberofindirect',
-     ]
-diff --git a/ipalib/plugins/netgroup.py b/ipalib/plugins/netgroup.py
-index d535b383e048fd12d08bde9247f158d183a5bcad..e69aaf94a035d0c4af28585f84b4b1f8105b3fc3 100644
---- a/ipalib/plugins/netgroup.py
-+++ b/ipalib/plugins/netgroup.py
-@@ -86,6 +86,10 @@ class netgroup(LDAPObject):
-     object_name_plural = _('netgroups')
-     object_class = ['ipaobject', 'ipaassociation', 'ipanisnetgroup']
-     permission_filter_objectclasses = ['ipanisnetgroup']
-+    search_attributes = [
-+        'cn', 'description', 'memberof', 'externalhost', 'nisdomainname',
-+        'memberuser', 'memberhost', 'member', 'usercategory', 'hostcategory',
-+    ]
-     default_attributes = [
-         'cn', 'description', 'memberof', 'externalhost', 'nisdomainname',
-         'memberuser', 'memberhost', 'member', 'memberindirect',
-diff --git a/ipalib/plugins/server.py b/ipalib/plugins/server.py
-index 7fc44197343dbb651782fbf79993cbbe8818efed..5808c9c5ea78fce4a15cd2e49740fbe20bca8358 100644
---- a/ipalib/plugins/server.py
-+++ b/ipalib/plugins/server.py
-@@ -38,6 +38,7 @@ class server(LDAPObject):
-     object_name = _('server')
-     object_name_plural = _('servers')
-     object_class = ['top']
-+    search_attributes = ['cn']
-     default_attributes = [
-         'cn', 'iparepltopomanagedsuffix', 'ipamindomainlevel',
-         'ipamaxdomainlevel'
-diff --git a/ipalib/plugins/service.py b/ipalib/plugins/service.py
-index a5e10921beac8b232f6b74640ef17713f7297a3d..a21d004c8a70d50385c94b12447d5fd5bc0851b4 100644
---- a/ipalib/plugins/service.py
-+++ b/ipalib/plugins/service.py
-@@ -391,8 +391,7 @@ class service(LDAPObject):
-     ]
-     possible_objectclasses = ['ipakrbprincipal', 'ipaallowedoperations']
-     permission_filter_objectclasses = ['ipaservice']
--    search_attributes = ['krbprincipalname', 'managedby', 'ipakrbauthzdata',
--        'ipaallowedtoperform']
-+    search_attributes = ['krbprincipalname', 'managedby', 'ipakrbauthzdata']
-     default_attributes = ['krbprincipalname', 'usercertificate', 'managedby',
-         'ipakrbauthzdata', 'memberof', 'ipaallowedtoperform']
-     uuid_attribute = 'ipauniqueid'
--- 
-2.4.3
-
diff --git a/SOURCES/0055-client-RPM-require-initscripts-to-get-domainname.ser.patch b/SOURCES/0055-client-RPM-require-initscripts-to-get-domainname.ser.patch
new file mode 100644
index 0000000..a60ff94
--- /dev/null
+++ b/SOURCES/0055-client-RPM-require-initscripts-to-get-domainname.ser.patch
@@ -0,0 +1,28 @@
+From 99105177385dbed1082db8676a1ff052e99e1eda Mon Sep 17 00:00:00 2001
+From: Petr Spacek <pspacek@redhat.com>
+Date: Mon, 8 Aug 2016 13:13:18 +0200
+Subject: [PATCH] client: RPM require initscripts to get *-domainname.service
+
+https://fedorahosted.org/freeipa/ticket/4831
+
+Reviewed-By: Jan Cholasta <jcholast@redhat.com>
+---
+ freeipa.spec.in | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/freeipa.spec.in b/freeipa.spec.in
+index 77fca24ef0e1e244e53d203a228931b4a444fb5a..29b63c9300b73d82aea88dbcf50f2f6ab5f9e9bd 100644
+--- a/freeipa.spec.in
++++ b/freeipa.spec.in
+@@ -324,6 +324,8 @@ Requires: krb5-workstation
+ Requires: authconfig
+ Requires: pam_krb5
+ Requires: curl
++# NIS domain name config: /usr/lib/systemd/system/*-domainname.service
++Requires: initscripts
+ Requires: libcurl >= 7.21.7-2
+ Requires: xmlrpc-c >= 1.27.4
+ Requires: sssd >= 1.14.0
+-- 
+2.7.4
+
diff --git a/SOURCES/0056-parameters-move-the-confirm-kwarg-to-Param.patch b/SOURCES/0056-parameters-move-the-confirm-kwarg-to-Param.patch
new file mode 100644
index 0000000..bc1a5cc
--- /dev/null
+++ b/SOURCES/0056-parameters-move-the-confirm-kwarg-to-Param.patch
@@ -0,0 +1,89 @@
+From c7b4c108ddd76d5ac02e2242a7eccb3acf3efce5 Mon Sep 17 00:00:00 2001
+From: Jan Cholasta <jcholast@redhat.com>
+Date: Mon, 8 Aug 2016 13:09:39 +0200
+Subject: [PATCH] parameters: move the `confirm` kwarg to Param
+
+Whether a parameter is treated like password is determined by the
+`password` class attribute defined in the Param class. Whether the CLI will
+asks for confirmation of a password parameter depends on the value of the
+`confirm` kwarg of the Password class.
+
+Move the `confirm` kwarg from the Password class to the Param class, so
+that it can be used by any Param subclass which has the `password` class
+attribute set to True.
+
+This fixes confirmation of the --key option of otptoken-add, which is a
+Bytes subclass with `password` set to True.
+
+https://fedorahosted.org/freeipa/ticket/6174
+
+Reviewed-By: Martin Basti <mbasti@redhat.com>
+Reviewed-By: David Kupka <dkupka@redhat.com>
+---
+ ipaclient/remote_plugins/schema.py | 2 +-
+ ipalib/parameters.py               | 6 ++----
+ ipaserver/plugins/otptoken.py      | 4 ----
+ 3 files changed, 3 insertions(+), 9 deletions(-)
+
+diff --git a/ipaclient/remote_plugins/schema.py b/ipaclient/remote_plugins/schema.py
+index cd1d5d607978899254325f634ccec91d2c92f59b..0301e54127dc236ebc14e1409484626f1427800d 100644
+--- a/ipaclient/remote_plugins/schema.py
++++ b/ipaclient/remote_plugins/schema.py
+@@ -155,7 +155,7 @@ class _SchemaPlugin(object):
+             elif key in ('cli_metavar',
+                          'cli_name'):
+                 kwargs[key] = str(value)
+-            elif key == 'confirm' and issubclass(cls, Password):
++            elif key == 'confirm':
+                 kwargs[key] = value
+             elif key == 'default':
+                 default = value
+diff --git a/ipalib/parameters.py b/ipalib/parameters.py
+index 1581b7dcac5259e5c4a127e2a38e13335002b204..6917c8d4fc117b47bddc11fbf3ea379e3c537ea4 100644
+--- a/ipalib/parameters.py
++++ b/ipalib/parameters.py
+@@ -377,6 +377,7 @@ class Param(ReadOnly):
+         parameter is not `required`
+       - sortorder: used to sort a list of parameters for Command. See
+         `Command.finalize()` for further information
++      - confirm: if password, ask for confirmation
+     """
+ 
+     # This is a dummy type so that most of the functionality of Param can be
+@@ -418,6 +419,7 @@ class Param(ReadOnly):
+         ('cli_metavar', str, None),
+         ('no_convert', bool, False),
+         ('deprecated', bool, False),
++        ('confirm', bool, True),
+ 
+         # The 'default' kwarg gets appended in Param.__init__():
+         # ('default', self.type, None),
+@@ -1511,10 +1513,6 @@ class Password(Str):
+ 
+     password = True
+ 
+-    kwargs = Str.kwargs + (
+-        ('confirm', bool, True),
+-    )
+-
+     def _convert_scalar(self, value, index=None):
+         if isinstance(value, (tuple, list)) and len(value) == 2:
+             (p1, p2) = value
+diff --git a/ipaserver/plugins/otptoken.py b/ipaserver/plugins/otptoken.py
+index 56b8c911b3492de9342946cd3e47681e99a5abef..39012e2f9106c33c520e19f14331fc440333015a 100644
+--- a/ipaserver/plugins/otptoken.py
++++ b/ipaserver/plugins/otptoken.py
+@@ -79,10 +79,6 @@ class OTPTokenKey(Bytes):
+ 
+     password = True
+ 
+-    kwargs = Bytes.kwargs + (
+-        ('confirm', bool, True),
+-    )
+-
+     def _convert_scalar(self, value, index=None):
+         if isinstance(value, (tuple, list)) and len(value) == 2:
+             (p1, p2) = value
+-- 
+2.7.4
+
diff --git a/SOURCES/0056-validate-mutually-exclusive-options-in-vault-add.patch b/SOURCES/0056-validate-mutually-exclusive-options-in-vault-add.patch
deleted file mode 100644
index 11907c5..0000000
--- a/SOURCES/0056-validate-mutually-exclusive-options-in-vault-add.patch
+++ /dev/null
@@ -1,38 +0,0 @@
-From 97f52ad53a6284b20e275e8ae28c599d96fc0b30 Mon Sep 17 00:00:00 2001
-From: Petr Vobornik <pvoborni@redhat.com>
-Date: Wed, 12 Aug 2015 11:07:22 +0200
-Subject: [PATCH] validate mutually exclusive options in vault-add
-
-https://fedorahosted.org/freeipa/ticket/5195
-
-Reviewed-By: Tomas Babej <tbabej@redhat.com>
----
- ipalib/plugins/vault.py | 12 ++++++++++++
- 1 file changed, 12 insertions(+)
-
-diff --git a/ipalib/plugins/vault.py b/ipalib/plugins/vault.py
-index fe4eec325dde4a9ecd8a7ce5af1a124fc5c6a9ae..055e8d00f1616c15b217e7570eeedd46efba7c81 100644
---- a/ipalib/plugins/vault.py
-+++ b/ipalib/plugins/vault.py
-@@ -597,6 +597,18 @@ class vault_add(PKQuery, Local):
-         if 'public_key_file' in options:
-             del options['public_key_file']
- 
-+        if vault_type != u'symmetric' and (password or password_file):
-+            raise errors.MutuallyExclusiveError(
-+                reason=_('Password can be specified only for '
-+                         'symmetric vault')
-+            )
-+
-+        if vault_type != u'asymmetric' and (public_key or public_key_file):
-+            raise errors.MutuallyExclusiveError(
-+                reason=_('Public key can be specified only for '
-+                         'asymmetric vault')
-+            )
-+
-         if self.api.env.in_server:
-             backend = self.api.Backend.ldap2
-         else:
--- 
-2.4.3
-
diff --git a/SOURCES/0057-client-add-missing-output-params-to-client-side-comm.patch b/SOURCES/0057-client-add-missing-output-params-to-client-side-comm.patch
new file mode 100644
index 0000000..c1bd136
--- /dev/null
+++ b/SOURCES/0057-client-add-missing-output-params-to-client-side-comm.patch
@@ -0,0 +1,95 @@
+From b654999d25de81e2c63b0765b6f16df2ff880144 Mon Sep 17 00:00:00 2001
+From: Jan Cholasta <jcholast@redhat.com>
+Date: Wed, 10 Aug 2016 09:02:47 +0200
+Subject: [PATCH] client: add missing output params to client-side commands
+
+Add output params for the otptoken-add-yubikey, vault-add, vault-mod,
+vault-archive and vault-retrieve commands.
+
+This fixes the commands not having any output in CLI.
+
+https://fedorahosted.org/freeipa/ticket/6182
+
+Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
+Reviewed-By: David Kupka <dkupka@redhat.com>
+---
+ ipaclient/plugins/otptoken_yubikey.py |  6 ++++++
+ ipaclient/plugins/vault.py            | 24 ++++++++++++++++++++++++
+ 2 files changed, 30 insertions(+)
+
+diff --git a/ipaclient/plugins/otptoken_yubikey.py b/ipaclient/plugins/otptoken_yubikey.py
+index 423b670de15dd7f803db1dcbb759bd0254827072..3c310eacbaeef654e43049db78437c8c29f52279 100644
+--- a/ipaclient/plugins/otptoken_yubikey.py
++++ b/ipaclient/plugins/otptoken_yubikey.py
+@@ -103,6 +103,12 @@ class otptoken_add_yubikey(Command):
+         for option in super(otptoken_add_yubikey, self).get_options():
+             yield option
+ 
++    def get_output_params(self):
++        for param in self.api.Command.otptoken_add.output_params():
++            yield param
++        for param in super(otptoken_add_yubikey, self).get_output_params():
++            yield param
++
+     def _iter_output(self):
+         return self.api.Command.otptoken_add.output()
+ 
+diff --git a/ipaclient/plugins/vault.py b/ipaclient/plugins/vault.py
+index 9026cbb0829a7557584df27a4262dfde640b4f28..3e116bbad54fea419b571d1f09c1b00280e94991 100644
+--- a/ipaclient/plugins/vault.py
++++ b/ipaclient/plugins/vault.py
+@@ -220,6 +220,12 @@ class vault_add(Local):
+         for option in super(vault_add, self).get_options():
+             yield option
+ 
++    def get_output_params(self):
++        for param in self.api.Command.vault_add_internal.output_params():
++            yield param
++        for param in super(vault_add, self).get_output_params():
++            yield param
++
+     def _iter_output(self):
+         return self.api.Command.vault_add_internal.output()
+ 
+@@ -418,6 +424,12 @@ class vault_mod(Local):
+         for option in super(vault_mod, self).get_options():
+             yield option
+ 
++    def get_output_params(self):
++        for param in self.api.Command.vault_mod_internal.output_params():
++            yield param
++        for param in super(vault_mod, self).get_output_params():
++            yield param
++
+     def _iter_output(self):
+         return self.api.Command.vault_mod_internal.output()
+ 
+@@ -600,6 +612,12 @@ class vault_archive(Local):
+         for option in super(vault_archive, self).get_options():
+             yield option
+ 
++    def get_output_params(self):
++        for param in self.api.Command.vault_archive_internal.output_params():
++            yield param
++        for param in super(vault_archive, self).get_output_params():
++            yield param
++
+     def _iter_output(self):
+         return self.api.Command.vault_archive_internal.output()
+ 
+@@ -846,6 +864,12 @@ class vault_retrieve(Local):
+         for option in super(vault_retrieve, self).get_options():
+             yield option
+ 
++    def get_output_params(self):
++        for param in self.api.Command.vault_retrieve_internal.output_params():
++            yield param
++        for param in super(vault_retrieve, self).get_output_params():
++            yield param
++
+     def _iter_output(self):
+         return self.api.Command.vault_retrieve_internal.output()
+ 
+-- 
+2.7.4
+
diff --git a/SOURCES/0057-idranges-raise-an-error-when-local-IPA-ID-range-is-b.patch b/SOURCES/0057-idranges-raise-an-error-when-local-IPA-ID-range-is-b.patch
deleted file mode 100644
index 1387dc3..0000000
--- a/SOURCES/0057-idranges-raise-an-error-when-local-IPA-ID-range-is-b.patch
+++ /dev/null
@@ -1,110 +0,0 @@
-From 887bd5f84d862dfb923c72a60b4491374be34d5f Mon Sep 17 00:00:00 2001
-From: Martin Babinsky <mbabinsk@redhat.com>
-Date: Fri, 7 Aug 2015 15:44:57 +0200
-Subject: [PATCH] idranges: raise an error when local IPA ID range is being
- modified
-
-also show the message about the way UID/GID ranges are managed in FreeIPA in
-the idrange-mod's help message
-
-https://fedorahosted.org/freeipa/ticket/4826
-
-Reviewed-By: Tomas Babej <tbabej@redhat.com>
----
- ipalib/plugins/idrange.py | 52 ++++++++++++++++++++++++++---------------------
- 1 file changed, 29 insertions(+), 23 deletions(-)
-
-diff --git a/ipalib/plugins/idrange.py b/ipalib/plugins/idrange.py
-index fb198d79d4c14ffd5f7dc633c9f01a1465ff01d7..2cec05bd8f837fb27803b869bf33fe389126506c 100644
---- a/ipalib/plugins/idrange.py
-+++ b/ipalib/plugins/idrange.py
-@@ -31,6 +31,20 @@ if api.env.in_server and api.env.context in ['lite', 'server']:
-     except ImportError:
-         _dcerpc_bindings_installed = False
- 
-+ID_RANGE_VS_DNA_WARNING = """=======
-+WARNING:
-+
-+DNA plugin in 389-ds will allocate IDs based on the ranges configured for the
-+local domain. Currently the DNA plugin *cannot* be reconfigured itself based
-+on the local ranges set via this family of commands.
-+
-+Manual configuration change has to be done in the DNA plugin configuration for
-+the new local range. Specifically, The dnaNextRange attribute of 'cn=Posix
-+IDs,cn=Distributed Numeric Assignment Plugin,cn=plugins,cn=config' has to be
-+modified to match the new range.
-+=======
-+"""
-+
- __doc__ = _("""
- ID ranges
- 
-@@ -139,17 +153,8 @@ this domain has the SID S-1-5-21-123-456-789-1010 then 1010 id the RID of the
- user. RIDs are unique in a domain, 32bit values and are used for users and
- groups.
- 
--WARNING:
--
--DNA plugin in 389-ds will allocate IDs based on the ranges configured for the
--local domain. Currently the DNA plugin *cannot* be reconfigured itself based
--on the local ranges set via this family of commands.
--
--Manual configuration change has to be done in the DNA plugin configuration for
--the new local range. Specifically, The dnaNextRange attribute of 'cn=Posix
--IDs,cn=Distributed Numeric Assignment Plugin,cn=plugins,cn=config' has to be
--modified to match the new range.
--""")
-+{0}
-+""".format(ID_RANGE_VS_DNA_WARNING))
- 
- register = Registry()
- 
-@@ -386,17 +391,8 @@ class idrange_add(LDAPCreate):
- 
-     must be given to add a new range for a trusted AD domain.
- 
--    WARNING:
--
--    DNA plugin in 389-ds will allocate IDs based on the ranges configured for the
--    local domain. Currently the DNA plugin *cannot* be reconfigured itself based
--    on the local ranges set via this family of commands.
--
--    Manual configuration change has to be done in the DNA plugin configuration for
--    the new local range. Specifically, The dnaNextRange attribute of 'cn=Posix
--    IDs,cn=Distributed Numeric Assignment Plugin,cn=plugins,cn=config' has to be
--    modified to match the new range.
--    """)
-+{0}
-+""".format(ID_RANGE_VS_DNA_WARNING))
- 
-     msg_summary = _('Added ID range "%(value)s"')
- 
-@@ -670,7 +666,10 @@ class idrange_show(LDAPRetrieve):
- 
- @register()
- class idrange_mod(LDAPUpdate):
--    __doc__ = _('Modify ID range.')
-+    __doc__ = _("""Modify ID range.
-+
-+{0}
-+""".format(ID_RANGE_VS_DNA_WARNING))
- 
-     msg_summary = _('Modified ID range "%(value)s"')
- 
-@@ -688,6 +687,13 @@ class idrange_mod(LDAPUpdate):
-         except errors.NotFound:
-             self.obj.handle_not_found(*keys)
- 
-+        if old_attrs['iparangetype'][0] == 'ipa-local':
-+            raise errors.ExecutionError(
-+                message=_('This command can not be used to change ID '
-+                          'allocation for local IPA domain. Run '
-+                          '`ipa help idrange` for more information')
-+            )
-+
-         is_set = lambda x: (x in entry_attrs) and (entry_attrs[x] is not None)
-         in_updated_attrs = lambda x:\
-             (x in entry_attrs and entry_attrs[x] is not None) or\
--- 
-2.4.3
-
diff --git a/SOURCES/0058-install-Fix-server-and-replica-install-options.patch b/SOURCES/0058-install-Fix-server-and-replica-install-options.patch
deleted file mode 100644
index 8c915c0..0000000
--- a/SOURCES/0058-install-Fix-server-and-replica-install-options.patch
+++ /dev/null
@@ -1,211 +0,0 @@
-From 8fd313b624e3da699280f81da1f88ef7149e6123 Mon Sep 17 00:00:00 2001
-From: Jan Cholasta <jcholast@redhat.com>
-Date: Wed, 12 Aug 2015 07:49:53 +0200
-Subject: [PATCH] install: Fix server and replica install options
-
-https://fedorahosted.org/freeipa/ticket/5184
-
-Reviewed-By: Martin Babinsky <mbabinsk@redhat.com>
----
- ipaserver/install/server/install.py        | 55 ++++++------------------------
- ipaserver/install/server/replicainstall.py | 36 ++++---------------
- 2 files changed, 17 insertions(+), 74 deletions(-)
-
-diff --git a/ipaserver/install/server/install.py b/ipaserver/install/server/install.py
-index b9bf3f34bdb7c32115e5c6a7038f11f901ab06b8..ff517513473a458a84f63c5c1308a8cc0b8699f8 100644
---- a/ipaserver/install/server/install.py
-+++ b/ipaserver/install/server/install.py
-@@ -1137,18 +1137,6 @@ def uninstall(installer):
- class ServerCA(common.Installable, core.Group, core.Composite):
-     description = "certificate system"
- 
--    setup_ca = Knob(
--        bool, False,
--        initializable=False,
--        description="configure a dogtag CA",
--    )
--
--    setup_kra = Knob(
--        bool, False,
--        initializable=False,
--        description="configure a dogtag KRA",
--    )
--
-     external_ca = Knob(
-         bool, False,
-         description=("Generate a CSR for the IPA CA certificate to be signed "
-@@ -1163,7 +1151,7 @@ class ServerCA(common.Installable, core.Group, core.Composite):
-     external_cert_files = Knob(
-         (list, str), None,
-         description=("File containing the IPA CA certificate and the external "
--                     "CA certificate chain (can be specified multiple times)"),
-+                     "CA certificate chain"),
-         cli_name='external-cert-file',
-         cli_aliases=['external_cert_file', 'external_ca_file'],
-         cli_metavar='FILE',
-@@ -1308,6 +1296,7 @@ class ServerDNS(common.Installable, core.Group, core.Composite):
-         description=("The reverse DNS zone to use. This option can be used "
-                      "multiple times"),
-         cli_name='reverse-zone',
-+        cli_metavar='REVERSE_ZONE',
-     )
- 
-     no_reverse = Knob(
-@@ -1320,31 +1309,6 @@ class ServerDNS(common.Installable, core.Group, core.Composite):
-         description="Disable DNSSEC validation",
-     )
- 
--    dnssec_master = Knob(
--        bool, False,
--        initializable=False,
--        description="Setup server to be DNSSEC key master",
--    )
--
--    disable_dnssec_master = Knob(
--        bool, False,
--        initializable=False,
--        description="Disable the DNSSEC master on this server",
--    )
--
--    kasp_db_file = Knob(
--        str, None,
--        initializable=False,
--        description="Copy OpenDNSSEC metadata from the specified file (will "
--                    "not create a new kasp.db file)",
--    )
--
--    force = Knob(
--        bool, False,
--        initializable=False,
--        description="Force install",
--    )
--
-     zonemgr = Knob(
-         str, None,
-         description=("DNS zone manager e-mail address. Defaults to "
-@@ -1416,7 +1380,6 @@ class Server(common.Installable, common.Interactive, core.Composite):
-     master_password = Knob(
-         str, None,
-         sensitive=True,
--        deprecated=True,
-         description="kerberos master password (normally autogenerated)",
-         cli_short_name='P',
-     )
-@@ -1466,11 +1429,13 @@ class Server(common.Installable, common.Interactive, core.Composite):
-         description=("Master Server IP Address. This option can be used "
-                      "multiple times"),
-         cli_name='ip-address',
-+        cli_metavar='IP_ADDRESS',
-     )
- 
-     no_ntp = Knob(
-         bool, False,
-         description="do not configure ntp",
-+        cli_short_name='N',
-     )
- 
-     idstart = Knob(
-@@ -1615,8 +1580,8 @@ class Server(common.Installable, common.Interactive, core.Composite):
-         # Automatically disable pkinit w/ dogtag until that is supported
-         self.ca.no_pkinit = True
- 
--        self.setup_ca = self.ca.setup_ca
--        self.setup_kra = self.ca.setup_kra
-+        self.setup_ca = False
-+        self.setup_kra = False
-         self.external_ca = self.ca.external_ca
-         self.external_ca_type = self.ca.external_ca_type
-         self.external_cert_files = self.ca.external_cert_files
-@@ -1639,10 +1604,10 @@ class Server(common.Installable, common.Interactive, core.Composite):
-         self.reverse_zones = self.dns.reverse_zones
-         self.no_reverse = self.dns.no_reverse
-         self.no_dnssec_validation = self.dns.no_dnssec_validation
--        self.dnssec_master = self.dns.dnssec_master
--        self.disable_dnssec_master = self.dns.disable_dnssec_master
--        self.kasp_db_file = self.dns.kasp_db_file
--        self.force = self.dns.force
-+        self.dnssec_master = False
-+        self.disable_dnssec_master = False
-+        self.kasp_db_file = None
-+        self.force = False
-         self.zonemgr = self.dns.zonemgr
-         self.no_host_dns = self.dns.no_host_dns
-         self.no_dns_sshfp = self.dns.no_dns_sshfp
-diff --git a/ipaserver/install/server/replicainstall.py b/ipaserver/install/server/replicainstall.py
-index 1ad291a1eada080361031a5723a0ea61679fc72e..dd8bc0d4bb7d8d9835a3e3e4dc24d1f67199d28f 100644
---- a/ipaserver/install/server/replicainstall.py
-+++ b/ipaserver/install/server/replicainstall.py
-@@ -679,6 +679,7 @@ class ReplicaDNS(common.Installable, core.Group, core.Composite):
-         description=("The reverse DNS zone to use. This option can be used "
-                      "multiple times"),
-         cli_name='reverse-zone',
-+        cli_metavar='REVERSE_ZONE',
-     )
- 
-     no_reverse = Knob(
-@@ -691,31 +692,6 @@ class ReplicaDNS(common.Installable, core.Group, core.Composite):
-         description="Disable DNSSEC validation",
-     )
- 
--    dnssec_master = Knob(
--        bool, False,
--        initializable=False,
--        description="Setup server to be DNSSEC key master",
--    )
--
--    disable_dnssec_master = Knob(
--        bool, False,
--        initializable=False,
--        description="Disable the DNSSEC master on this server",
--    )
--
--    force = Knob(
--        bool, False,
--        initializable=False,
--        description="Force install",
--    )
--
--    kasp_db_file = Knob(
--        str, None,
--        initializable=False,
--        description="Copy OpenDNSSEC metadata from the specified file (will "
--                    "not create a new kasp.db file)",
--    )
--
-     no_host_dns = Knob(
-         bool, False,
-         description="Do not use DNS for hostname lookup during installation",
-@@ -750,6 +726,7 @@ class Replica(common.Installable, common.Interactive, core.Composite):
-         description=("Replica server IP Address. This option can be used "
-                      "multiple times"),
-         cli_name='ip-address',
-+        cli_metavar='IP_ADDRESS',
-     )
- 
-     password = Knob(
-@@ -774,6 +751,7 @@ class Replica(common.Installable, common.Interactive, core.Composite):
-     no_ntp = Knob(
-         bool, False,
-         description="do not configure ntp",
-+        cli_short_name='N',
-     )
- 
-     no_ui_redirect = Knob(
-@@ -864,10 +842,10 @@ class Replica(common.Installable, common.Interactive, core.Composite):
-         self.reverse_zones = self.dns.reverse_zones
-         self.no_reverse = self.dns.no_reverse
-         self.no_dnssec_validation = self.dns.no_dnssec_validation
--        self.dnssec_master = self.dns.dnssec_master
--        self.disable_dnssec_master = self.dns.disable_dnssec_master
--        self.kasp_db_file = self.dns.kasp_db_file
--        self.force = self.dns.force
-+        self.dnssec_master = False
-+        self.disable_dnssec_master = False
-+        self.kasp_db_file = None
-+        self.force = False
-         self.zonemgr = None
-         self.no_host_dns = self.dns.no_host_dns
-         self.no_dns_sshfp = self.dns.no_dns_sshfp
--- 
-2.4.3
-
diff --git a/SOURCES/0058-server-install-Fix-hostname-option-to-always-overrid.patch b/SOURCES/0058-server-install-Fix-hostname-option-to-always-overrid.patch
new file mode 100644
index 0000000..4267f9f
--- /dev/null
+++ b/SOURCES/0058-server-install-Fix-hostname-option-to-always-overrid.patch
@@ -0,0 +1,52 @@
+From 09b5f9fc0e75886917aae014c2bb0c5bd67d3c4c Mon Sep 17 00:00:00 2001
+From: Petr Spacek <pspacek@redhat.com>
+Date: Tue, 12 Jul 2016 17:42:40 +0200
+Subject: [PATCH] server-install: Fix --hostname option to always override
+ api.env values
+
+Attempts to compare local hostname with user-provided values are error
+prone as we found out in #5794. This patch removes comparison and makes
+the env values deterministic.
+
+https://fedorahosted.org/freeipa/ticket/6071
+
+Reviewed-By: Jan Cholasta <jcholast@redhat.com>
+---
+ ipaserver/install/server/install.py | 13 +++++--------
+ 1 file changed, 5 insertions(+), 8 deletions(-)
+
+diff --git a/ipaserver/install/server/install.py b/ipaserver/install/server/install.py
+index 65f9318201e648b30a3c13626e807ac6f3a9416d..1e925595b93ff95a98b3e6c3d0c357b1766dc1dc 100644
+--- a/ipaserver/install/server/install.py
++++ b/ipaserver/install/server/install.py
+@@ -560,7 +560,12 @@ def install_check(installer):
+     cfg = dict(
+         context='installer',
+         in_server=True,
++        # make sure host name specified by user is used instead of default
++        host=host_name,
+     )
++    if setup_ca:
++        # we have an IPA-integrated CA
++        cfg['ca_host'] = host_name
+ 
+     # Create the management framework config file and finalize api
+     target_fname = paths.IPA_DEFAULT_CONF
+@@ -586,14 +591,6 @@ def install_check(installer):
+     # Must be readable for everyone
+     os.chmod(target_fname, 0o644)
+ 
+-    system_hostname = get_fqdn()
+-    if host_name != system_hostname:
+-        root_logger.debug("Chosen hostname (%s) differs from system hostname "
+-                          "(%s) - change it" % (host_name, system_hostname))
+-        # update `api.env.ca_host` to correct hostname
+-        # https://fedorahosted.org/freeipa/ticket/4936
+-        api.env.ca_host = host_name
+-
+     api.bootstrap(**cfg)
+     api.finalize()
+ 
+-- 
+2.7.4
+
diff --git a/SOURCES/0059-certprofile-add-profile-format-explanation.patch b/SOURCES/0059-certprofile-add-profile-format-explanation.patch
deleted file mode 100644
index fac47d7..0000000
--- a/SOURCES/0059-certprofile-add-profile-format-explanation.patch
+++ /dev/null
@@ -1,49 +0,0 @@
-From 056d185b4b2bfd7de423da7ff7a80f764c043810 Mon Sep 17 00:00:00 2001
-From: Fraser Tweedale <ftweedal@redhat.com>
-Date: Thu, 23 Jul 2015 23:07:10 -0400
-Subject: [PATCH] certprofile: add profile format explanation
-
-Part of: https://fedorahosted.org/freeipa/ticket/5089
-
-Reviewed-By: Tomas Babej <tbabej@redhat.com>
----
- ipalib/plugins/certprofile.py | 20 ++++++++++++++++++++
- 1 file changed, 20 insertions(+)
-
-diff --git a/ipalib/plugins/certprofile.py b/ipalib/plugins/certprofile.py
-index 658fbca3b4eb851eb5a22190c443044f6ceb8491..1dd4f403ee4461b83c053eb36019a8896506bb81 100644
---- a/ipalib/plugins/certprofile.py
-+++ b/ipalib/plugins/certprofile.py
-@@ -47,9 +47,29 @@ EXAMPLES:
-   Show information about a profile:
-     ipa certprofile-show ShortLivedUserCert
- 
-+  Save profile configuration to a file:
-+    ipa certprofile-show caIPAserviceCert --out caIPAserviceCert.cfg
-+
-   Search for profiles that do not store certificates:
-     ipa certprofile-find --store=false
- 
-+PROFILE CONFIGURATION FORMAT:
-+
-+The profile configuration format is the raw property-list format
-+used by Dogtag Certificate System.  The XML format is not supported.
-+
-+The following restrictions apply to profiles managed by FreeIPA:
-+
-+- When importing a profile the "profileId" field, if present, must
-+  match the ID given on the command line.
-+
-+- The "classId" field must be set to "caEnrollImpl"
-+
-+- The "auth.instance_id" field must be set to "raCertAuth"
-+
-+- The "certReqInputImpl" input class and "certOutputImpl" output
-+  class must be used.
-+
- """)
- 
- 
--- 
-2.4.3
-
diff --git a/SOURCES/0059-install-Call-hostnamectl-set-hostname-only-if-hostna.patch b/SOURCES/0059-install-Call-hostnamectl-set-hostname-only-if-hostna.patch
new file mode 100644
index 0000000..2154c99
--- /dev/null
+++ b/SOURCES/0059-install-Call-hostnamectl-set-hostname-only-if-hostna.patch
@@ -0,0 +1,148 @@
+From fa252eac5db87020c7f4ecd3646a25bb7cafd27c Mon Sep 17 00:00:00 2001
+From: Petr Spacek <pspacek@redhat.com>
+Date: Thu, 28 Jul 2016 16:13:55 +0200
+Subject: [PATCH] install: Call hostnamectl set-hostname only if --hostname
+ option is used
+
+This commit also splits hostname backup and configuration into two separate
+functions. This allows us to backup hostname without setting it at the
+same time.
+
+https://fedorahosted.org/freeipa/ticket/6071
+
+Reviewed-By: Jan Cholasta <jcholast@redhat.com>
+---
+ client/ipa-client-install           |  3 ++-
+ doc/guide/guide.org                 | 10 +++++-----
+ ipaplatform/base/tasks.py           |  7 ++-----
+ ipaplatform/redhat/tasks.py         | 13 ++-----------
+ ipaserver/install/server/install.py | 10 +++++-----
+ 5 files changed, 16 insertions(+), 27 deletions(-)
+
+diff --git a/client/ipa-client-install b/client/ipa-client-install
+index 45185d44feb43a8b8d30e412a26dd63121be4ad1..db2037b8372644f997de498dcf3b99edcf3abb56 100755
+--- a/client/ipa-client-install
++++ b/client/ipa-client-install
+@@ -2525,7 +2525,8 @@ def install(options, env, fstore, statestore):
+     if options.hostname and not options.on_master:
+         # skip this step when run by ipa-server-install as it always configures
+         # hostname
+-        tasks.backup_and_replace_hostname(fstore, statestore, options.hostname)
++        tasks.backup_hostname(fstore, statestore)
++        tasks.set_hostname(options.hostname)
+ 
+     ntp_srv_servers = []
+     if not options.on_master and options.conf_ntp:
+diff --git a/doc/guide/guide.org b/doc/guide/guide.org
+index 6d181559f0af90e7be7089aa94ab4900fa4e90b5..2e852a964991781ef5dd7b93ac481891897e1ed0 100644
+--- a/doc/guide/guide.org
++++ b/doc/guide/guide.org
+@@ -1039,14 +1039,14 @@ def restore_context_default(filepath):
+ # version in platform services
+ restore_context = restore_context_default
+ 
+-# Default implementation of backup and replace hostname that does nothing
+-def backup_and_replace_hostname_default(fstore, statestore, hostname):
++# Default implementation of backup hostname that does nothing
++def backup_hostname_default(fstore, statestore):
+     return
+ 
+-# Backup and replace system's hostname
+-# Since many platforms have their own way how to store system's hostname, this method must be
++# Backup system's hostname
++# Since many platforms have their own way of handling system's hostname, this method must be
+ # implemented in platform services
+-backup_and_replace_hostname = backup_and_replace_hostname_default
++backup_hostname = backup_hostname_default
+ 
+ from ipapython.platform.SUPPORTED_PLATFORM import *
+ #+END_SRC
+diff --git a/ipaplatform/base/tasks.py b/ipaplatform/base/tasks.py
+index c6860ce47ad3d043f1561a690c401537f5e2fdb7..1e687b6181fcff20303b50ac18bfde66280f8bfd 100644
+--- a/ipaplatform/base/tasks.py
++++ b/ipaplatform/base/tasks.py
+@@ -45,14 +45,11 @@ class BaseTaskNamespace(object):
+ 
+         raise NotImplementedError()
+ 
+-    def backup_and_replace_hostname(self, fstore, statestore, hostname):
++    def backup_hostname(self, fstore, statestore):
+         """
+         Backs up the current hostname in the statestore (so that it can be
+         restored by the restore_hostname platform task).
+ 
+-        Makes sure that new hostname (passed via hostname argument) is set
+-        as a new pemanent hostname for this host.
+-
+         No return value expected.
+         """
+ 
+@@ -109,7 +106,7 @@ class BaseTaskNamespace(object):
+     def restore_hostname(self, fstore, statestore):
+         """
+         Restores the original hostname as backed up in the
+-        backup_and_replace_hostname platform task.
++        backup_hostname platform task.
+         """
+ 
+         raise NotImplementedError()
+diff --git a/ipaplatform/redhat/tasks.py b/ipaplatform/redhat/tasks.py
+index 8ac88511e94d640f077c7a0e202bc545ec8bcbbe..dbe005abb0ecbcb398368789fee52895c6d6e980 100644
+--- a/ipaplatform/redhat/tasks.py
++++ b/ipaplatform/redhat/tasks.py
+@@ -332,22 +332,13 @@ class RedHatTaskNamespace(BaseTaskNamespace):
+ 
+         return result
+ 
+-    def backup_and_replace_hostname(self, fstore, statestore, hostname):
+-        old_hostname = socket.gethostname()
+-        try:
+-            self.set_hostname(hostname)
+-        except ipautil.CalledProcessError as e:
+-            root_logger.debug(traceback.format_exc())
+-            root_logger.error(
+-                "Failed to set this machine hostname to %s (%s).",
+-                old_hostname, e
+-            )
+-
++    def backup_hostname(self, fstore, statestore):
+         filepath = paths.ETC_HOSTNAME
+         if os.path.exists(filepath):
+             fstore.backup_file(filepath)
+ 
+         # store old hostname
++        old_hostname = socket.gethostname()
+         statestore.backup_state('network', 'hostname', old_hostname)
+ 
+     def restore_hostname(self, fstore, statestore):
+diff --git a/ipaserver/install/server/install.py b/ipaserver/install/server/install.py
+index 1e925595b93ff95a98b3e6c3d0c357b1766dc1dc..94698898934844350488d5fc52d6e1e567624502 100644
+--- a/ipaserver/install/server/install.py
++++ b/ipaserver/install/server/install.py
+@@ -651,6 +651,7 @@ def install_check(installer):
+     options.dm_password = dm_password
+     options.master_password = master_password
+     options.admin_password = admin_password
++    options._host_name_overridden = bool(options.host_name)
+     options.host_name = host_name
+     options.ip_addresses = ip_addresses
+ 
+@@ -702,11 +703,10 @@ def install(installer):
+         print("Please wait until the prompt is returned.")
+         print("")
+ 
+-    # configure /etc/sysconfig/network to contain the custom hostname
+-    tasks.backup_and_replace_hostname(fstore, sstore, host_name)
+-
+-    # set hostname (we need both transient and static)
+-    tasks.set_hostname(host_name)
++    # set hostname (transient and static) if user instructed us to do so
++    if options._host_name_overridden:
++        tasks.backup_hostname(fstore, sstore)
++        tasks.set_hostname(host_name)
+ 
+     if installer._update_hosts_file:
+         update_hosts_file(ip_addresses, host_name, fstore)
+-- 
+2.7.4
+
diff --git a/SOURCES/0060-ULC-Prevent-preserved-users-from-being-assigned-memb.patch b/SOURCES/0060-ULC-Prevent-preserved-users-from-being-assigned-memb.patch
deleted file mode 100644
index d8dbffa..0000000
--- a/SOURCES/0060-ULC-Prevent-preserved-users-from-being-assigned-memb.patch
+++ /dev/null
@@ -1,155 +0,0 @@
-From 6087dd789833738e99040d031473c76ed9d8723c Mon Sep 17 00:00:00 2001
-From: Jan Cholasta <jcholast@redhat.com>
-Date: Wed, 12 Aug 2015 11:03:40 +0200
-Subject: [PATCH] ULC: Prevent preserved users from being assigned membership
-
-https://fedorahosted.org/freeipa/ticket/5170
-
-Reviewed-By: David Kupka <dkupka@redhat.com>
----
- ipalib/plugins/user.py | 31 ++++++++++++++++++-------------
- 1 file changed, 18 insertions(+), 13 deletions(-)
-
-diff --git a/ipalib/plugins/user.py b/ipalib/plugins/user.py
-index 859939205f903fa4832524c8d2601141f3674bb5..4ea770ede7525149780f1486b5e4eb44699c8533 100644
---- a/ipalib/plugins/user.py
-+++ b/ipalib/plugins/user.py
-@@ -342,7 +342,7 @@ class user(baseuser):
-         ),
-     )
- 
--    def get_dn(self, *keys, **options):
-+    def get_either_dn(self, *keys, **options):
-         '''
-         Returns the DN of a user
-         The user can be active (active container) or delete (delete container)
-@@ -351,7 +351,7 @@ class user(baseuser):
-         ldap = self.backend
-         # Check that this value is a Active user
-         try:
--            active_dn = super(user, self).get_dn(*keys, **options)
-+            active_dn = self.get_dn(*keys, **options)
-             ldap.get_entry(active_dn, ['dn'])
- 
-             # The Active user exists
-@@ -402,7 +402,7 @@ class user_add(baseuser_add):
-     )
- 
-     def pre_callback(self, ldap, dn, entry_attrs, attrs_list, *keys, **options):
--        assert isinstance(dn, DN)
-+        dn = self.obj.get_either_dn(*keys, **options)
-         if not options.get('noprivate', False):
-             try:
-                 # The Managed Entries plugin will allow a user to be created
-@@ -599,7 +599,7 @@ class user_del(baseuser_del):
-         return super(user_del, self).forward(*keys, **options)
- 
-     def pre_callback(self, ldap, dn, *keys, **options):
--        assert isinstance(dn, DN)
-+        dn = self.obj.get_either_dn(*keys, **options)
- 
-         # For User life Cycle: user-del is a common plugin
-         # command to delete active user (active container) and
-@@ -625,7 +625,7 @@ class user_del(baseuser_del):
- 
-     def execute(self, *keys, **options):
- 
--        dn = self.obj.get_dn(*keys, **options)
-+        dn = self.obj.get_either_dn(*keys, **options)
- 
-         # We are going to permanent delete or the user is already in the delete container.
-         delete_container = DN(self.obj.delete_container_dn, self.api.env.basedn)
-@@ -644,7 +644,7 @@ class user_del(baseuser_del):
-             ldap = self.obj.backend
- 
-             # need to handle multiple keys (e.g. keys[-1]=(u'tb8', u'tb9')..
--            active_dn = self.obj.get_dn(*keys, **options)
-+            active_dn = self.obj.get_either_dn(*keys, **options)
-             superior_dn = DN(self.obj.delete_container_dn, api.env.basedn)
-             delete_dn = DN(active_dn[0], self.obj.delete_container_dn, api.env.basedn)
-             self.log.debug("preserve move %s -> %s" % (active_dn, delete_dn))
-@@ -701,6 +701,7 @@ class user_mod(baseuser_mod):
-     has_output_params = baseuser_mod.has_output_params + user_output_params
- 
-     def pre_callback(self, ldap, dn, entry_attrs, attrs_list, *keys, **options):
-+        dn = self.obj.get_either_dn(*keys, **options)
-         self.pre_common_callback(ldap, dn, entry_attrs, **options)
-         validate_nsaccountlock(entry_attrs)
-         return dn
-@@ -777,6 +778,10 @@ class user_show(baseuser_show):
-         ),
-     )
- 
-+    def pre_callback(self, ldap, dn, attrs_list, *keys, **options):
-+        dn = self.obj.get_either_dn(*keys, **options)
-+        return dn
-+
-     def post_callback(self, ldap, dn, entry_attrs, *keys, **options):
-         convert_nsaccountlock(entry_attrs)
-         self.post_common_callback(ldap, dn, entry_attrs, **options)
-@@ -813,7 +818,7 @@ class user_undel(LDAPQuery):
-         ldap = self.obj.backend
- 
-         # First check that the user exists and is a delete one
--        delete_dn = self.obj.get_dn(*keys, **options)
-+        delete_dn = self.obj.get_either_dn(*keys, **options)
-         if delete_dn.endswith(DN(self.obj.active_container_dn, api.env.basedn)):
-             raise errors.ValidationError(
-                         name=self.obj.primary_key.cli_name,
-@@ -860,7 +865,7 @@ class user_disable(LDAPQuery):
- 
-         check_protected_member(keys[-1])
- 
--        dn = self.obj.get_dn(*keys, **options)
-+        dn = self.obj.get_either_dn(*keys, **options)
-         ldap.deactivate_entry(dn)
- 
-         return dict(
-@@ -880,7 +885,7 @@ class user_enable(LDAPQuery):
-     def execute(self, *keys, **options):
-         ldap = self.obj.backend
- 
--        dn = self.obj.get_dn(*keys, **options)
-+        dn = self.obj.get_either_dn(*keys, **options)
- 
-         ldap.activate_entry(dn)
- 
-@@ -904,7 +909,7 @@ class user_unlock(LDAPQuery):
-     msg_summary = _('Unlocked account "%(value)s"')
- 
-     def execute(self, *keys, **options):
--        dn = self.obj.get_dn(*keys, **options)
-+        dn = self.obj.get_either_dn(*keys, **options)
-         entry = self.obj.backend.get_entry(
-             dn, ['krbLastAdminUnlock', 'krbLoginFailedCount'])
- 
-@@ -948,7 +953,7 @@ class user_status(LDAPQuery):
- 
-     def execute(self, *keys, **options):
-         ldap = self.obj.backend
--        dn = self.obj.get_dn(*keys, **options)
-+        dn = self.obj.get_either_dn(*keys, **options)
-         attr_list = ['krbloginfailedcount', 'krblastsuccessfulauth', 'krblastfailedauth', 'nsaccountlock']
- 
-         disabled = False
-@@ -1037,7 +1042,7 @@ class user_add_cert(LDAPAddAttribute):
- 
-     def pre_callback(self, ldap, dn, entry_attrs, attrs_list, *keys,
-                      **options):
--        assert isinstance(dn, DN)
-+        dn = self.obj.get_either_dn(*keys, **options)
- 
-         self.obj.convert_usercertificate_pre(entry_attrs)
- 
-@@ -1059,7 +1064,7 @@ class user_remove_cert(LDAPRemoveAttribute):
- 
-     def pre_callback(self, ldap, dn, entry_attrs, attrs_list, *keys,
-                      **options):
--        assert isinstance(dn, DN)
-+        dn = self.obj.get_either_dn(*keys, **options)
- 
-         self.obj.convert_usercertificate_pre(entry_attrs)
- 
--- 
-2.4.3
-
diff --git a/SOURCES/0060-schema-Speed-up-schema-cache.patch b/SOURCES/0060-schema-Speed-up-schema-cache.patch
new file mode 100644
index 0000000..7c7d189
--- /dev/null
+++ b/SOURCES/0060-schema-Speed-up-schema-cache.patch
@@ -0,0 +1,415 @@
+From beff42632d1db674802c817afd49a3ac8bcd8fb6 Mon Sep 17 00:00:00 2001
+From: David Kupka <dkupka@redhat.com>
+Date: Wed, 27 Jul 2016 10:46:40 +0200
+Subject: [PATCH] schema: Speed up schema cache
+
+Check presence of schema in cache (and download it if necessary) on
+__init__ instead of with each __getitem__ call. Prefill internal
+dictionary with empty record for each command to be able to quickly
+determine if requested command exist in schema or not. Rest of schema
+data are read from cache on first attempt to retrive them.
+
+https://fedorahosted.org/freeipa/ticket/6048
+https://fedorahosted.org/freeipa/ticket/6069
+
+Reviewed-By: Jan Cholasta <jcholast@redhat.com>
+---
+ ipaclient/remote_plugins/schema.py | 301 ++++++++++++++++++++++---------------
+ 1 file changed, 177 insertions(+), 124 deletions(-)
+
+diff --git a/ipaclient/remote_plugins/schema.py b/ipaclient/remote_plugins/schema.py
+index 0301e54127dc236ebc14e1409484626f1427800d..d039fb41991c26a9c7b7f76f6959668efb677586 100644
+--- a/ipaclient/remote_plugins/schema.py
++++ b/ipaclient/remote_plugins/schema.py
+@@ -5,10 +5,8 @@
+ import collections
+ import errno
+ import fcntl
+-import glob
+ import json
+ import os
+-import re
+ import sys
+ import time
+ import types
+@@ -65,8 +63,6 @@ USER_CACHE_PATH = (
+         '.cache'
+     )
+ )
+-SCHEMA_DIR = os.path.join(USER_CACHE_PATH, 'ipa', 'schema')
+-SERVERS_DIR = os.path.join(USER_CACHE_PATH, 'ipa', 'servers')
+ 
+ logger = log_mgr.get_logger(__name__)
+ 
+@@ -274,15 +270,6 @@ class _SchemaObjectPlugin(_SchemaPlugin):
+     schema_key = 'classes'
+ 
+ 
+-def _ensure_dir_created(d):
+-    try:
+-        os.makedirs(d)
+-    except OSError as e:
+-        if e.errno != errno.EEXIST:
+-            raise RuntimeError("Unable to create cache directory: {}"
+-                               "".format(e))
+-
+-
+ class _LockedZipFile(zipfile.ZipFile):
+     """ Add locking to zipfile.ZipFile
+     Shared lock is used with read mode, exclusive with write mode.
+@@ -308,7 +295,10 @@ class _SchemaNameSpace(collections.Mapping):
+         self._schema = schema
+ 
+     def __getitem__(self, key):
+-        return self._schema.read_namespace_member(self.name, key)
++        try:
++            return self._schema.read_namespace_member(self.name, key)
++        except KeyError:
++            raise KeyError(key)
+ 
+     def __iter__(self):
+         for key in self._schema.iter_namespace(self.name):
+@@ -322,6 +312,62 @@ class NotAvailable(Exception):
+     pass
+ 
+ 
++class ServerInfo(collections.MutableMapping):
++    _DIR = os.path.join(USER_CACHE_PATH, 'ipa', 'servers')
++
++    def __init__(self, api):
++        hostname = DNSName(api.env.server).ToASCII()
++        self._path = os.path.join(self._DIR, hostname)
++        self._dict = {}
++        self._dirty = False
++
++        self._read()
++
++    def __enter__(self):
++        return self
++
++    def __exit__(self, *_exc_info):
++        if self._dirty:
++            self._write()
++
++    def _read(self):
++        try:
++            with open(self._path, 'r') as sc:
++                self._dict = json.load(sc)
++        except EnvironmentError as e:
++            if e.errno != errno.ENOENT:
++                logger.warning('Failed to read server info: {}'.format(e))
++
++    def _write(self):
++        try:
++            try:
++                os.makedirs(self._DIR)
++            except EnvironmentError as e:
++                if e.errno != errno.EEXIST:
++                    raise
++            with open(self._path, 'w') as sc:
++                json.dump(self._dict, sc)
++        except EnvironmentError as e:
++            logger.warning('Failed to write server info: {}'.format(e))
++
++    def __getitem__(self, key):
++        return self._dict[key]
++
++    def __setitem__(self, key, value):
++        self._dirty = key not in self._dict or self._dict[key] != value
++        self._dict[key] = value
++
++    def __delitem__(self, key):
++        del self._dict[key]
++        self._dirty = True
++
++    def __iter__(self):
++        return iter(self._dict)
++
++    def __len__(self):
++        return len(self._dict)
++
++
+ class Schema(object):
+     """
+     Store and provide schema for commands and topics
+@@ -342,38 +388,76 @@ class Schema(object):
+     u'Ping the remote IPA server to ...'
+ 
+     """
+-    schema_path_template = os.path.join(SCHEMA_DIR, '{}')
+-    servers_path_template = os.path.join(SERVERS_DIR, '{}')
+-    ns_member_pattern_template = '^{}/(?P<name>.+)$'
+-    ns_member_path_template = '{}/{}'
+     namespaces = {'classes', 'commands', 'topics'}
+     schema_info_path = 'schema'
++    _DIR = os.path.join(USER_CACHE_PATH, 'ipa', 'schema')
+ 
+-    @classmethod
+-    def _list(cls):
+-        for f in glob.glob(cls.schema_path_template.format('*')):
+-            yield os.path.splitext(os.path.basename(f))[0]
++    def __init__(self, api, server_info, client):
++        self._dict = {}
++        self._namespaces = {}
++        self._help = None
+ 
+-    @classmethod
+-    def _in_cache(cls, fingeprint):
+-        return os.path.exists(cls.schema_path_template.format(fingeprint))
++        for ns in self.namespaces:
++            self._dict[ns] = {}
++            self._namespaces[ns] = _SchemaNameSpace(self, ns)
+ 
+-    def __init__(self, api, client):
+-        self._api = api
+-        self._client = client
+-        self._dict = {}
++        is_known = False
++        if not api.env.force_schema_check:
++            try:
++                self._fingerprint = server_info['fingerprint']
++                self._expiration = server_info['expiration']
++            except KeyError:
++                pass
++            else:
++                is_known = True
++
++        if is_known:
++            try:
++                self._read_schema()
++            except Exception:
++                pass
++            else:
++                return
+ 
+-    def _open_server_info(self, hostname, mode):
+-        encoded_hostname = DNSName(hostname).ToASCII()
+-        path = self.servers_path_template.format(encoded_hostname)
+-        return open(path, mode)
++        try:
++            self._fetch(client)
++        except NotAvailable:
++            raise
++        else:
++            self._write_schema()
++        finally:
++            try:
++                server_info['fingerprint'] = self._fingerprint
++                server_info['expiration'] = self._expiration
++            except AttributeError:
++                pass
+ 
+-    def _get_schema(self):
+-        client = self._client
++    def _open_schema(self, filename, mode):
++        path = os.path.join(self._DIR, filename)
++        return _LockedZipFile(path, mode)
++
++    def _get_schema_fingerprint(self, schema):
++        schema_info = json.loads(schema.read(self.schema_info_path))
++        return schema_info['fingerprint']
++
++    def _fetch(self, client):
+         if not client.isconnected():
+             client.connect(verbose=False)
+ 
+-        fps = [unicode(f) for f in Schema._list()]
++        fps = []
++        try:
++            files = os.listdir(self._DIR)
++        except EnvironmentError:
++            pass
++        else:
++            for filename in files:
++                try:
++                    with self._open_schema(filename, 'r') as schema:
++                        fps.append(
++                            unicode(self._get_schema_fingerprint(schema)))
++                except Exception:
++                    continue
++
+         kwargs = {u'version': u'2.170'}
+         if fps:
+             kwargs[u'known_fingerprints'] = fps
+@@ -386,110 +470,80 @@ class Schema(object):
+             ttl = e.ttl
+         else:
+             fp = schema['fingerprint']
+-            ttl = schema['ttl']
+-            self._store(fp, schema)
+-        finally:
+-            client.disconnect()
++            ttl = schema.pop('ttl', 0)
+ 
+-        exp = ttl + time.time()
+-        return (fp, exp)
++            for key, value in schema.items():
++                if key in self.namespaces:
++                    value = {m['full_name']: m for m in value}
++                self._dict[key] = value
+ 
+-    def _ensure_cached(self):
+-        no_info = False
+-        try:
+-            # pylint: disable=access-member-before-definition
+-            fp = self._server_schema_fingerprint
+-            exp = self._server_schema_expiration
+-        except AttributeError:
+-            try:
+-                with self._open_server_info(self._api.env.server, 'r') as sc:
+-                    si = json.load(sc)
+-
+-                fp = si['fingerprint']
+-                exp = si['expiration']
+-            except Exception as e:
+-                no_info = True
+-                if not (isinstance(e, EnvironmentError) and
+-                        e.errno == errno.ENOENT):  # pylint: disable=no-member
+-                    logger.warning('Failed to load server properties: {}'
+-                                   ''.format(e))
+-
+-        force_check = ((not getattr(self, '_schema_checked', False)) and
+-                       self._api.env.force_schema_check)
+-
+-        if (force_check or
+-                no_info or exp < time.time() or not Schema._in_cache(fp)):
+-            (fp, exp) = self._get_schema()
+-            self._schema_checked = True
+-            _ensure_dir_created(SERVERS_DIR)
+-            try:
+-                with self._open_server_info(self._api.env.server, 'w') as sc:
+-                    json.dump(dict(fingerprint=fp, expiration=exp), sc)
+-            except Exception as e:
+-                logger.warning('Failed to store server properties: {}'
+-                               ''.format(e))
+-
+-        if not self._dict:
+-            self._dict['fingerprint'] = fp
+-            schema_info = self._read(self.schema_info_path)
++        self._fingerprint = fp
++        self._expiration = ttl + time.time()
++
++    def _read_schema(self):
++        with self._open_schema(self._fingerprint, 'r') as schema:
++            self._dict['fingerprint'] = self._get_schema_fingerprint(schema)
++            schema_info = json.loads(schema.read(self.schema_info_path))
+             self._dict['version'] = schema_info['version']
+-            for ns in self.namespaces:
+-                self._dict[ns] = _SchemaNameSpace(self, ns)
+ 
+-        self._server_schema_fingerprintr = fp
+-        self._server_schema_expiration = exp
++            for name in schema.namelist():
++                ns, _slash, key = name.partition('/')
++                if ns in self.namespaces:
++                    self._dict[ns][key] = {}
+ 
+     def __getitem__(self, key):
+-        self._ensure_cached()
+-        return self._dict[key]
++        try:
++            return self._namespaces[key]
++        except KeyError:
++            return self._dict[key]
+ 
+-    def _open_archive(self, mode, fp=None):
+-        if not fp:
+-            fp = self['fingerprint']
+-        arch_path = self.schema_path_template.format(fp)
+-        return _LockedZipFile(arch_path, mode)
+-
+-    def _store(self, fingerprint, schema={}):
+-        _ensure_dir_created(SCHEMA_DIR)
+-
+-        schema_info = dict(version=schema['version'],
+-                           fingerprint=schema['fingerprint'])
+-
+-        with self._open_archive('w', fingerprint) as zf:
+-            # store schema information
+-            zf.writestr(self.schema_info_path, json.dumps(schema_info))
+-            # store namespaces
+-            for namespace in self.namespaces:
+-                for member in schema[namespace]:
+-                    path = self.ns_member_path_template.format(
+-                        namespace,
+-                        member['full_name']
+-                    )
+-                    zf.writestr(path, json.dumps(member))
++    def _write_schema(self):
++        try:
++            os.makedirs(self._DIR)
++        except EnvironmentError as e:
++            if e.errno != errno.EEXIST:
++                logger.warning("Failed ti write schema: {}".format(e))
++                return
++
++        with self._open_schema(self._fingerprint, 'w') as schema:
++            schema_info = {}
++            for key, value in self._dict.items():
++                if key in self.namespaces:
++                    ns = value
++                    for member in ns:
++                        path = '{}/{}'.format(key, member)
++                        schema.writestr(path, json.dumps(ns[member]))
++                else:
++                    schema_info[key] = value
++
++            schema.writestr(self.schema_info_path, json.dumps(schema_info))
+ 
+     def _read(self, path):
+-        with self._open_archive('r') as zf:
++        with self._open_schema(self._fingerprint, 'r') as zf:
+             return json.loads(zf.read(path))
+ 
+     def read_namespace_member(self, namespace, member):
+-        path = self.ns_member_path_template.format(namespace, member)
+-        return self._read(path)
++        value = self._dict[namespace][member]
++
++        if (not value) or ('full_name' not in value):
++            path = '{}/{}'.format(namespace, member)
++            value = self._dict[namespace].setdefault(
++                member, {}
++            ).update(self._read(path))
++
++        return value
+ 
+     def iter_namespace(self, namespace):
+-        pattern = self.ns_member_pattern_template.format(namespace)
+-        with self._open_archive('r') as zf:
+-            for name in zf.namelist():
+-                r = re.match(pattern, name)
+-                if r:
+-                    yield r.groups('name')[0]
++        return iter(self._dict[namespace])
+ 
+ 
+ def get_package(api, client):
+     try:
+         schema = api._schema
+     except AttributeError:
+-        schema = Schema(api, client)
+-        object.__setattr__(api, '_schema', schema)
++        with ServerInfo(api.env.hostname) as server_info:
++            schema = Schema(api, server_info, client)
++            object.__setattr__(api, '_schema', schema)
+ 
+     fingerprint = str(schema['fingerprint'])
+     package_name = '{}${}'.format(__name__, fingerprint)
+@@ -509,10 +563,9 @@ def get_package(api, client):
+     module = types.ModuleType(module_name)
+     module.__file__ = os.path.join(package_dir, 'plugins.py')
+     module.register = plugable.Registry()
+-    for key, plugin_cls in (('commands', _SchemaCommandPlugin),
+-                            ('classes', _SchemaObjectPlugin)):
+-        for full_name in schema[key]:
+-            plugin = plugin_cls(full_name)
++    for plugin_cls in (_SchemaCommandPlugin, _SchemaObjectPlugin):
++        for full_name in schema[plugin_cls.schema_key]:
++            plugin = plugin_cls(str(full_name))
+             plugin = module.register()(plugin)
+     sys.modules[module_name] = module
+ 
+-- 
+2.7.4
+
diff --git a/SOURCES/0061-Asymmetric-vault-validate-public-key-in-client.patch b/SOURCES/0061-Asymmetric-vault-validate-public-key-in-client.patch
deleted file mode 100644
index 8a5948a..0000000
--- a/SOURCES/0061-Asymmetric-vault-validate-public-key-in-client.patch
+++ /dev/null
@@ -1,45 +0,0 @@
-From 9eae8d891a8b5d5320cb38b8e697681802cbf573 Mon Sep 17 00:00:00 2001
-From: Christian Heimes <cheimes@redhat.com>
-Date: Thu, 23 Jul 2015 20:30:21 +0200
-Subject: [PATCH] Asymmetric vault: validate public key in client
-
-The ipa vault commands now load and validate the public key for
-asymmetric encryption, before sending it to the server. This prevents
-invalid vaults and prohibits accidental exposure of private key
-material.
-
-https://fedorahosted.org/freeipa/ticket/5142
-https://fedorahosted.org/freeipa/ticket/5143
-
-Reviewed-By: Petr Vobornik <pvoborni@redhat.com>
----
- ipalib/plugins/vault.py | 13 +++++++++++++
- 1 file changed, 13 insertions(+)
-
-diff --git a/ipalib/plugins/vault.py b/ipalib/plugins/vault.py
-index 055e8d00f1616c15b217e7570eeedd46efba7c81..ac608f5c7e2779da138c75a0f02bd5546f4aeffd 100644
---- a/ipalib/plugins/vault.py
-+++ b/ipalib/plugins/vault.py
-@@ -665,6 +665,19 @@ class vault_add(PKQuery, Local):
-                     name='ipavaultpublickey',
-                     error=_('Missing vault public key'))
- 
-+            # validate public key and prevent users from accidentally
-+            # sending a private key to the server.
-+            try:
-+                load_pem_public_key(
-+                    data=public_key,
-+                    backend=default_backend()
-+                )
-+            except ValueError as e:
-+                raise errors.ValidationError(
-+                    name='ipavaultpublickey',
-+                    error=_('Invalid or unsupported vault public key: %s') % e,
-+                )
-+
-         # create vault
-         response = self.api.Command.vault_add_internal(*args, **options)
- 
--- 
-2.4.3
-
diff --git a/SOURCES/0061-frontend-Change-doc-summary-topic-and-NO_CLI-to-clas.patch b/SOURCES/0061-frontend-Change-doc-summary-topic-and-NO_CLI-to-clas.patch
new file mode 100644
index 0000000..f27bd62
--- /dev/null
+++ b/SOURCES/0061-frontend-Change-doc-summary-topic-and-NO_CLI-to-clas.patch
@@ -0,0 +1,378 @@
+From 8293d36c504b59a6dac46187baf51719ab355fd2 Mon Sep 17 00:00:00 2001
+From: David Kupka <dkupka@redhat.com>
+Date: Wed, 20 Jul 2016 13:23:33 +0200
+Subject: [PATCH] frontend: Change doc, summary, topic and NO_CLI to class
+ properties
+
+Avoid need to instantiate all commands just to get information for
+displaying help.
+
+https://fedorahosted.org/freeipa/ticket/6048
+
+Reviewed-By: Jan Cholasta <jcholast@redhat.com>
+---
+ ipaclient/frontend.py                 | 32 ++++++++++++++-------
+ ipaclient/plugins/automount.py        |  9 ++++--
+ ipaclient/plugins/otptoken_yubikey.py | 11 +++++---
+ ipaclient/plugins/vault.py            | 35 ++++++++++++++---------
+ ipaclient/remote_plugins/schema.py    | 53 +++++++++++++++++++++++++++++++----
+ ipalib/frontend.py                    | 10 ++++---
+ ipalib/plugable.py                    | 17 ++++++-----
+ 7 files changed, 120 insertions(+), 47 deletions(-)
+
+diff --git a/ipaclient/frontend.py b/ipaclient/frontend.py
+index 1525c88b3dfeadccd8115cb4b6ba149caef22103..aeaed550771d3c6af04a9b34fcae414faacb47d7 100644
+--- a/ipaclient/frontend.py
++++ b/ipaclient/frontend.py
+@@ -2,9 +2,11 @@
+ # Copyright (C) 2016  FreeIPA Contributors see COPYING for license
+ #
+ 
++from ipalib import api
+ from ipalib.frontend import Command, Method
+ from ipalib.parameters import Str
+ from ipalib.text import _
++from ipalib.util import classproperty
+ 
+ 
+ class ClientCommand(Command):
+@@ -111,20 +113,30 @@ class CommandOverride(Command):
+     def __init__(self, api):
+         super(CommandOverride, self).__init__(api)
+ 
+-        next_class = api.get_plugin_next(type(self))
++        next_class = self.__get_next()
+         self.next = next_class(api)
+ 
+-    @property
+-    def doc(self):
+-        return self.next.doc
++    @classmethod
++    def __get_next(cls):
++        return api.get_plugin_next(cls)
+ 
+-    @property
+-    def NO_CLI(self):
+-        return self.next.NO_CLI
++    @classmethod
++    def __doc_getter(cls):
++        return cls.__get_next().doc
+ 
+-    @property
+-    def topic(self):
+-        return self.next.topic
++    doc = classproperty(__doc_getter)
++
++    @classmethod
++    def __NO_CLI_getter(cls):
++        return cls.__get_next().NO_CLI
++
++    NO_CLI = classproperty(__NO_CLI_getter)
++
++    @classmethod
++    def __topic_getter(cls):
++        return cls.__get_next().topic
++
++    topic = classproperty(__topic_getter)
+ 
+     @property
+     def forwarded_name(self):
+diff --git a/ipaclient/plugins/automount.py b/ipaclient/plugins/automount.py
+index c6537bc6c24b905a8e1f7fb6a7e2c931b95374c7..925b635ff27411fc7e2f8c3dae17c747216d7fb6 100644
+--- a/ipaclient/plugins/automount.py
++++ b/ipaclient/plugins/automount.py
+@@ -27,6 +27,7 @@ from ipalib import api, errors
+ from ipalib import Flag, Str
+ from ipalib.frontend import Command, Method, Object
+ from ipalib.plugable import Registry
++from ipalib.util import classproperty
+ from ipalib import _
+ from ipapython.dn import DN
+ 
+@@ -52,11 +53,13 @@ class _fake_automountlocation_show(Method):
+ 
+ @register(override=True, no_fail=True)
+ class automountlocation_tofiles(MethodOverride):
+-    @property
+-    def NO_CLI(self):
+-        return isinstance(self.api.Command.automountlocation_show,
++    @classmethod
++    def __NO_CLI_getter(cls):
++        return isinstance(api.Command.automountlocation_show,
+                           _fake_automountlocation_show)
+ 
++    NO_CLI = classproperty(__NO_CLI_getter)
++
+     def output_for_cli(self, textui, result, *keys, **options):
+         maps = result['result']['maps']
+         keys = result['result']['keys']
+diff --git a/ipaclient/plugins/otptoken_yubikey.py b/ipaclient/plugins/otptoken_yubikey.py
+index 3c310eacbaeef654e43049db78437c8c29f52279..549376a0ff65d44c5698666a84608849152368b2 100644
+--- a/ipaclient/plugins/otptoken_yubikey.py
++++ b/ipaclient/plugins/otptoken_yubikey.py
+@@ -23,10 +23,11 @@ import six
+ import usb.core
+ import yubico
+ 
+-from ipalib import _, IntEnum
++from ipalib import _, api, IntEnum
+ from ipalib.errors import NotFound
+ from ipalib.frontend import Command, Method, Object
+ from ipalib.plugable import Registry
++from ipalib.util import classproperty
+ 
+ if six.PY3:
+     unicode = str
+@@ -74,11 +75,13 @@ class otptoken_add_yubikey(Command):
+     )
+     has_output_params = takes_options
+ 
+-    @property
+-    def NO_CLI(self):
+-        return isinstance(self.api.Command.otptoken_add,
++    @classmethod
++    def __NO_CLI_getter(cls):
++        return isinstance(api.Command.otptoken_add,
+                           _fake_otptoken_add)
+ 
++    NO_CLI = classproperty(__NO_CLI_getter)
++
+     def get_args(self):
+         for arg in self.api.Command.otptoken_add.args():
+             yield arg
+diff --git a/ipaclient/plugins/vault.py b/ipaclient/plugins/vault.py
+index 3e116bbad54fea419b571d1f09c1b00280e94991..c0ded21d515fe41bde5fb0e547087cb7789aa6a3 100644
+--- a/ipaclient/plugins/vault.py
++++ b/ipaclient/plugins/vault.py
+@@ -38,7 +38,8 @@ import nss.nss as nss
+ 
+ from ipaclient.frontend import MethodOverride
+ from ipalib.frontend import Local, Method, Object
+-from ipalib import errors
++from ipalib.util import classproperty
++from ipalib import api, errors
+ from ipalib import Bytes, Flag, Str
+ from ipalib.plugable import Registry
+ from ipalib import _
+@@ -202,11 +203,13 @@ class vault_add(Local):
+         ),
+     )
+ 
+-    @property
+-    def NO_CLI(self):
+-        return isinstance(self.api.Command.vault_add_internal,
++    @classmethod
++    def __NO_CLI_getter(cls):
++        return isinstance(api.Command.vault_add_internal,
+                           _fake_vault_add_internal)
+ 
++    NO_CLI = classproperty(__NO_CLI_getter)
++
+     def get_args(self):
+         for arg in self.api.Command.vault_add_internal.args():
+             yield arg
+@@ -406,11 +409,13 @@ class vault_mod(Local):
+         ),
+     )
+ 
+-    @property
+-    def NO_CLI(self):
+-        return isinstance(self.api.Command.vault_mod_internal,
++    @classmethod
++    def __NO_CLI_getter(cls):
++        return isinstance(api.Command.vault_mod_internal,
+                           _fake_vault_mod_internal)
+ 
++    NO_CLI = classproperty(__NO_CLI_getter)
++
+     def get_args(self):
+         for arg in self.api.Command.vault_mod_internal.args():
+             yield arg
+@@ -591,11 +596,13 @@ class vault_archive(Local):
+         ),
+     )
+ 
+-    @property
+-    def NO_CLI(self):
+-        return isinstance(self.api.Command.vault_archive_internal,
++    @classmethod
++    def __NO_CLI_getter(cls):
++        return isinstance(api.Command.vault_archive_internal,
+                           _fake_vault_archive_internal)
+ 
++    NO_CLI = classproperty(__NO_CLI_getter)
++
+     def get_args(self):
+         for arg in self.api.Command.vault_archive_internal.args():
+             yield arg
+@@ -846,11 +853,13 @@ class vault_retrieve(Local):
+         ),
+     )
+ 
+-    @property
+-    def NO_CLI(self):
+-        return isinstance(self.api.Command.vault_retrieve_internal,
++    @classmethod
++    def __NO_CLI_getter(cls):
++        return isinstance(api.Command.vault_retrieve_internal,
+                           _fake_vault_retrieve_internal)
+ 
++    NO_CLI = classproperty(__NO_CLI_getter)
++
+     def get_args(self):
+         for arg in self.api.Command.vault_retrieve_internal.args():
+             yield arg
+diff --git a/ipaclient/remote_plugins/schema.py b/ipaclient/remote_plugins/schema.py
+index d039fb41991c26a9c7b7f76f6959668efb677586..f165736cde6f08d6d22c17070d570da261799e4b 100644
+--- a/ipaclient/remote_plugins/schema.py
++++ b/ipaclient/remote_plugins/schema.py
+@@ -89,10 +89,32 @@ class _SchemaPlugin(object):
+     bases = None
+     schema_key = None
+ 
+-    def __init__(self, full_name):
++    def __init__(self, schema, full_name):
+         self.name, _slash, self.version = full_name.partition('/')
+         self.full_name = full_name
+-        self.__class = None
++        self._schema = schema
++        self._class = None
++
++    @property
++    def doc(self):
++        if self._class is not None:
++            return self._class.doc
++        else:
++            schema = self._schema[self.schema_key][self.full_name]
++            try:
++                return schema['doc']
++            except KeyError:
++                return None
++
++    @property
++    def summary(self):
++        if self._class is not None:
++            return self._class.summary
++        else:
++            if self.doc is not None:
++                return self.doc.split('\n\n', 1)[0].strip()
++            else:
++                return u'<%s>' % self.full_name
+ 
+     def _create_default_from(self, api, name, keys):
+         cmd_name = self.full_name
+@@ -200,18 +222,37 @@ class _SchemaPlugin(object):
+         return self.name, self.bases, class_dict
+ 
+     def __call__(self, api):
+-        if self.__class is None:
++        if self._class is None:
+             schema = api._schema[self.schema_key][self.full_name]
+             name, bases, class_dict = self._create_class(api, schema)
+-            self.__class = type(name, bases, class_dict)
++            self._class = type(name, bases, class_dict)
+ 
+-        return self.__class(api)
++        return self._class(api)
+ 
+ 
+ class _SchemaCommandPlugin(_SchemaPlugin):
+     bases = (_SchemaCommand,)
+     schema_key = 'commands'
+ 
++    @property
++    def topic(self):
++        if self._class is not None:
++            return self._class.topic
++        else:
++            schema = self._schema[self.schema_key][self.full_name]
++            try:
++                return str(schema['topic_topic']).partition('/')[0]
++            except KeyError:
++                return None
++
++    @property
++    def NO_CLI(self):
++        if self._class is not None:
++            return self._class.NO_CLI
++        else:
++            schema = self._schema[self.schema_key][self.full_name]
++            return 'cli' in schema.get('exclude', [])
++
+     def _create_output(self, api, schema):
+         if schema.get('multivalue', False):
+             type_type = (tuple, list)
+@@ -565,7 +606,7 @@ def get_package(api, client):
+     module.register = plugable.Registry()
+     for plugin_cls in (_SchemaCommandPlugin, _SchemaObjectPlugin):
+         for full_name in schema[plugin_cls.schema_key]:
+-            plugin = plugin_cls(str(full_name))
++            plugin = plugin_cls(schema, str(full_name))
+             plugin = module.register()(plugin)
+     sys.modules[module_name] = module
+ 
+diff --git a/ipalib/frontend.py b/ipalib/frontend.py
+index cb00841f21bd5a3e3b4095dcd17a8816ca24400f..455b222d4d7fcbb65b43c4d8e1ffbbaf3e131d22 100644
+--- a/ipalib/frontend.py
++++ b/ipalib/frontend.py
+@@ -38,7 +38,7 @@ from ipalib.errors import (ZeroArgumentError, MaxArgumentError, OverlapError,
+     ValidationError, ConversionError)
+ from ipalib import errors, messages
+ from ipalib.request import context, context_frame
+-from ipalib.util import json_serialize
++from ipalib.util import classproperty, json_serialize
+ 
+ if six.PY3:
+     unicode = str
+@@ -426,9 +426,11 @@ class Command(HasParam):
+ 
+     api_version = API_VERSION
+ 
+-    @property
+-    def topic(self):
+-        return type(self).__module__.rpartition('.')[2]
++    @classmethod
++    def __topic_getter(cls):
++        return cls.__module__.rpartition('.')[2]
++
++    topic = classproperty(__topic_getter)
+ 
+     @property
+     def forwarded_name(self):
+diff --git a/ipalib/plugable.py b/ipalib/plugable.py
+index 26fbeaa26d7986f2e184f0974ef396bd323d6bf5..073ad05d7aee5e83cae5c6e20bac8f9439505198 100644
+--- a/ipalib/plugable.py
++++ b/ipalib/plugable.py
+@@ -155,19 +155,22 @@ class Plugin(ReadOnly):
+ 
+     bases = classproperty(__bases_getter)
+ 
+-    @property
+-    def doc(self):
+-        return type(self).__doc__
++    @classmethod
++    def __doc_getter(cls):
++        return cls.__doc__
+ 
+-    @property
+-    def summary(self):
+-        doc = self.doc
++    doc = classproperty(__doc_getter)
++
++    @classmethod
++    def __summary_getter(cls):
++        doc = cls.doc
+         if not _(doc).msg:
+-            cls = type(self)
+             return u'<%s.%s>' % (cls.__module__, cls.__name__)
+         else:
+             return unicode(doc).split('\n\n', 1)[0].strip()
+ 
++    summary = classproperty(__summary_getter)
++
+     @property
+     def api(self):
+         """
+-- 
+2.7.4
+
diff --git a/SOURCES/0062-add-permission-System-Manage-User-Certificates.patch b/SOURCES/0062-add-permission-System-Manage-User-Certificates.patch
deleted file mode 100644
index 8d0495e..0000000
--- a/SOURCES/0062-add-permission-System-Manage-User-Certificates.patch
+++ /dev/null
@@ -1,64 +0,0 @@
-From 159fe81f0f45f83f90037ba3315a3558d0ab94cf Mon Sep 17 00:00:00 2001
-From: Petr Vobornik <pvoborni@redhat.com>
-Date: Wed, 12 Aug 2015 14:48:09 +0200
-Subject: [PATCH] add permission: System: Manage User Certificates
-
-usercertificate attr was moved from "System Modify Users" to this
-new permission.
-
-https://fedorahosted.org/freeipa/ticket/5177
-
-Reviewed-By: Fraser Tweedale <ftweedal@redhat.com>
----
- ACI.txt                |  4 +++-
- ipalib/plugins/user.py | 10 +++++++++-
- 2 files changed, 12 insertions(+), 2 deletions(-)
-
-diff --git a/ACI.txt b/ACI.txt
-index 60607b98deb74d0b7f45d24ee9359b0cf8162b0d..99099275e1383f16aca122e05e34b2330f4d06a3 100644
---- a/ACI.txt
-+++ b/ACI.txt
-@@ -309,9 +309,11 @@ aci: (targetfilter = "(objectclass=posixaccount)")(version 3.0;acl "permission:S
- dn: cn=users,cn=accounts,dc=ipa,dc=example
- aci: (targetattr = "krbprincipalkey || passwordhistory || sambalmpassword || sambantpassword || userpassword")(targetfilter = "(&(!(memberOf=cn=admins,cn=groups,cn=accounts,dc=ipa,dc=example))(objectclass=posixaccount))")(version 3.0;acl "permission:System: Change User password";allow (write) groupdn = "ldap:///cn=System: Change User password,cn=permissions,cn=pbac,dc=ipa,dc=example";)
- dn: cn=users,cn=accounts,dc=ipa,dc=example
-+aci: (targetattr = "usercertificate")(targetfilter = "(objectclass=posixaccount)")(version 3.0;acl "permission:System: Manage User Certificates";allow (write) groupdn = "ldap:///cn=System: Manage User Certificates,cn=permissions,cn=pbac,dc=ipa,dc=example";)
-+dn: cn=users,cn=accounts,dc=ipa,dc=example
- aci: (targetattr = "ipasshpubkey")(targetfilter = "(objectclass=posixaccount)")(version 3.0;acl "permission:System: Manage User SSH Public Keys";allow (write) groupdn = "ldap:///cn=System: Manage User SSH Public Keys,cn=permissions,cn=pbac,dc=ipa,dc=example";)
- dn: cn=users,cn=accounts,dc=ipa,dc=example
--aci: (targetattr = "businesscategory || carlicense || cn || description || displayname || employeetype || facsimiletelephonenumber || gecos || givenname || homephone || inetuserhttpurl || initials || l || labeleduri || loginshell || manager || mepmanagedentry || mobile || objectclass || ou || pager || postalcode || preferredlanguage || roomnumber || secretary || seealso || sn || st || street || telephonenumber || title || usercertificate || userclass")(targetfilter = "(objectclass=posixaccount)")(version 3.0;acl "permission:System: Modify Users";allow (write) groupdn = "ldap:///cn=System: Modify Users,cn=permissions,cn=pbac,dc=ipa,dc=example";)
-+aci: (targetattr = "businesscategory || carlicense || cn || description || displayname || employeetype || facsimiletelephonenumber || gecos || givenname || homephone || inetuserhttpurl || initials || l || labeleduri || loginshell || manager || mepmanagedentry || mobile || objectclass || ou || pager || postalcode || preferredlanguage || roomnumber || secretary || seealso || sn || st || street || telephonenumber || title || userclass")(targetfilter = "(objectclass=posixaccount)")(version 3.0;acl "permission:System: Modify Users";allow (write) groupdn = "ldap:///cn=System: Modify Users,cn=permissions,cn=pbac,dc=ipa,dc=example";)
- dn: cn=UPG Definition,cn=Definitions,cn=Managed Entries,cn=etc,dc=ipa,dc=example
- aci: (targetattr = "*")(target = "ldap:///cn=UPG Definition,cn=Definitions,cn=Managed Entries,cn=etc,dc=ipa,dc=example")(version 3.0;acl "permission:System: Read UPG Definition";allow (compare,read,search) groupdn = "ldap:///cn=System: Read UPG Definition,cn=permissions,cn=pbac,dc=ipa,dc=example";)
- dn: cn=users,cn=accounts,dc=ipa,dc=example
-diff --git a/ipalib/plugins/user.py b/ipalib/plugins/user.py
-index 4ea770ede7525149780f1486b5e4eb44699c8533..90ae7260abf935abf92b49da04c11bc76e836e49 100644
---- a/ipalib/plugins/user.py
-+++ b/ipalib/plugins/user.py
-@@ -259,6 +259,14 @@ class user(baseuser):
-             ],
-             'default_privileges': {'User Administrators'},
-         },
-+        'System: Manage User Certificates': {
-+            'ipapermright': {'write'},
-+            'ipapermdefaultattr': {'usercertificate'},
-+            'default_privileges': {
-+                'User Administrators',
-+                'Modify Users and Reset passwords',
-+            },
-+        },
-         'System: Modify Users': {
-             'ipapermright': {'write'},
-             'ipapermdefaultattr': {
-@@ -269,7 +277,7 @@ class user(baseuser):
-                 'mepmanagedentry', 'mobile', 'objectclass', 'ou', 'pager',
-                 'postalcode', 'roomnumber', 'secretary', 'seealso', 'sn', 'st',
-                 'street', 'telephonenumber', 'title', 'userclass',
--                'preferredlanguage', 'usercertificate',
-+                'preferredlanguage',
-             },
-             'replaces': [
-                 '(targetattr = "givenname || sn || cn || displayname || title || initials || loginshell || gecos || homephone || mobile || pager || facsimiletelephonenumber || telephonenumber || street || roomnumber || l || st || postalcode || manager || secretary || description || carlicense || labeleduri || inetuserhttpurl || seealso || employeetype || businesscategory || ou || mepmanagedentry || objectclass")(target = "ldap:///uid=*,cn=users,cn=accounts,$SUFFIX")(version 3.0;acl "permission:Modify Users";allow (write) groupdn = "ldap:///cn=Modify Users,cn=permissions,cn=pbac,$SUFFIX";)',
--- 
-2.4.3
-
diff --git a/SOURCES/0062-schema-Introduce-schema-cache-format.patch b/SOURCES/0062-schema-Introduce-schema-cache-format.patch
new file mode 100644
index 0000000..1e6d14f
--- /dev/null
+++ b/SOURCES/0062-schema-Introduce-schema-cache-format.patch
@@ -0,0 +1,48 @@
+From 1242b26266b5f1222924dc06479e19d0914a0703 Mon Sep 17 00:00:00 2001
+From: David Kupka <dkupka@redhat.com>
+Date: Wed, 27 Jul 2016 10:54:16 +0200
+Subject: [PATCH] schema: Introduce schema cache format
+
+Information about schema cache format is stored in every cache item.
+When schema cache format changes in incompatible way format will be
+increased. When format stored in cache doesn't match currently used
+format the entry in cache is ignored.
+
+https://fedorahosted.org/freeipa/ticket/6048
+
+Reviewed-By: Jan Cholasta <jcholast@redhat.com>
+---
+ ipaclient/remote_plugins/schema.py | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+diff --git a/ipaclient/remote_plugins/schema.py b/ipaclient/remote_plugins/schema.py
+index f165736cde6f08d6d22c17070d570da261799e4b..d7c018e3de1cc79ffc086e3576542ce993ebc87a 100644
+--- a/ipaclient/remote_plugins/schema.py
++++ b/ipaclient/remote_plugins/schema.py
+@@ -23,6 +23,8 @@ from ipapython.dn import DN
+ from ipapython.dnsutil import DNSName
+ from ipapython.ipa_log_manager import log_mgr
+ 
++FORMAT = '0'
++
+ if six.PY3:
+     unicode = str
+ 
+@@ -478,6 +480,14 @@ class Schema(object):
+         return _LockedZipFile(path, mode)
+ 
+     def _get_schema_fingerprint(self, schema):
++        try:
++            fmt = json.loads(schema.read('format'))
++        except KeyError:
++            fmt = '0'
++
++        if fmt != FORMAT:
++            raise RuntimeError('invalid format')
++
+         schema_info = json.loads(schema.read(self.schema_info_path))
+         return schema_info['fingerprint']
+ 
+-- 
+2.7.4
+
diff --git a/SOURCES/0063-Add-permission-for-bypassing-CA-ACL-enforcement.patch b/SOURCES/0063-Add-permission-for-bypassing-CA-ACL-enforcement.patch
deleted file mode 100644
index 480d85b..0000000
--- a/SOURCES/0063-Add-permission-for-bypassing-CA-ACL-enforcement.patch
+++ /dev/null
@@ -1,86 +0,0 @@
-From 61487ce8cbcad43a711931e92c3c2ef9b160cc02 Mon Sep 17 00:00:00 2001
-From: Fraser Tweedale <ftweedal@redhat.com>
-Date: Tue, 4 Aug 2015 01:13:09 -0400
-Subject: [PATCH] Add permission for bypassing CA ACL enforcement
-
-Add the "Request Certificate ignoring CA ACLs" permission and
-associated ACI, initially assigned to "Certificate Administrators"
-privilege.
-
-Update cert-request command to skip CA ACL enforcement when the bind
-principal has this permission.
-
-Fixes: https://fedorahosted.org/freeipa/ticket/5099
-Reviewed-By: Martin Babinsky <mbabinsk@redhat.com>
----
- install/updates/40-delegation.update | 15 +++++++++++++++
- ipalib/plugins/cert.py               | 13 ++++++++++---
- 2 files changed, 25 insertions(+), 3 deletions(-)
-
-diff --git a/install/updates/40-delegation.update b/install/updates/40-delegation.update
-index bc0736c5b6c07747586a56c2cbde9596c7522d1c..8d4f6296cbed7fcc968c2193022cb50b488c8561 100644
---- a/install/updates/40-delegation.update
-+++ b/install/updates/40-delegation.update
-@@ -144,6 +144,21 @@ default:member: cn=Certificate Administrators,cn=privileges,cn=pbac,$SUFFIX
- dn: $SUFFIX
- add:aci:(targetattr = "objectclass")(target = "ldap:///cn=request certificate with subjectaltname,cn=virtual operations,cn=etc,$SUFFIX" )(version 3.0; acl "permission:Request Certificate with SubjectAltName"; allow (write) groupdn = "ldap:///cn=Request Certificate with SubjectAltName,cn=permissions,cn=pbac,$SUFFIX";)
- 
-+dn: cn=request certificate ignore caacl,cn=virtual operations,cn=etc,$SUFFIX
-+default:objectClass: top
-+default:objectClass: nsContainer
-+default:cn: request certificate ignore caacl
-+
-+dn: cn=Request Certificate ignoring CA ACLs,cn=permissions,cn=pbac,$SUFFIX
-+default:objectClass: top
-+default:objectClass: groupofnames
-+default:objectClass: ipapermission
-+default:cn: Request Certificate ignoring CA ACLs
-+default:member: cn=Certificate Administrators,cn=privileges,cn=pbac,$SUFFIX
-+
-+dn: $SUFFIX
-+add:aci:(targetattr = "objectclass")(target = "ldap:///cn=request certificate ignore caacl,cn=virtual operations,cn=etc,$SUFFIX" )(version 3.0; acl "permission:Request Certificate ignoring CA ACLs"; allow (write) groupdn = "ldap:///cn=Request Certificate ignoring CA ACLs,cn=permissions,cn=pbac,$SUFFIX";)
-+
- 
- # Read privileges
- dn: cn=RBAC Readers,cn=privileges,cn=pbac,$SUFFIX
-diff --git a/ipalib/plugins/cert.py b/ipalib/plugins/cert.py
-index 610f2149363eaa74180e9de5c9ee1439446ef409..daa698b54f2cc1b645245d312fae0f0500239ea2 100644
---- a/ipalib/plugins/cert.py
-+++ b/ipalib/plugins/cert.py
-@@ -345,8 +345,6 @@ class cert_request(VirtualCommand):
-         else:
-             principal_type = SERVICE
- 
--        caacl_check(principal_type, principal_string, ca, profile_id)
--
-         bind_principal = split_any_principal(getattr(context, 'principal'))
-         bind_service, bind_name, bind_realm = bind_principal
- 
-@@ -362,6 +360,15 @@ class cert_request(VirtualCommand):
-             self.check_access()
- 
-         try:
-+            self.check_access("request certificate ignore caacl")
-+            bypass_caacl = True
-+        except errors.ACIError:
-+            bypass_caacl = False
-+
-+        if not bypass_caacl:
-+            caacl_check(principal_type, principal_string, ca, profile_id)
-+
-+        try:
-             subject = pkcs10.get_subject(csr)
-             extensions = pkcs10.get_extensions(csr)
-             subjectaltname = pkcs10.get_subjectaltname(csr) or ()
-@@ -469,7 +476,7 @@ class cert_request(VirtualCommand):
-                         raise errors.ACIError(info=_(
-                             "Insufficient privilege to create a certificate "
-                             "with subject alt name '%s'.") % name)
--                if alt_principal_string is not None:
-+                if alt_principal_string is not None and not bypass_caacl:
-                     caacl_check(
-                         principal_type, alt_principal_string, ca, profile_id)
-             elif name_type in (pkcs10.SAN_OTHERNAME_KRB5PRINCIPALNAME,
--- 
-2.4.3
-
diff --git a/SOURCES/0063-schema-Generate-bits-for-help-load-them-on-request.patch b/SOURCES/0063-schema-Generate-bits-for-help-load-them-on-request.patch
new file mode 100644
index 0000000..2a0ba33
--- /dev/null
+++ b/SOURCES/0063-schema-Generate-bits-for-help-load-them-on-request.patch
@@ -0,0 +1,162 @@
+From 5386802ebc96ef0c2bc4a3bfa260ee83a6d7fe5f Mon Sep 17 00:00:00 2001
+From: David Kupka <dkupka@redhat.com>
+Date: Tue, 2 Aug 2016 08:16:30 +0200
+Subject: [PATCH] schema: Generate bits for help load them on request
+
+Store name, summary, topic_topic and exclude in single entry in cache
+for all commands. These data are needed for help and storing and
+loading them together allows fast help response.
+
+https://fedorahosted.org/freeipa/ticket/6048
+
+Reviewed-By: Jan Cholasta <jcholast@redhat.com>
+---
+ ipaclient/remote_plugins/schema.py | 54 +++++++++++++++++++++++++++++---------
+ 1 file changed, 42 insertions(+), 12 deletions(-)
+
+diff --git a/ipaclient/remote_plugins/schema.py b/ipaclient/remote_plugins/schema.py
+index d7c018e3de1cc79ffc086e3576542ce993ebc87a..5264d4cc177ba457c517f93f203e0baca7b0ac01 100644
+--- a/ipaclient/remote_plugins/schema.py
++++ b/ipaclient/remote_plugins/schema.py
+@@ -23,7 +23,7 @@ from ipapython.dn import DN
+ from ipapython.dnsutil import DNSName
+ from ipapython.ipa_log_manager import log_mgr
+ 
+-FORMAT = '0'
++FORMAT = '1'
+ 
+ if six.PY3:
+     unicode = str
+@@ -113,9 +113,11 @@ class _SchemaPlugin(object):
+         if self._class is not None:
+             return self._class.summary
+         else:
+-            if self.doc is not None:
+-                return self.doc.split('\n\n', 1)[0].strip()
+-            else:
++            self._schema.load_help()
++            schema = self._schema[self.schema_key][self.full_name]
++            try:
++                return schema['summary']
++            except KeyError:
+                 return u'<%s>' % self.full_name
+ 
+     def _create_default_from(self, api, name, keys):
+@@ -241,6 +243,7 @@ class _SchemaCommandPlugin(_SchemaPlugin):
+         if self._class is not None:
+             return self._class.topic
+         else:
++            self._schema.load_help()
+             schema = self._schema[self.schema_key][self.full_name]
+             try:
+                 return str(schema['topic_topic']).partition('/')[0]
+@@ -252,6 +255,7 @@ class _SchemaCommandPlugin(_SchemaPlugin):
+         if self._class is not None:
+             return self._class.NO_CLI
+         else:
++            self._schema.load_help()
+             schema = self._schema[self.schema_key][self.full_name]
+             return 'cli' in schema.get('exclude', [])
+ 
+@@ -432,7 +436,6 @@ class Schema(object):
+ 
+     """
+     namespaces = {'classes', 'commands', 'topics'}
+-    schema_info_path = 'schema'
+     _DIR = os.path.join(USER_CACHE_PATH, 'ipa', 'schema')
+ 
+     def __init__(self, api, server_info, client):
+@@ -488,8 +491,7 @@ class Schema(object):
+         if fmt != FORMAT:
+             raise RuntimeError('invalid format')
+ 
+-        schema_info = json.loads(schema.read(self.schema_info_path))
+-        return schema_info['fingerprint']
++        return json.loads(schema.read('fingerprint'))
+ 
+     def _fetch(self, client):
+         if not client.isconnected():
+@@ -522,6 +524,7 @@ class Schema(object):
+         else:
+             fp = schema['fingerprint']
+             ttl = schema.pop('ttl', 0)
++            schema.pop('version', None)
+ 
+             for key, value in schema.items():
+                 if key in self.namespaces:
+@@ -534,8 +537,6 @@ class Schema(object):
+     def _read_schema(self):
+         with self._open_schema(self._fingerprint, 'r') as schema:
+             self._dict['fingerprint'] = self._get_schema_fingerprint(schema)
+-            schema_info = json.loads(schema.read(self.schema_info_path))
+-            self._dict['version'] = schema_info['version']
+ 
+             for name in schema.namelist():
+                 ns, _slash, key = name.partition('/')
+@@ -548,6 +549,27 @@ class Schema(object):
+         except KeyError:
+             return self._dict[key]
+ 
++    def _generate_help(self, schema):
++        halp = {}
++
++        for namespace in ('commands', 'topics'):
++            halp[namespace] = {}
++
++            for member_schema in schema[namespace].values():
++                member_full_name = member_schema['full_name']
++
++                topic = halp[namespace].setdefault(member_full_name, {})
++                topic['name'] = member_schema['name']
++                if 'doc' in member_schema:
++                    topic['summary'] = (
++                        member_schema['doc'].split('\n\n', 1)[0].strip())
++                if 'topic_topic' in member_schema:
++                    topic['topic_topic'] = member_schema['topic_topic']
++                if 'exclude' in member_schema:
++                    topic['exclude'] = member_schema['exclude']
++
++        return halp
++
+     def _write_schema(self):
+         try:
+             os.makedirs(self._DIR)
+@@ -557,7 +579,6 @@ class Schema(object):
+                 return
+ 
+         with self._open_schema(self._fingerprint, 'w') as schema:
+-            schema_info = {}
+             for key, value in self._dict.items():
+                 if key in self.namespaces:
+                     ns = value
+@@ -565,9 +586,10 @@ class Schema(object):
+                         path = '{}/{}'.format(key, member)
+                         schema.writestr(path, json.dumps(ns[member]))
+                 else:
+-                    schema_info[key] = value
++                    schema.writestr(key, json.dumps(value))
+ 
+-            schema.writestr(self.schema_info_path, json.dumps(schema_info))
++            schema.writestr('_help',
++                            json.dumps(self._generate_help(self._dict)))
+ 
+     def _read(self, path):
+         with self._open_schema(self._fingerprint, 'r') as zf:
+@@ -587,6 +609,14 @@ class Schema(object):
+     def iter_namespace(self, namespace):
+         return iter(self._dict[namespace])
+ 
++    def load_help(self):
++        if not self._help:
++            self._help = self._read('_help')
++
++            for ns in self._help:
++                for member in self._help[ns]:
++                    self._dict[ns][member].update(self._help[ns][member])
++
+ 
+ def get_package(api, client):
+     try:
+-- 
+2.7.4
+
diff --git a/SOURCES/0064-Added-CLI-param-and-ACL-for-vault-service-operations.patch b/SOURCES/0064-Added-CLI-param-and-ACL-for-vault-service-operations.patch
deleted file mode 100644
index 278ea95..0000000
--- a/SOURCES/0064-Added-CLI-param-and-ACL-for-vault-service-operations.patch
+++ /dev/null
@@ -1,383 +0,0 @@
-From 366a208f9d7bbbf637d192d1dfcab4482f69c441 Mon Sep 17 00:00:00 2001
-From: "Endi S. Dewata" <edewata@redhat.com>
-Date: Tue, 11 Aug 2015 08:19:59 +0200
-Subject: [PATCH] Added CLI param and ACL for vault service operations.
-
-The CLIs to manage vault owners and members have been modified
-to accept services with a new parameter.
-
-A new ACL has been added to allow a service to create its own
-service container.
-
-https://fedorahosted.org/freeipa/ticket/5172
-
-Reviewed-By: Jan Cholasta <jcholast@redhat.com>
-Reviewed-By: Martin Kosek <mkosek@redhat.com>
----
- API.txt                    |  12 ++-
- VERSION                    |   4 +-
- install/share/vault.update |   1 +
- ipalib/plugins/vault.py    | 177 +++++++++++++++++++++------------------------
- 4 files changed, 94 insertions(+), 100 deletions(-)
-
-diff --git a/API.txt b/API.txt
-index 2e19d6b2f1e16cc1c89d71ed7d443145426a28e3..71df3a56595a012e6382414ad4453d30ede8155b 100644
---- a/API.txt
-+++ b/API.txt
-@@ -5434,13 +5434,14 @@ output: Entry('result', <type 'dict'>, Gettext('A dictionary representing an LDA
- output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
- output: PrimaryKey('value', None, None)
- command: vault_add_member
--args: 1,9,3
-+args: 1,10,3
- arg: Str('cn', attribute=True, cli_name='name', maxlength=255, multivalue=False, pattern='^[a-zA-Z0-9_.-]+$', primary_key=True, query=True, required=True)
- option: Flag('all', autofill=True, cli_name='all', default=False, exclude='webui')
- option: Str('group*', alwaysask=True, cli_name='groups', csv=True)
- option: Flag('no_members', autofill=True, default=False, exclude='webui')
- option: Flag('raw', autofill=True, cli_name='raw', default=False, exclude='webui')
- option: Str('service?')
-+option: Str('services', alwaysask=True, cli_name='services', csv=True, multivalue=True, required=False)
- option: Flag('shared?', autofill=True, default=False)
- option: Str('user*', alwaysask=True, cli_name='users', csv=True)
- option: Str('username?', cli_name='user')
-@@ -5449,13 +5450,14 @@ output: Output('completed', <type 'int'>, None)
- output: Output('failed', <type 'dict'>, None)
- output: Entry('result', <type 'dict'>, Gettext('A dictionary representing an LDAP entry', domain='ipa', localedir=None))
- command: vault_add_owner
--args: 1,9,3
-+args: 1,10,3
- arg: Str('cn', attribute=True, cli_name='name', maxlength=255, multivalue=False, pattern='^[a-zA-Z0-9_.-]+$', primary_key=True, query=True, required=True)
- option: Flag('all', autofill=True, cli_name='all', default=False, exclude='webui')
- option: Str('group*', alwaysask=True, cli_name='groups', csv=True)
- option: Flag('no_members', autofill=True, default=False, exclude='webui')
- option: Flag('raw', autofill=True, cli_name='raw', default=False, exclude='webui')
- option: Str('service?')
-+option: Str('services', alwaysask=True, cli_name='services', csv=True, multivalue=True, required=False)
- option: Flag('shared?', autofill=True, default=False)
- option: Str('user*', alwaysask=True, cli_name='users', csv=True)
- option: Str('username?', cli_name='user')
-@@ -5547,13 +5549,14 @@ output: Entry('result', <type 'dict'>, Gettext('A dictionary representing an LDA
- output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
- output: PrimaryKey('value', None, None)
- command: vault_remove_member
--args: 1,9,3
-+args: 1,10,3
- arg: Str('cn', attribute=True, cli_name='name', maxlength=255, multivalue=False, pattern='^[a-zA-Z0-9_.-]+$', primary_key=True, query=True, required=True)
- option: Flag('all', autofill=True, cli_name='all', default=False, exclude='webui')
- option: Str('group*', alwaysask=True, cli_name='groups', csv=True)
- option: Flag('no_members', autofill=True, default=False, exclude='webui')
- option: Flag('raw', autofill=True, cli_name='raw', default=False, exclude='webui')
- option: Str('service?')
-+option: Str('services', alwaysask=True, cli_name='services', csv=True, multivalue=True, required=False)
- option: Flag('shared?', autofill=True, default=False)
- option: Str('user*', alwaysask=True, cli_name='users', csv=True)
- option: Str('username?', cli_name='user')
-@@ -5562,13 +5565,14 @@ output: Output('completed', <type 'int'>, None)
- output: Output('failed', <type 'dict'>, None)
- output: Entry('result', <type 'dict'>, Gettext('A dictionary representing an LDAP entry', domain='ipa', localedir=None))
- command: vault_remove_owner
--args: 1,9,3
-+args: 1,10,3
- arg: Str('cn', attribute=True, cli_name='name', maxlength=255, multivalue=False, pattern='^[a-zA-Z0-9_.-]+$', primary_key=True, query=True, required=True)
- option: Flag('all', autofill=True, cli_name='all', default=False, exclude='webui')
- option: Str('group*', alwaysask=True, cli_name='groups', csv=True)
- option: Flag('no_members', autofill=True, default=False, exclude='webui')
- option: Flag('raw', autofill=True, cli_name='raw', default=False, exclude='webui')
- option: Str('service?')
-+option: Str('services', alwaysask=True, cli_name='services', csv=True, multivalue=True, required=False)
- option: Flag('shared?', autofill=True, default=False)
- option: Str('user*', alwaysask=True, cli_name='users', csv=True)
- option: Str('username?', cli_name='user')
-diff --git a/VERSION b/VERSION
-index ca43f3e0c06880d355c068514134187c5edda175..69351a8fa8e27c884c130ab49d3fab541cd09ff9 100644
---- a/VERSION
-+++ b/VERSION
-@@ -90,5 +90,5 @@ IPA_DATA_VERSION=20100614120000
- #                                                      #
- ########################################################
- IPA_API_VERSION_MAJOR=2
--IPA_API_VERSION_MINOR=148
--# Last change: ftweedal - add --out option to user-show
-+IPA_API_VERSION_MINOR=149
-+# Last change: edewata - Added CLI param and ACL for vault service operations
-diff --git a/install/share/vault.update b/install/share/vault.update
-index 61a8940b544fbc839b931f337389ac35dc2d1ffa..14421b5189efe9b3d9491e845e74debca6e18941 100644
---- a/install/share/vault.update
-+++ b/install/share/vault.update
-@@ -8,6 +8,7 @@ default: objectClass: top
- default: objectClass: ipaVaultContainer
- default: cn: vaults
- default: aci: (target="ldap:///cn=*,cn=users,cn=vaults,cn=kra,$SUFFIX")(version 3.0; acl "Allow users to create private container"; allow (add) userdn = "ldap:///uid=($$attr.cn),cn=users,cn=accounts,$SUFFIX";)
-+default: aci: (target="ldap:///cn=*,cn=services,cn=vaults,cn=kra,$SUFFIX")(version 3.0; acl "Allow services to create private container"; allow (add) userdn = "ldap:///krbprincipalname=($$attr.cn)@$REALM,cn=services,cn=accounts,$SUFFIX";)
- default: aci: (targetfilter="(objectClass=ipaVault)")(targetattr="*")(version 3.0; acl "Container owners can manage vaults in the container"; allow(read, search, compare, add, delete) userattr="parent[1].owner#USERDN";)
- default: aci: (targetfilter="(objectClass=ipaVault)")(targetattr="*")(version 3.0; acl "Indirect container owners can manage vaults in the container"; allow(read, search, compare, add, delete) userattr="parent[1].owner#GROUPDN";)
- default: aci: (targetfilter="(objectClass=ipaVault)")(targetattr="*")(version 3.0; acl "Vault members can access the vault"; allow(read, search, compare) userattr="member#USERDN";)
-diff --git a/ipalib/plugins/vault.py b/ipalib/plugins/vault.py
-index ac608f5c7e2779da138c75a0f02bd5546f4aeffd..01c6096335d47b337253d4f2d1e0571200383c7a 100644
---- a/ipalib/plugins/vault.py
-+++ b/ipalib/plugins/vault.py
-@@ -44,7 +44,7 @@ from ipalib.crud import PKQuery, Retrieve, Update
- from ipalib.plugable import Registry
- from ipalib.plugins.baseldap import LDAPObject, LDAPCreate, LDAPDelete,\
-     LDAPSearch, LDAPUpdate, LDAPRetrieve, LDAPAddMember, LDAPRemoveMember,\
--    pkey_to_value
-+    LDAPModMember, pkey_to_value
- from ipalib.request import context
- from ipalib.plugins.user import split_principal
- from ipalib import _, ngettext
-@@ -93,122 +93,91 @@ The secret can only be retrieved using the private key.
- """) + _("""
- EXAMPLES:
- """) + _("""
-- List private vaults:
-+ List vaults:
-    ipa vault-find
-+       [--user <user>|--service <service>|--shared]
- """) + _("""
-- List service vaults:
--   ipa vault-find --service <service name>
--""") + _("""
-- List shared vaults:
--   ipa vault-find --shared
--""") + _("""
-- List user vaults:
--   ipa vault-find --user <username>
--""") + _("""
-- Add a private vault:
-+ Add a standard vault:
-    ipa vault-add <name>
--""") + _("""
-- Add a service vault:
--   ipa vault-add <name> --service <service name>
--""") + _("""
-- Add a shared vault:
--   ipa vault-add <ame> --shared
--""") + _("""
-- Add a user vault:
--   ipa vault-add <name> --user <username>
-+       [--user <user>|--service <service>|--shared]
- """) + _("""
-  Add a symmetric vault:
--   ipa vault-add <name> --type symmetric --password-file password.txt
-+   ipa vault-add <name>
-+       [--user <user>|--service <service>|--shared]
-+       --type symmetric --password-file password.txt
- """) + _("""
-  Add an asymmetric vault:
--   ipa vault-add <name> --type asymmetric --public-key-file public.pem
-+   ipa vault-add <name>
-+       [--user <user>|--service <service>|--shared]
-+       --type asymmetric --public-key-file public.pem
- """) + _("""
-- Show a private vault:
-+ Show a vault:
-    ipa vault-show <name>
-+       [--user <user>|--service <service>|--shared]
- """) + _("""
-- Show a service vault:
--   ipa vault-show <name> --service <service name>
-+ Modify a vault:
-+   ipa vault-mod <name>
-+       [--user <user>|--service <service>|--shared]
-+       --desc <description>
- """) + _("""
-- Show a shared vault:
--   ipa vault-show <name> --shared
--""") + _("""
-- Show a user vault:
--   ipa vault-show <name> --user <username>
--""") + _("""
-- Modify a private vault:
--   ipa vault-mod <name> --desc <description>
--""") + _("""
-- Modify a service vault:
--   ipa vault-mod <name> --service <service name> --desc <description>
--""") + _("""
-- Modify a shared vault:
--   ipa vault-mod <name> --shared --desc <description>
--""") + _("""
-- Modify a user vault:
--   ipa vault-mod <name> --user <username> --desc <description>
--""") + _("""
-- Delete a private vault:
-+ Delete a vault:
-    ipa vault-del <name>
--""") + _("""
-- Delete a service vault:
--   ipa vault-del <name> --service <service name>
--""") + _("""
-- Delete a shared vault:
--   ipa vault-del <name> --shared
--""") + _("""
-- Delete a user vault:
--   ipa vault-del <name> --user <username>
-+       [--user <user>|--service <service>|--shared]
- """) + _("""
-  Display vault configuration:
-    ipa vaultconfig-show
- """) + _("""
-- Archive data into private vault:
--   ipa vault-archive <name> --in <input file>
--""") + _("""
-- Archive data into service vault:
--   ipa vault-archive <name> --service <service name> --in <input file>
--""") + _("""
-- Archive data into shared vault:
--   ipa vault-archive <name> --shared --in <input file>
--""") + _("""
-- Archive data into user vault:
--   ipa vault-archive <name> --user <username> --in <input file>
-+ Archive data into standard vault:
-+   ipa vault-archive <name>
-+       [--user <user>|--service <service>|--shared]
-+       --in <input file>
- """) + _("""
-  Archive data into symmetric vault:
--   ipa vault-archive <name> --in <input file>
-+   ipa vault-archive <name>
-+       [--user <user>|--service <service>|--shared]
-+       --in <input file>
-+       --password-file password.txt
- """) + _("""
-  Archive data into asymmetric vault:
--   ipa vault-archive <name> --in <input file>
--""") + _("""
-- Retrieve data from private vault:
--   ipa vault-retrieve <name> --out <output file>
--""") + _("""
-- Retrieve data from service vault:
--   ipa vault-retrieve <name> --service <service name> --out <output file>
--""") + _("""
-- Retrieve data from shared vault:
--   ipa vault-retrieve <name> --shared --out <output file>
-+   ipa vault-archive <name>
-+       [--user <user>|--service <service>|--shared]
-+       --in <input file>
- """) + _("""
-- Retrieve data from user vault:
--   ipa vault-retrieve <name> --user <username> --out <output file>
-+ Retrieve data from standard vault:
-+   ipa vault-retrieve <name>
-+       [--user <user>|--service <service>|--shared]
-+       --out <output file>
- """) + _("""
-  Retrieve data from symmetric vault:
--   ipa vault-retrieve <name> --out data.bin
-+   ipa vault-retrieve <name>
-+       [--user <user>|--service <service>|--shared]
-+       --out <output file>
-+       --password-file password.txt
- """) + _("""
-  Retrieve data from asymmetric vault:
--   ipa vault-retrieve <name> --out data.bin --private-key-file private.pem
-+   ipa vault-retrieve <name>
-+       [--user <user>|--service <service>|--shared]
-+       --out <output file> --private-key-file private.pem
- """) + _("""
-- Add a vault owner:
--   ipa vault-add-owner <name> --users <usernames>
-+ Add vault owners:
-+   ipa vault-add-owner <name>
-+       [--user <user>|--service <service>|--shared]
-+       [--users <users>]  [--groups <groups>] [--services <services>]
- """) + _("""
-- Delete a vault owner:
--   ipa vault-remove-owner <name> --users <usernames>
-+ Delete vault owners:
-+   ipa vault-remove-owner <name>
-+       [--user <user>|--service <service>|--shared]
-+       [--users <users>] [--groups <groups>] [--services <services>]
- """) + _("""
-- Add a vault member:
--   ipa vault-add-member <name> --users <usernames>
-+ Add vault members:
-+   ipa vault-add-member <name>
-+       [--user <user>|--service <service>|--shared]
-+       [--users <users>] [--groups <groups>] [--services <services>]
- """) + _("""
-- Delete a vault member:
--   ipa vault-remove-member <name> --users <usernames>
-+ Delete vault members:
-+   ipa vault-remove-member <name>
-+       [--user <user>|--service <service>|--shared]
-+       [--users <users>] [--groups <groups>] [--services <services>]
- """)
- 
- 
-@@ -285,8 +254,8 @@ class vault(LDAPObject):
-         'ipavaulttype',
-     ]
-     attribute_members = {
--        'owner': ['user', 'group'],
--        'member': ['user', 'group'],
-+        'owner': ['user', 'group', 'service'],
-+        'member': ['user', 'group', 'service'],
-     }
- 
-     label = _('Vaults')
-@@ -340,6 +309,11 @@ class vault(LDAPObject):
-             label=_('Owner groups'),
-             flags=['no_create', 'no_update', 'no_search'],
-         ),
-+        Str(
-+            'owner_service?',
-+            label=_('Owner services'),
-+            flags=['no_create', 'no_update', 'no_search'],
-+        ),
-     )
- 
-     def get_dn(self, *keys, **options):
-@@ -1432,8 +1406,23 @@ class vault_retrieve_internal(PKQuery):
-         return response
- 
- 
-+class VaultModMember(LDAPModMember):
-+    def get_options(self):
-+        for param in super(VaultModMember, self).get_options():
-+            if param.name == 'service' and param not in vault_options:
-+                param = param.clone_rename('services')
-+            yield param
-+
-+    def get_member_dns(self, **options):
-+        if 'services' in options:
-+            options['service'] = options.pop('services')
-+        else:
-+            options.pop('service', None)
-+        return super(VaultModMember, self).get_member_dns(**options)
-+
-+
- @register()
--class vault_add_owner(LDAPAddMember):
-+class vault_add_owner(VaultModMember, LDAPAddMember):
-     __doc__ = _('Add owners to a vault.')
- 
-     takes_options = LDAPAddMember.takes_options + vault_options
-@@ -1457,7 +1446,7 @@ class vault_add_owner(LDAPAddMember):
- 
- 
- @register()
--class vault_remove_owner(LDAPRemoveMember):
-+class vault_remove_owner(VaultModMember, LDAPRemoveMember):
-     __doc__ = _('Remove owners from a vault.')
- 
-     takes_options = LDAPRemoveMember.takes_options + vault_options
-@@ -1481,14 +1470,14 @@ class vault_remove_owner(LDAPRemoveMember):
- 
- 
- @register()
--class vault_add_member(LDAPAddMember):
-+class vault_add_member(VaultModMember, LDAPAddMember):
-     __doc__ = _('Add members to a vault.')
- 
-     takes_options = LDAPAddMember.takes_options + vault_options
- 
- 
- @register()
--class vault_remove_member(LDAPRemoveMember):
-+class vault_remove_member(VaultModMember, LDAPRemoveMember):
-     __doc__ = _('Remove members from a vault.')
- 
-     takes_options = LDAPRemoveMember.takes_options + vault_options
--- 
-2.4.3
-
diff --git a/SOURCES/0064-help-Do-not-create-instances-to-get-information-abou.patch b/SOURCES/0064-help-Do-not-create-instances-to-get-information-abou.patch
new file mode 100644
index 0000000..62dca09
--- /dev/null
+++ b/SOURCES/0064-help-Do-not-create-instances-to-get-information-abou.patch
@@ -0,0 +1,77 @@
+From 0ae77ea176190307ef74598179fc8be83169628a Mon Sep 17 00:00:00 2001
+From: David Kupka <dkupka@redhat.com>
+Date: Wed, 20 Jul 2016 13:24:03 +0200
+Subject: [PATCH] help: Do not create instances to get information about
+ commands and topics
+
+Creating instance requires that complete schema for the command is
+read from schema cache and passed to constructor. This operation takes
+a lot of time. Utilizing class properties and pregenerated help bits
+allows to get the necessary information directly from classes reducing
+time it takes significantly.
+
+https://fedorahosted.org/freeipa/ticket/6048
+
+Reviewed-By: Jan Cholasta <jcholast@redhat.com>
+---
+ ipalib/cli.py      | 15 ++++++++-------
+ ipalib/plugable.py |  7 +++++--
+ 2 files changed, 13 insertions(+), 9 deletions(-)
+
+diff --git a/ipalib/cli.py b/ipalib/cli.py
+index 1faf8285c47d950d5fd311154b6936c8371d746c..d89a5320853ecf575c7ba710b2db2e62e1003141 100644
+--- a/ipalib/cli.py
++++ b/ipalib/cli.py
+@@ -727,8 +727,8 @@ class help(frontend.Local):
+         self._builtins = []
+ 
+         # build help topics
+-        for c in self.api.Command():
+-            if c is not self.api.Command[c.name]:
++        for c in self.api.Command:
++            if c is not self.api.Command.get_plugin(c.name):
+                 continue
+             if c.NO_CLI:
+                 continue
+@@ -793,13 +793,14 @@ class help(frontend.Local):
+             self.print_commands(name, outfile)
+         elif name == "commands":
+             mcl = 0
+-            for cmd in self.Command():
+-                if cmd is not self.Command[cmd.name]:
++            for cmd_plugin in self.Command:
++                if cmd_plugin is not self.Command.get_plugin(cmd_plugin.name):
+                     continue
+-                if cmd.NO_CLI:
++                if cmd_plugin.NO_CLI:
+                     continue
+-                mcl = max(mcl, len(cmd.name))
+-                writer('%s  %s' % (to_cli(cmd.name).ljust(mcl), cmd.summary))
++                mcl = max(mcl, len(cmd_plugin.name))
++                writer('%s  %s' % (to_cli(cmd_plugin.name).ljust(mcl),
++                                   cmd_plugin.summary))
+         else:
+             raise HelpError(topic=name)
+ 
+diff --git a/ipalib/plugable.py b/ipalib/plugable.py
+index 073ad05d7aee5e83cae5c6e20bac8f9439505198..af35f5bae27a17230267d5b10b5fdc4f784a4760 100644
+--- a/ipalib/plugable.py
++++ b/ipalib/plugable.py
+@@ -318,9 +318,12 @@ class APINameSpace(collections.Mapping):
+         self.__enumerate()
+         return iter(self.__plugins)
+ 
+-    def __getitem__(self, key):
++    def get_plugin(self, key):
+         self.__enumerate()
+-        plugin = self.__plugins_by_key[key]
++        return self.__plugins_by_key[key]
++
++    def __getitem__(self, key):
++        plugin = self.get_plugin(key)
+         return self.__api._get(plugin)
+ 
+     def __call__(self):
+-- 
+2.7.4
+
diff --git a/SOURCES/0065-Fix-ipa-caalc-add-service-error-message.patch b/SOURCES/0065-Fix-ipa-caalc-add-service-error-message.patch
new file mode 100644
index 0000000..5435828
--- /dev/null
+++ b/SOURCES/0065-Fix-ipa-caalc-add-service-error-message.patch
@@ -0,0 +1,31 @@
+From 69a3d8a8abffe7a785efda8e6e2012718521783f Mon Sep 17 00:00:00 2001
+From: Tomas Krizek <tkrizek@redhat.com>
+Date: Tue, 9 Aug 2016 14:09:24 +0200
+Subject: [PATCH] Fix ipa-caalc-add-service error message
+
+When service is not found in ipa-caalc-add-service command, return the
+entire principal name of the service instead of the first character.
+
+https://fedorahosted.org/freeipa/ticket/6171
+
+Reviewed-By: Petr Spacek <pspacek@redhat.com>
+---
+ ipaserver/plugins/service.py | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/ipaserver/plugins/service.py b/ipaserver/plugins/service.py
+index 28ea364e9aca8c997a86e27c529fc49d8410115b..a44dcaa5e348d3deedda6c0b4f55760ad873cf49 100644
+--- a/ipaserver/plugins/service.py
++++ b/ipaserver/plugins/service.py
+@@ -575,7 +575,7 @@ class service(LDAPObject):
+             pass
+ 
+         try:
+-            return dn['krbprincipalname'][0]
++            return dn['krbprincipalname']
+         except KeyError:
+             return unicode(dn)
+ 
+-- 
+2.7.4
+
diff --git a/SOURCES/0065-trusts-Detect-missing-Samba-instance.patch b/SOURCES/0065-trusts-Detect-missing-Samba-instance.patch
deleted file mode 100644
index 50f4de4..0000000
--- a/SOURCES/0065-trusts-Detect-missing-Samba-instance.patch
+++ /dev/null
@@ -1,189 +0,0 @@
-From df641e93d2f88f642f476ad8c5b7313bdfce8d9e Mon Sep 17 00:00:00 2001
-From: Tomas Babej <tbabej@redhat.com>
-Date: Thu, 6 Aug 2015 10:10:04 +0200
-Subject: [PATCH] trusts: Detect missing Samba instance
-
-In the event of invocation of trust related commands, IPA server needs to
-contact local Samba instance. This is not possible on servers that
-merely act as AD trust agents, since they do not have Samba instance
-running.
-
-Properly detect the absence of the Samba instance and output
-user-friendly
-message which includes list of servers that are capable of running
-the command, if such exist.
-
-List of commands affected:
-* ipa trust-add
-* ipa trust-fetch-domains
-* all of the trustdomain commands available via CLI
-
-https://fedorahosted.org/freeipa/ticket/5165
-
-Reviewed-By: Martin Babinsky <mbabinsk@redhat.com>
----
- ipalib/plugins/trust.py | 99 +++++++++++++++++++++++++++++++++++++++----------
- 1 file changed, 79 insertions(+), 20 deletions(-)
-
-diff --git a/ipalib/plugins/trust.py b/ipalib/plugins/trust.py
-index 0bb5e6558b680ac1acad44461d78a571098c7b25..c7546692bdd8dd827ee9772b72a758042d97aa71 100644
---- a/ipalib/plugins/trust.py
-+++ b/ipalib/plugins/trust.py
-@@ -199,6 +199,73 @@ 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.
-+    """
-+
-+    try:
-+        entries, truncated = ldap.find_entries(
-+                "cn=ADTRUST",
-+                base_dn=api.env.container_masters + api.env.basedn
-+        )
-+    except errors.NotFound:
-+        entries = []
-+
-+    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.
-+    If Samba is not available, provide a heplful hint with the list of masters
-+    capable of running the commands.
-+    """
-+
-+    adtrust_present = api.Command['adtrust_is_enabled']()['result']
-+
-+    hint = _(
-+        ' Alternatively, following servers are capable of running this '
-+        'command: %(masters)s'
-+        )
-+
-+    def raise_missing_component_error(message):
-+        masters_with_adtrust = find_adtrust_masters(ldap, api)
-+
-+        # If there are any masters capable of running Samba requiring commands
-+        # let's advertise them directly
-+        if masters_with_adtrust:
-+            message += hint % dict(masters=', '.join(masters_with_adtrust))
-+
-+        raise errors.NotFound(
-+            name=_('AD Trust setup'),
-+            reason=message,
-+        )
-+
-+    # We're ok in this case, bail out
-+    if adtrust_present and _bindings_installed:
-+        return
-+
-+    # First check for packages missing
-+    elif not _bindings_installed:
-+        error_message=_(
-+            'Cannot perform the selected command without Samba 4 support '
-+            'installed. Make sure you have installed server-trust-ad '
-+            'sub-package of IPA.'
-+        )
-+
-+        raise_missing_component_error(error_message)
-+
-+    # Packages present, but ADTRUST instance is not configured
-+    elif not adtrust_present:
-+        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.'
-+        )
-+
-+        raise_missing_component_error(error_message)
-+
-+
- def generate_creds(trustinstance, style, **options):
-     """
-     Generate string representing credentials using trust instance
-@@ -554,6 +621,10 @@ sides.
-     has_output_params = LDAPCreate.has_output_params + trust_output_params
- 
-     def execute(self, *keys, **options):
-+        ldap = self.obj.backend
-+
-+        verify_samba_component_presence(ldap, self.api)
-+
-         full_join = self.validate_options(*keys, **options)
-         old_range, range_name, dom_sid = self.validate_range(*keys, **options)
-         result = self.execute_ad(full_join, *keys, **options)
-@@ -569,7 +640,6 @@ sides.
-             created_range_type = old_range['result']['iparangetype'][0]
- 
-         trust_filter = "cn=%s" % result['value']
--        ldap = self.obj.backend
-         (trusts, truncated) = ldap.find_entries(
-                          base_dn=DN(self.api.env.container_trusts, self.api.env.basedn),
-                          filter=trust_filter)
-@@ -642,16 +712,6 @@ sides.
-     def validate_options(self, *keys, **options):
-         trusted_realm_domain = keys[-1]
- 
--        if not _bindings_installed:
--            raise errors.NotFound(
--                name=_('AD Trust setup'),
--                reason=_(
--                    'Cannot perform join operation without Samba 4 support '
--                    'installed. Make sure you have installed server-trust-ad '
--                    'sub-package of IPA'
--                )
--            )
--
-         if not _murmur_installed and 'base_id' not in options:
-             raise errors.ValidationError(
-                 name=_('missing base_id'),
-@@ -1398,6 +1458,9 @@ class trustdomain_del(LDAPDelete):
-     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
- 
-@@ -1470,15 +1533,9 @@ class trust_fetch_domains(LDAPRetrieve):
-     )
- 
-     def execute(self, *keys, **options):
--        if not _bindings_installed:
--            raise errors.NotFound(
--                name=_('AD Trust setup'),
--                reason=_(
--                    'Cannot perform join operation without Samba 4 support '
--                    'installed. Make sure you have installed server-trust-ad '
--                    'sub-package of IPA'
--                )
--            )
-+        ldap = self.api.Backend.ldap2
-+        verify_samba_component_presence(ldap, self.api)
-+
-         trust = self.api.Command.trust_show(keys[0], raw=True)['result']
- 
-         result = dict()
-@@ -1524,6 +1581,7 @@ class trustdomain_enable(LDAPQuery):
- 
-     def execute(self, *keys, **options):
-         ldap = self.api.Backend.ldap2
-+        verify_samba_component_presence(ldap, self.api)
- 
-         if keys[0].lower() == keys[1].lower():
-             raise errors.ValidationError(name='domain',
-@@ -1564,6 +1622,7 @@ class trustdomain_disable(LDAPQuery):
- 
-     def execute(self, *keys, **options):
-         ldap = self.api.Backend.ldap2
-+        verify_samba_component_presence(ldap, self.api)
- 
-         if keys[0].lower() == keys[1].lower():
-             raise errors.ValidationError(name='domain',
--- 
-2.4.3
-
diff --git a/SOURCES/0066-Don-t-show-force-ntpd-option-in-replica-install.patch b/SOURCES/0066-Don-t-show-force-ntpd-option-in-replica-install.patch
new file mode 100644
index 0000000..96e2a22
--- /dev/null
+++ b/SOURCES/0066-Don-t-show-force-ntpd-option-in-replica-install.patch
@@ -0,0 +1,42 @@
+From a1b1518f02e0237fb8080851d0722f866b127918 Mon Sep 17 00:00:00 2001
+From: Stanislav Laznicka <slaznick@redhat.com>
+Date: Tue, 9 Aug 2016 15:22:33 +0200
+Subject: [PATCH] Don't show --force-ntpd option in replica install
+
+Always run the client installation script with --no-ntp
+option so that it does not show the message about --force-ntpd
+option that does not exist in ipa-replica-install. The time
+synchronization is done elsewhere anyway.
+
+https://fedorahosted.org/freeipa/ticket/6046
+
+Reviewed-By: Martin Basti <mbasti@redhat.com>
+---
+ ipaserver/install/server/replicainstall.py | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/ipaserver/install/server/replicainstall.py b/ipaserver/install/server/replicainstall.py
+index 9d05a0be5a2679d825b4ee6bc2ea55ed358e8ff9..f54ff7da06c57b9c8251429cbdacc5c300805f84 100644
+--- a/ipaserver/install/server/replicainstall.py
++++ b/ipaserver/install/server/replicainstall.py
+@@ -881,7 +881,7 @@ def install(installer):
+     try:
+         args = [paths.IPA_CLIENT_INSTALL, "--on-master", "--unattended",
+                 "--domain", config.domain_name, "--server", config.host_name,
+-                "--realm", config.realm_name]
++                "--realm", config.realm_name, "--no-ntp"]
+         if options.no_dns_sshfp:
+             args.append("--no-dns-sshfp")
+         if options.ssh_trust_dns:
+@@ -918,7 +918,7 @@ def ensure_enrolled(installer):
+     try:
+         installer._enrollment_performed = True
+ 
+-        args = [paths.IPA_CLIENT_INSTALL, "--unattended"]
++        args = [paths.IPA_CLIENT_INSTALL, "--unattended", "--no-ntp"]
+         stdin = None
+ 
+         if installer.domain_name:
+-- 
+2.7.4
+
diff --git a/SOURCES/0066-winsync-migrate-Add-warning-about-passsync.patch b/SOURCES/0066-winsync-migrate-Add-warning-about-passsync.patch
deleted file mode 100644
index d3917e2..0000000
--- a/SOURCES/0066-winsync-migrate-Add-warning-about-passsync.patch
+++ /dev/null
@@ -1,38 +0,0 @@
-From cdbf2fcc214bf8a4f94e3b25b6a742ea1fc9f75c Mon Sep 17 00:00:00 2001
-From: Tomas Babej <tbabej@redhat.com>
-Date: Mon, 17 Aug 2015 08:46:52 +0200
-Subject: [PATCH] winsync-migrate: Add warning about passsync
-
-https://fedorahosted.org/freeipa/ticket/5162
-
-Reviewed-By: Martin Babinsky <mbabinsk@redhat.com>
----
- ipaserver/install/ipa_winsync_migrate.py | 8 ++++++++
- 1 file changed, 8 insertions(+)
-
-diff --git a/ipaserver/install/ipa_winsync_migrate.py b/ipaserver/install/ipa_winsync_migrate.py
-index cbe068458cc0b6853573c9d23d4cb6386a816bb3..c327e502e6bfb6e402931e1962fe2410570b2bc2 100644
---- a/ipaserver/install/ipa_winsync_migrate.py
-+++ b/ipaserver/install/ipa_winsync_migrate.py
-@@ -302,6 +302,12 @@ class WinsyncMigrate(admintool.AdminTool):
-             object_container_dn=DN(api.env.container_selinux, api.env.basedn),
-         )
- 
-+    def warn_passsync(self):
-+        self.log.warning("Migration completed. Please note that if PassSync "
-+            "was configured on the given Active Directory server, "
-+            "it needs to be manually removed, otherwise it may try "
-+            "to reset password for accounts that are no longer existent.")
-+
-     @classmethod
-     def main(cls, argv):
-         """
-@@ -343,3 +349,5 @@ class WinsyncMigrate(admintool.AdminTool):
-             self.migrate_hbac_memberships(entry)
-             self.migrate_selinux_memberships(entry)
-             self.ldap.delete_entry(entry)
-+
-+        self.warn_passsync()
--- 
-2.4.3
-
diff --git a/SOURCES/0067-DNS-server-upgrade-do-not-fail-when-DNS-server-did-n.patch b/SOURCES/0067-DNS-server-upgrade-do-not-fail-when-DNS-server-did-n.patch
new file mode 100644
index 0000000..dce696d
--- /dev/null
+++ b/SOURCES/0067-DNS-server-upgrade-do-not-fail-when-DNS-server-did-n.patch
@@ -0,0 +1,62 @@
+From 78ef6581483190fc60fc928fb2263f5520a5edfa Mon Sep 17 00:00:00 2001
+From: Petr Spacek <pspacek@redhat.com>
+Date: Thu, 11 Aug 2016 13:44:29 +0200
+Subject: [PATCH] DNS server upgrade: do not fail when DNS server did not
+ respond
+
+Previously, update_dnsforward_emptyzones failed with an exeception if
+DNS query failed for some reason. Now the error is logged and upgrade
+continues.
+
+I assume that this is okay because the DNS query is used as heuristics
+of last resort in the upgrade logic and failure to do so should not have
+catastrophics consequences: In the worst case, the admin needs to
+manually change forwarding policy from 'first' to 'only'.
+
+In the end I have decided not to auto-start BIND because BIND depends on
+GSSAPI for authentication, which in turn depends on KDC ... Alternative
+like reconfiguring BIND to use LDAPI+EXTERNAL and reconfiguring DS to
+accept LDAP external bind from named user are too complicated.
+
+https://fedorahosted.org/freeipa/ticket/6205
+
+Reviewed-By: Martin Basti <mbasti@redhat.com>
+---
+ ipaserver/install/plugins/dns.py | 14 ++++++++++++--
+ 1 file changed, 12 insertions(+), 2 deletions(-)
+
+diff --git a/ipaserver/install/plugins/dns.py b/ipaserver/install/plugins/dns.py
+index 32247eedbac7fc7e00c7277ef0bc593a74cd22e4..7b06a5c0d3a59e5825af75fae87c9739a53d9913 100644
+--- a/ipaserver/install/plugins/dns.py
++++ b/ipaserver/install/plugins/dns.py
+@@ -17,6 +17,9 @@
+ # 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 __future__ import absolute_import
++
++import dns.exception
+ import re
+ import traceback
+ import time
+@@ -489,8 +492,15 @@ class update_dnsforward_emptyzones(DNSUpdater):
+         self.api.Command['dnsconfig_mod'](ipadnsversion=2)
+ 
+         self.update_zones()
+-        if dnsutil.has_empty_zone_addresses(self.api.env.host):
+-            self.update_global_ldap_forwarder()
++        try:
++            if dnsutil.has_empty_zone_addresses(self.api.env.host):
++                self.update_global_ldap_forwarder()
++        except dns.exception.DNSException as ex:
++            self.log.error('Skipping update of global DNS forwarder in LDAP: '
++                           'Unable to determine if local server is using an '
++                           'IP address belonging to an automatic empty zone. '
++                           'Consider changing forwarding policy to "only". '
++                           'DNS exception: %s', ex)
+ 
+         return False, []
+ 
+-- 
+2.7.4
+
diff --git a/SOURCES/0067-winsync-migrate-Expand-the-man-page.patch b/SOURCES/0067-winsync-migrate-Expand-the-man-page.patch
deleted file mode 100644
index 500fe82..0000000
--- a/SOURCES/0067-winsync-migrate-Expand-the-man-page.patch
+++ /dev/null
@@ -1,57 +0,0 @@
-From 6e006377d043155590024235d770cb37eb801652 Mon Sep 17 00:00:00 2001
-From: Tomas Babej <tbabej@redhat.com>
-Date: Mon, 17 Aug 2015 08:46:20 +0200
-Subject: [PATCH] winsync-migrate: Expand the man page
-
-https://fedorahosted.org/freeipa/ticket/5162
-
-Reviewed-By: Martin Babinsky <mbabinsk@redhat.com>
----
- install/tools/man/ipa-winsync-migrate.1 | 27 ++++++++++++++++++++++++++-
- 1 file changed, 26 insertions(+), 1 deletion(-)
-
-diff --git a/install/tools/man/ipa-winsync-migrate.1 b/install/tools/man/ipa-winsync-migrate.1
-index a1e01c83da6017d5cbe10297dbe84a4dd1741ec7..88702bad6fca66206dcbc1a90fce495eb33598fb 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-advise" "1" "Mar 10 2015" "FreeIPA" "FreeIPA Manual Pages"
-+.TH "ipa-winsync-migrate" "1" "Mar 10 2015" "FreeIPA" "FreeIPA Manual Pages"
- .SH "NAME"
- ipa\-winsync\-migrate \- Seamless migration of AD users created by winsync to native AD users.
- .SH "SYNOPSIS"
-@@ -25,3 +25,28 @@ ipa\-winsync\-migrate
- Migrates AD users created by winsync agreement to ID overrides in
- the Default Trust View, thus preserving the actual POSIX attributes
- already established.
-+
-+Prior to the actual migration, the winsync replication agreement
-+will be removed to protect the removal of the user accounts
-+on the Active Directory side.
-+
-+During the migration, group, assigned roles, HBAC rules and SELinux
-+memberships of the synced users will be preserved. Any local copies
-+(created by winsync) of the migrated users will be removed.
-+
-+.SH "WARNINGS"
-+After the migration, any PassSync agreements need to be removed
-+from Active Directory Domain Controllers, otherwise they might
-+attempt to update passwords for accounts that no longer exist
-+on the IPA server.
-+
-+.SH "OPTIONS"
-+.TP
-+\fB\-\-realm\fR
-+The Active Directory realm the winsynced users belong to.
-+.TP
-+\fB\-\-server\fR
-+The hostname of Active Directory Domain Controller the winsync replication agreement is established with.
-+.TP
-+\fB\-\-unattended\fR
-+Never prompts for user input.
--- 
-2.4.3
-
diff --git a/SOURCES/0068-DNS-allow-to-add-forward-zone-to-already-broken-sub-.patch b/SOURCES/0068-DNS-allow-to-add-forward-zone-to-already-broken-sub-.patch
new file mode 100644
index 0000000..567a26c
--- /dev/null
+++ b/SOURCES/0068-DNS-allow-to-add-forward-zone-to-already-broken-sub-.patch
@@ -0,0 +1,32 @@
+From 9b4153fdc1af86344da9f4cf6fa139a8dcb18c8c Mon Sep 17 00:00:00 2001
+From: Petr Spacek <pspacek@redhat.com>
+Date: Fri, 12 Aug 2016 17:08:30 +0200
+Subject: [PATCH] DNS: allow to add forward zone to already broken sub-domain
+
+Errors during DNS resolution might indicate that forwarder is the
+necessary configuration which is missing. Now we disallow adding a
+forwarder only if the zone is normally resolvable without the forwarder.
+
+https://fedorahosted.org/freeipa/ticket/6062
+
+Reviewed-By: Martin Basti <mbasti@redhat.com>
+---
+ ipaserver/plugins/dns.py | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/ipaserver/plugins/dns.py b/ipaserver/plugins/dns.py
+index 585b28c15daf00df2918a67585f7fb6e99462f1e..6f1bd716d202bd85dfc46b5eb94f73e85683b917 100644
+--- a/ipaserver/plugins/dns.py
++++ b/ipaserver/plugins/dns.py
+@@ -2097,7 +2097,7 @@ class DNSZoneBase_add(LDAPCreate):
+ 
+         if not options['skip_overlap_check']:
+             try:
+-                check_zone_overlap(keys[-1])
++                check_zone_overlap(keys[-1], raise_on_error=False)
+             except ValueError as e:
+                 raise errors.InvocationError(e.message)
+ 
+-- 
+2.7.4
+
diff --git a/SOURCES/0068-fix-typo-in-BasePathNamespace-member-pointing-to-ods.patch b/SOURCES/0068-fix-typo-in-BasePathNamespace-member-pointing-to-ods.patch
deleted file mode 100644
index f5bf21a..0000000
--- a/SOURCES/0068-fix-typo-in-BasePathNamespace-member-pointing-to-ods.patch
+++ /dev/null
@@ -1,55 +0,0 @@
-From e106329ac5dbbbcf1e303d1311cd0d742f5d8803 Mon Sep 17 00:00:00 2001
-From: Martin Babinsky <mbabinsk@redhat.com>
-Date: Thu, 13 Aug 2015 15:03:05 +0200
-Subject: [PATCH] fix typo in BasePathNamespace member pointing to ods exporter
- config
-
-Reviewed-By: Martin Basti <mbasti@redhat.com>
----
- ipaplatform/base/paths.py                | 2 +-
- ipaserver/install/ipa_backup.py          | 2 +-
- ipaserver/install/odsexporterinstance.py | 2 +-
- 3 files changed, 3 insertions(+), 3 deletions(-)
-
-diff --git a/ipaplatform/base/paths.py b/ipaplatform/base/paths.py
-index 4c93c1f7162b0aeb4f798ef84e1ac8db4573518b..0dd3c7fda3020264a1ace8f2d13557cfddf18c2d 100644
---- a/ipaplatform/base/paths.py
-+++ b/ipaplatform/base/paths.py
-@@ -119,7 +119,7 @@ class BasePathNamespace(object):
-     SYSCONFIG_DIRSRV_PKI_IPA_DIR = "/etc/sysconfig/dirsrv-PKI-IPA"
-     SYSCONFIG_DIRSRV_SYSTEMD = "/etc/sysconfig/dirsrv.systemd"
-     SYSCONFIG_IPA_DNSKEYSYNCD = "/etc/sysconfig/ipa-dnskeysyncd"
--    SYSOCNFIG_IPA_ODS_EXPORTER = "/etc/sysconfig/ipa-ods-exporter"
-+    SYSCONFIG_IPA_ODS_EXPORTER = "/etc/sysconfig/ipa-ods-exporter"
-     SYSCONFIG_HTTPD = "/etc/sysconfig/httpd"
-     SYSCONFIG_KRB5KDC_DIR = "/etc/sysconfig/krb5kdc"
-     SYSCONFIG_NAMED = "/etc/sysconfig/named"
-diff --git a/ipaserver/install/ipa_backup.py b/ipaserver/install/ipa_backup.py
-index f7e032ae572f404f84ce48c1a5d72e78c31b4766..1bb6f810b16c8344ab957dd6259983189a88e89f 100644
---- a/ipaserver/install/ipa_backup.py
-+++ b/ipaserver/install/ipa_backup.py
-@@ -132,7 +132,7 @@ class Backup(admintool.AdminTool):
-         paths.SYSCONFIG_KRB5KDC_DIR,
-         paths.SYSCONFIG_PKI_CA_PKI_CA_DIR,
-         paths.SYSCONFIG_IPA_DNSKEYSYNCD,
--        paths.SYSOCNFIG_IPA_ODS_EXPORTER,
-+        paths.SYSCONFIG_IPA_ODS_EXPORTER,
-         paths.SYSCONFIG_NAMED,
-         paths.SYSCONFIG_ODS,
-         paths.ETC_SYSCONFIG_AUTHCONFIG,
-diff --git a/ipaserver/install/odsexporterinstance.py b/ipaserver/install/odsexporterinstance.py
-index c37095cfc3bba8c6724f45d23293bdf6f4a200ee..248943d6c0ca4b71815bcf7526d575842f6ce426 100644
---- a/ipaserver/install/odsexporterinstance.py
-+++ b/ipaserver/install/odsexporterinstance.py
-@@ -86,7 +86,7 @@ class ODSExporterInstance(service.Service):
-             root_logger.error("DNSKeyExporter service already exists")
- 
-     def __setup_key_exporter(self):
--        installutils.set_directive(paths.SYSOCNFIG_IPA_ODS_EXPORTER,
-+        installutils.set_directive(paths.SYSCONFIG_IPA_ODS_EXPORTER,
-                                    'SOFTHSM2_CONF',
-                                    paths.DNSSEC_SOFTHSM2_CONF,
-                                    quotes=False, separator='=')
--- 
-2.4.3
-
diff --git a/SOURCES/0069-cert-speed-up-cert-find.patch b/SOURCES/0069-cert-speed-up-cert-find.patch
new file mode 100644
index 0000000..ecd9d83
--- /dev/null
+++ b/SOURCES/0069-cert-speed-up-cert-find.patch
@@ -0,0 +1,479 @@
+From be32fd1d727fc8398dd51fa0fd3f404ef451281a Mon Sep 17 00:00:00 2001
+From: Jan Cholasta <jcholast@redhat.com>
+Date: Mon, 1 Aug 2016 09:53:39 +0200
+Subject: [PATCH] cert: speed up cert-find
+
+Use issuer+serial rather than raw DER blob to identify certificates in
+cert-find's intermediate result.
+
+Restructure the code to make it (hopefully) easier to follow.
+
+https://fedorahosted.org/freeipa/ticket/6098
+
+Reviewed-By: Martin Basti <mbasti@redhat.com>
+Reviewed-By: Pavel Vomacka <pvomacka@redhat.com>
+---
+ ipaserver/plugins/cert.py | 398 +++++++++++++++++++++++++---------------------
+ 1 file changed, 216 insertions(+), 182 deletions(-)
+
+diff --git a/ipaserver/plugins/cert.py b/ipaserver/plugins/cert.py
+index 06041d3083565e8d093b610473d6083111d406d2..47dccf15a4010f2766642aedd2cc16e0a1eb1dd4 100644
+--- a/ipaserver/plugins/cert.py
++++ b/ipaserver/plugins/cert.py
+@@ -21,6 +21,7 @@
+ 
+ import base64
+ import binascii
++import collections
+ import datetime
+ import os
+ 
+@@ -295,18 +296,24 @@ class BaseCertObject(Object):
+         ),
+     )
+ 
+-    def _parse(self, obj):
+-        cert = x509.load_certificate(obj['certificate'])
+-        obj['subject'] = DN(unicode(cert.subject))
+-        obj['issuer'] = DN(unicode(cert.issuer))
+-        obj['valid_not_before'] = unicode(cert.valid_not_before_str)
+-        obj['valid_not_after'] = unicode(cert.valid_not_after_str)
+-        obj['md5_fingerprint'] = unicode(
+-            nss.data_to_hex(nss.md5_digest(cert.der_data), 64)[0])
+-        obj['sha1_fingerprint'] = unicode(
+-            nss.data_to_hex(nss.sha1_digest(cert.der_data), 64)[0])
+-        obj['serial_number'] = cert.serial_number
+-        obj['serial_number_hex'] = u'0x%X' % cert.serial_number
++    def _parse(self, obj, full=True):
++        cert = obj.get('certificate')
++        if cert is not None:
++            cert = x509.load_certificate(cert)
++            obj['subject'] = DN(unicode(cert.subject))
++            obj['issuer'] = DN(unicode(cert.issuer))
++            obj['serial_number'] = cert.serial_number
++            if full:
++                obj['valid_not_before'] = unicode(cert.valid_not_before_str)
++                obj['valid_not_after'] = unicode(cert.valid_not_after_str)
++                obj['md5_fingerprint'] = unicode(
++                    nss.data_to_hex(nss.md5_digest(cert.der_data), 64)[0])
++                obj['sha1_fingerprint'] = unicode(
++                    nss.data_to_hex(nss.sha1_digest(cert.der_data), 64)[0])
++
++        serial_number = obj.get('serial_number')
++        if serial_number is not None:
++            obj['serial_number_hex'] = u'0x%X' % serial_number
+ 
+ 
+ class BaseCertMethod(Method):
+@@ -691,10 +698,14 @@ class cert(BaseCertObject):
+             yield self.api.Object[name]
+ 
+     def _fill_owners(self, obj):
++        dns = obj.pop('owner', None)
++        if dns is None:
++            return
++
+         for owner in self._owners():
+             container_dn = DN(owner.container_dn, self.api.env.basedn)
+             name = 'owner_' + owner.name
+-            for dn in obj['owner']:
++            for dn in dns:
+                 if dn.endswith(container_dn, 1):
+                     value = owner.get_primary_key_from_dn(dn)
+                     obj.setdefault(name, []).append(value)
+@@ -776,9 +787,7 @@ class cert_show(Retrieve, CertMethod, VirtualCommand):
+             result['certificate'] = result['certificate'].replace('\r\n', '')
+             self.obj._parse(result)
+             result['revoked'] = ('revocation_reason' in result)
+-            if 'owner' in result:
+-                self.obj._fill_owners(result)
+-                del result['owner']
++            self.obj._fill_owners(result)
+ 
+         if hostname:
+             # If we have a hostname we want to verify that the subject
+@@ -984,36 +993,171 @@ class cert_find(Search, CertMethod):
+                 label=owner.object_name,
+             )
+ 
+-    def execute(self, criteria=None, all=False, raw=False, pkey_only=False,
+-                no_members=True, timelimit=None, sizelimit=None, **options):
+-        ca_options = {'cacn',
+-                      'revocation_reason',
+-                      'issuer',
+-                      'subject',
+-                      'min_serial_number', 'max_serial_number',
+-                      'exactly',
+-                      'validnotafter_from', 'validnotafter_to',
+-                      'validnotbefore_from', 'validnotbefore_to',
+-                      'issuedon_from', 'issuedon_to',
+-                      'revokedon_from', 'revokedon_to'}
+-        ldap_options = {prefix + owner.name
+-                        for owner in self.obj._owners()
+-                        for prefix in ('', 'no_')}
+-        has_ca_options = (
+-            any(name in options for name in ca_options - {'exactly'}) or
+-            options['exactly'])
+-        has_ldap_options = any(name in options for name in ldap_options)
+-        has_cert_option = 'certificate' in options
++    def _get_cert_key(self, cert):
++        nss_cert = x509.load_certificate(cert, x509.DER)
++
++        return (DN(unicode(nss_cert.issuer)), nss_cert.serial_number)
++
++    def _get_cert_obj(self, cert, all, raw, pkey_only):
++        obj = {'certificate': unicode(base64.b64encode(cert))}
++
++        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):
++        result = collections.OrderedDict()
++
++        try:
++            cert = options['certificate']
++        except KeyError:
++            return result, False, False
++
++        key = self._get_cert_key(cert)
++
++        result[key] = self._get_cert_obj(cert, all, raw, pkey_only)
++
++        return result, False, True
++
++    def _ca_search(self, all, raw, pkey_only, sizelimit, exactly, **options):
++        ra_options = {}
++        for name in ('revocation_reason',
++                     'issuer',
++                     'subject',
++                     'min_serial_number', 'max_serial_number',
++                     'validnotafter_from', 'validnotafter_to',
++                     'validnotbefore_from', 'validnotbefore_to',
++                     'issuedon_from', 'issuedon_to',
++                     'revokedon_from', 'revokedon_to'):
++            try:
++                value = options[name]
++            except KeyError:
++                continue
++            if isinstance(value, datetime.datetime):
++                value = value.strftime(PKIDATE_FORMAT)
++            elif isinstance(value, DN):
++                value = unicode(value)
++            ra_options[name] = value
++        if sizelimit:
++            ra_options['sizelimit'] = sizelimit
++        if exactly:
++            ra_options['exactly'] = True
++
++        result = collections.OrderedDict()
++        complete = bool(ra_options)
+ 
+         try:
+             ca_enabled_check()
+         except errors.NotFound:
+-            if has_ca_options:
++            if ra_options:
+                 raise
+-            ca_enabled = False
++            return result, False, complete
++
++        ra = self.api.Backend.ra
++        for ra_obj in ra.find(ra_options):
++            issuer = DN(ra_obj['issuer'])
++            serial_number = ra_obj['serial_number']
++
++            if pkey_only:
++                obj = {'serial_number': serial_number}
++            else:
++                obj = ra_obj
++                obj['issuer'] = issuer
++                obj['subject'] = DN(ra_obj['subject'])
++                del obj['serial_number_hex']
++
++                if all:
++                    ra_obj = ra.get_certificate(str(serial_number))
++                    if not raw:
++                        obj['certificate'] = (
++                            ra_obj['certificate'].replace('\r\n', ''))
++                        self.obj._parse(obj)
++
++            result[issuer, serial_number] = obj
++
++        return result, False, complete
++
++    def _ldap_search(self, all, raw, pkey_only, no_members, timelimit,
++                     sizelimit, **options):
++        ldap = self.api.Backend.ldap2
++
++        filters = []
++        for owner in self.obj._owners():
++            for prefix, rule in (('', ldap.MATCH_ALL),
++                                 ('no_', ldap.MATCH_NONE)):
++                try:
++                    value = options[prefix + owner.name]
++                except KeyError:
++                    continue
++
++                filter = ldap.make_filter_from_attr(
++                    'objectclass',
++                    owner.object_class,
++                    ldap.MATCH_ALL)
++                if filter not in filters:
++                    filters.append(filter)
++
++                filter = ldap.make_filter_from_attr(
++                    owner.primary_key.name,
++                    value,
++                    rule)
++                filters.append(filter)
++
++        cert = options.get('certificate')
++        if cert is not None:
++            filter = ldap.make_filter_from_attr('usercertificate', cert)
++            filters.append(filter)
++
++        result = collections.OrderedDict()
++        complete = bool(filters)
++
++        if cert is None:
++            filter = '(usercertificate=*)'
++            filters.append(filter)
++
++        filter = ldap.combine_filters(filters, ldap.MATCH_ALL)
++        try:
++            entries, truncated = ldap.find_entries(
++                base_dn=self.api.env.basedn,
++                filter=filter,
++                attrs_list=['usercertificate'],
++                time_limit=timelimit,
++                size_limit=sizelimit,
++            )
++        except errors.EmptyResult:
++            entries = []
++            truncated = False
+         else:
+-            ca_enabled = True
++            truncated = bool(truncated)
++
++        for entry in entries:
++            for attr in ('usercertificate', 'usercertificate;binary'):
++                for cert in entry.get(attr, []):
++                    key = self._get_cert_key(cert)
++
++                    try:
++                        obj = result[key]
++                    except KeyError:
++                        obj = self._get_cert_obj(cert, all, raw, pkey_only)
++                        result[key] = 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,
++                no_members=True, timelimit=None, sizelimit=None, **options):
+         if 'cacn' in options:
+             ca_obj = api.Command.ca_show(options['cacn'])['result']
+             ca_sdn = unicode(ca_obj['ipacasubjectdn'][0])
+@@ -1028,153 +1172,43 @@ class cert_find(Search, CertMethod):
+         if criteria is not None:
+             return dict(result=[], count=0, truncated=False)
+ 
+-        obj_seq = []
+-        obj_dict = {}
++        result = collections.OrderedDict()
+         truncated = False
+-
+-        if has_cert_option:
+-            cert = options['certificate']
+-            obj = {'certificate': unicode(base64.b64encode(cert))}
+-            obj_seq.append(obj)
+-            obj_dict[cert] = obj
+-
+-        if ca_enabled:
+-            ra_options = {}
+-            for name, value in options.items():
+-                if name not in ca_options:
+-                    continue
+-                if isinstance(value, datetime.datetime):
+-                    value = value.strftime(PKIDATE_FORMAT)
+-                elif isinstance(value, DN):
+-                    value = unicode(value)
+-                ra_options[name] = value
+-            if sizelimit is not None:
+-                if sizelimit != 0:
+-                    ra_options['sizelimit'] = sizelimit
+-                sizelimit = 0
+-                has_ca_options = True
+-
+-            for ra_obj in self.Backend.ra.find(ra_options):
+-                obj = {}
+-                if ((not pkey_only and all) or
+-                        not no_members or
+-                        not has_ca_options or
+-                        has_ldap_options or
+-                        has_cert_option):
+-                    ra_obj.update(
+-                        self.Backend.ra.get_certificate(
+-                            str(ra_obj['serial_number'])))
+-                    cert = base64.b64decode(ra_obj['certificate'])
+-                    try:
+-                        obj = obj_dict[cert]
+-                    except KeyError:
+-                        if has_cert_option:
+-                            continue
+-                        obj = {}
+-                        obj_seq.append(obj)
+-                        obj_dict[cert] = obj
++        complete = False
++
++        for sub_search in (self._cert_search,
++                           self._ca_search,
++                           self._ldap_search):
++            sub_result, sub_truncated, sub_complete = sub_search(
++                all=all,
++                raw=raw,
++                pkey_only=pkey_only,
++                no_members=no_members,
++                timelimit=timelimit,
++                sizelimit=sizelimit,
++                **options)
++
++            if sub_complete:
++                sizelimit = None
++
++                for key in tuple(result):
++                    if key not in sub_result:
++                        del result[key]
++
++            for key, sub_obj in six.iteritems(sub_result):
++                try:
++                    obj = result[key]
++                except KeyError:
++                    if complete:
++                        continue
++                    result[key] = sub_obj
+                 else:
+-                    obj_seq.append(obj)
+-                obj.update(ra_obj)
+-
+-        if ((not pkey_only and all) or
+-                not no_members or
+-                not has_ca_options or
+-                has_ldap_options or
+-                has_cert_option):
+-            ldap = self.api.Backend.ldap2
++                    obj.update(sub_obj)
+ 
+-            filters = []
+-            if 'certificate' in options:
+-                cert_filter = ldap.make_filter_from_attr(
+-                    'usercertificate', options['certificate'])
+-            else:
+-                cert_filter = '(usercertificate=*)'
+-            filters.append(cert_filter)
+-            for owner in self.obj._owners():
+-                oc_filter = ldap.make_filter_from_attr(
+-                    'objectclass', owner.object_class, ldap.MATCH_ALL)
+-                for prefix, rule in (('', ldap.MATCH_ALL),
+-                                     ('no_', ldap.MATCH_NONE)):
+-                    value = options.get(prefix + owner.name)
+-                    if value is None:
+-                        continue
+-                    pkey_filter = ldap.make_filter_from_attr(
+-                        owner.primary_key.name, value, rule)
+-                    filters.append(oc_filter)
+-                    filters.append(pkey_filter)
+-            filter = ldap.combine_filters(filters, ldap.MATCH_ALL)
++            truncated = truncated or sub_truncated
++            complete = complete or sub_complete
+ 
+-            try:
+-                entries, truncated = ldap.find_entries(
+-                    base_dn=self.api.env.basedn,
+-                    filter=filter,
+-                    attrs_list=['usercertificate'],
+-                    time_limit=timelimit,
+-                    size_limit=sizelimit,
+-                )
+-            except errors.EmptyResult:
+-                entries, truncated = [], False
+-            for entry in entries:
+-                seen = set()
+-                for attr in ('usercertificate', 'usercertificate;binary'):
+-                    for cert in entry.get(attr, []):
+-                        if cert in seen:
+-                            continue
+-                        seen.add(cert)
+-                        try:
+-                            obj = obj_dict[cert]
+-                        except KeyError:
+-                            if has_ca_options or has_cert_option:
+-                                continue
+-                            obj = {
+-                                'certificate': unicode(base64.b64encode(cert))}
+-                            obj_seq.append(obj)
+-                            obj_dict[cert] = obj
+-                        obj.setdefault('owner', []).append(entry.dn)
+-
+-        result = []
+-        for obj in obj_seq:
+-            if has_ldap_options and 'owner' not in obj:
+-                continue
+-            if not pkey_only:
+-                if not raw:
+-                    if 'certificate' in obj:
+-                        obj['certificate'] = (
+-                            obj['certificate'].replace('\r\n', ''))
+-                        self.obj._parse(obj)
+-                        if not all:
+-                            del obj['certificate']
+-                            del obj['valid_not_before']
+-                            del obj['valid_not_after']
+-                            del obj['md5_fingerprint']
+-                            del obj['sha1_fingerprint']
+-                    if 'subject' in obj:
+-                        obj['subject'] = DN(obj['subject'])
+-                    if 'issuer' in obj:
+-                        obj['issuer'] = DN(obj['issuer'])
+-                    if 'status' in obj:
+-                        obj['revoked'] = (
+-                            obj['status'] in (u'REVOKED', u'REVOKED_EXPIRED'))
+-                    if 'owner' in obj:
+-                        if all or not no_members:
+-                            self.obj._fill_owners(obj)
+-                        del obj['owner']
+-                else:
+-                    if 'certificate' in obj:
+-                        if not all:
+-                            del obj['certificate']
+-                    if 'owner' in obj:
+-                        if not all and no_members:
+-                            del obj['owner']
+-            else:
+-                if 'serial_number' in obj:
+-                    serial_number = obj['serial_number']
+-                    obj.clear()
+-                    obj['serial_number'] = serial_number
+-                else:
+-                    obj.clear()
+-            result.append(obj)
++        result = list(six.itervalues(result))
+ 
+         ret = dict(
+             result=result
+-- 
+2.7.4
+
diff --git a/SOURCES/0069-ipa-backup-archive-DNSSEC-zone-file-and-kasp.db.patch b/SOURCES/0069-ipa-backup-archive-DNSSEC-zone-file-and-kasp.db.patch
deleted file mode 100644
index f63f3b5..0000000
--- a/SOURCES/0069-ipa-backup-archive-DNSSEC-zone-file-and-kasp.db.patch
+++ /dev/null
@@ -1,28 +0,0 @@
-From 4d2932189ca9426492b2a69809e27c7aaca5e618 Mon Sep 17 00:00:00 2001
-From: Martin Babinsky <mbabinsk@redhat.com>
-Date: Thu, 13 Aug 2015 15:05:36 +0200
-Subject: [PATCH] ipa-backup: archive DNSSEC zone file and kasp.db
-
-https://fedorahosted.org/freeipa/ticket/5159
-
-Reviewed-By: Martin Basti <mbasti@redhat.com>
----
- ipaserver/install/ipa_backup.py | 2 ++
- 1 file changed, 2 insertions(+)
-
-diff --git a/ipaserver/install/ipa_backup.py b/ipaserver/install/ipa_backup.py
-index 1bb6f810b16c8344ab957dd6259983189a88e89f..d7afb3654b09e88321f1ce9f279749b19c2f6414 100644
---- a/ipaserver/install/ipa_backup.py
-+++ b/ipaserver/install/ipa_backup.py
-@@ -171,6 +171,8 @@ class Backup(admintool.AdminTool):
-         paths.SVC_LIST_FILE,
-         paths.OPENDNSSEC_CONF_FILE,
-         paths.OPENDNSSEC_KASP_FILE,
-+        paths.OPENDNSSEC_ZONELIST_FILE,
-+        paths.OPENDNSSEC_KASP_DB,
-         paths.DNSSEC_SOFTHSM2_CONF,
-         paths.DNSSEC_SOFTHSM_PIN_SO,
-         paths.IPA_ODS_EXPORTER_KEYTAB,
--- 
-2.4.3
-
diff --git a/SOURCES/0070-baseldap-Allow-overriding-member-param-label-in-LDAP.patch b/SOURCES/0070-baseldap-Allow-overriding-member-param-label-in-LDAP.patch
deleted file mode 100644
index 87b97f6..0000000
--- a/SOURCES/0070-baseldap-Allow-overriding-member-param-label-in-LDAP.patch
+++ /dev/null
@@ -1,40 +0,0 @@
-From 1dfdb32cbd73a3b1144645c0208fee88b3530172 Mon Sep 17 00:00:00 2001
-From: Jan Cholasta <jcholast@redhat.com>
-Date: Mon, 17 Aug 2015 09:39:21 +0200
-Subject: [PATCH] baseldap: Allow overriding member param label in
- LDAPModMember
-
-https://fedorahosted.org/freeipa/ticket/5214
-
-Reviewed-By: Petr Vobornik <pvoborni@redhat.com>
----
- ipalib/plugins/baseldap.py | 5 +++--
- 1 file changed, 3 insertions(+), 2 deletions(-)
-
-diff --git a/ipalib/plugins/baseldap.py b/ipalib/plugins/baseldap.py
-index 36a5d5f4918828a97b0b30d4613819f777722de8..31f38946afcbb51638bcab68a6e74ec309eba0e4 100644
---- a/ipalib/plugins/baseldap.py
-+++ b/ipalib/plugins/baseldap.py
-@@ -1652,6 +1652,7 @@ class LDAPModMember(LDAPQuery):
-     """
-     member_attributes = ['member']
-     member_param_doc = _('%s')
-+    member_param_label = _('member %s')
-     member_count_out = ('%i member processed.', '%i members processed.')
- 
-     def get_options(self):
-@@ -1662,9 +1663,9 @@ class LDAPModMember(LDAPQuery):
-                 ldap_obj = self.api.Object[ldap_obj_name]
-                 name = to_cli(ldap_obj_name)
-                 doc = self.member_param_doc % ldap_obj.object_name_plural
-+                label = self.member_param_label % ldap_obj.object_name
-                 yield Str('%s*' % name, cli_name='%ss' % name, doc=doc,
--                          label=_('member %s') % ldap_obj.object_name,
--                          csv=True, alwaysask=True)
-+                          label=label, csv=True, alwaysask=True)
- 
-     def get_member_dns(self, **options):
-         dns = {}
--- 
-2.4.3
-
diff --git a/SOURCES/0070-cert-do-not-crash-on-invalid-data-in-cert-find.patch b/SOURCES/0070-cert-do-not-crash-on-invalid-data-in-cert-find.patch
new file mode 100644
index 0000000..d1dba4e
--- /dev/null
+++ b/SOURCES/0070-cert-do-not-crash-on-invalid-data-in-cert-find.patch
@@ -0,0 +1,81 @@
+From adb6802b1b4dec30f19c3bf76089b6bc60ac0454 Mon Sep 17 00:00:00 2001
+From: Jan Cholasta <jcholast@redhat.com>
+Date: Mon, 1 Aug 2016 09:55:58 +0200
+Subject: [PATCH] cert: do not crash on invalid data in cert-find
+
+https://fedorahosted.org/freeipa/ticket/6150
+
+Reviewed-By: Martin Basti <mbasti@redhat.com>
+Reviewed-By: Pavel Vomacka <pvomacka@redhat.com>
+---
+ ipaserver/plugins/cert.py | 28 ++++++++++++++++++++++++----
+ 1 file changed, 24 insertions(+), 4 deletions(-)
+
+diff --git a/ipaserver/plugins/cert.py b/ipaserver/plugins/cert.py
+index 47dccf15a4010f2766642aedd2cc16e0a1eb1dd4..b8df074a186ca91daa8e8f5e725724ea7bc5a663 100644
+--- a/ipaserver/plugins/cert.py
++++ b/ipaserver/plugins/cert.py
+@@ -32,7 +32,7 @@ import six
+ 
+ from ipalib import Command, Str, Int, Flag
+ from ipalib import api
+-from ipalib import errors
++from ipalib import errors, messages
+ from ipalib import pkcs10
+ from ipalib import x509
+ from ipalib import ngettext
+@@ -994,7 +994,15 @@ class cert_find(Search, CertMethod):
+             )
+ 
+     def _get_cert_key(self, cert):
+-        nss_cert = x509.load_certificate(cert, x509.DER)
++        try:
++            nss_cert = x509.load_certificate(cert, x509.DER)
++        except NSPRError as e:
++            message = messages.SearchResultTruncated(
++                reason=_("failed to load certificate: %s") % e,
++            )
++            self.add_message(message)
++
++            raise ValueError("failed to load certificate")
+ 
+         return (DN(unicode(nss_cert.issuer)), nss_cert.serial_number)
+ 
+@@ -1017,7 +1025,10 @@ class cert_find(Search, CertMethod):
+         except KeyError:
+             return result, False, False
+ 
+-        key = self._get_cert_key(cert)
++        try:
++            key = self._get_cert_key(cert)
++        except ValueError:
++            return result, True, True
+ 
+         result[key] = self._get_cert_obj(cert, all, raw, pkey_only)
+ 
+@@ -1132,12 +1143,21 @@ class cert_find(Search, CertMethod):
+             entries = []
+             truncated = False
+         else:
++            try:
++                ldap.handle_truncated_result(truncated)
++            except errors.LimitsExceeded as e:
++                self.add_message(messages.SearchResultTruncated(reason=e))
++
+             truncated = bool(truncated)
+ 
+         for entry in entries:
+             for attr in ('usercertificate', 'usercertificate;binary'):
+                 for cert in entry.get(attr, []):
+-                    key = self._get_cert_key(cert)
++                    try:
++                        key = self._get_cert_key(cert)
++                    except ValueError:
++                        truncated = True
++                        continue
+ 
+                     try:
+                         obj = result[key]
+-- 
+2.7.4
+
diff --git a/SOURCES/0071-Add-warning-about-only-one-existing-CA-server.patch b/SOURCES/0071-Add-warning-about-only-one-existing-CA-server.patch
new file mode 100644
index 0000000..2526f30
--- /dev/null
+++ b/SOURCES/0071-Add-warning-about-only-one-existing-CA-server.patch
@@ -0,0 +1,151 @@
+From 7767a6befe2cc461cd6b8aadff1626108e3101b0 Mon Sep 17 00:00:00 2001
+From: Pavel Vomacka <pvomacka@redhat.com>
+Date: Tue, 16 Aug 2016 10:03:36 +0200
+Subject: [PATCH] Add warning about only one existing CA server
+
+It is not safe to have only one CA server in topology. Therefore there is a check
+and in case that there is only one CA server a warning is shown. The warning is
+shown after each refreshing of servers facet.
+
+https://fedorahosted.org/freeipa/ticket/5828
+
+Reviewed-By: Tomas Krizek <tkrizek@redhat.com>
+---
+ install/ui/src/freeipa/topology.js | 73 +++++++++++++++++++++++++++++++++++++-
+ install/ui/test/data/ipa_init.json |  2 ++
+ ipaserver/plugins/internal.py      |  2 ++
+ 3 files changed, 76 insertions(+), 1 deletion(-)
+
+diff --git a/install/ui/src/freeipa/topology.js b/install/ui/src/freeipa/topology.js
+index 7e501eb3506587ea653497d2806938890066e4f0..c33adba9a3c704b66b85689dd18e927ab975d2fe 100644
+--- a/install/ui/src/freeipa/topology.js
++++ b/install/ui/src/freeipa/topology.js
+@@ -28,13 +28,14 @@ define([
+         './facets/Facet',
+         './topology_graph',
+         './navigation',
++        './widget',
+         // plain imports
+         './search',
+         './entity'],
+             function(lang, declare, Evented, Stateful, Deferred, on, all, when,
+                 builder, IPA, $, menu, metadata_provider, phases, reg, rpc,
+                 text, mod_details, mod_facet, mod_field, ActionMixin,
+-                HeaderMixin, Facet, topology_graph, navigation) {
++                HeaderMixin, Facet, topology_graph, navigation, widget_mod) {
+ /**
+  * Topology module
+  * @class
+@@ -206,6 +207,7 @@ return {
+     facets: [
+            {
+             $type: 'search',
++            $factory: topology.servers_search_facet,
+             no_update: true,
+             disable_facet_tabs: false,
+             tabs_in_sidebar: true,
+@@ -483,6 +485,75 @@ topology.location_adapter = declare([mod_field.Adapter], {
+     }
+ });
+ 
++topology.servers_search_facet = function(spec, no_init) {
++    spec = spec || {};
++
++    var that = IPA.search_facet(spec);
++
++    that.create_get_records_command = function(pkeys, on_success, on_error) {
++
++        var on_success_extended = function(data, text_status, xhr) {
++            // Call original on_success handler
++            on_success(data, text_status, xhr);
++
++            var result = data.result.results;
++            var counter = 0;
++
++            for (var i=0, l=result.length; i<l; i++) {
++                var current = result[i];
++                var roles = current.result.enabled_role_servrole;
++                for (var k=0, m=roles.length; k<m; k++) {
++                    if (roles[k] === 'CA server') counter++;
++                }
++            }
++
++            // Create dialog and show it only when there is only one CA server
++            if (counter != 1) return;
++
++            var message = text.get('@i18n:objects.servers.ca_warning_message');
++            var dialog = IPA.dialog({
++                name: 'ca_warning',
++                title: '@i18n:objects.servers.ca_warning_title',
++                sections: [
++                    {
++                        show_header: false,
++                        layout:
++                        {
++                            $factory: widget_mod.fluid_layout,
++                            widget_cls: "col-sm-12 controls",
++                            label_cls: "hide"
++                        },
++                        fields: [
++                            {
++                                field: false,
++                                $type: 'html',
++                                html: message
++                            }
++                        ]
++                    }
++                ]
++            });
++
++            dialog.create_button({
++                name: 'ok',
++                label: '@i18n:buttons.ok',
++                click: function() {
++                    dialog.close();
++                }
++            });
++
++            dialog.open();
++        };
++
++        var batch = that.table_facet_create_get_records_command(pkeys,
++                                                on_success_extended, on_error);
++
++        return batch;
++    };
++
++    return that;
++};
++
+ topology.servers_facet = function(spec, no_init) {
+     spec = spec || {};
+ 
+diff --git a/install/ui/test/data/ipa_init.json b/install/ui/test/data/ipa_init.json
+index 77d6fce4e9ca0cf281d89e09f803d6a1a81c6870..efaf6b649296507c3b5b78c96d64db50e087370a 100644
+--- a/install/ui/test/data/ipa_init.json
++++ b/install/ui/test/data/ipa_init.json
+@@ -552,6 +552,8 @@
+                             "label_singular": "Server Role",
+                         },
+                         "servers": {
++                            "ca_warning_message": "It is strongly recommended to keep the CA services installed on more than one server.",
++                            "ca_warning_title": "Warning: Only One CA Server Detected",
+                             "remove_server": "Delete Server",
+                             "remove_server_msg": "Deleting a server removes it permanently from the topology. Note that this is a non-reversible action."
+                         },
+diff --git a/ipaserver/plugins/internal.py b/ipaserver/plugins/internal.py
+index ff29262180a967b2611db17271a742c5e472a19f..8af0af76c0b6305e9411d5bf4763d80df7304924 100644
+--- a/ipaserver/plugins/internal.py
++++ b/ipaserver/plugins/internal.py
+@@ -704,6 +704,8 @@ class i18n_messages(Command):
+                 "label_singular": _("Server Role"),
+             },
+             "servers": {
++                "ca_warning_message": _("It is strongly recommended to keep the CA services installed on more than one server."),
++                "ca_warning_title": _("Warning: Only One CA Server Detected"),
+                 "remove_server": _("Delete Server"),
+                 "remove_server_msg": _("Deleting a server removes it permanently from the topology. Note that this is a non-reversible action.")
+             },
+-- 
+2.7.4
+
diff --git a/SOURCES/0071-vault-Fix-param-labels-in-output-of-vault-owner-comm.patch b/SOURCES/0071-vault-Fix-param-labels-in-output-of-vault-owner-comm.patch
deleted file mode 100644
index 32eaecc..0000000
--- a/SOURCES/0071-vault-Fix-param-labels-in-output-of-vault-owner-comm.patch
+++ /dev/null
@@ -1,59 +0,0 @@
-From ddb58a9dd79558764c992a4a965c2cca404b615a Mon Sep 17 00:00:00 2001
-From: Jan Cholasta <jcholast@redhat.com>
-Date: Mon, 17 Aug 2015 09:39:48 +0200
-Subject: [PATCH] vault: Fix param labels in output of vault owner commands
-
-https://fedorahosted.org/freeipa/ticket/5214
-
-Reviewed-By: Petr Vobornik <pvoborni@redhat.com>
----
- ipalib/plugins/vault.py | 12 ++++++++++++
- 1 file changed, 12 insertions(+)
-
-diff --git a/ipalib/plugins/vault.py b/ipalib/plugins/vault.py
-index 01c6096335d47b337253d4f2d1e0571200383c7a..b5a12d5c3da599d7f5afaed90f579ad3a23c27cd 100644
---- a/ipalib/plugins/vault.py
-+++ b/ipalib/plugins/vault.py
-@@ -314,6 +314,11 @@ class vault(LDAPObject):
-             label=_('Owner services'),
-             flags=['no_create', 'no_update', 'no_search'],
-         ),
-+        Str(
-+            'owner?',
-+            label=_('Failed owners'),
-+            flags=['no_create', 'no_update', 'no_search'],
-+        ),
-     )
- 
-     def get_dn(self, *keys, **options):
-@@ -1420,6 +1425,11 @@ class VaultModMember(LDAPModMember):
-             options.pop('service', None)
-         return super(VaultModMember, self).get_member_dns(**options)
- 
-+    def post_callback(self, ldap, completed, failed, dn, entry_attrs, *keys, **options):
-+        for fail in failed.itervalues():
-+            fail['services'] = fail.pop('service', [])
-+        return completed, dn
-+
- 
- @register()
- class vault_add_owner(VaultModMember, LDAPAddMember):
-@@ -1428,6 +1438,7 @@ class vault_add_owner(VaultModMember, LDAPAddMember):
-     takes_options = LDAPAddMember.takes_options + vault_options
- 
-     member_attributes = ['owner']
-+    member_param_label = _('owner %s')
-     member_count_out = ('%i owner added.', '%i owners added.')
- 
-     has_output = (
-@@ -1452,6 +1463,7 @@ class vault_remove_owner(VaultModMember, LDAPRemoveMember):
-     takes_options = LDAPRemoveMember.takes_options + vault_options
- 
-     member_attributes = ['owner']
-+    member_param_label = _('owner %s')
-     member_count_out = ('%i owner removed.', '%i owners removed.')
- 
-     has_output = (
--- 
-2.4.3
-
diff --git a/SOURCES/0072-Fixed-vault-container-ownership.patch b/SOURCES/0072-Fixed-vault-container-ownership.patch
deleted file mode 100644
index 284f9ac..0000000
--- a/SOURCES/0072-Fixed-vault-container-ownership.patch
+++ /dev/null
@@ -1,60 +0,0 @@
-From 82738f7ef90586668761a4f1215a734ab8c25f5a Mon Sep 17 00:00:00 2001
-From: "Endi S. Dewata" <edewata@redhat.com>
-Date: Mon, 10 Aug 2015 20:57:58 +0200
-Subject: [PATCH] Fixed vault container ownership.
-
-The vault-add command has been fixed such that if the user/service
-private vault container does not exist yet it will be created and
-owned by the user/service instead of the vault creator.
-
-https://fedorahosted.org/freeipa/ticket/5194
-
-Reviewed-By: Petr Vobornik <pvoborni@redhat.com>
----
- ipalib/plugins/vault.py | 27 ++++++++++++++++++++++++---
- 1 file changed, 24 insertions(+), 3 deletions(-)
-
-diff --git a/ipalib/plugins/vault.py b/ipalib/plugins/vault.py
-index b5a12d5c3da599d7f5afaed90f579ad3a23c27cd..88c63071f04462aa240a70d3a3eeac2d04e66062 100644
---- a/ipalib/plugins/vault.py
-+++ b/ipalib/plugins/vault.py
-@@ -704,12 +704,33 @@ class vault_add_internal(LDAPCreate):
-         else:
-             owner_dn = self.api.Object.user.get_dn(name)
- 
-+        parent_dn = DN(*dn[1:])
-+
-+        container_dn = DN(self.api.Object.vault.container_dn,
-+                          self.api.env.basedn)
-+
-+        services_dn = DN(('cn', 'services'), container_dn)
-+        users_dn = DN(('cn', 'users'), container_dn)
-+
-+        if dn.endswith(services_dn):
-+            # service container should be owned by the service
-+            service = parent_dn[0]['cn']
-+            parent_owner_dn = self.api.Object.service.get_dn(service)
-+
-+        elif dn.endswith(users_dn):
-+            # user container should be owned by the user
-+            user = parent_dn[0]['cn']
-+            parent_owner_dn = self.api.Object.user.get_dn(user)
-+
-+        else:
-+            parent_owner_dn = owner_dn
-+
-         try:
--            parent_dn = DN(*dn[1:])
--            self.obj.create_container(parent_dn, owner_dn)
--        except errors.DuplicateEntry, e:
-+            self.obj.create_container(parent_dn, parent_owner_dn)
-+        except errors.DuplicateEntry as e:
-             pass
- 
-+        # vault should be owned by the creator
-         entry_attrs['owner'] = owner_dn
- 
-         return dn
--- 
-2.4.3
-
diff --git a/SOURCES/0072-Set-servers-list-as-default-facet-in-topology-facet-.patch b/SOURCES/0072-Set-servers-list-as-default-facet-in-topology-facet-.patch
new file mode 100644
index 0000000..a19800c
--- /dev/null
+++ b/SOURCES/0072-Set-servers-list-as-default-facet-in-topology-facet-.patch
@@ -0,0 +1,32 @@
+From 9f684d883f21747ba413bf456cca114e67c1e53a Mon Sep 17 00:00:00 2001
+From: Pavel Vomacka <pvomacka@redhat.com>
+Date: Tue, 16 Aug 2016 10:06:28 +0200
+Subject: [PATCH] Set servers list as default facet in topology facet group
+
+Since there is a new warning about only one CA server, the default facet
+of topology facet group is set to servers list where the warning is.
+So the warning will be shown right after clicking on Topology section.
+
+Part of: https://fedorahosted.org/freeipa/ticket/5828
+
+Reviewed-By: Tomas Krizek <tkrizek@redhat.com>
+---
+ install/ui/src/freeipa/navigation/menu_spec.js | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/install/ui/src/freeipa/navigation/menu_spec.js b/install/ui/src/freeipa/navigation/menu_spec.js
+index 108f4577f7e1326b9c9bc495c54f6e1f12a0cce6..1abd7204f9d7cc2f6e9f840eb026ea78841ce438 100644
+--- a/install/ui/src/freeipa/navigation/menu_spec.js
++++ b/install/ui/src/freeipa/navigation/menu_spec.js
+@@ -212,7 +212,7 @@ var nav = {};
+                     ]
+                 },
+                 {
+-                    entity: 'topologysuffix',
++                    entity: 'server',
+                     label: '@i18n:tabs.topology',
+                     facet: 'search',
+                     children: [
+-- 
+2.7.4
+
diff --git a/SOURCES/0073-schema-cache-Do-not-reset-ServerInfo-dirty-flag.patch b/SOURCES/0073-schema-cache-Do-not-reset-ServerInfo-dirty-flag.patch
new file mode 100644
index 0000000..e283fb8
--- /dev/null
+++ b/SOURCES/0073-schema-cache-Do-not-reset-ServerInfo-dirty-flag.patch
@@ -0,0 +1,32 @@
+From 2ee7cd65c678f310154775d69bc0d044b8ad881a Mon Sep 17 00:00:00 2001
+From: David Kupka <dkupka@redhat.com>
+Date: Thu, 4 Aug 2016 16:02:24 +0200
+Subject: [PATCH] schema cache: Do not reset ServerInfo dirty flag
+
+Once dirty flag is set to True it must not be set back to False.
+Otherwise changes are not written back to file.
+
+https://fedorahosted.org/freeipa/ticket/6048
+
+Reviewed-By: Jan Cholasta <jcholast@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 5264d4cc177ba457c517f93f203e0baca7b0ac01..b49ccbb7f7905e2561598d66beca6d8b1d5ed48e 100644
+--- a/ipaclient/remote_plugins/schema.py
++++ b/ipaclient/remote_plugins/schema.py
+@@ -401,7 +401,8 @@ class ServerInfo(collections.MutableMapping):
+         return self._dict[key]
+ 
+     def __setitem__(self, key, value):
+-        self._dirty = key not in self._dict or self._dict[key] != value
++        if key not in self._dict or self._dict[key] != value:
++            self._dirty = True
+         self._dict[key] = value
+ 
+     def __delitem__(self, key):
+-- 
+2.7.4
+
diff --git a/SOURCES/0073-vault-normalize-service-principal-in-service-vault-o.patch b/SOURCES/0073-vault-normalize-service-principal-in-service-vault-o.patch
deleted file mode 100644
index 328a3da..0000000
--- a/SOURCES/0073-vault-normalize-service-principal-in-service-vault-o.patch
+++ /dev/null
@@ -1,36 +0,0 @@
-From 9e930edf8b3b4e65bf39043e7b033f0b5537b7e3 Mon Sep 17 00:00:00 2001
-From: Petr Vobornik <pvoborni@redhat.com>
-Date: Tue, 18 Aug 2015 12:14:36 +0200
-Subject: [PATCH] vault: normalize service principal in service vault
- operations
-
-https://fedorahosted.org/freeipa/ticket/5233
-
-Reviewed-By: Jan Cholasta <jcholast@redhat.com>
----
- ipalib/plugins/vault.py | 2 ++
- 1 file changed, 2 insertions(+)
-
-diff --git a/ipalib/plugins/vault.py b/ipalib/plugins/vault.py
-index 88c63071f04462aa240a70d3a3eeac2d04e66062..a1508b63b8c8aa506eadad415ecf7fa4942c74fc 100644
---- a/ipalib/plugins/vault.py
-+++ b/ipalib/plugins/vault.py
-@@ -47,6 +47,7 @@ from ipalib.plugins.baseldap import LDAPObject, LDAPCreate, LDAPDelete,\
-     LDAPModMember, pkey_to_value
- from ipalib.request import context
- from ipalib.plugins.user import split_principal
-+from ipalib.plugins.service import normalize_principal
- from ipalib import _, ngettext
- from ipaplatform.paths import paths
- from ipapython.dn import DN
-@@ -214,6 +215,7 @@ vault_options = (
-     Str(
-         'service?',
-         doc=_('Service name of the service vault'),
-+        normalizer=normalize_principal,
-     ),
-     Flag(
-         'shared?',
--- 
-2.4.3
-
diff --git a/SOURCES/0074-schema-cache-Do-not-read-fingerprint-and-format-from.patch b/SOURCES/0074-schema-cache-Do-not-read-fingerprint-and-format-from.patch
new file mode 100644
index 0000000..e7bc841
--- /dev/null
+++ b/SOURCES/0074-schema-cache-Do-not-read-fingerprint-and-format-from.patch
@@ -0,0 +1,86 @@
+From 5138ff563b1ac870ecc77485c200d839e17622a8 Mon Sep 17 00:00:00 2001
+From: David Kupka <dkupka@redhat.com>
+Date: Thu, 4 Aug 2016 16:07:08 +0200
+Subject: [PATCH] schema cache: Do not read fingerprint and format from cache
+
+Fingerprint can be obtained from schema filename of from ServerInfo
+instance. Use FORMAT in path to avoid openening schema just to read its
+format.
+
+https://fedorahosted.org/freeipa/ticket/6048
+
+Reviewed-By: Jan Cholasta <jcholast@redhat.com>
+---
+ ipaclient/remote_plugins/schema.py | 29 +++++------------------------
+ 1 file changed, 5 insertions(+), 24 deletions(-)
+
+diff --git a/ipaclient/remote_plugins/schema.py b/ipaclient/remote_plugins/schema.py
+index b49ccbb7f7905e2561598d66beca6d8b1d5ed48e..c62b74408b448faf794ed9e2b315b03fc1a5a315 100644
+--- a/ipaclient/remote_plugins/schema.py
++++ b/ipaclient/remote_plugins/schema.py
+@@ -19,6 +19,7 @@ from ipalib import errors, parameters, plugable
+ from ipalib.frontend import Object
+ from ipalib.output import Output
+ from ipalib.parameters import DefaultFrom, Flag, Password, Str
++from ipapython.ipautil import fsdecode
+ from ipapython.dn import DN
+ from ipapython.dnsutil import DNSName
+ from ipapython.ipa_log_manager import log_mgr
+@@ -437,7 +438,7 @@ class Schema(object):
+ 
+     """
+     namespaces = {'classes', 'commands', 'topics'}
+-    _DIR = os.path.join(USER_CACHE_PATH, 'ipa', 'schema')
++    _DIR = os.path.join(USER_CACHE_PATH, 'ipa', 'schema', FORMAT)
+ 
+     def __init__(self, api, server_info, client):
+         self._dict = {}
+@@ -483,34 +484,14 @@ class Schema(object):
+         path = os.path.join(self._DIR, filename)
+         return _LockedZipFile(path, mode)
+ 
+-    def _get_schema_fingerprint(self, schema):
+-        try:
+-            fmt = json.loads(schema.read('format'))
+-        except KeyError:
+-            fmt = '0'
+-
+-        if fmt != FORMAT:
+-            raise RuntimeError('invalid format')
+-
+-        return json.loads(schema.read('fingerprint'))
+-
+     def _fetch(self, client):
+         if not client.isconnected():
+             client.connect(verbose=False)
+ 
+-        fps = []
+         try:
+-            files = os.listdir(self._DIR)
++            fps = [fsdecode(f) for f in os.listdir(self._DIR)]
+         except EnvironmentError:
+-            pass
+-        else:
+-            for filename in files:
+-                try:
+-                    with self._open_schema(filename, 'r') as schema:
+-                        fps.append(
+-                            unicode(self._get_schema_fingerprint(schema)))
+-                except Exception:
+-                    continue
++            fps = []
+ 
+         kwargs = {u'version': u'2.170'}
+         if fps:
+@@ -537,7 +518,7 @@ class Schema(object):
+ 
+     def _read_schema(self):
+         with self._open_schema(self._fingerprint, 'r') as schema:
+-            self._dict['fingerprint'] = self._get_schema_fingerprint(schema)
++            self._dict['fingerprint'] = self._fingerprint
+ 
+             for name in schema.namelist():
+                 ns, _slash, key = name.partition('/')
+-- 
+2.7.4
+
diff --git a/SOURCES/0074-vault-validate-vault-type.patch b/SOURCES/0074-vault-validate-vault-type.patch
deleted file mode 100644
index 5440f69..0000000
--- a/SOURCES/0074-vault-validate-vault-type.patch
+++ /dev/null
@@ -1,87 +0,0 @@
-From fc704bf5248ae3b224ce5066231bb826008f375d Mon Sep 17 00:00:00 2001
-From: Petr Vobornik <pvoborni@redhat.com>
-Date: Tue, 18 Aug 2015 12:50:54 +0200
-Subject: [PATCH] vault: validate vault type
-
-https://fedorahosted.org/freeipa/ticket/5211
-
-Reviewed-By: Jan Cholasta <jcholast@redhat.com>
----
- API.txt                 | 6 +++---
- VERSION                 | 4 ++--
- ipalib/plugins/vault.py | 5 +++--
- 3 files changed, 8 insertions(+), 7 deletions(-)
-
-diff --git a/API.txt b/API.txt
-index 71df3a56595a012e6382414ad4453d30ede8155b..a39b22b602e0baf5d283732d18d83b2a25d5cf50 100644
---- a/API.txt
-+++ b/API.txt
-@@ -5423,7 +5423,7 @@ option: Flag('all', autofill=True, cli_name='all', default=False, exclude='webui
- option: Str('description', attribute=True, cli_name='desc', multivalue=False, required=False)
- option: Bytes('ipavaultpublickey', attribute=True, cli_name='public_key', multivalue=False, required=False)
- option: Bytes('ipavaultsalt', attribute=True, cli_name='salt', multivalue=False, required=False)
--option: Str('ipavaulttype', attribute=True, autofill=True, cli_name='type', default=u'standard', multivalue=False, required=False)
-+option: StrEnum('ipavaulttype', attribute=True, autofill=True, cli_name='type', default=u'standard', multivalue=False, required=False, values=(u'standard', u'symmetric', u'asymmetric'))
- option: Flag('no_members', autofill=True, default=False, exclude='webui')
- option: Flag('raw', autofill=True, cli_name='raw', default=False, exclude='webui')
- option: Str('service?')
-@@ -5513,7 +5513,7 @@ arg: Str('criteria?', noextrawhitespace=False)
- option: Flag('all', autofill=True, cli_name='all', default=False, exclude='webui')
- option: Str('cn', attribute=True, autofill=False, cli_name='name', maxlength=255, multivalue=False, pattern='^[a-zA-Z0-9_.-]+$', primary_key=True, query=True, required=False)
- option: Str('description', attribute=True, autofill=False, cli_name='desc', multivalue=False, query=True, required=False)
--option: Str('ipavaulttype', attribute=True, autofill=False, cli_name='type', default=u'standard', multivalue=False, query=True, required=False)
-+option: StrEnum('ipavaulttype', attribute=True, autofill=False, cli_name='type', default=u'standard', multivalue=False, query=True, required=False, values=(u'standard', u'symmetric', u'asymmetric'))
- option: Flag('no_members', autofill=True, default=False, exclude='webui')
- option: Flag('pkey_only?', autofill=True, default=False)
- option: Flag('raw', autofill=True, cli_name='raw', default=False, exclude='webui')
-@@ -5536,7 +5536,7 @@ option: Str('delattr*', cli_name='delattr', exclude='webui')
- option: Str('description', attribute=True, autofill=False, cli_name='desc', multivalue=False, required=False)
- option: Bytes('ipavaultpublickey', attribute=True, autofill=False, cli_name='public_key', multivalue=False, required=False)
- option: Bytes('ipavaultsalt', attribute=True, autofill=False, cli_name='salt', multivalue=False, required=False)
--option: Str('ipavaulttype', attribute=True, autofill=False, cli_name='type', default=u'standard', multivalue=False, required=False)
-+option: StrEnum('ipavaulttype', attribute=True, autofill=False, cli_name='type', default=u'standard', multivalue=False, required=False, values=(u'standard', u'symmetric', u'asymmetric'))
- option: Flag('no_members', autofill=True, default=False, exclude='webui')
- option: Flag('raw', autofill=True, cli_name='raw', default=False, exclude='webui')
- option: Flag('rights', autofill=True, default=False)
-diff --git a/VERSION b/VERSION
-index 69351a8fa8e27c884c130ab49d3fab541cd09ff9..6569eeb70fa4e8065b5abb9dc89bd4cc6d42bd15 100644
---- a/VERSION
-+++ b/VERSION
-@@ -90,5 +90,5 @@ IPA_DATA_VERSION=20100614120000
- #                                                      #
- ########################################################
- IPA_API_VERSION_MAJOR=2
--IPA_API_VERSION_MINOR=149
--# Last change: edewata - Added CLI param and ACL for vault service operations
-+IPA_API_VERSION_MINOR=150
-+# Last change: pvoborni - change type of vault type option to StrEnum
-diff --git a/ipalib/plugins/vault.py b/ipalib/plugins/vault.py
-index a1508b63b8c8aa506eadad415ecf7fa4942c74fc..4d430ee88658e7ba7f2863ca4ef1e8672e298923 100644
---- a/ipalib/plugins/vault.py
-+++ b/ipalib/plugins/vault.py
-@@ -38,7 +38,7 @@ import krbV
- 
- from ipalib.frontend import Command, Object, Local
- from ipalib import api, errors
--from ipalib import Bytes, Str, Flag
-+from ipalib import Bytes, Flag, Str, StrEnum
- from ipalib import output
- from ipalib.crud import PKQuery, Retrieve, Update
- from ipalib.plugable import Registry
-@@ -279,11 +279,12 @@ class vault(LDAPObject):
-             label=_('Description'),
-             doc=_('Vault description'),
-         ),
--        Str(
-+        StrEnum(
-             'ipavaulttype?',
-             cli_name='type',
-             label=_('Type'),
-             doc=_('Vault type'),
-+            values=(u'standard', u'symmetric', u'asymmetric', ),
-             default=u'standard',
-             autofill=True,
-         ),
--- 
-2.4.3
-
diff --git a/SOURCES/0075-Access-data-for-help-separately.patch b/SOURCES/0075-Access-data-for-help-separately.patch
new file mode 100644
index 0000000..182c526
--- /dev/null
+++ b/SOURCES/0075-Access-data-for-help-separately.patch
@@ -0,0 +1,121 @@
+From e91392536994ce3167a1f025e819926ba6de299f Mon Sep 17 00:00:00 2001
+From: David Kupka <dkupka@redhat.com>
+Date: Thu, 4 Aug 2016 16:14:33 +0200
+Subject: [PATCH] Access data for help separately
+
+To avoid the need to read all data for a plugin from cache and actualy
+use the separately stored help data it must be requested and returned
+separately.
+
+https://fedorahosted.org/freeipa/ticket/6048
+
+Reviewed-By: Jan Cholasta <jcholast@redhat.com>
+---
+ ipaclient/remote_plugins/schema.py | 37 ++++++++++++++++++-------------------
+ 1 file changed, 18 insertions(+), 19 deletions(-)
+
+diff --git a/ipaclient/remote_plugins/schema.py b/ipaclient/remote_plugins/schema.py
+index c62b74408b448faf794ed9e2b315b03fc1a5a315..c72109ac3bb9b7a71f9cbc056eaf3a4d8371d035 100644
+--- a/ipaclient/remote_plugins/schema.py
++++ b/ipaclient/remote_plugins/schema.py
+@@ -114,10 +114,9 @@ class _SchemaPlugin(object):
+         if self._class is not None:
+             return self._class.summary
+         else:
+-            self._schema.load_help()
+-            schema = self._schema[self.schema_key][self.full_name]
++            halp = self._schema[self.schema_key].get_help(self.full_name)
+             try:
+-                return schema['summary']
++                return halp['summary']
+             except KeyError:
+                 return u'<%s>' % self.full_name
+ 
+@@ -244,10 +243,9 @@ class _SchemaCommandPlugin(_SchemaPlugin):
+         if self._class is not None:
+             return self._class.topic
+         else:
+-            self._schema.load_help()
+-            schema = self._schema[self.schema_key][self.full_name]
++            halp = self._schema[self.schema_key].get_help(self.full_name)
+             try:
+-                return str(schema['topic_topic']).partition('/')[0]
++                return str(halp['topic_topic']).partition('/')[0]
+             except KeyError:
+                 return None
+ 
+@@ -256,9 +254,8 @@ class _SchemaCommandPlugin(_SchemaPlugin):
+         if self._class is not None:
+             return self._class.NO_CLI
+         else:
+-            self._schema.load_help()
+-            schema = self._schema[self.schema_key][self.full_name]
+-            return 'cli' in schema.get('exclude', [])
++            halp = self._schema[self.schema_key].get_help(self.full_name)
++            return 'cli' in halp.get('exclude', [])
+ 
+     def _create_output(self, api, schema):
+         if schema.get('multivalue', False):
+@@ -355,6 +352,12 @@ class _SchemaNameSpace(collections.Mapping):
+     def __len__(self):
+         return len(list(self._schema.iter_namespace(self.name)))
+ 
++    def get_help(self, key):
++        try:
++            return self._schema.get_help(self.name, key)
++        except KeyError:
++            raise KeyError(key)
++
+ 
+ class NotAvailable(Exception):
+     pass
+@@ -523,7 +526,7 @@ class Schema(object):
+             for name in schema.namelist():
+                 ns, _slash, key = name.partition('/')
+                 if ns in self.namespaces:
+-                    self._dict[ns][key] = {}
++                    self._dict[ns][key] = None
+ 
+     def __getitem__(self, key):
+         try:
+@@ -557,7 +560,7 @@ class Schema(object):
+             os.makedirs(self._DIR)
+         except EnvironmentError as e:
+             if e.errno != errno.EEXIST:
+-                logger.warning("Failed ti write schema: {}".format(e))
++                logger.warning("Failed to write schema: {}".format(e))
+                 return
+ 
+         with self._open_schema(self._fingerprint, 'w') as schema:
+@@ -580,24 +583,20 @@ class Schema(object):
+     def read_namespace_member(self, namespace, member):
+         value = self._dict[namespace][member]
+ 
+-        if (not value) or ('full_name' not in value):
++        if value is None:
+             path = '{}/{}'.format(namespace, member)
+-            value = self._dict[namespace].setdefault(
+-                member, {}
+-            ).update(self._read(path))
++            value = self._dict[namespace][member] = self._read(path)
+ 
+         return value
+ 
+     def iter_namespace(self, namespace):
+         return iter(self._dict[namespace])
+ 
+-    def load_help(self):
++    def get_help(self, namespace, member):
+         if not self._help:
+             self._help = self._read('_help')
+ 
+-            for ns in self._help:
+-                for member in self._help[ns]:
+-                    self._dict[ns][member].update(self._help[ns][member])
++        return self._help[namespace][member]
+ 
+ 
+ def get_package(api, client):
+-- 
+2.7.4
+
diff --git a/SOURCES/0075-install-Fix-replica-install-with-custom-certificates.patch b/SOURCES/0075-install-Fix-replica-install-with-custom-certificates.patch
deleted file mode 100644
index 6753e81..0000000
--- a/SOURCES/0075-install-Fix-replica-install-with-custom-certificates.patch
+++ /dev/null
@@ -1,43 +0,0 @@
-From c2a1e876492bc630d3d5f74a2482cf9c94be763d Mon Sep 17 00:00:00 2001
-From: Jan Cholasta <jcholast@redhat.com>
-Date: Tue, 18 Aug 2015 12:51:26 +0200
-Subject: [PATCH] install: Fix replica install with custom certificates
-
-https://fedorahosted.org/freeipa/ticket/5226
-
-Reviewed-By: Martin Babinsky <mbabinsk@redhat.com>
----
- ipaserver/install/server/replicainstall.py | 17 +++++++++--------
- 1 file changed, 9 insertions(+), 8 deletions(-)
-
-diff --git a/ipaserver/install/server/replicainstall.py b/ipaserver/install/server/replicainstall.py
-index dd8bc0d4bb7d8d9835a3e3e4dc24d1f67199d28f..0725c7763e505ca0cc5a8892414a3c36c557cf1d 100644
---- a/ipaserver/install/server/replicainstall.py
-+++ b/ipaserver/install/server/replicainstall.py
-@@ -573,14 +573,15 @@ def install(installer):
-     otpd.create_instance('OTPD', config.host_name, config.dirman_password,
-                          ipautil.realm_to_suffix(config.realm_name))
- 
--    CA = cainstance.CAInstance(
--        config.realm_name, certs.NSS_DIR,
--        dogtag_constants=dogtag_constants)
--    CA.dm_password = config.dirman_password
--
--    CA.configure_certmonger_renewal()
--    CA.import_ra_cert(config.dir + "/ra.p12")
--    CA.fix_ra_perms()
-+    if ipautil.file_exists(config.dir + "/cacert.p12"):
-+        CA = cainstance.CAInstance(
-+            config.realm_name, certs.NSS_DIR,
-+            dogtag_constants=dogtag_constants)
-+        CA.dm_password = config.dirman_password
-+
-+        CA.configure_certmonger_renewal()
-+        CA.import_ra_cert(config.dir + "/ra.p12")
-+        CA.fix_ra_perms()
- 
-     # The DS instance is created before the keytab, add the SSL cert we
-     # generated
--- 
-2.4.3
-
diff --git a/SOURCES/0076-frontent-Add-summary-class-property-to-CommandOverri.patch b/SOURCES/0076-frontent-Add-summary-class-property-to-CommandOverri.patch
new file mode 100644
index 0000000..ab0ece5
--- /dev/null
+++ b/SOURCES/0076-frontent-Add-summary-class-property-to-CommandOverri.patch
@@ -0,0 +1,34 @@
+From 5b427134d613a49bcbd2fe89e7cac938d664b9e7 Mon Sep 17 00:00:00 2001
+From: David Kupka <dkupka@redhat.com>
+Date: Tue, 9 Aug 2016 17:03:25 +0200
+Subject: [PATCH] frontent: Add summary class property to CommandOverride
+
+Avoid creating instance of overriden command to get its summary.
+
+https://fedorahosted.org/freeipa/ticket/6048
+
+Reviewed-By: Jan Cholasta <jcholast@redhat.com>
+---
+ ipaclient/frontend.py | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/ipaclient/frontend.py b/ipaclient/frontend.py
+index aeaed550771d3c6af04a9b34fcae414faacb47d7..587e31c89b3935984e799f7d4c500c652bcb5d43 100644
+--- a/ipaclient/frontend.py
++++ b/ipaclient/frontend.py
+@@ -127,6 +127,12 @@ class CommandOverride(Command):
+     doc = classproperty(__doc_getter)
+ 
+     @classmethod
++    def __summary_getter(cls):
++        return cls.__get_next().summary
++
++    summary = classproperty(__summary_getter)
++
++    @classmethod
+     def __NO_CLI_getter(cls):
+         return cls.__get_next().NO_CLI
+ 
+-- 
+2.7.4
+
diff --git a/SOURCES/0076-trusts-harden-trust-fetch-domains-oddjobd-based-scri.patch b/SOURCES/0076-trusts-harden-trust-fetch-domains-oddjobd-based-scri.patch
deleted file mode 100644
index afdc77b..0000000
--- a/SOURCES/0076-trusts-harden-trust-fetch-domains-oddjobd-based-scri.patch
+++ /dev/null
@@ -1,135 +0,0 @@
-From 2c577bc650613f5adfcc1efed0bfa40187eb362e Mon Sep 17 00:00:00 2001
-From: Alexander Bokovoy <abokovoy@redhat.com>
-Date: Thu, 13 Aug 2015 17:18:57 +0300
-Subject: [PATCH] trusts: harden trust-fetch-domains oddjobd-based script
-
-When ipa-getkeytab is used to fetch trusted domain object credentials,
-the fetched entry has always kvno 1. ipa-getkeytab always adds a key to
-keytab which means older key versions will be in the SSSD keytab and
-will confuse libkrb5 ccache initialization code as all kvno values are
-equal to 1. Wrong key is picked up then and kinit fails.
-
-To solve this problem, always remove existing
-/var/lib/sss/keytabs/forest.keytab before retrieving a new one.
-
-To make sure script's input cannot be used to define what should be
-removed (by passing a relative path), make sure we retrieve trusted
-forest name from LDAP. If it is not possible to retrieve, the script
-will issue an exception and quit. If abrtd is running, this will be
-recorded as a 'crash' and an attempt to use script by malicious user
-would be recorded as well in the abrtd journal.
-
-Additionally, as com.redhat.idm.trust-fetch-domains will create
-ID ranges for the domains of the trusted forest if they don't exist,
-it needs permissions to do so. The permission should be granted only
-to cifs/ipa.master@IPA.REALM services which means they must have
-krbprincipalname=cifs/*@IPA.REALM,cn=services,... DN and be members of
-cn=adtrust agents,cn=sysaccounts,... group.
-
-Solves https://bugzilla.redhat.com/show_bug.cgi?id=1250190
-
-Ticket https://fedorahosted.org/freeipa/ticket/5182
-
-Reviewed-By: Tomas Babej <tbabej@redhat.com>
----
- install/oddjob/com.redhat.idm.trust-fetch-domains | 29 +++++++++++++++++++----
- install/updates/20-aci.update                     |  4 ++++
- 2 files changed, 28 insertions(+), 5 deletions(-)
-
-diff --git a/install/oddjob/com.redhat.idm.trust-fetch-domains b/install/oddjob/com.redhat.idm.trust-fetch-domains
-index e50c81e50e73b258bf08737c2d9a13a8832eb69f..6a2171d5f1936fabd00081bbbcea562a0e7041b8 100755
---- a/install/oddjob/com.redhat.idm.trust-fetch-domains
-+++ b/install/oddjob/com.redhat.idm.trust-fetch-domains
-@@ -41,6 +41,9 @@ def retrieve_keytab(api, ccache_name, oneway_keytab_name, oneway_principal):
-                       "-p", oneway_principal,
-                       "-k", oneway_keytab_name,
-                       "-r"]
-+    if os.path.isfile(oneway_keytab_name):
-+        os.unlink(oneway_keytab_name)
-+
-     (stdout, stderr, retcode) = ipautil.run(getkeytab_args,
-                                             env={'KRB5CCNAME': ccache_name, 'LANG': 'C'},
-                                             raiseonerr=False)
-@@ -111,7 +114,6 @@ from ipalib.plugins import trust
- # retrieve the keys to oneway_keytab_name.
- 
- keytab_name = '/etc/samba/samba.keytab'
--oneway_keytab_name = '/var/lib/sss/keytabs/' + trusted_domain + '.keytab'
- 
- principal = str('cifs/' + api.env.host)
- 
-@@ -137,10 +139,20 @@ else:
- old_ccache = os.environ.get('KRB5CCNAME')
- api.Backend.ldap2.connect(ccache)
- 
-+# Retrieve own NetBIOS name and trusted forest's name.
-+# We use script's input to retrieve the trusted forest's name to sanitize input
-+# for file-level access as we might need to wipe out keytab in /var/lib/sss/keytabs
- own_trust_dn = DN(('cn', api.env.domain),('cn','ad'), ('cn', 'etc'), api.env.basedn)
- own_trust_entry = api.Backend.ldap2.get_entry(own_trust_dn, ['ipantflatname'])
--own_trust_flatname = own_trust_entry['ipantflatname'][0].upper()
-+own_trust_flatname = own_trust_entry.single_value.get('ipantflatname').upper()
-+trusted_domain_dn = DN(('cn', trusted_domain.lower()), api.env.container_adtrusts, api.env.basedn)
-+trusted_domain_entry = api.Backend.ldap2.get_entry(trusted_domain_dn, ['cn'])
-+trusted_domain = trusted_domain_entry.single_value.get('cn').lower()
- 
-+# At this point if we didn't find trusted forest name, an exception will be raised
-+# and script will quit. This is actually intended.
-+
-+oneway_keytab_name = '/var/lib/sss/keytabs/' + trusted_domain + '.keytab'
- oneway_principal = str('%s$@%s' % (own_trust_flatname, trusted_domain.upper()))
- 
- # If keytab does not exist, retrieve it
-@@ -152,11 +164,18 @@ try:
-     # The keytab may have stale key material (from older trust-add run)
-     if not os.path.isfile(oneway_ccache_name):
-         oneway_ccache = kinit_keytab(oneway_principal, oneway_keytab_name, oneway_ccache_name)
-+    else:
-+        oneway_ccache_check = KRB5_CCache(oneway_ccache_name)
-+        if not oneway_ccache_check.credential_is_valid(oneway_principal):
-+            # If credentials were invalid, obtain them again
-+            oneway_ccache = kinit_keytab(oneway_principal, oneway_keytab_name, oneway_ccache_name)
-+        else:
-+            oneway_ccache = oneway_ccache_check.ccache
- except krbV.Krb5Error as e:
-     # If there was failure on using keytab, assume it is stale and retrieve again
-     retrieve_keytab(api, ccache_name, oneway_keytab_name, oneway_principal)
- 
--if oneway_ccache:
-+try:
-     # There wasn existing ccache, validate its content
-     oneway_ccache_check = KRB5_CCache(oneway_ccache_name)
-     if not oneway_ccache_check.credential_is_valid(oneway_principal):
-@@ -164,7 +183,7 @@ if oneway_ccache:
-         oneway_ccache = kinit_keytab(oneway_principal, oneway_keytab_name, oneway_ccache_name)
-     else:
-         oneway_ccache = oneway_ccache_check.ccache
--else:
-+except krbV.Krb5Error as e:
-     oneway_ccache = kinit_keytab(oneway_principal, oneway_keytab_name, oneway_ccache_name)
- 
- # We are done: we have ccache with TDO credentials and can fetch domains
-@@ -193,7 +212,7 @@ if domains:
-                 dom['range_type'] = u'ipa-ad-trust'
-                 # Do not pass ipaserver.dcerpc.TrustInstance to trust.add_range
-                 # to force it using existing credentials cache
--                trust.add_range(None, range_name, dom['ipanttrusteddomainsid'],
-+                trust.add_range(api, None, range_name, dom['ipanttrusteddomainsid'],
-                                 trusted_domain, name, **dom)
-         except errors.DuplicateEntry:
-             # Ignore updating duplicate entries
-diff --git a/install/updates/20-aci.update b/install/updates/20-aci.update
-index 0bdeeb6acefad4f79385a1ddaec95df2e40377fb..cba1897e1fd1136fbcbd7c6ccaf03bfa4b696a44 100644
---- a/install/updates/20-aci.update
-+++ b/install/updates/20-aci.update
-@@ -87,3 +87,7 @@ add:aci:(targetattr = "usercertificate")(version 3.0;acl "selfservice:Users can
- # Hosts can add their own services
- dn: cn=services,cn=accounts,$SUFFIX
- add:aci: (target = "ldap:///krbprincipalname=*/($$dn)@$REALM,cn=services,cn=accounts,$SUFFIX")(targetfilter = "(objectClass=ipaKrbPrincipal)")(version 3.0;acl "Hosts can add own services"; allow(add) userdn="ldap:///fqdn=($$dn),cn=computers,cn=accounts,$SUFFIX";)
-+
-+# CIFS service on the master can manage ID ranges
-+dn: cn=ranges,cn=etc,$SUFFIX
-+add:aci: (target = "ldap:///cn=*,cn=ranges,cn=etc,$SUFFIX")(targetfilter = "(objectClass=ipaIDrange)")(version 3.0;acl "CIFS service can manage ID ranges for trust"; allow(all) userdn="ldap:///krbprincipalname=cifs/*@$REALM,cn=services,cn=accounts,$SUFFIX" and groupdn="ldap:///cn=adtrust agents,cn=sysaccounts,cn=etc,$SUFFIX";)
--- 
-2.4.3
-
diff --git a/SOURCES/0077-schema-cache-Read-server-info-only-once.patch b/SOURCES/0077-schema-cache-Read-server-info-only-once.patch
new file mode 100644
index 0000000..5ed5ee1
--- /dev/null
+++ b/SOURCES/0077-schema-cache-Read-server-info-only-once.patch
@@ -0,0 +1,50 @@
+From 6959578fdbdfd38113b26cd9e4f94b298343a6f0 Mon Sep 17 00:00:00 2001
+From: David Kupka <dkupka@redhat.com>
+Date: Tue, 9 Aug 2016 17:05:17 +0200
+Subject: [PATCH] schema cache: Read server info only once
+
+Do not open/close the file with every access to plugins. Extensive
+access to filesystem may cause significant slowdown.
+
+https://fedorahosted.org/freeipa/ticket/6048
+
+Reviewed-By: Jan Cholasta <jcholast@redhat.com>
+---
+ ipaclient/remote_plugins/schema.py | 12 +++++++++++-
+ 1 file changed, 11 insertions(+), 1 deletion(-)
+
+diff --git a/ipaclient/remote_plugins/schema.py b/ipaclient/remote_plugins/schema.py
+index c72109ac3bb9b7a71f9cbc056eaf3a4d8371d035..aadc891750782b0961bc46989e3693d1d3ed0ecb 100644
+--- a/ipaclient/remote_plugins/schema.py
++++ b/ipaclient/remote_plugins/schema.py
+@@ -378,6 +378,9 @@ class ServerInfo(collections.MutableMapping):
+         return self
+ 
+     def __exit__(self, *_exc_info):
++        self.flush()
++
++    def flush(self):
+         if self._dirty:
+             self._write()
+ 
+@@ -603,9 +606,16 @@ def get_package(api, client):
+     try:
+         schema = api._schema
+     except AttributeError:
+-        with ServerInfo(api.env.hostname) as server_info:
++        try:
++            server_info = api._server_info
++        except AttributeError:
++            server_info = api._server_info = ServerInfo(api)
++
++        try:
+             schema = Schema(api, server_info, client)
+             object.__setattr__(api, '_schema', schema)
++        finally:
++            server_info.flush()
+ 
+     fingerprint = str(schema['fingerprint'])
+     package_name = '{}${}'.format(__name__, fingerprint)
+-- 
+2.7.4
+
diff --git a/SOURCES/0077-user-undel-Fix-error-messages.patch b/SOURCES/0077-user-undel-Fix-error-messages.patch
deleted file mode 100644
index fb41e39..0000000
--- a/SOURCES/0077-user-undel-Fix-error-messages.patch
+++ /dev/null
@@ -1,41 +0,0 @@
-From f021f35447a0b71957b2294b1000f9229ea064f6 Mon Sep 17 00:00:00 2001
-From: David Kupka <dkupka@redhat.com>
-Date: Thu, 13 Aug 2015 08:11:38 +0200
-Subject: [PATCH] user-undel: Fix error messages.
-
-https://fedorahosted.org/freeipa/ticket/5207
-
-Reviewed-By: Martin Basti <mbasti@redhat.com>
----
- ipalib/plugins/user.py | 12 +++++-------
- 1 file changed, 5 insertions(+), 7 deletions(-)
-
-diff --git a/ipalib/plugins/user.py b/ipalib/plugins/user.py
-index 90ae7260abf935abf92b49da04c11bc76e836e49..418c51bdafc4e462e2decfe1e8541aaf49705cb0 100644
---- a/ipalib/plugins/user.py
-+++ b/ipalib/plugins/user.py
-@@ -827,16 +827,14 @@ class user_undel(LDAPQuery):
- 
-         # First check that the user exists and is a delete one
-         delete_dn = self.obj.get_either_dn(*keys, **options)
--        if delete_dn.endswith(DN(self.obj.active_container_dn, api.env.basedn)):
--            raise errors.ValidationError(
--                        name=self.obj.primary_key.cli_name,
--                        error=_('User %r is already active') % keys[-1][0])
-         try:
-             entry_attrs = self._exc_wrapper(keys, options, ldap.get_entry)(delete_dn)
-         except errors.NotFound:
--            raise errors.ValidationError(
--                        name=self.obj.primary_key.cli_name,
--                        error=_('User %r not found') % keys[-1][0])
-+            self.obj.handle_not_found(*keys)
-+        if delete_dn.endswith(DN(self.obj.active_container_dn,
-+                                 api.env.basedn)):
-+            raise errors.InvocationError(
-+                message=_('user "%s" is already active') % keys[-1])
- 
-         active_dn = DN(delete_dn[0], self.obj.active_container_dn, api.env.basedn)
- 
--- 
-2.4.3
-
diff --git a/SOURCES/0078-Prohibit-deletion-of-predefined-profiles.patch b/SOURCES/0078-Prohibit-deletion-of-predefined-profiles.patch
deleted file mode 100644
index 5f1c49e..0000000
--- a/SOURCES/0078-Prohibit-deletion-of-predefined-profiles.patch
+++ /dev/null
@@ -1,87 +0,0 @@
-From ba321efe715dbbb3b4be22cb786995cf441e1a74 Mon Sep 17 00:00:00 2001
-From: Fraser Tweedale <ftweedal@redhat.com>
-Date: Thu, 13 Aug 2015 02:32:54 -0400
-Subject: [PATCH] Prohibit deletion of predefined profiles
-
-Deletion of predefined profiles, including the default profile,
-should not be allowed.  Detect this case and raise an error.
-
-Also update the predefined profiles collection to use namedtuple,
-making it easier to access the various components.
-
-Fixes: https://fedorahosted.org/freeipa/ticket/5198
-Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
----
- ipalib/plugins/certprofile.py | 13 +++++++++++--
- ipapython/dogtag.py           |  8 +++++---
- 2 files changed, 16 insertions(+), 5 deletions(-)
-
-diff --git a/ipalib/plugins/certprofile.py b/ipalib/plugins/certprofile.py
-index 1dd4f403ee4461b83c053eb36019a8896506bb81..007cc543406b7e5705fd7474f3685cd6a9ce6aca 100644
---- a/ipalib/plugins/certprofile.py
-+++ b/ipalib/plugins/certprofile.py
-@@ -3,6 +3,7 @@
- #
- 
- import re
-+from operator import attrgetter
- 
- from ipalib import api, Bool, File, Str
- from ipalib import output, util
-@@ -14,6 +15,7 @@ from ipalib.plugins.baseldap import (
- from ipalib.request import context
- from ipalib import ngettext
- from ipalib.text import _
-+from ipapython.dogtag import INCLUDED_PROFILES
- from ipapython.version import API_VERSION
- 
- from ipalib import errors
-@@ -287,9 +289,16 @@ class certprofile_del(LDAPDelete):
-     __doc__ = _("Delete a Certificate Profile.")
-     msg_summary = _('Deleted profile "%(value)s"')
- 
--    def execute(self, *args, **kwargs):
-+    def pre_callback(self, ldap, dn, *keys, **options):
-         ca_enabled_check()
--        return super(certprofile_del, self).execute(*args, **kwargs)
-+
-+        if keys[0] in map(attrgetter('profile_id'), INCLUDED_PROFILES):
-+            raise errors.ValidationError(name='profile_id',
-+                error=_("Predefined profile '%(profile_id)s' cannot be deleted")
-+                    % {'profile_id': keys[0]}
-+            )
-+
-+        return dn
- 
-     def post_callback(self, ldap, dn, *keys, **options):
-         with self.api.Backend.ra_certprofile as profile_api:
-diff --git a/ipapython/dogtag.py b/ipapython/dogtag.py
-index 0782d360ccf2ce2c90c4e9cfa66b5159e437e77c..3f0d08154d21a3072e344c311c3e70e414d9dee4 100644
---- a/ipapython/dogtag.py
-+++ b/ipapython/dogtag.py
-@@ -17,6 +17,7 @@
- # along with this program.  If not, see <http://www.gnu.org/licenses/>.
- #
- 
-+import collections
- import os
- import httplib
- import xml.dom.minidom
-@@ -42,10 +43,11 @@ from ipapython.ipa_log_manager import *
- # the configured version.
- 
- 
-+Profile = collections.namedtuple('Profile', ['profile_id', 'description', 'store_issued'])
-+
- INCLUDED_PROFILES = {
--    # ( profile_id    ,         description      ,      store_issued)
--    (u'caIPAserviceCert', u'Standard profile for network services', True),
--    (u'IECUserRoles', u'User profile that includes IECUserRoles extension from request', True),
-+    Profile(u'caIPAserviceCert', u'Standard profile for network services', True),
-+    Profile(u'IECUserRoles', u'User profile that includes IECUserRoles extension from request', True),
-     }
- 
- DEFAULT_PROFILE = u'caIPAserviceCert'
--- 
-2.4.3
-
diff --git a/SOURCES/0078-schema-cache-Store-API-schema-cache-in-memory.patch b/SOURCES/0078-schema-cache-Store-API-schema-cache-in-memory.patch
new file mode 100644
index 0000000..eb9dfd3
--- /dev/null
+++ b/SOURCES/0078-schema-cache-Store-API-schema-cache-in-memory.patch
@@ -0,0 +1,125 @@
+From 1aa300c53f070436888150ae582dad23cddac03b Mon Sep 17 00:00:00 2001
+From: David Kupka <dkupka@redhat.com>
+Date: Mon, 15 Aug 2016 08:01:59 +0200
+Subject: [PATCH] schema cache: Store API schema cache in memory
+
+Read whole cache into memory and keep it there for lifetime of api
+object. This removes the need to repetitively open/close the cache and
+speeds up every access to it.
+
+https://fedorahosted.org/freeipa/ticket/6048
+
+Reviewed-By: Jan Cholasta <jcholast@redhat.com>
+---
+ ipaclient/remote_plugins/schema.py | 51 +++++++++++++++++++++-----------------
+ 1 file changed, 28 insertions(+), 23 deletions(-)
+
+diff --git a/ipaclient/remote_plugins/schema.py b/ipaclient/remote_plugins/schema.py
+index aadc891750782b0961bc46989e3693d1d3ed0ecb..2fc6cce3eca392447cd4230216900116002934f4 100644
+--- a/ipaclient/remote_plugins/schema.py
++++ b/ipaclient/remote_plugins/schema.py
+@@ -3,6 +3,7 @@
+ #
+ 
+ import collections
++import contextlib
+ import errno
+ import fcntl
+ import json
+@@ -315,24 +316,6 @@ class _SchemaObjectPlugin(_SchemaPlugin):
+     schema_key = 'classes'
+ 
+ 
+-class _LockedZipFile(zipfile.ZipFile):
+-    """ Add locking to zipfile.ZipFile
+-    Shared lock is used with read mode, exclusive with write mode.
+-    """
+-    def __enter__(self):
+-        if 'r' in self.mode:
+-            fcntl.flock(self.fp, fcntl.LOCK_SH)
+-        elif 'w' in self.mode or 'a' in self.mode:
+-            fcntl.flock(self.fp, fcntl.LOCK_EX)
+-
+-        return super(_LockedZipFile, self).__enter__()
+-
+-    def __exit__(self, type_, value, traceback):
+-        fcntl.flock(self.fp, fcntl.LOCK_UN)
+-
+-        return super(_LockedZipFile, self).__exit__(type_, value, traceback)
+-
+-
+ class _SchemaNameSpace(collections.Mapping):
+ 
+     def __init__(self, schema, name):
+@@ -450,6 +433,7 @@ class Schema(object):
+         self._dict = {}
+         self._namespaces = {}
+         self._help = None
++        self._file = six.StringIO()
+ 
+         for ns in self.namespaces:
+             self._dict[ns] = {}
+@@ -486,9 +470,20 @@ class Schema(object):
+             except AttributeError:
+                 pass
+ 
+-    def _open_schema(self, filename, mode):
++    @contextlib.contextmanager
++    def _open(self, filename, mode):
+         path = os.path.join(self._DIR, filename)
+-        return _LockedZipFile(path, mode)
++
++        with open(path, mode) as f:
++            if mode.startswith('r'):
++                fcntl.flock(f, fcntl.LOCK_SH)
++            else:
++                fcntl.flock(f, fcntl.LOCK_EX)
++
++            try:
++                yield f
++            finally:
++                fcntl.flock(f, fcntl.LOCK_UN)
+ 
+     def _fetch(self, client):
+         if not client.isconnected():
+@@ -523,7 +518,11 @@ class Schema(object):
+         self._expiration = ttl + time.time()
+ 
+     def _read_schema(self):
+-        with self._open_schema(self._fingerprint, 'r') as schema:
++        self._file.truncate(0)
++        with self._open(self._fingerprint, 'r') as f:
++            self._file.write(f.read())
++
++        with zipfile.ZipFile(self._file, 'r') as schema:
+             self._dict['fingerprint'] = self._fingerprint
+ 
+             for name in schema.namelist():
+@@ -566,7 +565,8 @@ class Schema(object):
+                 logger.warning("Failed to write schema: {}".format(e))
+                 return
+ 
+-        with self._open_schema(self._fingerprint, 'w') as schema:
++        self._file.truncate(0)
++        with zipfile.ZipFile(self._file, 'w', zipfile.ZIP_DEFLATED) as schema:
+             for key, value in self._dict.items():
+                 if key in self.namespaces:
+                     ns = value
+@@ -579,8 +579,13 @@ class Schema(object):
+             schema.writestr('_help',
+                             json.dumps(self._generate_help(self._dict)))
+ 
++        self._file.seek(0)
++        with self._open(self._fingerprint, 'w') as f:
++            f.truncate(0)
++            f.write(self._file.read())
++
+     def _read(self, path):
+-        with self._open_schema(self._fingerprint, 'r') as zf:
++        with zipfile.ZipFile(self._file, 'r') as zf:
+             return json.loads(zf.read(path))
+ 
+     def read_namespace_member(self, namespace, member):
+-- 
+2.7.4
+
diff --git a/SOURCES/0079-client-Do-not-create-instance-just-to-check-isinstan.patch b/SOURCES/0079-client-Do-not-create-instance-just-to-check-isinstan.patch
new file mode 100644
index 0000000..60707e8
--- /dev/null
+++ b/SOURCES/0079-client-Do-not-create-instance-just-to-check-isinstan.patch
@@ -0,0 +1,97 @@
+From bac0d7c286768a67715ca1ac1e835a272e540721 Mon Sep 17 00:00:00 2001
+From: David Kupka <dkupka@redhat.com>
+Date: Thu, 11 Aug 2016 14:30:00 +0200
+Subject: [PATCH] client: Do not create instance just to check isinstance
+
+Checking that classes are idenical gives the same result and
+avoids unnecessary instantiation.
+
+https://fedorahosted.org/freeipa/ticket/6048
+
+Reviewed-By: Jan Cholasta <jcholast@redhat.com>
+---
+ ipaclient/plugins/automount.py        |  4 ++--
+ ipaclient/plugins/otptoken_yubikey.py |  3 +--
+ ipaclient/plugins/vault.py            | 16 ++++++++--------
+ 3 files changed, 11 insertions(+), 12 deletions(-)
+
+diff --git a/ipaclient/plugins/automount.py b/ipaclient/plugins/automount.py
+index 925b635ff27411fc7e2f8c3dae17c747216d7fb6..3742705face49d02370e845e3d6e6599a34809eb 100644
+--- a/ipaclient/plugins/automount.py
++++ b/ipaclient/plugins/automount.py
+@@ -55,8 +55,8 @@ class _fake_automountlocation_show(Method):
+ class automountlocation_tofiles(MethodOverride):
+     @classmethod
+     def __NO_CLI_getter(cls):
+-        return isinstance(api.Command.automountlocation_show,
+-                          _fake_automountlocation_show)
++        return (api.Command.get_plugin('automountlocation_show') is
++                _fake_automountlocation_show)
+ 
+     NO_CLI = classproperty(__NO_CLI_getter)
+ 
+diff --git a/ipaclient/plugins/otptoken_yubikey.py b/ipaclient/plugins/otptoken_yubikey.py
+index 549376a0ff65d44c5698666a84608849152368b2..1075b6d839c785b44f035050ed5c9773c66d57b7 100644
+--- a/ipaclient/plugins/otptoken_yubikey.py
++++ b/ipaclient/plugins/otptoken_yubikey.py
+@@ -77,8 +77,7 @@ class otptoken_add_yubikey(Command):
+ 
+     @classmethod
+     def __NO_CLI_getter(cls):
+-        return isinstance(api.Command.otptoken_add,
+-                          _fake_otptoken_add)
++        return api.Command.get_plugin('otptoken_add') is _fake_otptoken_add
+ 
+     NO_CLI = classproperty(__NO_CLI_getter)
+ 
+diff --git a/ipaclient/plugins/vault.py b/ipaclient/plugins/vault.py
+index c0ded21d515fe41bde5fb0e547087cb7789aa6a3..08bbeb50f3bdc756321df9e45496e5388edd92c5 100644
+--- a/ipaclient/plugins/vault.py
++++ b/ipaclient/plugins/vault.py
+@@ -205,8 +205,8 @@ class vault_add(Local):
+ 
+     @classmethod
+     def __NO_CLI_getter(cls):
+-        return isinstance(api.Command.vault_add_internal,
+-                          _fake_vault_add_internal)
++        return (api.Command.get_plugin('vault_add_internal') is
++                _fake_vault_add_internal)
+ 
+     NO_CLI = classproperty(__NO_CLI_getter)
+ 
+@@ -411,8 +411,8 @@ class vault_mod(Local):
+ 
+     @classmethod
+     def __NO_CLI_getter(cls):
+-        return isinstance(api.Command.vault_mod_internal,
+-                          _fake_vault_mod_internal)
++        return (api.Command.get_plugin('vault_mod_internal') is
++                _fake_vault_mod_internal)
+ 
+     NO_CLI = classproperty(__NO_CLI_getter)
+ 
+@@ -598,8 +598,8 @@ class vault_archive(Local):
+ 
+     @classmethod
+     def __NO_CLI_getter(cls):
+-        return isinstance(api.Command.vault_archive_internal,
+-                          _fake_vault_archive_internal)
++        return (api.Command.get_plugin('vault_archive_internal') is
++                _fake_vault_archive_internal)
+ 
+     NO_CLI = classproperty(__NO_CLI_getter)
+ 
+@@ -855,8 +855,8 @@ class vault_retrieve(Local):
+ 
+     @classmethod
+     def __NO_CLI_getter(cls):
+-        return isinstance(api.Command.vault_retrieve_internal,
+-                          _fake_vault_retrieve_internal)
++        return (api.Command.get_plugin('vault_retrieve_internal') is
++                _fake_vault_retrieve_internal)
+ 
+     NO_CLI = classproperty(__NO_CLI_getter)
+ 
+-- 
+2.7.4
+
diff --git a/SOURCES/0079-improve-the-handling-of-krb5-related-errors-in-dnsse.patch b/SOURCES/0079-improve-the-handling-of-krb5-related-errors-in-dnsse.patch
deleted file mode 100644
index 6faaa63..0000000
--- a/SOURCES/0079-improve-the-handling-of-krb5-related-errors-in-dnsse.patch
+++ /dev/null
@@ -1,92 +0,0 @@
-From 61d06ac1701a6a3a4afe75bcff64f271991a82ec Mon Sep 17 00:00:00 2001
-From: Martin Babinsky <mbabinsk@redhat.com>
-Date: Tue, 18 Aug 2015 18:33:37 +0200
-Subject: [PATCH] improve the handling of krb5-related errors in dnssec daemons
-
-ipa-dnskeysync* and ipa-ods-exporter handle kerberos errors more gracefully
-instead of crashing with tracebacks.
-
-https://fedorahosted.org/freeipa/ticket/5229
-
-Reviewed-By: Martin Basti <mbasti@redhat.com>
----
- daemons/dnssec/ipa-dnskeysync-replica | 10 +++++++++-
- daemons/dnssec/ipa-dnskeysyncd        |  4 ++--
- daemons/dnssec/ipa-ods-exporter       | 10 +++++++++-
- 3 files changed, 20 insertions(+), 4 deletions(-)
-
-diff --git a/daemons/dnssec/ipa-dnskeysync-replica b/daemons/dnssec/ipa-dnskeysync-replica
-index 551c2f21d5b85b76a7281f719ce722a6c5830cf7..b80b38962957f922cc871ead471f8da0831bec4d 100755
---- a/daemons/dnssec/ipa-dnskeysync-replica
-+++ b/daemons/dnssec/ipa-dnskeysync-replica
-@@ -12,6 +12,7 @@ from binascii import hexlify
- from datetime import datetime
- import dns.dnssec
- import fcntl
-+from krbV import Krb5Error
- import logging
- import os
- from pprint import pprint
-@@ -141,7 +142,14 @@ log.setLevel(level=logging.DEBUG)
- PRINCIPAL = str('%s/%s' % (DAEMONNAME, ipalib.api.env.host))
- log.debug('Kerberos principal: %s', PRINCIPAL)
- ccache_filename = os.path.join(WORKDIR, 'ipa-dnskeysync-replica.ccache')
--ipautil.kinit_keytab(PRINCIPAL, paths.IPA_DNSKEYSYNCD_KEYTAB, ccache_filename)
-+
-+try:
-+    ipautil.kinit_keytab(PRINCIPAL, paths.IPA_DNSKEYSYNCD_KEYTAB,
-+                         ccache_filename, attempts=5)
-+except Krb5Error as e:
-+    log.critical('Kerberos authentication failed: %s', e)
-+    sys.exit(1)
-+
- os.environ['KRB5CCNAME'] = ccache_filename
- log.debug('Got TGT')
- 
-diff --git a/daemons/dnssec/ipa-dnskeysyncd b/daemons/dnssec/ipa-dnskeysyncd
-index a0fcf8b4b2f27627f3ebcb089e212eefda2adbd3..660e34b45084dd5a31967e9493f488632ec00932 100755
---- a/daemons/dnssec/ipa-dnskeysyncd
-+++ b/daemons/dnssec/ipa-dnskeysyncd
-@@ -66,9 +66,9 @@ PRINCIPAL = str('%s/%s' % (DAEMONNAME, api.env.host))
- log.debug('Kerberos principal: %s', PRINCIPAL)
- ccache_filename = os.path.join(WORKDIR, 'ipa-dnskeysyncd.ccache')
- try:
--    ipautil.kinit_keytab(PRINCIPAL, KEYTAB_FB, ccache_filename)
-+    ipautil.kinit_keytab(PRINCIPAL, KEYTAB_FB, ccache_filename, attempts=5)
- except Exception as ex:
--    log.critical(ex)
-+    log.critical("Kerberos authentication failed: %s", ex)
-     # signal failure and let init system to restart the daemon
-     sys.exit(1)
- os.environ['KRB5CCNAME'] = ccache_filename
-diff --git a/daemons/dnssec/ipa-ods-exporter b/daemons/dnssec/ipa-ods-exporter
-index 4c6649c2fbfe77e563ab70276a92b59201fcbace..4d5423797fc9d4bdd0a432bac96b8209bb98c6d8 100755
---- a/daemons/dnssec/ipa-ods-exporter
-+++ b/daemons/dnssec/ipa-ods-exporter
-@@ -20,6 +20,7 @@ from datetime import datetime
- import dateutil.tz
- import dns.dnssec
- import fcntl
-+from krbV import Krb5Error
- import logging
- import os
- import subprocess
-@@ -482,7 +483,14 @@ ipalib.api.finalize()
- PRINCIPAL = str('%s/%s' % (DAEMONNAME, ipalib.api.env.host))
- log.debug('Kerberos principal: %s', PRINCIPAL)
- ccache_name = os.path.join(WORKDIR, 'ipa-ods-exporter.ccache')
--ipautil.kinit_keytab(PRINCIPAL, paths.IPA_ODS_EXPORTER_KEYTAB, ccache_name)
-+
-+try:
-+    ipautil.kinit_keytab(PRINCIPAL, paths.IPA_ODS_EXPORTER_KEYTAB, ccache_name,
-+                         attempts=5)
-+except Krb5Error as e:
-+    log.critical('Kerberos authentication failed: %s', e)
-+    sys.exit(1)
-+
- os.environ['KRB5CCNAME'] = ccache_name
- log.debug('Got TGT')
- 
--- 
-2.4.3
-
diff --git a/SOURCES/0080-client-Add-support-for-multiple-IP-addresses-during-.patch b/SOURCES/0080-client-Add-support-for-multiple-IP-addresses-during-.patch
deleted file mode 100644
index 2212e58..0000000
--- a/SOURCES/0080-client-Add-support-for-multiple-IP-addresses-during-.patch
+++ /dev/null
@@ -1,398 +0,0 @@
-From 12cafe49be52deca889c6a909f6451a464085b06 Mon Sep 17 00:00:00 2001
-From: David Kupka <dkupka@redhat.com>
-Date: Sun, 4 Jan 2015 15:04:18 -0500
-Subject: [PATCH] client: Add support for multiple IP addresses during
- installation.
-
-https://fedorahosted.org/freeipa/ticket/4249
-
-Reviewed-By: Martin Basti <mbasti@redhat.com>
----
- ipa-client/ipa-install/ipa-client-install | 289 +++++++++++++++++++++++-------
- 1 file changed, 223 insertions(+), 66 deletions(-)
-
-diff --git a/ipa-client/ipa-install/ipa-client-install b/ipa-client/ipa-install/ipa-client-install
-index 91323ae115a27d221bcbc43fee887c56d99c8635..793de4fc950ad73b1d88f9ab4bd5178afc8b813d 100755
---- a/ipa-client/ipa-install/ipa-client-install
-+++ b/ipa-client/ipa-install/ipa-client-install
-@@ -32,6 +32,7 @@ try:
-     from optparse import SUPPRESS_HELP, OptionGroup, OptionValueError
-     import shutil
-     from krbV import Krb5Error
-+    import dns
- 
-     import nss.nss as nss
-     import SSSDConfig
-@@ -180,9 +181,15 @@ def parse_options():
-     basic_group.add_option("--configure-firefox", dest="configure_firefox",
-                             action="store_true", default=False,
-                             help="configure Firefox")
--    parser.add_option_group(basic_group)
-     basic_group.add_option("--firefox-dir", dest="firefox_dir", default=None,
-                             help="specify directory where Firefox is installed (for example: '/usr/lib/firefox')")
-+    basic_group.add_option("--ip-address", dest="ip_addresses", default=[],
-+        action="append", help="Specify IP address that should be added to DNS."
-+        " This option can be used multiple times")
-+    basic_group.add_option("--all-ip-addresses", dest="all_ip_addresses",
-+        default=False, action="store_true", help="All routable IP"
-+        " addresses configured on any inteface will be added to DNS")
-+    parser.add_option_group(basic_group)
- 
-     sssd_group = OptionGroup(parser, "SSSD options")
-     sssd_group.add_option("--permit", dest="permit",
-@@ -223,6 +230,15 @@ def parse_options():
-     if options.no_nisdomain and options.nisdomain:
-         parser.error("--no-nisdomain cannot be used together with --nisdomain")
- 
-+    if options.ip_addresses:
-+        if options.dns_updates:
-+            parser.error("--ip-address cannot be used together with"
-+                         " --enable-dns-updates")
-+
-+        if options.all_ip_addresses:
-+            parser.error("--ip-address cannot be used together with"
-+                         " --all-ip-addresses")
-+
-     return safe_opts, options
- 
- def logging_setup(options):
-@@ -1285,6 +1301,11 @@ def configure_sssd_conf(fstore, cli_realm, cli_domain, cli_server, options, clie
- 
-     if options.dns_updates:
-         domain.set_option('dyndns_update', True)
-+        if options.all_ip_addresses:
-+            domain.set_option('dyndns_iface', '*')
-+        else:
-+            iface = get_server_connection_interface(cli_server[0])
-+            domain.set_option('dyndns_iface', iface)
-     if options.krb5_offline_passwords:
-         domain.set_option('krb5_store_password_if_offline', True)
- 
-@@ -1501,39 +1522,41 @@ def unconfigure_nisdomain():
-         services.knownservices.domainname.disable()
- 
- 
--def resolve_ipaddress(server):
--    """ Connect to the server's LDAP port in order to determine what ip
--        address this machine uses as "public" ip (relative to the server).
--
--        Returns a tuple with the IP address and address family when
--        connection was successful. Socket error is raised otherwise.
--    """
--    last_socket_error = None
--
--    for res in socket.getaddrinfo(server, 389, socket.AF_UNSPEC,
--            socket.SOCK_STREAM):
--        af, socktype, proto, canonname, sa = res
--        try:
--            s = socket.socket(af, socktype, proto)
--        except socket.error, e:
--            last_socket_error = e
--            s = None
-+def get_iface_from_ip(ip_addr):
-+    ipresult = ipautil.run([paths.IP, '-oneline', 'address', 'show'])
-+    for line in ipresult[0].split('\n'):
-+        fields = line.split()
-+        if len(fields) < 6:
-             continue
--
-+        if fields[2] not in ['inet', 'inet6']:
-+            continue
-+        (ip, mask) = fields[3].rsplit('/', 1)
-+        if ip == ip_addr:
-+            return fields[1]
-+    else:
-+        raise RuntimeError("IP %s not assigned to any interface." % ip_addr)
-+
-+
-+def get_local_ipaddresses(iface=None):
-+    args = [paths.IP, '-oneline', 'address', 'show']
-+    if iface:
-+        args += ['dev', iface]
-+    ipresult = ipautil.run(args)
-+    lines = ipresult[0].split('\n')
-+    ips = []
-+    for line in lines:
-+        fields = line.split()
-+        if len(fields) < 6:
-+            continue
-+        if fields[2] not in ['inet', 'inet6']:
-+            continue
-+        (ip, mask) = fields[3].rsplit('/', 1)
-         try:
--            s.connect(sa)
--            sockname = s.getsockname()
--
--            # For both IPv4 and IPv6 own IP address is always the first item
--            return (sockname[0], af)
--        except socket.error, e:
--            last_socket_error = e
--        finally:
--            if s:
--                s.close()
-+            ips.append(ipautil.CheckedIPAddress(ip))
-+        except ValueError:
-+            continue
-+    return ips
- 
--    if last_socket_error is not None:
--        raise last_socket_error  # pylint: disable=E0702
- 
- def do_nsupdate(update_txt):
-     root_logger.debug("Writing nsupdate commands to %s:", UPDATE_FILE)
-@@ -1558,21 +1581,24 @@ def do_nsupdate(update_txt):
- 
-     return result
- 
--UPDATE_TEMPLATE_A = """
--debug
-+DELETE_TEMPLATE_A = """
- update delete $HOSTNAME. IN A
- show
- send
--update add $HOSTNAME. $TTL IN A $IPADDRESS
--show
--send
- """
- 
--UPDATE_TEMPLATE_AAAA = """
--debug
-+DELETE_TEMPLATE_AAAA = """
- update delete $HOSTNAME. IN AAAA
- show
- send
-+"""
-+ADD_TEMPLATE_A = """
-+update add $HOSTNAME. $TTL IN A $IPADDRESS
-+show
-+send
-+"""
-+
-+ADD_TEMPLATE_AAAA = """
- update add $HOSTNAME. $TTL IN AAAA $IPADDRESS
- show
- send
-@@ -1581,46 +1607,174 @@ send
- UPDATE_FILE = paths.IPA_DNS_UPDATE_TXT
- CCACHE_FILE = paths.IPA_DNS_CCACHE
- 
--def update_dns(server, hostname):
- 
-+def update_dns(server, hostname, options):
-     try:
--        (ip, af) = resolve_ipaddress(server)
--    except socket.gaierror, e:
--        root_logger.debug("update_dns: could not connect to server: %s", e)
--        root_logger.error("Cannot update DNS records! "
--                          "Failed to connect to server '%s'.", server)
--        return
--
--    sub_dict = dict(HOSTNAME=hostname,
--                    IPADDRESS=ip,
--                    TTL=1200
--                )
--
--    if af == socket.AF_INET:
--        template = UPDATE_TEMPLATE_A
--    elif af == socket.AF_INET6:
--        template = UPDATE_TEMPLATE_AAAA
-+        ips = get_local_ipaddresses()
-+    except CalledProcessError as e:
-+        root_logger.error("Cannot update DNS records. %s" % e)
-+        root_logger.debug("Unable to get local IP addresses.")
-+
-+    if options.all_ip_addresses:
-+        update_ips = ips
-+    elif options.ip_addresses:
-+        update_ips = []
-+        for ip in options.ip_addresses:
-+            update_ips.append(ipautil.CheckedIPAddress(ip))
-     else:
--        root_logger.info("Failed to determine this machine's ip address.")
--        root_logger.warning("Failed to update DNS A record.")
-+        try:
-+            iface = get_server_connection_interface(server)
-+        except RuntimeError as e:
-+            root_logger.error("Cannot update DNS records. %s" % e)
-+            return
-+        try:
-+            update_ips = get_local_ipaddresses(iface)
-+        except CalledProcessError as e:
-+            root_logger.error("Cannot update DNS records. %s" % e)
-+            return
-+
-+    if not update_ips:
-+        root_logger.info("Failed to determine this machine's ip address(es).")
-         return
- 
--    update_txt = ipautil.template_str(template, sub_dict)
-+    update_txt = "debug\n"
-+    update_txt += ipautil.template_str(DELETE_TEMPLATE_A,
-+                                       dict(HOSTNAME=hostname))
-+    update_txt += ipautil.template_str(DELETE_TEMPLATE_AAAA,
-+                                       dict(HOSTNAME=hostname))
-+
-+    for ip in update_ips:
-+        sub_dict = dict(HOSTNAME=hostname, IPADDRESS=ip, TTL=1200)
-+        if ip.version == 4:
-+            template = ADD_TEMPLATE_A
-+        elif ip.version == 6:
-+            template = ADD_TEMPLATE_AAAA
-+        update_txt += ipautil.template_str(template, sub_dict)
-+
-+    if not do_nsupdate(update_txt):
-+        root_logger.error("Failed to update DNS records.")
-+    verify_dns_update(hostname, update_ips)
-+
- 
--    if do_nsupdate(update_txt):
--        root_logger.info("DNS server record set to: %s -> %s", hostname, ip)
-+def verify_dns_update(fqdn, ips):
-+    """
-+    Verify that the fqdn resolves to all IP addresses and
-+    that there's matching PTR record for every IP address.
-+    """
-+    # verify A/AAAA records
-+    missing_ips = [str(ip) for ip in ips]
-+    extra_ips = []
-+    for record_type in [dns.rdatatype.A, dns.rdatatype.AAAA]:
-+        root_logger.debug('DNS resolver: Query: %s IN %s' %
-+                          (fqdn, dns.rdatatype.to_text(record_type)))
-+        try:
-+            answers = dns.resolver.query(fqdn, record_type)
-+        except (dns.resolver.NoAnswer, dns.resolver.NXDOMAIN):
-+            root_logger.debug('DNS resolver: No record.')
-+        except dns.resolver.NoNameservers:
-+            root_logger.debug('DNS resolver: No nameservers answered the'
-+                              'query.')
-+        except dns.exception.DNSException:
-+            root_logger.debug('DNS resolver error.')
-+        else:
-+            for rdata in answers:
-+                try:
-+                    missing_ips.remove(rdata.address)
-+                except ValueError:
-+                    extra_ips.append(rdata.address)
-+
-+    # verify PTR records
-+    fqdn_name = dns.name.from_text(fqdn)
-+    wrong_reverse = {}
-+    missing_reverse = [str(ip) for ip in ips]
-+    for ip in ips:
-+        ip_str = str(ip)
-+        addr = dns.reversename.from_address(ip_str)
-+        root_logger.debug('DNS resolver: Query: %s IN PTR' % addr)
-+        try:
-+            answers = dns.resolver.query(addr, dns.rdatatype.PTR)
-+        except (dns.resolver.NoAnswer, dns.resolver.NXDOMAIN):
-+            root_logger.debug('DNS resolver: No record.')
-+        except dns.resolver.NoNameservers:
-+            root_logger.debug('DNS resolver: No nameservers answered the'
-+                              'query.')
-+        except dns.exception.DNSException:
-+            root_logger.debug('DNS resolver error.')
-+        else:
-+            missing_reverse.remove(ip_str)
-+            for rdata in answers:
-+                if not rdata.target == fqdn_name:
-+                    wrong_reverse.setdefault(ip_str, []).append(rdata.target)
-+
-+    if missing_ips:
-+        root_logger.warning('Missing A/AAAA record(s) for host %s: %s.' %
-+                            (fqdn, ', '.join(missing_ips)))
-+    if extra_ips:
-+        root_logger.warning('Extra A/AAAA record(s) for host %s: %s.' %
-+                            (fqdn, ', '.join(extra_ips)))
-+    if missing_reverse:
-+        root_logger.warning('Missing reverse record(s) for address(es): %s.' %
-+                            ', '.join(missing_reverse))
-+    if wrong_reverse:
-+        root_logger.warning('Incorrect reverse record(s):')
-+        for ip in wrong_reverse:
-+            for target in wrong_reverse[ip]:
-+                root_logger.warning('%s is pointing to %s instead of %s' %
-+                                    (ip, target, fqdn_name))
-+
-+def get_server_connection_interface(server):
-+    # connect to IPA server, get all ip addresses of inteface used to connect
-+    for res in socket.getaddrinfo(server, 389, socket.AF_UNSPEC, socket.SOCK_STREAM):
-+        (af, socktype, proto, canonname, sa) = res
-+        try:
-+            s = socket.socket(af, socktype, proto)
-+        except socket.error as e:
-+            last_error = e
-+            s = None
-+            continue
-+        try:
-+            s.connect(sa)
-+            sockname = s.getsockname()
-+            ip = sockname[0]
-+        except socket.error as e:
-+            last_error = e
-+            continue
-+        finally:
-+            if s:
-+                s.close()
-+        try:
-+            return get_iface_from_ip(ip)
-+        except (CalledProcessError, RuntimeError) as e:
-+            last_error = e
-     else:
--        root_logger.error("Failed to update DNS records.")
-+        msg = "Cannot get server connection interface"
-+        if last_error:
-+            msg += ": %s" % (last_error)
-+        raise RuntimeError(msg)
- 
--def client_dns(server, hostname, dns_updates=False):
-+
-+def client_dns(server, hostname, options):
- 
-     dns_ok = ipautil.is_host_resolvable(hostname)
- 
-     if not dns_ok:
--        root_logger.warning("Hostname (%s) not found in DNS", hostname)
-+        root_logger.warning("Hostname (%s) does not have A/AAAA record.",
-+                            hostname)
-+
-+    if (options.dns_updates or options.all_ip_addresses or options.ip_addresses
-+            or not dns_ok):
-+        update_dns(server, hostname, options)
- 
--    if dns_updates or not dns_ok:
--        update_dns(server, hostname)
-+
-+def check_ip_addresses(options):
-+    if options.ip_addresses:
-+        for ip in options.ip_addresses:
-+            try:
-+                ipautil.CheckedIPAddress(ip, match_local=True)
-+            except ValueError as e:
-+                root_logger.error(e)
-+                return False
-+    return True
- 
- def update_ssh_keys(server, hostname, ssh_dir, create_sshfp):
-     if not os.path.isdir(ssh_dir):
-@@ -2127,6 +2281,9 @@ def install(options, env, fstore, statestore):
-     if not options.ca_cert_file and get_cert_path(options.ca_cert_file) == CACERT:
-         root_logger.warning("Using existing certificate '%s'.", CACERT)
- 
-+    if not check_ip_addresses(options):
-+        return CLIENT_INSTALL_ERROR
-+
-     # Create the discovery instance
-     ds = ipadiscovery.IPADiscovery()
- 
-@@ -2717,7 +2874,7 @@ def install(options, env, fstore, statestore):
-     root_logger.info("Added CA certificates to the default NSS database.")
- 
-     if not options.on_master:
--        client_dns(cli_server[0], hostname, options.dns_updates)
-+        client_dns(cli_server[0], hostname, options)
-         configure_certmonger(fstore, subject_base, cli_realm, hostname,
-                              options, ca_enabled)
- 
--- 
-2.4.3
-
diff --git a/SOURCES/0080-schema-cache-Read-schema-instead-of-rewriting-it-whe.patch b/SOURCES/0080-schema-cache-Read-schema-instead-of-rewriting-it-whe.patch
new file mode 100644
index 0000000..acc7d26
--- /dev/null
+++ b/SOURCES/0080-schema-cache-Read-schema-instead-of-rewriting-it-whe.patch
@@ -0,0 +1,104 @@
+From a9ebd731b23ebf9a56401139fe20dafc50322ff3 Mon Sep 17 00:00:00 2001
+From: David Kupka <dkupka@redhat.com>
+Date: Tue, 16 Aug 2016 15:32:47 +0200
+Subject: [PATCH] schema cache: Read schema instead of rewriting it when
+ SchemaUpToDate
+
+https://fedorahosted.org/freeipa/ticket/6048
+
+Reviewed-By: Jan Cholasta <jcholast@redhat.com>
+---
+ ipaclient/remote_plugins/schema.py | 46 ++++++++++++++++++++------------------
+ 1 file changed, 24 insertions(+), 22 deletions(-)
+
+diff --git a/ipaclient/remote_plugins/schema.py b/ipaclient/remote_plugins/schema.py
+index 2fc6cce3eca392447cd4230216900116002934f4..e8b3f61bd8460c60630e8710028da79654819bd1 100644
+--- a/ipaclient/remote_plugins/schema.py
++++ b/ipaclient/remote_plugins/schema.py
+@@ -17,6 +17,7 @@ import six
+ 
+ from ipaclient.frontend import ClientCommand, ClientMethod
+ from ipalib import errors, parameters, plugable
++from ipalib.errors import SchemaUpToDate
+ from ipalib.frontend import Object
+ from ipalib.output import Output
+ from ipalib.parameters import DefaultFrom, Flag, Password, Str
+@@ -439,15 +440,14 @@ class Schema(object):
+             self._dict[ns] = {}
+             self._namespaces[ns] = _SchemaNameSpace(self, ns)
+ 
+-        is_known = False
+-        if not api.env.force_schema_check:
+-            try:
+-                self._fingerprint = server_info['fingerprint']
+-                self._expiration = server_info['expiration']
+-            except KeyError:
+-                pass
+-            else:
+-                is_known = True
++        try:
++            self._fingerprint = server_info['fingerprint']
++            self._expiration = server_info['expiration']
++        except KeyError:
++            is_known = False
++        else:
++            is_known = (not api.env.force_schema_check and
++                        self._expiration > time.time())
+ 
+         if is_known:
+             try:
+@@ -461,14 +461,15 @@ class Schema(object):
+             self._fetch(client)
+         except NotAvailable:
+             raise
++        except SchemaUpToDate as e:
++            self._fingerprint = e.fingerprint
++            self._expiration = time.time() + e.ttl
++            self._read_schema()
+         else:
+             self._write_schema()
+-        finally:
+-            try:
+-                server_info['fingerprint'] = self._fingerprint
+-                server_info['expiration'] = self._expiration
+-            except AttributeError:
+-                pass
++
++        server_info['fingerprint'] = self._fingerprint
++        server_info['expiration'] = self._expiration
+ 
+     @contextlib.contextmanager
+     def _open(self, filename, mode):
+@@ -501,21 +502,22 @@ class Schema(object):
+             schema = client.forward(u'schema', **kwargs)['result']
+         except errors.CommandError:
+             raise NotAvailable()
+-        except errors.SchemaUpToDate as e:
+-            fp = e.fingerprint
+-            ttl = e.ttl
+-        else:
++
++        try:
+             fp = schema['fingerprint']
+-            ttl = schema.pop('ttl', 0)
+-            schema.pop('version', None)
++            ttl = schema.pop('ttl')
++            schema.pop('version')
+ 
+             for key, value in schema.items():
+                 if key in self.namespaces:
+                     value = {m['full_name']: m for m in value}
+                 self._dict[key] = value
++        except KeyError as e:
++            logger.warning("Failed to fetch schema: %s", e)
++            raise NotAvailable()
+ 
+         self._fingerprint = fp
+-        self._expiration = ttl + time.time()
++        self._expiration = time.time() + ttl
+ 
+     def _read_schema(self):
+         self._file.truncate(0)
+-- 
+2.7.4
+
diff --git a/SOURCES/0081-schema-check-Check-current-client-language-against-c.patch b/SOURCES/0081-schema-check-Check-current-client-language-against-c.patch
new file mode 100644
index 0000000..1837ad4
--- /dev/null
+++ b/SOURCES/0081-schema-check-Check-current-client-language-against-c.patch
@@ -0,0 +1,57 @@
+From 70430cf0c22ab28a145de775aee343b3605c798a Mon Sep 17 00:00:00 2001
+From: David Kupka <dkupka@redhat.com>
+Date: Tue, 16 Aug 2016 15:36:07 +0200
+Subject: [PATCH] schema check: Check current client language against cached
+ one
+
+https://fedorahosted.org/freeipa/ticket/6204
+
+Reviewed-By: Jan Cholasta <jcholast@redhat.com>
+---
+ ipaclient/remote_plugins/schema.py | 9 ++++++++-
+ 1 file changed, 8 insertions(+), 1 deletion(-)
+
+diff --git a/ipaclient/remote_plugins/schema.py b/ipaclient/remote_plugins/schema.py
+index e8b3f61bd8460c60630e8710028da79654819bd1..6fc70bf4b294badedd651e15b7e403cc40619f5c 100644
+--- a/ipaclient/remote_plugins/schema.py
++++ b/ipaclient/remote_plugins/schema.py
+@@ -7,6 +7,7 @@ import contextlib
+ import errno
+ import fcntl
+ import json
++import locale
+ import os
+ import sys
+ import time
+@@ -440,14 +441,19 @@ class Schema(object):
+             self._dict[ns] = {}
+             self._namespaces[ns] = _SchemaNameSpace(self, ns)
+ 
++        self._language = (
++            locale.setlocale(locale.LC_ALL, '').split('.')[0].lower()
++        )
+         try:
+             self._fingerprint = server_info['fingerprint']
+             self._expiration = server_info['expiration']
++            language = server_info['language']
+         except KeyError:
+             is_known = False
+         else:
+             is_known = (not api.env.force_schema_check and
+-                        self._expiration > time.time())
++                        self._expiration > time.time() and
++                        self._language == language)
+ 
+         if is_known:
+             try:
+@@ -470,6 +476,7 @@ class Schema(object):
+ 
+         server_info['fingerprint'] = self._fingerprint
+         server_info['expiration'] = self._expiration
++        server_info['language'] = self._language
+ 
+     @contextlib.contextmanager
+     def _open(self, filename, mode):
+-- 
+2.7.4
+
diff --git a/SOURCES/0081-vault-Fix-vault-find-with-criteria.patch b/SOURCES/0081-vault-Fix-vault-find-with-criteria.patch
deleted file mode 100644
index 8b33fad..0000000
--- a/SOURCES/0081-vault-Fix-vault-find-with-criteria.patch
+++ /dev/null
@@ -1,28 +0,0 @@
-From a97b7c5bd372c7a581c440564f4e9d6f3c12a3ea Mon Sep 17 00:00:00 2001
-From: Jan Cholasta <jcholast@redhat.com>
-Date: Tue, 18 Aug 2015 21:11:52 +0200
-Subject: [PATCH] vault: Fix vault-find with criteria
-
-https://fedorahosted.org/freeipa/ticket/5212
-
-Reviewed-By: Petr Vobornik <pvoborni@redhat.com>
----
- ipalib/plugins/vault.py | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/ipalib/plugins/vault.py b/ipalib/plugins/vault.py
-index 4d430ee88658e7ba7f2863ca4ef1e8672e298923..ff021a6a2106b6bcbd690b50bf58e49249e80500 100644
---- a/ipalib/plugins/vault.py
-+++ b/ipalib/plugins/vault.py
-@@ -802,7 +802,7 @@ class vault_find(LDAPSearch):
-             raise errors.InvocationError(
-                 format=_('KRA service is not enabled'))
- 
--        base_dn = self.obj.get_dn(*args, **options)
-+        base_dn = self.obj.get_dn(None, **options)
- 
-         return (filter, base_dn, scope)
- 
--- 
-2.4.3
-
diff --git a/SOURCES/0082-Fail-on-topology-disconnect-last-role-removal.patch b/SOURCES/0082-Fail-on-topology-disconnect-last-role-removal.patch
new file mode 100644
index 0000000..91f2417
--- /dev/null
+++ b/SOURCES/0082-Fail-on-topology-disconnect-last-role-removal.patch
@@ -0,0 +1,51 @@
+From 90b827a6d23d864bfac96d2ff0f89f1a3ba1d245 Mon Sep 17 00:00:00 2001
+From: Stanislav Laznicka <slaznick@redhat.com>
+Date: Fri, 12 Aug 2016 11:59:41 +0200
+Subject: [PATCH] Fail on topology disconnect/last role removal
+
+Disconnecting topology/removing last-role-host during server
+uninstallation should raise error rather than just being logged
+if the appropriate ignore settings are not present.
+
+https://fedorahosted.org/freeipa/ticket/6168
+
+Reviewed-By: Martin Babinsky <mbabinsk@redhat.com>
+---
+ ipaserver/install/server/install.py | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/ipaserver/install/server/install.py b/ipaserver/install/server/install.py
+index 94698898934844350488d5fc52d6e1e567624502..86b8402750b503ea7dacd1f4c59c82d9bd4082e6 100644
+--- a/ipaserver/install/server/install.py
++++ b/ipaserver/install/server/install.py
+@@ -25,6 +25,7 @@ from ipapython.ipa_log_manager import root_logger
+ from ipapython.ipautil import (
+     decrypt_file, format_netloc, ipa_generate_password, run, user_input,
+     is_fips_enabled)
++from ipapython.admintool import ScriptError
+ from ipaplatform import services
+ from ipaplatform.paths import paths
+ from ipaplatform.tasks import tasks
+@@ -294,7 +295,6 @@ def common_cleanup(func):
+ def remove_master_from_managed_topology(api_instance, options):
+     try:
+         # we may force the removal
+-        # if the master was already deleted we will just get a warning
+         server_del_options = dict(
+             force=True,
+             ignore_topology_disconnect=options.ignore_topology_disconnect,
+@@ -303,8 +303,10 @@ def remove_master_from_managed_topology(api_instance, options):
+ 
+         replication.run_server_del_as_cli(
+             api_instance, api_instance.env.host, **server_del_options)
+-
++    except errors.ServerRemovalError as e:
++        raise ScriptError(str(e))
+     except Exception as e:
++        # if the master was already deleted we will just get a warning
+         root_logger.warning("Failed to delete master: {}".format(e))
+ 
+ 
+-- 
+2.9.3
+
diff --git a/SOURCES/0082-vault-Add-container-information-to-vault-command-res.patch b/SOURCES/0082-vault-Add-container-information-to-vault-command-res.patch
deleted file mode 100644
index 731126b..0000000
--- a/SOURCES/0082-vault-Add-container-information-to-vault-command-res.patch
+++ /dev/null
@@ -1,112 +0,0 @@
-From 23dd6ad21e09a14a802c7776bf073f22011f7eb6 Mon Sep 17 00:00:00 2001
-From: Jan Cholasta <jcholast@redhat.com>
-Date: Tue, 18 Aug 2015 21:44:13 +0200
-Subject: [PATCH] vault: Add container information to vault command results
-
-https://fedorahosted.org/freeipa/ticket/5150
-
-Reviewed-By: Petr Vobornik <pvoborni@redhat.com>
----
- ipalib/plugins/vault.py | 44 ++++++++++++++++++++++++++++++++++++++++++++
- 1 file changed, 44 insertions(+)
-
-diff --git a/ipalib/plugins/vault.py b/ipalib/plugins/vault.py
-index ff021a6a2106b6bcbd690b50bf58e49249e80500..712e2d5ddfa723eb84b80a261289a7cf1c75674f 100644
---- a/ipalib/plugins/vault.py
-+++ b/ipalib/plugins/vault.py
-@@ -322,6 +322,21 @@ class vault(LDAPObject):
-             label=_('Failed owners'),
-             flags=['no_create', 'no_update', 'no_search'],
-         ),
-+        Str(
-+            'service?',
-+            label=_('Vault service'),
-+            flags={'virtual_attribute', 'no_create', 'no_update', 'no_search'},
-+        ),
-+        Flag(
-+            'shared?',
-+            label=_('Shared vault'),
-+            flags={'virtual_attribute', 'no_create', 'no_update', 'no_search'},
-+        ),
-+        Str(
-+            'username?',
-+            label=_('Vault user'),
-+            flags={'virtual_attribute', 'no_create', 'no_update', 'no_search'},
-+        ),
-     )
- 
-     def get_dn(self, *keys, **options):
-@@ -523,6 +538,17 @@ class vault(LDAPObject):
-                 raise errors.AuthenticationError(
-                     message=_('Invalid credentials'))
- 
-+    def get_container_attribute(self, entry, options):
-+        if options.get('raw', False):
-+            return
-+        container_dn = DN(self.container_dn, self.api.env.basedn)
-+        if entry.dn.endswith(DN(('cn', 'services'), container_dn)):
-+            entry['service'] = entry.dn[1]['cn']
-+        elif entry.dn.endswith(DN(('cn', 'shared'), container_dn)):
-+            entry['shared'] = True
-+        elif entry.dn.endswith(DN(('cn', 'users'), container_dn)):
-+            entry['username'] = entry.dn[1]['cn']
-+
- 
- @register()
- class vault_add(PKQuery, Local):
-@@ -738,6 +764,10 @@ class vault_add_internal(LDAPCreate):
- 
-         return dn
- 
-+    def post_callback(self, ldap, dn, entry, *keys, **options):
-+        self.obj.get_container_attribute(entry, options)
-+        return dn
-+
- 
- @register()
- class vault_del(LDAPDelete):
-@@ -806,6 +836,11 @@ class vault_find(LDAPSearch):
- 
-         return (filter, base_dn, scope)
- 
-+    def post_callback(self, ldap, entries, truncated, *args, **options):
-+        for entry in entries:
-+            self.obj.get_container_attribute(entry, options)
-+        return truncated
-+
-     def exc_callback(self, args, options, exc, call_func, *call_args,
-                      **call_kwargs):
-         if call_func.__name__ == 'find_entries':
-@@ -836,6 +871,10 @@ class vault_mod(LDAPUpdate):
- 
-         return dn
- 
-+    def post_callback(self, ldap, dn, entry_attrs, *keys, **options):
-+        self.obj.get_container_attribute(entry_attrs, options)
-+        return dn
-+
- 
- @register()
- class vault_show(LDAPRetrieve):
-@@ -854,6 +893,10 @@ class vault_show(LDAPRetrieve):
- 
-         return dn
- 
-+    def post_callback(self, ldap, dn, entry_attrs, *keys, **options):
-+        self.obj.get_container_attribute(entry_attrs, options)
-+        return dn
-+
- 
- @register()
- class vaultconfig(Object):
-@@ -1452,6 +1495,7 @@ class VaultModMember(LDAPModMember):
-     def post_callback(self, ldap, completed, failed, dn, entry_attrs, *keys, **options):
-         for fail in failed.itervalues():
-             fail['services'] = fail.pop('service', [])
-+        self.obj.get_container_attribute(entry_attrs, options)
-         return completed, dn
- 
- 
--- 
-2.4.3
-
diff --git a/SOURCES/0083-Server-Upgrade-Start-DS-before-CA-is-started.patch b/SOURCES/0083-Server-Upgrade-Start-DS-before-CA-is-started.patch
deleted file mode 100644
index db04618..0000000
--- a/SOURCES/0083-Server-Upgrade-Start-DS-before-CA-is-started.patch
+++ /dev/null
@@ -1,61 +0,0 @@
-From dc32238b191a84f0677e2d3ae47f5b319946faf9 Mon Sep 17 00:00:00 2001
-From: Martin Basti <mbasti@redhat.com>
-Date: Tue, 18 Aug 2015 18:01:09 +0200
-Subject: [PATCH] Server Upgrade: Start DS before CA is started.
-
-https://fedorahosted.org/freeipa/ticket/5232
-
-Reviewed-By: Jan Cholasta <jcholast@redhat.com>
----
- ipaserver/install/server/upgrade.py | 14 ++++++++++++--
- 1 file changed, 12 insertions(+), 2 deletions(-)
-
-diff --git a/ipaserver/install/server/upgrade.py b/ipaserver/install/server/upgrade.py
-index 692d0c77e0683f4ad35ebbc14d5a34decc098deb..a57682a4bbdaab2a15b4e415223e2f5faa67ba73 100644
---- a/ipaserver/install/server/upgrade.py
-+++ b/ipaserver/install/server/upgrade.py
-@@ -1328,6 +1328,13 @@ def upgrade_configuration():
-         raise RuntimeError("ipa-rewrite.conf doesn't exists (is this server?)")
- 
-     # Ok, we are an IPA server, do the additional tests
-+    ds_serverid = installutils.realm_to_serverid(api.env.realm)
-+    ds = dsinstance.DsInstance()
-+
-+    # start DS, CA will not start without running DS, and cause error
-+    ds_running = ds.is_running()
-+    if not ds_running:
-+        ds.start(ds_serverid)
- 
-     check_certs()
- 
-@@ -1359,7 +1366,6 @@ def upgrade_configuration():
-                     'ca.crl.MasterCRL.enableCRLUpdates', '=')
-             sub_dict['CLONE']='#' if crl.lower() == 'true' else ''
- 
--        ds_serverid = installutils.realm_to_serverid(api.env.realm)
-         ds_dirname = dsinstance.config_dirname(ds_serverid)
- 
-         upgrade_file(sub_dict, paths.HTTPD_IPA_CONF,
-@@ -1396,7 +1402,6 @@ def upgrade_configuration():
-     http.change_mod_nss_port_from_http()
-     http.configure_certmonger_renewal_guard()
- 
--    ds = dsinstance.DsInstance()
-     ds.configure_dirsrv_ccache()
- 
-     # ldap2 connection is not valid after DS restart, close connection otherwise
-@@ -1526,6 +1531,11 @@ def upgrade_configuration():
- 
-     set_sssd_domain_option('ipa_server_mode', 'True')
- 
-+    if ds_running and not ds.is_running():
-+        ds.start(ds_serverid)
-+    elif not ds_running and ds.is_running():
-+        ds.stop(ds_serverid)
-+
- 
- def upgrade_check(options):
-     try:
--- 
-2.4.3
-
diff --git a/SOURCES/0083-server-install-do-not-prompt-for-cert-file-PIN-repea.patch b/SOURCES/0083-server-install-do-not-prompt-for-cert-file-PIN-repea.patch
new file mode 100644
index 0000000..d701518
--- /dev/null
+++ b/SOURCES/0083-server-install-do-not-prompt-for-cert-file-PIN-repea.patch
@@ -0,0 +1,98 @@
+From 620dced81e4ef95522fcaf50c0b3e060f911754f Mon Sep 17 00:00:00 2001
+From: Jan Cholasta <jcholast@redhat.com>
+Date: Tue, 16 Aug 2016 17:34:06 +0200
+Subject: [PATCH] server install: do not prompt for cert file PIN repeatedly
+
+Prompt for PIN only once in interactive mode.
+
+This fixes ipa-server-install, ipa-server-certinstall and
+ipa-replica-prepare prompting over and over when the PIN is empty.
+
+https://fedorahosted.org/freeipa/ticket/6032
+
+Reviewed-By: Pavel Vomacka <pvomacka@redhat.com>
+---
+ ipaserver/install/ipa_replica_prepare.py    | 6 +++---
+ ipaserver/install/ipa_server_certinstall.py | 3 ++-
+ ipaserver/install/server/install.py         | 6 +++---
+ 3 files changed, 8 insertions(+), 7 deletions(-)
+
+diff --git a/ipaserver/install/ipa_replica_prepare.py b/ipaserver/install/ipa_replica_prepare.py
+index fdd32f0c8437a0d8c3947d57089662ea09bb2304..80813086c6a7212bdb6ef9d54202b28808b80076 100644
+--- a/ipaserver/install/ipa_replica_prepare.py
++++ b/ipaserver/install/ipa_replica_prepare.py
+@@ -303,7 +303,7 @@ class ReplicaPrepare(admintool.AdminTool):
+             if options.http_pin is None:
+                 options.http_pin = installutils.read_password(
+                     "Enter Apache Server private key unlock",
+-                    confirm=False, validate=False)
++                    confirm=False, validate=False, retry=False)
+                 if options.http_pin is None:
+                     raise admintool.ScriptError(
+                         "Apache Server private key unlock password required")
+@@ -317,7 +317,7 @@ class ReplicaPrepare(admintool.AdminTool):
+             if options.dirsrv_pin is None:
+                 options.dirsrv_pin = installutils.read_password(
+                     "Enter Directory Server private key unlock",
+-                    confirm=False, validate=False)
++                    confirm=False, validate=False, retry=False)
+                 if options.dirsrv_pin is None:
+                     raise admintool.ScriptError(
+                         "Directory Server private key unlock password required")
+@@ -331,7 +331,7 @@ class ReplicaPrepare(admintool.AdminTool):
+             if options.pkinit_pin is None:
+                 options.pkinit_pin = installutils.read_password(
+                     "Enter Kerberos KDC private key unlock",
+-                    confirm=False, validate=False)
++                    confirm=False, validate=False, retry=False)
+                 if options.pkinit_pin is None:
+                     raise admintool.ScriptError(
+                         "Kerberos KDC private key unlock password required")
+diff --git a/ipaserver/install/ipa_server_certinstall.py b/ipaserver/install/ipa_server_certinstall.py
+index 5ab47303add479c7c492c251b0cf6646de681a4b..0a8fb214a232e60a89b6c06940b928f97c007b93 100644
+--- a/ipaserver/install/ipa_server_certinstall.py
++++ b/ipaserver/install/ipa_server_certinstall.py
+@@ -92,7 +92,8 @@ class ServerCertInstall(admintool.AdminTool):
+ 
+         if self.options.pin is None:
+             self.options.pin = installutils.read_password(
+-                "Enter private key unlock", confirm=False, validate=False)
++                "Enter private key unlock",
++                confirm=False, validate=False, retry=False)
+             if self.options.pin is None:
+                 raise admintool.ScriptError(
+                     "Private key unlock password required")
+diff --git a/ipaserver/install/server/install.py b/ipaserver/install/server/install.py
+index 86b8402750b503ea7dacd1f4c59c82d9bd4082e6..b33b0243d4d909a561b59d93f0014c390146b333 100644
+--- a/ipaserver/install/server/install.py
++++ b/ipaserver/install/server/install.py
+@@ -488,7 +488,7 @@ def install_check(installer):
+         if options.http_pin is None:
+             options.http_pin = installutils.read_password(
+                 "Enter Apache Server private key unlock",
+-                confirm=False, validate=False)
++                confirm=False, validate=False, retry=False)
+             if options.http_pin is None:
+                 sys.exit(
+                     "Apache Server private key unlock password required")
+@@ -504,7 +504,7 @@ def install_check(installer):
+         if options.dirsrv_pin is None:
+             options.dirsrv_pin = read_password(
+                 "Enter Directory Server private key unlock",
+-                confirm=False, validate=False)
++                confirm=False, validate=False, retry=False)
+             if options.dirsrv_pin is None:
+                 sys.exit(
+                     "Directory Server private key unlock password required")
+@@ -520,7 +520,7 @@ def install_check(installer):
+         if options.pkinit_pin is None:
+             options.pkinit_pin = read_password(
+                 "Enter Kerberos KDC private key unlock",
+-                confirm=False, validate=False)
++                confirm=False, validate=False, retry=False)
+             if options.pkinit_pin is None:
+                 sys.exit(
+                     "Kerberos KDC private key unlock password required")
+-- 
+2.9.3
+
diff --git a/SOURCES/0084-cert-request-remove-allowed-extensions-check.patch b/SOURCES/0084-cert-request-remove-allowed-extensions-check.patch
deleted file mode 100644
index ee3a5c0..0000000
--- a/SOURCES/0084-cert-request-remove-allowed-extensions-check.patch
+++ /dev/null
@@ -1,72 +0,0 @@
-From 5a39de97688f517acf5dea952c82b6535352744b Mon Sep 17 00:00:00 2001
-From: Fraser Tweedale <ftweedal@redhat.com>
-Date: Thu, 13 Aug 2015 01:42:06 -0400
-Subject: [PATCH] cert-request: remove allowed extensions check
-
-cert-request currently permits a limited number of request
-extensions; uncommon and esoteric extensions are prohibited and this
-limits the usefulness of custom profiles.
-
-The Dogtag profile has total control over what goes into the final
-certificate and has the option to reject request based on the
-request extensions present or their values, so there is little
-reason to restrict what extensions can be used in FreeIPA.  Remove
-the check.
-
-Fixes: https://fedorahosted.org/freeipa/ticket/5205
-Reviewed-By: Jan Cholasta <jcholast@redhat.com>
----
- ipalib/plugins/cert.py | 22 +++-------------------
- 1 file changed, 3 insertions(+), 19 deletions(-)
-
-diff --git a/ipalib/plugins/cert.py b/ipalib/plugins/cert.py
-index daa698b54f2cc1b645245d312fae0f0500239ea2..7a07039a8488cc11d9bf05ef23642b8059d5921e 100644
---- a/ipalib/plugins/cert.py
-+++ b/ipalib/plugins/cert.py
-@@ -306,15 +306,6 @@ class cert_request(VirtualCommand):
-         ),
-     )
- 
--    _allowed_extensions = {
--        '2.5.29.14': None,      # Subject Key Identifier
--        '2.5.29.15': None,      # Key Usage
--        '2.5.29.17': 'request certificate with subjectaltname',
--        '2.5.29.19': None,      # Basic Constraints
--        '2.5.29.37': None,      # Extended Key Usage
--        '1.2.840.10070.8.1': None, # IECUserRoles (DNP3 / IEC 62351-8)
--    }
--
-     def execute(self, csr, **kw):
-         ca_enabled_check()
- 
-@@ -376,12 +367,10 @@ class cert_request(VirtualCommand):
-             raise errors.CertificateOperationError(
-                 error=_("Failure decoding Certificate Signing Request: %s") % e)
- 
--        # host principals may bypass allowed ext check
-+        # self-service and host principals may bypass SAN permission check
-         if bind_principal != principal and bind_principal_type != HOST:
--            for ext in extensions:
--                operation = self._allowed_extensions.get(ext)
--                if operation:
--                    self.check_access(operation)
-+            if '2.5.29.17' in extensions:
-+                self.check_access('request certificate with subjectaltname')
- 
-         dn = None
-         principal_obj = None
-@@ -433,11 +422,6 @@ class cert_request(VirtualCommand):
-                         "any of user's email addresses")
-                 )
- 
--        for ext in extensions:
--            if ext not in self._allowed_extensions:
--                raise errors.ValidationError(
--                    name='csr', error=_("extension %s is forbidden") % ext)
--
-         # We got this far so the principal entry exists, can we write it?
-         if not ldap.can_write(dn, "usercertificate"):
-             raise errors.ACIError(info=_("Insufficient 'write' privilege "
--- 
-2.4.3
-
diff --git a/SOURCES/0084-service-add-flag-to-allow-S4U2Self.patch b/SOURCES/0084-service-add-flag-to-allow-S4U2Self.patch
new file mode 100644
index 0000000..2655bd6
--- /dev/null
+++ b/SOURCES/0084-service-add-flag-to-allow-S4U2Self.patch
@@ -0,0 +1,122 @@
+From e885fdff4d1bfee23bd41e6e64f64680ae643624 Mon Sep 17 00:00:00 2001
+From: Alexander Bokovoy <abokovoy@redhat.com>
+Date: Thu, 11 Aug 2016 11:52:05 +0300
+Subject: [PATCH] service: add flag to allow S4U2Self
+
+Prerequisite for: https://fedorahosted.org/freeipa/ticket/5764
+
+Reviewed-By: Stanislav Laznicka <slaznick@redhat.com>
+---
+ API.txt                      | 12 ++++++++----
+ VERSION                      |  4 ++--
+ ipaserver/plugins/service.py |  7 +++++++
+ 3 files changed, 17 insertions(+), 6 deletions(-)
+
+diff --git a/API.txt b/API.txt
+index 535d8ec9a4990395207e2455a09a8c1bdef5529a..5b83bfbd0b457b77e0522ab7d83abfae4df3ebe9 100644
+--- a/API.txt
++++ b/API.txt
+@@ -2260,7 +2260,7 @@ output: Output('summary', type=[<type 'unicode'>, <type 'NoneType'>])
+ output: Output('value', type=[<type 'bool'>])
+ output: Output('warning', type=[<type 'list'>, <type 'tuple'>, <type 'NoneType'>])
+ command: host_add/1
+-args: 1,24,3
++args: 1,25,3
+ arg: Str('fqdn', cli_name='hostname')
+ option: Str('addattr*', cli_name='addattr')
+ option: Flag('all', autofill=True, cli_name='all', default=False)
+@@ -2269,6 +2269,7 @@ option: Flag('force', autofill=True, default=False)
+ option: Str('ip_address?')
+ option: Str('ipaassignedidview?')
+ option: Bool('ipakrbokasdelegate?', cli_name='ok_as_delegate')
++option: Bool('ipakrboktoauthasdelegate?', cli_name='ok_to_auth_as_delegate')
+ option: Bool('ipakrbrequirespreauth?', cli_name='requires_pre_auth')
+ option: Str('ipasshpubkey*', cli_name='sshpubkey')
+ option: Str('krbprincipalauthind*', cli_name='auth_ind')
+@@ -2437,7 +2438,7 @@ output: ListOfEntries('result')
+ output: Output('summary', type=[<type 'unicode'>, <type 'NoneType'>])
+ output: Output('truncated', type=[<type 'bool'>])
+ command: host_mod/1
+-args: 1,25,3
++args: 1,26,3
+ arg: Str('fqdn', cli_name='hostname')
+ option: Str('addattr*', cli_name='addattr')
+ option: Flag('all', autofill=True, cli_name='all', default=False)
+@@ -2445,6 +2446,7 @@ option: Str('delattr*', cli_name='delattr')
+ option: Str('description?', autofill=False, cli_name='desc')
+ option: Str('ipaassignedidview?', autofill=False)
+ option: Bool('ipakrbokasdelegate?', autofill=False, cli_name='ok_as_delegate')
++option: Bool('ipakrboktoauthasdelegate?', autofill=False, cli_name='ok_to_auth_as_delegate')
+ option: Bool('ipakrbrequirespreauth?', autofill=False, cli_name='requires_pre_auth')
+ option: Str('ipasshpubkey*', autofill=False, cli_name='sshpubkey')
+ option: Str('krbprincipalauthind*', autofill=False, cli_name='auth_ind')
+@@ -4293,13 +4295,14 @@ output: Entry('result')
+ output: Output('summary', type=[<type 'unicode'>, <type 'NoneType'>])
+ output: PrimaryKey('value')
+ command: service_add/1
+-args: 1,12,3
++args: 1,13,3
+ arg: Principal('krbcanonicalname', cli_name='canonical_principal')
+ option: Str('addattr*', cli_name='addattr')
+ option: Flag('all', autofill=True, cli_name='all', default=False)
+ option: Flag('force', autofill=True, default=False)
+ option: StrEnum('ipakrbauthzdata*', cli_name='pac_type', values=[u'MS-PAC', u'PAD', u'NONE'])
+ option: Bool('ipakrbokasdelegate?', cli_name='ok_as_delegate')
++option: Bool('ipakrboktoauthasdelegate?', cli_name='ok_to_auth_as_delegate')
+ option: Bool('ipakrbrequirespreauth?', cli_name='requires_pre_auth')
+ option: Str('krbprincipalauthind*', cli_name='auth_ind')
+ option: Flag('no_members', autofill=True, default=False)
+@@ -4435,13 +4438,14 @@ output: ListOfEntries('result')
+ output: Output('summary', type=[<type 'unicode'>, <type 'NoneType'>])
+ output: Output('truncated', type=[<type 'bool'>])
+ command: service_mod/1
+-args: 1,14,3
++args: 1,15,3
+ arg: Principal('krbcanonicalname', cli_name='canonical_principal')
+ option: Str('addattr*', cli_name='addattr')
+ option: Flag('all', autofill=True, cli_name='all', default=False)
+ option: Str('delattr*', cli_name='delattr')
+ option: StrEnum('ipakrbauthzdata*', autofill=False, cli_name='pac_type', values=[u'MS-PAC', u'PAD', u'NONE'])
+ option: Bool('ipakrbokasdelegate?', autofill=False, cli_name='ok_as_delegate')
++option: Bool('ipakrboktoauthasdelegate?', autofill=False, cli_name='ok_to_auth_as_delegate')
+ option: Bool('ipakrbrequirespreauth?', autofill=False, cli_name='requires_pre_auth')
+ option: Str('krbprincipalauthind*', autofill=False, cli_name='auth_ind')
+ option: Principal('krbprincipalname*', autofill=False, cli_name='principal')
+diff --git a/VERSION b/VERSION
+index ca489965050f32d2d8987dfd251ec2b2a0ba1768..a8b89ed305bcfdf2990a7400d005a68d734fa7e8 100644
+--- a/VERSION
++++ b/VERSION
+@@ -90,5 +90,5 @@ IPA_DATA_VERSION=20100614120000
+ #                                                      #
+ ########################################################
+ IPA_API_VERSION_MAJOR=2
+-IPA_API_VERSION_MINOR=211
+-# Last change: mbabinsk: allow 'value' output param in commands without primary key
++IPA_API_VERSION_MINOR=212
++# Last change: ab: service: add flag to allow S4U2Self
+diff --git a/ipaserver/plugins/service.py b/ipaserver/plugins/service.py
+index a44dcaa5e348d3deedda6c0b4f55760ad873cf49..04d1916fe989a8651bcc4d44f1914c460be1081c 100644
+--- a/ipaserver/plugins/service.py
++++ b/ipaserver/plugins/service.py
+@@ -171,11 +171,18 @@ ticket_flags_params = (
+         doc=_('Client credentials may be delegated to the service'),
+         flags=['virtual_attribute', 'no_search'],
+     ),
++    Bool('ipakrboktoauthasdelegate?',
++        cli_name='ok_to_auth_as_delegate',
++        label=_('Trusted to authenticate as user'),
++        doc=_('The service is allowed to authenticate on behalf of a client'),
++        flags=['virtual_attribute', 'no_search'],
++    ),
+ )
+ 
+ _ticket_flags_map = {
+     'ipakrbrequirespreauth': 0x00000080,
+     'ipakrbokasdelegate': 0x00100000,
++    'ipakrboktoauthasdelegate': 0x00200000,
+ }
+ 
+ _ticket_flags_default = _ticket_flags_map['ipakrbrequirespreauth']
+-- 
+2.7.4
+
diff --git a/SOURCES/0085-Add-trusted-to-auth-as-user-checkbox.patch b/SOURCES/0085-Add-trusted-to-auth-as-user-checkbox.patch
new file mode 100644
index 0000000..46d91b1
--- /dev/null
+++ b/SOURCES/0085-Add-trusted-to-auth-as-user-checkbox.patch
@@ -0,0 +1,50 @@
+From 9bad7f0d876a0ed4f7ee9fdff6ca6d117debf404 Mon Sep 17 00:00:00 2001
+From: Pavel Vomacka <pvomacka@redhat.com>
+Date: Thu, 11 Aug 2016 18:53:55 +0200
+Subject: [PATCH] Add 'trusted to auth as user' checkbox
+
+Add new checkbox to host and service details page
+
+Prerequisite for: https://fedorahosted.org/freeipa/ticket/5764
+
+Reviewed-By: Stanislav Laznicka <slaznick@redhat.com>
+---
+ install/ui/src/freeipa/host.js    | 5 +++++
+ install/ui/src/freeipa/service.js | 5 +++++
+ 2 files changed, 10 insertions(+)
+
+diff --git a/install/ui/src/freeipa/host.js b/install/ui/src/freeipa/host.js
+index 33d443c2bc96c385bd13abf4d85adda6e51db718..87cf264ef20b79aceed639f45d926fd7aef19edf 100644
+--- a/install/ui/src/freeipa/host.js
++++ b/install/ui/src/freeipa/host.js
+@@ -142,6 +142,11 @@ return {
+                             flags: ['w_if_no_aci']
+                         },
+                         {
++                            name: 'ipakrboktoauthasdelegate',
++                            $type: 'checkbox',
++                            acl_param: 'krbticketflags'
++                        },
++                        {
+                             name: 'ipaassignedidview',
+                             $type: 'link',
+                             label: '@i18n:objects.idview.ipaassignedidview',
+diff --git a/install/ui/src/freeipa/service.js b/install/ui/src/freeipa/service.js
+index 35d486605ebfee41d8b3ffa5bb77bf9e72a60c01..30e336c35b8eece2e5e3ef55629d0c98f097fbf5 100644
+--- a/install/ui/src/freeipa/service.js
++++ b/install/ui/src/freeipa/service.js
+@@ -142,6 +142,11 @@ return {
+                             acl_param: 'krbticketflags'
+                         },
+                         {
++                            name: 'ipakrboktoauthasdelegate',
++                            $type: 'checkbox',
++                            acl_param: 'krbticketflags'
++                        },
++                        {
+                             name: 'ipakrbrequirespreauth',
+                             $type: 'checkbox',
+                             acl_param: 'krbticketflags'
+-- 
+2.7.4
+
diff --git a/SOURCES/0085-client-Add-description-of-ip-address-and-all-ip-addr.patch b/SOURCES/0085-client-Add-description-of-ip-address-and-all-ip-addr.patch
deleted file mode 100644
index 0f5366a..0000000
--- a/SOURCES/0085-client-Add-description-of-ip-address-and-all-ip-addr.patch
+++ /dev/null
@@ -1,33 +0,0 @@
-From 492e167705075bcecc6f7a79a6476496a2303986 Mon Sep 17 00:00:00 2001
-From: David Kupka <dkupka@redhat.com>
-Date: Wed, 19 Aug 2015 12:28:34 +0200
-Subject: [PATCH] client: Add description of --ip-address and
- --all-ip-addresses to man page
-
-https://fedorahosted.org/freeipa/ticket/4249
-
-Reviewed-By: Martin Basti <mbasti@redhat.com>
----
- ipa-client/man/ipa-client-install.1 | 6 ++++++
- 1 file changed, 6 insertions(+)
-
-diff --git a/ipa-client/man/ipa-client-install.1 b/ipa-client/man/ipa-client-install.1
-index 41437f0ec2fe432c8088cb57cfe01b482e4116e6..0fafd8a3f2ee24b400b1cbeada4ddf7cea9493b0 100644
---- a/ipa-client/man/ipa-client-install.1
-+++ b/ipa-client/man/ipa-client-install.1
-@@ -180,6 +180,12 @@ Request certificate for the machine. The certificate will be stored in /etc/ipa/
- \fB\-\-automount\-location\fR=\fILOCATION\fR
- Configure automount by running ipa\-client\-automount(1) with \fILOCATION\fR as
- automount location.
-+.TP
-+\fB\-\-ip\-address\fR=\fIIP_ADDRESS\fR
-+Use \fIIP_ADDRESS\fR in DNS A/AAAA record for this host. May be specified multiple times to add multiple DNS records.
-+.TP
-+\fB\-\-all\-ip\-addresses\fR
-+Create DNS A/AAAA record for each IP address on this host.
- 
- .SS "SSSD OPTIONS"
- .TP
--- 
-2.4.3
-
diff --git a/SOURCES/0086-Added-new-authentication-method.patch b/SOURCES/0086-Added-new-authentication-method.patch
new file mode 100644
index 0000000..fb222f6
--- /dev/null
+++ b/SOURCES/0086-Added-new-authentication-method.patch
@@ -0,0 +1,79 @@
+From b620de7a08aa626290f166213bb8e1eac62a47be Mon Sep 17 00:00:00 2001
+From: Tiboris <tibor.dudlak@gmail.com>
+Date: Tue, 16 Aug 2016 14:13:29 +0200
+Subject: [PATCH] Added new authentication method
+
+Addressing ticket https://fedorahosted.org/freeipa/ticket/5764
+
+Reviewed-By: Stanislav Laznicka <slaznick@redhat.com>
+---
+ ipaserver/plugins/xmlserver.py |  6 +++++-
+ ipaserver/rpcserver.py         | 17 +++++++++++++----
+ 2 files changed, 18 insertions(+), 5 deletions(-)
+
+diff --git a/ipaserver/plugins/xmlserver.py b/ipaserver/plugins/xmlserver.py
+index d8fe24e0cb407603e9898e934229c9373f3c8b62..08c7456ed6dbfcc59f532314894031fba584e20a 100644
+--- a/ipaserver/plugins/xmlserver.py
++++ b/ipaserver/plugins/xmlserver.py
+@@ -28,12 +28,16 @@ register = Registry()
+ 
+ 
+ if api.env.context in ('server', 'lite'):
+-    from ipaserver.rpcserver import wsgi_dispatch, xmlserver, jsonserver_kerb, jsonserver_session, login_kerberos, login_password, change_password, sync_token, xmlserver_session
++    from ipaserver.rpcserver import (
++        wsgi_dispatch, xmlserver, jsonserver_kerb, jsonserver_session,
++        login_kerberos, login_x509, login_password, change_password,
++        sync_token, xmlserver_session)
+     register()(wsgi_dispatch)
+     register()(xmlserver)
+     register()(jsonserver_kerb)
+     register()(jsonserver_session)
+     register()(login_kerberos)
++    register()(login_x509)
+     register()(login_password)
+     register()(change_password)
+     register()(sync_token)
+diff --git a/ipaserver/rpcserver.py b/ipaserver/rpcserver.py
+index d036f3c27521f17709672b830d5aa58167c76b34..e48dc3498d6ed8feb6ea44a9a678a8b8c50e8d9b 100644
+--- a/ipaserver/rpcserver.py
++++ b/ipaserver/rpcserver.py
+@@ -857,16 +857,16 @@ class jsonserver_kerb(jsonserver, KerberosWSGIExecutioner):
+     key = '/json'
+ 
+ 
+-class login_kerberos(Backend, KerberosSession, HTTP_Status):
+-    key = '/session/login_kerberos'
++class KerberosLogin(Backend, KerberosSession, HTTP_Status):
++    key = None
+ 
+     def _on_finalize(self):
+-        super(login_kerberos, self)._on_finalize()
++        super(KerberosLogin, self)._on_finalize()
+         self.api.Backend.wsgi_dispatch.mount(self, self.key)
+         self.kerb_session_on_finalize()
+ 
+     def __call__(self, environ, start_response):
+-        self.debug('WSGI login_kerberos.__call__:')
++        self.debug('WSGI KerberosLogin.__call__:')
+ 
+         # Get the ccache created by mod_auth_gssapi
+         user_ccache_name=environ.get('KRB5CCNAME')
+@@ -876,6 +876,15 @@ class login_kerberos(Backend, KerberosSession, HTTP_Status):
+ 
+         return self.finalize_kerberos_acquisition('login_kerberos', user_ccache_name, environ, start_response)
+ 
++
++class login_kerberos(KerberosLogin):
++    key = '/session/login_kerberos'
++
++
++class login_x509(KerberosLogin):
++    key = '/session/login_x509'
++
++
+ class login_password(Backend, KerberosSession, HTTP_Status):
+ 
+     content_type = 'text/plain'
+-- 
+2.7.4
+
diff --git a/SOURCES/0086-Backup-resore-authentication-control-configuration.patch b/SOURCES/0086-Backup-resore-authentication-control-configuration.patch
deleted file mode 100644
index f47ed94..0000000
--- a/SOURCES/0086-Backup-resore-authentication-control-configuration.patch
+++ /dev/null
@@ -1,115 +0,0 @@
-From fcd40cd3f47b15dae8c2e964e890b69906045f32 Mon Sep 17 00:00:00 2001
-From: David Kupka <dkupka@redhat.com>
-Date: Wed, 19 Aug 2015 08:10:03 +0200
-Subject: [PATCH] Backup/resore authentication control configuration
-
-https://fedorahosted.org/freeipa/ticket/5071
-
-Reviewed-By: Martin Babinsky <mbabinsk@redhat.com>
----
- ipaplatform/base/tasks.py        | 15 +++++++++++++++
- ipaplatform/redhat/authconfig.py |  6 ++++++
- ipaplatform/redhat/tasks.py      |  8 ++++++++
- ipaserver/install/ipa_backup.py  |  4 ++++
- ipaserver/install/ipa_restore.py |  4 ++++
- 5 files changed, 37 insertions(+)
-
-diff --git a/ipaplatform/base/tasks.py b/ipaplatform/base/tasks.py
-index 08fdb494a3bfc6c59bebf4af2f72f54a26724700..65715145af533c90038b3e8667da07fd28b7ec56 100644
---- a/ipaplatform/base/tasks.py
-+++ b/ipaplatform/base/tasks.py
-@@ -150,6 +150,21 @@ class BaseTaskNamespace(object):
- 
-         return
- 
-+    def backup_auth_configuration(self, path):
-+        """
-+        Create backup of access control configuration.
-+        :param path: store the backup here. This will be passed to
-+        restore_auth_configuration as well.
-+        """
-+        return
-+
-+    def restore_auth_configuration(self, path):
-+        """
-+        Restore backup of access control configuration.
-+        :param path: restore the backup from here.
-+        """
-+        return
-+
-     def set_selinux_booleans(self, required_settings, backup_func=None):
-         """Set the specified SELinux booleans
- 
-diff --git a/ipaplatform/redhat/authconfig.py b/ipaplatform/redhat/authconfig.py
-index 901eb51637d193d80bc3927929d7d436065ec262..edefee8b2b4922ad67cdbac158615ef32c776bb4 100644
---- a/ipaplatform/redhat/authconfig.py
-+++ b/ipaplatform/redhat/authconfig.py
-@@ -84,3 +84,9 @@ class RedHatAuthConfig(object):
- 
-         args = self.build_args()
-         ipautil.run(["/usr/sbin/authconfig"] + args)
-+
-+    def backup(self, path):
-+        ipautil.run(["/usr/sbin/authconfig", "--savebackup", path])
-+
-+    def restore(self, path):
-+        ipautil.run(["/usr/sbin/authconfig", "--restorebackup", path])
-diff --git a/ipaplatform/redhat/tasks.py b/ipaplatform/redhat/tasks.py
-index b26604aa736eb472c88bc0dcbc3a4b515712ce9d..1af99d318c6745b1e5285c7829c2b292f86c8390 100644
---- a/ipaplatform/redhat/tasks.py
-+++ b/ipaplatform/redhat/tasks.py
-@@ -161,6 +161,14 @@ class RedHatTaskNamespace(BaseTaskNamespace):
-         auth_config.add_option("nostart")
-         auth_config.execute()
- 
-+    def backup_auth_configuration(self, path):
-+        auth_config = RedHatAuthConfig()
-+        auth_config.backup(path)
-+
-+    def restore_auth_configuration(self, path):
-+        auth_config = RedHatAuthConfig()
-+        auth_config.restore(path)
-+
-     def reload_systemwide_ca_store(self):
-         try:
-             ipautil.run([paths.UPDATE_CA_TRUST])
-diff --git a/ipaserver/install/ipa_backup.py b/ipaserver/install/ipa_backup.py
-index d7afb3654b09e88321f1ce9f279749b19c2f6414..0ba44b280dfb7c9d9cbbe2470392c3c98ef35bcc 100644
---- a/ipaserver/install/ipa_backup.py
-+++ b/ipaserver/install/ipa_backup.py
-@@ -41,6 +41,7 @@ from ipapython import ipaldap
- from ipalib.session import ISO8601_DATETIME_FMT
- from ipalib.constants import CACERT
- from ConfigParser import SafeConfigParser
-+from ipaplatform.tasks import tasks
- 
- """
- A test gpg can be generated like this:
-@@ -302,6 +303,9 @@ class Backup(admintool.AdminTool):
-                     self.db2ldif(instance, 'userRoot', online=options.online)
-                     self.db2bak(instance, online=options.online)
-             if not options.data_only:
-+                # create backup of auth configuration
-+                auth_backup_path = os.path.join(paths.VAR_LIB_IPA, 'auth_backup')
-+                tasks.backup_auth_configuration(auth_backup_path)
-                 self.file_backup(options)
-             self.finalize_backup(options.data_only, options.gpg, options.gpg_keyring)
- 
-diff --git a/ipaserver/install/ipa_restore.py b/ipaserver/install/ipa_restore.py
-index 528a6daf0d4b6d3dfc69b6bbf8e8b05ad91ce02d..8960626d0f0e438ef198e2d92803983e520051a8 100644
---- a/ipaserver/install/ipa_restore.py
-+++ b/ipaserver/install/ipa_restore.py
-@@ -386,6 +386,10 @@ class Restore(admintool.AdminTool):
-                     self.log.info('Starting Directory Server')
-                     dirsrv.start(capture_output=False)
-             else:
-+                # restore access controll configuration
-+                auth_backup_path = os.path.join(paths.VAR_LIB_IPA, 'auth_backup')
-+                if os.path.exists(auth_backup_path):
-+                    tasks.restore_auth_configuration(auth_backup_path)
-                 # explicitly enable then disable the pki tomcatd service to
-                 # re-register its instance. FIXME, this is really wierd.
-                 services.knownservices.pki_tomcatd.enable()
--- 
-2.4.3
-
diff --git a/SOURCES/0087-Add-flag-to-list-all-service-and-user-vaults.patch b/SOURCES/0087-Add-flag-to-list-all-service-and-user-vaults.patch
deleted file mode 100644
index e70f3de..0000000
--- a/SOURCES/0087-Add-flag-to-list-all-service-and-user-vaults.patch
+++ /dev/null
@@ -1,179 +0,0 @@
-From 0fac76b07e7b15eb46e4db942d5c9890b704549d Mon Sep 17 00:00:00 2001
-From: Christian Heimes <cheimes@redhat.com>
-Date: Wed, 19 Aug 2015 13:32:01 +0200
-Subject: [PATCH] Add flag to list all service and user vaults
-
-The vault-find plugin has two additional arguments to list all
-service vaults or user vaults. Since the name of a vault is only unique
-for a particular user or service, the commands also print the vault user
-or vault service. The virtual attributes were added in rev
-01dd951ddc0181b559eb3dd5ff0336c81e245628.
-
-Example:
-
-$ ipa vault-find --users
-----------------
-2 vaults matched
-----------------
-  Vault name: myvault
-  Type: standard
-  Vault user: admin
-
-  Vault name: UserVault
-  Type: standard
-  Vault user: admin
-----------------------------
-Number of entries returned 2
-----------------------------
-
-$ ipa vault-find --services
-----------------
-2 vaults matched
-----------------
-  Vault name: myvault
-  Type: standard
-  Vault service: HTTP/ipatest.freeipa.local@FREEIPA.LOCAL
-
-  Vault name: myvault
-  Type: standard
-  Vault service: ldap/ipatest.freeipa.local@FREEIPA.LOCAL
-----------------------------
-Number of entries returned 2
-----------------------------
-
-https://fedorahosted.org/freeipa/ticket/5150
-
-Reviewed-By: Jan Cholasta <jcholast@redhat.com>
----
- API.txt                 |  4 +++-
- VERSION                 |  4 ++--
- ipalib/plugins/vault.py | 48 +++++++++++++++++++++++++++++++++---------------
- 3 files changed, 38 insertions(+), 18 deletions(-)
-
-diff --git a/API.txt b/API.txt
-index a39b22b602e0baf5d283732d18d83b2a25d5cf50..f23d9a40c647a3c4d209419631794cd36e8e5e2f 100644
---- a/API.txt
-+++ b/API.txt
-@@ -5508,7 +5508,7 @@ output: Output('result', <type 'dict'>, None)
- output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
- output: ListOfPrimaryKeys('value', None, None)
- command: vault_find
--args: 1,13,4
-+args: 1,15,4
- arg: Str('criteria?', noextrawhitespace=False)
- option: Flag('all', autofill=True, cli_name='all', default=False, exclude='webui')
- option: Str('cn', attribute=True, autofill=False, cli_name='name', maxlength=255, multivalue=False, pattern='^[a-zA-Z0-9_.-]+$', primary_key=True, query=True, required=False)
-@@ -5518,10 +5518,12 @@ option: Flag('no_members', autofill=True, default=False, exclude='webui')
- option: Flag('pkey_only?', autofill=True, default=False)
- option: Flag('raw', autofill=True, cli_name='raw', default=False, exclude='webui')
- option: Str('service?')
-+option: Flag('services?', autofill=True, default=False)
- option: Flag('shared?', autofill=True, default=False)
- option: Int('sizelimit?', autofill=False, minvalue=0)
- option: Int('timelimit?', autofill=False, minvalue=0)
- option: Str('username?', cli_name='user')
-+option: Flag('users?', autofill=True, default=False)
- option: Str('version?', exclude='webui')
- output: Output('count', <type 'int'>, None)
- output: ListOfEntries('result', (<type 'list'>, <type 'tuple'>), Gettext('A list of LDAP entries', domain='ipa', localedir=None))
-diff --git a/VERSION b/VERSION
-index 6569eeb70fa4e8065b5abb9dc89bd4cc6d42bd15..31a4af4a819415740e5c8db9259f934e13418cb5 100644
---- a/VERSION
-+++ b/VERSION
-@@ -90,5 +90,5 @@ IPA_DATA_VERSION=20100614120000
- #                                                      #
- ########################################################
- IPA_API_VERSION_MAJOR=2
--IPA_API_VERSION_MINOR=150
--# Last change: pvoborni - change type of vault type option to StrEnum
-+IPA_API_VERSION_MINOR=151
-+# Last change: cheimes - Add flag to list all service and user vaults
-diff --git a/ipalib/plugins/vault.py b/ipalib/plugins/vault.py
-index 712e2d5ddfa723eb84b80a261289a7cf1c75674f..83dc085b5aadb4e2878e29d17449f0808cc7a9c2 100644
---- a/ipalib/plugins/vault.py
-+++ b/ipalib/plugins/vault.py
-@@ -343,21 +343,11 @@ class vault(LDAPObject):
-         """
-         Generates vault DN from parameters.
-         """
--
-         service = options.get('service')
-         shared = options.get('shared')
-         user = options.get('username')
- 
--        count = 0
--        if service:
--            count += 1
--
--        if shared:
--            count += 1
--
--        if user:
--            count += 1
--
-+        count = (bool(service) + bool(shared) + bool(user))
-         if count > 1:
-             raise errors.MutuallyExclusiveError(
-                 reason=_('Service, shared, and user options ' +
-@@ -387,8 +377,10 @@ class vault(LDAPObject):
-             parent_dn = DN(('cn', service), ('cn', 'services'), container_dn)
-         elif shared:
-             parent_dn = DN(('cn', 'shared'), container_dn)
--        else:
-+        elif user:
-             parent_dn = DN(('cn', user), ('cn', 'users'), container_dn)
-+        else:
-+            raise RuntimeError
- 
-         return DN(rdns, parent_dn)
- 
-@@ -814,7 +806,16 @@ class vault_del(LDAPDelete):
- class vault_find(LDAPSearch):
-     __doc__ = _('Search for vaults.')
- 
--    takes_options = LDAPSearch.takes_options + vault_options
-+    takes_options = LDAPSearch.takes_options + vault_options + (
-+        Flag(
-+            'services?',
-+            doc=_('List all service vaults'),
-+        ),
-+        Flag(
-+            'users?',
-+            doc=_('List all user vaults'),
-+        ),
-+    )
- 
-     has_output_params = LDAPSearch.has_output_params
- 
-@@ -832,9 +833,26 @@ class vault_find(LDAPSearch):
-             raise errors.InvocationError(
-                 format=_('KRA service is not enabled'))
- 
--        base_dn = self.obj.get_dn(None, **options)
-+        if options.get('users') or options.get('services'):
-+            mutex = ['service', 'services', 'shared', 'username', 'users']
-+            count = sum(bool(options.get(option)) for option in mutex)
-+            if count > 1:
-+                raise errors.MutuallyExclusiveError(
-+                    reason=_('Service(s), shared, and user(s) options ' +
-+                             'cannot be specified simultaneously'))
-+
-+            scope = ldap.SCOPE_SUBTREE
-+            container_dn = DN(self.obj.container_dn,
-+                              self.api.env.basedn)
-+
-+            if options.get('services'):
-+                base_dn = DN(('cn', 'services'), container_dn)
-+            else:
-+                base_dn = DN(('cn', 'users'), container_dn)
-+        else:
-+            base_dn = self.obj.get_dn(None, **options)
- 
--        return (filter, base_dn, scope)
-+        return filter, base_dn, scope
- 
-     def post_callback(self, ldap, entries, truncated, *args, **options):
-         for entry in entries:
--- 
-2.4.3
-
diff --git a/SOURCES/0087-schema-cache-Fallback-to-en_us-when-locale-is-not-av.patch b/SOURCES/0087-schema-cache-Fallback-to-en_us-when-locale-is-not-av.patch
new file mode 100644
index 0000000..0d7d637
--- /dev/null
+++ b/SOURCES/0087-schema-cache-Fallback-to-en_us-when-locale-is-not-av.patch
@@ -0,0 +1,39 @@
+From 444907f8dd6d840bfbb97cf65ae754f0d816f706 Mon Sep 17 00:00:00 2001
+From: David Kupka <dkupka@redhat.com>
+Date: Thu, 18 Aug 2016 10:59:09 +0200
+Subject: [PATCH] schema cache: Fallback to 'en_us' when locale is not
+ available
+
+https://fedorahosted.org/freeipa/ticket/6204
+
+Reviewed-By: Jan Cholasta <jcholast@redhat.com>
+---
+ ipaclient/remote_plugins/schema.py | 12 +++++++++---
+ 1 file changed, 9 insertions(+), 3 deletions(-)
+
+diff --git a/ipaclient/remote_plugins/schema.py b/ipaclient/remote_plugins/schema.py
+index 6fc70bf4b294badedd651e15b7e403cc40619f5c..8a77a15d489f067ab1312e863178458570403cc6 100644
+--- a/ipaclient/remote_plugins/schema.py
++++ b/ipaclient/remote_plugins/schema.py
+@@ -441,9 +441,15 @@ class Schema(object):
+             self._dict[ns] = {}
+             self._namespaces[ns] = _SchemaNameSpace(self, ns)
+ 
+-        self._language = (
+-            locale.setlocale(locale.LC_ALL, '').split('.')[0].lower()
+-        )
++        # copy-paste from ipalib/rpc.py
++        try:
++            self._language = (
++                locale.setlocale(locale.LC_ALL, '').split('.')[0].lower()
++            )
++        except locale.Error:
++            # fallback to default locale
++            self._language = 'en_us'
++
+         try:
+             self._fingerprint = server_info['fingerprint']
+             self._expiration = server_info['expiration']
+-- 
+2.7.4
+
diff --git a/SOURCES/0088-Add-user-stage-command.patch b/SOURCES/0088-Add-user-stage-command.patch
deleted file mode 100644
index 7de1560..0000000
--- a/SOURCES/0088-Add-user-stage-command.patch
+++ /dev/null
@@ -1,205 +0,0 @@
-From d5e7ef94033660aed43edb0f2dc4e1eb096579aa Mon Sep 17 00:00:00 2001
-From: Martin Basti <mbasti@redhat.com>
-Date: Mon, 17 Aug 2015 20:11:21 +0200
-Subject: [PATCH] Add user-stage command
-
-This patch replaces 'stageuser-add --from-delete' with new command
-user-stage.
-
-Original way always required  to specify first and last name, and
-overall combination of options was hard to manage. The new command
-requires only login of deleted user (user-del --preserve).
-
-https://fedorahosted.org/freeipa/ticket/5041
-
-Reviewed-By: Thierry Bordaz <tbordaz@redhat.com>
-Reviewed-By: Jan Cholasta <jcholast@redhat.com>
----
- API.txt                     | 10 ++++++++-
- VERSION                     |  4 ++--
- ipalib/plugins/stageuser.py | 44 +++++++-------------------------------
- ipalib/plugins/user.py      | 51 +++++++++++++++++++++++++++++++++++++++++++++
- 4 files changed, 70 insertions(+), 39 deletions(-)
-
-diff --git a/API.txt b/API.txt
-index f23d9a40c647a3c4d209419631794cd36e8e5e2f..b0f456e725a6c3d24c1071b282de5a28c3b5a671 100644
---- a/API.txt
-+++ b/API.txt
-@@ -4211,7 +4211,7 @@ option: Str('displayname', attribute=True, autofill=True, cli_name='displayname'
- option: Str('employeenumber', attribute=True, cli_name='employeenumber', multivalue=False, required=False)
- option: Str('employeetype', attribute=True, cli_name='employeetype', multivalue=False, required=False)
- option: Str('facsimiletelephonenumber', attribute=True, cli_name='fax', multivalue=True, required=False)
--option: Flag('from_delete?', autofill=True, cli_name='from_delete', default=False)
-+option: DeprecatedParam('from_delete?', cli_name='from_delete', default=False)
- option: Str('gecos', attribute=True, autofill=True, cli_name='gecos', multivalue=False, required=False)
- option: Int('gidnumber', attribute=True, cli_name='gidnumber', minvalue=1, multivalue=False, required=False)
- option: Str('givenname', attribute=True, cli_name='first', multivalue=False, required=True)
-@@ -5371,6 +5371,14 @@ option: Str('version?', exclude='webui')
- output: Entry('result', <type 'dict'>, Gettext('A dictionary representing an LDAP entry', domain='ipa', localedir=None))
- output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
- output: PrimaryKey('value', None, None)
-+command: user_stage
-+args: 1,2,3
-+arg: Str('uid', attribute=True, cli_name='login', maxlength=255, multivalue=True, pattern='^[a-zA-Z0-9_.][a-zA-Z0-9_.-]{0,252}[a-zA-Z0-9_.$-]?$', primary_key=True, query=True, required=True)
-+option: Flag('continue', autofill=True, cli_name='continue', default=False)
-+option: Str('version?', exclude='webui')
-+output: Output('result', <type 'dict'>, None)
-+output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
-+output: ListOfPrimaryKeys('value', None, None)
- command: user_status
- args: 1,4,4
- arg: Str('uid', attribute=True, cli_name='login', maxlength=255, multivalue=False, pattern='^[a-zA-Z0-9_.][a-zA-Z0-9_.-]{0,252}[a-zA-Z0-9_.$-]?$', primary_key=True, query=True, required=True)
-diff --git a/VERSION b/VERSION
-index 31a4af4a819415740e5c8db9259f934e13418cb5..9fe2f4d4f9ff6ffd42c2ee7493c385b0a432a6a0 100644
---- a/VERSION
-+++ b/VERSION
-@@ -90,5 +90,5 @@ IPA_DATA_VERSION=20100614120000
- #                                                      #
- ########################################################
- IPA_API_VERSION_MAJOR=2
--IPA_API_VERSION_MINOR=151
--# Last change: cheimes - Add flag to list all service and user vaults
-+IPA_API_VERSION_MINOR=152
-+# Last change: mbasti - add 'user-stage' command
-diff --git a/ipalib/plugins/stageuser.py b/ipalib/plugins/stageuser.py
-index 41844712042c4456fc515afd316af60b612f164f..b6d98005314ab671af345aacb2e3c9f08193e155 100644
---- a/ipalib/plugins/stageuser.py
-+++ b/ipalib/plugins/stageuser.py
-@@ -23,7 +23,8 @@ import posixpath
- import os
- from copy import deepcopy
- from ipalib import api, errors
--from ipalib import Flag, Int, Password, Str, Bool, StrEnum, DateTime
-+from ipalib import (Flag, Int, Password, Str, Bool, StrEnum, DateTime,
-+                    DeprecatedParam)
- from ipalib.plugable import Registry
- from ipalib.plugins.baseldap import LDAPCreate, LDAPQuery, LDAPSearch, DN, entry_to_dict, pkey_to_value
- from ipalib.plugins import baseldap
-@@ -260,7 +261,7 @@ class stageuser_add(baseuser_add):
-     has_output_params = baseuser_add.has_output_params + stageuser_output_params
- 
-     takes_options = LDAPCreate.takes_options + (
--        Flag('from_delete?',
-+        DeprecatedParam('from_delete?',
-             doc=_('Create Stage user in from a delete user'),
-             cli_name='from_delete',
-             default=False,
-@@ -270,13 +271,12 @@ class stageuser_add(baseuser_add):
-     def pre_callback(self, ldap, dn, entry_attrs, attrs_list, *keys, **options):
-         assert isinstance(dn, DN)
- 
--        if not options.get('from_delete'):
--            # then givenname and sn are required attributes
--            if 'givenname' not in entry_attrs:
--                raise errors.RequirementError(name='givenname', error=_('givenname is required'))
-+        # then givenname and sn are required attributes
-+        if 'givenname' not in entry_attrs:
-+            raise errors.RequirementError(name='givenname', error=_('givenname is required'))
- 
--            if 'sn' not in entry_attrs:
--                raise errors.RequirementError(name='sn', error=_('sn is required'))
-+        if 'sn' not in entry_attrs:
-+            raise errors.RequirementError(name='sn', error=_('sn is required'))
- 
-         # we don't want an user private group to be created for this user
-         # add NO_UPG_MAGIC description attribute to let the DS plugin know
-@@ -367,34 +367,6 @@ class stageuser_add(baseuser_add):
- 
-         return dn
- 
--    def execute(self, *keys, **options):
--        '''
--        A stage entry may be taken from the Delete container.
--        In that case we rather do 'MODRDN' than 'ADD'.
--        '''
--        if options.get('from_delete'):
--            ldap = self.obj.backend
--
--            staging_dn = self.obj.get_dn(*keys, **options)
--            delete_dn = DN(staging_dn[0], self.obj.delete_container_dn, api.env.basedn)
--            new_dn = DN(staging_dn[0], self.obj.stage_container_dn, api.env.basedn)
--            # Check that this value is a Active user
--            try:
--                entry_attrs = self._exc_wrapper(keys, options, ldap.get_entry)(delete_dn, ['dn'])
--            except errors.NotFound:
--                self.obj.handle_not_found(*keys)
--
--            self._exc_wrapper(keys, options, ldap.move_entry)(
--                delete_dn, new_dn)
--            entry_attrs = entry_to_dict(entry_attrs, **options)
--            entry_attrs['dn'] = new_dn
--
--            if self.obj.primary_key and keys[-1] is not None:
--                return dict(result=entry_attrs, value=keys[-1])
--            return dict(result=entry_attrs, value=u'')
--        else:
--            return super(stageuser_add, self).execute(*keys, **options)
--
-     def post_callback(self, ldap, dn, entry_attrs, *keys, **options):
-         assert isinstance(dn, DN)
-         config = ldap.get_ipa_config()
-diff --git a/ipalib/plugins/user.py b/ipalib/plugins/user.py
-index 418c51bdafc4e462e2decfe1e8541aaf49705cb0..d7cf9666d43b69b0cab91cfa0c98a8373f095ab5 100644
---- a/ipalib/plugins/user.py
-+++ b/ipalib/plugins/user.py
-@@ -859,6 +859,57 @@ class user_undel(LDAPQuery):
-             value=pkey_to_value(keys[0], options),
-         )
- 
-+
-+@register()
-+class user_stage(LDAPMultiQuery):
-+    __doc__ = _('Move deleted user into staged area')
-+
-+    has_output = output.standard_multi_delete
-+    msg_summary = _('Staged user account "%(value)s"')
-+
-+    def execute(self, *keys, **options):
-+        staged = []
-+        failed = []
-+
-+        for key in keys[-1]:
-+            single_keys = keys[:-1] + (key,)
-+            multi_keys = keys[:-1] + ((key,),)
-+
-+            user = self.api.Command.user_show(*single_keys, all=True)['result']
-+            new_options = {}
-+            for param in self.api.Command.stageuser_add.options():
-+                try:
-+                    value = user[param.name]
-+                except KeyError:
-+                    continue
-+                if param.multivalue and not isinstance(value, (list, tuple)):
-+                    value = [value]
-+                elif not param.multivalue and isinstance(value, (list, tuple)):
-+                    value = value[0]
-+                new_options[param.name] = value
-+
-+            try:
-+                self.api.Command.stageuser_add(*single_keys, **new_options)
-+                try:
-+                    self.api.Command.user_del(*multi_keys, preserve=False)
-+                except errors.ExecutionError:
-+                    self.api.Command.stageuser_del(*multi_keys)
-+                    raise
-+            except errors.ExecutionError:
-+                if not options['continue']:
-+                    raise
-+                failed.append(key)
-+            else:
-+                staged.append(key)
-+
-+        return dict(
-+            result=dict(
-+                failed=pkey_to_value(failed, options),
-+            ),
-+            value=pkey_to_value(staged, options),
-+        )
-+
-+
- @register()
- class user_disable(LDAPQuery):
-     __doc__ = _('Disable a user account.')
--- 
-2.4.3
-
diff --git a/SOURCES/0088-cert-revoke-fix-permission-check-bypass-CVE-2016-540.patch b/SOURCES/0088-cert-revoke-fix-permission-check-bypass-CVE-2016-540.patch
new file mode 100644
index 0000000..7876cbf
--- /dev/null
+++ b/SOURCES/0088-cert-revoke-fix-permission-check-bypass-CVE-2016-540.patch
@@ -0,0 +1,132 @@
+From 18d4af260f777920dc2b474a588c3dcda20d8801 Mon Sep 17 00:00:00 2001
+From: Fraser Tweedale <ftweedal@redhat.com>
+Date: Thu, 30 Jun 2016 10:21:01 +1000
+Subject: [PATCH] cert-revoke: fix permission check bypass (CVE-2016-5404)
+
+The 'cert_revoke' command checks the 'revoke certificate'
+permission, however, if an ACIError is raised, it then invokes the
+'cert_show' command.  The rational was to re-use a "host manages
+certificate" check that is part of the 'cert_show' command, however,
+it is sufficient that 'cert_show' executes successfully for
+'cert_revoke' to recover from the ACIError continue.  Therefore,
+anyone with 'retrieve certificate' permission can revoke *any*
+certificate and cause various kinds of DoS.
+
+Fix the problem by extracting the "host manages certificate" check
+to its own method and explicitly calling it from 'cert_revoke'.
+
+Fixes: https://fedorahosted.org/freeipa/ticket/6232
+Reviewed-By: Jan Cholasta <jcholast@redhat.com>
+---
+ ipaserver/plugins/cert.py | 60 +++++++++++++++++++++++++----------------------
+ 1 file changed, 32 insertions(+), 28 deletions(-)
+
+diff --git a/ipaserver/plugins/cert.py b/ipaserver/plugins/cert.py
+index b8df074a186ca91daa8e8f5e725724ea7bc5a663..6dd9f6ffcdcd9d051d50d912996fea2104d71dff 100644
+--- a/ipaserver/plugins/cert.py
++++ b/ipaserver/plugins/cert.py
+@@ -242,6 +242,24 @@ def validate_certificate(value):
+     return x509.validate_certificate(value, x509.DER)
+ 
+ 
++def bind_principal_can_manage_cert(cert):
++    """Check that the bind principal can manage the given cert.
++
++    ``cert``
++        An NSS certificate object.
++
++    """
++    bind_principal = kerberos.Principal(getattr(context, 'principal'))
++    if not bind_principal.is_host:
++        return False
++
++    hostname = bind_principal.hostname
++
++    # If we have a hostname we want to verify that the subject
++    # of the certificate matches it.
++    return hostname == cert.subject.common_name  #pylint: disable=E1101
++
++
+ class BaseCertObject(Object):
+     takes_params = (
+         Bytes(
+@@ -744,18 +762,6 @@ class cert_show(Retrieve, CertMethod, VirtualCommand):
+     def execute(self, serial_number, all=False, raw=False, no_members=False,
+                 **options):
+         ca_enabled_check()
+-        hostname = None
+-        try:
+-            self.check_access()
+-        except errors.ACIError as acierr:
+-            self.debug("Not granted by ACI to retrieve certificate, looking at principal")
+-            bind_principal = kerberos.Principal(getattr(context, 'principal'))
+-            if not bind_principal.is_host:
+-                raise acierr
+-            hostname = bind_principal.hostname
+-
+-        ca_obj = api.Command.ca_show(options['cacn'])['result']
+-        issuer_dn = ca_obj['ipacasubjectdn'][0]
+ 
+         # Dogtag lightweight CAs have shared serial number domain, so
+         # we don't tell Dogtag the issuer (but we check the cert after).
+@@ -763,7 +769,15 @@ class cert_show(Retrieve, CertMethod, VirtualCommand):
+         result = self.Backend.ra.get_certificate(str(serial_number))
+         cert = x509.load_certificate(result['certificate'])
+ 
+-        if DN(unicode(cert.issuer)) != DN(issuer_dn):
++        try:
++            self.check_access()
++        except errors.ACIError as acierr:
++            self.debug("Not granted by ACI to retrieve certificate, looking at principal")
++            if not bind_principal_can_manage_cert(cert):
++                raise acierr  # pylint: disable=E0702
++
++        ca_obj = api.Command.ca_show(options['cacn'])['result']
++        if DN(unicode(cert.issuer)) != DN(ca_obj['ipacasubjectdn'][0]):
+             # DN of cert differs from what we requested
+             raise errors.NotFound(
+                 reason=_("Certificate with serial number %(serial)s "
+@@ -789,12 +803,6 @@ class cert_show(Retrieve, CertMethod, VirtualCommand):
+             result['revoked'] = ('revocation_reason' in result)
+             self.obj._fill_owners(result)
+ 
+-        if hostname:
+-            # If we have a hostname we want to verify that the subject
+-            # of the certificate matches it, otherwise raise an error
+-            if hostname != cert.subject.common_name:    #pylint: disable=E1101
+-                raise acierr
+-
+         return dict(result=result, value=pkey_to_value(serial_number, options))
+ 
+ 
+@@ -819,22 +827,18 @@ class cert_revoke(PKQuery, CertMethod, VirtualCommand):
+ 
+         # Make sure that the cert specified by issuer+serial exists.
+         # Will raise NotFound if it does not.
+-        cert_show_options = dict(cacn=kw['cacn'])
+-        api.Command.cert_show(unicode(serial_number), **cert_show_options)
++        resp = api.Command.cert_show(unicode(serial_number), cacn=kw['cacn'])
+ 
+-        hostname = None
+         try:
+             self.check_access()
+         except errors.ACIError as acierr:
+             self.debug("Not granted by ACI to revoke certificate, looking at principal")
+             try:
+-                # Let cert_show() handle verifying that the subject of the
+-                # cert we're dealing with matches the hostname in the principal
+-                result = api.Command['cert_show'](
+-                    unicode(serial_number), **cert_show_options
+-                )['result']
++                cert = x509.load_certificate(resp['result']['certificate'])
++                if not bind_principal_can_manage_cert(cert):
++                    raise acierr
+             except errors.NotImplementedError:
+-                pass
++                raise acierr
+         revocation_reason = kw['revocation_reason']
+         if revocation_reason == 7:
+             raise errors.CertificateOperationError(error=_('7 is not a valid revocation reason'))
+-- 
+2.9.3
+
diff --git a/SOURCES/0089-Fix-container-owner-should-be-able-to-add-vault.patch b/SOURCES/0089-Fix-container-owner-should-be-able-to-add-vault.patch
new file mode 100644
index 0000000..03c7269
--- /dev/null
+++ b/SOURCES/0089-Fix-container-owner-should-be-able-to-add-vault.patch
@@ -0,0 +1,34 @@
+From d3e11b06bbb996b1605f15912be106dcf47b357a Mon Sep 17 00:00:00 2001
+From: Martin Basti <mbasti@redhat.com>
+Date: Thu, 18 Aug 2016 10:11:25 +0200
+Subject: [PATCH] Fix: container owner should be able to add vault
+
+With recent change in DS (CVE fix), ds is not returging DuplicatedEntry
+error in case that user is not permitted by ACI to write, but ACIError instead.
+
+Is safe to ignore ACI error in container, because it will be raised
+again later if user has no access to container.
+
+https://fedorahosted.org/freeipa/ticket/6159
+
+Reviewed-By: Martin Basti <mbasti@redhat.com>
+---
+ ipaserver/plugins/vault.py | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/ipaserver/plugins/vault.py b/ipaserver/plugins/vault.py
+index c9b7cb942cfbca74134bce4ba039619b4f5f2845..5c4c09685ceb95c6634306c4275008d602099e12 100644
+--- a/ipaserver/plugins/vault.py
++++ b/ipaserver/plugins/vault.py
+@@ -783,7 +783,7 @@ class vault_add_internal(LDAPCreate):
+ 
+         try:
+             self.obj.create_container(parent_dn, owner_dn)
+-        except errors.DuplicateEntry as e:
++        except (errors.DuplicateEntry, errors.ACIError):
+             pass
+ 
+         # vault should be owned by the creator
+-- 
+2.7.4
+
diff --git a/SOURCES/0089-trusts-format-Kerberos-principal-properly-when-fetch.patch b/SOURCES/0089-trusts-format-Kerberos-principal-properly-when-fetch.patch
deleted file mode 100644
index bf4caea..0000000
--- a/SOURCES/0089-trusts-format-Kerberos-principal-properly-when-fetch.patch
+++ /dev/null
@@ -1,46 +0,0 @@
-From e9fdf223cdb39e685ad9c57a7348016917d5cba2 Mon Sep 17 00:00:00 2001
-From: Alexander Bokovoy <abokovoy@redhat.com>
-Date: Thu, 20 Aug 2015 15:12:42 +0300
-Subject: [PATCH] trusts: format Kerberos principal properly when fetching
- trust topology
-
-For bidirectional trust if we have AD administrator credentials, we
-should be using them with Kerberos authentication. If we don't have
-AD administrator credentials, we should be using
-HTTP/ipa.master@IPA.REALM credentials. This means we should ask
-formatting 'creds' object in Kerberos style.
-
-For one-way trust we'll be fetching trust topology as TDO object,
-authenticating with pre-created Kerberos credentials cache, so in all
-cases we do use Kerberos authentication to talk to Active Directory
-domain controllers over cross-forest trust link.
-
-Part of trust refactoring series.
-Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1250190
-Fixes: https://fedorahosted.org/freeipa/ticket/5182
-Reviewed-By: Tomas Babej <tbabej@redhat.com>
----
- ipalib/plugins/trust.py | 7 ++++++-
- 1 file changed, 6 insertions(+), 1 deletion(-)
-
-diff --git a/ipalib/plugins/trust.py b/ipalib/plugins/trust.py
-index c7546692bdd8dd827ee9772b72a758042d97aa71..173463ae7d4134b5bd155cc5fa920bfabd0a6958 100644
---- a/ipalib/plugins/trust.py
-+++ b/ipalib/plugins/trust.py
-@@ -1479,7 +1479,12 @@ class trustdomain_del(LDAPDelete):
- 
- def fetch_domains_from_trust(myapi, trustinstance, trust_entry, **options):
-     trust_name = trust_entry['cn'][0]
--    creds = generate_creds(trustinstance, style=CRED_STYLE_SAMBA, **options)
-+    # 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.
-+    creds = generate_creds(trustinstance, style=CRED_STYLE_KERBEROS, **options)
-     server = options.get('realm_server', None)
-     domains = ipaserver.dcerpc.fetch_domains(myapi,
-                                              trustinstance.local_flatname,
--- 
-2.4.3
-
diff --git a/SOURCES/0090-Change-internal-rsa_-public-private-_key-variable-na.patch b/SOURCES/0090-Change-internal-rsa_-public-private-_key-variable-na.patch
deleted file mode 100644
index 0232220..0000000
--- a/SOURCES/0090-Change-internal-rsa_-public-private-_key-variable-na.patch
+++ /dev/null
@@ -1,52 +0,0 @@
-From 6031fed29f3e81450b48b73eba0f9e716efcb73f Mon Sep 17 00:00:00 2001
-From: Christian Heimes <cheimes@redhat.com>
-Date: Tue, 28 Jul 2015 16:12:40 +0200
-Subject: [PATCH] Change internal rsa_(public|private)_key variable names
-
-In two places the vault plugin refers to rsa public or rsa private key
-although the code can handle just any kind of asymmetric algorithms,
-e.g. ECDSA. The patch just renames the occurences to avoid more
-confusion in the future.
-
-Reviewed-By: Simo Sorce <ssorce@redhat.com>
-Reviewed-By: Martin Basti <mbasti@redhat.com>
----
- ipalib/plugins/vault.py | 8 ++++----
- 1 file changed, 4 insertions(+), 4 deletions(-)
-
-diff --git a/ipalib/plugins/vault.py b/ipalib/plugins/vault.py
-index 83dc085b5aadb4e2878e29d17449f0808cc7a9c2..4b2c8a518e5c9a93e5490841a3d2177536c905b1 100644
---- a/ipalib/plugins/vault.py
-+++ b/ipalib/plugins/vault.py
-@@ -486,11 +486,11 @@ class vault(LDAPObject):
-             return fernet.encrypt(data)
- 
-         elif public_key:
--            rsa_public_key = load_pem_public_key(
-+            public_key_obj = load_pem_public_key(
-                 data=public_key,
-                 backend=default_backend()
-             )
--            return rsa_public_key.encrypt(
-+            return public_key_obj.encrypt(
-                 data,
-                 padding.OAEP(
-                     mgf=padding.MGF1(algorithm=hashes.SHA1()),
-@@ -513,12 +513,12 @@ class vault(LDAPObject):
- 
-         elif private_key:
-             try:
--                rsa_private_key = load_pem_private_key(
-+                private_key_obj = load_pem_private_key(
-                     data=private_key,
-                     password=None,
-                     backend=default_backend()
-                 )
--                return rsa_private_key.decrypt(
-+                return private_key_obj.decrypt(
-                     data,
-                     padding.OAEP(
-                         mgf=padding.MGF1(algorithm=hashes.SHA1()),
--- 
-2.4.3
-
diff --git a/SOURCES/0090-ipaserver-dcerpc-reformat-to-make-the-code-closer-to.patch b/SOURCES/0090-ipaserver-dcerpc-reformat-to-make-the-code-closer-to.patch
new file mode 100644
index 0000000..f4bc1d9
--- /dev/null
+++ b/SOURCES/0090-ipaserver-dcerpc-reformat-to-make-the-code-closer-to.patch
@@ -0,0 +1,1005 @@
+From a9a73b0e0b601767324d5b6747b6ba46b6e5e90f Mon Sep 17 00:00:00 2001
+From: Alexander Bokovoy <abokovoy@redhat.com>
+Date: Tue, 7 Jun 2016 22:41:10 +0300
+Subject: [PATCH] ipaserver/dcerpc: reformat to make the code closer to pep8
+
+Because Samba Python bindings provide long-named methods and constants,
+sometimes it is impossible to fit into 80 columns without causing
+damage to readability of the code. This patchset attempts to reduce
+pep8 complaints to a minimum.
+
+https://fedorahosted.org/freeipa/ticket/6076
+
+Reviewed-By: Martin Babinsky <mbabinsk@redhat.com>
+---
+ ipaserver/dcerpc.py | 473 +++++++++++++++++++++++++++++++++-------------------
+ 1 file changed, 298 insertions(+), 175 deletions(-)
+
+diff --git a/ipaserver/dcerpc.py b/ipaserver/dcerpc.py
+index 21ac89dfd71271ed384b875f95054d7ad1c0556d..19be6bf7a3617a3b867d51a9358c9926e91049a7 100644
+--- a/ipaserver/dcerpc.py
++++ b/ipaserver/dcerpc.py
+@@ -44,10 +44,12 @@ import samba
+ import random
+ from cryptography.hazmat.primitives.ciphers import Cipher, algorithms
+ from cryptography.hazmat.backends import default_backend
++# pylint: disable=F0401
+ try:
+-    from ldap.controls import RequestControl as LDAPControl #pylint: disable=F0401
++    from ldap.controls import RequestControl as LDAPControl
+ except ImportError:
+-    from ldap.controls import LDAPControl as LDAPControl    #pylint: disable=F0401
++    from ldap.controls import LDAPControl as LDAPControl
++# pylint: enable=F0401
+ import ldap as _ldap
+ from ipapython.ipaldap import IPAdmin
+ from ipaserver.session import krbccache_dir, krbccache_prefix
+@@ -74,7 +76,7 @@ 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_ONEWAY = 1
+ TRUST_BIDIRECTIONAL = 3
+ 
+ # Trust join behavior
+@@ -91,31 +93,44 @@ def is_sid_valid(sid):
+         return True
+ 
+ 
+-access_denied_error =  errors.ACIError(info=_('CIFS server denied your credentials'))
++access_denied_error = errors.ACIError(
++                          info=_('CIFS server denied your credentials'))
+ dcerpc_error_codes = {
+     -1073741823:
+-        errors.RemoteRetrieveError(reason=_('communication with CIFS server was unsuccessful')),
++        errors.RemoteRetrieveError(
++            reason=_('communication with CIFS server was unsuccessful')),
+     -1073741790: access_denied_error,
+     -1073741715: access_denied_error,
+     -1073741614: access_denied_error,
+     -1073741603:
+-        errors.ValidationError(name=_('AD domain controller'), error=_('unsupported functional level')),
+-    -1073741811: # NT_STATUS_INVALID_PARAMETER
++        errors.ValidationError(
++            name=_('AD domain controller'),
++            error=_('unsupported functional level')),
++    -1073741811:  # NT_STATUS_INVALID_PARAMETER
+         errors.RemoteRetrieveError(
+-            reason=_('AD domain controller complains about communication sequence. It may mean unsynchronized time on both sides, for example')),
+-    -1073741776: # NT_STATUS_INVALID_PARAMETER_MIX, we simply will skip the binding
++            reason=_('AD domain controller complains about communication '
++                     'sequence. It may mean unsynchronized time on both '
++                     'sides, for example')),
++    -1073741776:  # NT_STATUS_INVALID_PARAMETER_MIX,
++                  # 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')),
++    -1073741772:  # NT_STATUS_OBJECT_NAME_NOT_FOUND
++        errors.RemoteRetrieveError(
++            reason=_('CIFS server configuration does not allow '
++                     'access to \\\\pipe\\lsarpc')),
+ }
+ 
+ dcerpc_error_messages = {
+     "NT_STATUS_OBJECT_NAME_NOT_FOUND":
+-         errors.NotFound(reason=_('Cannot find specified domain or server name')),
++        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')),
++        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')),
++        errors.RequirementError(
++            name=_('At least the domain or IP address should be specified')),
+ }
+ 
+ pysss_type_key_translation_dict = {
+@@ -126,7 +141,7 @@ pysss_type_key_translation_dict = {
+ }
+ 
+ 
+-def assess_dcerpc_exception(num=None,message=None):
++def assess_dcerpc_exception(num=None, message=None):
+     """
+     Takes error returned by Samba bindings and converts it into
+     an IPA error class.
+@@ -135,8 +150,9 @@ def assess_dcerpc_exception(num=None,message=None):
+         return dcerpc_error_codes[num]
+     if message and message in dcerpc_error_messages:
+         return dcerpc_error_messages[message]
+-    reason = _('''CIFS server communication error: code "%(num)s",
+-                  message "%(message)s" (both may be "None")''') % dict(num=num, message=message)
++    reason = _('CIFS server communication error: code "%(num)s", '
++               'message "%(message)s" (both may be "None")') % \
++        dict(num=num, message=message)
+     return errors.RemoteRetrieveError(reason=reason)
+ 
+ 
+@@ -182,9 +198,13 @@ class DomainValidator(object):
+         self._parm = None
+ 
+     def is_configured(self):
+-        cn_trust_local = DN(('cn', self.api.env.domain), self.api.env.container_cifsdomains, self.api.env.basedn)
++        cn_trust_local = DN(('cn', self.api.env.domain),
++                            self.api.env.container_cifsdomains,
++                            self.api.env.basedn)
+         try:
+-            entry_attrs = self.ldap.get_entry(cn_trust_local, [self.ATTR_FLATNAME, self.ATTR_SID])
++            entry_attrs = self.ldap.get_entry(cn_trust_local,
++                                              [self.ATTR_FLATNAME,
++                                               self.ATTR_SID])
+             self.flatname = entry_attrs[self.ATTR_FLATNAME][0]
+             self.sid = entry_attrs[self.ATTR_SID][0]
+             self.dn = entry_attrs.dn
+@@ -203,7 +223,8 @@ class DomainValidator(object):
+ 
+         try:
+             search_kw = {'objectClass': 'ipaNTTrustedDomain'}
+-            filter = self.ldap.make_filter(search_kw, rules=self.ldap.MATCH_ALL)
++            filter = self.ldap.make_filter(search_kw,
++                                           rules=self.ldap.MATCH_ALL)
+             (entries, truncated) = self.ldap.find_entries(
+                 filter=filter,
+                 base_dn=cn_trust,
+@@ -216,22 +237,22 @@ class DomainValidator(object):
+             # domain names as keys and those are generally case-insensitive
+             result = ipautil.CIDict()
+ 
+-            for entry in entries:
++            for e in entries:
+                 try:
+-                    trust_partner = entry[self.ATTR_TRUST_PARTNER][0]
+-                    flatname_normalized = entry[self.ATTR_FLATNAME][0].lower()
+-                    trusted_sid = entry[self.ATTR_TRUSTED_SID][0]
+-                except KeyError as e:
++                    t_partner = e.single_value.get(self.ATTR_TRUST_PARTNER)
++                    fname_norm = e.single_value.get(self.ATTR_FLATNAME).lower()
++                    trusted_sid = e.single_value.get(self.ATTR_TRUSTED_SID)
++                except KeyError as exc:
+                     # Some piece of trusted domain info in LDAP is missing
+                     # Skip the domain, but leave log entry for investigation
+                     api.log.warning("Trusted domain '%s' entry misses an "
+-                                 "attribute: %s", entry.dn, e)
++                                    "attribute: %s", e.dn, exc)
+                     continue
+ 
+-                result[trust_partner] = (flatname_normalized,
+-                                         security.dom_sid(trusted_sid))
++                result[t_partner] = (fname_norm,
++                                     security.dom_sid(trusted_sid))
+             return result
+-        except errors.NotFound as e:
++        except errors.NotFound as exc:
+             return []
+ 
+     def set_trusted_domains(self):
+@@ -244,21 +265,22 @@ class DomainValidator(object):
+             # This means we can't check the correctness of a trusted
+             # domain SIDs
+             raise errors.ValidationError(name='sid',
+-                  error=_('no trusted domain is configured'))
++                                         error=_('no trusted domain '
++                                                 'is configured'))
+ 
+     def get_domain_by_sid(self, sid, exact_match=False):
+         if not self.domain:
+             # our domain is not configured or self.is_configured() never run
+             # reject SIDs as we can't check correctness of them
+             raise errors.ValidationError(name='sid',
+-                  error=_('domain is not configured'))
++                                         error=_('domain is not configured'))
+ 
+         # Parse sid string to see if it is really in a SID format
+         try:
+             test_sid = security.dom_sid(sid)
+         except TypeError:
+             raise errors.ValidationError(name='sid',
+-                  error=_('SID is not valid'))
++                                         error=_('SID is not valid'))
+ 
+         # At this point we have SID_NT_AUTHORITY family SID and really need to
+         # check it against prefixes of domain SIDs we trust to
+@@ -314,30 +336,34 @@ class DomainValidator(object):
+             return None
+ 
+     def get_trusted_domain_objects(self, domain=None, flatname=None, filter="",
+-            attrs=None, scope=_ldap.SCOPE_SUBTREE, basedn=None):
++                                   attrs=None, scope=_ldap.SCOPE_SUBTREE,
++                                   basedn=None):
+         """
+-        Search for LDAP objects in a trusted domain specified either by `domain'
+-        or `flatname'. The actual LDAP search is specified by `filter', `attrs',
+-        `scope' and `basedn'. When `basedn' is empty, database root DN is used.
++        Search for LDAP objects in a trusted domain specified either by
++        `domain' or `flatname'. The actual LDAP search is specified by
++        `filter', `attrs', `scope' and `basedn'. When `basedn' is empty,
++        database root DN is used.
+         """
+         assert domain is not None or flatname is not None
+         """Returns SID for the trusted domain object (user or group only)"""
+         if not self.domain:
+             # our domain is not configured or self.is_configured() never run
+             raise errors.ValidationError(name=_('Trust setup'),
+-                error=_('Our domain is not configured'))
++                                         error=_('Our domain is '
++                                                 'not configured'))
+         if not self._domains:
+             self._domains = self.get_trusted_domains()
+         if len(self._domains) == 0:
+             # Our domain is configured but no trusted domains are configured
+             raise errors.ValidationError(name=_('Trust setup'),
+-                error=_('No trusted domain is not configured'))
++                                         error=_('No trusted domain is '
++                                                 'not configured'))
+ 
+         entries = None
+         if domain is not None:
+             if domain not in self._domains:
+                 raise errors.ValidationError(name=_('trusted domain object'),
+-                   error= _('domain is not trusted'))
++                                             error=_('domain is not trusted'))
+             # Now we have a name to check against our list of trusted domains
+             entries = self.search_in_dc(domain, filter, attrs, scope, basedn)
+         elif flatname is not None:
+@@ -347,53 +373,65 @@ class DomainValidator(object):
+             for domain in self._domains:
+                 if self._domains[domain][0] == flatname:
+                     found_flatname = True
+-                    entries = self.search_in_dc(domain, filter, attrs, scope, basedn)
++                    entries = self.search_in_dc(domain, filter,
++                                                attrs, scope, basedn)
+                     if entries:
+                         break
+             if not found_flatname:
+                 raise errors.ValidationError(name=_('trusted domain object'),
+-                        error= _('no trusted domain matched the specified flat name'))
++                                             error=_('no trusted domain '
++                                                     'matched the specified '
++                                                     'flat name'))
+         if not entries:
+             raise errors.NotFound(reason=_('trusted domain object not found'))
+ 
+         return entries
+ 
+-    def get_trusted_domain_object_sid(self, object_name, fallback_to_ldap=True):
++    def get_trusted_domain_object_sid(self, object_name,
++                                      fallback_to_ldap=True):
+         result = pysss_nss_idmap.getsidbyname(object_name)
+-        if object_name in result and (pysss_nss_idmap.SID_KEY in result[object_name]):
++        if object_name in result and \
++           (pysss_nss_idmap.SID_KEY in result[object_name]):
+             object_sid = result[object_name][pysss_nss_idmap.SID_KEY]
+             return object_sid
+ 
+         # If fallback to AD DC LDAP is not allowed, bail out
+         if not fallback_to_ldap:
+             raise errors.ValidationError(name=_('trusted domain object'),
+-               error= _('SSSD was unable to resolve the object to a valid SID'))
++                                         error=_('SSSD was unable to resolve '
++                                                 'the object to a valid SID'))
+ 
+         # Else, we are going to contact AD DC LDAP
+         components = normalize_name(object_name)
+         if not ('domain' in components or 'flatname' in components):
+             # No domain or realm specified, ambiguous search
+-             raise errors.ValidationError(name=_('trusted domain object'),
+-                   error= _('Ambiguous search, user domain was not specified'))
++            raise errors.ValidationError(name=_('trusted domain object'),
++                                         error=_('Ambiguous search, user '
++                                                 'domain was not specified'))
+ 
+         attrs = ['objectSid']
+-        filter = '(&(sAMAccountName=%(name)s)(|(objectClass=user)(objectClass=group)))' \
+-                % dict(name=components['name'])
++        filter = '(&(sAMAccountName=%(name)s)' \
++                 '(|(objectClass=user)(objectClass=group)))' \
++                 % dict(name=components['name'])
+         scope = _ldap.SCOPE_SUBTREE
+         entries = self.get_trusted_domain_objects(components.get('domain'),
+-                components.get('flatname'), filter, attrs, scope)
++                                                  components.get('flatname'),
++                                                  filter, attrs, scope)
+ 
+         if len(entries) > 1:
+             # Treat non-unique entries as invalid
+             raise errors.ValidationError(name=_('trusted domain object'),
+-               error= _('Trusted domain did not return a unique object'))
++                                         error=_('Trusted domain did not '
++                                                 'return a unique object'))
+         sid = self.__sid_to_str(entries[0]['objectSid'][0])
+         try:
+             test_sid = security.dom_sid(sid)
+             return unicode(test_sid)
+         except TypeError as e:
+             raise errors.ValidationError(name=_('trusted domain object'),
+-               error= _('Trusted domain did not return a valid SID for the object'))
++                                         error=_('Trusted domain did not '
++                                                 'return a valid SID for '
++                                                 'the object'))
+ 
+     def get_trusted_domain_object_type(self, name_or_sid):
+         """
+@@ -443,7 +481,8 @@ class DomainValidator(object):
+         )
+ 
+         attrs = ['sAMAccountName']
+-        filter = (r'(&(objectSid=%(sid)s)(|(objectClass=user)(objectClass=group)))'
++        filter = (r'(&(objectSid=%(sid)s)'
++                  '(|(objectClass=user)(objectClass=group)))'
+                   % dict(sid=escaped_sid))  # sid in binary
+         domain = self.get_domain_by_sid(sid)
+ 
+@@ -454,7 +493,8 @@ class DomainValidator(object):
+         if len(entries) > 1:
+             # Treat non-unique entries as invalid
+             raise errors.ValidationError(name=_('trusted domain object'),
+-               error=_('Trusted domain did not return a unique object'))
++                                         error=_('Trusted domain did not '
++                                                 'return a unique object'))
+ 
+         object_name = (
+             "%s@%s" % (entries[0].single_value['sAMAccountName'].lower(),
+@@ -486,27 +526,31 @@ class DomainValidator(object):
+             # Now search a trusted domain for a user with this SID
+             attrs = ['cn']
+             filter = '(&(objectClass=user)(objectSid=%(sid)s))' \
+-                    % dict(sid=object_name)
++                % dict(sid=object_name)
+             try:
+-                entries = self.get_trusted_domain_objects(domain=domain, filter=filter,
+-                        attrs=attrs, scope=_ldap.SCOPE_SUBTREE)
++                entries = self.get_trusted_domain_objects(domain=domain,
++                                                          filter=filter,
++                                                          attrs=attrs,
++                                                          scope=_ldap.SCOPE_SUBTREE)
+             except errors.NotFound:
+                 raise errors.NotFound(reason=_('trusted domain user not found'))
+             user_dn = entries[0].dn
+         elif domain or flatname:
+             attrs = ['cn']
+             filter = '(&(sAMAccountName=%(name)s)(objectClass=user))' \
+-                    % dict(name=name)
++                     % dict(name=name)
+             try:
+                 entries = self.get_trusted_domain_objects(domain,
+-                        flatname, filter, attrs, _ldap.SCOPE_SUBTREE)
++                                                          flatname, filter, attrs,
++                                                          _ldap.SCOPE_SUBTREE)
+             except errors.NotFound:
+                 raise errors.NotFound(reason=_('trusted domain user not found'))
+             user_dn = entries[0].dn
+         else:
+             # No domain or realm specified, ambiguous search
+             raise errors.ValidationError(name=_('trusted domain object'),
+-                   error= _('Ambiguous search, user domain was not specified'))
++                                         error=_('Ambiguous search, '
++                                                 'user domain was not specified'))
+ 
+         # Get SIDs of user object and it's groups
+         # tokenGroups attribute must be read with a scope BASE for a known user
+@@ -514,9 +558,11 @@ class DomainValidator(object):
+         attrs = ['objectSID', 'tokenGroups']
+         filter = "(objectClass=user)"
+         entries = self.get_trusted_domain_objects(domain,
+-            flatname, filter, attrs, _ldap.SCOPE_BASE, user_dn)
++                                                  flatname, filter, attrs,
++                                                  _ldap.SCOPE_BASE, user_dn)
+         object_sid = self.__sid_to_str(entries[0]['objectSid'][0])
+-        group_sids = [self.__sid_to_str(sid) for sid in entries[0]['tokenGroups']]
++        group_sids = [self.__sid_to_str(sid)
++                      for sid in entries[0]['tokenGroups']]
+         return (object_sid, group_sids)
+ 
+     def get_trusted_domain_user_and_groups(self, object_name):
+@@ -540,11 +586,14 @@ class DomainValidator(object):
+         if is_valid_sid:
+             object_sid = object_name
+             result = pysss_nss_idmap.getnamebysid(object_name)
+-            if object_name in result and (pysss_nss_idmap.NAME_KEY in result[object_name]):
+-                group_list = pysss.getgrouplist(result[object_name][pysss_nss_idmap.NAME_KEY])
++            if object_name in result and \
++               (pysss_nss_idmap.NAME_KEY in result[object_name]):
++                group_list = pysss.getgrouplist(
++                                 result[object_name][pysss_nss_idmap.NAME_KEY])
+         else:
+             result = pysss_nss_idmap.getsidbyname(object_name)
+-            if object_name in result and (pysss_nss_idmap.SID_KEY in result[object_name]):
++            if object_name in result and \
++               (pysss_nss_idmap.SID_KEY in result[object_name]):
+                 object_sid = result[object_name][pysss_nss_idmap.SID_KEY]
+                 group_list = pysss.getgrouplist(object_name)
+ 
+@@ -552,7 +601,10 @@ class DomainValidator(object):
+             return self.__get_trusted_domain_user_and_groups(object_name)
+ 
+         group_sids = pysss_nss_idmap.getsidbyname(group_list)
+-        return (object_sid, [el[1][pysss_nss_idmap.SID_KEY] for el in group_sids.items()])
++        return (
++                object_sid,
++                [el[1][pysss_nss_idmap.SID_KEY] for el in group_sids.items()]
++               )
+ 
+     def __sid_to_str(self, sid):
+         """
+@@ -561,12 +613,13 @@ class DomainValidator(object):
+         """
+         sid_rev_num = ord(sid[0])
+         number_sub_id = ord(sid[1])
+-        ia = struct.unpack('!Q','\x00\x00'+sid[2:8])[0]
++        ia = struct.unpack('!Q', '\x00\x00'+sid[2:8])[0]
+         subs = [
+-            struct.unpack('<I',sid[8+4*i:12+4*i])[0]
++            struct.unpack('<I', sid[8+4*i:12+4*i])[0]
+             for i in range(number_sub_id)
+         ]
+-        return u'S-%d-%d-%s' % ( sid_rev_num, ia, '-'.join([str(s) for s in subs]),)
++        return u'S-%d-%d-%s' % (sid_rev_num, ia,
++                                '-'.join([str(s) for s in subs]),)
+ 
+     def kinit_as_http(self, domain):
+         """
+@@ -624,7 +677,7 @@ class DomainValidator(object):
+         error on ccache initialization
+         """
+ 
+-        if self._admin_creds == None:
++        if self._admin_creds is None:
+             return (None, None)
+ 
+         domain_suffix = domain.replace('.', '-')
+@@ -691,7 +744,8 @@ class DomainValidator(object):
+         ccache_name = None
+ 
+         if self._admin_creds:
+-            (ccache_name, principal) = self.kinit_as_administrator(info['dns_domain'])
++            (ccache_name,
++             principal) = self.kinit_as_administrator(info['dns_domain'])
+ 
+         if ccache_name:
+             with ipautil.private_ccache(path=ccache_name):
+@@ -736,7 +790,7 @@ class DomainValidator(object):
+ 
+         if not self._creds:
+             self._parm = param.LoadParm()
+-            self._parm.load(os.path.join(ipautil.SHARE_DIR,"smb.conf.empty"))
++            self._parm.load(os.path.join(ipautil.SHARE_DIR, "smb.conf.empty"))
+             self._parm.set('netbios name', self.flatname)
+             self._creds = credentials.Credentials()
+             self._creds.set_kerberos_state(credentials.MUST_USE_KERBEROS)
+@@ -746,12 +800,14 @@ class DomainValidator(object):
+         netrc = net.Net(creds=self._creds, lp=self._parm)
+         finddc_error = None
+         result = None
++        flags = nbt.NBT_SERVER_LDAP | nbt.NBT_SERVER_GC | nbt.NBT_SERVER_CLOSEST
+         try:
+-            result = netrc.finddc(domain=domain, flags=nbt.NBT_SERVER_LDAP | nbt.NBT_SERVER_GC | nbt.NBT_SERVER_CLOSEST)
++            result = netrc.finddc(domain=domain, flags=flags)
+         except RuntimeError as e:
+             try:
+                 # If search of closest GC failed, attempt to find any one
+-                result = netrc.finddc(domain=domain, flags=nbt.NBT_SERVER_LDAP | nbt.NBT_SERVER_GC)
++                flags = nbt.NBT_SERVER_LDAP | nbt.NBT_SERVER_GC
++                result = netrc.finddc(domain=domain, flags=flags)
+             except RuntimeError as e:
+                 finddc_error = e
+ 
+@@ -789,6 +845,7 @@ class DomainValidator(object):
+         self._info[domain] = info
+         return info
+ 
++
+ def string_to_array(what):
+     return [ord(v) for v in what]
+ 
+@@ -797,7 +854,7 @@ class TrustDomainInstance(object):
+ 
+     def __init__(self, hostname, creds=None):
+         self.parm = param.LoadParm()
+-        self.parm.load(os.path.join(ipautil.SHARE_DIR,"smb.conf.empty"))
++        self.parm.load(os.path.join(ipautil.SHARE_DIR, "smb.conf.empty"))
+         if len(hostname) > 0:
+             self.parm.set('netbios name', hostname)
+         self.creds = creds
+@@ -810,14 +867,14 @@ class TrustDomainInstance(object):
+         self.validation_attempts = 0
+ 
+     def __gen_lsa_connection(self, binding):
+-       if self.creds is None:
+-           raise errors.RequirementError(name=_('CIFS credentials object'))
+-       try:
+-           result = lsa.lsarpc(binding, self.parm, self.creds)
+-           return result
+-       except RuntimeError as e:
+-           num, message = e.args  # pylint: disable=unpacking-non-sequence
+-           raise assess_dcerpc_exception(num=num, message=message)
++        if self.creds is None:
++            raise errors.RequirementError(name=_('CIFS credentials object'))
++        try:
++            result = lsa.lsarpc(binding, self.parm, self.creds)
++            return result
++        except RuntimeError as e:
++            num, message = e.args  # pylint: disable=unpacking-non-sequence
++            raise assess_dcerpc_exception(num=num, message=message)
+ 
+     def init_lsa_pipe(self, remote_host):
+         """
+@@ -847,30 +904,35 @@ class TrustDomainInstance(object):
+                 # When session key is not available, we just skip this binding
+                 session_attempts = session_attempts + 1
+ 
+-        if self._pipe is None and (attempts + session_attempts) == len(bindings):
++        if self._pipe is None and \
++           (attempts + session_attempts) == len(bindings):
+             raise errors.ACIError(
+-                info=_('CIFS server %(host)s denied your credentials') % dict(host=remote_host))
++                      info=_('CIFS server %(host)s denied your credentials')
++                      % dict(host=remote_host))
+ 
+         if self._pipe is None:
+             raise errors.RemoteRetrieveError(
+-                reason=_('Cannot establish LSA connection to %(host)s. Is CIFS server running?') % dict(host=remote_host))
++                    reason=_('Cannot establish LSA connection to %(host)s. '
++                             'Is CIFS server running?') % dict(host=remote_host))
+         self.binding = binding
+         self.session_key = self._pipe.session_key
+ 
+     def __gen_lsa_bindings(self, remote_host):
+         """
+-        There are multiple transports to issue LSA calls. However, depending on a
+-        system in use they may be blocked by local operating system policies.
++        There are multiple transports to issue LSA calls. However, depending on
++        a system in use they may be blocked by local operating system policies.
+         Generate all we can use. init_lsa_pipe() will try them one by one until
+         there is one working.
+ 
+-        We try NCACN_NP before NCACN_IP_TCP and use SMB2 before SMB1 or defaults.
++        We try NCACN_NP before NCACN_IP_TCP and use SMB2 before SMB1.
+         """
+         transports = (u'ncacn_np', u'ncacn_ip_tcp')
+-        options = ( u'smb2,print', u'print')
+-        return [u'%s:%s[%s]' % (t, remote_host, o) for t in transports for o in options]
++        options = (u'smb2,print', u'print')
++        return [u'%s:%s[%s]' % (t, remote_host, o)
++                for t in transports for o in options]
+ 
+-    def retrieve_anonymously(self, remote_host, discover_srv=False, search_pdc=False):
++    def retrieve_anonymously(self, remote_host,
++                             discover_srv=False, search_pdc=False):
+         """
+         When retrieving DC information anonymously, we can't get SID of the domain
+         """
+@@ -896,7 +958,8 @@ class TrustDomainInstance(object):
+         self.info['is_pdc'] = (result.server_type & nbt.NBT_SERVER_PDC) != 0
+ 
+         # Netlogon response doesn't contain SID of the domain.
+-        # We need to do rootDSE search with LDAP_SERVER_EXTENDED_DN_OID control to reveal the SID
++        # We need to do rootDSE search with LDAP_SERVER_EXTENDED_DN_OID
++        # control to reveal the SID
+         ldap_uri = 'ldap://%s' % (result.pdc_dns_name)
+         conn = _ldap.initialize(ldap_uri)
+         conn.set_option(_ldap.OPT_SERVER_CONTROLS, [ExtendedDNControl()])
+@@ -908,7 +971,7 @@ class TrustDomainInstance(object):
+         except _ldap.LDAPError as e:
+             root_logger.error(
+                 "LDAP error when connecting to %(host)s: %(error)s" %
+-                    dict(host=unicode(result.pdc_name), error=str(e)))
++                dict(host=unicode(result.pdc_name), error=str(e)))
+         except KeyError as e:
+             root_logger.error("KeyError: {err}, LDAP entry from {host} "
+                               "returned malformed. Your DNS might be "
+@@ -930,8 +993,11 @@ class TrustDomainInstance(object):
+         objectAttribute = lsa.ObjectAttribute()
+         objectAttribute.sec_qos = lsa.QosInfo()
+         try:
+-            self._policy_handle = self._pipe.OpenPolicy2(u"", objectAttribute, security.SEC_FLAG_MAXIMUM_ALLOWED)
+-            result = self._pipe.QueryInfoPolicy2(self._policy_handle, lsa.LSA_POLICY_INFO_DNS)
++            self._policy_handle = \
++                self._pipe.OpenPolicy2(u"", objectAttribute,
++                                       security.SEC_FLAG_MAXIMUM_ALLOWED)
++            result = self._pipe.QueryInfoPolicy2(self._policy_handle,
++                                                 lsa.LSA_POLICY_INFO_DNS)
+         except RuntimeError as e:
+             num, message = e.args  # pylint: disable=unpacking-non-sequence
+             raise assess_dcerpc_exception(num=num, message=message)
+@@ -944,7 +1010,8 @@ class TrustDomainInstance(object):
+         self.info['dc'] = remote_host
+ 
+         try:
+-            result = self._pipe.QueryInfoPolicy2(self._policy_handle, lsa.LSA_POLICY_INFO_ROLE)
++            result = self._pipe.QueryInfoPolicy2(self._policy_handle,
++                                                 lsa.LSA_POLICY_INFO_ROLE)
+         except RuntimeError as e:
+             num, message = e.args  # pylint: disable=unpacking-non-sequence
+             raise assess_dcerpc_exception(num=num, message=message)
+@@ -958,18 +1025,18 @@ class TrustDomainInstance(object):
+         clear_value.size = len(password_blob)
+         clear_value.password = password_blob
+ 
+-        clear_authentication_information = drsblobs.AuthenticationInformation()
+-        clear_authentication_information.LastUpdateTime = samba.unix2nttime(int(time.time()))
+-        clear_authentication_information.AuthType = lsa.TRUST_AUTH_TYPE_CLEAR
+-        clear_authentication_information.AuthInfo = clear_value
++        clear_authinfo = drsblobs.AuthenticationInformation()
++        clear_authinfo.LastUpdateTime = samba.unix2nttime(int(time.time()))
++        clear_authinfo.AuthType = lsa.TRUST_AUTH_TYPE_CLEAR
++        clear_authinfo.AuthInfo = clear_value
+ 
+-        authentication_information_array = drsblobs.AuthenticationInformationArray()
+-        authentication_information_array.count = 1
+-        authentication_information_array.array = [clear_authentication_information]
++        authinfo_array = drsblobs.AuthenticationInformationArray()
++        authinfo_array.count = 1
++        authinfo_array.array = [clear_authinfo]
+ 
+         outgoing = drsblobs.trustAuthInOutBlob()
+         outgoing.count = 1
+-        outgoing.current = authentication_information_array
++        outgoing.current = authinfo_array
+ 
+         confounder = [3]*512
+         for i in range(512):
+@@ -983,7 +1050,8 @@ class TrustDomainInstance(object):
+ 
+         trustpass_blob = ndr_pack(trustpass)
+ 
+-        encrypted_trustpass = arcfour_encrypt(self._pipe.session_key, trustpass_blob)
++        encrypted_trustpass = arcfour_encrypt(self._pipe.session_key,
++                                              trustpass_blob)
+ 
+         auth_blob = lsa.DATA_BUF2()
+         auth_blob.size = len(encrypted_trustpass)
+@@ -993,7 +1061,6 @@ class TrustDomainInstance(object):
+         auth_info.auth_blob = auth_blob
+         self.auth_info = auth_info
+ 
+-
+     def generate_ftinfo(self, another_domain):
+         """
+         Generates TrustDomainInfoFullInfo2Internal structure
+@@ -1032,27 +1099,38 @@ class TrustDomainInstance(object):
+                 # smbd already has the information about itself
+                 ldname = lsa.StringLarge()
+                 ldname.string = another_domain.info['dns_domain']
+-                collision_info = self._pipe.lsaRSetForestTrustInformation(self._policy_handle,
+-                                                                          ldname,
+-                                                                          lsa.LSA_FOREST_TRUST_DOMAIN_INFO,
+-                                                                          ftinfo, 0)
+-                if collision_info:
+-                    root_logger.error("When setting forest trust information, got collision info back:\n%s" % (ndr_print(collision_info)))
++                ftlevel = lsa.LSA_FOREST_TRUST_DOMAIN_INFO
++                # RSetForestTrustInformation returns collision information
++                # for trust topology
++                cinfo = self._pipe.lsaRSetForestTrustInformation(
++                            self._policy_handle,
++                            ldname,
++                            ftlevel,
++                            ftinfo, 0)
++                if cinfo:
++                    root_logger.error("When setting forest trust information, "
++                                      "got collision info back:\n%s"
++                                      % (ndr_print(cinfo)))
+         except RuntimeError as e:
+-            # We can ignore the error here -- setting up name suffix routes may fail
++            # We can ignore the error here --
++            # setting up name suffix routes may fail
+             pass
+ 
+-    def establish_trust(self, another_domain, trustdom_secret, trust_type='bidirectional', trust_external=False):
++    def establish_trust(self, another_domain, trustdom_secret,
++                        trust_type='bidirectional', trust_external=False):
+         """
+         Establishes trust between our and another domain
+-        Input: another_domain -- instance of TrustDomainInstance, initialized with #retrieve call
++        Input: another_domain -- instance of TrustDomainInstance,
++                                 initialized with #retrieve call
+                trustdom_secret -- shared secred used for the trust
+         """
+         if self.info['name'] == another_domain.info['name']:
+             # Check that NetBIOS names do not clash
+             raise errors.ValidationError(name=u'AD Trust Setup',
+-                    error=_('the IPA server and the remote domain cannot share the same '
+-                            'NetBIOS name: %s') % self.info['name'])
++                                         error=_('the IPA server and the '
++                                                 'remote domain cannot share '
++                                                 'the same NetBIOS name: %s')
++                                         % self.info['name'])
+ 
+         self.generate_auth(trustdom_secret)
+ 
+@@ -1071,8 +1149,12 @@ class TrustDomainInstance(object):
+         try:
+             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._pipe.DeleteTrustedDomain(self._policy_handle, res.info_ex.sid)
++            res = self._pipe.QueryTrustedDomainInfoByName(
++                                self._policy_handle,
++                                dname,
++                                lsa.LSA_TRUSTED_DOMAIN_INFO_FULL_INFO)
++            self._pipe.DeleteTrustedDomain(self._policy_handle,
++                                           res.info_ex.sid)
+         except RuntimeError as e:
+             num, message = e.args  # pylint: disable=unpacking-non-sequence
+             # Ignore anything but access denied (NT_STATUS_ACCESS_DENIED)
+@@ -1080,7 +1162,10 @@ class TrustDomainInstance(object):
+                 raise access_denied_error
+ 
+         try:
+-            trustdom_handle = self._pipe.CreateTrustedDomainEx2(self._policy_handle, info, self.auth_info, security.SEC_STD_DELETE)
++            trustdom_handle = self._pipe.CreateTrustedDomainEx2(
++                                           self._policy_handle,
++                                           info, self.auth_info,
++                                           security.SEC_STD_DELETE)
+         except RuntimeError as e:
+             num, message = e.args  # pylint: disable=unpacking-non-sequence
+             raise assess_dcerpc_exception(num=num, message=message)
+@@ -1089,13 +1174,19 @@ class TrustDomainInstance(object):
+         # trust settings. Samba insists this has to be done with LSA
+         # OpenTrustedDomain* calls, it is not enough to have a handle
+         # returned by the CreateTrustedDomainEx2 call.
+-        trustdom_handle = self._pipe.OpenTrustedDomainByName(self._policy_handle, dname, security.SEC_FLAG_MAXIMUM_ALLOWED)
++        trustdom_handle = self._pipe.OpenTrustedDomainByName(
++                                         self._policy_handle,
++                                         dname,
++                                         security.SEC_FLAG_MAXIMUM_ALLOWED)
+         try:
+-            infoclass = lsa.TrustDomainInfoSupportedEncTypes()
+-            infoclass.enc_types = security.KERB_ENCTYPE_RC4_HMAC_MD5
+-            infoclass.enc_types |= security.KERB_ENCTYPE_AES128_CTS_HMAC_SHA1_96
+-            infoclass.enc_types |= security.KERB_ENCTYPE_AES256_CTS_HMAC_SHA1_96
+-            self._pipe.SetInformationTrustedDomain(trustdom_handle, lsa.LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES, infoclass)
++            infocls = lsa.TrustDomainInfoSupportedEncTypes()
++            infocls.enc_types = security.KERB_ENCTYPE_RC4_HMAC_MD5
++            infocls.enc_types |= security.KERB_ENCTYPE_AES128_CTS_HMAC_SHA1_96
++            infocls.enc_types |= security.KERB_ENCTYPE_AES256_CTS_HMAC_SHA1_96
++            self._pipe.SetInformationTrustedDomain(
++                           trustdom_handle,
++                           lsa.LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES,
++                           infocls)
+         except RuntimeError as e:
+             # We can ignore the error here -- changing enctypes is for
+             # improved security but the trust will work with default values as
+@@ -1105,13 +1196,16 @@ class TrustDomainInstance(object):
+ 
+         if not trust_external:
+             try:
+-                info = self._pipe.QueryTrustedDomainInfo(trustdom_handle,
+-                                                         lsa.LSA_TRUSTED_DOMAIN_INFO_INFO_EX)
++                info = self._pipe.QueryTrustedDomainInfo(
++                                      trustdom_handle,
++                                      lsa.LSA_TRUSTED_DOMAIN_INFO_INFO_EX)
+                 info.trust_attributes |= lsa.LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE
+-                self._pipe.SetInformationTrustedDomain(trustdom_handle,
+-                                                       lsa.LSA_TRUSTED_DOMAIN_INFO_INFO_EX, info)
++                self._pipe.SetInformationTrustedDomain(
++                                      trustdom_handle,
++                                      lsa.LSA_TRUSTED_DOMAIN_INFO_INFO_EX, info)
+             except RuntimeError as e:
+-                root_logger.error('unable to set trust transitivity status: %s' % (str(e)))
++                root_logger.error(
++                      'unable to set trust transitivity status: %s' % (str(e)))
+ 
+         if self.info['is_pdc'] or trust_external:
+             self.update_ftinfo(another_domain)
+@@ -1119,12 +1213,13 @@ class TrustDomainInstance(object):
+     def verify_trust(self, another_domain):
+         def retrieve_netlogon_info_2(logon_server, domain, function_code, data):
+             try:
+-                netr_pipe = netlogon.netlogon(domain.binding, domain.parm, domain.creds)
+-                result = netr_pipe.netr_LogonControl2Ex(logon_server=logon_server,
++                netr_pipe = netlogon.netlogon(domain.binding,
++                                              domain.parm, domain.creds)
++                result = netr_pipe.netr_LogonControl2Ex(
++                                           logon_server=logon_server,
+                                            function_code=function_code,
+                                            level=2,
+-                                           data=data
+-                                           )
++                                           data=data)
+                 return result
+             except RuntimeError as e:
+                 num, message = e.args  # pylint: disable=unpacking-non-sequence
+@@ -1135,9 +1230,11 @@ class TrustDomainInstance(object):
+                                           another_domain.info['dns_domain'])
+ 
+         if result and result.flags and netlogon.NETLOGON_VERIFY_STATUS_RETURNED:
+-            if result.pdc_connection_status[0] != 0 and result.tc_connection_status[0] != 0:
++            if result.pdc_connection_status[0] != 0 and \
++               result.tc_connection_status[0] != 0:
+                 if result.pdc_connection_status[1] == "WERR_ACCESS_DENIED":
+-                    # Most likely AD DC hit another IPA replica which yet has no trust secret replicated
++                    # Most likely AD DC hit another IPA replica which
++                    # yet has no trust secret replicated
+ 
+                     # Sleep and repeat again
+                     self.validation_attempts += 1
+@@ -1176,23 +1273,23 @@ class TrustDomainInstance(object):
+ 
+ def fetch_domains(api, mydomain, trustdomain, creds=None, server=None):
+     trust_flags = dict(
+-                NETR_TRUST_FLAG_IN_FOREST = 0x00000001,
+-                NETR_TRUST_FLAG_OUTBOUND  = 0x00000002,
+-                NETR_TRUST_FLAG_TREEROOT  = 0x00000004,
+-                NETR_TRUST_FLAG_PRIMARY   = 0x00000008,
+-                NETR_TRUST_FLAG_NATIVE    = 0x00000010,
+-                NETR_TRUST_FLAG_INBOUND   = 0x00000020,
+-                NETR_TRUST_FLAG_MIT_KRB5  = 0x00000080,
+-                NETR_TRUST_FLAG_AES       = 0x00000100)
++                NETR_TRUST_FLAG_IN_FOREST=0x00000001,
++                NETR_TRUST_FLAG_OUTBOUND=0x00000002,
++                NETR_TRUST_FLAG_TREEROOT=0x00000004,
++                NETR_TRUST_FLAG_PRIMARY=0x00000008,
++                NETR_TRUST_FLAG_NATIVE=0x00000010,
++                NETR_TRUST_FLAG_INBOUND=0x00000020,
++                NETR_TRUST_FLAG_MIT_KRB5=0x00000080,
++                NETR_TRUST_FLAG_AES=0x00000100)
+ 
+     trust_attributes = dict(
+-                NETR_TRUST_ATTRIBUTE_NON_TRANSITIVE     = 0x00000001,
+-                NETR_TRUST_ATTRIBUTE_UPLEVEL_ONLY       = 0x00000002,
+-                NETR_TRUST_ATTRIBUTE_QUARANTINED_DOMAIN = 0x00000004,
+-                NETR_TRUST_ATTRIBUTE_FOREST_TRANSITIVE  = 0x00000008,
+-                NETR_TRUST_ATTRIBUTE_CROSS_ORGANIZATION = 0x00000010,
+-                NETR_TRUST_ATTRIBUTE_WITHIN_FOREST      = 0x00000020,
+-                NETR_TRUST_ATTRIBUTE_TREAT_AS_EXTERNAL  = 0x00000040)
++                NETR_TRUST_ATTRIBUTE_NON_TRANSITIVE=0x00000001,
++                NETR_TRUST_ATTRIBUTE_UPLEVEL_ONLY=0x00000002,
++                NETR_TRUST_ATTRIBUTE_QUARANTINED_DOMAIN=0x00000004,
++                NETR_TRUST_ATTRIBUTE_FOREST_TRANSITIVE=0x00000008,
++                NETR_TRUST_ATTRIBUTE_CROSS_ORGANIZATION=0x00000010,
++                NETR_TRUST_ATTRIBUTE_WITHIN_FOREST=0x00000020,
++                NETR_TRUST_ATTRIBUTE_TREAT_AS_EXTERNAL=0x00000040)
+ 
+     def communicate(td):
+         td.init_lsa_pipe(td.info['dc'])
+@@ -1314,7 +1411,8 @@ class TrustDomainJoins(object):
+         ld.retrieve(installutils.get_fqdn())
+         self.local_domain = ld
+ 
+-    def populate_remote_domain(self, realm, realm_server=None, realm_admin=None, realm_passwd=None):
++    def populate_remote_domain(self, realm, realm_server=None,
++                               realm_admin=None, realm_passwd=None):
+         def get_instance(self):
+             # Fetch data from foreign domain using password only
+             rd = TrustDomainInstance('')
+@@ -1330,7 +1428,8 @@ class TrustDomainJoins(object):
+         if realm_server is None:
+             rd.retrieve_anonymously(realm, discover_srv=True, search_pdc=True)
+         else:
+-            rd.retrieve_anonymously(realm_server, discover_srv=False, search_pdc=True)
++            rd.retrieve_anonymously(realm_server,
++                                    discover_srv=False, search_pdc=True)
+         rd.read_only = True
+         if realm_admin and realm_passwd:
+             if 'name' in rd.info:
+@@ -1339,12 +1438,14 @@ class TrustDomainJoins(object):
+                     # realm admin is in DOMAIN\user format
+                     # strip DOMAIN part as we'll enforce the one discovered
+                     realm_admin = names[-1]
+-                auth_string = u"%s\%s%%%s" % (rd.info['name'], realm_admin, realm_passwd)
++                auth_string = u"%s\%s%%%s" \
++                              % (rd.info['name'], realm_admin, realm_passwd)
+                 td = get_instance(self)
+                 td.creds.parse_string(auth_string)
+                 td.creds.set_workstation(self.local_domain.hostname)
+                 if realm_server is None:
+-                    # we must have rd.info['dns_hostname'] then, part of anonymous discovery
++                    # we must have rd.info['dns_hostname'] then
++                    # as it is part of the anonymous discovery
+                     td.retrieve(rd.info['dns_hostname'])
+                 else:
+                     td.retrieve(realm_server)
+@@ -1358,8 +1459,8 @@ class TrustDomainJoins(object):
+         """
+         Generate list of records for forest trust information about
+         our realm domains. Note that the list generated currently
+-        includes only top level domains, no exclusion domains, and no TDO objects
+-        as we handle the latter in a separate way
++        includes only top level domains, no exclusion domains, and
++        no TDO objects as we handle the latter in a separate way
+         """
+         if self.local_domain.read_only:
+             return
+@@ -1367,10 +1468,15 @@ class TrustDomainJoins(object):
+         self.local_domain.ftinfo_records = []
+ 
+         realm_domains = self.api.Command.realmdomains_show()['result']
+-        # Use realmdomains' modification timestamp to judge records last update time
+-        entry = self.api.Backend.ldap2.get_entry(realm_domains['dn'], ['modifyTimestamp'])
++        # Use realmdomains' modification timestamp
++        # to judge records' last update time
++        entry = self.api.Backend.ldap2.get_entry(
++                    realm_domains['dn'], ['modifyTimestamp'])
+         # Convert the timestamp to Windows 64-bit timestamp format
+-        trust_timestamp = long(time.mktime(entry['modifytimestamp'][0].timetuple())*1e7+116444736000000000)
++        trust_timestamp = long(
++                time.mktime(
++                     entry.single_value.get('modifytimestamp').timetuple()
++                )*1e7+116444736000000000)
+ 
+         for dom in realm_domains['associateddomain']:
+             ftinfo = dict()
+@@ -1379,7 +1485,8 @@ class TrustDomainJoins(object):
+             ftinfo['rec_type'] = lsa.LSA_FOREST_TRUST_TOP_LEVEL_NAME
+             self.local_domain.ftinfo_records.append(ftinfo)
+ 
+-    def join_ad_full_credentials(self, realm, realm_server, realm_admin, realm_passwd, trust_type):
++    def join_ad_full_credentials(self, realm, realm_server, realm_admin,
++                                 realm_passwd, trust_type):
+         if not self.configured:
+             return None
+ 
+@@ -1392,24 +1499,33 @@ class TrustDomainJoins(object):
+             )
+ 
+         trust_external = bool(self.__allow_behavior & TRUST_JOIN_EXTERNAL)
+-        if self.remote_domain.info['dns_domain'] != self.remote_domain.info['dns_forest']:
++        if self.remote_domain.info['dns_domain'] != \
++           self.remote_domain.info['dns_forest']:
+             if not trust_external:
+-                raise errors.NotAForestRootError(forest=self.remote_domain.info['dns_forest'],
+-                                                 domain=self.remote_domain.info['dns_domain'])
++                raise errors.NotAForestRootError(
++                          forest=self.remote_domain.info['dns_forest'],
++                          domain=self.remote_domain.info['dns_domain'])
+ 
+         if not self.remote_domain.read_only:
+             trustdom_pass = samba.generate_random_password(128, 128)
+             self.get_realmdomains()
+             self.remote_domain.establish_trust(self.local_domain,
+-                                               trustdom_pass, trust_type, trust_external)
++                                               trustdom_pass,
++                                               trust_type, trust_external)
+             self.local_domain.establish_trust(self.remote_domain,
+-                                              trustdom_pass, trust_type, trust_external)
+-            # if trust is inbound, we don't need to verify it because AD DC will respond
+-            # with WERR_NO_SUCH_DOMAIN -- in only does verification for outbound trusts.
++                                              trustdom_pass,
++                                              trust_type, trust_external)
++            # if trust is inbound, we don't need to verify it because
++            # AD DC will respond with WERR_NO_SUCH_DOMAIN --
++            # it only does verification for outbound trusts.
+             result = True
+             if trust_type == TRUST_BIDIRECTIONAL:
+                 result = self.remote_domain.verify_trust(self.local_domain)
+-            return dict(local=self.local_domain, remote=self.remote_domain, verified=result)
++            return dict(
++                        local=self.local_domain,
++                        remote=self.remote_domain,
++                        verified=result
++                       )
+         return None
+ 
+     def join_ad_ipa_half(self, realm, realm_server, trustdom_passwd, trust_type):
+@@ -1420,11 +1536,18 @@ class TrustDomainJoins(object):
+             self.populate_remote_domain(realm, realm_server, realm_passwd=None)
+ 
+         trust_external = bool(self.__allow_behavior & TRUST_JOIN_EXTERNAL)
+-        if self.remote_domain.info['dns_domain'] != self.remote_domain.info['dns_forest']:
++        if self.remote_domain.info['dns_domain'] != \
++           self.remote_domain.info['dns_forest']:
+             if not trust_external:
+-                raise errors.NotAForestRootError(forest=self.remote_domain.info['dns_forest'],
+-                                                 domain=self.remote_domain.info['dns_domain'])
++                raise errors.NotAForestRootError(
++                          forest=self.remote_domain.info['dns_forest'],
++                          domain=self.remote_domain.info['dns_domain'])
+ 
+         self.local_domain.establish_trust(self.remote_domain,
+-                                          trustdom_passwd, trust_type, trust_external)
+-        return dict(local=self.local_domain, remote=self.remote_domain, verified=False)
++                                          trustdom_passwd,
++                                          trust_type, trust_external)
++        return dict(
++                    local=self.local_domain,
++                    remote=self.remote_domain,
++                    verified=False
++                   )
+-- 
+2.7.4
+
diff --git a/SOURCES/0091-improve-the-usability-of-ipa-user-del-preserve-comma.patch b/SOURCES/0091-improve-the-usability-of-ipa-user-del-preserve-comma.patch
deleted file mode 100644
index 21a27bc..0000000
--- a/SOURCES/0091-improve-the-usability-of-ipa-user-del-preserve-comma.patch
+++ /dev/null
@@ -1,170 +0,0 @@
-From 8208a3b4a642b19ebf112d29f4b3f4feae1a6011 Mon Sep 17 00:00:00 2001
-From: Martin Babinsky <mbabinsk@redhat.com>
-Date: Wed, 19 Aug 2015 14:43:14 +0200
-Subject: [PATCH] improve the usability of `ipa user-del --preserve` command
-
-`ipa user-del` with `--preserve` option will now process multiple entries and
-handle `--continue` option in a manner analogous to `ipa user-del` in normal
-mode.
-
-In addition, it is now no longer possible to permanently delete a user by
-accidentally running `ipa user-del --preserve` twice.
-
-https://fedorahosted.org/freeipa/ticket/5234
-https://fedorahosted.org/freeipa/ticket/5236
-
-Reviewed-By: Thierry Bordaz <tbordaz@redhat.com>
-Reviewed-By: Martin Basti <mbasti@redhat.com>
----
- ipalib/plugins/user.py | 123 ++++++++++++++++++++++++++-----------------------
- 1 file changed, 66 insertions(+), 57 deletions(-)
-
-diff --git a/ipalib/plugins/user.py b/ipalib/plugins/user.py
-index d7cf9666d43b69b0cab91cfa0c98a8373f095ab5..cb47cbb4869cb978f87603817033580647cc2d17 100644
---- a/ipalib/plugins/user.py
-+++ b/ipalib/plugins/user.py
-@@ -593,6 +593,60 @@ class user_del(baseuser_del):
-         ),
-     )
- 
-+    def _preserve_user(self, pkey, delete_container, **options):
-+        assert isinstance(delete_container, DN)
-+
-+        dn = self.obj.get_either_dn(pkey, **options)
-+        delete_dn = DN(dn[0], delete_container)
-+        ldap = self.obj.backend
-+        self.log.debug("preserve move %s -> %s" % (dn, delete_dn))
-+
-+        if dn.endswith(delete_container):
-+            raise errors.ExecutionError(
-+                _('%s: user is already preserved' % pkey)
-+            )
-+        # Check that this value is a Active user
-+        try:
-+            original_entry_attrs = self._exc_wrapper(
-+                pkey, options, ldap.get_entry)(dn, ['dn'])
-+        except errors.NotFound:
-+            self.obj.handle_not_found(pkey)
-+
-+        # start to move the entry to Delete container
-+        self._exc_wrapper(pkey, options, ldap.move_entry)(dn, delete_dn,
-+                                                          del_old=True)
-+
-+        # Then clear the credential attributes
-+        attrs_to_clear = ['krbPrincipalKey', 'krbLastPwdChange',
-+                          'krbPasswordExpiration', 'userPassword']
-+
-+        entry_attrs = self._exc_wrapper(pkey, options, ldap.get_entry)(
-+            delete_dn, attrs_to_clear)
-+
-+        clearedCredential = False
-+        for attr in attrs_to_clear:
-+            if attr.lower() in entry_attrs:
-+                del entry_attrs[attr]
-+                clearedCredential = True
-+        if clearedCredential:
-+            self._exc_wrapper(pkey, options, ldap.update_entry)(entry_attrs)
-+
-+        # Then restore some original entry attributes
-+        attrs_to_restore = ['secretary', 'managedby', 'manager', 'ipauniqueid',
-+                            'uidnumber', 'gidnumber', 'passwordHistory']
-+
-+        entry_attrs = self._exc_wrapper(
-+            pkey, options, ldap.get_entry)(delete_dn, attrs_to_restore)
-+
-+        restoreAttr = False
-+        for attr in attrs_to_restore:
-+            if ((attr.lower() in original_entry_attrs) and
-+                    not (attr.lower() in entry_attrs)):
-+                restoreAttr = True
-+                entry_attrs[attr.lower()] = original_entry_attrs[attr.lower()]
-+        if restoreAttr:
-+            self._exc_wrapper(pkey, options, ldap.update_entry)(entry_attrs)
-+
-     def forward(self, *keys, **options):
-         if self.api.env.context == 'cli':
-             if options['no_preserve'] and options['preserve']:
-@@ -633,68 +687,23 @@ class user_del(baseuser_del):
- 
-     def execute(self, *keys, **options):
- 
--        dn = self.obj.get_either_dn(*keys, **options)
--
-         # We are going to permanent delete or the user is already in the delete container.
-         delete_container = DN(self.obj.delete_container_dn, self.api.env.basedn)
--        user_from_delete_container = dn.endswith(delete_container)
--
--        if not options.get('preserve', True) or user_from_delete_container:
--            # Remove any ID overrides tied with this user
--            remove_ipaobject_overrides(self.obj.backend, self.obj.api, dn)
--
--            # Issue a true DEL on that entry
--            return super(user_del, self).execute(*keys, **options)
- 
-         # The user to delete is active and there is no 'no_preserve' option
-         if options.get('preserve', False):
--
--            ldap = self.obj.backend
--
--            # need to handle multiple keys (e.g. keys[-1]=(u'tb8', u'tb9')..
--            active_dn = self.obj.get_either_dn(*keys, **options)
--            superior_dn = DN(self.obj.delete_container_dn, api.env.basedn)
--            delete_dn = DN(active_dn[0], self.obj.delete_container_dn, api.env.basedn)
--            self.log.debug("preserve move %s -> %s" % (active_dn, delete_dn))
--
--            # Check that this value is a Active user
--            try:
--                original_entry_attrs = self._exc_wrapper(keys, options, ldap.get_entry)(active_dn, ['dn'])
--            except errors.NotFound:
--                raise
--
--            # start to move the entry to Delete container
--            self._exc_wrapper(keys, options, ldap.move_entry)(active_dn, delete_dn, del_old=True)
--
--            # Then clear the credential attributes
--            attrs_to_clear = ['krbPrincipalKey', 'krbLastPwdChange', 'krbPasswordExpiration', 'userPassword']
--            try:
--                entry_attrs = self._exc_wrapper(keys, options, ldap.get_entry)(delete_dn, attrs_to_clear)
--            except errors.NotFound:
--                raise
--            clearedCredential = False
--            for attr in attrs_to_clear:
--                if attr.lower() in entry_attrs:
--                    del entry_attrs[attr]
--                    clearedCredential = True
--            if clearedCredential:
--                self._exc_wrapper(keys, options, ldap.update_entry)(entry_attrs)
--
--            # Then restore some original entry attributes
--            attrs_to_restore = [ 'secretary', 'managedby', 'manager', 'ipauniqueid', 'uidnumber', 'gidnumber', 'passwordHistory']
--            try:
--                entry_attrs = self._exc_wrapper(keys, options, ldap.get_entry)(delete_dn, attrs_to_restore)
--            except errors.NotFound:
--                raise
--            restoreAttr = False
--            for attr in attrs_to_restore:
--                if (attr.lower() in original_entry_attrs) and not (attr.lower() in entry_attrs):
--                    restoreAttr = True
--                    entry_attrs[attr.lower()] = original_entry_attrs[attr.lower()]
--            if restoreAttr:
--                self._exc_wrapper(keys, options, ldap.update_entry)(entry_attrs)
--
--            val = dict(result=dict(failed=[]), value=[keys[-1][0]])
-+            failed = []
-+            preserved = []
-+            for pkey in keys[-1]:
-+                try:
-+                    self._preserve_user(pkey, delete_container, **options)
-+                    preserved.append(pkey_to_value(pkey, options))
-+                except:
-+                    if not options.get('continue', False):
-+                        raise
-+                    failed.append(pkey_to_value(pkey, options))
-+
-+            val = dict(result=dict(failed=failed), value=preserved)
-             return val
-         else:
-             return super(user_del, self).execute(*keys, **options)
--- 
-2.4.3
-
diff --git a/SOURCES/0091-trust-automatically-resolve-DNS-trust-conflicts-for-.patch b/SOURCES/0091-trust-automatically-resolve-DNS-trust-conflicts-for-.patch
new file mode 100644
index 0000000..3d3a5e8
--- /dev/null
+++ b/SOURCES/0091-trust-automatically-resolve-DNS-trust-conflicts-for-.patch
@@ -0,0 +1,382 @@
+From 79bcdeb76d51fec5e8eab08f7642e7910e925bb4 Mon Sep 17 00:00:00 2001
+From: Alexander Bokovoy <abokovoy@redhat.com>
+Date: Mon, 15 Aug 2016 18:14:00 +0300
+Subject: [PATCH] trust: automatically resolve DNS trust conflicts for triangle
+ trusts
+
+For configuration where:
+  - AD example.com trusts IPA at ipa.example.com
+  - AD example.org trusts AD example.com
+  - a trust is tried to be established between ipa.example.com and
+    example.org,
+
+there will be a trust topology conflict detected by example.org domain
+controller because ipa.example.com DNS namespace overlaps with
+example.com DNS namespace.
+
+This type of trust topology conflict is documented in MS-ADTS 6.1.6.9.3.2
+"Building Well-Formed msDS-TrustForestTrustInfo Message". A similar
+conflict can arise for SID and NetBIOS namespaces. However, unlike SID
+and NetBIOS namespaces, we can solve DNS namespace conflict
+automatically if there are administrative credentials for example.org
+available.
+
+A manual sequence to solve the DNS namespace conflict is described in
+https://msdn.microsoft.com/it-it/library/cc786254%28v=ws.10%29.aspx.
+This sequence boils down to the following steps:
+
+   1. As an administrator of the example.org, you need to add an
+exclusion entry for ipa.example.com in the properties of the trust to
+example.com
+   2. Establish trust between ipa.example.com and example.org
+
+It is important to add the exclusion entry before step 4 or there will
+be conflict recorded which cannot be cleared easily right now due to a
+combination of bugs in both IPA and Active Directory.
+
+This patchset implements automated solution for the case when we have
+access to the example.org's administrator credentials:
+
+   1. Attempt to establish trust and update trust topology information.
+   2. If trust topology conflict is detected as result of (1):
+   2.1. Fetch trust topology infromation for the conflicting forest
+        trust
+   2.2. Add exclusion entry to our domain to the trust topology obtained
+        in (2.1)
+   2.3. Update trust topology for the conflicting forest trust
+   3. Re-establish trust between ipa.example.com and example.org
+
+We cannot do the same for shared secret trust and for external trust,
+though:
+
+   1. For shared secret trust we don't have administrative credentials
+      in the forest reporting the conflict
+
+   2. For the external trust we cannot set topology information due to
+      MS-LSAD 3.1.4.7.16 because external trust is non-transitive by
+      definition and thus setting topology information will fail.
+
+To test this logic one can use two Samba AD forests with FreeIPA
+using a sub-domain of one of them.
+
+Fixes: https://fedorahosted.org/freeipa/ticket/6076
+Reviewed-By: Martin Babinsky <mbabinsk@redhat.com>
+---
+ ipalib/errors.py    |  29 ++++++-
+ ipaserver/dcerpc.py | 220 +++++++++++++++++++++++++++++++++++++++++++++-------
+ 2 files changed, 220 insertions(+), 29 deletions(-)
+
+diff --git a/ipalib/errors.py b/ipalib/errors.py
+index 7b4f15dd60ee80719195ba1b9b85d075b10bdf4f..4cc4455b0abf7d2b1366e1ce6dbb3762bc551cc6 100644
+--- a/ipalib/errors.py
++++ b/ipalib/errors.py
+@@ -866,7 +866,6 @@ class NotAForestRootError(InvocationError):
+     errno = 3016
+     format = _("Domain '%(domain)s' is not a root domain for forest '%(forest)s'")
+ 
+-
+ ##############################################################################
+ # 4000 - 4999: Execution errors
+ 
+@@ -1908,6 +1907,34 @@ class DNSResolverError(DNSError):
+     errno = 4401
+     format = _('%(exception)s')
+ 
++class TrustError(ExecutionError):
++    """
++    **4500** Base class for trust execution errors (*4500 - 4599*).
++    These are typically instantiated when there is an error in establishing or
++    modifying a trust to another forest.
++    """
++
++    errno = 4500
++
++class TrustTopologyConflictError(TrustError):
++    """
++    **4501** Raised when an attempt to establish trust fails with a topology
++             conflict against another forest the target forest trusts
++
++    For example:
++
++    >>> raise TrustTopologyConflictError(forest='example.test',
++                                         conflict='my.ad.test',
++                                         domains=['ad.test'])
++    Traceback (most recent call last):
++      ...
++    TrustTopologyConflictError: Forest 'example.test' has existing trust to forest(s) ['ad.test'] which prevents a trust to 'my.ad.test'
++    """
++
++    errno = 4501
++    format = _("Forest '%(forest)s' has existing trust to forest(s) "
++               "%(domains)s which prevents a trust to '%(conflict)s'")
++
+ 
+ ##############################################################################
+ # 5000 - 5999: Generic errors
+diff --git a/ipaserver/dcerpc.py b/ipaserver/dcerpc.py
+index 19be6bf7a3617a3b867d51a9358c9926e91049a7..a1c12f16a655493808d50e6adb95e618a664a98c 100644
+--- a/ipaserver/dcerpc.py
++++ b/ipaserver/dcerpc.py
+@@ -1,7 +1,7 @@
+ # Authors:
+ #     Alexander Bokovoy <abokovoy@redhat.com>
+ #
+-# Copyright (C) 2011  Red Hat
++# Copyright (C) 2011-2016  Red Hat
+ # see file 'COPYING' for use and warranty information
+ #
+ # Portions (C) Andrew Tridgell, Andrew Bartlett
+@@ -140,6 +140,15 @@ pysss_type_key_translation_dict = {
+     pysss_nss_idmap.ID_BOTH: 'both',
+ }
+ 
++class TrustTopologyConflictSolved(Exception):
++    """
++    Internal trust error: raised when previously detected
++    trust topology conflict is automatically solved.
++
++    No separate errno is assigned as this error should
++    not be visible outside the dcerpc.py code.
++    """
++    pass
+ 
+ def assess_dcerpc_exception(num=None, message=None):
+     """
+@@ -1087,34 +1096,165 @@ class TrustDomainInstance(object):
+         info.entries = ftinfo_records
+         return info
+ 
++    def clear_ftinfo_conflict(self, another_domain, cinfo):
++        """
++        Attempt to clean up the forest trust collisions
++
++        :param self: the forest we establish trust to
++        :param another_domain: a forest that establishes trust to 'self'
++        :param cinfo: lsa_ForestTrustCollisionInfo structure that contain
++                      set of of lsa_ForestTrustCollisionRecord structures
++        :raises: TrustTopologyConflictSolved, TrustTopologyConflictError
++
++        This code tries to perform intelligent job of going
++        over individual collisions and making exclusion entries
++        for affected IPA namespaces.
++
++        There are three possible conflict configurations:
++          - conflict of DNS namespace (TLN conflict, LSA_TLN_DISABLED_CONFLICT)
++          - conflict of SID namespace (LSA_SID_DISABLED_CONFLICT)
++          - conflict of NetBIOS namespace (LSA_NB_DISABLED_CONFLICT)
++
++        we only can handle TLN conflicts because (a) excluding SID namespace
++        is not possible and (b) excluding NetBIOS namespace not possible.
++        These two types of conflicts should result in trust-add CLI error
++
++        These conflicts can come from external source (another forest) or
++        from internal source (another domain in the same forest). We only
++        can fix the problems with another forest.
++
++        To resolve TLN conflict we need to do following:
++          1. Retrieve forest trust information for the forest we conflict on
++          2. Add an exclusion entry for IPA DNS namespace to it
++          3. Set forest trust information for the forest we conflict on
++          4. Re-try establishing trust to the original forest
++
++        This all can only be done under privileges of Active Directory admin
++        that can change forest trusts. If we cannot have those privileges,
++        the work has to be done manually in the Windows UI for
++        'Active Directory Domains and Trusts' by the administrator of the
++        original forest.
++        """
++
++        # List of entries for unsolved conflicts
++        result = []
++
++        trust_timestamp = long(time.time()*1e7+116444736000000000)
++
++        # Collision information contains entries for specific trusted domains
++        # we collide with. Look into TLN collisions and add a TLN exclusion
++        # entry to the specific domain trust.
++        root_logger.error("Attempt to solve forest trust topology conflicts")
++        for rec in cinfo.entries:
++            if rec.type == lsa.LSA_FOREST_TRUST_COLLISION_TDO:
++                dominfo = self._pipe.lsaRQueryForestTrustInformation(
++                                 self._policy_handle,
++                                 rec.name,
++                                 lsa.LSA_FOREST_TRUST_DOMAIN_INFO)
++
++                # Oops, we were unable to retrieve trust topology for this
++                # trusted domain (forest).
++                if not dominfo:
++                    result.append(rec)
++                    root_logger.error("Unable to resolve conflict for "
++                                      "DNS domain %s in the forest %s "
++                                      "for domain trust %s. Trust cannot "
++                                      "be established unless this conflict "
++                                      "is fixed manually."
++                                      % (another_domain.info['dns_domain'],
++                                         self.info['dns_domain'],
++                                         rec.name.string))
++                    continue
++
++                # Copy over the entries, extend with TLN exclusion
++                entries = []
++                for e in dominfo.entries:
++                    e1 = lsa.ForestTrustRecord()
++                    e1.type = e.type
++                    e1.flags = e.flags
++                    e1.time = e.time
++                    e1.forest_trust_data = e.forest_trust_data
++                    entries.append(e1)
++
++                # Create TLN exclusion record
++                record = lsa.ForestTrustRecord()
++                record.type = lsa.LSA_FOREST_TRUST_TOP_LEVEL_NAME_EX
++                record.flags = 0
++                record.time = trust_timestamp
++                record.forest_trust_data.string = \
++                    another_domain.info['dns_domain']
++                entries.append(record)
++
++                fti = lsa.ForestTrustInformation()
++                fti.count = len(entries)
++                fti.entries = entries
++
++                # Update the forest trust information now
++                ldname = lsa.StringLarge()
++                ldname.string = rec.name.string
++                cninfo = self._pipe.lsaRSetForestTrustInformation(
++                             self._policy_handle,
++                             ldname,
++                             lsa.LSA_FOREST_TRUST_DOMAIN_INFO,
++                             fti, 0)
++                if cninfo:
++                    result.append(rec)
++                    root_logger.error("When defining exception for DNS "
++                                      "domain %s in forest %s for "
++                                      "trusted forest %s, "
++                                      "got collision info back:\n%s"
++                                      % (another_domain.info['dns_domain'],
++                                         self.info['dns_domain'],
++                                         rec.name.string,
++                                         ndr_print(cninfo)))
++            else:
++                result.append(rec)
++                root_logger.error("Unable to resolve conflict for "
++                                  "DNS domain %s in the forest %s "
++                                  "for in-forest domain %s. Trust cannot "
++                                  "be established unless this conflict "
++                                  "is fixed manually."
++                                  % (another_domain.info['dns_domain'],
++                                     self.info['dns_domain'],
++                                     rec.name.string))
++
++        if len(result) == 0:
++            root_logger.error("Successfully solved all conflicts")
++            raise TrustTopologyConflictSolved()
++
++        # Otherwise, raise TrustTopologyConflictError() exception
++        domains = [x.name.string for x in result]
++        raise errors.TrustTopologyConflictError(
++                              target=self.info['dns_domain'],
++                              conflict=another_domain.info['dns_domain'],
++                              domains=domains)
++
++
++
+     def update_ftinfo(self, another_domain):
+         """
+         Updates forest trust information in this forest corresponding
+         to the another domain's information.
+         """
+-        try:
+-            if another_domain.ftinfo_records:
+-                ftinfo = self.generate_ftinfo(another_domain)
+-                # Set forest trust information -- we do it only against AD DC as
+-                # smbd already has the information about itself
+-                ldname = lsa.StringLarge()
+-                ldname.string = another_domain.info['dns_domain']
+-                ftlevel = lsa.LSA_FOREST_TRUST_DOMAIN_INFO
+-                # RSetForestTrustInformation returns collision information
+-                # for trust topology
+-                cinfo = self._pipe.lsaRSetForestTrustInformation(
+-                            self._policy_handle,
+-                            ldname,
+-                            ftlevel,
+-                            ftinfo, 0)
+-                if cinfo:
+-                    root_logger.error("When setting forest trust information, "
+-                                      "got collision info back:\n%s"
+-                                      % (ndr_print(cinfo)))
+-        except RuntimeError as e:
+-            # We can ignore the error here --
+-            # setting up name suffix routes may fail
+-            pass
++        if another_domain.ftinfo_records:
++            ftinfo = self.generate_ftinfo(another_domain)
++            # Set forest trust information -- we do it only against AD DC as
++            # smbd already has the information about itself
++            ldname = lsa.StringLarge()
++            ldname.string = another_domain.info['dns_domain']
++            ftlevel = lsa.LSA_FOREST_TRUST_DOMAIN_INFO
++            # RSetForestTrustInformation returns collision information
++            # for trust topology
++            cinfo = self._pipe.lsaRSetForestTrustInformation(
++                        self._policy_handle,
++                        ldname,
++                        ftlevel,
++                        ftinfo, 0)
++            if cinfo:
++                root_logger.error("When setting forest trust information, "
++                                  "got collision info back:\n%s"
++                                  % (ndr_print(cinfo)))
++                self.clear_ftinfo_conflict(another_domain, cinfo)
+ 
+     def establish_trust(self, another_domain, trustdom_secret,
+                         trust_type='bidirectional', trust_external=False):
+@@ -1207,7 +1347,19 @@ class TrustDomainInstance(object):
+                 root_logger.error(
+                       'unable to set trust transitivity status: %s' % (str(e)))
+ 
+-        if self.info['is_pdc'] or trust_external:
++        # Updating forest trust info may fail
++        # If it failed due to topology conflict, it may be fixed automatically
++        # update_ftinfo() will through exceptions in that case
++        # Note that MS-LSAD 3.1.4.7.16 says:
++        # -------------------------
++        # The server MUST also make sure that the trust attributes associated
++        # with the trusted domain object referenced by the TrustedDomainName
++        # parameter has the TRUST_ATTRIBUTE_FOREST_TRANSITIVE set.
++        # If the attribute is not present, the server MUST return
++        # STATUS_INVALID_PARAMETER.
++        # -------------------------
++        # Thus, we must not update forest trust info for the external trust
++        if self.info['is_pdc'] and not trust_external:
+             self.update_ftinfo(another_domain)
+ 
+     def verify_trust(self, another_domain):
+@@ -1509,9 +1661,21 @@ class TrustDomainJoins(object):
+         if not self.remote_domain.read_only:
+             trustdom_pass = samba.generate_random_password(128, 128)
+             self.get_realmdomains()
+-            self.remote_domain.establish_trust(self.local_domain,
+-                                               trustdom_pass,
+-                                               trust_type, trust_external)
++
++            # Establishing trust may throw an exception for topology
++            # conflict. If it was solved, re-establish the trust again
++            # Otherwise let the CLI to display a message about the conflict
++            try:
++                self.remote_domain.establish_trust(self.local_domain,
++                                                   trustdom_pass,
++                                                   trust_type, trust_external)
++            except TrustTopologyConflictSolved as e:
++                # we solved topology conflict, retry again
++                self.remote_domain.establish_trust(self.local_domain,
++                                                   trustdom_pass,
++                                                   trust_type, trust_external)
++
++            # For local domain we don't set topology information
+             self.local_domain.establish_trust(self.remote_domain,
+                                               trustdom_pass,
+                                               trust_type, trust_external)
+-- 
+2.7.4
+
diff --git a/SOURCES/0092-DNSSEC-fix-forward-zone-forwarders-checks.patch b/SOURCES/0092-DNSSEC-fix-forward-zone-forwarders-checks.patch
deleted file mode 100644
index d4945d7..0000000
--- a/SOURCES/0092-DNSSEC-fix-forward-zone-forwarders-checks.patch
+++ /dev/null
@@ -1,47 +0,0 @@
-From 0f44ee49596f565f78144f676f431cb7f29bf15b Mon Sep 17 00:00:00 2001
-From: Martin Basti <mbasti@redhat.com>
-Date: Mon, 24 Aug 2015 12:53:30 +0200
-Subject: [PATCH] DNSSEC: fix forward zone forwarders checks
-
-https://fedorahosted.org/freeipa/ticket/5179
-
-Reviewed-By: Petr Spacek <pspacek@redhat.com>
----
- ipalib/util.py | 13 +++++++------
- 1 file changed, 7 insertions(+), 6 deletions(-)
-
-diff --git a/ipalib/util.py b/ipalib/util.py
-index 649a4875fde0b44844749946cce53d81f7f6eea4..a3500ae29b56ac6a289fbec97d15cf026baf7068 100644
---- a/ipalib/util.py
-+++ b/ipalib/util.py
-@@ -694,20 +694,21 @@ def validate_dnssec_zone_forwarder_step2(ipa_ip_addr, fwzone, log=None,
-         ans_cd = _resolve_record(fwzone, rtype, nameserver_ip=ipa_ip_addr,
-                                  edns0=True, dnssec=True, flag_cd=True,
-                                  timeout=timeout)
-+    except NXDOMAIN as e:
-+        # sometimes CD flag is ignored and NXDomain is returned
-+        _log_response(log, e)
-+        raise DNSSECValidationError(owner=fwzone, rtype=rtype, ip=ipa_ip_addr)
-     except DNSException as e:
-         _log_response(log, e)
-+        raise UnresolvableRecordError(owner=fwzone, rtype=rtype,
-+                                      ip=ipa_ip_addr, error=e)
- 
-     try:
-         ans_do = _resolve_record(fwzone, rtype, nameserver_ip=ipa_ip_addr,
-                                  edns0=True, dnssec=True, timeout=timeout)
--    except NXDOMAIN as e:
--        # sometimes CD flag is ignored and NXDomain is returned
--        _log_response(log, e)
--        raise DNSSECValidationError(owner=fwzone, rtype=rtype, ip=ipa_ip_addr)
-     except DNSException as e:
-         _log_response(log, e)
--        raise UnresolvableRecordError(owner=fwzone, rtype=rtype, ip=ipa_ip_addr,
--                                      error=e)
-+        raise DNSSECValidationError(owner=fwzone, rtype=rtype, ip=ipa_ip_addr)
-     else:
-         if (ans_do.canonical_name == ans_cd.canonical_name
-             and ans_do.rrset == ans_cd.rrset):
--- 
-2.4.3
-
diff --git a/SOURCES/0092-trust-make-sure-external-trust-topology-is-correctly.patch b/SOURCES/0092-trust-make-sure-external-trust-topology-is-correctly.patch
new file mode 100644
index 0000000..ed41671
--- /dev/null
+++ b/SOURCES/0092-trust-make-sure-external-trust-topology-is-correctly.patch
@@ -0,0 +1,90 @@
+From 2026313385db9ff2d1e74b22b7e2c6be7f7a9705 Mon Sep 17 00:00:00 2001
+From: Alexander Bokovoy <abokovoy@redhat.com>
+Date: Mon, 15 Aug 2016 18:32:25 +0300
+Subject: [PATCH] trust: make sure external trust topology is correctly
+ rendered
+
+When external trust is established, it is by definition is
+non-transitive: it is not possible to obtain Kerberos tickets to any
+service outside the trusted domain.
+
+Reflect this reality by only accepting UPN suffixes from the external
+trust -- since the trusted domain is a part of another forest and UPN
+suffixes are forest-wide, there could be user accounts in the trusted
+domain that use forest-wide UPN suffix but it will be impossible to
+reach the forest root via the externally trusted domain.
+
+Also, an argument to netr_DsRGetForestTrustInformation() has to be
+either forest root domain name or None (NULL). Otherwise we'll get
+an error as explained in MS-NRPC 3.5.4.7.5.
+
+https://fedorahosted.org/freeipa/ticket/6021
+
+Reviewed-By: Martin Babinsky <mbabinsk@redhat.com>
+---
+ ipaserver/dcerpc.py        |  2 +-
+ ipaserver/plugins/trust.py | 28 +++++++++++++++++-----------
+ 2 files changed, 18 insertions(+), 12 deletions(-)
+
+diff --git a/ipaserver/dcerpc.py b/ipaserver/dcerpc.py
+index a1c12f16a655493808d50e6adb95e618a664a98c..4d98485e17a9113322b7e38629fc43b593e99fd9 100644
+--- a/ipaserver/dcerpc.py
++++ b/ipaserver/dcerpc.py
+@@ -1449,7 +1449,7 @@ def fetch_domains(api, mydomain, trustdomain, creds=None, server=None):
+         # Older FreeIPA versions used netr_DsrEnumerateDomainTrusts call
+         # but it doesn't provide information about non-domain UPNs associated
+         # with the forest, thus we have to use netr_DsRGetForestTrustInformation
+-        domains = netr_pipe.netr_DsRGetForestTrustInformation(td.info['dc'], '', 0)
++        domains = netr_pipe.netr_DsRGetForestTrustInformation(td.info['dc'], None, 0)
+         return domains
+ 
+     domains = None
+diff --git a/ipaserver/plugins/trust.py b/ipaserver/plugins/trust.py
+index f2e0b1ee4b261ddc4f29477f46b7f4027af18892..8a25b560f9ae086ba8524cca22f39e8f67696146 100644
+--- a/ipaserver/plugins/trust.py
++++ b/ipaserver/plugins/trust.py
+@@ -1663,6 +1663,23 @@ def add_new_domains_from_trust(myapi, trustinstance, trust_entry, domains, **opt
+                     for x, y in six.iteritems(domains['suffixes'])
+                     if x not in domains['domains'])
+ 
++    try:
++        dn = myapi.Object.trust.get_dn(trust_name, trust_type=u'ad')
++        ldap = myapi.Backend.ldap2
++        entry = ldap.get_entry(dn)
++        tlns = entry.get('ipantadditionalsuffixes', [])
++        tlns.extend(x for x in suffixes if x not in tlns)
++        entry['ipantadditionalsuffixes'] = tlns
++        ldap.update_entry(entry)
++    except errors.EmptyModlist:
++        pass
++
++    is_nontransitive = int(trust_entry.get('ipanttrustattributes',
++                           [0])[0]) & LSA_TRUST_ATTRIBUTE_NON_TRANSITIVE
++
++    if is_nontransitive:
++        return result
++
+     for dom in six.itervalues(domains['domains']):
+         dom['trust_type'] = u'ad'
+         try:
+@@ -1686,17 +1703,6 @@ def add_new_domains_from_trust(myapi, trustinstance, trust_entry, domains, **opt
+             # Ignore updating duplicate entries
+             pass
+ 
+-    try:
+-        dn = myapi.Object.trust.get_dn(trust_name, trust_type=u'ad')
+-        ldap = myapi.Backend.ldap2
+-        entry = ldap.get_entry(dn)
+-        tlns = entry.get('ipantadditionalsuffixes', [])
+-        tlns.extend(x for x in suffixes if x not in tlns)
+-        entry['ipantadditionalsuffixes'] = tlns
+-        ldap.update_entry(entry)
+-    except errors.EmptyModlist:
+-        pass
+-
+     return result
+ 
+ 
+-- 
+2.7.4
+
diff --git a/SOURCES/0093-Added-support-for-changing-vault-encryption.patch b/SOURCES/0093-Added-support-for-changing-vault-encryption.patch
deleted file mode 100644
index 466806e..0000000
--- a/SOURCES/0093-Added-support-for-changing-vault-encryption.patch
+++ /dev/null
@@ -1,656 +0,0 @@
-From d3271ee9de63d9c6275184875d05762666ba9088 Mon Sep 17 00:00:00 2001
-From: "Endi S. Dewata" <edewata@redhat.com>
-Date: Fri, 31 Jul 2015 07:53:15 +0200
-Subject: [PATCH] Added support for changing vault encryption.
-
-The vault-mod command has been modified to support changing vault
-encryption attributes (i.e. type, password, public/private keys)
-in addition to normal attributes (i.e. description). Changing the
-encryption requires retrieving the stored secret with the old
-attributes and rearchiving it with the new attributes.
-
-https://fedorahosted.org/freeipa/ticket/5176
-
-Reviewed-By: Martin Basti <mbasti@redhat.com>
----
- API.txt                                   |  27 +++-
- VERSION                                   |   4 +-
- ipalib/plugins/vault.py                   | 233 ++++++++++++++++++++++++++--
- ipatests/test_xmlrpc/test_vault_plugin.py | 249 ++++++++++++++++++++++++++++++
- 4 files changed, 498 insertions(+), 15 deletions(-)
-
-diff --git a/API.txt b/API.txt
-index b0f456e725a6c3d24c1071b282de5a28c3b5a671..8105cfb5ba61cabcf5c0f7e1c6e44dfc0cacc9cb 100644
---- a/API.txt
-+++ b/API.txt
-@@ -5474,11 +5474,12 @@ output: Output('completed', <type 'int'>, None)
- output: Output('failed', <type 'dict'>, None)
- output: Entry('result', <type 'dict'>, Gettext('A dictionary representing an LDAP entry', domain='ipa', localedir=None))
- command: vault_archive
--args: 1,10,3
-+args: 1,11,3
- arg: Str('cn', attribute=True, cli_name='name', maxlength=255, multivalue=False, pattern='^[a-zA-Z0-9_.-]+$', primary_key=True, query=True, required=True)
- option: Flag('all', autofill=True, cli_name='all', default=False, exclude='webui')
- option: Bytes('data?')
- option: Str('in?')
-+option: Flag('override_password?', autofill=True, default=False)
- option: Str('password?', cli_name='password')
- option: Str('password_file?', cli_name='password_file')
- option: Flag('raw', autofill=True, cli_name='raw', default=False, exclude='webui')
-@@ -5538,6 +5539,30 @@ output: ListOfEntries('result', (<type 'list'>, <type 'tuple'>), Gettext('A list
- output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
- output: Output('truncated', <type 'bool'>, None)
- command: vault_mod
-+args: 1,18,3
-+arg: Str('cn', attribute=True, cli_name='name', maxlength=255, multivalue=False, pattern='^[a-zA-Z0-9_.-]+$', primary_key=True, query=True, required=True)
-+option: Flag('all', autofill=True, cli_name='all', default=False, exclude='webui')
-+option: Flag('change_password?', autofill=True, default=False)
-+option: Str('description?', cli_name='desc')
-+option: Bytes('ipavaultpublickey?', cli_name='public_key')
-+option: Bytes('ipavaultsalt?', cli_name='salt')
-+option: Str('ipavaulttype?', cli_name='type')
-+option: Str('new_password?', cli_name='new_password')
-+option: Str('new_password_file?', cli_name='new_password_file')
-+option: Str('old_password?', cli_name='old_password')
-+option: Str('old_password_file?', cli_name='old_password_file')
-+option: Bytes('private_key?', cli_name='private_key')
-+option: Str('private_key_file?', cli_name='private_key_file')
-+option: Str('public_key_file?', cli_name='public_key_file')
-+option: Flag('raw', autofill=True, cli_name='raw', default=False, exclude='webui')
-+option: Str('service?')
-+option: Flag('shared?', autofill=True, default=False)
-+option: Str('username?', cli_name='user')
-+option: Str('version?', exclude='webui')
-+output: Entry('result', <type 'dict'>, Gettext('A dictionary representing an LDAP entry', domain='ipa', localedir=None))
-+output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
-+output: PrimaryKey('value', None, None)
-+command: vault_mod_internal
- args: 1,15,3
- arg: Str('cn', attribute=True, cli_name='name', maxlength=255, multivalue=False, pattern='^[a-zA-Z0-9_.-]+$', primary_key=True, query=True, required=True)
- option: Str('addattr*', cli_name='addattr', exclude='webui')
-diff --git a/VERSION b/VERSION
-index 9fe2f4d4f9ff6ffd42c2ee7493c385b0a432a6a0..3fdd2db88a7b2b6d3bd36ba0d7257c9994bc06af 100644
---- a/VERSION
-+++ b/VERSION
-@@ -90,5 +90,5 @@ IPA_DATA_VERSION=20100614120000
- #                                                      #
- ########################################################
- IPA_API_VERSION_MAJOR=2
--IPA_API_VERSION_MINOR=152
--# Last change: mbasti - add 'user-stage' command
-+IPA_API_VERSION_MINOR=153
-+# Last change: edewata - Added support for changing vault encryption.
-diff --git a/ipalib/plugins/vault.py b/ipalib/plugins/vault.py
-index 4b2c8a518e5c9a93e5490841a3d2177536c905b1..6a07a76b5b85680536b27fd147d8ec1583bb0bc7 100644
---- a/ipalib/plugins/vault.py
-+++ b/ipalib/plugins/vault.py
-@@ -116,11 +116,37 @@ EXAMPLES:
-    ipa vault-show <name>
-        [--user <user>|--service <service>|--shared]
- """) + _("""
-- Modify a vault:
-+ Modify vault description:
-    ipa vault-mod <name>
-        [--user <user>|--service <service>|--shared]
-        --desc <description>
- """) + _("""
-+ Modify vault type:
-+   ipa vault-mod <name>
-+       [--user <user>|--service <service>|--shared]
-+       --type <type>
-+       [old password/private key]
-+       [new password/public key]
-+""") + _("""
-+ Modify symmetric vault password:
-+   ipa vault-mod <name>
-+       [--user <user>|--service <service>|--shared]
-+       --change-password
-+   ipa vault-mod <name>
-+       [--user <user>|--service <service>|--shared]
-+       --old-password <old password>
-+       --new-password <new password>
-+   ipa vault-mod <name>
-+       [--user <user>|--service <service>|--shared]
-+       --old-password-file <old password file>
-+       --new-password-file <new password file>
-+""") + _("""
-+ Modify asymmetric vault keys:
-+   ipa vault-mod <name>
-+       [--user <user>|--service <service>|--shared]
-+       --private-key-file <old private key file>
-+       --public-key-file <new public key file>
-+""") + _("""
-  Delete a vault:
-    ipa vault-del <name>
-        [--user <user>|--service <service>|--shared]
-@@ -457,7 +483,7 @@ class vault(LDAPObject):
- 
-             print '  ** Passwords do not match! **'
- 
--    def get_existing_password(self, new=False):
-+    def get_existing_password(self):
-         """
-         Gets existing password from user.
-         """
-@@ -871,9 +897,182 @@ class vault_find(LDAPSearch):
- 
- 
- @register()
--class vault_mod(LDAPUpdate):
-+class vault_mod(PKQuery, Local):
-     __doc__ = _('Modify a vault.')
- 
-+    takes_options = vault_options + (
-+        Str(
-+            'description?',
-+            cli_name='desc',
-+            doc=_('Vault description'),
-+        ),
-+        Str(
-+            'ipavaulttype?',
-+            cli_name='type',
-+            doc=_('Vault type'),
-+        ),
-+        Bytes(
-+            'ipavaultsalt?',
-+            cli_name='salt',
-+            doc=_('Vault salt'),
-+        ),
-+        Flag(
-+            'change_password?',
-+            doc=_('Change password'),
-+        ),
-+        Str(
-+            'old_password?',
-+            cli_name='old_password',
-+            doc=_('Old vault password'),
-+        ),
-+        Str(  # TODO: use File parameter
-+            'old_password_file?',
-+            cli_name='old_password_file',
-+            doc=_('File containing the old vault password'),
-+        ),
-+        Str(
-+            'new_password?',
-+            cli_name='new_password',
-+            doc=_('New vault password'),
-+        ),
-+        Str(  # TODO: use File parameter
-+            'new_password_file?',
-+            cli_name='new_password_file',
-+            doc=_('File containing the new vault password'),
-+        ),
-+        Bytes(
-+            'private_key?',
-+            cli_name='private_key',
-+            doc=_('Old vault private key'),
-+        ),
-+        Str(  # TODO: use File parameter
-+            'private_key_file?',
-+            cli_name='private_key_file',
-+            doc=_('File containing the old vault private key'),
-+        ),
-+        Bytes(
-+            'ipavaultpublickey?',
-+            cli_name='public_key',
-+            doc=_('New vault public key'),
-+        ),
-+        Str(  # TODO: use File parameter
-+            'public_key_file?',
-+            cli_name='public_key_file',
-+            doc=_('File containing the new vault public key'),
-+        ),
-+    )
-+
-+    has_output = output.standard_entry
-+
-+    def forward(self, *args, **options):
-+
-+        vault_type = options.pop('ipavaulttype', False)
-+        salt = options.pop('ipavaultsalt', False)
-+        change_password = options.pop('change_password', False)
-+
-+        old_password = options.pop('old_password', None)
-+        old_password_file = options.pop('old_password_file', None)
-+        new_password = options.pop('new_password', None)
-+        new_password_file = options.pop('new_password_file', None)
-+
-+        old_private_key = options.pop('private_key', None)
-+        old_private_key_file = options.pop('private_key_file', None)
-+        new_public_key = options.pop('ipavaultpublickey', None)
-+        new_public_key_file = options.pop('public_key_file', None)
-+
-+        if self.api.env.in_server:
-+            backend = self.api.Backend.ldap2
-+        else:
-+            backend = self.api.Backend.rpcclient
-+        if not backend.isconnected():
-+            backend.connect(ccache=krbV.default_context().default_ccache())
-+
-+        # determine the vault type based on parameters specified
-+        if vault_type:
-+            pass
-+
-+        elif change_password or new_password or new_password_file or salt:
-+            vault_type = u'symmetric'
-+
-+        elif new_public_key or new_public_key_file:
-+            vault_type = u'asymmetric'
-+
-+        # if vault type is specified, retrieve existing secret
-+        if vault_type:
-+            opts = options.copy()
-+            opts.pop('description', None)
-+
-+            opts['password'] = old_password
-+            opts['password_file'] = old_password_file
-+            opts['private_key'] = old_private_key
-+            opts['private_key_file'] = old_private_key_file
-+
-+            response = self.api.Command.vault_retrieve(*args, **opts)
-+            data = response['result']['data']
-+
-+        opts = options.copy()
-+
-+        # if vault type is specified, update crypto attributes
-+        if vault_type:
-+            opts['ipavaulttype'] = vault_type
-+
-+            if vault_type == u'standard':
-+                opts['ipavaultsalt'] = None
-+                opts['ipavaultpublickey'] = None
-+
-+            elif vault_type == u'symmetric':
-+                if salt:
-+                    opts['ipavaultsalt'] = salt
-+                else:
-+                    opts['ipavaultsalt'] = os.urandom(16)
-+
-+                opts['ipavaultpublickey'] = None
-+
-+            elif vault_type == u'asymmetric':
-+
-+                # get new vault public key
-+                if new_public_key and new_public_key_file:
-+                    raise errors.MutuallyExclusiveError(
-+                        reason=_('New public key specified multiple times'))
-+
-+                elif new_public_key:
-+                    pass
-+
-+                elif new_public_key_file:
-+                    new_public_key = validated_read('public_key_file',
-+                                                    new_public_key_file,
-+                                                    mode='rb')
-+
-+                else:
-+                    raise errors.ValidationError(
-+                        name='ipavaultpublickey',
-+                        error=_('Missing new vault public key'))
-+
-+                opts['ipavaultsalt'] = None
-+                opts['ipavaultpublickey'] = new_public_key
-+
-+        response = self.api.Command.vault_mod_internal(*args, **opts)
-+
-+        # if vault type is specified, rearchive existing secret
-+        if vault_type:
-+            opts = options.copy()
-+            opts.pop('description', None)
-+
-+            opts['data'] = data
-+            opts['password'] = new_password
-+            opts['password_file'] = new_password_file
-+            opts['override_password'] = True
-+
-+            self.api.Command.vault_archive(*args, **opts)
-+
-+        return response
-+
-+
-+@register()
-+class vault_mod_internal(LDAPUpdate):
-+
-+    NO_CLI = True
-+
-     takes_options = LDAPUpdate.takes_options + vault_options
- 
-     msg_summary = _('Modified vault "%(value)s"')
-@@ -994,6 +1193,10 @@ class vault_archive(PKQuery, Local):
-             cli_name='password_file',
-             doc=_('File containing the vault password'),
-         ),
-+        Flag(
-+            'override_password?',
-+            doc=_('Override existing password'),
-+        ),
-     )
- 
-     has_output = output.standard_entry
-@@ -1008,6 +1211,8 @@ class vault_archive(PKQuery, Local):
-         password = options.get('password')
-         password_file = options.get('password_file')
- 
-+        override_password = options.pop('override_password', False)
-+
-         # don't send these parameters to server
-         if 'data' in options:
-             del options['data']
-@@ -1062,15 +1267,19 @@ class vault_archive(PKQuery, Local):
-                 password = password.rstrip('\n')
- 
-             else:
--                password = self.obj.get_existing_password()
--
--            # verify password by retrieving existing data
--            opts = options.copy()
--            opts['password'] = password
--            try:
--                self.api.Command.vault_retrieve(*args, **opts)
--            except errors.NotFound:
--                pass
-+                if override_password:
-+                    password = self.obj.get_new_password()
-+                else:
-+                    password = self.obj.get_existing_password()
-+
-+            if not override_password:
-+                # verify password by retrieving existing data
-+                opts = options.copy()
-+                opts['password'] = password
-+                try:
-+                    self.api.Command.vault_retrieve(*args, **opts)
-+                except errors.NotFound:
-+                    pass
- 
-             salt = vault['ipavaultsalt'][0]
- 
-diff --git a/ipatests/test_xmlrpc/test_vault_plugin.py b/ipatests/test_xmlrpc/test_vault_plugin.py
-index fe2f2f67d664e0640fdda99fd3e2f068ee61cb01..40ce46406702740ef5a781c3d3569b4f2e088b92 100644
---- a/ipatests/test_xmlrpc/test_vault_plugin.py
-+++ b/ipatests/test_xmlrpc/test_vault_plugin.py
-@@ -36,6 +36,7 @@ asymmetric_vault_name = u'asymmetric_test_vault'
- secret = ''.join(map(chr, xrange(0, 256)))
- 
- password = u'password'
-+other_password = u'other_password'
- 
- public_key = """
- -----BEGIN PUBLIC KEY-----
-@@ -79,6 +80,48 @@ kUlCMj24a8XsShzYTWBIyW2ngvGe3pQ9PfjkUdm0LGZjYITCBvgOKw==
- -----END RSA PRIVATE KEY-----
- """
- 
-+other_public_key = """
-+-----BEGIN PUBLIC KEY-----
-+MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAv7E/QLVyKjrgDctZ50U7
-+rmtL7Ks1QLoccp9WvZJ6WI1rYd0fX5FySS4dI6QTNZc6qww8NeNuZtkoxT9m1wkk
-+Rl/3wK7fWNLenH/+VHOaTQc20exg7ztfsO7JIsmKmigtticdR5C4jLfjcOp+WjLH
-+w3zrmrO5SIZ8njxMoDcQJa2vu/t281U/I7ti8ue09FSitIECU05vgmPS+MnXR8HK
-+PxXqrNkjl29mXNbPiByWwlse3Prwved9I7fwgpiHJqUBFudD/0tZ4DWyLG7t9wM1
-+O8gRaRg1r+ENVpmMSvXo4+8+bR3rEYddD5zU7nKXafeuthXlXplae/8uZmCiSI63
-+TwIDAQAB
-+-----END PUBLIC KEY-----
-+"""
-+
-+other_private_key = """
-+-----BEGIN RSA PRIVATE KEY-----
-+MIIEpgIBAAKCAQEAv7E/QLVyKjrgDctZ50U7rmtL7Ks1QLoccp9WvZJ6WI1rYd0f
-+X5FySS4dI6QTNZc6qww8NeNuZtkoxT9m1wkkRl/3wK7fWNLenH/+VHOaTQc20exg
-+7ztfsO7JIsmKmigtticdR5C4jLfjcOp+WjLHw3zrmrO5SIZ8njxMoDcQJa2vu/t2
-+81U/I7ti8ue09FSitIECU05vgmPS+MnXR8HKPxXqrNkjl29mXNbPiByWwlse3Prw
-+ved9I7fwgpiHJqUBFudD/0tZ4DWyLG7t9wM1O8gRaRg1r+ENVpmMSvXo4+8+bR3r
-+EYddD5zU7nKXafeuthXlXplae/8uZmCiSI63TwIDAQABAoIBAQCA+0GFR9F+isjx
-+Xy+qBpKmxLl8kKKvX8r+cSpLOkEqTlW/rqqKgnI0vVuL/L2UJKKsLvpghBxoBZyC
-+RCvtatBGrhIlS0UrHg/9m73Ek1hylfUUAQokTn4PrkwWJSgmm/xOATmZSs5ymNTn
-+yFCmXl69sdNR77YvD5bQXeBtOT+bKXy7yQ1TmYPwwSjL+WSlMV6ZfE3HNVmxPTpk
-+CTFS638cJblWk9MUIy8HIlhu6If2P4RnHr7ZGGivhREayvs0zXcAfqhIyFHruxSE
-+yYnmqH9paWjv5mP3YyLoKr+NUvvxnBr/9wCTt0TKgG8G6rpkHuPDLQni9wUGnew8
-+QdMgFEohAoGBAPH4vaVB5gDVfvIqwJBsBLHpPq72GvxjrM/exD0jIIpXZxz9gCql
-+CmC5b1RS1uy8PMoc/RO4CE7UTLaTesciP6LjTD1RhH3rLLJO8/iVC1RXgMrCLHLm
-+ZQnDhIQGGNQxpvBjQy5ZOWat2dFxYhHN630IFPOtrWsOmJ5HsL1JrjzxAoGBAMrO
-+R1zNwQ42VbJS6AFshZVjmUV2h3REGh4zG/9IqL0Hz493hyCTGoDPLLXIbtkqNqzQ
-+XibSZ9RMVPKKTiNQTx91DTgh4Anz8xUr84tA2iAf3ayNWKi3Y3GhmP2EWp1qYeom
-+kV8Uq0lt4dHZuEo3LuqvbtbzlF9qUXqKS5qy6Tg/AoGBAKCp02o2HjzxhS/QeTmr
-+r1ZeE7PiTzrECAuh01TwzPtuW1XhcEdgfEqK9cPcmT5pIkflBZkhOcr1pdYYiI5O
-+TEigeY/BX6KoE251hALLG9GtpCN82DyWhAH+oy9ySOwj5793eTT+I2HtD1LE4SQH
-+QVQsmJTP/fS2pVl7KnwUvy9RAoGBAKzo2qchNewsHzx+uxgbsnkABfnXaP2T4sDE
-+yqYJCPTB6BFl02vOf9Y6zN/gF8JH333P2bY3xhaXTgXMLXqmSg+D+NVW7HEP8Lyo
-+UGj1zgN9p74qdODEGqETKiFb6vYzcW/1mhP6x18/tDz658k+611kXZge7O288+MK
-+bhNjXrx5AoGBAMox25PcxVgOjCd9+LdUcIOG6LQ971eCH1NKL9YAekICnwMrStbK
-+veCYju6ok4ZWnMiH8MR1jgC39RWtjJZwynCuPXUP2/vZkoVf1tCZyz7dSm8TdS/2
-+5NdOHVy7+NQcEPSm7/FmXdpcR9ZSGAuxMBfnEUibdyz5LdJGnFUN/+HS
-+-----END RSA PRIVATE KEY-----
-+"""
-+
- 
- class test_vault_plugin(Declarative):
- 
-@@ -580,6 +623,48 @@ class test_vault_plugin(Declarative):
-         },
- 
-         {
-+            'desc': 'Change standard vault to symmetric vault',
-+            'command': (
-+                'vault_mod',
-+                [standard_vault_name],
-+                {
-+                    'ipavaulttype': u'symmetric',
-+                    'new_password': password,
-+                },
-+            ),
-+            'expected': {
-+                'value': standard_vault_name,
-+                'summary': u'Modified vault "%s"' % standard_vault_name,
-+                'result': {
-+                    'cn': [standard_vault_name],
-+                    'ipavaulttype': [u'symmetric'],
-+                    'ipavaultsalt': [fuzzy_string],
-+                    'owner_user': [u'admin'],
-+                },
-+            },
-+        },
-+
-+        {
-+            'desc': 'Retrieve secret from standard vault converted to '
-+                    'symmetric vault',
-+            'command': (
-+                'vault_retrieve',
-+                [standard_vault_name],
-+                {
-+                    'password': password,
-+                },
-+            ),
-+            'expected': {
-+                'value': standard_vault_name,
-+                'summary': 'Retrieved data from vault "%s"'
-+                           % standard_vault_name,
-+                'result': {
-+                    'data': secret,
-+                },
-+            },
-+        },
-+
-+        {
-             'desc': 'Create symmetric vault',
-             'command': (
-                 'vault_add',
-@@ -642,6 +727,90 @@ class test_vault_plugin(Declarative):
-         },
- 
-         {
-+            'desc': 'Change symmetric vault password',
-+            'command': (
-+                'vault_mod',
-+                [symmetric_vault_name],
-+                {
-+                    'old_password': password,
-+                    'new_password': other_password,
-+                },
-+            ),
-+            'expected': {
-+                'value': symmetric_vault_name,
-+                'summary': u'Modified vault "%s"' % symmetric_vault_name,
-+                'result': {
-+                    'cn': [symmetric_vault_name],
-+                    'ipavaulttype': [u'symmetric'],
-+                    'ipavaultsalt': [fuzzy_string],
-+                    'owner_user': [u'admin'],
-+                },
-+            },
-+        },
-+
-+        {
-+            'desc': 'Retrieve secret from symmetric vault with new password',
-+            'command': (
-+                'vault_retrieve',
-+                [symmetric_vault_name],
-+                {
-+                    'password': other_password,
-+                },
-+            ),
-+            'expected': {
-+                'value': symmetric_vault_name,
-+                'summary': 'Retrieved data from vault "%s"'
-+                           % symmetric_vault_name,
-+                'result': {
-+                    'data': secret,
-+                },
-+            },
-+        },
-+
-+        {
-+            'desc': 'Change symmetric vault to asymmetric vault',
-+            'command': (
-+                'vault_mod',
-+                [symmetric_vault_name],
-+                {
-+                    'ipavaulttype': u'asymmetric',
-+                    'old_password': other_password,
-+                    'ipavaultpublickey': public_key,
-+                },
-+            ),
-+            'expected': {
-+                'value': symmetric_vault_name,
-+                'summary': u'Modified vault "%s"' % symmetric_vault_name,
-+                'result': {
-+                    'cn': [symmetric_vault_name],
-+                    'ipavaulttype': [u'asymmetric'],
-+                    'ipavaultpublickey': [public_key],
-+                    'owner_user': [u'admin'],
-+                },
-+            },
-+        },
-+
-+        {
-+            'desc': 'Retrieve secret from symmetric vault converted to '
-+                    'asymmetric vault',
-+            'command': (
-+                'vault_retrieve',
-+                [symmetric_vault_name],
-+                {
-+                    'private_key': private_key,
-+                },
-+            ),
-+            'expected': {
-+                'value': symmetric_vault_name,
-+                'summary': 'Retrieved data from vault "%s"'
-+                           % symmetric_vault_name,
-+                'result': {
-+                    'data': secret,
-+                },
-+            },
-+        },
-+
-+        {
-             'desc': 'Create asymmetric vault',
-             'command': (
-                 'vault_add',
-@@ -702,4 +871,84 @@ class test_vault_plugin(Declarative):
-             },
-         },
- 
-+        {
-+            'desc': 'Change asymmetric vault keys',
-+            'command': (
-+                'vault_mod',
-+                [asymmetric_vault_name],
-+                {
-+                    'private_key': private_key,
-+                    'ipavaultpublickey': other_public_key,
-+                },
-+            ),
-+            'expected': {
-+                'value': asymmetric_vault_name,
-+                'summary': u'Modified vault "%s"' % asymmetric_vault_name,
-+                'result': {
-+                    'cn': [asymmetric_vault_name],
-+                    'ipavaulttype': [u'asymmetric'],
-+                    'ipavaultpublickey': [other_public_key],
-+                    'owner_user': [u'admin'],
-+                },
-+            },
-+        },
-+
-+        {
-+            'desc': 'Retrieve secret from asymmetric vault with new keys',
-+            'command': (
-+                'vault_retrieve',
-+                [asymmetric_vault_name],
-+                {
-+                    'private_key': other_private_key,
-+                },
-+            ),
-+            'expected': {
-+                'value': asymmetric_vault_name,
-+                'summary': 'Retrieved data from vault "%s"'
-+                           % asymmetric_vault_name,
-+                'result': {
-+                    'data': secret,
-+                },
-+            },
-+        },
-+
-+        {
-+            'desc': 'Change asymmetric vault to standard vault',
-+            'command': (
-+                'vault_mod',
-+                [asymmetric_vault_name],
-+                {
-+                    'ipavaulttype': u'standard',
-+                    'private_key': other_private_key,
-+                },
-+            ),
-+            'expected': {
-+                'value': asymmetric_vault_name,
-+                'summary': u'Modified vault "%s"' % asymmetric_vault_name,
-+                'result': {
-+                    'cn': [asymmetric_vault_name],
-+                    'ipavaulttype': [u'standard'],
-+                    'owner_user': [u'admin'],
-+                },
-+            },
-+        },
-+
-+        {
-+            'desc': 'Retrieve secret from asymmetric vault converted to '
-+                    'standard vault',
-+            'command': (
-+                'vault_retrieve',
-+                [asymmetric_vault_name],
-+                {},
-+            ),
-+            'expected': {
-+                'value': asymmetric_vault_name,
-+                'summary': 'Retrieved data from vault "%s"'
-+                           % asymmetric_vault_name,
-+                'result': {
-+                    'data': secret,
-+                },
-+            },
-+        },
-+
-     ]
--- 
-2.4.3
-
diff --git a/SOURCES/0093-trust-make-sure-ID-range-is-created-for-the-child-do.patch b/SOURCES/0093-trust-make-sure-ID-range-is-created-for-the-child-do.patch
new file mode 100644
index 0000000..eab6add
--- /dev/null
+++ b/SOURCES/0093-trust-make-sure-ID-range-is-created-for-the-child-do.patch
@@ -0,0 +1,71 @@
+From 590c3649471832092a20a5eaf09ed0418ae468f6 Mon Sep 17 00:00:00 2001
+From: Alexander Bokovoy <abokovoy@redhat.com>
+Date: Sat, 6 Aug 2016 11:12:13 +0300
+Subject: [PATCH] trust: make sure ID range is created for the child domain
+ even if it exists
+
+ID ranges for child domains of a forest trust were created incorrectly
+in FreeIPA 4.4.0 due to refactoring of -- if the domain was already
+existing, we never attempted to create the ID range for it.
+
+At the same time, when domain was missing, we attempted to add ID range
+and passed both forest root and the child domain names to add_range().
+However, add_range() only looks at the first positional argument which
+was the forest root name. That ID range always exists (it is created
+before child domains are processed).
+
+Modify the code to make sure child domain name is passed as the first
+positional argument. In addition, the oddjob helper should explicitly
+set context='server' so that idrange code will be able to see and use
+ipaserver/dcerpc.py helpers.
+
+Resolves: https://fedorahosted.org/freeipa/ticket/5738
+Reviewed-By: Martin Babinsky <mbabinsk@redhat.com>
+---
+ install/oddjob/com.redhat.idm.trust-fetch-domains |  2 +-
+ ipaserver/plugins/trust.py                        | 10 +++++++---
+ 2 files changed, 8 insertions(+), 4 deletions(-)
+
+diff --git a/install/oddjob/com.redhat.idm.trust-fetch-domains b/install/oddjob/com.redhat.idm.trust-fetch-domains
+index 7c948fd53bd54bf3638ef3cc4407576b9011f4fb..bffa021cd4f01d31b7271d1ad84420884ce8d99e 100755
+--- a/install/oddjob/com.redhat.idm.trust-fetch-domains
++++ b/install/oddjob/com.redhat.idm.trust-fetch-domains
+@@ -76,7 +76,7 @@ env._bootstrap(debug=options.debug, log=None)
+ env._finalize_core(**dict(DEFAULT_CONFIG))
+ 
+ # Initialize the API with the proper debug level
+-api.bootstrap(in_server=True, debug=env.debug, log=None)
++api.bootstrap(in_server=True, debug=env.debug, log=None, context='server')
+ api.finalize()
+ 
+ # Only import trust plugin after api is initialized or internal imports
+diff --git a/ipaserver/plugins/trust.py b/ipaserver/plugins/trust.py
+index 8a25b560f9ae086ba8524cca22f39e8f67696146..b9d9b122a90de62946307b99b44932129eb611e8 100644
+--- a/ipaserver/plugins/trust.py
++++ b/ipaserver/plugins/trust.py
+@@ -1690,15 +1690,19 @@ def add_new_domains_from_trust(myapi, trustinstance, trust_entry, domains, **opt
+             if 'raw' in options:
+                 dom['raw'] = options['raw']
+ 
+-            res = myapi.Command.trustdomain_add(trust_name, name, **dom)
+-            result.append(res['result'])
++            try:
++                res = myapi.Command.trustdomain_add(trust_name, name, **dom)
++                result.append(res['result'])
++            except errors.DuplicateEntry:
++                # Ignore updating duplicate entries
++                pass
+ 
+             if idrange_type != u'ipa-ad-trust-posix':
+                 range_name = name.upper() + '_id_range'
+                 dom['range_type'] = u'ipa-ad-trust'
+                 add_range(myapi, trustinstance,
+                           range_name, dom['ipanttrusteddomainsid'],
+-                          trust_name, name, **dom)
++                          name, **dom)
+         except errors.DuplicateEntry:
+             # Ignore updating duplicate entries
+             pass
+-- 
+2.7.4
+
diff --git a/SOURCES/0094-ipa-kdb-simplify-trusted-domain-parent-search.patch b/SOURCES/0094-ipa-kdb-simplify-trusted-domain-parent-search.patch
new file mode 100644
index 0000000..416bba9
--- /dev/null
+++ b/SOURCES/0094-ipa-kdb-simplify-trusted-domain-parent-search.patch
@@ -0,0 +1,87 @@
+From 6c69ea75765b93768ccc3cf55a4813f2d4b81dac Mon Sep 17 00:00:00 2001
+From: Alexander Bokovoy <abokovoy@redhat.com>
+Date: Sun, 7 Aug 2016 21:42:14 +0300
+Subject: [PATCH] ipa-kdb: simplify trusted domain parent search
+
+In terms of cross-forest trust parent domain is the root domain of
+the forest because we only have trust established with the forest root.
+
+In FreeIPA LDAP store all sub-domains stored in cn=<forest root>,
+cn=ad,cn=trusts,... subtree. Thus, a first RDN after cn=ad is the
+forest root domain. This allows us to simplify logic of finding
+the parent domain.
+
+For complex hierachical forests with more than two levels of
+sub-domains, this will still be true because of the forest trust:
+as forest trust is established to the forest root domain, any
+communication to any sub-domain must traverse forest root domain's
+domain controller.
+
+Note that SSSD also generated incorrectly CA paths information
+for forests with non-hierarchical tree-roots. In such cases
+IPA KDC got confused and mistakenly assumed direct trust to the
+non-hierarchical tree-root instead of going through the forest
+root domain. See https://fedorahosted.org/sssd/ticket/3103 for
+details.
+
+Resolves: https://fedorahosted.org/freeipa/ticket/5738
+Reviewed-By: Martin Babinsky <mbabinsk@redhat.com>
+---
+ daemons/ipa-kdb/ipa_kdb_mspac.c | 27 ++++++++++++++-------------
+ 1 file changed, 14 insertions(+), 13 deletions(-)
+
+diff --git a/daemons/ipa-kdb/ipa_kdb_mspac.c b/daemons/ipa-kdb/ipa_kdb_mspac.c
+index 80e7055fd6cd7b962eeffbccc675a73d73700793..76e9e99d0b691d06ccc86e0e851fb7e226d62597 100644
+--- a/daemons/ipa-kdb/ipa_kdb_mspac.c
++++ b/daemons/ipa-kdb/ipa_kdb_mspac.c
+@@ -2420,6 +2420,7 @@ krb5_error_code ipadb_mspac_get_trusted_domains(struct ipadb_context *ipactx)
+     char *base = NULL;
+     char *dnstr = NULL;
+     char *dnl = NULL;
++    LDAPDN dn = NULL;
+     char **sid_blacklist_incoming = NULL;
+     char **sid_blacklist_outgoing = NULL;
+     int ret, n, i;
+@@ -2547,26 +2548,26 @@ krb5_error_code ipadb_mspac_get_trusted_domains(struct ipadb_context *ipactx)
+             goto done;
+         }
+ 
+-        /* Note that after ldap_str2rdn() call dnl will point to end of one RDN
+-         * which would be '\0' for trust root domain and ',' for subdomain */
+         dnl--; dnl[0] = '\0';
+-        ret = ldap_str2rdn(dnstr, &rdn, &dnl, LDAP_DN_FORMAT_LDAPV3);
++        /* Create a DN, which is now everything before the base,
++         * to get list of rdn values -- the last one would be a root domain.
++         * Since with cross-forest trust we have to route everything via root
++         * domain, that is enough for us to assign parentship. */
++        ret = ldap_str2dn(dnstr, &dn, LDAP_DN_FORMAT_LDAPV3);
+         if (ret) {
+             goto done;
+         }
+ 
+-        ldap_rdnfree(rdn);
+-
+-        if (dnl[0] != '\0') {
+-            dnl++;
+-            ret = ldap_str2rdn(dnl, &rdn, &dnl, LDAP_DN_FORMAT_LDAPV3);
+-            if (ret) {
+-                goto done;
+-            }
+-            t[n].parent_name = strndup(rdn[0]->la_value.bv_val, rdn[0]->la_value.bv_len);
+-            ldap_rdnfree(rdn);
++        rdn = NULL;
++        for (i = 0; dn[i] != NULL; i++) {
++            rdn = dn[i];
+         }
+ 
++        /* We should have a single AVA in the domain RDN */
++        t[n].parent_name = strndup(rdn[0]->la_value.bv_val, rdn[0]->la_value.bv_len);
++
++        ldap_dnfree(dn);
++
+         free(dnstr);
+         dnstr = NULL;
+     }
+-- 
+2.7.4
+
diff --git a/SOURCES/0094-vault-change-default-vault-type-to-symmetric.patch b/SOURCES/0094-vault-change-default-vault-type-to-symmetric.patch
deleted file mode 100644
index 791afdb..0000000
--- a/SOURCES/0094-vault-change-default-vault-type-to-symmetric.patch
+++ /dev/null
@@ -1,115 +0,0 @@
-From 1c3faaeec41e54896536f2a3f2c3a2034d99bbdf Mon Sep 17 00:00:00 2001
-From: Petr Vobornik <pvoborni@redhat.com>
-Date: Tue, 25 Aug 2015 18:25:50 +0200
-Subject: [PATCH] vault: change default vault type to symmetric
-
-https://fedorahosted.org/freeipa/ticket/5251
-
-Reviewed-By: Martin Basti <mbasti@redhat.com>
----
- API.txt                 |  8 ++++----
- VERSION                 |  4 ++--
- ipalib/plugins/vault.py | 11 ++++++++---
- 3 files changed, 14 insertions(+), 9 deletions(-)
-
-diff --git a/API.txt b/API.txt
-index 8105cfb5ba61cabcf5c0f7e1c6e44dfc0cacc9cb..871ddb5b7ee8b9bbae219eac673d52ad7229edc7 100644
---- a/API.txt
-+++ b/API.txt
-@@ -5411,7 +5411,7 @@ option: Str('addattr*', cli_name='addattr', exclude='webui')
- option: Flag('all', autofill=True, cli_name='all', default=False, exclude='webui')
- option: Str('description?', cli_name='desc')
- option: Bytes('ipavaultpublickey?', cli_name='public_key')
--option: Str('ipavaulttype?', cli_name='type')
-+option: StrEnum('ipavaulttype?', autofill=True, cli_name='type', default=u'symmetric', values=(u'standard', u'symmetric', u'asymmetric'))
- option: Str('password?', cli_name='password')
- option: Str('password_file?', cli_name='password_file')
- option: Str('public_key_file?', cli_name='public_key_file')
-@@ -5431,7 +5431,7 @@ option: Flag('all', autofill=True, cli_name='all', default=False, exclude='webui
- option: Str('description', attribute=True, cli_name='desc', multivalue=False, required=False)
- option: Bytes('ipavaultpublickey', attribute=True, cli_name='public_key', multivalue=False, required=False)
- option: Bytes('ipavaultsalt', attribute=True, cli_name='salt', multivalue=False, required=False)
--option: StrEnum('ipavaulttype', attribute=True, autofill=True, cli_name='type', default=u'standard', multivalue=False, required=False, values=(u'standard', u'symmetric', u'asymmetric'))
-+option: StrEnum('ipavaulttype', attribute=True, autofill=True, cli_name='type', default=u'symmetric', multivalue=False, required=False, values=(u'standard', u'symmetric', u'asymmetric'))
- option: Flag('no_members', autofill=True, default=False, exclude='webui')
- option: Flag('raw', autofill=True, cli_name='raw', default=False, exclude='webui')
- option: Str('service?')
-@@ -5522,7 +5522,7 @@ arg: Str('criteria?', noextrawhitespace=False)
- option: Flag('all', autofill=True, cli_name='all', default=False, exclude='webui')
- option: Str('cn', attribute=True, autofill=False, cli_name='name', maxlength=255, multivalue=False, pattern='^[a-zA-Z0-9_.-]+$', primary_key=True, query=True, required=False)
- option: Str('description', attribute=True, autofill=False, cli_name='desc', multivalue=False, query=True, required=False)
--option: StrEnum('ipavaulttype', attribute=True, autofill=False, cli_name='type', default=u'standard', multivalue=False, query=True, required=False, values=(u'standard', u'symmetric', u'asymmetric'))
-+option: StrEnum('ipavaulttype', attribute=True, autofill=False, cli_name='type', default=u'symmetric', multivalue=False, query=True, required=False, values=(u'standard', u'symmetric', u'asymmetric'))
- option: Flag('no_members', autofill=True, default=False, exclude='webui')
- option: Flag('pkey_only?', autofill=True, default=False)
- option: Flag('raw', autofill=True, cli_name='raw', default=False, exclude='webui')
-@@ -5571,7 +5571,7 @@ option: Str('delattr*', cli_name='delattr', exclude='webui')
- option: Str('description', attribute=True, autofill=False, cli_name='desc', multivalue=False, required=False)
- option: Bytes('ipavaultpublickey', attribute=True, autofill=False, cli_name='public_key', multivalue=False, required=False)
- option: Bytes('ipavaultsalt', attribute=True, autofill=False, cli_name='salt', multivalue=False, required=False)
--option: StrEnum('ipavaulttype', attribute=True, autofill=False, cli_name='type', default=u'standard', multivalue=False, required=False, values=(u'standard', u'symmetric', u'asymmetric'))
-+option: StrEnum('ipavaulttype', attribute=True, autofill=False, cli_name='type', default=u'symmetric', multivalue=False, required=False, values=(u'standard', u'symmetric', u'asymmetric'))
- option: Flag('no_members', autofill=True, default=False, exclude='webui')
- option: Flag('raw', autofill=True, cli_name='raw', default=False, exclude='webui')
- option: Flag('rights', autofill=True, default=False)
-diff --git a/VERSION b/VERSION
-index 3fdd2db88a7b2b6d3bd36ba0d7257c9994bc06af..c102e020bbbec921b0f4a2141d1c768ac093acf8 100644
---- a/VERSION
-+++ b/VERSION
-@@ -90,5 +90,5 @@ IPA_DATA_VERSION=20100614120000
- #                                                      #
- ########################################################
- IPA_API_VERSION_MAJOR=2
--IPA_API_VERSION_MINOR=153
--# Last change: edewata - Added support for changing vault encryption.
-+IPA_API_VERSION_MINOR=154
-+# Last change: pvoborni - change default vault type to 'symmetric'
-diff --git a/ipalib/plugins/vault.py b/ipalib/plugins/vault.py
-index 6a07a76b5b85680536b27fd147d8ec1583bb0bc7..667524465031b6d027afbabeea48871e29c0e1e4 100644
---- a/ipalib/plugins/vault.py
-+++ b/ipalib/plugins/vault.py
-@@ -101,6 +101,7 @@ EXAMPLES:
-  Add a standard vault:
-    ipa vault-add <name>
-        [--user <user>|--service <service>|--shared]
-+       --type standard
- """) + _("""
-  Add a symmetric vault:
-    ipa vault-add <name>
-@@ -311,7 +312,7 @@ class vault(LDAPObject):
-             label=_('Type'),
-             doc=_('Vault type'),
-             values=(u'standard', u'symmetric', u'asymmetric', ),
--            default=u'standard',
-+            default=u'symmetric',
-             autofill=True,
-         ),
-         Bytes(
-@@ -578,10 +579,14 @@ class vault_add(PKQuery, Local):
-             cli_name='desc',
-             doc=_('Vault description'),
-         ),
--        Str(
-+        StrEnum(
-             'ipavaulttype?',
-             cli_name='type',
-+            label=_('Type'),
-             doc=_('Vault type'),
-+            values=(u'standard', u'symmetric', u'asymmetric', ),
-+            default=u'symmetric',
-+            autofill=True,
-         ),
-         Str(
-             'password?',
-@@ -609,7 +614,7 @@ class vault_add(PKQuery, Local):
- 
-     def forward(self, *args, **options):
- 
--        vault_type = options.get('ipavaulttype', u'standard')
-+        vault_type = options.get('ipavaulttype')
-         password = options.get('password')
-         password_file = options.get('password_file')
-         public_key = options.get('ipavaultpublickey')
--- 
-2.4.3
-
diff --git a/SOURCES/0095-Remove-Custodia-server-keys-from-LDAP.patch b/SOURCES/0095-Remove-Custodia-server-keys-from-LDAP.patch
new file mode 100644
index 0000000..c4fdee1
--- /dev/null
+++ b/SOURCES/0095-Remove-Custodia-server-keys-from-LDAP.patch
@@ -0,0 +1,78 @@
+From dd108a1fd1088f6a4f382cccec2aec69c7d9f0fe Mon Sep 17 00:00:00 2001
+From: Christian Heimes <cheimes@redhat.com>
+Date: Mon, 8 Aug 2016 16:06:08 +0200
+Subject: [PATCH] Remove Custodia server keys from LDAP
+
+The server-del plugin now removes the Custodia keys for encryption and
+key signing from LDAP.
+
+https://fedorahosted.org/freeipa/ticket/6015
+
+Reviewed-By: Martin Basti <mbasti@redhat.com>
+---
+ ipalib/constants.py         |  1 +
+ ipaserver/plugins/server.py | 29 +++++++++++++++++++++++++++++
+ 2 files changed, 30 insertions(+)
+
+diff --git a/ipalib/constants.py b/ipalib/constants.py
+index 0574bb3aa457dd79a6d64f6b8a6b57161d32da92..9b351e260f15211330521453b3ffcd41433a04bb 100644
+--- a/ipalib/constants.py
++++ b/ipalib/constants.py
+@@ -124,6 +124,7 @@ DEFAULT_CONFIG = (
+     ('container_locations', DN(('cn', 'locations'), ('cn', 'etc'))),
+     ('container_ca', DN(('cn', 'cas'), ('cn', 'ca'))),
+     ('container_dnsservers', DN(('cn', 'servers'), ('cn', 'dns'))),
++    ('container_custodia', DN(('cn', 'custodia'), ('cn', 'ipa'), ('cn', 'etc'))),
+ 
+     # Ports, hosts, and URIs:
+     ('xmlrpc_uri', 'http://localhost:8888/ipa/xml'),
+diff --git a/ipaserver/plugins/server.py b/ipaserver/plugins/server.py
+index b245dcf72a2f9f32f52ec9acf68d96c69d6169c5..d62c0232c5e33642e44a088dbfd9f10675d733f4 100644
+--- a/ipaserver/plugins/server.py
++++ b/ipaserver/plugins/server.py
+@@ -609,6 +609,32 @@ class server_del(LDAPDelete):
+                     message=_("Failed to remove server %(master)s from server "
+                               "list: %(err)s") % dict(master=master, err=e)))
+ 
++    def _remove_server_custodia_keys(self, ldap, master):
++        """
++        Delete all Custodia encryption and signing keys
++        """
++        conn = self.Backend.ldap2
++        env = self.api.env
++        # search for memberPrincipal=*/fqdn@realm
++        member_filter = ldap.make_filter_from_attr(
++            'memberPrincipal', "/{}@{}".format(master, env.realm),
++            exact=False, leading_wildcard=True, trailing_wildcard=False)
++        custodia_subtree = DN(env.container_custodia, env.basedn)
++        try:
++            entries = conn.get_entries(custodia_subtree,
++                                       ldap.SCOPE_SUBTREE,
++                                       filter=member_filter)
++            for entry in entries:
++                conn.delete_entry(entry)
++        except errors.NotFound:
++            pass
++        except Exception as e:
++            self.add_message(
++                messages.ServerRemovalWarning(
++                    message=_(
++                        "Failed to clean up Custodia keys for "
++                        "%(master)s: %(err)s") % dict(master=master, err=e)))
++
+     def _remove_server_host_services(self, ldap, master):
+         """
+         delete server kerberos key and all its svc principals
+@@ -682,6 +708,9 @@ class server_del(LDAPDelete):
+         # remove the references to master's ldap/http principals
+         self._remove_server_principal_references(pkey)
+ 
++        # remove Custodia encryption and signing keys
++        self._remove_server_custodia_keys(ldap, pkey)
++
+         # finally destroy all Kerberos principals
+         self._remove_server_host_services(ldap, pkey)
+ 
+-- 
+2.7.4
+
diff --git a/SOURCES/0095-fix-missing-information-in-object-metadata.patch b/SOURCES/0095-fix-missing-information-in-object-metadata.patch
deleted file mode 100644
index 5c60f17..0000000
--- a/SOURCES/0095-fix-missing-information-in-object-metadata.patch
+++ /dev/null
@@ -1,51 +0,0 @@
-From 6ed7f2846c04c5b6a570787b8022797c279aaaee Mon Sep 17 00:00:00 2001
-From: Petr Vobornik <pvoborni@redhat.com>
-Date: Tue, 25 Aug 2015 16:26:00 +0200
-Subject: [PATCH] fix missing information in object metadata
-
-Missing 'required' values in takes_params causes Web UI to treat required
-fields as optional.
-
-Regression caused by ba0a1c6b33e2519a48754602413c8379fb1f0ff1
-
-https://fedorahosted.org/freeipa/ticket/5258
-
-Reviewed-By: Martin Basti <mbasti@redhat.com>
----
- ipalib/parameters.py | 17 ++++++++++++++---
- 1 file changed, 14 insertions(+), 3 deletions(-)
-
-diff --git a/ipalib/parameters.py b/ipalib/parameters.py
-index 6cc6f8c9244abb9e895782f40cbdde63b2144d22..5ced5067ed2657962c35d7d675c4ddd822df6a36 100644
---- a/ipalib/parameters.py
-+++ b/ipalib/parameters.py
-@@ -922,12 +922,23 @@ class Param(ReadOnly):
- 
-     def __json__(self):
-         json_dict = {}
--        for key in self.__kw:
--            json_dict[key] = json_serialize(self.__kw[key])
-+        for (a, k, d) in self.kwargs:
-+            if k in (callable, DefaultFrom):
-+                continue
-+            elif isinstance(getattr(self, a), frozenset):
-+                json_dict[a] = [k for k in getattr(self, a, [])]
-+            else:
-+                val = getattr(self, a, '')
-+                if val is None:
-+                    # ignore 'not set' because lack of their presence is
-+                    # the information itself
-+                    continue
-+                json_dict[a] = json_serialize(val)
-+
-         json_dict['class'] = self.__class__.__name__
-         json_dict['name'] = self.name
-         json_dict['type'] = self.type.__name__
--        json_dict['flags'] = json_serialize([f for f in self.flags])
-+
-         return json_dict
- 
- 
--- 
-2.4.3
-
diff --git a/SOURCES/0096-Handled-empty-hostname-in-server-del-command.patch b/SOURCES/0096-Handled-empty-hostname-in-server-del-command.patch
new file mode 100644
index 0000000..0d24e57
--- /dev/null
+++ b/SOURCES/0096-Handled-empty-hostname-in-server-del-command.patch
@@ -0,0 +1,42 @@
+From eddc43e5973cb81d88fe2e88bab5eed72d7d3cff Mon Sep 17 00:00:00 2001
+From: Abhijeet Kasurde <akasurde@redhat.com>
+Date: Tue, 23 Aug 2016 17:34:51 +0530
+Subject: [PATCH] Handled empty hostname in server-del command
+
+Fixes: https://fedorahosted.org/freeipa/ticket/6248
+
+Signed-off-by: Abhijeet Kasurde <akasurde@redhat.com>
+Reviewed-By: Martin Basti <mbasti@redhat.com>
+Reviewed-By: Stanislav Laznicka <slaznick@redhat.com>
+---
+ ipaclient/plugins/server.py | 8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+diff --git a/ipaclient/plugins/server.py b/ipaclient/plugins/server.py
+index 725a2ce95708529bd4e1de7fc364c2aba0d805de..5356dbbf58373eebeab1c8c59ff0e23b374a15f3 100644
+--- a/ipaclient/plugins/server.py
++++ b/ipaclient/plugins/server.py
+@@ -3,7 +3,7 @@
+ #
+ 
+ from ipaclient.frontend import MethodOverride
+-from ipalib import _
++from ipalib import _, errors
+ from ipalib.plugable import Registry
+ 
+ register = Registry()
+@@ -12,6 +12,10 @@ register = Registry()
+ @register(override=True, no_fail=True)
+ class server_del(MethodOverride):
+     def interactive_prompt_callback(self, kw):
++        server_list = kw.get('cn')
++        if not server_list:
++            raise errors.RequirementError(name='cn')
++
+         self.api.Backend.textui.print_plain(
+             _("Removing %(servers)s from replication topology, "
+-              "please wait...") % {'servers': ', '.join(kw['cn'])})
++              "please wait...") % {'servers': ', '.join(server_list)})
+-- 
+2.7.4
+
diff --git a/SOURCES/0096-webui-add-option-to-establish-bidirectional-trust.patch b/SOURCES/0096-webui-add-option-to-establish-bidirectional-trust.patch
deleted file mode 100644
index 0532445..0000000
--- a/SOURCES/0096-webui-add-option-to-establish-bidirectional-trust.patch
+++ /dev/null
@@ -1,46 +0,0 @@
-From 85a5f70811b223edf86ce395b9ec781e788758d1 Mon Sep 17 00:00:00 2001
-From: Petr Vobornik <pvoborni@redhat.com>
-Date: Tue, 25 Aug 2015 17:17:04 +0200
-Subject: [PATCH] webui: add option to establish bidirectional trust
-
-https://fedorahosted.org/freeipa/ticket/5259
-
-Reviewed-By: Tomas Babej <tbabej@redhat.com>
----
- install/ui/src/freeipa/trust.js | 13 ++++++++++++-
- 1 file changed, 12 insertions(+), 1 deletion(-)
-
-diff --git a/install/ui/src/freeipa/trust.js b/install/ui/src/freeipa/trust.js
-index 51cfefb99fe10010385b528af209ad535e88b673..f26e2f21b7c8a97536a0a5cb23484da4173d6463 100644
---- a/install/ui/src/freeipa/trust.js
-+++ b/install/ui/src/freeipa/trust.js
-@@ -172,6 +172,12 @@ return {
-                 widget: 'realm.realm_server'
-             },
-             {
-+                $type: 'checkbox',
-+                name: 'bidirectional',
-+                metadata: '@mc-opt:trust_add:bidirectional',
-+                widget: 'realm.bidirectional'
-+            },
-+            {
-                 name: 'realm_admin',
-                 label: '@i18n:objects.trust.account',
-                 widget: 'method.realm_admin'
-@@ -224,7 +230,12 @@ return {
-                 $type: 'details_section',
-                 name: 'realm',
-                 widgets: [
--                    'realm_server'
-+                    'realm_server',
-+                    {
-+                        $type: 'checkbox',
-+                        name: 'bidirectional',
-+                        tooltip: '@mc-opt:trust_add:bidirectional:doc'
-+                    }
-                 ]
-             },
-             {
--- 
-2.4.3
-
diff --git a/SOURCES/0097-Removed-clear-text-passwords-from-KRA-install-log.patch b/SOURCES/0097-Removed-clear-text-passwords-from-KRA-install-log.patch
deleted file mode 100644
index b5dda55..0000000
--- a/SOURCES/0097-Removed-clear-text-passwords-from-KRA-install-log.patch
+++ /dev/null
@@ -1,95 +0,0 @@
-From bb60e6d76d0dfa8106e195cc830b3ce685e84f77 Mon Sep 17 00:00:00 2001
-From: "Endi S. Dewata" <edewata@redhat.com>
-Date: Sat, 22 Aug 2015 01:14:16 +0200
-Subject: [PATCH] Removed clear text passwords from KRA install log.
-
-The ipa-kra-install tool has been modified to use password files
-instead of clear text passwords when invoking pki tool such that
-the passwords are no longer visible in ipaserver-kra-install.log.
-
-https://fedorahosted.org/freeipa/ticket/5246
-
-Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
----
- ipaplatform/base/paths.py        |  2 ++
- ipaserver/install/krainstance.py | 16 ++++++++--------
- 2 files changed, 10 insertions(+), 8 deletions(-)
-
-diff --git a/ipaplatform/base/paths.py b/ipaplatform/base/paths.py
-index 0dd3c7fda3020264a1ace8f2d13557cfddf18c2d..5c8f25d6ef85fab2b9b30a660cd1c0360dbe9931 100644
---- a/ipaplatform/base/paths.py
-+++ b/ipaplatform/base/paths.py
-@@ -343,6 +343,8 @@ class BasePathNamespace(object):
-     SLAPD_INSTANCE_SOCKET_TEMPLATE = "/var/run/slapd-%s.socket"
-     ALL_SLAPD_INSTANCE_SOCKETS = "/var/run/slapd-*.socket"
-     ADMIN_CERT_PATH = '/root/.dogtag/pki-tomcat/ca_admin.cert'
-+    KRA_NSSDB_PASSWORD_FILE = "/root/.dogtag/pki-tomcat/kra/password.conf"
-+    KRA_PKCS12_PASSWORD_FILE = "/root/.dogtag/pki-tomcat/kra/pkcs12_password.conf"
-     ENTROPY_AVAIL = '/proc/sys/kernel/random/entropy_avail'
-     LDIF2DB = '/usr/sbin/ldif2db'
-     DB2LDIF = '/usr/sbin/db2ldif'
-diff --git a/ipaserver/install/krainstance.py b/ipaserver/install/krainstance.py
-index fa50c3dec897d63b9d3522d196054163f7b3369a..e5cdbf5e7714603041e3f0156e87311994175b18 100644
---- a/ipaserver/install/krainstance.py
-+++ b/ipaserver/install/krainstance.py
-@@ -275,16 +275,16 @@ class KRAInstance(DogtagInstance):
-         # import CA certificate into temporary security database
-         args = ["/usr/bin/pki",
-             "-d", self.agent_db,
--            "-c", self.admin_password,
-+            "-C", paths.KRA_NSSDB_PASSWORD_FILE,
-             "client-cert-import",
-             "--pkcs12", paths.KRACERT_P12,
--            "--pkcs12-password", self.admin_password]
-+            "--pkcs12-password-file", paths.KRA_PKCS12_PASSWORD_FILE]
-         ipautil.run(args)
- 
-         # trust CA certificate
-         args = ["/usr/bin/pki",
-             "-d", self.agent_db,
--            "-c", self.admin_password,
-+            "-C", paths.KRA_NSSDB_PASSWORD_FILE,
-             "client-cert-mod", "Certificate Authority - %s" % api.env.realm,
-             "--trust", "CT,c,"]
-         ipautil.run(args)
-@@ -292,16 +292,16 @@ class KRAInstance(DogtagInstance):
-         # import Dogtag admin certificate into temporary security database
-         args = ["/usr/bin/pki",
-             "-d", self.agent_db,
--            "-c", self.admin_password,
-+            "-C", paths.KRA_NSSDB_PASSWORD_FILE,
-             "client-cert-import",
-             "--pkcs12", paths.DOGTAG_ADMIN_P12,
--            "--pkcs12-password", self.admin_password]
-+            "--pkcs12-password-file", paths.KRA_PKCS12_PASSWORD_FILE]
-         ipautil.run(args)
- 
-         # as Dogtag admin, create ipakra user in KRA
-         args = ["/usr/bin/pki",
-             "-d", self.agent_db,
--            "-c", self.admin_password,
-+            "-C", paths.KRA_NSSDB_PASSWORD_FILE,
-             "-n", "ipa-ca-agent",
-             "kra-user-add", "ipakra",
-             "--fullName", "IPA KRA User"]
-@@ -310,7 +310,7 @@ class KRAInstance(DogtagInstance):
-         # as Dogtag admin, add ipakra into KRA agents group
-         args = ["/usr/bin/pki",
-             "-d", self.agent_db,
--            "-c", self.admin_password,
-+            "-C", paths.KRA_NSSDB_PASSWORD_FILE,
-             "-n", "ipa-ca-agent",
-             "kra-user-membership-add", "ipakra", "Data Recovery Manager Agents"]
-         ipautil.run(args)
-@@ -330,7 +330,7 @@ class KRAInstance(DogtagInstance):
-             # as Dogtag admin, upload and assign ipaCert to ipakra
-             args = ["/usr/bin/pki",
-                 "-d", self.agent_db,
--                "-c", self.admin_password,
-+                "-C", paths.KRA_NSSDB_PASSWORD_FILE,
-                 "-n", "ipa-ca-agent",
-                 "kra-user-cert-add", "ipakra",
-                 "--input", filename]
--- 
-2.4.3
-
diff --git a/SOURCES/0097-Secure-permissions-of-Custodia-server.keys.patch b/SOURCES/0097-Secure-permissions-of-Custodia-server.keys.patch
new file mode 100644
index 0000000..6da375e
--- /dev/null
+++ b/SOURCES/0097-Secure-permissions-of-Custodia-server.keys.patch
@@ -0,0 +1,69 @@
+From f7d3a49f3cf88b5950b11a19785794348d072c20 Mon Sep 17 00:00:00 2001
+From: Christian Heimes <cheimes@redhat.com>
+Date: Mon, 8 Aug 2016 15:05:52 +0200
+Subject: [PATCH] Secure permissions of Custodia server.keys
+
+Custodia's server.keys file contain the private RSA keys for encrypting
+and signing Custodia messages. The file was created with permission 644
+and is only secured by permission 700 of the directory
+/etc/ipa/custodia. The installer and upgrader ensure that the file
+has 600.
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1353936
+https://fedorahosted.org/freeipa/ticket/6056
+
+Reviewed-By: Martin Basti <mbasti@redhat.com>
+---
+ ipapython/secrets/kem.py              | 5 ++++-
+ ipaserver/install/custodiainstance.py | 5 +++++
+ 2 files changed, 9 insertions(+), 1 deletion(-)
+
+diff --git a/ipapython/secrets/kem.py b/ipapython/secrets/kem.py
+index d45efe8cc4fb63ae9d8c0b2c920fd1f9e5331a9d..fb51e64a678bbdec45d690a5223bd61f84ef770e 100644
+--- a/ipapython/secrets/kem.py
++++ b/ipapython/secrets/kem.py
+@@ -1,6 +1,7 @@
+ # Copyright (C) 2015  IPA Project Contributors, see COPYING for license
+ 
+ from __future__ import print_function
++import os
+ from ipaplatform.paths import paths
+ from six.moves.configparser import ConfigParser
+ from ipapython.dn import DN
+@@ -143,7 +144,9 @@ class KEMLdap(iSecLdap):
+ def newServerKeys(path, keyid):
+     skey = JWK(generate='RSA', use='sig', kid=keyid)
+     ekey = JWK(generate='RSA', use='enc', kid=keyid)
+-    with open(path, 'w+') as f:
++    with open(path, 'w') as f:
++        os.fchmod(f.fileno(), 0o600)
++        os.fchown(f.fileno(), 0, 0)
+         f.write('[%s,%s]' % (skey.export(), ekey.export()))
+     return [skey.get_op_key('verify'), ekey.get_op_key('encrypt')]
+ 
+diff --git a/ipaserver/install/custodiainstance.py b/ipaserver/install/custodiainstance.py
+index fd30430bbf9c39e7153986999199474cfca60d09..785f86fc159f2d73184ea5bb3c0303cecde153df 100644
+--- a/ipaserver/install/custodiainstance.py
++++ b/ipaserver/install/custodiainstance.py
+@@ -15,6 +15,7 @@ from jwcrypto.common import json_decode
+ import functools
+ import shutil
+ import os
++import stat
+ import tempfile
+ import pwd
+ 
+@@ -73,6 +74,10 @@ class CustodiaInstance(SimpleServiceInstance):
+         if not sysupgrade.get_upgrade_state("custodia", "installed"):
+             root_logger.info("Custodia service is being configured")
+             self.create_instance()
++        mode = os.stat(self.server_keys).st_mode
++        if stat.S_IMODE(mode) != 0o600:
++            root_logger.info("Secure server.keys mode")
++            os.chmod(self.server_keys, 0o600)
+ 
+     def create_replica(self, master_host_name):
+         suffix = ipautil.realm_to_suffix(self.realm)
+-- 
+2.7.4
+
diff --git a/SOURCES/0098-Require-httpd-2.4.6-31-with-mod_proxy-Unix-socket-su.patch b/SOURCES/0098-Require-httpd-2.4.6-31-with-mod_proxy-Unix-socket-su.patch
new file mode 100644
index 0000000..f8a52c6
--- /dev/null
+++ b/SOURCES/0098-Require-httpd-2.4.6-31-with-mod_proxy-Unix-socket-su.patch
@@ -0,0 +1,45 @@
+From eaa631227fa1a89d55c8dbaa236b7c8a1cdf7d9c Mon Sep 17 00:00:00 2001
+From: Christian Heimes <cheimes@redhat.com>
+Date: Wed, 24 Aug 2016 12:28:47 +0200
+Subject: [PATCH] Require httpd 2.4.6-31 with mod_proxy Unix socket support
+
+httpd 2.4.6-6 does not support mod_proxy ProxyPass for Unix sockets. The
+feature is provided by 2.4.7 upstream was backported to 2.4.6-31
+(bz1168081). It's required to proxy Custodia.
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1168081
+https://httpd.apache.org/docs/trunk/mod/mod_proxy.html#proxypass
+
+https://fedorahosted.org/freeipa/ticket/6251
+
+Signed-off-by: Christian Heimes <cheimes@redhat.com>
+Reviewed-By: Martin Basti <mbasti@redhat.com>
+---
+ freeipa.spec.in | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/freeipa.spec.in b/freeipa.spec.in
+index 29b63c9300b73d82aea88dbcf50f2f6ab5f9e9bd..08343d9f2049680185ddd32428b040824d882d66 100644
+--- a/freeipa.spec.in
++++ b/freeipa.spec.in
+@@ -141,7 +141,7 @@ Requires(post): krb5-server >= %{krb5_base_version}, krb5-server < %{krb5_base_v
+ Requires: krb5-pkinit-openssl
+ Requires: cyrus-sasl-gssapi%{?_isa}
+ Requires: ntp
+-Requires: httpd >= 2.4.6-6
++Requires: httpd >= 2.4.6-31
+ Requires: mod_wsgi
+ Requires: mod_auth_gssapi >= 1.4.0
+ Requires: mod_nss >= 1.0.8-26
+@@ -231,7 +231,7 @@ Summary: Common files used by IPA server
+ Group: System Environment/Base
+ BuildArch: noarch
+ Requires: %{name}-client-common = %{version}-%{release}
+-Requires: httpd >= 2.4.6-6
++Requires: httpd >= 2.4.6-31
+ Requires: systemd-units >= 38
+ Requires: custodia
+ 
+-- 
+2.7.4
+
diff --git a/SOURCES/0098-certprofile-prevent-rename-modrdn.patch b/SOURCES/0098-certprofile-prevent-rename-modrdn.patch
deleted file mode 100644
index 5fab0b7..0000000
--- a/SOURCES/0098-certprofile-prevent-rename-modrdn.patch
+++ /dev/null
@@ -1,30 +0,0 @@
-From 80767a47c9eda6c82f172b87a6a901be9ebf0c9a Mon Sep 17 00:00:00 2001
-From: Fraser Tweedale <ftweedal@redhat.com>
-Date: Mon, 24 Aug 2015 20:25:10 -0400
-Subject: [PATCH] certprofile: prevent rename (modrdn)
-
-Fixes: https://fedorahosted.org/freeipa/ticket/5247
-Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
----
- ipalib/plugins/certprofile.py | 5 +++--
- 1 file changed, 3 insertions(+), 2 deletions(-)
-
-diff --git a/ipalib/plugins/certprofile.py b/ipalib/plugins/certprofile.py
-index 007cc543406b7e5705fd7474f3685cd6a9ce6aca..a0ffa38608400860994c771e4eba81304ead27be 100644
---- a/ipalib/plugins/certprofile.py
-+++ b/ipalib/plugins/certprofile.py
-@@ -323,8 +323,9 @@ class certprofile_mod(LDAPUpdate):
-     def pre_callback(self, ldap, dn, entry_attrs, attrs_list, *keys, **options):
-         ca_enabled_check()
-         # Once a profile id is set it cannot be changed
--        if 'cn' in entry_attrs:
--            raise errors.ACIError(info=_('cn is immutable'))
-+        if 'rename' in options or 'cn' in entry_attrs:
-+            raise errors.ProtectedEntryError(label='certprofile', key=keys[0],
-+                reason=_('Certificate profiles cannot be renamed'))
-         if 'file' in options:
-             with self.api.Backend.ra_certprofile as profile_api:
-                 profile_api.disable_profile(keys[0])
--- 
-2.4.3
-
diff --git a/SOURCES/0099-Fix-ipa-server-install-in-pure-IPv6-environment.patch b/SOURCES/0099-Fix-ipa-server-install-in-pure-IPv6-environment.patch
new file mode 100644
index 0000000..1a66f1f
--- /dev/null
+++ b/SOURCES/0099-Fix-ipa-server-install-in-pure-IPv6-environment.patch
@@ -0,0 +1,34 @@
+From 2dab553e06ce7b01a285c9d80866a6efa80d254d Mon Sep 17 00:00:00 2001
+From: Tomas Krizek <tkrizek@redhat.com>
+Date: Fri, 19 Aug 2016 12:16:54 +0200
+Subject: [PATCH] Fix ipa-server-install in pure IPv6 environment
+
+Installation in pure IPv6 environment failed because pki-tomcat tried to use
+IPv4 loopback. Configuring tomcat to use IPv6 loopback instead of IPv4 fixes
+this issue.
+
+https://fedorahosted.org/freeipa/ticket/4291
+
+Reviewed-By: Martin Basti <mbasti@redhat.com>
+---
+ ipaserver/install/cainstance.py | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/ipaserver/install/cainstance.py b/ipaserver/install/cainstance.py
+index 070498fe8a394802ea55f848a268e2b6563ec472..e94fec5f6fd898b66dc12407be6e3f671ac3f4de 100644
+--- a/ipaserver/install/cainstance.py
++++ b/ipaserver/install/cainstance.py
+@@ -577,6 +577,10 @@ class CAInstance(DogtagInstance):
+             config.set("CA", "pki_external_ca_cert_chain_path", cert_chain_file.name)
+             config.set("CA", "pki_external_step_two", "True")
+ 
++        # PKI IPv6 Configuration
++        config.add_section("Tomcat")
++        config.set("Tomcat", "pki_ajp_host", "::1")
++
+         # Generate configuration file
+         with open(cfg_file, "wb") as f:
+             config.write(f)
+-- 
+2.7.4
+
diff --git a/SOURCES/0099-vault-Limit-size-of-data-stored-in-vault.patch b/SOURCES/0099-vault-Limit-size-of-data-stored-in-vault.patch
deleted file mode 100644
index 3606295..0000000
--- a/SOURCES/0099-vault-Limit-size-of-data-stored-in-vault.patch
+++ /dev/null
@@ -1,57 +0,0 @@
-From a9367de918ae4f28159275b32f1d6d4716de0122 Mon Sep 17 00:00:00 2001
-From: David Kupka <dkupka@redhat.com>
-Date: Wed, 26 Aug 2015 14:11:21 +0200
-Subject: [PATCH] vault: Limit size of data stored in vault
-
-https://fedorahosted.org/freeipa/ticket/5231
-
-Reviewed-By: Petr Vobornik <pvoborni@redhat.com>
----
- ipalib/plugins/vault.py | 21 ++++++++++++++++++++-
- 1 file changed, 20 insertions(+), 1 deletion(-)
-
-diff --git a/ipalib/plugins/vault.py b/ipalib/plugins/vault.py
-index 667524465031b6d027afbabeea48871e29c0e1e4..e369eeee20f5652942681f7c3e268e6173005452 100644
---- a/ipalib/plugins/vault.py
-+++ b/ipalib/plugins/vault.py
-@@ -237,6 +237,7 @@ def validated_read(argname, filename, mode='r', encoding=None):
- 
- register = Registry()
- 
-+MAX_VAULT_DATA_SIZE = 2**20  # = 1 MB
- 
- vault_options = (
-     Str(
-@@ -1233,10 +1234,28 @@ class vault_archive(PKQuery, Local):
-             raise errors.MutuallyExclusiveError(
-                 reason=_('Input data specified multiple times'))
- 
-+        elif data:
-+            if len(data) > MAX_VAULT_DATA_SIZE:
-+                raise errors.ValidationError(name="data", error=_(
-+                    "Size of data exceeds the limit. Current vault data size "
-+                    "limit is %(limit)d B")
-+                    % {'limit': MAX_VAULT_DATA_SIZE})
-+
-         elif input_file:
-+            try:
-+                stat = os.stat(input_file)
-+            except OSError as exc:
-+                raise errors.ValidationError(name="in", error=_(
-+                    "Cannot read file '%(filename)s': %(exc)s")
-+                    % {'filename': input_file, 'exc': exc[1]})
-+            if stat.st_size > MAX_VAULT_DATA_SIZE:
-+                raise errors.ValidationError(name="in", error=_(
-+                    "Size of data exceeds the limit. Current vault data size "
-+                    "limit is %(limit)d B")
-+                    % {'limit': MAX_VAULT_DATA_SIZE})
-             data = validated_read('in', input_file, mode='rb')
- 
--        elif not data:
-+        else:
-             data = ''
- 
-         if self.api.env.in_server:
--- 
-2.4.3
-
diff --git a/SOURCES/0100-ipactl-Do-not-start-stop-restart-single-service-mult.patch b/SOURCES/0100-ipactl-Do-not-start-stop-restart-single-service-mult.patch
deleted file mode 100644
index a6dde81..0000000
--- a/SOURCES/0100-ipactl-Do-not-start-stop-restart-single-service-mult.patch
+++ /dev/null
@@ -1,89 +0,0 @@
-From 92224c6e83ca7ad196478b0057b523b6f2b7d150 Mon Sep 17 00:00:00 2001
-From: David Kupka <dkupka@redhat.com>
-Date: Wed, 26 Aug 2015 15:10:16 +0200
-Subject: [PATCH] ipactl: Do not start/stop/restart single service multiple
- times
-
-In case multiple services are provided by single system daemon
-it is not needed to start/stop/restart it mutiple time.
-
-https://fedorahosted.org/freeipa/ticket/5248
-
-Reviewed-By: Petr Vobornik <pvoborni@redhat.com>
----
- install/tools/ipactl | 17 ++++++++++++++++-
- 1 file changed, 16 insertions(+), 1 deletion(-)
-
-diff --git a/install/tools/ipactl b/install/tools/ipactl
-index 52dfe67ddb65939bc1f431ccc67d9f03114c0454..acad7ff3771561d5dce530317b65aaf117f153a1 100755
---- a/install/tools/ipactl
-+++ b/install/tools/ipactl
-@@ -45,6 +45,16 @@ def check_IPA_configuration():
-         raise IpactlError("IPA is not configured " +
-                           "(see man pages of ipa-server-install for help)", 6)
- 
-+def deduplicate(lst):
-+    new_lst = []
-+    s = set(lst)
-+    for i in lst:
-+        if i in s:
-+            s.remove(i)
-+            new_lst.append(i)
-+
-+    return new_lst
-+
- def is_dirsrv_debugging_enabled():
-     """
-     Check the 389-ds instance to see if debugging is enabled.
-@@ -283,6 +293,7 @@ def ipa_start(options):
-         # no service to start
-         return
- 
-+    svc_list = deduplicate(svc_list)
-     for svc in svc_list:
-         svchandle = services.service(svc)
-         try:
-@@ -321,6 +332,7 @@ def ipa_stop(options):
-             finally:
-                 raise IpactlError()
- 
-+    svc_list = deduplicate(svc_list)
-     for svc in reversed(svc_list):
-         svchandle = services.service(svc)
-         try:
-@@ -398,6 +410,7 @@ def ipa_restart(options):
- 
-     if len(old_svc_list) != 0:
-         # we need to definitely stop some services
-+        old_svc_list = deduplicate(old_svc_list)
-         for svc in reversed(old_svc_list):
-             svchandle = services.service(svc)
-             try:
-@@ -422,7 +435,7 @@ def ipa_restart(options):
- 
-     if len(svc_list) != 0:
-         # there are services to restart
--
-+        svc_list = deduplicate(svc_list)
-         for svc in svc_list:
-             svchandle = services.service(svc)
-             try:
-@@ -444,6 +457,7 @@ def ipa_restart(options):
- 
-     if len(new_svc_list) != 0:
-         # we still need to start some services
-+        new_svc_list = deduplicate(new_svc_list)
-         for svc in new_svc_list:
-             svchandle = services.service(svc)
-             try:
-@@ -494,6 +508,7 @@ def ipa_status(options):
-     if len(svc_list) == 0:
-         return
- 
-+    svc_list = deduplicate(svc_list)
-     for svc in svc_list:
-         svchandle = services.service(svc)
-         try:
--- 
-2.4.3
-
diff --git a/SOURCES/0100-support-multiple-uid-values-in-schema-compatibility-.patch b/SOURCES/0100-support-multiple-uid-values-in-schema-compatibility-.patch
new file mode 100644
index 0000000..58433e2
--- /dev/null
+++ b/SOURCES/0100-support-multiple-uid-values-in-schema-compatibility-.patch
@@ -0,0 +1,53 @@
+From 485e70f9ca0e7352b17839b2375092f7a886bc81 Mon Sep 17 00:00:00 2001
+From: Alexander Bokovoy <abokovoy@redhat.com>
+Date: Thu, 4 Aug 2016 09:58:50 +0300
+Subject: [PATCH] support multiple uid values in schema compatibility tree
+
+https://fedorahosted.org/freeipa/ticket/6138
+
+Reviewed-By: Thierry Bordaz <tbordaz@redhat.com>
+---
+ freeipa.spec.in                         | 4 +++-
+ install/updates/10-schema_compat.update | 4 ++++
+ 2 files changed, 7 insertions(+), 1 deletion(-)
+
+diff --git a/freeipa.spec.in b/freeipa.spec.in
+index 08343d9f2049680185ddd32428b040824d882d66..7456a9ea77ec289312eb11c05709018b3d6d0c90 100644
+--- a/freeipa.spec.in
++++ b/freeipa.spec.in
+@@ -12,9 +12,11 @@
+ %if 0%{?rhel}
+ %global samba_version 4.0.5-1
+ %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
+ %global selinux_policy_version 3.13.1-158.4
++%global slapi_nis_version 0.56.1
+ %endif
+ 
+ %define krb5_base_version %(LC_ALL=C rpm -q --qf '%%{VERSION}' krb5-devel | grep -Eo '^[^.]+\.[^.]+')
+@@ -156,7 +158,7 @@ Requires(pre): systemd-units
+ Requires(post): systemd-units
+ Requires: selinux-policy >= %{selinux_policy_version}
+ Requires(post): selinux-policy-base >= %{selinux_policy_version}
+-Requires: slapi-nis >= 0.56.0
++Requires: slapi-nis >= %{slapi_nis_version}
+ Requires: pki-ca >= 10.3.4
+ Requires: pki-kra >= 10.3.4
+ Requires(preun): python systemd-units
+diff --git a/install/updates/10-schema_compat.update b/install/updates/10-schema_compat.update
+index e4c257d323644a93757e01027d3b8ed62c2ca98c..fbe8703407aacd75baf160630c20835a1b4ddc65 100644
+--- a/install/updates/10-schema_compat.update
++++ b/install/updates/10-schema_compat.update
+@@ -87,3 +87,7 @@ add:schema-compat-entry-attribute: %ifeq("ipauniqueid","%{ipauniqueid}","objectc
+ 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}")
+-- 
+2.7.4
+
diff --git a/SOURCES/0101-cert-renewal-Include-KRA-users-in-Dogtag-LDAP-update.patch b/SOURCES/0101-cert-renewal-Include-KRA-users-in-Dogtag-LDAP-update.patch
deleted file mode 100644
index fb706b1..0000000
--- a/SOURCES/0101-cert-renewal-Include-KRA-users-in-Dogtag-LDAP-update.patch
+++ /dev/null
@@ -1,46 +0,0 @@
-From a4ea0af1fb74ac9bdf9afe1bee62cddf65f5160e Mon Sep 17 00:00:00 2001
-From: Jan Cholasta <jcholast@redhat.com>
-Date: Thu, 27 Aug 2015 07:23:39 +0200
-Subject: [PATCH] cert renewal: Include KRA users in Dogtag LDAP update
-
-https://fedorahosted.org/freeipa/ticket/5253
-
-Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
----
- ipaserver/install/cainstance.py | 13 +++++++++----
- 1 file changed, 9 insertions(+), 4 deletions(-)
-
-diff --git a/ipaserver/install/cainstance.py b/ipaserver/install/cainstance.py
-index 5fd3017e16e0d7ed4b4f8eead0e59266fdaff097..ecd9300036353426097d929918be974cbbb5c69d 100644
---- a/ipaserver/install/cainstance.py
-+++ b/ipaserver/install/cainstance.py
-@@ -1575,7 +1575,7 @@ def update_people_entry(dercert):
- 
-     Returns True or False
-     """
--    base_dn = DN(('ou','People'), ('o','ipaca'))
-+    base_dn = DN(('o', 'ipaca'))
-     serial_number = x509.get_serial_number(dercert, datatype=x509.DER)
-     subject = x509.get_subject(dercert, datatype=x509.DER)
-     issuer = x509.get_issuer(dercert, datatype=x509.DER)
-@@ -1591,9 +1591,14 @@ def update_people_entry(dercert):
-             conn = ldap2.ldap2(api, ldap_uri=dogtag_uri)
-             conn.connect(autobind=True)
- 
--            db_filter = conn.make_filter(
--                {'description': ';%s;%s' % (issuer, subject)},
--                exact=False, trailing_wildcard=False)
-+            db_filter = conn.combine_filters(
-+                [
-+                    conn.make_filter({'objectClass': 'inetOrgPerson'}),
-+                    conn.make_filter(
-+                        {'description': ';%s;%s' % (issuer, subject)},
-+                        exact=False, trailing_wildcard=False),
-+                ],
-+                conn.MATCH_ALL)
-             try:
-                 entries = conn.get_entries(base_dn, conn.SCOPE_SUBTREE, db_filter)
-             except errors.NotFound:
--- 
-2.5.1
-
diff --git a/SOURCES/0101-custodia-include-known-CA-certs-in-the-PKCS-12-file-.patch b/SOURCES/0101-custodia-include-known-CA-certs-in-the-PKCS-12-file-.patch
new file mode 100644
index 0000000..256e70a
--- /dev/null
+++ b/SOURCES/0101-custodia-include-known-CA-certs-in-the-PKCS-12-file-.patch
@@ -0,0 +1,43 @@
+From 70ec9193404463ad62ee6fe14a033425906e6b13 Mon Sep 17 00:00:00 2001
+From: Jan Cholasta <jcholast@redhat.com>
+Date: Tue, 23 Aug 2016 10:39:08 +0200
+Subject: [PATCH] custodia: include known CA certs in the PKCS#12 file for
+ Dogtag
+
+This fixes CA replica install in a topology upgraded from CA-less to
+CA-full.
+
+https://fedorahosted.org/freeipa/ticket/6207
+
+Reviewed-By: Martin Basti <mbasti@redhat.com>
+---
+ ipaserver/install/custodiainstance.py | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/ipaserver/install/custodiainstance.py b/ipaserver/install/custodiainstance.py
+index 785f86fc159f2d73184ea5bb3c0303cecde153df..18bd51426cde09af6a34855a49db386a72cc6b9c 100644
+--- a/ipaserver/install/custodiainstance.py
++++ b/ipaserver/install/custodiainstance.py
+@@ -2,6 +2,7 @@
+ 
+ from ipapython.secrets.kem import IPAKEMKeys
+ from ipapython.secrets.client import CustodiaClient
++from ipaserver.install.certs import CertDB
+ from ipaplatform.paths import paths
+ from ipaplatform.constants import constants
+ from ipaserver.install.service import SimpleServiceInstance
+@@ -154,6 +155,11 @@ class CustodiaInstance(SimpleServiceInstance):
+                              '-i', pk12file,
+                              '-w', pk12pwfile])
+ 
++            # Add CA certificates
++            tmpdb = CertDB(self.realm, nssdir=tmpnssdir)
++            self.suffix = ipautil.realm_to_suffix(self.realm)
++            self.import_ca_certs(tmpdb, True)
++
+             # Now that we gathered all certs, re-export
+             ipautil.run([paths.PKCS12EXPORT,
+                          '-d', tmpnssdir,
+-- 
+2.7.4
+
diff --git a/SOURCES/0102-cert-renewal-Automatically-update-KRA-agent-PEM-file.patch b/SOURCES/0102-cert-renewal-Automatically-update-KRA-agent-PEM-file.patch
deleted file mode 100644
index 0350832..0000000
--- a/SOURCES/0102-cert-renewal-Automatically-update-KRA-agent-PEM-file.patch
+++ /dev/null
@@ -1,45 +0,0 @@
-From f0e3715b39ea2682f4ef689f5d5864e16117fb00 Mon Sep 17 00:00:00 2001
-From: Jan Cholasta <jcholast@redhat.com>
-Date: Thu, 27 Aug 2015 07:37:24 +0200
-Subject: [PATCH] cert renewal: Automatically update KRA agent PEM file
-
-https://fedorahosted.org/freeipa/ticket/5253
-
-Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
----
- install/restart_scripts/renew_ra_cert | 12 +++++++++++-
- 1 file changed, 11 insertions(+), 1 deletion(-)
-
-diff --git a/install/restart_scripts/renew_ra_cert b/install/restart_scripts/renew_ra_cert
-index 1f8fcae6fa09033f7a5c6448e0bbef14a5f76844..93ffd4035723831f3955bcdf5a2082fd1ec5e22a 100644
---- a/install/restart_scripts/renew_ra_cert
-+++ b/install/restart_scripts/renew_ra_cert
-@@ -29,7 +29,7 @@ import traceback
- 
- from ipapython import ipautil
- from ipalib import api
--from ipaserver.install import certs, cainstance
-+from ipaserver.install import certs, cainstance, krainstance
- from ipaplatform import services
- from ipaplatform.paths import paths
- 
-@@ -60,6 +60,16 @@ def _main():
- 
-             # Load it into dogtag
-             cainstance.update_people_entry(dercert)
-+
-+        kra = krainstance.KRAInstance(api.env.realm)
-+        if kra.is_installed():
-+            # export ipaCert with private key for client authentication
-+            args = ["/usr/bin/pki",
-+                    "-d", paths.HTTPD_ALIAS_DIR,
-+                    "-C", paths.ALIAS_PWDFILE_TXT,
-+                    "client-cert-show", "ipaCert",
-+                    "--client-cert", paths.KRA_AGENT_PEM]
-+            ipautil.run(args)
-     finally:
-         shutil.rmtree(tmpdir)
- 
--- 
-2.5.1
-
diff --git a/SOURCES/0102-otptoken-permission-Convert-custom-type-parameters-o.patch b/SOURCES/0102-otptoken-permission-Convert-custom-type-parameters-o.patch
new file mode 100644
index 0000000..017a0ef
--- /dev/null
+++ b/SOURCES/0102-otptoken-permission-Convert-custom-type-parameters-o.patch
@@ -0,0 +1,46 @@
+From 321bd7bf56109c546a92298d54bcaccfe1289800 Mon Sep 17 00:00:00 2001
+From: David Kupka <dkupka@redhat.com>
+Date: Thu, 25 Aug 2016 11:53:39 +0200
+Subject: [PATCH] otptoken, permission: Convert custom type parameters on
+ server
+
+Force client to send the value of ipatokenotpkey and ipapermlocation as
+entered by user.
+
+https://fedorahosted.org/freeipa/ticket/6247
+
+Reviewed-By: Jan Cholasta <jcholast@redhat.com>
+---
+ ipaserver/plugins/otptoken.py   | 2 ++
+ ipaserver/plugins/permission.py | 2 ++
+ 2 files changed, 4 insertions(+)
+
+diff --git a/ipaserver/plugins/otptoken.py b/ipaserver/plugins/otptoken.py
+index 39012e2f9106c33c520e19f14331fc440333015a..0b4250043618b4f434d2f8b337b88ee396c312ce 100644
+--- a/ipaserver/plugins/otptoken.py
++++ b/ipaserver/plugins/otptoken.py
+@@ -214,6 +214,8 @@ class otptoken(LDAPObject):
+             doc=_('Token secret (Base32; default: random)'),
+             default_from=lambda: os.urandom(KEY_LENGTH),
+             autofill=True,
++            # force server-side conversion
++            normalizer=lambda x: x,
+             flags=('no_display', 'no_update', 'no_search'),
+         ),
+         StrEnum('ipatokenotpalgorithm?',
+diff --git a/ipaserver/plugins/permission.py b/ipaserver/plugins/permission.py
+index 830773ae7a09f0197da702e4ec31b0b58f1214dd..0c040ce874534dc4716e700493e547df5b97ea99 100644
+--- a/ipaserver/plugins/permission.py
++++ b/ipaserver/plugins/permission.py
+@@ -283,6 +283,8 @@ class permission(baseldap.LDAPObject):
+             cli_name='subtree',
+             label=_('Subtree'),
+             doc=_('Subtree to apply permissions to'),
++            # force server-side conversion
++            normalizer=lambda x: x,
+             flags={'ask_create'},
+         ),
+         Str(
+-- 
+2.7.4
+
diff --git a/SOURCES/0103-DNSSEC-remove-DNSSEC-is-experimental-warnings.patch b/SOURCES/0103-DNSSEC-remove-DNSSEC-is-experimental-warnings.patch
deleted file mode 100644
index eeb2b27..0000000
--- a/SOURCES/0103-DNSSEC-remove-DNSSEC-is-experimental-warnings.patch
+++ /dev/null
@@ -1,72 +0,0 @@
-From 36d0ae5682bd4e71ba3c27900f4699c07aa27f68 Mon Sep 17 00:00:00 2001
-From: Martin Basti <mbasti@redhat.com>
-Date: Mon, 31 Aug 2015 13:51:02 +0200
-Subject: [PATCH] DNSSEC: remove "DNSSEC is experimental" warnings
-
-https://fedorahosted.org/freeipa/ticket/5265
-
-Reviewed-By: Martin Babinsky <mbabinsk@redhat.com>
----
- ipalib/plugins/dns.py    | 18 ------------------
- ipaserver/install/dns.py |  2 --
- 2 files changed, 20 deletions(-)
-
-diff --git a/ipalib/plugins/dns.py b/ipalib/plugins/dns.py
-index 512a653c3cc8ee641debec0d20f58e17eff08266..a3d562edb186682a872073e6c83a416b6a4cbc09 100644
---- a/ipalib/plugins/dns.py
-+++ b/ipalib/plugins/dns.py
-@@ -2624,22 +2624,6 @@ class dnszone(DNSZoneBase):
-             messages.add_message(options.get('version', VERSION_WITHOUT_CAPABILITIES),
-                                  result, messages.ForwardersWarning())
- 
--    def _warning_dnssec_experimental(self, result, *keys, **options):
--        # add warning when user use option --dnssec
--        if 'idnssecinlinesigning' in options:
--            if options['idnssecinlinesigning'] is True:
--                messages.add_message(options['version'], result,
--                    messages.DNSSECWarning(
--                    additional_info=_("Visit 'http://www.freeipa.org/page/Releases/4.1.0#DNSSEC_Support'.")
--                ))
--            else:
--                messages.add_message(options['version'], result,
--                    messages.DNSSECWarning(
--                    additional_info=_("If you encounter any problems please "
--                    "report them and restart 'named' service on affected IPA "
--                    "server.")
--                ))
--
-     def _warning_name_server_option(self, result, context, **options):
-         if getattr(context, 'show_warning_nameserver_option', False):
-             messages.add_message(
-@@ -2735,7 +2719,6 @@ class dnszone_add(DNSZoneBase_add):
-         result = super(dnszone_add, self).execute(*keys, **options)
-         self._warning_deprecated_option(result, **options)
-         self.obj._warning_forwarding(result, **options)
--        self.obj._warning_dnssec_experimental(result, *keys, **options)
-         self.obj._warning_name_server_option(result, context, **options)
-         self.obj._warning_fw_zone_is_not_effective(result, *keys, **options)
-         return result
-@@ -2826,7 +2809,6 @@ class dnszone_mod(DNSZoneBase_mod):
-     def execute(self, *keys, **options):
-         result = super(dnszone_mod, self).execute(*keys, **options)
-         self.obj._warning_forwarding(result, **options)
--        self.obj._warning_dnssec_experimental(result, *keys, **options)
-         self.obj._warning_name_server_option(result, context, **options)
-         return result
- 
-diff --git a/ipaserver/install/dns.py b/ipaserver/install/dns.py
-index 9430d189978b0984b0b71d7d754516a4135053fb..538e99fbe01a34cee627f1cebd938be19777c134 100644
---- a/ipaserver/install/dns.py
-+++ b/ipaserver/install/dns.py
-@@ -126,8 +126,6 @@ def install_check(standalone, replica, options, hostname):
-         print "NOTE: DNSSEC zone signing is not enabled by default"
-         print ""
-         if options.dnssec_master:
--            print "DNSSEC support is experimental!"
--            print ""
-             print "Plan carefully, replacing DNSSEC key master is not recommended"
-             print ""
-         print ""
--- 
-2.5.1
-
diff --git a/SOURCES/0103-Raise-DuplicatedEnrty-error-when-user-exists-in-dele.patch b/SOURCES/0103-Raise-DuplicatedEnrty-error-when-user-exists-in-dele.patch
new file mode 100644
index 0000000..716b615
--- /dev/null
+++ b/SOURCES/0103-Raise-DuplicatedEnrty-error-when-user-exists-in-dele.patch
@@ -0,0 +1,61 @@
+From ef2480e2a9a10665208a6547fe3d3cb1d4047763 Mon Sep 17 00:00:00 2001
+From: Martin Basti <mbasti@redhat.com>
+Date: Fri, 19 Aug 2016 10:39:40 +0200
+Subject: [PATCH] Raise DuplicatedEnrty error when user exists in
+ delete_container
+
+We do not have right to write to users delete_container. In case that
+user already exists in that container and we tried to add entry, we
+receive ACIError. This must be checked and DuplicationEntry error must
+be raised before.
+
+https://fedorahosted.org/freeipa/ticket/6199
+
+Reviewed-By: Jan Cholasta <jcholast@redhat.com>
+---
+ ipaserver/plugins/user.py | 15 +++++++++++++--
+ 1 file changed, 13 insertions(+), 2 deletions(-)
+
+diff --git a/ipaserver/plugins/user.py b/ipaserver/plugins/user.py
+index 935ea892cde9e2cb5b21f4714fd93e73c3fa53d5..d690f01ab4d155f6b403790a7215e1777f383604 100644
+--- a/ipaserver/plugins/user.py
++++ b/ipaserver/plugins/user.py
+@@ -381,6 +381,10 @@ class user(baseuser):
+         ),
+     )
+ 
++    def get_delete_dn(self, *keys, **options):
++        active_dn = self.get_dn(*keys, **options)
++        return DN(active_dn[0], self.delete_container_dn, api.env.basedn)
++
+     def get_either_dn(self, *keys, **options):
+         '''
+         Returns the DN of a user
+@@ -397,7 +401,7 @@ class user(baseuser):
+             dn = active_dn
+         except errors.NotFound:
+             # Check that this value is a Delete user
+-            delete_dn = DN(active_dn[0], self.delete_container_dn, api.env.basedn)
++            delete_dn = self.get_delete_dn(*keys, **options)
+             try:
+                 ldap.get_entry(delete_dn, ['dn'])
+ 
+@@ -441,7 +445,14 @@ class user_add(baseuser_add):
+     )
+ 
+     def pre_callback(self, ldap, dn, entry_attrs, attrs_list, *keys, **options):
+-        dn = self.obj.get_either_dn(*keys, **options)
++        delete_dn = self.obj.get_delete_dn(*keys, **options)
++        try:
++            ldap.get_entry(delete_dn, [''])
++        except errors.NotFound:
++            pass
++        else:
++            raise self.obj.handle_duplicate_entry(*keys)
++
+         if not options.get('noprivate', False):
+             try:
+                 # The Managed Entries plugin will allow a user to be created
+-- 
+2.7.4
+
diff --git a/SOURCES/0104-Backup-back-up-the-hosts-file.patch b/SOURCES/0104-Backup-back-up-the-hosts-file.patch
deleted file mode 100644
index e581e41..0000000
--- a/SOURCES/0104-Backup-back-up-the-hosts-file.patch
+++ /dev/null
@@ -1,27 +0,0 @@
-From 89b5a01486f8a5200323c753f6ac278d089ba05e Mon Sep 17 00:00:00 2001
-From: Martin Basti <mbasti@redhat.com>
-Date: Tue, 1 Sep 2015 16:24:44 +0200
-Subject: [PATCH] Backup: back up the hosts file
-
-https://fedorahosted.org/freeipa/ticket/5275
-
-Reviewed-By: Martin Babinsky <mbabinsk@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 0ba44b280dfb7c9d9cbbe2470392c3c98ef35bcc..8df1005a222220a0ece95a3691766ed3cd00a0d9 100644
---- a/ipaserver/install/ipa_backup.py
-+++ b/ipaserver/install/ipa_backup.py
-@@ -178,6 +178,7 @@ class Backup(admintool.AdminTool):
-         paths.DNSSEC_SOFTHSM_PIN_SO,
-         paths.IPA_ODS_EXPORTER_KEYTAB,
-         paths.IPA_DNSKEYSYNCD_KEYTAB,
-+        paths.HOSTS,
-     ) + tuple(
-         os.path.join(base, file)
-         for base in (paths.NSS_DB_DIR, paths.IPA_NSSDB_DIR)
--- 
-2.5.1
-
diff --git a/SOURCES/0104-cert-add-missing-param-values-to-cert-find-output.patch b/SOURCES/0104-cert-add-missing-param-values-to-cert-find-output.patch
new file mode 100644
index 0000000..f37807b
--- /dev/null
+++ b/SOURCES/0104-cert-add-missing-param-values-to-cert-find-output.patch
@@ -0,0 +1,32 @@
+From 7bad2b168b2abbfcd0d81afe7f52342648b75bc4 Mon Sep 17 00:00:00 2001
+From: Jan Cholasta <jcholast@redhat.com>
+Date: Mon, 29 Aug 2016 17:49:56 +0200
+Subject: [PATCH] cert: add missing param values to cert-find output
+
+Add back `serial_number_hex` and `revoked` param values to cert-find output
+accidentally removed in commit c718ef058847bb39e78236e8af0ad69ac961bbcf.
+
+https://fedorahosted.org/freeipa/ticket/6269
+
+Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
+---
+ ipaserver/plugins/cert.py | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/ipaserver/plugins/cert.py b/ipaserver/plugins/cert.py
+index 6dd9f6ffcdcd9d051d50d912996fea2104d71dff..a1166a0d0e5b09586832550c055fc6714c3efe26 100644
+--- a/ipaserver/plugins/cert.py
++++ b/ipaserver/plugins/cert.py
+@@ -1083,7 +1083,8 @@ class cert_find(Search, CertMethod):
+                 obj = ra_obj
+                 obj['issuer'] = issuer
+                 obj['subject'] = DN(ra_obj['subject'])
+-                del obj['serial_number_hex']
++                obj['revoked'] = (
++                    ra_obj['status'] in (u'REVOKED', u'REVOKED_EXPIRED'))
+ 
+                 if all:
+                     ra_obj = ra.get_certificate(str(serial_number))
+-- 
+2.7.4
+
diff --git a/SOURCES/0105-certprofile-remove-rename-option.patch b/SOURCES/0105-certprofile-remove-rename-option.patch
deleted file mode 100644
index a3d7d58..0000000
--- a/SOURCES/0105-certprofile-remove-rename-option.patch
+++ /dev/null
@@ -1,74 +0,0 @@
-From 4b6bd162df3eed18c124527467b9beea930169db Mon Sep 17 00:00:00 2001
-From: Fraser Tweedale <ftweedal@redhat.com>
-Date: Tue, 1 Sep 2015 21:04:34 -0400
-Subject: [PATCH] certprofile: remove 'rename' option
-
-The initial fix of ticket 5247 rejected renames, but left the option
-behind for API compatibility.  Remove the option now, according to
-the consensus that because it never worked, it is fine to remove it.
-
-Fixes: https://fedorahosted.org/freeipa/ticket/5247
-Reviewed-By: Petr Vobornik <pvoborni@redhat.com>
----
- API.txt                       | 3 +--
- VERSION                       | 4 ++--
- ipalib/plugins/certprofile.py | 3 +--
- 3 files changed, 4 insertions(+), 6 deletions(-)
-
-diff --git a/API.txt b/API.txt
-index 871ddb5b7ee8b9bbae219eac673d52ad7229edc7..5253e1585e000f39d6e185a94548037dfe54d4d8 100644
---- a/API.txt
-+++ b/API.txt
-@@ -731,7 +731,7 @@ output: Entry('result', <type 'dict'>, Gettext('A dictionary representing an LDA
- output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
- output: PrimaryKey('value', None, None)
- command: certprofile_mod
--args: 1,11,3
-+args: 1,10,3
- arg: Str('cn', attribute=True, cli_name='id', multivalue=False, primary_key=True, query=True, required=True)
- option: Str('addattr*', cli_name='addattr', exclude='webui')
- option: Flag('all', autofill=True, cli_name='all', default=False, exclude='webui')
-@@ -740,7 +740,6 @@ option: Str('description', attribute=True, autofill=False, cli_name='desc', mult
- option: File('file?', cli_name='file')
- option: Bool('ipacertprofilestoreissued', attribute=True, autofill=False, cli_name='store', default=True, multivalue=False, required=False)
- option: Flag('raw', autofill=True, cli_name='raw', default=False, exclude='webui')
--option: Str('rename', cli_name='rename', multivalue=False, primary_key=True, required=False)
- option: Flag('rights', autofill=True, default=False)
- option: Str('setattr*', cli_name='setattr', exclude='webui')
- option: Str('version?', exclude='webui')
-diff --git a/VERSION b/VERSION
-index c102e020bbbec921b0f4a2141d1c768ac093acf8..da721fdd548023dc3dcd9b4f6a8ba72922a3c6f2 100644
---- a/VERSION
-+++ b/VERSION
-@@ -90,5 +90,5 @@ IPA_DATA_VERSION=20100614120000
- #                                                      #
- ########################################################
- IPA_API_VERSION_MAJOR=2
--IPA_API_VERSION_MINOR=154
--# Last change: pvoborni - change default vault type to 'symmetric'
-+IPA_API_VERSION_MINOR=155
-+# Last change: ftweedal - remove certprofile 'rename' option
-diff --git a/ipalib/plugins/certprofile.py b/ipalib/plugins/certprofile.py
-index a0ffa38608400860994c771e4eba81304ead27be..bd835f4c241ba1936555869d481262a8093bbb42 100644
---- a/ipalib/plugins/certprofile.py
-+++ b/ipalib/plugins/certprofile.py
-@@ -115,7 +115,6 @@ class certprofile(LDAPObject):
-     search_attributes = [
-         'cn', 'description', 'ipacertprofilestoreissued'
-     ]
--    rdn_is_primary_key = True
-     label = _('Certificate Profiles')
-     label_singular = _('Certificate Profile')
- 
-@@ -323,7 +322,7 @@ class certprofile_mod(LDAPUpdate):
-     def pre_callback(self, ldap, dn, entry_attrs, attrs_list, *keys, **options):
-         ca_enabled_check()
-         # Once a profile id is set it cannot be changed
--        if 'rename' in options or 'cn' in entry_attrs:
-+        if 'cn' in entry_attrs:
-             raise errors.ProtectedEntryError(label='certprofile', key=keys[0],
-                 reason=_('Certificate profiles cannot be renamed'))
-         if 'file' in options:
--- 
-2.5.1
-
diff --git a/SOURCES/0105-rpcserver-assume-version-1-for-unversioned-command-c.patch b/SOURCES/0105-rpcserver-assume-version-1-for-unversioned-command-c.patch
new file mode 100644
index 0000000..acafde6
--- /dev/null
+++ b/SOURCES/0105-rpcserver-assume-version-1-for-unversioned-command-c.patch
@@ -0,0 +1,130 @@
+From 96bb5ecac07255fd4b6149c617c5ef23b7e7c84f Mon Sep 17 00:00:00 2001
+From: Jan Cholasta <jcholast@redhat.com>
+Date: Mon, 29 Aug 2016 14:49:44 +0200
+Subject: [PATCH] rpcserver: assume version 1 for unversioned command calls
+
+When a command is called on the server over RPC without its version
+specified, assume version 1 instead of the highest known version.
+
+This ensures backward compatibility with old clients, which do not support
+versioned commands and understand only the first version of any given
+command.
+
+https://fedorahosted.org/freeipa/ticket/6217
+
+Reviewed-By: David Kupka <dkupka@redhat.com>
+---
+ ipaserver/rpcserver.py | 43 +++++++++++++++++++++++++++----------------
+ 1 file changed, 27 insertions(+), 16 deletions(-)
+
+diff --git a/ipaserver/rpcserver.py b/ipaserver/rpcserver.py
+index e48dc3498d6ed8feb6ea44a9a678a8b8c50e8d9b..dd446ae849076d350c97ce9cd6c5a704783f39c0 100644
+--- a/ipaserver/rpcserver.py
++++ b/ipaserver/rpcserver.py
+@@ -42,7 +42,7 @@ from ipalib import plugable, errors
+ from ipalib.capabilities import VERSION_WITHOUT_CAPABILITIES
+ from ipalib.frontend import Local
+ from ipalib.backend import Executioner
+-from ipalib.errors import (PublicError, InternalError, CommandError, JSONError,
++from ipalib.errors import (PublicError, InternalError, JSONError,
+     CCacheError, RefererError, InvalidSessionPassword, NotFound, ACIError,
+     ExecutionError, PasswordExpired, KrbPrincipalExpired, UserLocked)
+ from ipalib.request import context, destroy_context
+@@ -311,6 +311,21 @@ class WSGIExecutioner(Executioner):
+         if 'wsgi_dispatch' in self.api.Backend:
+             self.api.Backend.wsgi_dispatch.mount(self, self.key)
+ 
++    def __get_command(self, name):
++        try:
++            # assume version 1 for unversioned command calls
++            command = self.api.Command[name, '1']
++        except KeyError:
++            try:
++                command = self.api.Command[name]
++            except KeyError:
++                command = None
++
++        if command is None or isinstance(command, Local):
++            raise errors.CommandError(name=name)
++
++        return command
++
+     def wsgi_execute(self, environ):
+         result = None
+         error = None
+@@ -319,6 +334,7 @@ class WSGIExecutioner(Executioner):
+         name = None
+         args = ()
+         options = {}
++        command = None
+ 
+         e = None
+         if not 'HTTP_REFERER' in environ:
+@@ -345,11 +361,9 @@ class WSGIExecutioner(Executioner):
+                 (name, args, options, _id) = self.simple_unmarshal(environ)
+             if name in self._system_commands:
+                 result = self._system_commands[name](self, *args, **options)
+-            elif (name not in self.api.Command or
+-                    isinstance(self.api.Command[name], Local)):
+-                raise CommandError(name=name)
+             else:
+-                result = self.Command[name](*args, **options)
++                command = self.__get_command(name)
++                result = command(*args, **options)
+         except PublicError as e:
+             if self.api.env.debug:
+                 self.debug('WSGI wsgi_execute PublicError: %s', traceback.format_exc())
+@@ -363,9 +377,9 @@ class WSGIExecutioner(Executioner):
+             os.environ['LANG'] = lang
+ 
+         principal = getattr(context, 'principal', 'UNKNOWN')
+-        if name and name in self.Command:
++        if command is not None:
+             try:
+-                params = self.Command[name].args_options_2_params(*args, **options)
++                params = command.args_options_2_params(*args, **options)
+             except Exception as e:
+                 self.info(
+                    'exception %s caught when converting options: %s', e.__class__.__name__, str(e)
+@@ -380,7 +394,7 @@ class WSGIExecutioner(Executioner):
+                       type(self).__name__,
+                       principal,
+                       name,
+-                      ', '.join(self.Command[name]._repr_iter(**params)),
++                      ', '.join(command._repr_iter(**params)),
+                       result_string)
+         else:
+             self.info('[%s] %s: %s: %s',
+@@ -698,24 +712,21 @@ class xmlserver(KerberosWSGIExecutioner):
+             # TODO
+             # for now let's not go out of our way to document standard XML-RPC
+             return u'undef'
+-        elif (method_name in self.api.Command and
+-                not isinstance(self.api.Command[method_name], Local)):
++        else:
++            self.__get_command(method_name)
++
+             # All IPA commands return a dict (struct),
+             # and take a params, options - list and dict (array, struct)
+             return [[u'struct', u'array', u'struct']]
+-        else:
+-            raise errors.CommandError(name=method_name)
+ 
+     def methodHelp(self, *params):
+         """get method docstring for XML-RPC introspection"""
+         method_name = self._get_method_name('system.methodHelp', *params)
+         if method_name in self._system_commands:
+             return u''
+-        elif (method_name in self.api.Command and
+-                not isinstance(self.api.Command[method_name], Local)):
+-            return unicode(self.Command[method_name].doc or '')
+         else:
+-            raise errors.CommandError(name=method_name)
++            command = self.__get_command(method_name)
++            return unicode(command.doc or '')
+ 
+     _system_commands = {
+         'system.listMethods': listMethods,
+-- 
+2.7.4
+
diff --git a/SOURCES/0106-Installer-do-not-modify-etc-hosts-before-user-agreem.patch b/SOURCES/0106-Installer-do-not-modify-etc-hosts-before-user-agreem.patch
deleted file mode 100644
index a158b1d..0000000
--- a/SOURCES/0106-Installer-do-not-modify-etc-hosts-before-user-agreem.patch
+++ /dev/null
@@ -1,235 +0,0 @@
-From b6c7247319575a376ac9a480ae6ceda39a2bd968 Mon Sep 17 00:00:00 2001
-From: Martin Basti <mbasti@redhat.com>
-Date: Tue, 1 Sep 2015 19:05:01 +0200
-Subject: [PATCH] Installer: do not modify /etc/hosts before user agreement
-
-https://fedorahosted.org/freeipa/ticket/4561
-
-As side effect this also fixes:
-https://fedorahosted.org/freeipa/ticket/5266
-
-Reviewed-By: David Kupka <dkupka@redhat.com>
----
- ipaserver/install/dns.py                   |  9 ++++++--
- ipaserver/install/installutils.py          | 36 +++++++++++++++++++-----------
- ipaserver/install/server/install.py        | 14 ++++++++++--
- ipaserver/install/server/replicainstall.py | 12 +++++++++-
- 4 files changed, 53 insertions(+), 18 deletions(-)
-
-diff --git a/ipaserver/install/dns.py b/ipaserver/install/dns.py
-index 538e99fbe01a34cee627f1cebd938be19777c134..099e35dc331722607c8ca02cdbc7a0e66f8c4754 100644
---- a/ipaserver/install/dns.py
-+++ b/ipaserver/install/dns.py
-@@ -19,6 +19,7 @@ from ipapython.ipaldap import AUTOBIND_ENABLED
- from ipapython.ipautil import user_input
- from ipaserver.install.installutils import get_server_ip_address
- from ipaserver.install.installutils import read_dns_forwarders
-+from ipaserver.install.installutils import update_hosts_file
- from ipaserver.install import bindinstance
- from ipaserver.install import dnskeysyncinstance
- from ipaserver.install import ntpinstance
-@@ -225,8 +226,8 @@ def install_check(standalone, replica, options, hostname):
-                 "the original kasp.db file." %
-                 ", ".join([str(zone) for zone in dnssec_zones]))
- 
--    ip_addresses = get_server_ip_address(
--        hostname, fstore, options.unattended, True, options.ip_addresses)
-+    ip_addresses = get_server_ip_address(hostname, options.unattended,
-+                                         True, options.ip_addresses)
- 
-     if options.no_forwarders:
-         dns_forwarders = ()
-@@ -277,6 +278,10 @@ def install(standalone, replica, options):
- 
-     conf_ntp = ntpinstance.NTPInstance(fstore).is_enabled()
- 
-+    if standalone:
-+        # otherwise this is done by server/replica installer
-+        update_hosts_file(ip_addresses, api.env.host, fstore)
-+
-     bind = bindinstance.BindInstance(fstore, ldapi=True,
-                                      autobind=AUTOBIND_ENABLED)
-     bind.setup(api.env.host, ip_addresses, api.env.realm, api.env.domain,
-diff --git a/ipaserver/install/installutils.py b/ipaserver/install/installutils.py
-index 02e8526317dbab909ed48a1823000922ce6e6b7a..81a025597c97b41377c35a6714bf1d3001c868cc 100644
---- a/ipaserver/install/installutils.py
-+++ b/ipaserver/install/installutils.py
-@@ -264,7 +264,8 @@ def read_ip_address(host_name, fstore):
- 
-     return ip_parsed
- 
--def read_ip_addresses(host_name, fstore):
-+
-+def read_ip_addresses():
-     ips = []
-     print "Enter the IP address to use, or press Enter to finish."
-     while True:
-@@ -470,7 +471,7 @@ def get_host_name(no_host_dns):
-     verify_fqdn(hostname, no_host_dns)
-     return hostname
- 
--def get_server_ip_address(host_name, fstore, unattended, setup_dns, ip_addresses):
-+def get_server_ip_address(host_name, unattended, setup_dns, ip_addresses):
-     # Check we have a public IP that is associated with the hostname
-     try:
-         hostaddr = resolve_host(host_name)
-@@ -483,8 +484,6 @@ def get_server_ip_address(host_name, fstore, unattended, setup_dns, ip_addresses
-         print >> sys.stderr, "Please fix your /etc/hosts file and restart the setup program"
-         sys.exit(1)
- 
--    ip_add_to_hosts = False
--
-     ips = []
-     if len(hostaddr):
-         for ha in hostaddr:
-@@ -495,7 +494,7 @@ def get_server_ip_address(host_name, fstore, unattended, setup_dns, ip_addresses
- 
-     if not ips and not ip_addresses:
-         if not unattended:
--            ip_addresses = read_ip_addresses(host_name, fstore)
-+            ip_addresses = read_ip_addresses()
- 
-     if ip_addresses:
-         if setup_dns:
-@@ -511,22 +510,16 @@ def get_server_ip_address(host_name, fstore, unattended, setup_dns, ip_addresses
-                 print >>sys.stderr, "Provided but not resolved address(es): %s" % \
-                                     ", ".join(str(ip) for ip in (set(ip_addresses) - set(ips)))
-                 sys.exit(1)
--        ip_add_to_hosts = True
- 
-     if not ips:
-         print >> sys.stderr, "No usable IP address provided nor resolved."
-         sys.exit(1)
- 
-     for ip_address in ips:
--        # check /etc/hosts sanity, add a record when needed
-+        # check /etc/hosts sanity
-         hosts_record = record_in_hosts(str(ip_address))
- 
--        if hosts_record is None:
--            if ip_add_to_hosts or setup_dns:
--                print "Adding ["+str(ip_address)+" "+host_name+"] to your /etc/hosts file"
--                fstore.backup_file(paths.HOSTS)
--                add_record_to_hosts(str(ip_address), host_name)
--        else:
-+        if hosts_record is not None:
-             primary_host = hosts_record[1][0]
-             if primary_host != host_name:
-                 print >>sys.stderr, "Error: there is already a record in /etc/hosts for IP address %s:" \
-@@ -539,6 +532,23 @@ def get_server_ip_address(host_name, fstore, unattended, setup_dns, ip_addresses
- 
-     return ips
- 
-+
-+def update_hosts_file(ip_addresses, host_name, fstore):
-+    """
-+    Update hosts with specified addresses
-+    :param ip_addresses: list of IP addresses
-+    :return:
-+    """
-+    if not fstore.has_file(paths.HOSTS):
-+        fstore.backup_file(paths.HOSTS)
-+    for ip_address in ip_addresses:
-+        if record_in_hosts(str(ip_address)):
-+            continue
-+        print "Adding [{address!s} {name}] to your /etc/hosts file".format(
-+            address=ip_address, name=host_name)
-+        add_record_to_hosts(str(ip_address), host_name)
-+
-+
- def expand_replica_info(filename, password):
-     """
-     Decrypt and expand a replica installation file into a temporary
-diff --git a/ipaserver/install/server/install.py b/ipaserver/install/server/install.py
-index ff517513473a458a84f63c5c1308a8cc0b8699f8..9d7036a7786a35e6aa2429254d62c8afb30970db 100644
---- a/ipaserver/install/server/install.py
-+++ b/ipaserver/install/server/install.py
-@@ -32,7 +32,8 @@ from ipaserver.install import (
-     otpdinstance, replication, service, sysupgrade)
- from ipaserver.install.installutils import (
-     IPA_MODULES, BadHostError, get_fqdn, get_server_ip_address,
--    is_ipa_configured, load_pkcs12, read_password, verify_fqdn)
-+    is_ipa_configured, load_pkcs12, read_password, verify_fqdn,
-+    update_hosts_file)
- from ipaserver.plugins.ldap2 import ldap2
- try:
-     from ipaserver.install import adtrustinstance
-@@ -607,10 +608,15 @@ def install_check(installer):
-         dns.install_check(False, False, options, host_name)
-         ip_addresses = dns.ip_addresses
-     else:
--        ip_addresses = get_server_ip_address(host_name, fstore,
-+        ip_addresses = get_server_ip_address(host_name,
-                                              not installer.interactive, False,
-                                              options.ip_addresses)
- 
-+    # installer needs to update hosts file when DNS subsystem will be
-+    # installed or custom addresses are used
-+    if options.ip_addresses or options.setup_dns:
-+        installer._update_hosts_file = True
-+
-     print
-     print "The IPA Master Server will be configured with:"
-     print "Hostname:       %s" % host_name
-@@ -709,6 +715,9 @@ def install(installer):
-         # configure /etc/sysconfig/network to contain the custom hostname
-         tasks.backup_and_replace_hostname(fstore, sstore, host_name)
- 
-+    if installer._update_hosts_file:
-+        update_hosts_file(ip_addresses, host_name, fstore)
-+
-     # Create DS user/group if it doesn't exist yet
-     dsinstance.create_ds_user()
- 
-@@ -1494,6 +1503,7 @@ class Server(common.Installable, common.Interactive, core.Composite):
-         self._external_cert_file = None
-         self._external_ca_file = None
-         self._ca_cert = None
-+        self._update_hosts_file = False
- 
-         #pylint: disable=no-member
- 
-diff --git a/ipaserver/install/server/replicainstall.py b/ipaserver/install/server/replicainstall.py
-index 0725c7763e505ca0cc5a8892414a3c36c557cf1d..6f9a6141fe9af44806244ce52df59c191dc966b0 100644
---- a/ipaserver/install/server/replicainstall.py
-+++ b/ipaserver/install/server/replicainstall.py
-@@ -502,11 +502,17 @@ def install_check(installer):
- 
-     if options.setup_dns:
-         dns.install_check(False, True, options, config.host_name)
-+        config.ips = dns.ip_addresses
-     else:
-         config.ips = installutils.get_server_ip_address(
--            config.host_name, fstore, not installer.interactive, False,
-+            config.host_name, not installer.interactive, False,
-             options.ip_addresses)
- 
-+    # installer needs to update hosts file when DNS subsystem will be
-+    # installed or custom addresses are used
-+    if options.setup_dns or options.ip_addresses:
-+        installer._update_hosts_file = True
-+
-     # check connection
-     if not options.skip_conncheck:
-         replica_conn_check(
-@@ -528,6 +534,9 @@ def install(installer):
- 
-     dogtag_constants = dogtag.install_constants
- 
-+    if installer._update_hosts_file:
-+        installutils.update_hosts_file(config.ips, config.host_name, fstore)
-+
-     # Create DS user/group if it doesn't exist yet
-     dsinstance.create_ds_user()
- 
-@@ -785,6 +794,7 @@ class Replica(common.Installable, common.Interactive, core.Composite):
- 
-         self._top_dir = None
-         self._config = None
-+        self._update_hosts_file = False
- 
-         #pylint: disable=no-member
- 
--- 
-2.5.1
-
diff --git a/SOURCES/0106-custodia-force-reconnect-before-retrieving-CA-certs-.patch b/SOURCES/0106-custodia-force-reconnect-before-retrieving-CA-certs-.patch
new file mode 100644
index 0000000..c88ceb7
--- /dev/null
+++ b/SOURCES/0106-custodia-force-reconnect-before-retrieving-CA-certs-.patch
@@ -0,0 +1,34 @@
+From d5723c202f45edc17c45a7f2a1970eebed259dd5 Mon Sep 17 00:00:00 2001
+From: Jan Cholasta <jcholast@redhat.com>
+Date: Thu, 1 Sep 2016 10:32:18 +0200
+Subject: [PATCH] custodia: force reconnect before retrieving CA certs from
+ LDAP
+
+Force reconnect to LDAP as DS might have been restarted after the
+connection was opened, rendering the connection invalid.
+
+This fixes a crash in ipa-replica-install with --setup-ca.
+
+https://fedorahosted.org/freeipa/ticket/6207
+
+Reviewed-By: Martin Basti <mbasti@redhat.com>
+---
+ ipaserver/install/custodiainstance.py | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/ipaserver/install/custodiainstance.py b/ipaserver/install/custodiainstance.py
+index 18bd51426cde09af6a34855a49db386a72cc6b9c..32740274ceae17eebeeb32ef5e043cf4b738ee0d 100644
+--- a/ipaserver/install/custodiainstance.py
++++ b/ipaserver/install/custodiainstance.py
+@@ -158,6 +158,8 @@ class CustodiaInstance(SimpleServiceInstance):
+             # Add CA certificates
+             tmpdb = CertDB(self.realm, nssdir=tmpnssdir)
+             self.suffix = ipautil.realm_to_suffix(self.realm)
++            if self.admin_conn is not None:
++                self.ldap_disconnect()
+             self.import_ca_certs(tmpdb, True)
+ 
+             # Now that we gathered all certs, re-export
+-- 
+2.7.4
+
diff --git a/SOURCES/0107-DNSSEC-backup-and-restore-opendnssec-zone-list-file.patch b/SOURCES/0107-DNSSEC-backup-and-restore-opendnssec-zone-list-file.patch
deleted file mode 100644
index b07436f..0000000
--- a/SOURCES/0107-DNSSEC-backup-and-restore-opendnssec-zone-list-file.patch
+++ /dev/null
@@ -1,43 +0,0 @@
-From 7b04b9e603bf6517458cccae7509e99f10c8a0ec Mon Sep 17 00:00:00 2001
-From: Martin Basti <mbasti@redhat.com>
-Date: Tue, 1 Sep 2015 12:10:00 +0200
-Subject: [PATCH] DNSSEC: backup and restore opendnssec zone list file
-
-When zone list is not restored after unninstall, this may slow down
-enbaling DNSSEC signing for zones and print unwanted
-errors into log after new installation.
-
-Related to: https://fedorahosted.org/freeipa/ticket/5273
-
-Reviewed-By: Petr Spacek <pspacek@redhat.com>
----
- ipaserver/install/opendnssecinstance.py | 6 +++++-
- 1 file changed, 5 insertions(+), 1 deletion(-)
-
-diff --git a/ipaserver/install/opendnssecinstance.py b/ipaserver/install/opendnssecinstance.py
-index 0f1af828ea245046330fdfab77db130ca14faba3..c5377d910d8f38a1ea0e05461ecf1b92f05ca2ca 100644
---- a/ipaserver/install/opendnssecinstance.py
-+++ b/ipaserver/install/opendnssecinstance.py
-@@ -171,6 +171,9 @@ class OpenDNSSECInstance(service.Service):
-         if not self.fstore.has_file(paths.OPENDNSSEC_KASP_FILE):
-             self.fstore.backup_file(paths.OPENDNSSEC_KASP_FILE)
- 
-+        if not self.fstore.has_file(paths.OPENDNSSEC_ZONELIST_FILE):
-+            self.fstore.backup_file(paths.OPENDNSSEC_ZONELIST_FILE)
-+
-         pin_fd = open(paths.DNSSEC_SOFTHSM_PIN, "r")
-         pin = pin_fd.read()
-         pin_fd.close()
-@@ -357,7 +360,8 @@ class OpenDNSSECInstance(service.Service):
-                                  paths.IPA_KASP_DB_BACKUP)
- 
-         for f in [paths.OPENDNSSEC_CONF_FILE, paths.OPENDNSSEC_KASP_FILE,
--                  paths.OPENDNSSEC_KASP_DB, paths.SYSCONFIG_ODS]:
-+                  paths.OPENDNSSEC_KASP_DB, paths.SYSCONFIG_ODS,
-+                  paths.OPENDNSSEC_ZONELIST_FILE]:
-             try:
-                 self.fstore.restore_file(f)
-             except ValueError, error:
--- 
-2.5.1
-
diff --git a/SOURCES/0107-rpcserver-fix-crash-in-XML-RPC-system-commands.patch b/SOURCES/0107-rpcserver-fix-crash-in-XML-RPC-system-commands.patch
new file mode 100644
index 0000000..4bd2649
--- /dev/null
+++ b/SOURCES/0107-rpcserver-fix-crash-in-XML-RPC-system-commands.patch
@@ -0,0 +1,59 @@
+From 71910b902993cb0b263bc5a6483fcce733820c80 Mon Sep 17 00:00:00 2001
+From: Jan Cholasta <jcholast@redhat.com>
+Date: Thu, 1 Sep 2016 09:59:37 +0200
+Subject: [PATCH] rpcserver: fix crash in XML-RPC system commands
+
+Fix an AttributeError in XML-RPC methodSignature and methodHelp commands
+caused by incorrect mangled name usage.
+
+https://fedorahosted.org/freeipa/ticket/6217
+
+Reviewed-By: Lenka Doudova <ldoudova@redhat.com>
+Reviewed-By: David Kupka <dkupka@redhat.com>
+---
+ ipaserver/rpcserver.py | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/ipaserver/rpcserver.py b/ipaserver/rpcserver.py
+index dd446ae849076d350c97ce9cd6c5a704783f39c0..f1d5a40694f015fd7f9ad05836ec55c6906d764e 100644
+--- a/ipaserver/rpcserver.py
++++ b/ipaserver/rpcserver.py
+@@ -311,7 +311,7 @@ class WSGIExecutioner(Executioner):
+         if 'wsgi_dispatch' in self.api.Backend:
+             self.api.Backend.wsgi_dispatch.mount(self, self.key)
+ 
+-    def __get_command(self, name):
++    def _get_command(self, name):
+         try:
+             # assume version 1 for unversioned command calls
+             command = self.api.Command[name, '1']
+@@ -362,7 +362,7 @@ class WSGIExecutioner(Executioner):
+             if name in self._system_commands:
+                 result = self._system_commands[name](self, *args, **options)
+             else:
+-                command = self.__get_command(name)
++                command = self._get_command(name)
+                 result = command(*args, **options)
+         except PublicError as e:
+             if self.api.env.debug:
+@@ -713,7 +713,7 @@ class xmlserver(KerberosWSGIExecutioner):
+             # for now let's not go out of our way to document standard XML-RPC
+             return u'undef'
+         else:
+-            self.__get_command(method_name)
++            self._get_command(method_name)
+ 
+             # All IPA commands return a dict (struct),
+             # and take a params, options - list and dict (array, struct)
+@@ -725,7 +725,7 @@ class xmlserver(KerberosWSGIExecutioner):
+         if method_name in self._system_commands:
+             return u''
+         else:
+-            command = self.__get_command(method_name)
++            command = self._get_command(method_name)
+             return unicode(command.doc or '')
+ 
+     _system_commands = {
+-- 
+2.7.4
+
diff --git a/SOURCES/0108-DNSSEC-remove-ccache-and-keytab-of-ipa-ods-exporter.patch b/SOURCES/0108-DNSSEC-remove-ccache-and-keytab-of-ipa-ods-exporter.patch
deleted file mode 100644
index bb67a96..0000000
--- a/SOURCES/0108-DNSSEC-remove-ccache-and-keytab-of-ipa-ods-exporter.patch
+++ /dev/null
@@ -1,63 +0,0 @@
-From 832335c92c7ce21ffb8ea9315837aebc2a085d88 Mon Sep 17 00:00:00 2001
-From: Martin Basti <mbasti@redhat.com>
-Date: Tue, 1 Sep 2015 16:17:16 +0200
-Subject: [PATCH] DNSSEC: remove ccache and keytab of ipa-ods-exporter
-
-Reusing old ccache after reinstall causes authentication error. And
-prevents DNSSEC from working.
-
-Related to ticket: https://fedorahosted.org/freeipa/ticket/5273
-
-Reviewed-By: Petr Spacek <pspacek@redhat.com>
----
- daemons/dnssec/ipa-ods-exporter          | 2 +-
- ipaplatform/base/paths.py                | 1 +
- ipaserver/install/odsexporterinstance.py | 7 +++++++
- 3 files changed, 9 insertions(+), 1 deletion(-)
-
-diff --git a/daemons/dnssec/ipa-ods-exporter b/daemons/dnssec/ipa-ods-exporter
-index 4d5423797fc9d4bdd0a432bac96b8209bb98c6d8..62eca71da10ee6f3efd4d391a274278875714570 100755
---- a/daemons/dnssec/ipa-ods-exporter
-+++ b/daemons/dnssec/ipa-ods-exporter
-@@ -482,7 +482,7 @@ ipalib.api.finalize()
- # Kerberos initialization
- PRINCIPAL = str('%s/%s' % (DAEMONNAME, ipalib.api.env.host))
- log.debug('Kerberos principal: %s', PRINCIPAL)
--ccache_name = os.path.join(WORKDIR, 'ipa-ods-exporter.ccache')
-+ccache_name = paths.IPA_ODS_EXPORTER_CCACHE
- 
- try:
-     ipautil.kinit_keytab(PRINCIPAL, paths.IPA_ODS_EXPORTER_KEYTAB, ccache_name,
-diff --git a/ipaplatform/base/paths.py b/ipaplatform/base/paths.py
-index 5c8f25d6ef85fab2b9b30a660cd1c0360dbe9931..a407c1273f01b3465bcb1985dd41f2f242346a62 100644
---- a/ipaplatform/base/paths.py
-+++ b/ipaplatform/base/paths.py
-@@ -333,6 +333,7 @@ class BasePathNamespace(object):
-     NAMED_RUN = "/var/named/data/named.run"
-     VAR_OPENDNSSEC_DIR = "/var/opendnssec"
-     OPENDNSSEC_KASP_DB = "/var/opendnssec/kasp.db"
-+    IPA_ODS_EXPORTER_CCACHE = "/var/opendnssec/tmp/ipa-ods-exporter.ccache"
-     VAR_RUN_DIRSRV_DIR = "/var/run/dirsrv"
-     KRB5CC_HTTPD = "/var/run/httpd/ipa/krbcache/krb5ccache"
-     IPA_RENEWAL_LOCK = "/var/run/ipa/renewal.lock"
-diff --git a/ipaserver/install/odsexporterinstance.py b/ipaserver/install/odsexporterinstance.py
-index 248943d6c0ca4b71815bcf7526d575842f6ce426..db45d2b812ff6d2d56cb8fb326119658bd1f4b7e 100644
---- a/ipaserver/install/odsexporterinstance.py
-+++ b/ipaserver/install/odsexporterinstance.py
-@@ -93,6 +93,13 @@ class ODSExporterInstance(service.Service):
- 
-     def __setup_principal(self):
-         assert self.ods_uid is not None
-+
-+        for f in [paths.IPA_ODS_EXPORTER_CCACHE, paths.IPA_ODS_EXPORTER_KEYTAB]:
-+            try:
-+                os.remove(f)
-+            except OSError:
-+                pass
-+
-         dns_exporter_principal = "ipa-ods-exporter/" + self.fqdn + "@" + self.realm
-         installutils.kadmin_addprinc(dns_exporter_principal)
- 
--- 
-2.5.1
-
diff --git a/SOURCES/0108-compat-Save-server-s-API-version-in-for-pre-schema-s.patch b/SOURCES/0108-compat-Save-server-s-API-version-in-for-pre-schema-s.patch
new file mode 100644
index 0000000..ea6cd5e
--- /dev/null
+++ b/SOURCES/0108-compat-Save-server-s-API-version-in-for-pre-schema-s.patch
@@ -0,0 +1,346 @@
+From b738ea5d78d7c6d7ba9d72c7cd57fe10f0f1b305 Mon Sep 17 00:00:00 2001
+From: David Kupka <dkupka@redhat.com>
+Date: Tue, 26 Jul 2016 13:35:22 +0200
+Subject: [PATCH] compat: Save server's API version in for pre-schema servers
+
+When client comunicates with server that doesn't support 'schema'
+command it needs to determine its api version to be able to use the
+right compat code. Storing information about server version reduces the
+need to call 'env' or 'ping' command only to first time the server is
+contacted.
+
+https://fedorahosted.org/freeipa/ticket/6069
+
+Reviewed-By: Jan Cholasta <jcholast@redhat.com>
+---
+ ipaclient/remote_plugins/__init__.py | 81 ++++++++++++++++++++++++++++++-
+ ipaclient/remote_plugins/compat.py   | 29 +++++++-----
+ ipaclient/remote_plugins/schema.py   | 92 +++---------------------------------
+ ipaplatform/base/paths.py            | 15 ++++++
+ 4 files changed, 116 insertions(+), 101 deletions(-)
+
+diff --git a/ipaclient/remote_plugins/__init__.py b/ipaclient/remote_plugins/__init__.py
+index 6454a4f4ef956a1ef545b82a649ebf26ef6edd7b..2be9222be693a5c4a04a735c216f590d75c1ecfe 100644
+--- a/ipaclient/remote_plugins/__init__.py
++++ b/ipaclient/remote_plugins/__init__.py
+@@ -2,9 +2,79 @@
+ # Copyright (C) 2016  FreeIPA Contributors see COPYING for license
+ #
+ 
++import collections
++import errno
++import json
++import os
++
+ from . import compat
+ from . import schema
+ from ipaclient.plugins.rpcclient import rpcclient
++from ipaplatform.paths import paths
++from ipapython.dnsutil import DNSName
++from ipapython.ipa_log_manager import log_mgr
++
++logger = log_mgr.get_logger(__name__)
++
++
++class ServerInfo(collections.MutableMapping):
++    _DIR = os.path.join(paths.USER_CACHE_PATH, 'ipa', 'servers')
++
++    def __init__(self, api):
++        hostname = DNSName(api.env.server).ToASCII()
++        self._path = os.path.join(self._DIR, hostname)
++        self._dict = {}
++        self._dirty = False
++
++        self._read()
++
++    def __enter__(self):
++        return self
++
++    def __exit__(self, *_exc_info):
++        self.flush()
++
++    def flush(self):
++        if self._dirty:
++            self._write()
++
++    def _read(self):
++        try:
++            with open(self._path, 'r') as sc:
++                self._dict = json.load(sc)
++        except EnvironmentError as e:
++            if e.errno != errno.ENOENT:
++                logger.warning('Failed to read server info: {}'.format(e))
++
++    def _write(self):
++        try:
++            try:
++                os.makedirs(self._DIR)
++            except EnvironmentError as e:
++                if e.errno != errno.EEXIST:
++                    raise
++            with open(self._path, 'w') as sc:
++                json.dump(self._dict, sc)
++        except EnvironmentError as e:
++            logger.warning('Failed to write server info: {}'.format(e))
++
++    def __getitem__(self, key):
++        return self._dict[key]
++
++    def __setitem__(self, key, value):
++        if key not in self._dict or self._dict[key] != value:
++            self._dirty = True
++        self._dict[key] = value
++
++    def __delitem__(self, key):
++        del self._dict[key]
++        self._dirty = True
++
++    def __iter__(self):
++        return iter(self._dict)
++
++    def __len__(self):
++        return len(self._dict)
+ 
+ 
+ def get_package(api):
+@@ -13,11 +83,18 @@ def get_package(api):
+     else:
+         client = rpcclient(api)
+         client.finalize()
++
++        try:
++            server_info = api._server_info
++        except AttributeError:
++            server_info = api._server_info = ServerInfo(api)
++
+         try:
+-            plugins = schema.get_package(api, client)
++            plugins = schema.get_package(api, server_info, client)
+         except schema.NotAvailable:
+-            plugins = compat.get_package(api, client)
++            plugins = compat.get_package(api, server_info, client)
+         finally:
++            server_info.flush()
+             if client.isconnected():
+                 client.disconnect()
+ 
+diff --git a/ipaclient/remote_plugins/compat.py b/ipaclient/remote_plugins/compat.py
+index aef5718fcaade157487c0e65562c3bc8a11ad7de..b6d099a075deaaa17143f8ddddfb11d97b75f0ed 100644
+--- a/ipaclient/remote_plugins/compat.py
++++ b/ipaclient/remote_plugins/compat.py
+@@ -31,23 +31,26 @@ class CompatObject(Object):
+     pass
+ 
+ 
+-def get_package(api, client):
+-    if not client.isconnected():
+-        client.connect(verbose=False)
+-
+-    env = client.forward(u'env', u'api_version', version=u'2.0')
++def get_package(api, server_info, client):
+     try:
+-        server_version = env['result']['api_version']
++        server_version = server_info['version']
+     except KeyError:
+-        ping = client.forward(u'ping', version=u'2.0')
++        if not client.isconnected():
++            client.connect(verbose=False)
++        env = client.forward(u'env', u'api_version', version=u'2.0')
+         try:
+-            match = re.search(u'API version (2\.[0-9]+)', ping['summary'])
++            server_version = env['result']['api_version']
+         except KeyError:
+-            match = None
+-        if match is not None:
+-            server_version = match.group(1)
+-        else:
+-            server_version = u'2.0'
++            ping = client.forward(u'ping', u'api_version', version=u'2.0')
++            try:
++                match = re.search(u'API version (2\.[0-9]+)', ping['summary'])
++            except KeyError:
++                match = None
++            if match is not None:
++                server_version = match.group(1)
++            else:
++                server_version = u'2.0'
++        server_info['version'] = server_version
+     server_version = LooseVersion(server_version)
+ 
+     package_names = {}
+diff --git a/ipaclient/remote_plugins/schema.py b/ipaclient/remote_plugins/schema.py
+index 8a77a15d489f067ab1312e863178458570403cc6..553da35127188b1ae842a7a0b58433e632c82b9f 100644
+--- a/ipaclient/remote_plugins/schema.py
++++ b/ipaclient/remote_plugins/schema.py
+@@ -22,6 +22,7 @@ from ipalib.errors import SchemaUpToDate
+ from ipalib.frontend import Object
+ from ipalib.output import Output
+ from ipalib.parameters import DefaultFrom, Flag, Password, Str
++from ipaplatform.paths import paths
+ from ipapython.ipautil import fsdecode
+ from ipapython.dn import DN
+ from ipapython.dnsutil import DNSName
+@@ -59,17 +60,6 @@ _PARAMS = {
+     'str': parameters.Str,
+ }
+ 
+-USER_CACHE_PATH = (
+-    os.environ.get('XDG_CACHE_HOME') or
+-    os.path.join(
+-        os.environ.get(
+-            'HOME',
+-            os.path.expanduser('~')
+-        ),
+-        '.cache'
+-    )
+-)
+-
+ logger = log_mgr.get_logger(__name__)
+ 
+ 
+@@ -348,66 +338,6 @@ class NotAvailable(Exception):
+     pass
+ 
+ 
+-class ServerInfo(collections.MutableMapping):
+-    _DIR = os.path.join(USER_CACHE_PATH, 'ipa', 'servers')
+-
+-    def __init__(self, api):
+-        hostname = DNSName(api.env.server).ToASCII()
+-        self._path = os.path.join(self._DIR, hostname)
+-        self._dict = {}
+-        self._dirty = False
+-
+-        self._read()
+-
+-    def __enter__(self):
+-        return self
+-
+-    def __exit__(self, *_exc_info):
+-        self.flush()
+-
+-    def flush(self):
+-        if self._dirty:
+-            self._write()
+-
+-    def _read(self):
+-        try:
+-            with open(self._path, 'r') as sc:
+-                self._dict = json.load(sc)
+-        except EnvironmentError as e:
+-            if e.errno != errno.ENOENT:
+-                logger.warning('Failed to read server info: {}'.format(e))
+-
+-    def _write(self):
+-        try:
+-            try:
+-                os.makedirs(self._DIR)
+-            except EnvironmentError as e:
+-                if e.errno != errno.EEXIST:
+-                    raise
+-            with open(self._path, 'w') as sc:
+-                json.dump(self._dict, sc)
+-        except EnvironmentError as e:
+-            logger.warning('Failed to write server info: {}'.format(e))
+-
+-    def __getitem__(self, key):
+-        return self._dict[key]
+-
+-    def __setitem__(self, key, value):
+-        if key not in self._dict or self._dict[key] != value:
+-            self._dirty = True
+-        self._dict[key] = value
+-
+-    def __delitem__(self, key):
+-        del self._dict[key]
+-        self._dirty = True
+-
+-    def __iter__(self):
+-        return iter(self._dict)
+-
+-    def __len__(self):
+-        return len(self._dict)
+-
+-
+ class Schema(object):
+     """
+     Store and provide schema for commands and topics
+@@ -429,7 +359,7 @@ class Schema(object):
+ 
+     """
+     namespaces = {'classes', 'commands', 'topics'}
+-    _DIR = os.path.join(USER_CACHE_PATH, 'ipa', 'schema', FORMAT)
++    _DIR = os.path.join(paths.USER_CACHE_PATH, 'ipa', 'schema', FORMAT)
+ 
+     def __init__(self, api, server_info, client):
+         self._dict = {}
+@@ -538,8 +468,6 @@ class Schema(object):
+             self._file.write(f.read())
+ 
+         with zipfile.ZipFile(self._file, 'r') as schema:
+-            self._dict['fingerprint'] = self._fingerprint
+-
+             for name in schema.namelist():
+                 ns, _slash, key = name.partition('/')
+                 if ns in self.namespaces:
+@@ -622,22 +550,14 @@ class Schema(object):
+         return self._help[namespace][member]
+ 
+ 
+-def get_package(api, client):
++def get_package(api, server_info, client):
+     try:
+         schema = api._schema
+     except AttributeError:
+-        try:
+-            server_info = api._server_info
+-        except AttributeError:
+-            server_info = api._server_info = ServerInfo(api)
+-
+-        try:
+-            schema = Schema(api, server_info, client)
+-            object.__setattr__(api, '_schema', schema)
+-        finally:
+-            server_info.flush()
++        schema = Schema(api, server_info, client)
++        object.__setattr__(api, '_schema', schema)
+ 
+-    fingerprint = str(schema['fingerprint'])
++    fingerprint = str(server_info['fingerprint'])
+     package_name = '{}${}'.format(__name__, fingerprint)
+     package_dir = '{}${}'.format(os.path.splitext(__file__)[0], fingerprint)
+ 
+diff --git a/ipaplatform/base/paths.py b/ipaplatform/base/paths.py
+index 5ffe689950792a40c179533c8baf2794c2388696..065a2011027bf362abd498d227e24928ccf66724 100644
+--- a/ipaplatform/base/paths.py
++++ b/ipaplatform/base/paths.py
+@@ -21,6 +21,8 @@
+ This base platform module exports default filesystem paths.
+ '''
+ 
++import os
++
+ 
+ class BasePathNamespace(object):
+     BASH = "/bin/bash"
+@@ -353,4 +355,17 @@ class BasePathNamespace(object):
+     IPA_CUSTODIA_AUDIT_LOG = '/var/log/ipa-custodia.audit.log'
+     IPA_GETKEYTAB = '/usr/sbin/ipa-getkeytab'
+ 
++    @property
++    def USER_CACHE_PATH(self):
++        return (
++            os.environ.get('XDG_CACHE_HOME') or
++            os.path.join(
++                os.environ.get(
++                    'HOME',
++                    os.path.expanduser('~')
++                ),
++                '.cache'
++            )
++        )
++
+ path_namespace = BasePathNamespace
+-- 
+2.7.4
+
diff --git a/SOURCES/0109-DNSSEC-prevent-ipa-ods-exporter-from-looping-after-s.patch b/SOURCES/0109-DNSSEC-prevent-ipa-ods-exporter-from-looping-after-s.patch
deleted file mode 100644
index 2bad936..0000000
--- a/SOURCES/0109-DNSSEC-prevent-ipa-ods-exporter-from-looping-after-s.patch
+++ /dev/null
@@ -1,47 +0,0 @@
-From 29cf6ce568747eca90497a29aa21927ac2b69496 Mon Sep 17 00:00:00 2001
-From: Petr Spacek <pspacek@redhat.com>
-Date: Mon, 31 Aug 2015 17:58:07 +0200
-Subject: [PATCH] DNSSEC: prevent ipa-ods-exporter from looping after service
- auto-restart
-
-It might happen that systemd will restart the service even if there is
-no incomming connection to service socket. In that case we want to exit
-because HSM synchronization is done before socket.accept() and we want
-to synchronize HSM and DNS zones at the same time.
-
-https://fedorahosted.org/freeipa/ticket/5273
-
-Reviewed-By: Martin Basti <mbasti@redhat.com>
-Reviewed-By: Oleg Fayans <ofayans@redhat.com>
----
- daemons/dnssec/ipa-ods-exporter | 6 ++++++
- 1 file changed, 6 insertions(+)
-
-diff --git a/daemons/dnssec/ipa-ods-exporter b/daemons/dnssec/ipa-ods-exporter
-index 62eca71da10ee6f3efd4d391a274278875714570..9544db149aed6574a8962d6c8e6b6f1bc520d6db 100755
---- a/daemons/dnssec/ipa-ods-exporter
-+++ b/daemons/dnssec/ipa-ods-exporter
-@@ -25,6 +25,7 @@ import logging
- import os
- import subprocess
- import socket
-+import select
- import sys
- import systemd.daemon
- import systemd.journal
-@@ -346,7 +347,12 @@ def receive_systemd_command(log):
-         raise KeyError('Exactly one socket is expected.')
- 
-     sck = socket.fromfd(fds[0], socket.AF_UNIX, socket.SOCK_STREAM)
-+    rlist, wlist, xlist = select.select([sck], [], [], 0)
-+    if not rlist:
-+        log.critical('socket activation did not return socket with a command')
-+        sys.exit(0)
- 
-+    log.debug('accepting new connection')
-     conn, addr = sck.accept()
-     log.debug('accepted new connection %s', repr(conn))
- 
--- 
-2.5.1
-
diff --git a/SOURCES/0109-compat-Fix-ping-command-call.patch b/SOURCES/0109-compat-Fix-ping-command-call.patch
new file mode 100644
index 0000000..ac1a53c
--- /dev/null
+++ b/SOURCES/0109-compat-Fix-ping-command-call.patch
@@ -0,0 +1,30 @@
+From a13d964ab5b76816a38170f569c3edb4cbe3e06d Mon Sep 17 00:00:00 2001
+From: David Kupka <dkupka@redhat.com>
+Date: Tue, 16 Aug 2016 16:49:57 +0200
+Subject: [PATCH] compat: Fix ping command call
+
+Remove extra argument from client.forward call.
+
+https://fedorahosted.org/freeipa/ticket/6095
+
+Reviewed-By: Jan Cholasta <jcholast@redhat.com>
+---
+ ipaclient/remote_plugins/compat.py | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/ipaclient/remote_plugins/compat.py b/ipaclient/remote_plugins/compat.py
+index b6d099a075deaaa17143f8ddddfb11d97b75f0ed..5e08cb0ed73becbc17e724864d1a853142a5ef6f 100644
+--- a/ipaclient/remote_plugins/compat.py
++++ b/ipaclient/remote_plugins/compat.py
+@@ -41,7 +41,7 @@ def get_package(api, server_info, client):
+         try:
+             server_version = env['result']['api_version']
+         except KeyError:
+-            ping = client.forward(u'ping', u'api_version', version=u'2.0')
++            ping = client.forward(u'ping', version=u'2.0')
+             try:
+                 match = re.search(u'API version (2\.[0-9]+)', ping['summary'])
+             except KeyError:
+-- 
+2.7.4
+
diff --git a/SOURCES/0110-DNSSEC-Fix-deadlock-in-ipa-ods-exporter-ods-enforcer.patch b/SOURCES/0110-DNSSEC-Fix-deadlock-in-ipa-ods-exporter-ods-enforcer.patch
deleted file mode 100644
index 51fd00d..0000000
--- a/SOURCES/0110-DNSSEC-Fix-deadlock-in-ipa-ods-exporter-ods-enforcer.patch
+++ /dev/null
@@ -1,97 +0,0 @@
-From c50f7610b1781ccbd6f169805d29d84e34e46db8 Mon Sep 17 00:00:00 2001
-From: Petr Spacek <pspacek@redhat.com>
-Date: Mon, 31 Aug 2015 18:01:12 +0200
-Subject: [PATCH] DNSSEC: Fix deadlock in ipa-ods-exporter <-> ods-enforcerd
- interaction
-
-https://fedorahosted.org/freeipa/ticket/5273
-
-Reviewed-By: Martin Basti <mbasti@redhat.com>
-Reviewed-By: Oleg Fayans <ofayans@redhat.com>
----
- daemons/dnssec/ipa-ods-exporter | 39 +++++++++++++++++++++++++++++++--------
- 1 file changed, 31 insertions(+), 8 deletions(-)
-
-diff --git a/daemons/dnssec/ipa-ods-exporter b/daemons/dnssec/ipa-ods-exporter
-index 9544db149aed6574a8962d6c8e6b6f1bc520d6db..76c7e484c65888b3d722448ee669ca8d95e3f3d9 100755
---- a/daemons/dnssec/ipa-ods-exporter
-+++ b/daemons/dnssec/ipa-ods-exporter
-@@ -368,12 +368,12 @@ def parse_command(cmd):
-     """
-     if cmd == 'ipa-hsm-update':
-         return (0,
--                'HSM synchronization finished, exiting.',
-+                'HSM synchronization finished, skipping zone synchronization.',
-                 None)
- 
-     elif cmd == 'ipa-full-update':
-         return (None,
--                'Synchronization of all zones requested.',
-+                'Synchronization of all zones was finished.',
-                 None)
- 
-     elif not cmd.startswith('update '):
-@@ -386,7 +386,7 @@ def parse_command(cmd):
-     else:
-         zone_name = cmd2ods_zone_name(cmd)
-         return (None,
--                'Update request for zone "%s" queued.\n' % zone_name,
-+                'Zone was "%s" updated.\n' % zone_name,
-                 zone_name)
- 
- def send_systemd_reply(conn, reply):
-@@ -541,18 +541,29 @@ except KeyError as e:
- 
- exitcode, msg, zone_name = parse_command(cmd)
- 
--if conn:
--    send_systemd_reply(conn, msg)
- if exitcode is not None:
-+    if conn:
-+        send_systemd_reply(conn, msg)
-     log.info(msg)
-     sys.exit(exitcode)
- else:
-     log.debug(msg)
- 
- # Open DB directly and read key timestamps etc.
--with ods_db_lock():
--    db = sqlite3.connect(paths.OPENDNSSEC_KASP_DB,
--            isolation_level="EXCLUSIVE")
-+db = None
-+try:
-+    # LOCK WARNING:
-+    # ods-enforcerd is holding kasp.db.our_lock when processing all zones and
-+    # the lock is unlocked only after all calls to ods-signer are finished,
-+    # i.e. when ods-enforcerd receives reply from each ods-signer call.
-+    #
-+    # Consequently, ipa-ods-exporter (ods-signerd implementation) must not
-+    # request kasp.db.our_lock to prevent deadlocks.
-+    # SQLite transaction isolation should suffice.
-+    # Beware: Reply can be sent back only after DB is unlocked and closed
-+    #         otherwise ods-enforcerd will fail.
-+
-+    db = sqlite3.connect(paths.OPENDNSSEC_KASP_DB)
-     db.row_factory = sqlite3.Row
-     db.execute('BEGIN')
- 
-@@ -564,4 +575,16 @@ with ods_db_lock():
-         for zone_row in db.execute("SELECT name FROM zones"):
-             sync_zone(log, ldap, dns_dn, zone_row['name'])
- 
-+except Exception as ex:
-+    msg = "ipa-ods-exporter exception: %s" % ex
-+    raise ex
-+
-+finally:
-+    try:
-+        if db:
-+            db.close()
-+    finally:
-+        if conn:
-+            send_systemd_reply(conn, msg)
-+
- log.debug('Done')
--- 
-2.5.1
-
diff --git a/SOURCES/0110-Fix-man-page-ipa-replica-manage-remove-duplicate-c-o.patch b/SOURCES/0110-Fix-man-page-ipa-replica-manage-remove-duplicate-c-o.patch
new file mode 100644
index 0000000..4afdce0
--- /dev/null
+++ b/SOURCES/0110-Fix-man-page-ipa-replica-manage-remove-duplicate-c-o.patch
@@ -0,0 +1,36 @@
+From bce240ec6a80d5d401387d727ea891f7c961c879 Mon Sep 17 00:00:00 2001
+From: Petr Spacek <pspacek@redhat.com>
+Date: Mon, 22 Aug 2016 08:33:34 +0200
+Subject: [PATCH] Fix man page ipa-replica-manage: remove duplicate -c option
+ from --no-lookup
+
+https://fedorahosted.org/freeipa/ticket/6233
+
+Reviewed-By: Martin Basti <mbasti@redhat.com>
+---
+ install/tools/man/ipa-replica-manage.1 | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/install/tools/man/ipa-replica-manage.1 b/install/tools/man/ipa-replica-manage.1
+index 34cd314a517ae2f74da7bc87d6336e62d7b57118..ed975c92c4453798e6536a75318d5e5065c876a4 100644
+--- a/install/tools/man/ipa-replica-manage.1
++++ b/install/tools/man/ipa-replica-manage.1
+@@ -109,12 +109,12 @@ Provide additional information
+ \fB\-f\fR, \fB\-\-force\fR
+ Ignore some types of errors, don't prompt when deleting a master
+ .TP
+-\fB\-c\fR, \fB\-\-no\-lookup\fR
+-Do not perform DNS lookup checks.
+-.TP
+ \fB\-c\fR, \fB\-\-cleanup\fR
+ When deleting a master with the \-\-force flag, remove leftover references to an already deleted master.
+ .TP
++\fB\-\-no\-lookup\fR
++Do not perform DNS lookup checks.
++.TP
+ \fB\-\-binddn\fR=\fIADMIN_DN\fR
+ Bind DN to use with remote server (default is cn=Directory Manager) \- Be careful to quote this value on the command line
+ .TP
+-- 
+2.7.4
+
diff --git a/SOURCES/0111-DNSSEC-Fix-HSM-synchronization-in-ipa-dnskeysyncd-wh.patch b/SOURCES/0111-DNSSEC-Fix-HSM-synchronization-in-ipa-dnskeysyncd-wh.patch
deleted file mode 100644
index 705c9c7..0000000
--- a/SOURCES/0111-DNSSEC-Fix-HSM-synchronization-in-ipa-dnskeysyncd-wh.patch
+++ /dev/null
@@ -1,27 +0,0 @@
-From fec0e8360bbd2ead6eb522348ed2b05bd6fdf7bb Mon Sep 17 00:00:00 2001
-From: Petr Spacek <pspacek@redhat.com>
-Date: Mon, 31 Aug 2015 18:03:33 +0200
-Subject: [PATCH] DNSSEC: Fix HSM synchronization in ipa-dnskeysyncd when
- running on DNSSEC key master
-
-https://fedorahosted.org/freeipa/ticket/5273
-
-Reviewed-By: Martin Basti <mbasti@redhat.com>
-Reviewed-By: Oleg Fayans <ofayans@redhat.com>
----
- ipapython/dnssec/keysyncer.py | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/ipapython/dnssec/keysyncer.py b/ipapython/dnssec/keysyncer.py
-index 837602fb4e7c74a7099a351c727d1435b5645706..de5b5aa5f670db4c58fb92b989e181d45d887b55 100644
---- a/ipapython/dnssec/keysyncer.py
-+++ b/ipapython/dnssec/keysyncer.py
-@@ -177,4 +177,4 @@ class KeySyncer(SyncReplConsumer):
-             return
-         if not self.init_done:
-             return
--        ipautil.run([paths.ODS_SIGNER])
-+        ipautil.run([paths.ODS_SIGNER, 'ipa-hsm-update'])
--- 
-2.5.1
-
diff --git a/SOURCES/0111-cert-include-CA-name-in-cert-command-output.patch b/SOURCES/0111-cert-include-CA-name-in-cert-command-output.patch
new file mode 100644
index 0000000..2499a32
--- /dev/null
+++ b/SOURCES/0111-cert-include-CA-name-in-cert-command-output.patch
@@ -0,0 +1,112 @@
+From c5fe2ba58e011425d56d5edc7823d575e3366b7d Mon Sep 17 00:00:00 2001
+From: Jan Cholasta <jcholast@redhat.com>
+Date: Tue, 23 Aug 2016 13:59:33 +0200
+Subject: [PATCH] cert: include CA name in cert command output
+
+Include name of the CA that issued a certificate in cert-request, cert-show
+and cert-find.
+
+This allows the caller to call further commands on the cert without having
+to call ca-find to find the name of the CA.
+
+https://fedorahosted.org/freeipa/ticket/6151
+
+Reviewed-By: Martin Basti <mbasti@redhat.com>
+---
+ ipaserver/plugins/cert.py | 33 ++++++++++++++++++++++++---------
+ 1 file changed, 24 insertions(+), 9 deletions(-)
+
+diff --git a/ipaserver/plugins/cert.py b/ipaserver/plugins/cert.py
+index a1166a0d0e5b09586832550c055fc6714c3efe26..67eaeba33610321bf88143dc4ac06a94887427cd 100644
+--- a/ipaserver/plugins/cert.py
++++ b/ipaserver/plugins/cert.py
+@@ -262,6 +262,15 @@ def bind_principal_can_manage_cert(cert):
+ 
+ class BaseCertObject(Object):
+     takes_params = (
++        Str(
++            'cacn?',
++            cli_name='ca',
++            default=IPA_CA_CN,
++            autofill=True,
++            label=_('Issuing CA'),
++            doc=_('Name of issuing CA'),
++            flags={'no_create', 'no_update', 'no_search'},
++        ),
+         Bytes(
+             'certificate', validate_certificate,
+             label=_("Certificate"),
+@@ -336,14 +345,7 @@ class BaseCertObject(Object):
+ 
+ class BaseCertMethod(Method):
+     def get_options(self):
+-        yield Str('cacn?',
+-            cli_name='ca',
+-            default=IPA_CA_CN,
+-            autofill=True,
+-            query=True,
+-            label=_('Issuing CA'),
+-            doc=_('Name of issuing CA'),
+-        )
++        yield self.obj.params['cacn'].clone(query=True)
+ 
+         for option in super(BaseCertMethod, self).get_options():
+             yield option
+@@ -432,7 +434,8 @@ class cert_request(Create, BaseCertMethod, VirtualCommand):
+         # referencing nonexistant CA) and look up authority ID.
+         #
+         ca = kw['cacn']
+-        ca_id = api.Command.ca_show(ca)['result']['ipacaid'][0]
++        ca_obj = api.Command.ca_show(ca)['result']
++        ca_id = ca_obj['ipacaid'][0]
+ 
+         """
+         Access control is partially handled by the ACI titled
+@@ -623,6 +626,7 @@ class cert_request(Create, BaseCertMethod, VirtualCommand):
+         if not raw:
+             self.obj._parse(result)
+             result['request_id'] = int(result['request_id'])
++            result['cacn'] = ca_obj['cn'][0]
+ 
+         # Success? Then add it to the principal's entry
+         # (unless the profile tells us not to)
+@@ -802,6 +806,7 @@ class cert_show(Retrieve, CertMethod, VirtualCommand):
+             self.obj._parse(result)
+             result['revoked'] = ('revocation_reason' in result)
+             self.obj._fill_owners(result)
++            result['cacn'] = ca_obj['cn'][0]
+ 
+         return dict(result=result, value=pkey_to_value(serial_number, options))
+ 
+@@ -1072,11 +1077,19 @@ class cert_find(Search, CertMethod):
+                 raise
+             return result, False, complete
+ 
++        ca_objs = self.api.Command.ca_find()['result']
++        ca_objs = {DN(ca['ipacasubjectdn'][0]): ca for ca in ca_objs}
++
+         ra = self.api.Backend.ra
+         for ra_obj in ra.find(ra_options):
+             issuer = DN(ra_obj['issuer'])
+             serial_number = ra_obj['serial_number']
+ 
++            try:
++                ca_obj = ca_objs[issuer]
++            except KeyError:
++                continue
++
+             if pkey_only:
+                 obj = {'serial_number': serial_number}
+             else:
+@@ -1093,6 +1106,8 @@ class cert_find(Search, CertMethod):
+                             ra_obj['certificate'].replace('\r\n', ''))
+                         self.obj._parse(obj)
+ 
++            obj['cacn'] = ca_obj['cn'][0]
++
+             result[issuer, serial_number] = obj
+ 
+         return result, False, complete
+-- 
+2.7.4
+
diff --git a/SOURCES/0112-DNSSEC-Fix-key-metadata-export.patch b/SOURCES/0112-DNSSEC-Fix-key-metadata-export.patch
deleted file mode 100644
index 719266d..0000000
--- a/SOURCES/0112-DNSSEC-Fix-key-metadata-export.patch
+++ /dev/null
@@ -1,32 +0,0 @@
-From b250ac5d752b3565b4fdfb74e8de38784ba93d89 Mon Sep 17 00:00:00 2001
-From: Petr Spacek <pspacek@redhat.com>
-Date: Mon, 31 Aug 2015 18:40:50 +0200
-Subject: [PATCH] DNSSEC: Fix key metadata export
-
-Incorrect SQL join condition could lead to situation where metadata from
-ZSK and KSK were interchanged.
-
-https://fedorahosted.org/freeipa/ticket/5273
-
-Reviewed-By: Martin Basti <mbasti@redhat.com>
-Reviewed-By: Oleg Fayans <ofayans@redhat.com>
----
- daemons/dnssec/ipa-ods-exporter | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/daemons/dnssec/ipa-ods-exporter b/daemons/dnssec/ipa-ods-exporter
-index 76c7e484c65888b3d722448ee669ca8d95e3f3d9..e0c88936d5983297483c504d422c8d1ee483b6cf 100755
---- a/daemons/dnssec/ipa-ods-exporter
-+++ b/daemons/dnssec/ipa-ods-exporter
-@@ -174,7 +174,7 @@ def get_ods_keys(zone_name):
- 
-     # get all keys for given zone ID
-     cur = db.execute("SELECT kp.HSMkey_id, kp.generate, kp.algorithm, dnsk.publish, dnsk.active, dnsk.retire, dnsk.dead, dnsk.keytype "
--             "FROM keypairs AS kp JOIN dnsseckeys AS dnsk ON kp.id = dnsk.id "
-+             "FROM keypairs AS kp JOIN dnsseckeys AS dnsk ON kp.id = dnsk.keypair_id "
-              "WHERE dnsk.zone_id = ?", (zone_id,))
-     keys = {}
-     for row in cur:
--- 
-2.5.1
-
diff --git a/SOURCES/0112-Fix-CA-ACL-Check-on-SubjectAltNames.patch b/SOURCES/0112-Fix-CA-ACL-Check-on-SubjectAltNames.patch
new file mode 100644
index 0000000..a5043e2
--- /dev/null
+++ b/SOURCES/0112-Fix-CA-ACL-Check-on-SubjectAltNames.patch
@@ -0,0 +1,55 @@
+From 645ddb282a5b75cc17a80c97445cf61806b53cb4 Mon Sep 17 00:00:00 2001
+From: Simo Sorce <simo@redhat.com>
+Date: Tue, 26 Jul 2016 11:25:27 -0400
+Subject: [PATCH] Fix CA ACL Check on SubjectAltNames
+
+The code is supposed to check that the SAN name is also authorized to be used
+with the specified profile id.
+The original principal has already been checked.
+
+Signed-off-by: Simo Sorce <simo@redhat.com>
+Reviewed-By: Fraser Tweedale <ftweedal@redhat.com>
+Reviewed-By: Martin Babinsky <mbabinsk@redhat.com>
+---
+ ipaserver/plugins/cert.py | 12 ++++++++----
+ 1 file changed, 8 insertions(+), 4 deletions(-)
+
+diff --git a/ipaserver/plugins/cert.py b/ipaserver/plugins/cert.py
+index 67eaeba33610321bf88143dc4ac06a94887427cd..6495bf1491f939a032fad03fe4ef86839c0575ef 100644
+--- a/ipaserver/plugins/cert.py
++++ b/ipaserver/plugins/cert.py
+@@ -565,14 +565,18 @@ class cert_request(Create, BaseCertMethod, VirtualCommand):
+         for name_type, name in subjectaltname:
+             if name_type == pkcs10.SAN_DNSNAME:
+                 name = unicode(name)
++                alt_principal = None
+                 alt_principal_obj = None
+-                alt_principal_string = unicode(principal)
+                 try:
+                     if principal_type == HOST:
++                        alt_principal = kerberos.Principal(
++                            (u'host', name), principal.realm)
+                         alt_principal_obj = api.Command['host_show'](name, all=True)
+                     elif principal_type == SERVICE:
++                        alt_principal = kerberos.Principal(
++                            (principal.service_name, name), principal.realm)
+                         alt_principal_obj = api.Command['service_show'](
+-                            alt_principal_string, all=True)
++                            alt_principal, all=True)
+                     elif principal_type == USER:
+                         raise errors.ValidationError(
+                             name='csr',
+@@ -592,8 +596,8 @@ class cert_request(Create, BaseCertMethod, VirtualCommand):
+                         raise errors.ACIError(info=_(
+                             "Insufficient privilege to create a certificate "
+                             "with subject alt name '%s'.") % name)
+-                if alt_principal_string is not None and not bypass_caacl:
+-                    caacl_check(principal_type, principal, ca, profile_id)
++                if alt_principal is not None and not bypass_caacl:
++                    caacl_check(principal_type, alt_principal, ca, profile_id)
+             elif name_type in (pkcs10.SAN_OTHERNAME_KRB5PRINCIPALNAME,
+                                pkcs10.SAN_OTHERNAME_UPN):
+                 if name != principal_string:
+-- 
+2.7.4
+
diff --git a/SOURCES/0113-DNSSEC-Wrap-master-key-using-RSA-OAEP-instead-of-old.patch b/SOURCES/0113-DNSSEC-Wrap-master-key-using-RSA-OAEP-instead-of-old.patch
deleted file mode 100644
index abc1a74..0000000
--- a/SOURCES/0113-DNSSEC-Wrap-master-key-using-RSA-OAEP-instead-of-old.patch
+++ /dev/null
@@ -1,40 +0,0 @@
-From 7bcdc22d4e08739837039027f7c939a7469b8110 Mon Sep 17 00:00:00 2001
-From: Petr Spacek <pspacek@redhat.com>
-Date: Tue, 1 Sep 2015 18:16:06 +0200
-Subject: [PATCH] DNSSEC: Wrap master key using RSA OAEP instead of old PKCS
- v1.5.
-
-https://fedorahosted.org/freeipa/ticket/5273
-
-Reviewed-By: Martin Basti <mbasti@redhat.com>
----
- daemons/dnssec/ipa-ods-exporter | 6 +++---
- 1 file changed, 3 insertions(+), 3 deletions(-)
-
-diff --git a/daemons/dnssec/ipa-ods-exporter b/daemons/dnssec/ipa-ods-exporter
-index e0c88936d5983297483c504d422c8d1ee483b6cf..f30a2253a713d857aa4e7566e52a0a45f7bd50c2 100755
---- a/daemons/dnssec/ipa-ods-exporter
-+++ b/daemons/dnssec/ipa-ods-exporter
-@@ -53,8 +53,7 @@ KEYTAB_FB = paths.IPA_ODS_EXPORTER_KEYTAB
- ODS_SE_MAXLINE = 1024  # from ODS common/config.h
- ODS_DB_LOCK_PATH = "%s%s" % (paths.OPENDNSSEC_KASP_DB, '.our_lock')
- 
--# TODO: MECH_RSA_OAEP
--SECRETKEY_WRAPPING_MECH = 'rsaPkcs'
-+SECRETKEY_WRAPPING_MECH = 'rsaPkcsOaep'
- PRIVKEY_WRAPPING_MECH = 'aesKeyWrapPad'
- 
- # DNSKEY flag constants
-@@ -294,7 +293,8 @@ def master2ldap_master_keys_sync(log, ldapkeydb, localhsm):
-                 hexlify(mkey_id), hexlify(replica_key_id)))
-             replica_key = localhsm.replica_pubkeys_wrap[replica_key_id]
-             keydata = localhsm.p11.export_wrapped_key(mkey_local.handle,
--                    replica_key.handle, _ipap11helper.MECH_RSA_PKCS)
-+                    replica_key.handle,
-+                    wrappingmech_name2id[SECRETKEY_WRAPPING_MECH])
-             mkey_ldap.add_wrapped_data(keydata, SECRETKEY_WRAPPING_MECH,
-                     replica_key_id)
- 
--- 
-2.5.1
-
diff --git a/SOURCES/0113-do-not-use-trusted-forest-name-to-construct-domain-a.patch b/SOURCES/0113-do-not-use-trusted-forest-name-to-construct-domain-a.patch
new file mode 100644
index 0000000..be6a22a
--- /dev/null
+++ b/SOURCES/0113-do-not-use-trusted-forest-name-to-construct-domain-a.patch
@@ -0,0 +1,37 @@
+From c8f3d08c4b90bf89dd4c180d14ced95c14692ff7 Mon Sep 17 00:00:00 2001
+From: Martin Babinsky <mbabinsk@redhat.com>
+Date: Wed, 31 Aug 2016 13:59:14 +0200
+Subject: [PATCH] do not use trusted forest name to construct domain admin
+ principal
+
+When `trust-add` is supplied AD domain admin name without realm component, the
+code appends the uppercased AD forest root domain name to construct the full
+principal. This can cause authentication error, however, when external trust
+with non-root domain is requested.
+
+We should instead use the supplied DNS domain name (if valid) as a realm
+component.
+
+https://fedorahosted.org/freeipa/ticket/6277
+
+Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
+---
+ ipaserver/plugins/trust.py | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/ipaserver/plugins/trust.py b/ipaserver/plugins/trust.py
+index b9d9b122a90de62946307b99b44932129eb611e8..8ed96c253e7c7862f60ad668aa6c252038274624 100644
+--- a/ipaserver/plugins/trust.py
++++ b/ipaserver/plugins/trust.py
+@@ -319,7 +319,7 @@ def generate_creds(trustinstance, style, **options):
+             else:
+                sp = admin_name.split(sep)
+             if len(sp) == 1:
+-                sp.append(trustinstance.remote_domain.info['dns_forest'].upper())
++                sp.append(trustinstance.remote_domain.info['dns_domain'].upper())
+         creds = u"{name}%{password}".format(name=sep.join(sp),
+                                             password=password)
+     return creds
+-- 
+2.7.4
+
diff --git a/SOURCES/0114-Always-fetch-forest-info-from-root-DCs-when-establis.patch b/SOURCES/0114-Always-fetch-forest-info-from-root-DCs-when-establis.patch
new file mode 100644
index 0000000..540d3cc
--- /dev/null
+++ b/SOURCES/0114-Always-fetch-forest-info-from-root-DCs-when-establis.patch
@@ -0,0 +1,85 @@
+From 95d17d4e632effc37eda54e77a71cbf2cf2f888c Mon Sep 17 00:00:00 2001
+From: Martin Babinsky <mbabinsk@redhat.com>
+Date: Thu, 1 Sep 2016 09:30:23 +0200
+Subject: [PATCH] Always fetch forest info from root DCs when establishing
+ two-way trust
+
+Prior To Windows Server 2012R2, the `netr_DsRGetForestTrustInformation` calls
+performed against non-root forest domain DCs were automatically routed to the
+root domain DCs to resolve trust topology information.
+
+This is no longer the case, so the `dcerpc.fetch_domains` function must
+explicitly contact root domain DCs even in the case when an external two-way
+trust to non-root domain is requested.
+
+https://fedorahosted.org/freeipa/ticket/6057
+
+Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
+---
+ ipaserver/plugins/trust.py | 29 +++++++++++++++++++++--------
+ 1 file changed, 21 insertions(+), 8 deletions(-)
+
+diff --git a/ipaserver/plugins/trust.py b/ipaserver/plugins/trust.py
+index 8ed96c253e7c7862f60ad668aa6c252038274624..b3cb56c14496c0d56d3f3fedddee8d123f929344 100644
+--- a/ipaserver/plugins/trust.py
++++ b/ipaserver/plugins/trust.py
+@@ -770,7 +770,7 @@ sides.
+                 # 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,
+-                                               result['result'], **options)
++                                               **options)
+                 domains = add_new_domains_from_trust(self.api, self.trustinstance,
+                                                      result['result'], res, **options)
+             else:
+@@ -1631,8 +1631,21 @@ class trustdomain_del(LDAPDelete):
+         return result
+ 
+ 
+-def fetch_domains_from_trust(myapi, trustinstance, trust_entry, **options):
+-    trust_name = trust_entry['cn'][0]
++def fetch_domains_from_trust(myapi, trustinstance, **options):
++    """
++    Contact trust forest root DC and fetch trusted forest topology information.
++
++    :param myapi: API instance
++    :param trustinstance: Initialized instance of `dcerpc.TrustDomainJoins`
++        class
++    :param options: options passed from API command's `execute()` method
++
++    :returns: dict containing forest domain information and forest-wide UPN
++        suffixes (if any)
++    """
++
++    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
+@@ -1640,10 +1653,10 @@ def fetch_domains_from_trust(myapi, trustinstance, trust_entry, **options):
+     # as well.
+     creds = generate_creds(trustinstance, style=CRED_STYLE_KERBEROS, **options)
+     server = options.get('realm_server', None)
+-    domains = ipaserver.dcerpc.fetch_domains(myapi,
+-                                             trustinstance.local_flatname,
+-                                             trust_name, creds=creds,
+-                                             server=server)
++    domains = ipaserver.dcerpc.fetch_domains(
++        myapi, trustinstance.local_flatname, forest_root_name, creds=creds,
++        server=server)
++
+     return domains
+ 
+ 
+@@ -1749,7 +1762,7 @@ class trust_fetch_domains(LDAPRetrieve):
+                     'on the IPA server first'
+                 )
+             )
+-        res = fetch_domains_from_trust(self.api, trustinstance, trust, **options)
++        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:
+-- 
+2.7.4
+
diff --git a/SOURCES/0114-ldap-Make-ldap2-connection-management-thread-safe-ag.patch b/SOURCES/0114-ldap-Make-ldap2-connection-management-thread-safe-ag.patch
deleted file mode 100644
index 0c98cc6..0000000
--- a/SOURCES/0114-ldap-Make-ldap2-connection-management-thread-safe-ag.patch
+++ /dev/null
@@ -1,177 +0,0 @@
-From 96cadaec3c16b296627991ed517d7015fbe2882f Mon Sep 17 00:00:00 2001
-From: Jan Cholasta <jcholast@redhat.com>
-Date: Wed, 2 Sep 2015 14:04:17 +0200
-Subject: [PATCH] ldap: Make ldap2 connection management thread-safe again
-
-This fixes the connection code in LDAPClient to not store the LDAP connection
-in an attribute of the object, which in combination with ldap2's per-thread
-connections lead to race conditions resulting in connection failures. ldap2
-code was updated accordingly.
-
-https://fedorahosted.org/freeipa/ticket/5268
-
-Reviewed-By: Tomas Babej <tbabej@redhat.com>
----
- ipapython/ipaldap.py       | 32 +++++++++-----------------------
- ipaserver/plugins/ldap2.py | 29 +++++++++++++----------------
- 2 files changed, 22 insertions(+), 39 deletions(-)
-
-diff --git a/ipapython/ipaldap.py b/ipapython/ipaldap.py
-index ef7c41a37c1f46290afbb11f912d7a4b8ea224c9..4443db03bcee25033abf63786016a7931f7eed20 100644
---- a/ipapython/ipaldap.py
-+++ b/ipapython/ipaldap.py
-@@ -710,11 +710,10 @@ class LDAPClient(object):
-         self._decode_attrs = decode_attrs
- 
-         self.log = log_mgr.get_logger(self)
--        self._conn = None
-         self._has_schema = False
-         self._schema = None
- 
--        self._connect()
-+        self._conn = self._connect()
- 
-     @property
-     def conn(self):
-@@ -1023,29 +1022,16 @@ class LDAPClient(object):
-         """
-         Close the connection.
-         """
--        if self._conn is not None:
--            self._disconnect()
-+        self._conn = None
- 
-     def _connect(self):
--        if self._conn is not None:
--            raise errors.DatabaseError(
--                desc="Can't connect to server", info="Already connected")
--
-         with self.error_handler():
--            # bypass ldap2's locking
--            object.__setattr__(self, '_conn',
--                               ldap.initialize(self.ldap_uri))
-+            conn = ldap.initialize(self.ldap_uri)
- 
-             if self._start_tls:
--                self._conn.start_tls_s()
--
--    def _disconnect(self):
--        if self._conn is None:
--            raise errors.DatabaseError(
--                desc="Can't disconnect from server", info="Not connected")
-+                conn.start_tls_s()
- 
--        # bypass ldap2's locking
--        object.__setattr__(self, '_conn', None)
-+        return conn
- 
-     def simple_bind(self, bind_dn, bind_password, server_controls=None,
-                     client_controls=None):
-@@ -1059,7 +1045,7 @@ class LDAPClient(object):
-             assert isinstance(bind_dn, DN)
-             bind_dn = str(bind_dn)
-             bind_password = self.encode(bind_password)
--            self._conn.simple_bind_s(
-+            self.conn.simple_bind_s(
-                 bind_dn, bind_password, server_controls, client_controls)
- 
-     def external_bind(self, user_name, server_controls=None,
-@@ -1070,7 +1056,7 @@ class LDAPClient(object):
-         with self.error_handler():
-             auth_tokens = ldap.sasl.external(user_name)
-             self._flush_schema()
--            self._conn.sasl_interactive_bind_s(
-+            self.conn.sasl_interactive_bind_s(
-                 '', auth_tokens, server_controls, client_controls)
- 
-     def gssapi_bind(self, server_controls=None, client_controls=None):
-@@ -1080,7 +1066,7 @@ class LDAPClient(object):
-         with self.error_handler():
-             auth_tokens = ldap.sasl.sasl({}, 'GSSAPI')
-             self._flush_schema()
--            self._conn.sasl_interactive_bind_s(
-+            self.conn.sasl_interactive_bind_s(
-                 '', auth_tokens, server_controls, client_controls)
- 
-     def unbind(self):
-@@ -1089,7 +1075,7 @@ class LDAPClient(object):
-         """
-         with self.error_handler():
-             self._flush_schema()
--            self._conn.unbind_s()
-+            self.conn.unbind_s()
- 
-     def make_dn_from_attr(self, attr, value, parent_dn=None):
-         """
-diff --git a/ipaserver/plugins/ldap2.py b/ipaserver/plugins/ldap2.py
-index 68feee4f09eb12e50867dfbe3c482a359838aa82..deb0592ab68ab8eb712a6d29fdffd8776e2e289a 100644
---- a/ipaserver/plugins/ldap2.py
-+++ b/ipaserver/plugins/ldap2.py
-@@ -76,10 +76,7 @@ class ldap2(CrudBackend, LDAPClient):
-         # do not set it
-         pass
- 
--    def _disconnect(self):
--        pass
--
--    def __del__(self):
-+    def close(self):
-         if self.isconnected():
-             self.disconnect()
- 
-@@ -118,10 +115,11 @@ class ldap2(CrudBackend, LDAPClient):
-         if debug_level:
-             _ldap.set_option(_ldap.OPT_DEBUG_LEVEL, debug_level)
- 
--        LDAPClient._connect(self)
--        conn = self._conn
-+        client = LDAPClient(self.ldap_uri,
-+                            force_schema_updates=self._force_schema_updates)
-+        conn = client._conn
- 
--        with self.error_handler():
-+        with client.error_handler():
-             if self.ldap_uri.startswith('ldapi://') and ccache:
-                 conn.set_option(_ldap.OPT_HOST_NAME, self.api.env.host)
-             minssf = conn.get_option(_ldap.OPT_X_SASL_SSF_MIN)
-@@ -147,29 +145,28 @@ class ldap2(CrudBackend, LDAPClient):
-                     context=krbV.default_context()).principal().name
- 
-             os.environ['KRB5CCNAME'] = ccache
--            self.gssapi_bind(server_controls=serverctrls,
--                             client_controls=clientctrls)
-+            client.gssapi_bind(server_controls=serverctrls,
-+                               client_controls=clientctrls)
-             setattr(context, 'principal', principal)
-         else:
-             # no kerberos ccache, use simple bind or external sasl
-             if autobind:
-                 pent = pwd.getpwuid(os.geteuid())
--                self.external_bind(pent.pw_name,
-+                client.external_bind(pent.pw_name,
-+                                     server_controls=serverctrls,
-+                                     client_controls=clientctrls)
-+            else:
-+                client.simple_bind(bind_dn, bind_pw,
-                                    server_controls=serverctrls,
-                                    client_controls=clientctrls)
--            else:
--                self.simple_bind(bind_dn, bind_pw,
--                                 server_controls=serverctrls,
--                                 client_controls=clientctrls)
- 
-         return conn
- 
-     def destroy_connection(self):
-         """Disconnect from LDAP server."""
-         try:
--            if self._conn is not None:
-+            if self.conn is not None:
-                 self.unbind()
--                LDAPClient._disconnect(self)
-         except errors.PublicError:
-             # ignore when trying to unbind multiple times
-             pass
--- 
-2.5.1
-
diff --git a/SOURCES/0115-Using-LDAPI-to-setup-CA-and-KRA-agents.patch b/SOURCES/0115-Using-LDAPI-to-setup-CA-and-KRA-agents.patch
deleted file mode 100644
index 8dc5c60..0000000
--- a/SOURCES/0115-Using-LDAPI-to-setup-CA-and-KRA-agents.patch
+++ /dev/null
@@ -1,271 +0,0 @@
-From 0ceb0c7b9730314cb8dfff7d2af9ef811a96aa13 Mon Sep 17 00:00:00 2001
-From: "Endi S. Dewata" <edewata@redhat.com>
-Date: Thu, 27 Aug 2015 06:44:29 +0200
-Subject: [PATCH] Using LDAPI to setup CA and KRA agents.
-
-The CA and KRA installation code has been modified to use LDAPI
-to create the CA and KRA agents directly in the CA and KRA
-database. This way it's no longer necessary to use the Directory
-Manager password or CA and KRA admin certificate.
-
-https://fedorahosted.org/freeipa/ticket/5257
-
-Reviewed-By: Martin Basti <mbasti@redhat.com>
----
- ipaplatform/base/paths.py        |   2 -
- ipaserver/install/cainstance.py  |  49 ++++++++++-------
- ipaserver/install/krainstance.py | 113 +++++++++++++++------------------------
- 3 files changed, 72 insertions(+), 92 deletions(-)
-
-diff --git a/ipaplatform/base/paths.py b/ipaplatform/base/paths.py
-index a407c1273f01b3465bcb1985dd41f2f242346a62..ff75e0d7a5a0250ce71e67b0302bbaab64c5e935 100644
---- a/ipaplatform/base/paths.py
-+++ b/ipaplatform/base/paths.py
-@@ -344,8 +344,6 @@ class BasePathNamespace(object):
-     SLAPD_INSTANCE_SOCKET_TEMPLATE = "/var/run/slapd-%s.socket"
-     ALL_SLAPD_INSTANCE_SOCKETS = "/var/run/slapd-*.socket"
-     ADMIN_CERT_PATH = '/root/.dogtag/pki-tomcat/ca_admin.cert'
--    KRA_NSSDB_PASSWORD_FILE = "/root/.dogtag/pki-tomcat/kra/password.conf"
--    KRA_PKCS12_PASSWORD_FILE = "/root/.dogtag/pki-tomcat/kra/pkcs12_password.conf"
-     ENTROPY_AVAIL = '/proc/sys/kernel/random/entropy_avail'
-     LDIF2DB = '/usr/sbin/ldif2db'
-     DB2LDIF = '/usr/sbin/db2ldif'
-diff --git a/ipaserver/install/cainstance.py b/ipaserver/install/cainstance.py
-index ecd9300036353426097d929918be974cbbb5c69d..a4504a35a42b8c8ea2a96738c82c546ebebf569f 100644
---- a/ipaserver/install/cainstance.py
-+++ b/ipaserver/install/cainstance.py
-@@ -464,7 +464,7 @@ class CAInstance(DogtagInstance):
-                 self.step("restarting certificate server", self.restart_instance)
-                 self.step("requesting RA certificate from CA", self.__request_ra_certificate)
-                 self.step("issuing RA agent certificate", self.__issue_ra_cert)
--                self.step("adding RA agent as a trusted user", self.__configure_ra)
-+                self.step("adding RA agent as a trusted user", self.__create_ca_agent)
-                 self.step("authorizing RA to modify profiles", self.__configure_profiles_acl)
-             self.step("configure certmonger for renewals", self.configure_certmonger_renewal)
-             self.step("configure certificate renewals", self.configure_renewal)
-@@ -903,18 +903,26 @@ class CAInstance(DogtagInstance):
- 
-         self.configure_agent_renewal()
- 
--    def __configure_ra(self):
--        # Create an RA user in the CA LDAP server and add that user to
--        # the appropriate groups so it can issue certificates without
--        # manual intervention.
--        conn = ipaldap.IPAdmin(self.fqdn, self.ds_port)
--        conn.do_simple_bind(DN(('cn', 'Directory Manager')), self.dm_password)
-+    def __create_ca_agent(self):
-+        """
-+        Create CA agent, assign a certificate, and add the user to
-+        the appropriate groups for accessing CA services.
-+        """
- 
--        decoded = base64.b64decode(self.ra_cert)
-+        # get ipaCert certificate
-+        cert_data = base64.b64decode(self.ra_cert)
-+        cert = x509.load_certificate(cert_data, x509.DER)
- 
--        entry_dn = DN(('uid', "ipara"), ('ou', 'People'), self.basedn)
-+        # connect to CA database
-+        server_id = installutils.realm_to_serverid(api.env.realm)
-+        dogtag_uri = 'ldapi://%%2fvar%%2frun%%2fslapd-%s.socket' % server_id
-+        conn = ldap2.ldap2(api, ldap_uri=dogtag_uri)
-+        conn.connect(autobind=True)
-+
-+        # create ipara user with ipaCert certificate
-+        user_dn = DN(('uid', "ipara"), ('ou', 'People'), self.basedn)
-         entry = conn.make_entry(
--            entry_dn,
-+            user_dn,
-             objectClass=['top', 'person', 'organizationalPerson',
-                          'inetOrgPerson', 'cmsuser'],
-             uid=["ipara"],
-@@ -922,23 +930,24 @@ class CAInstance(DogtagInstance):
-             cn=["ipara"],
-             usertype=["agentType"],
-             userstate=["1"],
--            userCertificate=[decoded],
-+            userCertificate=[cert_data],
-             description=['2;%s;%s;%s' % (
--                str(self.requestId),
-+                cert.serial_number,
-                 DN(('CN', 'Certificate Authority'), self.subject_base),
-                 DN(('CN', 'IPA RA'), self.subject_base))])
--
-         conn.add_entry(entry)
- 
--        dn = DN(('cn', 'Certificate Manager Agents'), ('ou', 'groups'), self.basedn)
--        modlist = [(0, 'uniqueMember', '%s' % entry_dn)]
--        conn.modify_s(dn, modlist)
-+        # add ipara user to Certificate Manager Agents group
-+        group_dn = DN(('cn', 'Certificate Manager Agents'), ('ou', 'groups'),
-+            self.basedn)
-+        conn.add_entry_to_group(user_dn, group_dn, 'uniqueMember')
- 
--        dn = DN(('cn', 'Registration Manager Agents'), ('ou', 'groups'), self.basedn)
--        modlist = [(0, 'uniqueMember', '%s' % entry_dn)]
--        conn.modify_s(dn, modlist)
-+        # add ipara user to Registration Manager Agents group
-+        group_dn = DN(('cn', 'Registration Manager Agents'), ('ou', 'groups'),
-+            self.basedn)
-+        conn.add_entry_to_group(user_dn, group_dn, 'uniqueMember')
- 
--        conn.unbind()
-+        conn.disconnect()
- 
-     def __configure_profiles_acl(self):
-         """Allow the Certificate Manager Agents group to modify profiles."""
-diff --git a/ipaserver/install/krainstance.py b/ipaserver/install/krainstance.py
-index e5cdbf5e7714603041e3f0156e87311994175b18..958fe6fb095e69f83342ce8299d1586b8bbacd47 100644
---- a/ipaserver/install/krainstance.py
-+++ b/ipaserver/install/krainstance.py
-@@ -25,17 +25,21 @@ import sys
- import tempfile
- 
- from ipalib import api
-+from ipalib import x509
- from ipaplatform import services
- from ipaplatform.paths import paths
-+from ipapython import certdb
- from ipapython import dogtag
- from ipapython import ipautil
- from ipapython.dn import DN
- from ipaserver.install import certs
- from ipaserver.install import cainstance
-+from ipaserver.install import installutils
- from ipaserver.install import ldapupdate
- from ipaserver.install import service
- from ipaserver.install.dogtaginstance import DogtagInstance
- from ipaserver.install.dogtaginstance import DEFAULT_DSPORT, PKI_USER
-+from ipaserver.plugins import ldap2
- from ipapython.ipa_log_manager import log_mgr
- 
- # When IPA is installed with DNS support, this CNAME should hold all IPA
-@@ -111,8 +115,8 @@ class KRAInstance(DogtagInstance):
- 
-         self.step("configuring KRA instance", self.__spawn_instance)
-         if not self.clone:
--            self.step("add RA user to KRA agent group",
--                      self.__add_ra_user_to_agent_group)
-+            self.step("create KRA agent",
-+                      self.__create_kra_agent)
-         self.step("restarting KRA", self.restart_instance)
-         self.step("configure certmonger for renewals",
-                   self.configure_certmonger_renewal)
-@@ -267,77 +271,46 @@ class KRAInstance(DogtagInstance):
- 
-         self.log.debug("completed creating KRA instance")
- 
--    def __add_ra_user_to_agent_group(self):
-+    def __create_kra_agent(self):
-         """
--        Add RA agent created for CA to KRA agent group.
-+        Create KRA agent, assign a certificate, and add the user to
-+        the appropriate groups for accessing KRA services.
-         """
- 
--        # import CA certificate into temporary security database
--        args = ["/usr/bin/pki",
--            "-d", self.agent_db,
--            "-C", paths.KRA_NSSDB_PASSWORD_FILE,
--            "client-cert-import",
--            "--pkcs12", paths.KRACERT_P12,
--            "--pkcs12-password-file", paths.KRA_PKCS12_PASSWORD_FILE]
--        ipautil.run(args)
--
--        # trust CA certificate
--        args = ["/usr/bin/pki",
--            "-d", self.agent_db,
--            "-C", paths.KRA_NSSDB_PASSWORD_FILE,
--            "client-cert-mod", "Certificate Authority - %s" % api.env.realm,
--            "--trust", "CT,c,"]
--        ipautil.run(args)
--
--        # import Dogtag admin certificate into temporary security database
--        args = ["/usr/bin/pki",
--            "-d", self.agent_db,
--            "-C", paths.KRA_NSSDB_PASSWORD_FILE,
--            "client-cert-import",
--            "--pkcs12", paths.DOGTAG_ADMIN_P12,
--            "--pkcs12-password-file", paths.KRA_PKCS12_PASSWORD_FILE]
--        ipautil.run(args)
--
--        # as Dogtag admin, create ipakra user in KRA
--        args = ["/usr/bin/pki",
--            "-d", self.agent_db,
--            "-C", paths.KRA_NSSDB_PASSWORD_FILE,
--            "-n", "ipa-ca-agent",
--            "kra-user-add", "ipakra",
--            "--fullName", "IPA KRA User"]
--        ipautil.run(args)
--
--        # as Dogtag admin, add ipakra into KRA agents group
--        args = ["/usr/bin/pki",
--            "-d", self.agent_db,
--            "-C", paths.KRA_NSSDB_PASSWORD_FILE,
--            "-n", "ipa-ca-agent",
--            "kra-user-membership-add", "ipakra", "Data Recovery Manager Agents"]
--        ipautil.run(args)
--
--        # assign ipaCert to ipakra
--        (file, filename) = tempfile.mkstemp()
--        os.close(file)
--        try:
--            # export ipaCert without private key
--            args = ["/usr/bin/pki",
--                "-d", paths.HTTPD_ALIAS_DIR,
--                "-C", paths.ALIAS_PWDFILE_TXT,
--                "client-cert-show", "ipaCert",
--                "--cert", filename]
--            ipautil.run(args)
--
--            # as Dogtag admin, upload and assign ipaCert to ipakra
--            args = ["/usr/bin/pki",
--                "-d", self.agent_db,
--                "-C", paths.KRA_NSSDB_PASSWORD_FILE,
--                "-n", "ipa-ca-agent",
--                "kra-user-cert-add", "ipakra",
--                "--input", filename]
--            ipautil.run(args)
--
--        finally:
--            os.remove(filename)
-+        # get ipaCert certificate
-+        with certdb.NSSDatabase(paths.HTTPD_ALIAS_DIR) as ipa_nssdb:
-+           cert_data = ipa_nssdb.get_cert("ipaCert")
-+        cert = x509.load_certificate(cert_data, x509.DER)
-+
-+        # connect to KRA database
-+        server_id = installutils.realm_to_serverid(api.env.realm)
-+        dogtag_uri = 'ldapi://%%2fvar%%2frun%%2fslapd-%s.socket' % server_id
-+        conn = ldap2.ldap2(api, ldap_uri=dogtag_uri)
-+        conn.connect(autobind=True)
-+
-+        # create ipakra user with ipaCert certificate
-+        user_dn = DN(('uid', "ipakra"), ('ou', 'people'), self.basedn)
-+        entry = conn.make_entry(
-+            user_dn,
-+            objectClass=['top', 'person', 'organizationalPerson',
-+                         'inetOrgPerson', 'cmsuser'],
-+            uid=["ipakra"],
-+            sn=["IPA KRA User"],
-+            cn=["IPA KRA User"],
-+            usertype=["undefined"],
-+            userCertificate=[cert_data],
-+            description=['2;%s;%s;%s' % (
-+                cert.serial_number,
-+                DN(('CN', 'Certificate Authority'), self.subject_base),
-+                DN(('CN', 'IPA RA'), self.subject_base))])
-+        conn.add_entry(entry)
-+
-+        # add ipakra user to Data Recovery Manager Agents group
-+        group_dn = DN(('cn', 'Data Recovery Manager Agents'), ('ou', 'groups'),
-+                self.basedn)
-+        conn.add_entry_to_group(user_dn, group_dn, 'uniqueMember')
-+
-+        conn.disconnect()
- 
-     def __add_vault_container(self):
-         sub_dict = {
--- 
-2.5.1
-
diff --git a/SOURCES/0115-factor-out-populate_remote_domain-method-into-module.patch b/SOURCES/0115-factor-out-populate_remote_domain-method-into-module.patch
new file mode 100644
index 0000000..522e57d
--- /dev/null
+++ b/SOURCES/0115-factor-out-populate_remote_domain-method-into-module.patch
@@ -0,0 +1,132 @@
+From 9b3a64e24a25a6ebbf7e755ae67c2f0eb2bfdf39 Mon Sep 17 00:00:00 2001
+From: Martin Babinsky <mbabinsk@redhat.com>
+Date: Thu, 1 Sep 2016 18:09:05 +0200
+Subject: [PATCH] factor out `populate_remote_domain` method into module-level
+ function
+
+This allows for re-use of this method in cases where the caller can not or
+wishes not to instantiate local Samba domain to retrieve information about
+remote ones.
+
+https://fedorahosted.org/freeipa/ticket/6057
+
+Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
+---
+ ipaserver/dcerpc.py | 94 ++++++++++++++++++++++++++++++-----------------------
+ 1 file changed, 53 insertions(+), 41 deletions(-)
+
+diff --git a/ipaserver/dcerpc.py b/ipaserver/dcerpc.py
+index 4d98485e17a9113322b7e38629fc43b593e99fd9..71b8ba6f17bea6b52ae26fe2467de380e5458099 100644
+--- a/ipaserver/dcerpc.py
++++ b/ipaserver/dcerpc.py
+@@ -1534,6 +1534,52 @@ def fetch_domains(api, mydomain, trustdomain, creds=None, server=None):
+     return result
+ 
+ 
++def retrieve_remote_domain(hostname, local_flatname,
++                           realm, realm_server=None,
++                           realm_admin=None, realm_passwd=None):
++    def get_instance(local_flatname):
++        # Fetch data from foreign domain using password only
++        rd = TrustDomainInstance('')
++        rd.parm.set('workgroup', local_flatname)
++        rd.creds = credentials.Credentials()
++        rd.creds.set_kerberos_state(credentials.DONT_USE_KERBEROS)
++        rd.creds.guess(rd.parm)
++        return rd
++
++    rd = get_instance(local_flatname)
++    rd.creds.set_anonymous()
++    rd.creds.set_workstation(hostname)
++    if realm_server is None:
++        rd.retrieve_anonymously(realm, discover_srv=True, search_pdc=True)
++    else:
++        rd.retrieve_anonymously(realm_server,
++                                discover_srv=False, search_pdc=True)
++    rd.read_only = True
++    if realm_admin and realm_passwd:
++        if 'name' in rd.info:
++            names = realm_admin.split('\\')
++            if len(names) > 1:
++                # realm admin is in DOMAIN\user format
++                # strip DOMAIN part as we'll enforce the one discovered
++                realm_admin = names[-1]
++            auth_string = u"%s\%s%%%s" \
++                          % (rd.info['name'], realm_admin, realm_passwd)
++            td = get_instance(local_flatname)
++            td.creds.parse_string(auth_string)
++            td.creds.set_workstation(hostname)
++            if realm_server is None:
++                # we must have rd.info['dns_hostname'] then
++                # as it is part of the anonymous discovery
++                td.retrieve(rd.info['dns_hostname'])
++            else:
++                td.retrieve(realm_server)
++            td.read_only = False
++            return td
++
++    # Otherwise, use anonymously obtained data
++    return rd
++
++
+ class TrustDomainJoins(object):
+     def __init__(self, api):
+         self.api = api
+@@ -1565,47 +1611,13 @@ class TrustDomainJoins(object):
+ 
+     def populate_remote_domain(self, realm, realm_server=None,
+                                realm_admin=None, realm_passwd=None):
+-        def get_instance(self):
+-            # Fetch data from foreign domain using password only
+-            rd = TrustDomainInstance('')
+-            rd.parm.set('workgroup', self.local_domain.info['name'])
+-            rd.creds = credentials.Credentials()
+-            rd.creds.set_kerberos_state(credentials.DONT_USE_KERBEROS)
+-            rd.creds.guess(rd.parm)
+-            return rd
+-
+-        rd = get_instance(self)
+-        rd.creds.set_anonymous()
+-        rd.creds.set_workstation(self.local_domain.hostname)
+-        if realm_server is None:
+-            rd.retrieve_anonymously(realm, discover_srv=True, search_pdc=True)
+-        else:
+-            rd.retrieve_anonymously(realm_server,
+-                                    discover_srv=False, search_pdc=True)
+-        rd.read_only = True
+-        if realm_admin and realm_passwd:
+-            if 'name' in rd.info:
+-                names = realm_admin.split('\\')
+-                if len(names) > 1:
+-                    # realm admin is in DOMAIN\user format
+-                    # strip DOMAIN part as we'll enforce the one discovered
+-                    realm_admin = names[-1]
+-                auth_string = u"%s\%s%%%s" \
+-                              % (rd.info['name'], realm_admin, realm_passwd)
+-                td = get_instance(self)
+-                td.creds.parse_string(auth_string)
+-                td.creds.set_workstation(self.local_domain.hostname)
+-                if realm_server is None:
+-                    # we must have rd.info['dns_hostname'] then
+-                    # as it is part of the anonymous discovery
+-                    td.retrieve(rd.info['dns_hostname'])
+-                else:
+-                    td.retrieve(realm_server)
+-                td.read_only = False
+-                self.remote_domain = td
+-                return
+-        # Otherwise, use anonymously obtained data
+-        self.remote_domain = rd
++        self.remote_domain = retrieve_remote_domain(
++            self.local_domain.hostname,
++            self.local_domain.info['name'],
++            realm,
++            realm_server=realm_server,
++            realm_admin=realm_admin,
++            realm_passwd=realm_passwd)
+ 
+     def get_realmdomains(self):
+         """
+-- 
+2.7.4
+
diff --git a/SOURCES/0116-Always-fetch-forest-info-from-root-DCs-when-establis.patch b/SOURCES/0116-Always-fetch-forest-info-from-root-DCs-when-establis.patch
new file mode 100644
index 0000000..2defd3e
--- /dev/null
+++ b/SOURCES/0116-Always-fetch-forest-info-from-root-DCs-when-establis.patch
@@ -0,0 +1,67 @@
+From 6686a4d8906f283a394eb9991af1ab6b66d5dfd1 Mon Sep 17 00:00:00 2001
+From: Martin Babinsky <mbabinsk@redhat.com>
+Date: Thu, 1 Sep 2016 18:14:22 +0200
+Subject: [PATCH] Always fetch forest info from root DCs when establishing
+ one-way trust
+
+Prior To Windows Server 2012R2, the `netr_DsRGetForestTrustInformation` calls
+performed against non-root forest domain DCs were automatically routed to
+the root domain DCs to resolve trust topology information.
+
+This is no longer the case, so the `com.redhat.idm.trust-fetch-domains` oddjob
+helper used to establish one-way needs to explicitly contact root domain DCs
+even in the case when an external trust to non-root domain is requested.
+
+https://fedorahosted.org/freeipa/ticket/6057
+
+Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
+---
+ install/oddjob/com.redhat.idm.trust-fetch-domains | 25 ++++++++++++++++++++++-
+ 1 file changed, 24 insertions(+), 1 deletion(-)
+
+diff --git a/install/oddjob/com.redhat.idm.trust-fetch-domains b/install/oddjob/com.redhat.idm.trust-fetch-domains
+index bffa021cd4f01d31b7271d1ad84420884ce8d99e..32406ac9274f63251180a1e1051e1f1e60f5ecec 100755
+--- a/install/oddjob/com.redhat.idm.trust-fetch-domains
++++ b/install/oddjob/com.redhat.idm.trust-fetch-domains
+@@ -40,6 +40,24 @@ def retrieve_keytab(api, ccache_name, oneway_keytab_name, oneway_principal):
+         pass
+ 
+ 
++def get_forest_root_domain(api_instance, trusted_domain):
++    """
++    retrieve trusted forest root domain for given domain name
++
++    :param api_instance: IPA API instance
++    :param trusted_domain: trusted domain name
++
++    :returns: forest root domain DNS name
++    """
++    trustconfig_show = api_instance.Command.trustconfig_show
++    flatname = trustconfig_show()['result']['ipantflatname'][0]
++
++    remote_domain = dcerpc.retrieve_remote_domain(
++        api_instance.env.host, flatname, trusted_domain)
++
++    return remote_domain.info['dns_forest']
++
++
+ def parse_options():
+     usage = "%prog <trusted domain name>\n"
+     parser = config.IPAOptionParser(usage=usage,
+@@ -169,7 +187,12 @@ except gssapi.exceptions.GSSError:
+ # We are done: we have ccache with TDO credentials and can fetch domains
+ ipa_domain = api.env.domain
+ os.environ['KRB5CCNAME'] = oneway_ccache_name
+-domains = dcerpc.fetch_domains(api, ipa_domain, trusted_domain, creds=True)
++
++# retrieve the forest root domain name and contact it to retrieve trust
++# topology info
++forest_root = get_forest_root_domain(api, trusted_domain)
++
++domains = dcerpc.fetch_domains(api, ipa_domain, forest_root, creds=True)
+ trust_domain_object = api.Command.trust_show(trusted_domain, raw=True)['result']
+ trust.add_new_domains_from_trust(api, None, trust_domain_object, domains)
+ 
+-- 
+2.7.4
+
diff --git a/SOURCES/0116-load-RA-backend-plugins-during-standalone-CA-install.patch b/SOURCES/0116-load-RA-backend-plugins-during-standalone-CA-install.patch
deleted file mode 100644
index d4d8af4..0000000
--- a/SOURCES/0116-load-RA-backend-plugins-during-standalone-CA-install.patch
+++ /dev/null
@@ -1,35 +0,0 @@
-From c26fec494cc348282d037efb88927f70df17f584 Mon Sep 17 00:00:00 2001
-From: Martin Babinsky <mbabinsk@redhat.com>
-Date: Fri, 4 Sep 2015 15:14:48 +0200
-Subject: [PATCH] load RA backend plugins during standalone CA install on
- CA-less IPA master
-
-CA-less IPA master has 'ra_plugin' set to 'none' in IPA config. When setting
-up Dogtag CA on the master we must override this setting in order to load
-dogtag backend plugins and succesfully complete CA installation.
-
-https://fedorahosted.org/freeipa/ticket/5288
-
-Reviewed-By: Jan Cholasta <jcholast@redhat.com>
----
- install/tools/ipa-ca-install | 4 +++-
- 1 file changed, 3 insertions(+), 1 deletion(-)
-
-diff --git a/install/tools/ipa-ca-install b/install/tools/ipa-ca-install
-index 8b1cea8d557f315ae38c2448e816ca0b2557077f..6564e4d0304d4e189b133c495b75f200b04e2988 100755
---- a/install/tools/ipa-ca-install
-+++ b/install/tools/ipa-ca-install
-@@ -160,7 +160,9 @@ def install_master(safe_options, options):
-     if not dsinstance.DsInstance().is_configured():
-         sys.exit("IPA server is not configured on this system.\n")
- 
--    api.bootstrap(in_server=True)
-+    # override ra_plugin setting read from default.conf so that we have
-+    # functional dogtag backend plugins during CA install
-+    api.bootstrap(in_server=True, ra_plugin='dogtag')
-     api.finalize()
- 
-     dm_password = options.password
--- 
-2.5.1
-
diff --git a/SOURCES/0117-Handle-timeout-error-in-ipa-httpd-kdcproxy.patch b/SOURCES/0117-Handle-timeout-error-in-ipa-httpd-kdcproxy.patch
deleted file mode 100644
index 389ac69..0000000
--- a/SOURCES/0117-Handle-timeout-error-in-ipa-httpd-kdcproxy.patch
+++ /dev/null
@@ -1,39 +0,0 @@
-From 6b5411bd9bf98bd7c4bb695b37c2e878f4b0f1ef Mon Sep 17 00:00:00 2001
-From: Christian Heimes <cheimes@redhat.com>
-Date: Thu, 10 Sep 2015 11:54:32 +0200
-Subject: [PATCH] Handle timeout error in ipa-httpd-kdcproxy
-
-The ipa-httpd-kdcproxy script now handles LDAP timeout errors correctly.
-A timeout does no longer result into an Apache startup error.
-
-https://fedorahosted.org/freeipa/ticket/5292
-
-Reviewed-By: Martin Basti <mbasti@redhat.com>
----
- install/tools/ipa-httpd-kdcproxy | 3 ++-
- 1 file changed, 2 insertions(+), 1 deletion(-)
-
-diff --git a/install/tools/ipa-httpd-kdcproxy b/install/tools/ipa-httpd-kdcproxy
-index 60b22f2cc321d416871c74f3b4d580594c186a85..5e9863f8bd82e1628030b0b767a6697ab2a1d7bd 100755
---- a/install/tools/ipa-httpd-kdcproxy
-+++ b/install/tools/ipa-httpd-kdcproxy
-@@ -24,6 +24,7 @@ This script creates or removes the symlink from /etc/ipa/ipa-kdc-proxy.conf
- to /etc/httpd/conf.d/. It's called from ExecStartPre hook in httpd.service.
- """
- import os
-+import socket
- import sys
- 
- from ipalib import api, errors
-@@ -81,7 +82,7 @@ class KDCProxyConfig(object):
-             # EXTERNAL bind as root user
-             self.con.ldapi = True
-             self.con.do_bind(timeout=self.time_limit)
--        except errors.NetworkError as e:
-+        except (errors.NetworkError, socket.timeout) as e:
-             msg = 'Unable to connect to dirsrv: %s' % e
-             raise CheckError(msg)
-         except errors.AuthorizationError as e:
--- 
-2.4.3
-
diff --git a/SOURCES/0117-cli-use-full-name-when-executing-a-command.patch b/SOURCES/0117-cli-use-full-name-when-executing-a-command.patch
new file mode 100644
index 0000000..7bf6ae2
--- /dev/null
+++ b/SOURCES/0117-cli-use-full-name-when-executing-a-command.patch
@@ -0,0 +1,31 @@
+From 5139c4ad3a4601d0fc7204b46e2a889d44a79b36 Mon Sep 17 00:00:00 2001
+From: Jan Cholasta <jcholast@redhat.com>
+Date: Mon, 5 Sep 2016 10:18:13 +0200
+Subject: [PATCH] cli: use full name when executing a command
+
+Fixes the CLI not to always call the default version of a command even when
+the version was explicitly specified.
+
+https://fedorahosted.org/freeipa/ticket/6279
+
+Reviewed-By: Martin Basti <mbasti@redhat.com>
+---
+ ipalib/cli.py | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/ipalib/cli.py b/ipalib/cli.py
+index d89a5320853ecf575c7ba710b2db2e62e1003141..df9e6cfd20fead7fd28667386c359db250e64b20 100644
+--- a/ipalib/cli.py
++++ b/ipalib/cli.py
+@@ -1101,7 +1101,7 @@ class cli(backend.Executioner):
+         cmd = self.get_command(argv)
+         if cmd is None:
+             return
+-        name = cmd.name
++        name = cmd.full_name
+         kw = self.parse(cmd, argv[1:])
+         if not isinstance(cmd, frontend.Local):
+             self.create_context()
+-- 
+2.7.4
+
diff --git a/SOURCES/0118-Server-Upgrade-backup-CS.cfg-when-dogtag-is-turned-o.patch b/SOURCES/0118-Server-Upgrade-backup-CS.cfg-when-dogtag-is-turned-o.patch
deleted file mode 100644
index 2edc965..0000000
--- a/SOURCES/0118-Server-Upgrade-backup-CS.cfg-when-dogtag-is-turned-o.patch
+++ /dev/null
@@ -1,36 +0,0 @@
-From 908019639e5e0975d3cd73c3c851319224737dcd Mon Sep 17 00:00:00 2001
-From: Martin Basti <mbasti@redhat.com>
-Date: Thu, 10 Sep 2015 18:46:00 +0200
-Subject: [PATCH] Server Upgrade: backup CS.cfg when dogtag is turned off
-
-Is unable to made CS.cfg when dogtag is running.
-
-https://fedorahosted.org/freeipa/ticket/5287
-
-Reviewed-By: David Kupka <dkupka@redhat.com>
----
- ipaserver/install/server/upgrade.py | 5 ++++-
- 1 file changed, 4 insertions(+), 1 deletion(-)
-
-diff --git a/ipaserver/install/server/upgrade.py b/ipaserver/install/server/upgrade.py
-index a57682a4bbdaab2a15b4e415223e2f5faa67ba73..5288f8fcc5fb56b13773e3bb8ea6a5a6c8c0e8a9 100644
---- a/ipaserver/install/server/upgrade.py
-+++ b/ipaserver/install/server/upgrade.py
-@@ -1354,10 +1354,13 @@ def upgrade_configuration():
-         sub_dict['SUBJECT_BASE'] = subject_base
- 
-     ca = cainstance.CAInstance(api.env.realm, certs.NSS_DIR)
--    ca.backup_config()
- 
-     with installutils.stopped_service(configured_constants.SERVICE_NAME,
-             configured_constants.PKI_INSTANCE_NAME):
-+
-+        # Dogtag must be stopped to be able to backup CS.cfg config
-+        ca.backup_config()
-+
-         # migrate CRL publish dir before the location in ipa.conf is updated
-         ca_restart = migrate_crl_publish_dir(ca)
- 
--- 
-2.4.3
-
diff --git a/SOURCES/0118-Use-RSA-OAEP-instead-of-RSA-PKCS-1-v1.5.patch b/SOURCES/0118-Use-RSA-OAEP-instead-of-RSA-PKCS-1-v1.5.patch
new file mode 100644
index 0000000..301cfd9
--- /dev/null
+++ b/SOURCES/0118-Use-RSA-OAEP-instead-of-RSA-PKCS-1-v1.5.patch
@@ -0,0 +1,33 @@
+From 88b8163fa5f3b4f01dab588c2b08db9258c55be1 Mon Sep 17 00:00:00 2001
+From: Christian Heimes <cheimes@redhat.com>
+Date: Mon, 5 Sep 2016 15:38:48 +0200
+Subject: [PATCH] Use RSA-OAEP instead of RSA PKCS#1 v1.5
+
+jwcrypto's RSA1-5 (PKCS#1 v1.5) is vulnerable to padding oracle
+side-channel attacks. OAEP (PKCS#1 v2.0) is a safe, more modern
+alternative.
+
+https://fedorahosted.org/freeipa/ticket/6278
+
+Signed-off-by: Christian Heimes <cheimes@redhat.com>
+Reviewed-By: Martin Basti <mbasti@redhat.com>
+---
+ ipapython/secrets/client.py | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/ipapython/secrets/client.py b/ipapython/secrets/client.py
+index 56ed6f7944c46393ed225cde1b5e0bb80fe6bef0..d9cc7d0f5b066dfd8efba480feb5f271ed1ebe83 100644
+--- a/ipapython/secrets/client.py
++++ b/ipapython/secrets/client.py
+@@ -86,7 +86,7 @@ class CustodiaClient(object):
+         url = 'https://%s/ipa/keys/%s' % (self.server, keyname)
+ 
+         # Prepare signed/encrypted request
+-        encalg = ('RSA1_5', 'A256CBC-HS512')
++        encalg = ('RSA-OAEP', 'A256CBC-HS512')
+         request = self.kemcli.make_request(keyname, encalg=encalg)
+ 
+         # Prepare Authentication header
+-- 
+2.7.4
+
diff --git a/SOURCES/0119-Fix-ipa-certupdate-for-CA-less-installation.patch b/SOURCES/0119-Fix-ipa-certupdate-for-CA-less-installation.patch
new file mode 100644
index 0000000..31d64a9
--- /dev/null
+++ b/SOURCES/0119-Fix-ipa-certupdate-for-CA-less-installation.patch
@@ -0,0 +1,44 @@
+From 0c3b7bd3b51626fc7f29c98087e1d59ea079bcda Mon Sep 17 00:00:00 2001
+From: Florence Blanc-Renaud <flo@redhat.com>
+Date: Thu, 1 Sep 2016 15:53:38 +0200
+Subject: [PATCH] Fix ipa-certupdate for CA-less installation
+
+In a CA-less installation, ipa-certupdate fails with the error message:
+  $ ipa-certupdate
+  trying https://vm-180.abc.idm.lab.eng.brq.redhat.com/ipa/session/json
+  Forwarding 'ca_is_enabled' to json server 'https://vm-180.abc.idm.lab.eng.brq.redhat.com/ipa/session/json'
+  Forwarding 'ca_find/1' to json server 'https://vm-180.abc.idm.lab.eng.brq.redhat.com/ipa/session/json'
+  CA is not configured
+  The ipa-certupdate command failed.
+
+The issue happens because ipa-certupdate tries to call ca_find even on a
+CA_less deployment. The fix skips the call to ca_find in this case.
+
+https://fedorahosted.org/freeipa/ticket/6288
+
+Reviewed-By: Tomas Krizek <tkrizek@redhat.com>
+---
+ ipaclient/ipa_certupdate.py | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+diff --git a/ipaclient/ipa_certupdate.py b/ipaclient/ipa_certupdate.py
+index e59047a2705eb8ccb98b5213c4c8771f55a29bc5..f340f32bcdca5f5d98177f7aa9af366b67d8dd80 100644
+--- a/ipaclient/ipa_certupdate.py
++++ b/ipaclient/ipa_certupdate.py
+@@ -87,9 +87,10 @@ class CertUpdate(admintool.AdminTool):
+ 
+             # find lightweight CAs (on renewal master only)
+             lwcas = []
+-            for ca_obj in api.Command.ca_find()['result']:
+-                if IPA_CA_CN not in ca_obj['cn']:
+-                    lwcas.append(ca_obj)
++            if ca_enabled:
++                for ca_obj in api.Command.ca_find()['result']:
++                    if IPA_CA_CN not in ca_obj['cn']:
++                        lwcas.append(ca_obj)
+ 
+             api.Backend.rpcclient.disconnect()
+         finally:
+-- 
+2.7.4
+
diff --git a/SOURCES/0119-IPA-Restore-allows-to-specify-files-that-should-be-r.patch b/SOURCES/0119-IPA-Restore-allows-to-specify-files-that-should-be-r.patch
deleted file mode 100644
index 27a4fda..0000000
--- a/SOURCES/0119-IPA-Restore-allows-to-specify-files-that-should-be-r.patch
+++ /dev/null
@@ -1,75 +0,0 @@
-From 98e289720cbe58e2d921ee95d316644c1bb5cce8 Mon Sep 17 00:00:00 2001
-From: Martin Basti <mbasti@redhat.com>
-Date: Thu, 10 Sep 2015 16:35:54 +0200
-Subject: [PATCH] IPA Restore: allows to specify files that should be removed
-
-Some files/directories should be removed before backup files are copied
-to filesystem.
-
-In case of DNSSEC, the /var/lib/ipa/dnssec/tokens directory has to be
-removed, otherwise tokens that are backed up and existing tokens will be
-mixed and SOFTHSM log in will not work
-
-https://fedorahosted.org/freeipa/ticket/5293
-
-Reviewed-By: David Kupka <dkupka@redhat.com>
----
- ipaserver/install/ipa_restore.py | 28 ++++++++++++++++++++++++++++
- 1 file changed, 28 insertions(+)
-
-diff --git a/ipaserver/install/ipa_restore.py b/ipaserver/install/ipa_restore.py
-index 8960626d0f0e438ef198e2d92803983e520051a8..dc57a4937365ad1db960955cf21e1bf2d2eb3dda 100644
---- a/ipaserver/install/ipa_restore.py
-+++ b/ipaserver/install/ipa_restore.py
-@@ -128,6 +128,14 @@ class Restore(admintool.AdminTool):
- 
-     description = "Restore IPA files and databases."
- 
-+    # directories and files listed here will be removed from filesystem before
-+    # files from backup are copied
-+    DIRS_TO_BE_REMOVED = [
-+        paths.DNSSEC_TOKENS_DIR,
-+    ]
-+
-+    FILES_TO_BE_REMOVED = []
-+
-     def __init__(self, options, args):
-         super(Restore, self).__init__(options, args)
-         self._conn = None
-@@ -365,6 +373,7 @@ 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()
-@@ -640,6 +649,25 @@ class Restore(admintool.AdminTool):
-                               (paths.IPA_DEFAULT_CONF, stderr))
-         os.chdir(cwd)
- 
-+    def remove_old_files(self):
-+        """
-+        Removes all directories, files or temporal files that should be
-+        removed before backup files are copied, to prevent errors.
-+        """
-+        for d in self.DIRS_TO_BE_REMOVED:
-+            try:
-+                shutil.rmtree(d)
-+            except OSError as e:
-+                if e.errno != 2:  # 2: dir does not exist
-+                    self.log.warning("Could not remove directory: %s (%s)",
-+                                     d, e)
-+
-+        for f in self.FILES_TO_BE_REMOVED:
-+            try:
-+                os.remove(f)
-+            except OSError as e:
-+                if e.errno != 2:  # 2: file does not exist
-+                    self.log.warning("Could not remove file: %s (%s)", f, e)
- 
-     def file_restore(self, nologs=False):
-         '''
--- 
-2.4.3
-
diff --git a/SOURCES/0120-Track-lightweight-CAs-on-replica-installation.patch b/SOURCES/0120-Track-lightweight-CAs-on-replica-installation.patch
new file mode 100644
index 0000000..dc2fe2f
--- /dev/null
+++ b/SOURCES/0120-Track-lightweight-CAs-on-replica-installation.patch
@@ -0,0 +1,208 @@
+From 01fcae3f99ba3368cb88418e14b6bbbe81bc555d Mon Sep 17 00:00:00 2001
+From: Fraser Tweedale <ftweedal@redhat.com>
+Date: Tue, 23 Aug 2016 16:14:30 +1000
+Subject: [PATCH] Track lightweight CAs on replica installation
+
+Add Certmonger tracking requests for lightweight CAs on replica
+installation.  As part of this change, extract most of the
+lightweight CA tracking code out of ipa-certupdate and into
+cainstance.
+
+Fixes: https://fedorahosted.org/freeipa/ticket/6019
+Reviewed-By: Martin Babinsky <mbabinsk@redhat.com>
+---
+ ipaclient/ipa_certupdate.py     | 53 ++++++---------------------------
+ ipalib/constants.py             |  2 ++
+ ipaserver/install/cainstance.py | 66 +++++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 77 insertions(+), 44 deletions(-)
+
+diff --git a/ipaclient/ipa_certupdate.py b/ipaclient/ipa_certupdate.py
+index f340f32bcdca5f5d98177f7aa9af366b67d8dd80..4b97b85b83c8b1a130d6db9cdcc7a76fc569af9e 100644
+--- a/ipaclient/ipa_certupdate.py
++++ b/ipaclient/ipa_certupdate.py
+@@ -29,10 +29,8 @@ from ipaplatform import services
+ from ipaplatform.paths import paths
+ from ipaplatform.tasks import tasks
+ from ipalib import api, errors, x509, certstore
+-from ipalib.constants import IPA_CA_CN
++from ipalib.constants import IPA_CA_NICKNAME, RENEWAL_CA_NAME
+ 
+-IPA_CA_NICKNAME = 'caSigningCert cert-pki-ca'
+-RENEWAL_CA_NAME = 'dogtag-ipa-ca-renew-agent'
+ 
+ class CertUpdate(admintool.AdminTool):
+     command_name = 'ipa-certupdate'
+@@ -85,12 +83,7 @@ class CertUpdate(admintool.AdminTool):
+             certs = certstore.get_ca_certs(ldap, api.env.basedn,
+                                            api.env.realm, ca_enabled)
+ 
+-            # find lightweight CAs (on renewal master only)
+-            lwcas = []
+-            if ca_enabled:
+-                for ca_obj in api.Command.ca_find()['result']:
+-                    if IPA_CA_CN not in ca_obj['cn']:
+-                        lwcas.append(ca_obj)
++            lwcas = api.Command.ca_find()['result']
+ 
+             api.Backend.rpcclient.disconnect()
+         finally:
+@@ -99,8 +92,13 @@ class CertUpdate(admintool.AdminTool):
+         server_fstore = sysrestore.FileStore(paths.SYSRESTORE)
+         if server_fstore.has_files():
+             self.update_server(certs)
+-            for entry in lwcas:
+-                self.server_track_lightweight_ca(entry)
++            try:
++                from ipaserver.install import cainstance
++                cainstance.add_lightweight_ca_tracking_requests(
++                    self.log, lwcas)
++            except Exception as e:
++                self.log.exception(
++                    "Failed to add lightweight CA tracking requests")
+ 
+         self.update_client(certs)
+ 
+@@ -164,39 +162,6 @@ class CertUpdate(admintool.AdminTool):
+ 
+         self.update_file(paths.CA_CRT, certs)
+ 
+-    def server_track_lightweight_ca(self, entry):
+-        nickname = "{} {}".format(IPA_CA_NICKNAME, entry['ipacaid'][0])
+-        criteria = {
+-            'cert-database': paths.PKI_TOMCAT_ALIAS_DIR,
+-            'cert-nickname': nickname,
+-            'ca-name': RENEWAL_CA_NAME,
+-        }
+-        request_id = certmonger.get_request_id(criteria)
+-        if request_id is None:
+-            try:
+-                certmonger.dogtag_start_tracking(
+-                    secdir=paths.PKI_TOMCAT_ALIAS_DIR,
+-                    pin=certmonger.get_pin('internal'),
+-                    pinfile=None,
+-                    nickname=nickname,
+-                    ca=RENEWAL_CA_NAME,
+-                    pre_command='stop_pkicad',
+-                    post_command='renew_ca_cert "%s"' % nickname,
+-                )
+-                request_id = certmonger.get_request_id(criteria)
+-                certmonger.modify(request_id, profile='ipaCACertRenewal')
+-                self.log.debug(
+-                    'Lightweight CA renewal: '
+-                    'added tracking request for "%s"', nickname)
+-            except RuntimeError as e:
+-                self.log.error(
+-                    'Lightweight CA renewal: Certmonger failed to '
+-                    'start tracking certificate: %s', e)
+-        else:
+-            self.log.debug(
+-                'Lightweight CA renewal: '
+-                'already tracking certificate "%s"', nickname)
+-
+     def update_file(self, filename, certs, mode=0o444):
+         certs = (c[0] for c in certs if c[2] is not False)
+         try:
+diff --git a/ipalib/constants.py b/ipalib/constants.py
+index 9b351e260f15211330521453b3ffcd41433a04bb..04515dcd25d066d8f1ab79ae8e8b96e909a1d884 100644
+--- a/ipalib/constants.py
++++ b/ipalib/constants.py
+@@ -274,3 +274,5 @@ CA_SUFFIX_NAME = 'ca'
+ PKI_GSSAPI_SERVICE_NAME = 'dogtag'
+ IPA_CA_CN = u'ipa'
+ IPA_CA_RECORD = "ipa-ca"
++IPA_CA_NICKNAME = 'caSigningCert cert-pki-ca'
++RENEWAL_CA_NAME = 'dogtag-ipa-ca-renew-agent'
+diff --git a/ipaserver/install/cainstance.py b/ipaserver/install/cainstance.py
+index e94fec5f6fd898b66dc12407be6e3f671ac3f4de..3551887cd8ff8baa5e17f8969c84fb92d7552ef3 100644
+--- a/ipaserver/install/cainstance.py
++++ b/ipaserver/install/cainstance.py
+@@ -1382,6 +1382,9 @@ class CAInstance(DogtagInstance):
+ 
+         self.step("enabling CA instance", self.__enable_instance)
+ 
++        self.step("configuring certmonger renewal for lightweight CAs",
++                  self.__add_lightweight_ca_tracking_requests)
++
+         self.start_creation(runtime=210)
+ 
+     def setup_lightweight_ca_key_retrieval(self):
+@@ -1447,6 +1450,22 @@ class CAInstance(DogtagInstance):
+         os.chmod(keyfile, 0o600)
+         os.chown(keyfile, pent.pw_uid, pent.pw_gid)
+ 
++    def __add_lightweight_ca_tracking_requests(self):
++        if not self.admin_conn:
++            self.ldap_connect()
++
++        try:
++            lwcas = self.admin_conn.get_entries(
++                base_dn=api.env.basedn,
++                filter='(objectclass=ipaca)',
++                attrs_list=['cn', 'ipacaid'],
++            )
++            add_lightweight_ca_tracking_requests(self.log, lwcas)
++        except errors.NotFound:
++            # shouldn't happen, but don't fail if it does
++            root_logger.warning(
++                "Did not find any lightweight CAs; nothing to track")
++
+ 
+ def replica_ca_install_check(config):
+     if not config.setup_ca:
+@@ -2069,6 +2088,53 @@ def ensure_default_caacl():
+         api.Backend.ldap2.disconnect()
+ 
+ 
++def add_lightweight_ca_tracking_requests(logger, lwcas):
++    """Add tracking requests for the given lightweight CAs.
++
++    The entries must have the 'cn' and 'ipacaid' attributes.
++
++    The IPA CA, if present, is skipped.
++
++    """
++    for entry in lwcas:
++        if ipalib.constants.IPA_CA_CN in entry['cn']:
++            continue
++
++        nickname = "{} {}".format(
++                ipalib.constants.IPA_CA_NICKNAME,
++                entry['ipacaid'][0])
++        criteria = {
++            'cert-database': paths.PKI_TOMCAT_ALIAS_DIR,
++            'cert-nickname': nickname,
++            'ca-name': ipalib.constants.RENEWAL_CA_NAME,
++        }
++        request_id = certmonger.get_request_id(criteria)
++        if request_id is None:
++            try:
++                certmonger.dogtag_start_tracking(
++                    secdir=paths.PKI_TOMCAT_ALIAS_DIR,
++                    pin=certmonger.get_pin('internal'),
++                    pinfile=None,
++                    nickname=nickname,
++                    ca=ipalib.constants.RENEWAL_CA_NAME,
++                    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)
++            except RuntimeError as e:
++                logger.error(
++                    'Lightweight CA renewal: Certmonger failed to '
++                    'start tracking certificate: %s', e)
++        else:
++            logger.debug(
++                'Lightweight CA renewal: '
++                'already tracking certificate "%s"', nickname)
++
++
+ def update_ipa_conf():
+     """
+     Update IPA configuration file to ensure that RA plugins are enabled and
+-- 
+2.7.4
+
diff --git a/SOURCES/0120-config-allow-user-host-attributes-with-tagging-optio.patch b/SOURCES/0120-config-allow-user-host-attributes-with-tagging-optio.patch
deleted file mode 100644
index 926c779..0000000
--- a/SOURCES/0120-config-allow-user-host-attributes-with-tagging-optio.patch
+++ /dev/null
@@ -1,35 +0,0 @@
-From 19f9ad712fc8d8652d66b8aac8befd9d83dad721 Mon Sep 17 00:00:00 2001
-From: Jan Cholasta <jcholast@redhat.com>
-Date: Wed, 16 Sep 2015 08:24:22 +0200
-Subject: [PATCH] config: allow user/host attributes with tagging options
-
-https://fedorahosted.org/freeipa/ticket/5295
-
-Reviewed-By: David Kupka <dkupka@redhat.com>
----
- ipalib/plugins/config.py | 2 ++
- 1 file changed, 2 insertions(+)
-
-diff --git a/ipalib/plugins/config.py b/ipalib/plugins/config.py
-index 6267313d5e9af2d97f45f987115de143d7aa7915..76368c0887f782153c3131c7833f78afe86dcf89 100644
---- a/ipalib/plugins/config.py
-+++ b/ipalib/plugins/config.py
-@@ -262,6 +262,7 @@ class config_mod(LDAPUpdate):
-                 fields = entry_attrs[k].split(',')
-                 for a in fields:
-                     a = a.strip()
-+                    a, tomato, olive = a.partition(';')
-                     if a not in allowed_attrs:
-                         raise errors.ValidationError(
-                             name=k, error=_('attribute "%s" not allowed') % a
-@@ -281,6 +282,7 @@ class config_mod(LDAPUpdate):
-                 if self.api.Object[obj].uuid_attribute:
-                     checked_attrs = checked_attrs + [self.api.Object[obj].uuid_attribute]
-                 for obj_attr in checked_attrs:
-+                    obj_attr, tomato, olive = obj_attr.partition(';')
-                     if obj_attr in OPERATIONAL_ATTRIBUTES:
-                         continue
-                     if obj_attr in self.api.Object[obj].params and \
--- 
-2.4.3
-
diff --git a/SOURCES/0121-dns-normalize-record-type-read-interactively-in-dnsr.patch b/SOURCES/0121-dns-normalize-record-type-read-interactively-in-dnsr.patch
new file mode 100644
index 0000000..f2700cb
--- /dev/null
+++ b/SOURCES/0121-dns-normalize-record-type-read-interactively-in-dnsr.patch
@@ -0,0 +1,36 @@
+From 52ad614c1d2c7dedc46ce2420cbd146a623fbd94 Mon Sep 17 00:00:00 2001
+From: Jan Cholasta <jcholast@redhat.com>
+Date: Mon, 5 Sep 2016 09:35:42 +0200
+Subject: [PATCH] dns: normalize record type read interactively in
+ dnsrecord_add
+
+When dnsrecord_add is called without options in interactive mode, it
+prompts the user to enter a record type. The record type is expected to be
+upper case further in the code, which causes non-upper case values not to
+work correctly.
+
+Fix this issue by upper casing the value after it is read.
+
+https://fedorahosted.org/freeipa/ticket/6203
+
+Reviewed-By: Martin Basti <mbasti@redhat.com>
+---
+ ipaclient/plugins/dns.py | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/ipaclient/plugins/dns.py b/ipaclient/plugins/dns.py
+index e17c282fab2bf1ede095fe37e5cb240eaea21e35..db9c17f8b523365779e53adfb2acc43f4a23401f 100644
+--- a/ipaclient/plugins/dns.py
++++ b/ipaclient/plugins/dns.py
+@@ -175,6 +175,8 @@ class dnsrecord_add(MethodOverride):
+             if rrtype is None:
+                 return
+ 
++            rrtype = rrtype.upper()
++
+             try:
+                 name = record_name_format % rrtype.lower()
+                 param = self.params[name]
+-- 
+2.7.4
+
diff --git a/SOURCES/0121-winsync-Add-inetUser-objectclass-to-the-passsync-sys.patch b/SOURCES/0121-winsync-Add-inetUser-objectclass-to-the-passsync-sys.patch
deleted file mode 100644
index f3350a8..0000000
--- a/SOURCES/0121-winsync-Add-inetUser-objectclass-to-the-passsync-sys.patch
+++ /dev/null
@@ -1,52 +0,0 @@
-From e2c2bd871a0282628364dcb83d1feba44c5f71dc Mon Sep 17 00:00:00 2001
-From: Tomas Babej <tbabej@redhat.com>
-Date: Tue, 15 Sep 2015 11:28:18 +0200
-Subject: [PATCH] winsync: Add inetUser objectclass to the passsync sysaccount
-
-https://bugzilla.redhat.com/show_bug.cgi?id=1262315
-
-Reviewed-By: Petr Vobornik <pvoborni@redhat.com>
----
- install/updates/73-winsync.update | 3 +++
- install/updates/Makefile.am       | 1 +
- ipaserver/install/replication.py  | 2 +-
- 3 files changed, 5 insertions(+), 1 deletion(-)
- create mode 100644 install/updates/73-winsync.update
-
-diff --git a/install/updates/73-winsync.update b/install/updates/73-winsync.update
-new file mode 100644
-index 0000000000000000000000000000000000000000..538eaa1cb6f97a73bfaadd61ac2ce9e9137739cf
---- /dev/null
-+++ b/install/updates/73-winsync.update
-@@ -0,0 +1,3 @@
-+# Add a inetUser objectclass to the passsync user
-+dn: uid=passsync,cn=sysaccounts,cn=etc,$SUFFIX
-+addifexist: objectClass: inetUser
-diff --git a/install/updates/Makefile.am b/install/updates/Makefile.am
-index 2693e4f8f81dc1464a43041e5104ea4363440933..1f4a91c9bb4222f99ad7a7ad16e376aeef7f525b 100644
---- a/install/updates/Makefile.am
-+++ b/install/updates/Makefile.am
-@@ -51,6 +51,7 @@ app_DATA =				\
- 	62-ranges.update		\
- 	71-idviews.update		\
- 	72-domainlevels.update		\
-+	73-winsync.update		\
- 	90-post_upgrade_plugins.update	\
- 	$(NULL)
- 
-diff --git a/ipaserver/install/replication.py b/ipaserver/install/replication.py
-index 2b36a5eb9287bf1789009a3198e540e333869e98..4bd3849e5e91c7251856362891f6c8848da43448 100644
---- a/ipaserver/install/replication.py
-+++ b/ipaserver/install/replication.py
-@@ -565,7 +565,7 @@ class ReplicationManager(object):
-             print "Adding Windows PassSync system account"
-             entry = conn.make_entry(
-                 pass_dn,
--                objectclass=["account", "simplesecurityobject"],
-+                objectclass=["account", "simplesecurityobject", "inetUser"],
-