The Identity, Policy and Audit system
CentOS Sources
2017-10-19 460745326ba253b5c4924b624dbc2f0714a2af42
import ipa-4.5.0-21.el7_4.2.2
13 files added
1 files deleted
5 files modified
1278 ■■■■■ changed files
SOURCES/0220-ipa-otptoken-import-Make-PBKDF2-refer-to-the-pkcs5-n.patch 84 ●●●●● patch | view | raw | blame | history
SOURCES/0221-Adds-whoami-DS-plugin-in-case-that-plugin-is-missing.patch 59 ●●●●● patch | view | raw | blame | history
SOURCES/0222-Fix-ipa-config-mod-ca-renewal-master.patch 88 ●●●●● patch | view | raw | blame | history
SOURCES/0223-Backport-PR-988-to-ipa-4-5-Fix-Certificate-renewal-w.patch 60 ●●●●● patch | view | raw | blame | history
SOURCES/0224-Backport-PR-1008-to-ipa-4-5-Fix-ipa-server-upgrade-T.patch 213 ●●●●● patch | view | raw | blame | history
SOURCES/0225-Fixing-how-sssd.conf-is-updated-when-promoting-a-cli.patch 92 ●●●●● patch | view | raw | blame | history
SOURCES/0226-Backport-4-5-Fix-ipa-server-upgrade-with-server-cert.patch 199 ●●●●● patch | view | raw | blame | history
SOURCES/0227-Always-check-peer-has-keys-before-connecting.patch 73 ●●●●● patch | view | raw | blame | history
SOURCES/0228-Make-sure-upgrade-also-checks-for-IPv6-stack.patch 61 ●●●●● patch | view | raw | blame | history
SOURCES/0229-control-logging-of-host_port_open-from-caller.patch 103 ●●●●● patch | view | raw | blame | history
SOURCES/0230-log-progress-of-wait_for_open_ports.patch 44 ●●●●● patch | view | raw | blame | history
SOURCES/0231-Store-help-in-Schema-before-writing-to-disk.patch 39 ●●●●● patch | view | raw | blame | history
SOURCES/0232-Disable-pylint-in-get_help-function-because-of-type-.patch 33 ●●●●● patch | view | raw | blame | history
SOURCES/1001-Change-branding-to-IPA-and-Identity-Management.patch 8 ●●●● patch | view | raw | blame | history
SOURCES/1002-Package-copy-schema-to-ca.py.patch 4 ●●●● patch | view | raw | blame | history
SOURCES/1003-Revert-Increased-mod_wsgi-socket-timeout.patch 4 ●●●● patch | view | raw | blame | history
SOURCES/1004-Remove-csrgen.patch 4 ●●●● patch | view | raw | blame | history
SOURCES/ipa-centos-branding.patch 38 ●●●●● patch | view | raw | blame | history
SPECS/ipa.spec 72 ●●●● patch | view | raw | blame | history
SOURCES/0220-ipa-otptoken-import-Make-PBKDF2-refer-to-the-pkcs5-n.patch
New file
@@ -0,0 +1,84 @@
From 92f450a4b6eacb7950e5414d40d9949076cb096e Mon Sep 17 00:00:00 2001
From: Nathaniel McCallum <npmccallum@redhat.com>
Date: Tue, 20 Jun 2017 10:31:15 -0400
Subject: [PATCH] ipa-otptoken-import: Make PBKDF2 refer to the pkcs5 namespace
For some unknown reason, when I wrote the ipa-otptoken-import script
I used bad input data which had the PBKDF2 parameters in the wrong
XML namespace. I have corrected this input data to match RFC 6030.
https://pagure.io/freeipa/issue/7035
Signed-off-by: Nathaniel McCallum <npmccallum@redhat.com>
Reviewed-By: Martin Basti <mbasti@redhat.com>
Reviewed-By: Stanislav Laznicka <slaznick@redhat.com>
---
 ipaserver/install/ipa_otptoken_import.py      | 15 ++++++---------
 ipatests/test_ipaserver/data/pskc-figure7.xml | 16 ++++++++--------
 2 files changed, 14 insertions(+), 17 deletions(-)
diff --git a/ipaserver/install/ipa_otptoken_import.py b/ipaserver/install/ipa_otptoken_import.py
index 2580e2cfc97f4960af68a5eae407a7ebe3c7a257..31225e96b55c20bd78e9a8650848a28cf9feef63 100644
--- a/ipaserver/install/ipa_otptoken_import.py
+++ b/ipaserver/install/ipa_otptoken_import.py
@@ -52,6 +52,7 @@ class ValidationError(Exception):
 def fetchAll(element, xpath, conv=lambda x: x):
     return [conv(e) for e in element.xpath(xpath, namespaces={
+        "pkcs5": "http://www.rsasecurity.com/rsalabs/pkcs/schemas/pkcs-5v2-0#",
         "pskc": "urn:ietf:params:xml:ns:keyprov:pskc",
         "xenc11": "http://www.w3.org/2009/xmlenc11#",
         "xenc": "http://www.w3.org/2001/04/xmlenc#",
@@ -175,18 +176,14 @@ class XMLKeyDerivation(six.with_metaclass(abc.ABCMeta, object)):
 class PBKDF2KeyDerivation(XMLKeyDerivation):
     def __init__(self, enckey):
-        params = fetch(enckey, "./xenc11:DerivedKey/xenc11:KeyDerivationMethod/xenc11:PBKDF2-params")
+        params = fetch(enckey, "./xenc11:DerivedKey/xenc11:KeyDerivationMethod/pkcs5:PBKDF2-params")
         if params is None:
             raise ValueError("XML file is missing PBKDF2 parameters!")
-        salt = fetch(
-            params, "./xenc11:Salt/xenc11:Specified/text()", base64.b64decode)
-        itrs = fetch(
-            params, "./xenc11:IterationCount/text()", int)
-        klen = fetch(
-            params, "./xenc11:KeyLength/text()", int)
-        hmod = fetch(
-            params, "./xenc11:PRF/@Algorithm", convertHMACType, hashes.SHA1)
+        salt = fetch(params, "./Salt/Specified/text()", base64.b64decode)
+        itrs = fetch(params, "./IterationCount/text()", int)
+        klen = fetch(params, "./KeyLength/text()", int)
+        hmod = fetch(params, "./PRF/@Algorithm", convertHMACType, hashes.SHA1)
         if salt is None:
             raise ValueError("XML file is missing PBKDF2 salt!")
diff --git a/ipatests/test_ipaserver/data/pskc-figure7.xml b/ipatests/test_ipaserver/data/pskc-figure7.xml
index 1fb04fc319d7572d9d25ff34a0ce3378a939dfc6..808e272a5469a1c9eb4087ed53e0907bb80b39ad 100644
--- a/ipatests/test_ipaserver/data/pskc-figure7.xml
+++ b/ipatests/test_ipaserver/data/pskc-figure7.xml
@@ -8,14 +8,14 @@
     <xenc11:DerivedKey>
       <xenc11:KeyDerivationMethod
       Algorithm="http://www.rsasecurity.com/rsalabs/pkcs/schemas/pkcs-5v2-0#pbkdf2">
-        <xenc11:PBKDF2-params>
-          <xenc11:Salt>
-            <xenc11:Specified>Ej7/PEpyEpw=</xenc11:Specified>
-          </xenc11:Salt>
-          <xenc11:IterationCount>1000</xenc11:IterationCount>
-          <xenc11:KeyLength>16</xenc11:KeyLength>
-          <xenc11:PRF/>
-        </xenc11:PBKDF2-params>
+        <pkcs5:PBKDF2-params>
+          <Salt>
+            <Specified>Ej7/PEpyEpw=</Specified>
+          </Salt>
+          <IterationCount>1000</IterationCount>
+          <KeyLength>16</KeyLength>
+          <PRF/>
+        </pkcs5:PBKDF2-params>
       </xenc11:KeyDerivationMethod>
       <xenc:ReferenceList>
         <xenc:DataReference URI="#ED"/>
--
2.13.5
SOURCES/0221-Adds-whoami-DS-plugin-in-case-that-plugin-is-missing.patch
New file
@@ -0,0 +1,59 @@
From d06b29772609d14dccfe0d556fdb83140fcb2b3f Mon Sep 17 00:00:00 2001
From: Pavel Vomacka <pvomacka@redhat.com>
Date: Mon, 28 Aug 2017 10:51:53 +0200
Subject: [PATCH] Adds whoami DS plugin in case that plugin is missing
When first installation of IPA has been done when whoami
plugin was not enabled in DS by default and then IPA was
upgraded to newer versions, then after upgrade to IPA 4.5
WebUI stops working. This is caused by new requirement on
whoami DS plugin which is used to obtain information about
logged in entity.
This fix adds the whoami plugin during update in case that the plugin
is not enabled.
https://pagure.io/freeipa/issue/7126
Reviewed-By: Tibor Dudlak <tdudlak@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
---
 install/updates/20-whoami.update | 14 ++++++++++++++
 install/updates/Makefile.am      |  1 +
 2 files changed, 15 insertions(+)
 create mode 100644 install/updates/20-whoami.update
diff --git a/install/updates/20-whoami.update b/install/updates/20-whoami.update
new file mode 100644
index 0000000000000000000000000000000000000000..ed2c6cbd772ec1c2b664e450463bb64d61b1ceab
--- /dev/null
+++ b/install/updates/20-whoami.update
@@ -0,0 +1,14 @@
+dn: cn=whoami,cn=plugins,cn=config
+default:objectClass: top
+default:objectClass: nsSlapdPlugin
+default:objectClass: extensibleObject
+default:cn: whoami
+default:nsslapd-plugin-depends-on-type: database
+default:nsslapd-pluginDescription: whoami extended operation plugin
+default:nsslapd-pluginEnabled: on
+default:nsslapd-pluginId: whoami-plugin
+default:nsslapd-pluginInitfunc: whoami_init
+default:nsslapd-pluginPath: libwhoami-plugin
+default:nsslapd-pluginType: extendedop
+default:nsslapd-pluginVendor: 389 Project
+default:nsslapd-pluginVersion: 1.0
diff --git a/install/updates/Makefile.am b/install/updates/Makefile.am
index e18d01127b592a6c7941729d6160d10fb2d3e76c..ae3d3e0528929a30922f0395d7092654dd753a64 100644
--- a/install/updates/Makefile.am
+++ b/install/updates/Makefile.am
@@ -24,6 +24,7 @@ app_DATA =                \
     20-idoverride_index.update    \
     20-uuid.update  \
     20-default_password_policy.update \
+    20-whoami.update    \
     21-replicas_container.update    \
     21-ca_renewal_container.update    \
     21-certstore_container.update    \
--
2.13.5
SOURCES/0222-Fix-ipa-config-mod-ca-renewal-master.patch
New file
@@ -0,0 +1,88 @@
From 9a8352637aeb32ddffd83f4477695ec290da8429 Mon Sep 17 00:00:00 2001
From: Florence Blanc-Renaud <flo@redhat.com>
Date: Wed, 23 Aug 2017 16:31:18 +0200
Subject: [PATCH] Fix ipa config-mod --ca-renewal-master
commit bddb90f38a3505a2768862d2f814c5e749a7dcde added the support for
multivalued server attributes (for pkinit_server_server), but this
introduced an API change where the setter and getter of ServerAttribute
are expecting list of values.
When a SingleValuedServerAttribute is used, we need to convert one elem
into a list containing this elem and vice-versa, so that the ipa config-mod
and ipa config_show APIs are not modified.
https://pagure.io/freeipa/issue/7120
Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
Reviewed-By: Fraser Tweedale <ftweedal@redhat.com>
---
 ipaserver/plugins/serverroles.py            | 16 +++++++++++++++-
 ipatests/test_ipaserver/test_serverroles.py |  4 ++--
 2 files changed, 17 insertions(+), 3 deletions(-)
diff --git a/ipaserver/plugins/serverroles.py b/ipaserver/plugins/serverroles.py
index e81635c3315cc3fca84450f43fb7df883aae57d9..04e21090657197b9267f2ffc05048399a7ce3d38 100644
--- a/ipaserver/plugins/serverroles.py
+++ b/ipaserver/plugins/serverroles.py
@@ -46,6 +46,7 @@ from ipalib import errors, _
 from ipalib.backend import Backend
 from ipalib.plugable import Registry
 from ipaserver.servroles import (attribute_instances, ENABLED, role_instances)
+from ipaserver.servroles import SingleValuedServerAttribute
 if six.PY3:
@@ -136,13 +137,26 @@ class serverroles(Backend):
         for name, attr in assoc_attributes.items():
             attr_value = attr.get(self.api)
-            result.update({name: attr_value})
+
+            if attr_value:
+                # attr can be a SingleValuedServerAttribute
+                # in this case, the API expects a value, not a list of values
+                if isinstance(attr, SingleValuedServerAttribute):
+                    attr_value = attr_value[0]
+                result.update({name: attr_value})
         return result
     def config_update(self, **attrs_values):
         for attr, value in attrs_values.items():
             try:
+                # when the attribute is single valued, it will be stored
+                # in a SingleValuedServerAttribute. The set method expects
+                # a list containing a single value.
+                # We need to convert value to a list containing value
+                if isinstance(self.attributes[attr],
+                              SingleValuedServerAttribute):
+                    value = [value]
                 self.attributes[attr].set(self.api, value)
             except KeyError:
                 raise errors.NotFound(
diff --git a/ipatests/test_ipaserver/test_serverroles.py b/ipatests/test_ipaserver/test_serverroles.py
index 985c750b64f109e0a83686f31ddb3b8d4171072d..e8967517d0c65fb6e3daebf220cae7df38bfe044 100644
--- a/ipatests/test_ipaserver/test_serverroles.py
+++ b/ipatests/test_ipaserver/test_serverroles.py
@@ -715,7 +715,7 @@ class TestServerAttributes(object):
         non_ca_fqdn = mock_masters.get_fqdn('trust-controller-dns')
         with pytest.raises(errors.ValidationError):
-            self.config_update(mock_api, **{attr_name: [non_ca_fqdn]})
+            self.config_update(mock_api, **{attr_name: non_ca_fqdn})
     def test_set_unknown_attribute_on_master_raises_notfound(
             self, mock_api, mock_masters):
@@ -732,7 +732,7 @@ class TestServerAttributes(object):
         original_renewal_master = self.config_retrieve(
             role_name, mock_api)[attr_name]
-        other_ca_server = [mock_masters.get_fqdn('trust-controller-ca')]
+        other_ca_server = mock_masters.get_fqdn('trust-controller-ca')
         for host in (other_ca_server, original_renewal_master):
             self.config_update(mock_api, **{attr_name: host})
--
2.13.5
SOURCES/0223-Backport-PR-988-to-ipa-4-5-Fix-Certificate-renewal-w.patch
New file
@@ -0,0 +1,60 @@
From 21b0fdb48179e6060eff0ecb11ce6522983ccc00 Mon Sep 17 00:00:00 2001
From: Florence Blanc-Renaud <flo@redhat.com>
Date: Fri, 18 Aug 2017 18:02:57 +0200
Subject: [PATCH] Backport PR 988 to ipa-4-5 Fix Certificate renewal (with ext
 ca)
Fix certificate renewal scripts that use IPACertificate object:
- renew_ca_cert adds the C flag to the trust flags and needs to
be adapted to IPACertificate object
- ipa-cacert-manage: fix python3 encoding issue
https://pagure.io/freeipa/issue/7106
Reviewed-By: Fraser Tweedale <ftweedal@redhat.com>
Reviewed-By: Stanislav Laznicka <slaznick@redhat.com>
---
 install/restart_scripts/renew_ca_cert  | 7 ++++++-
 ipaserver/install/ipa_cacert_manage.py | 2 +-
 2 files changed, 7 insertions(+), 2 deletions(-)
diff --git a/install/restart_scripts/renew_ca_cert b/install/restart_scripts/renew_ca_cert
index bb31defc0e2bdca044e68ae067f42fb3bd41a57f..3bbf003bad47a189fd26df19e6ab137fcbb67ed0 100644
--- a/install/restart_scripts/renew_ca_cert
+++ b/install/restart_scripts/renew_ca_cert
@@ -35,6 +35,7 @@ from ipaserver.install import certs, cainstance, installutils
 from ipaserver.plugins.ldap2 import ldap2
 from ipaplatform import services
 from ipaplatform.paths import paths
+from ipapython.certdb import TrustFlags
 def _main():
@@ -180,7 +181,11 @@ def _main():
                 # Pass Dogtag's self-tests
                 for ca_nick in db.find_root_cert(nickname)[-2:-1]:
                     ca_flags = dict(cc[1:] for cc in ca_certs)[ca_nick]
-                    db.trust_root_cert(ca_nick, 'C' + ca_flags)
+                    usages = ca_flags.usages or set()
+                    ca_flags_modified = TrustFlags(ca_flags.has_key,
+                        True, True,
+                        usages | {x509.EKU_SERVER_AUTH})
+                    db.trust_root_cert(ca_nick, ca_flags_modified)
             finally:
                 if conn is not None and conn.isconnected():
                     conn.disconnect()
diff --git a/ipaserver/install/ipa_cacert_manage.py b/ipaserver/install/ipa_cacert_manage.py
index e88e8b63ae94759ac835f3b3b31b0735d68a67b0..fcbf09155a3abc9ce9481aa2519ed39aaa6aa9bb 100644
--- a/ipaserver/install/ipa_cacert_manage.py
+++ b/ipaserver/install/ipa_cacert_manage.py
@@ -218,7 +218,7 @@ class CACertManage(admintool.AdminTool):
         cert_file, ca_file = installutils.load_external_cert(
             options.external_cert_files, DN(old_cert_obj.subject))
-        with open(cert_file.name) as f:
+        with open(cert_file.name, 'rb') as f:
             new_cert_data = f.read()
         new_cert_der = x509.normalize_certificate(new_cert_data)
         new_cert_obj = x509.load_certificate(new_cert_der, x509.DER)
--
2.13.5
SOURCES/0224-Backport-PR-1008-to-ipa-4-5-Fix-ipa-server-upgrade-T.patch
New file
@@ -0,0 +1,213 @@
From c9fb09190ac243bcf45622693944d7e6785141b4 Mon Sep 17 00:00:00 2001
From: Florence Blanc-Renaud <flo@redhat.com>
Date: Mon, 28 Aug 2017 10:50:58 +0200
Subject: [PATCH] Backport PR 1008 to ipa-4-5 Fix ipa-server-upgrade: This
 entry already exists
ipa-server-upgrade fails when running the ipaload_cacrt plugin. The plugin
finds all CA certificates in /etc/httpd/alias and uploads them in LDAP
below cn=certificates,cn=ipa,cn=etc,$BASEDN.
The issue happens because there is already an entry in LDAP for IPA CA, but
with a different DN. The nickname in /etc/httpd/alias can differ from
$DOMAIN IPA CA.
To avoid the issue:
1/ during upgrade, run a new plugin that removes duplicates and restarts ldap
(to make sure that uniqueness attr plugin is working after the new plugin)
2/ modify upload_cacert plugin so that it is using $DOMAIN IPA CA instead of
cn=$nickname,cn=ipa,cn=etc,$BASEDN when uploading IPA CA.
https://pagure.io/freeipa/issue/7125
Reviewed-By: Fraser Tweedale <ftweedal@redhat.com>
---
 install/updates/90-post_upgrade_plugins.update     |  1 +
 ipalib/install/certstore.py                        | 19 +++++
 .../plugins/update_fix_duplicate_cacrt_in_ldap.py  | 84 ++++++++++++++++++++++
 ipaserver/install/plugins/upload_cacrt.py          | 19 ++++-
 4 files changed, 120 insertions(+), 3 deletions(-)
 create mode 100644 ipaserver/install/plugins/update_fix_duplicate_cacrt_in_ldap.py
diff --git a/install/updates/90-post_upgrade_plugins.update b/install/updates/90-post_upgrade_plugins.update
index 8477199e07d6729d5847e58bfa67d061bd1410c2..bbc3e29422fc0f139c2ca68a7033863e4c25f8cf 100644
--- a/install/updates/90-post_upgrade_plugins.update
+++ b/install/updates/90-post_upgrade_plugins.update
@@ -15,6 +15,7 @@ plugin: update_ca_renewal_master
 plugin: update_idrange_type
 plugin: update_pacs
 plugin: update_service_principalalias
+plugin: update_fix_duplicate_cacrt_in_ldap
 plugin: update_upload_cacrt
 # update_ra_cert_store has to be executed after update_ca_renewal_master
 plugin: update_ra_cert_store
diff --git a/ipalib/install/certstore.py b/ipalib/install/certstore.py
index bc2079fb12873444cbe6796eebfdfcfebd0e284d..76181fe47de585974f3fb33ec586f5c576adebb5 100644
--- a/ipalib/install/certstore.py
+++ b/ipalib/install/certstore.py
@@ -27,6 +27,7 @@ from pyasn1.error import PyAsn1Error
 from ipapython.dn import DN
 from ipapython.certdb import get_ca_nickname, TrustFlags
 from ipalib import errors, x509
+from ipalib.constants import IPA_CA_CN
 def _parse_cert(dercert):
     try:
@@ -381,3 +382,21 @@ def get_ca_certs_nss(ldap, base_dn, compat_realm, compat_ipa_ca,
         nss_certs.append((cert, nickname, trust_flags))
     return nss_certs
+
+
+def get_ca_subject(ldap, container_ca, base_dn):
+    """
+    Look for the IPA CA certificate subject.
+    """
+    dn = DN(('cn', IPA_CA_CN), container_ca, base_dn)
+    try:
+        cacert_subject = ldap.get_entry(dn)['ipacasubjectdn'][0]
+    except errors.NotFound:
+        # if the entry doesn't exist, we are dealing with a pre-v4.4
+        # installation, where the default CA subject was always based
+        # on the subject_base.
+        attrs = ldap.get_ipa_config()
+        subject_base = attrs.get('ipacertificatesubjectbase')[0]
+        cacert_subject = DN(('CN', 'Certificate Authority'), subject_base)
+
+    return cacert_subject
diff --git a/ipaserver/install/plugins/update_fix_duplicate_cacrt_in_ldap.py b/ipaserver/install/plugins/update_fix_duplicate_cacrt_in_ldap.py
new file mode 100644
index 0000000000000000000000000000000000000000..cd4f13a8eb6b5bc9e04fcdd407907497528f8be1
--- /dev/null
+++ b/ipaserver/install/plugins/update_fix_duplicate_cacrt_in_ldap.py
@@ -0,0 +1,84 @@
+# Authors:
+#   Florence Blanc-Renaud <flo@redhat.com>
+#
+# Copyright (C) 2017  Red Hat
+# see file 'COPYING' for use and warranty information
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+import logging
+
+from ipalib import Registry, errors
+from ipalib import Updater
+from ipalib.install import certstore
+from ipapython.dn import DN
+from ipapython.certdb import get_ca_nickname
+
+logger = logging.getLogger(__name__)
+
+register = Registry()
+
+
+@register()
+class update_fix_duplicate_cacrt_in_ldap(Updater):
+    """
+    When multiple entries exist for IPA CA cert in ldap, remove the duplicate
+
+    After this plugin, ds needs to be restarted. This ensures that
+    the attribute uniqueness plugin is working and prevents
+    other plugins from adding duplicates.
+    """
+
+    def execute(self, **options):
+        # If CA is disabled, no need to check for duplicates of IPA CA
+        ca_enabled = self.api.Command.ca_is_enabled()['result']
+        if not ca_enabled:
+            return True, []
+
+        # Look for the IPA CA cert subject
+        ldap = self.api.Backend.ldap2
+        cacert_subject = certstore.get_ca_subject(
+            ldap,
+            self.api.env.container_ca,
+            self.api.env.basedn)
+
+        # Find if there are other certificates with the same subject
+        # They are duplicates resulting of BZ 1480102
+        base_dn = DN(('cn', 'certificates'), ('cn', 'ipa'), ('cn', 'etc'),
+                     self.api.env.basedn)
+        try:
+            filter = ldap.make_filter({'ipaCertSubject': cacert_subject})
+            result, _truncated = ldap.find_entries(
+                base_dn=base_dn,
+                filter=filter,
+                attrs_list=[])
+        except errors.NotFound:
+            # No duplicate, we're good
+            logger.debug("No duplicates for IPA CA in LDAP")
+            return True, []
+
+        logger.debug("Found %d entrie(s) for IPA CA in LDAP", len(result))
+        cacert_dn = DN(('cn', get_ca_nickname(self.api.env.realm)), base_dn)
+        for entry in result:
+            if entry.dn == cacert_dn:
+                continue
+            # Remove the duplicate
+            try:
+                ldap.delete_entry(entry)
+                logger.debug("Removed the duplicate %s", entry.dn)
+            except Exception as e:
+                logger.warning("Failed to remove the duplicate %s: %s",
+                               entry.dn, e)
+
+        return True, []
diff --git a/ipaserver/install/plugins/upload_cacrt.py b/ipaserver/install/plugins/upload_cacrt.py
index a1957ca5b675b86f0df36dc820ee31305f54f863..985b74c06e80a3620eb6454c0bd9c7590b04184d 100644
--- a/ipaserver/install/plugins/upload_cacrt.py
+++ b/ipaserver/install/plugins/upload_cacrt.py
@@ -20,7 +20,7 @@
 from ipalib.install import certstore
 from ipaplatform.paths import paths
 from ipaserver.install import certs
-from ipalib import Registry, errors
+from ipalib import Registry, errors, x509
 from ipalib import Updater
 from ipapython import certdb
 from ipapython.dn import DN
@@ -41,6 +41,10 @@ class update_upload_cacrt(Updater):
         ca_enabled = self.api.Command.ca_is_enabled()['result']
         if ca_enabled:
             ca_nickname = certdb.get_ca_nickname(self.api.env.realm)
+            ca_subject = certstore.get_ca_subject(
+                self.api.Backend.ldap2,
+                self.api.env.container_ca,
+                self.api.env.basedn)
         else:
             ca_nickname = None
             server_certs = db.find_server_certs()
@@ -54,9 +58,18 @@ class update_upload_cacrt(Updater):
         for nickname, trust_flags in db.list_certs():
             if trust_flags.has_key:
                 continue
-            if nickname == ca_nickname and ca_enabled:
-                trust_flags = certdb.IPA_CA_TRUST_FLAGS
             cert = db.get_cert_from_db(nickname, pem=False)
+            subject = DN(
+                x509.load_certificate(cert, datatype=x509.DER).subject)
+            if ca_enabled and subject == ca_subject:
+                # When ca is enabled, we can have the IPA CA cert stored
+                # in the nss db with a different nickname (for instance
+                # when the server was installed with --subject to
+                # customize the CA cert subject), but it must always be
+                # stored in LDAP with the DN cn=$DOMAIN IPA CA
+                # This is why we check the subject instead of the nickname here
+                nickname = ca_nickname
+                trust_flags = certdb.IPA_CA_TRUST_FLAGS
             trust, _ca, eku = certstore.trust_flags_to_key_policy(trust_flags)
             dn = DN(('cn', nickname), ('cn', 'certificates'), ('cn', 'ipa'),
--
2.13.5
SOURCES/0225-Fixing-how-sssd.conf-is-updated-when-promoting-a-cli.patch
New file
@@ -0,0 +1,92 @@
From c8fcaa5dc792e7b87c8f21c7c322ddfabe219980 Mon Sep 17 00:00:00 2001
From: Felipe Volpone <fbarreto@redhat.com>
Date: Wed, 13 Sep 2017 09:26:41 -0300
Subject: [PATCH] Fixing how sssd.conf is updated when promoting a client to
 replica
When promoting a client to a replica we have to change sssd.conf,
deleting _srv_ part from 'ipa_server' property and setting
'ipa_server_mode' to true.
Previously, the wrong domain could be updated since the ipa_domain
variable was not being used properly.
https://pagure.io/freeipa/issue/7127
Reviewed-By: Stanislav Laznicka <slaznick@redhat.com>
Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
---
 ipaserver/install/server/replicainstall.py | 27 ++++++++++++---------------
 ipaserver/install/server/upgrade.py        |  4 ++++
 2 files changed, 16 insertions(+), 15 deletions(-)
diff --git a/ipaserver/install/server/replicainstall.py b/ipaserver/install/server/replicainstall.py
index 814925de152809808f726c60ae7f35a24bc32a4a..326daf708f091d9d2c56ad399e46aef659dbba2e 100644
--- a/ipaserver/install/server/replicainstall.py
+++ b/ipaserver/install/server/replicainstall.py
@@ -432,30 +432,27 @@ def promote_sssd(host_name):
     sssdconfig.import_config()
     domains = sssdconfig.list_active_domains()
-    ipa_domain = None
-
     for name in domains:
         domain = sssdconfig.get_domain(name)
         try:
             hostname = domain.get_option('ipa_hostname')
             if hostname == host_name:
-                ipa_domain = domain
+                break
         except SSSDConfig.NoOptionError:
             continue
-
-    if ipa_domain is None:
-        raise RuntimeError("Couldn't find IPA domain in sssd.conf")
     else:
-        domain.set_option('ipa_server', host_name)
-        domain.set_option('ipa_server_mode', True)
-        sssdconfig.save_domain(domain)
-        sssdconfig.write()
+        raise RuntimeError("Couldn't find IPA domain in sssd.conf")
-        sssd = services.service('sssd', api)
-        try:
-            sssd.restart()
-        except CalledProcessError:
-            root_logger.warning("SSSD service restart was unsuccessful.")
+    domain.set_option('ipa_server', host_name)
+    domain.set_option('ipa_server_mode', True)
+    sssdconfig.save_domain(domain)
+    sssdconfig.write()
+
+    sssd = services.service('sssd', api)
+    try:
+        sssd.restart()
+    except CalledProcessError:
+        root_logger.warning("SSSD service restart was unsuccessful.")
 def promote_openldap_conf(hostname, master):
diff --git a/ipaserver/install/server/upgrade.py b/ipaserver/install/server/upgrade.py
index 732776f2cf513a4bb11d8f3f0dfaac78217e460f..109e922e3a3ea25f882fdd81765788a3881e87bd 100644
--- a/ipaserver/install/server/upgrade.py
+++ b/ipaserver/install/server/upgrade.py
@@ -1816,11 +1816,15 @@ def upgrade_configuration():
         cainstance.ensure_ipa_authority_entry()
     set_sssd_domain_option('ipa_server_mode', 'True')
+    set_sssd_domain_option('ipa_server', api.env.host)
     sssdconfig = SSSDConfig.SSSDConfig()
     sssdconfig.import_config()
     sssd_enable_service(sssdconfig, 'ifp')
+    sssd = services.service('sssd', api)
+    sssd.restart()
+
     krb = krbinstance.KrbInstance(fstore)
     krb.fqdn = fqdn
     krb.realm = api.env.realm
--
2.13.5
SOURCES/0226-Backport-4-5-Fix-ipa-server-upgrade-with-server-cert.patch
New file
@@ -0,0 +1,199 @@
From 8c576e8c3640b84869abacc43a74aa250df5a8e9 Mon Sep 17 00:00:00 2001
From: Florence Blanc-Renaud <flo@redhat.com>
Date: Tue, 5 Sep 2017 16:17:31 +0200
Subject: [PATCH] Backport 4-5: Fix ipa-server-upgrade with server cert
 tracking
ipa-server-upgrade fails with Server-Cert not found, when trying to
track httpd/ldap server certificates. There are 2 issues in the upgrade:
- the certificates should be tracked only if they were issued by IPA CA
(it is possible to have CA configured but 3rd part certs)
- the certificate nickname can be different from Server-Cert
The fix provides methods to find the server crt nickname for http and ldap,
and a method to check if the server certs are issued by IPA and need to be
tracked by certmonger.
https://pagure.io/freeipa/issue/7141
Reviewed-By: Stanislav Laznicka <slaznick@redhat.com>
Reviewed-By: Fraser Tweedale <ftweedal@redhat.com>
---
 ipaserver/install/certs.py          | 27 ++++++++++++++++++++++
 ipaserver/install/dsinstance.py     | 45 +++++++++++++++++++++++++++++++++----
 ipaserver/install/httpinstance.py   | 16 ++++++++++---
 ipaserver/install/server/upgrade.py |  4 ++--
 4 files changed, 83 insertions(+), 9 deletions(-)
diff --git a/ipaserver/install/certs.py b/ipaserver/install/certs.py
index 02c479d92511fcf4043e7d6798c85cf8256c3299..de96318db51b03f2515814d574cfebf1b242b6a6 100644
--- a/ipaserver/install/certs.py
+++ b/ipaserver/install/certs.py
@@ -42,6 +42,7 @@ from ipapython.certdb import get_ca_nickname, find_cert_from_txt, NSSDatabase
 from ipapython.dn import DN
 from ipalib import pkcs10, x509, api
 from ipalib.errors import CertificateOperationError
+from ipalib.install import certstore
 from ipalib.text import _
 from ipaplatform.paths import paths
@@ -669,6 +670,32 @@ class CertDB(object):
                                              subject=host,
                                              passwd_fname=self.passwd_fname)
+    def is_ipa_issued_cert(self, api, nickname):
+        """
+        Return True if the certificate contained in the CertDB with the
+        provided nickname has been issued by IPA.
+
+        Note that this method can only be executed if api has been initialized
+        """
+        # This method needs to compare the cert issuer (from the NSS DB
+        # and the subject from the CA (from LDAP), because nicknames are not
+        # always aligned.
+
+        cacert_subject = certstore.get_ca_subject(
+            api.Backend.ldap2,
+            api.env.container_ca,
+            api.env.basedn)
+
+        # The cert can be issued directly by IPA. In this case, the cert
+        # issuer is IPA CA subject.
+        cert = self.get_cert_from_db(nickname)
+        if cert is None:
+            raise RuntimeError("Could not find the cert %s in %s"
+                               % (nickname, self.secdir))
+        issuer = DN(x509.load_certificate(cert).issuer)
+
+        return issuer == cacert_subject
+
 class _CrossProcessLock(object):
     _DATETIME_FORMAT = '%Y%m%d%H%M%S%f'
diff --git a/ipaserver/install/dsinstance.py b/ipaserver/install/dsinstance.py
index 39248edb285ee4d792b4500d83d88b24f5732d10..c9db8ac28c3ca10539b745ca09f4d8aaece02e0c 100644
--- a/ipaserver/install/dsinstance.py
+++ b/ipaserver/install/dsinstance.py
@@ -1028,22 +1028,59 @@ class DsInstance(service.Service):
                 root_logger.error(
                     'Unable to restart DS instance %s: %s', ds_instance, e)
+    def get_server_cert_nickname(self, serverid=None):
+        """
+        Retrieve the nickname of the server cert used by dirsrv.
+
+        The method directly reads the dse.ldif to find the attribute
+        nsSSLPersonalitySSL of cn=RSA,cn=encryption,cn=config because
+        LDAP is not always accessible when we need to get the nickname
+        (for instance during uninstall).
+        """
+        if serverid is None:
+            serverid = self.get_state("serverid")
+        if serverid is not None:
+            dirname = config_dirname(serverid)
+            config_file = os.path.join(dirname, "dse.ldif")
+            rsa_dn = "cn=RSA,cn=encryption,cn=config"
+            with open(config_file, "r") as in_file:
+                parser = upgradeinstance.GetEntryFromLDIF(
+                    in_file,
+                    entries_dn=[rsa_dn])
+                parser.parse()
+                try:
+                    config_entry = parser.get_results()[rsa_dn]
+                    nickname = config_entry["nsSSLPersonalitySSL"][0]
+                    return nickname.decode('utf-8')
+                except (KeyError, IndexError):
+                    root_logger.error("Unable to find server cert nickname in "
+                                      "%s", config_file)
+
+        root_logger.debug("Falling back to nickname Server-Cert")
+        return 'Server-Cert'
+
     def stop_tracking_certificates(self, serverid=None):
         if serverid is None:
             serverid = self.get_state("serverid")
         if not serverid is None:
+            nickname = self.get_server_cert_nickname(serverid)
             # drop the trailing / off the config_dirname so the directory
             # will match what is in certmonger
             dirname = config_dirname(serverid)[:-1]
             dsdb = certs.CertDB(self.realm, nssdir=dirname)
-            dsdb.untrack_server_cert(self.nickname)
+            dsdb.untrack_server_cert(nickname)
     def start_tracking_certificates(self, serverid):
+        nickname = self.get_server_cert_nickname(serverid)
         dirname = config_dirname(serverid)[:-1]
         dsdb = certs.CertDB(self.realm, nssdir=dirname)
-        dsdb.track_server_cert(self.nickname, self.principal,
-                               dsdb.passwd_fname,
-                               'restart_dirsrv %s' % serverid)
+        if dsdb.is_ipa_issued_cert(api, nickname):
+            dsdb.track_server_cert(nickname, self.principal,
+                                   dsdb.passwd_fname,
+                                   'restart_dirsrv %s' % serverid)
+        else:
+            root_logger.debug("Will not track DS server certificate %s as it "
+                              "is not issued by IPA", nickname)
     # we could probably move this function into the service.Service
     # class - it's very generic - all we need is a way to get an
diff --git a/ipaserver/install/httpinstance.py b/ipaserver/install/httpinstance.py
index f637b97db8f21ddbc00c4f70e18e836d300b2f33..e55edebc5d4e45d7cb4cb66d28a270e6d6a56e33 100644
--- a/ipaserver/install/httpinstance.py
+++ b/ipaserver/install/httpinstance.py
@@ -266,6 +266,11 @@ class HTTPInstance(service.Service):
         installutils.set_directive(
             paths.HTTPD_NSS_CONF, 'NSSNickname', quoted_nickname, quotes=False)
+    def get_mod_nss_nickname(self):
+        cert = installutils.get_directive(paths.HTTPD_NSS_CONF, 'NSSNickname')
+        nickname = installutils.unquote_directive_value(cert, quote_char="'")
+        return nickname
+
     def set_mod_nss_protocol(self):
         installutils.set_directive(paths.HTTPD_NSS_CONF, 'NSSProtocol', 'TLSv1.0,TLSv1.1,TLSv1.2', False)
@@ -582,12 +587,17 @@ class HTTPInstance(service.Service):
     def stop_tracking_certificates(self):
         db = certs.CertDB(api.env.realm, nssdir=paths.HTTPD_ALIAS_DIR)
-        db.untrack_server_cert(self.cert_nickname)
+        db.untrack_server_cert(self.get_mod_nss_nickname())
     def start_tracking_certificates(self):
         db = certs.CertDB(self.realm, nssdir=paths.HTTPD_ALIAS_DIR)
-        db.track_server_cert(self.cert_nickname, self.principal,
-                             db.passwd_fname, 'restart_httpd')
+        nickname = self.get_mod_nss_nickname()
+        if db.is_ipa_issued_cert(api, nickname):
+            db.track_server_cert(nickname, self.principal,
+                                 db.passwd_fname, 'restart_httpd')
+        else:
+            root_logger.debug("Will not track HTTP server cert %s as it is "
+                              "not issued by IPA", nickname)
     def request_service_keytab(self):
         super(HTTPInstance, self).request_service_keytab()
diff --git a/ipaserver/install/server/upgrade.py b/ipaserver/install/server/upgrade.py
index 109e922e3a3ea25f882fdd81765788a3881e87bd..0947766c076251e7608241803d3a1eabee65ae11 100644
--- a/ipaserver/install/server/upgrade.py
+++ b/ipaserver/install/server/upgrade.py
@@ -957,13 +957,13 @@ def certificate_renewal_update(ca, ds, http):
         },
         {
             'cert-database': paths.HTTPD_ALIAS_DIR,
-            'cert-nickname': 'Server-Cert',
+            'cert-nickname': http.get_mod_nss_nickname(),
             'ca': 'IPA',
             'cert-postsave-command': template % 'restart_httpd',
         },
         {
             'cert-database': dsinstance.config_dirname(serverid),
-            'cert-nickname': 'Server-Cert',
+            'cert-nickname': ds.get_server_cert_nickname(serverid),
             'ca': 'IPA',
             'cert-postsave-command':
                 '%s %s' % (template % 'restart_dirsrv', serverid),
--
2.13.5
SOURCES/0227-Always-check-peer-has-keys-before-connecting.patch
New file
@@ -0,0 +1,73 @@
From 82e860ae81b9e34fc6a326be4183f37a21ac1564 Mon Sep 17 00:00:00 2001
From: Simo Sorce <simo@redhat.com>
Date: Fri, 23 Jun 2017 04:48:41 -0400
Subject: [PATCH] Always check peer has keys before connecting
When pulling the DM password we may have the same issues reported in
ticket #6838 for CA keys.
This commit makes sure we always check the peer has keys before any
client operation.
Ticket #6838
Signed-off-by: Simo Sorce <simo@redhat.com>
Reviewed-By: Stanislav Laznicka <slaznick@redhat.com>
Reviewed-By: Michal Reznik <mreznik@redhat.com>
---
 ipaserver/install/custodiainstance.py | 20 ++++++++------------
 1 file changed, 8 insertions(+), 12 deletions(-)
diff --git a/ipaserver/install/custodiainstance.py b/ipaserver/install/custodiainstance.py
index 390576bc0c0edfb7d8f8895eca9df30079526aa8..bc3cea7063dff183c85b4f6e8ced7567f691001d 100644
--- a/ipaserver/install/custodiainstance.py
+++ b/ipaserver/install/custodiainstance.py
@@ -13,7 +13,6 @@ from ipaserver.install import ldapupdate
 from ipaserver.install import sysupgrade
 from base64 import b64decode
 from jwcrypto.common import json_decode
-import functools
 import shutil
 import os
 import stat
@@ -31,13 +30,6 @@ class CustodiaInstance(SimpleServiceInstance):
         self.ldap_uri = None
         self.fqdn = host_name
         self.realm = realm
-        self.__CustodiaClient = functools.partial(
-            CustodiaClient,
-            client_service='host@%s' % self.fqdn,
-            keyfile=self.server_keys,
-            keytab=paths.KRB5_KEYTAB,
-            realm=realm,
-        )
     def __config_file(self):
         template_file = os.path.basename(self.config_file) + '.template'
@@ -144,6 +136,14 @@ class CustodiaInstance(SimpleServiceInstance):
                     raise RuntimeError("Timed out trying to obtain keys.")
                 time.sleep(1)
+    def __CustodiaClient(self, server):
+        # Before we attempt to fetch keys from this host, make sure our public
+        # keys have been replicated there.
+        self.__wait_keys(server)
+
+        return CustodiaClient('host@%s' % self.fqdn, self.server_keys,
+                              paths.KRB5_KEYTAB, server, realm=self.realm)
+
     def __get_keys(self, ca_host, cacerts_file, cacerts_pwd, data):
         # Fecth all needed certs one by one, then combine them in a single
         # p12 file
@@ -151,10 +151,6 @@ class CustodiaInstance(SimpleServiceInstance):
         prefix = data['prefix']
         certlist = data['list']
-        # Before we attempt to fetch keys from this host, make sure our public
-        # keys have been replicated there.
-        self.__wait_keys(ca_host)
-
         cli = self.__CustodiaClient(server=ca_host)
         # Temporary nssdb
--
2.13.5
SOURCES/0228-Make-sure-upgrade-also-checks-for-IPv6-stack.patch
New file
@@ -0,0 +1,61 @@
From 010f6405288b1ca519d684d85ca25ce86de60b66 Mon Sep 17 00:00:00 2001
From: Alexander Bokovoy <abokovoy@redhat.com>
Date: Tue, 19 Sep 2017 12:06:39 +0300
Subject: [PATCH] Make sure upgrade also checks for IPv6 stack
 - Add check for IPv6 stack to upgrade process
 - Change IPv6 checker to also check that localhost resolves to ::1
Part of fixes https://pagure.io/freeipa/issue/7083
Reviewed-By: Tomas Krizek <tkrizek@redhat.com>
---
 ipaplatform/redhat/tasks.py         | 19 ++++++++++++++++---
 ipaserver/install/server/upgrade.py |  1 +
 2 files changed, 17 insertions(+), 3 deletions(-)
diff --git a/ipaplatform/redhat/tasks.py b/ipaplatform/redhat/tasks.py
index 07efebab97eabcf2dc39bd345920a1c7be56e9f5..94d1863c5cc20ec6c2399f339ce19498976553bc 100644
--- a/ipaplatform/redhat/tasks.py
+++ b/ipaplatform/redhat/tasks.py
@@ -153,9 +153,22 @@ class RedHatTaskNamespace(BaseTaskNamespace):
         """
         if not os.path.exists(paths.IF_INET6):
             raise RuntimeError(
-                "IPv6 kernel module has to be enabled. If you do not wish to "
-                "use IPv6, please disable it on the interfaces in "
-                "sysctl.conf and enable the IPv6 kernel module.")
+                "IPv6 stack has to be enabled in the kernel and some "
+                "interface has to have ::1 address assigned. Typically "
+                "this is 'lo' interface. If you do not wish to use IPv6 "
+                "globally, disable it on the specific interfaces in "
+                "sysctl.conf except 'lo' interface.")
+
+        try:
+            localhost6 = ipautil.CheckedIPAddress('::1', allow_loopback=True)
+            if localhost6.get_matching_interface() is None:
+                raise ValueError("no interface for ::1 address found")
+        except ValueError:
+            raise RuntimeError(
+                 "IPv6 stack is enabled in the kernel but there is no "
+                 "interface that has ::1 address assigned. Add ::1 address "
+                 "resolution to 'lo' interface. You might need to enable IPv6 "
+                 "on the interface 'lo' in sysctl.conf.")
     def restore_pre_ipa_client_configuration(self, fstore, statestore,
                                              was_sssd_installed,
diff --git a/ipaserver/install/server/upgrade.py b/ipaserver/install/server/upgrade.py
index 0947766c076251e7608241803d3a1eabee65ae11..1c4b2357d5d016b8a7501f46380d5e0a61dc21a0 100644
--- a/ipaserver/install/server/upgrade.py
+++ b/ipaserver/install/server/upgrade.py
@@ -1860,6 +1860,7 @@ def upgrade_configuration():
 def upgrade_check(options):
     try:
         installutils.check_server_configuration()
+        tasks.check_ipv6_stack_enabled()
     except RuntimeError as e:
         root_logger.error(e)
         sys.exit(1)
--
2.13.5
SOURCES/0229-control-logging-of-host_port_open-from-caller.patch
New file
@@ -0,0 +1,103 @@
From fbaa55fbe8447745a20c99a68d62790f5dd5a0f7 Mon Sep 17 00:00:00 2001
From: Petr Vobornik <pvoborni@redhat.com>
Date: Thu, 3 Aug 2017 15:48:33 +0200
Subject: [PATCH] control logging of host_port_open from caller
host_port_open copied logging behavior of ipa-replica-conncheck utility
which doesn't make it much reusable.
Now log level can be controlled from caller so other callers might use
other logging level without host_port_open guessing what was the
intention.
https://pagure.io/freeipa/issue/7083
Reviewed-By: Tomas Krizek <tkrizek@redhat.com>
---
 install/tools/ipa-replica-conncheck |  9 ++++++++-
 ipapython/ipautil.py                | 17 ++++++-----------
 2 files changed, 14 insertions(+), 12 deletions(-)
diff --git a/install/tools/ipa-replica-conncheck b/install/tools/ipa-replica-conncheck
index 528242268f9992e903781b76a379039d533853c0..f10b7e3d2f94540dba3956bf460c4b9f38da90da 100755
--- a/install/tools/ipa-replica-conncheck
+++ b/install/tools/ipa-replica-conncheck
@@ -46,6 +46,8 @@ import distutils.spawn
 from ipaplatform.paths import paths
 import gssapi
 from cryptography.hazmat.primitives import serialization
+import logging
+
 CONNECT_TIMEOUT = 5
 RESPONDER = None
@@ -379,11 +381,16 @@ class PortResponder(threading.Thread):
 def port_check(host, port_list):
     ports_failed = []
     ports_udp_warning = []  # conncheck could not verify that port is open
+    log_level = {
+        SOCK_DGRAM: logging.WARNING,
+        SOCK_STREAM: logging.ERROR
+    }
     for port in port_list:
         try:
             port_open = ipautil.host_port_open(
                 host, port.port, port.port_type,
-                socket_timeout=CONNECT_TIMEOUT, log_errors=True)
+                socket_timeout=CONNECT_TIMEOUT, log_errors=True,
+                log_level=log_level[port.port_type])
         except socket.gaierror:
             raise RuntimeError("Port check failed! Unable to resolve host name '%s'" % host)
         if port_open:
diff --git a/ipapython/ipautil.py b/ipapython/ipautil.py
index 5a6bf5a27d5a6e25c51fbaa6e2b1167652e2735d..e1e6e32b15559486caecb070627db82e14a57bdf 100644
--- a/ipapython/ipautil.py
+++ b/ipapython/ipautil.py
@@ -42,6 +42,7 @@ from contextlib import contextmanager
 import locale
 import collections
 from subprocess import CalledProcessError
+import logging
 from dns import resolver, reversename
 from dns.exception import DNSException
@@ -948,7 +949,8 @@ def user_input(prompt, default = None, allow_empty = True):
 def host_port_open(host, port, socket_type=socket.SOCK_STREAM,
-                   socket_timeout=None, log_errors=False):
+                   socket_timeout=None, log_errors=False,
+                   log_level=logging.DEBUG):
     """
     host: either hostname or IP address;
           if hostname is provided, port MUST be open on ALL resolved IPs
@@ -970,23 +972,16 @@ def host_port_open(host, port, socket_type=socket.SOCK_STREAM,
             s.connect(sa)
             if socket_type == socket.SOCK_DGRAM:
-                s.send('')
+                s.send(b'')
                 s.recv(512)
         except socket.error:
             port_open = False
-
             if log_errors:
-                msg = ('Failed to connect to port %(port)d %(proto)s on '
+                msg = ('Failed to connect to port %(port)s %(proto)s on '
                        '%(addr)s' % dict(port=port,
                                          proto=PROTOCOL_NAMES[socket_type],
                                          addr=sa[0]))
-
-                # Do not log udp failures as errors (to be consistent with
-                # the rest of the code that checks for open ports)
-                if socket_type == socket.SOCK_DGRAM:
-                    root_logger.warning(msg)
-                else:
-                    root_logger.error(msg)
+                root_logger.log(log_level, msg)
         finally:
             if s is not None:
                 s.close()
--
2.13.5
SOURCES/0230-log-progress-of-wait_for_open_ports.patch
New file
@@ -0,0 +1,44 @@
From 647e23eb307e09597f355fb10abfd4c74a4b6f84 Mon Sep 17 00:00:00 2001
From: Petr Vobornik <pvoborni@redhat.com>
Date: Thu, 3 Aug 2017 16:03:29 +0200
Subject: [PATCH] log progress of wait_for_open_ports
To know what to focus on when some check fail. E.g. to detect that
IPv6 address or its resolution for localhost is misconfigured.
https://pagure.io/freeipa/issue/7083
Reviewed-By: Tomas Krizek <tkrizek@redhat.com>
---
 ipapython/ipautil.py | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/ipapython/ipautil.py b/ipapython/ipautil.py
index e1e6e32b15559486caecb070627db82e14a57bdf..59ea84da4ac667a39bdaa9a6fd7d87ab1b6e658d 100644
--- a/ipapython/ipautil.py
+++ b/ipapython/ipautil.py
@@ -1213,15 +1213,20 @@ def wait_for_open_ports(host, ports, timeout=0):
     op_timeout = time.time() + timeout
     for port in ports:
+        root_logger.debug('waiting for port: %s', port)
+        log_error = True
         while True:
-            port_open = host_port_open(host, port)
+            port_open = host_port_open(host, port, log_errors=log_error)
+            log_error = False  # Log only first err so that the log is readable
             if port_open:
+                root_logger.debug('SUCCESS: port: %s', port)
                 break
             if timeout and time.time() > op_timeout: # timeout exceeded
                 raise socket.timeout("Timeout exceeded")
             time.sleep(1)
+
 def wait_for_open_socket(socket_name, timeout=0):
     """
     Wait until the specified socket on the local host is open. Timeout
--
2.13.5
SOURCES/0231-Store-help-in-Schema-before-writing-to-disk.patch
New file
@@ -0,0 +1,39 @@
From 5693c0fe6dfe998fa5ea3f86f477dc9dcbfab881 Mon Sep 17 00:00:00 2001
From: David Kreitschmann <david@kreitschmann.de>
Date: Fri, 7 Apr 2017 18:22:25 +0200
Subject: [PATCH] Store help in Schema before writing to disk
Signed-off-by: David Kreitschmann <david@kreitschmann.de>
Reviewed-By: David Kupka <dkupka@redhat.com>
Reviewed-By: Martin Babinsky <mbabinsk@redhat.com>
Reviewed-By: David Kupka <dkupka@redhat.com>
Reviewed-By: Martin Babinsky <mbabinsk@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
---
 ipaclient/remote_plugins/schema.py | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/ipaclient/remote_plugins/schema.py b/ipaclient/remote_plugins/schema.py
index 3ecd608f96e336df57739db380a00c2d95b2ece5..9b6668d26352a24d7249bac5e304277563ee450f 100644
--- a/ipaclient/remote_plugins/schema.py
+++ b/ipaclient/remote_plugins/schema.py
@@ -383,6 +383,7 @@ class Schema(object):
         if fingerprint is None:
             fingerprint, ttl = self._fetch(client, ignore_cache=read_failed)
+            self._help = self._generate_help(self._dict)
             try:
                 self._write_schema(fingerprint)
             except Exception as e:
@@ -498,7 +499,7 @@ class Schema(object):
             schema.writestr(
                 '_help',
-                json.dumps(self._generate_help(self._dict)).encode('utf-8')
+                json.dumps(self._help).encode('utf-8')
             )
     def read_namespace_member(self, namespace, member):
--
2.13.5
SOURCES/0232-Disable-pylint-in-get_help-function-because-of-type-.patch
New file
@@ -0,0 +1,33 @@
From df9933a8cbc5c6cf4041709ed61c589adaae7a08 Mon Sep 17 00:00:00 2001
From: David Kreitschmann <david@kreitschmann.de>
Date: Fri, 9 Jun 2017 17:59:35 +0200
Subject: [PATCH] Disable pylint in get_help function because of type
 confusion.
Reviewed-By: David Kupka <dkupka@redhat.com>
Reviewed-By: Martin Babinsky <mbabinsk@redhat.com>
Reviewed-By: David Kupka <dkupka@redhat.com>
Reviewed-By: Martin Babinsky <mbabinsk@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
---
 ipaclient/remote_plugins/schema.py | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/ipaclient/remote_plugins/schema.py b/ipaclient/remote_plugins/schema.py
index 9b6668d26352a24d7249bac5e304277563ee450f..2892ab9ec7c6fb092ef470b7e5bd2b9c0760c2af 100644
--- a/ipaclient/remote_plugins/schema.py
+++ b/ipaclient/remote_plugins/schema.py
@@ -516,7 +516,9 @@ class Schema(object):
     def get_help(self, namespace, member):
         if isinstance(self._help, bytes):
-            self._help = json.loads(self._help.decode('utf-8'))
+            self._help = json.loads(
+                self._help.decode('utf-8')  # pylint: disable=no-member
+            )
         return self._help[namespace][member]
--
2.13.5
SOURCES/1001-Change-branding-to-IPA-and-Identity-Management.patch
@@ -1,4 +1,4 @@
From 27b4f549af4f55b95ff44b9c5a59b9174ab7ad2e Mon Sep 17 00:00:00 2001
From 7a5799402ddfbe2704afa4449bb597f2feeea6c2 Mon Sep 17 00:00:00 2001
From: Jan Cholasta <jcholast@redhat.com>
Date: Tue, 14 Mar 2017 15:48:07 +0000
Subject: [PATCH] Change branding to IPA and Identity Management
@@ -982,10 +982,10 @@
     print("This includes:")
     if setup_ca:
diff --git a/ipaserver/install/server/replicainstall.py b/ipaserver/install/server/replicainstall.py
index 814925de152809808f726c60ae7f35a24bc32a4a..05f263cd2b1c6a7cd9d21b0d9a076d32d241ab96 100644
index 326daf708f091d9d2c56ad399e46aef659dbba2e..0d3fc5a24dcd55aab420db4a6565809dbe8e70a9 100644
--- a/ipaserver/install/server/replicainstall.py
+++ b/ipaserver/install/server/replicainstall.py
@@ -604,7 +604,7 @@ def check_domain_level_is_supported(current):
@@ -601,7 +601,7 @@ def check_domain_level_is_supported(current):
     above_upper_bound = current > constants.MAX_DOMAIN_LEVEL
 
     if under_lower_bound or above_upper_bound:
@@ -995,5 +995,5 @@
                    "this domain. The Domain Level needs to be "
                    "raised before installing a replica with "
-- 
2.9.4
2.13.5
SOURCES/1002-Package-copy-schema-to-ca.py.patch
@@ -1,4 +1,4 @@
From 85ac8d7f55b26f7d783844acbf942f5db99d0a37 Mon Sep 17 00:00:00 2001
From 6013929e6ae2ea5cce4437281b3ee019b33ec151 Mon Sep 17 00:00:00 2001
From: Jan Cholasta <jcholast@redhat.com>
Date: Tue, 14 Mar 2017 16:07:15 +0000
Subject: [PATCH] Package copy-schema-to-ca.py
@@ -40,5 +40,5 @@
 
 
-- 
2.9.4
2.13.5
SOURCES/1003-Revert-Increased-mod_wsgi-socket-timeout.patch
@@ -1,4 +1,4 @@
From e419842024b0fc9a774988972fadcbaf4650c395 Mon Sep 17 00:00:00 2001
From 3faf68ad37710c6650fdb12fc1b5751896a6e7e0 Mon Sep 17 00:00:00 2001
From: Jan Cholasta <jcholast@redhat.com>
Date: Wed, 22 Jun 2016 13:53:46 +0200
Subject: [PATCH] Revert "Increased mod_wsgi socket-timeout"
@@ -24,5 +24,5 @@
 WSGIScriptAlias /ipa /usr/share/ipa/wsgi.py
 WSGIScriptReloading Off
-- 
2.9.4
2.13.5
SOURCES/1004-Remove-csrgen.patch
@@ -1,4 +1,4 @@
From 12d2356795d64089ce2578031a1297d56c8048ce Mon Sep 17 00:00:00 2001
From f0851afdf0abd516dcd707e6e3ec0086f09f6090 Mon Sep 17 00:00:00 2001
From: Jan Cholasta <jcholast@redhat.com>
Date: Thu, 16 Mar 2017 09:44:21 +0000
Subject: [PATCH] Remove csrgen
@@ -1662,5 +1662,5 @@
-            _script = generator.csr_script(
-                principal, {}, 'example', 'identity')
-- 
2.9.4
2.13.5
SOURCES/ipa-centos-branding.patch
File was deleted
SPECS/ipa.spec
@@ -68,7 +68,7 @@
Name:           ipa
Version:        %{IPA_VERSION}
Release:        21%{?dist}.1.2
Release:        21%{?dist}.2.2
Summary:        The Identity, Policy and Audit system
Group:          System Environment/Base
@@ -76,10 +76,10 @@
URL:            http://www.freeipa.org/
Source0:        https://releases.pagure.org/freeipa/freeipa-%{version}.tar.gz
# RHEL spec file only: START: Change branding to IPA and Identity Management
#Source1:        header-logo.png
#Source2:        login-screen-background.jpg
#Source3:        login-screen-logo.png
#Source4:        product-name.png
Source1:        header-logo.png
Source2:        login-screen-background.jpg
Source3:        login-screen-logo.png
Source4:        product-name.png
# RHEL spec file only: END: Change branding to IPA and Identity Management
BuildRoot:      %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
@@ -303,6 +303,19 @@
Patch0217:      0217-smart-card-advises-ensure-that-krb5-pkinit-is-instal.patch
Patch0218:      0218-NULL-LDAP-context-in-call-to-ldap_search_ext_s-durin.patch
Patch0219:      0219-Restore-old-version-of-caIPAserviceCert-for-upgrade-.patch
Patch0220:      0220-ipa-otptoken-import-Make-PBKDF2-refer-to-the-pkcs5-n.patch
Patch0221:      0221-Adds-whoami-DS-plugin-in-case-that-plugin-is-missing.patch
Patch0222:      0222-Fix-ipa-config-mod-ca-renewal-master.patch
Patch0223:      0223-Backport-PR-988-to-ipa-4-5-Fix-Certificate-renewal-w.patch
Patch0224:      0224-Backport-PR-1008-to-ipa-4-5-Fix-ipa-server-upgrade-T.patch
Patch0225:      0225-Fixing-how-sssd.conf-is-updated-when-promoting-a-cli.patch
Patch0226:      0226-Backport-4-5-Fix-ipa-server-upgrade-with-server-cert.patch
Patch0227:      0227-Always-check-peer-has-keys-before-connecting.patch
Patch0228:      0228-Make-sure-upgrade-also-checks-for-IPv6-stack.patch
Patch0229:      0229-control-logging-of-host_port_open-from-caller.patch
Patch0230:      0230-log-progress-of-wait_for_open_ports.patch
Patch0231:      0231-Store-help-in-Schema-before-writing-to-disk.patch
Patch0232:      0232-Disable-pylint-in-get_help-function-because-of-type-.patch
Patch1001:      1001-Change-branding-to-IPA-and-Identity-Management.patch
Patch1002:      1002-Package-copy-schema-to-ca.py.patch
@@ -1104,10 +1117,10 @@
%endif # with_python3
# RHEL spec file only: START: Change branding to IPA and Identity Management
#cp %SOURCE1 install/ui/images/header-logo.png
#cp %SOURCE2 install/ui/images/login-screen-background.jpg
#cp %SOURCE3 install/ui/images/login-screen-logo.png
#cp %SOURCE4 install/ui/images/product-name.png
cp %SOURCE1 install/ui/images/header-logo.png
cp %SOURCE2 install/ui/images/login-screen-background.jpg
cp %SOURCE3 install/ui/images/login-screen-logo.png
cp %SOURCE4 install/ui/images/product-name.png
# RHEL spec file only: END: Change branding to IPA and Identity Management
@@ -1131,8 +1144,7 @@
%configure --with-vendor-suffix=-%{release} \
           %{enable_server_option} \
           %{with_ipatests_option} \
           %{linter_options} \
           --with-ipaplatform=rhel
           %{linter_options}
%make_build
@@ -1856,11 +1868,41 @@
%changelog
* Wed Sep 06 2017 Johnny Hughes <johnny@centos.org> - 4.5.0-21.el7.centos.1.2
- set ipaplatform to rhel for compatibilty for updates
* Wed Sep 20 2017 Felipe Barreto <fbarreto@redhat.com> - 4.5.0-21.el7.2.2
- Resolves: #1493410 ipa-server-upgrade timeouts on wait_for_open ports
  expecting IPA services listening on IPv6 ports
    - Make sure upgrade also checks for IPv6 stack
    - control logging of host_port_open from caller
    - log progress of wait_for_open_ports
- Resolves: #1493411 ipa help command returns traceback when no cache
  is present
    - Store help in Schema before writing to disk
    - Disable pylint in get_help function because of type confusion.
* Tue Sep 05 2017 CentOS Sources <bugs@centos.org> - 4.5.0-21.el7.centos.1.2
- Roll in CentOS Branding
* Tue Sep 19 2017 Felipe Barreto <fbarreto@redhat.com> - 4.5.0-21.el7.2
- Resolves: #1486794 - [ipa-replica-install] - 406 Client Error: Failed to
  validate message: Incorrect number of results (0) searching forpublic
  key for host
    - Always check peer has keys before connecting
- Resolves: #1489300 - Unable to set ca renewal master on replica
    - Fix ipa config-mod --ca-renewal-master
- Resolves: #1489815 - TypeError in renew_ca_cert prevents from swiching
  back to self-signed CA
    - Backport PR 988 to ipa-4-5 Fix Certificate renewal (with ext ca)
- Resolves: #1489817 - ipa-server-upgrade failes with "This entry already exists"
    - Backport PR 1008 to ipa-4-5 Fix ipa-server-upgrade: This entry already exists
- Resolves: #1490331 - FreeIPA/IdM installations which were upgraded from
  versions with 389 DS prior to 1.3.3.0 doesn't have whomai plugin enabled and
  thus startup of Web UI fails
    - Adds whoami DS plugin in case that plugin is missing
- Resolves: #1491545 - IPA WebUI does not work after upgrade from IPA 4.4 to 4.5
    - Fixing how sssd.conf is updated when promoting a client to replica
- Resolves: #1492616 - ipa-otptoken-import - XML file is missing PBKDF2
  parameters!
    - ipa-otptoken-import: Make PBKDF2 refer to the pkcs5 namespace
- Resolves: #1493153 - Updating from RHEL 7.3 fails with Server-Cert not found
  (ipa-server-upgrade)
    - Backport 4-5: Fix ipa-server-upgrade with server cert tracking
* Wed Aug 16 2017 Pavel Vomacka <pvomacka@redhat.com> - 4.5.0-21.el7.1.2
- Fixing issues reported by Errata tool