On 23.02.2016 13:02, Alexander Bokovoy wrote:
On Tue, 23 Feb 2016, Martin Basti wrote:
From f2ae1bd129a1741500d2f3dcb86a0da553604d15 Mon Sep 17 00:00:00 2001
From: Martin Basti <mba...@redhat.com>
Date: Tue, 23 Feb 2016 10:37:47 +0100
Subject: [PATCH 4/4] fix upgrade: wait for proper DS socket after DS restart

Restarting DS executed by upgrade plugin causes that upgrade frameworg
was waiting for not proper socket to be ready. This commit fix issue.
Please fix the commit message typos.

Fixed. Updated patches attached.
From 779ca0e230252d40bb275539b4cc512d0460a056 Mon Sep 17 00:00:00 2001
From: Martin Basti <mba...@redhat.com>
Date: Thu, 18 Feb 2016 19:59:50 +0100
Subject: [PATCH 1/4] upgrade: fix config of sidgen and extdom plugins

During upgrade to IPA 4.2, literally "$SUFFIX" value was added to
configuration of sidgen and extdom plugins. This cause that SID are not properly configured.

Upgrade must fix "$SUFFIX" to reals suffix DN, and run sidgen task
against IPA domain (if exists).

All trusts added when plugins configuration was broken must be re-added.

https://fedorahosted.org/freeipa/ticket/5665
---
 install/updates/90-post_upgrade_plugins.update |   2 +
 ipaserver/install/dsinstance.py                |  12 +-
 ipaserver/install/plugins/adtrust.py           | 153 +++++++++++++++++++++++++
 ipaserver/install/server/upgrade.py            |   4 +-
 4 files changed, 163 insertions(+), 8 deletions(-)

diff --git a/install/updates/90-post_upgrade_plugins.update b/install/updates/90-post_upgrade_plugins.update
index 5642021ad93cf336db2d872bf3ef6db99b5ffa46..9c9ee160fffedbc8e8d59705169e6cf08ddc9779 100644
--- a/install/updates/90-post_upgrade_plugins.update
+++ b/install/updates/90-post_upgrade_plugins.update
@@ -5,6 +5,8 @@
 plugin: update_ca_topology
 plugin: update_dnszones
 plugin: update_dns_limits
+plugin: update_sigden_extdom_broken_config
+plugin: update_sids
 plugin: update_default_range
 plugin: update_default_trust_view
 plugin: update_ca_renewal_master
diff --git a/ipaserver/install/dsinstance.py b/ipaserver/install/dsinstance.py
index 2905c31c64c4fa8bd034d2cdf6ce5d90ecfea091..f474e189a47f945b7c91cba4ccc17266b9c7e430 100644
--- a/ipaserver/install/dsinstance.py
+++ b/ipaserver/install/dsinstance.py
@@ -1054,9 +1054,9 @@ class DsInstance(service.Service):
         """
         Add sidgen directory server plugin configuration if it does not already exist.
         """
-        self._ldap_mod('ipa-sidgen-conf.ldif', self.sub_dict)
+        self.add_sidgen_plugin(self.sub_dict['SUFFIX'])
 
-    def add_sidgen_plugin(self):
+    def add_sidgen_plugin(self, suffix):
         """
         Add sidgen plugin configuration only if it does not already exist.
         """
@@ -1064,7 +1064,7 @@ class DsInstance(service.Service):
         try:
             self.admin_conn.get_entry(dn)
         except errors.NotFound:
-            self._add_sidgen_plugin()
+            self._ldap_mod('ipa-sidgen-conf.ldif', dict(SUFFIX=suffix))
         else:
             root_logger.debug("sidgen plugin is already configured")
 
@@ -1072,9 +1072,9 @@ class DsInstance(service.Service):
         """
         Add directory server configuration for the extdom extended operation.
         """
-        self._ldap_mod('ipa-extdom-extop-conf.ldif', self.sub_dict)
+        self.add_extdom_plugin(self.sub_dict['SUFFIX'])
 
-    def add_extdom_plugin(self):
+    def add_extdom_plugin(self, suffix):
         """
         Add extdom configuration if it does not already exist.
         """
@@ -1082,7 +1082,7 @@ class DsInstance(service.Service):
         try:
             self.admin_conn.get_entry(dn)
         except errors.NotFound:
-            self._add_extdom_plugin()
+            self._ldap_mod('ipa-extdom-extop-conf.ldif', dict(SUFFIX=suffix))
         else:
             root_logger.debug("extdom plugin is already configured")
 
diff --git a/ipaserver/install/plugins/adtrust.py b/ipaserver/install/plugins/adtrust.py
index df9412adba833251cc1c70d7d72ebebbdc77c2a4..5b81b2efd5be63f45b02b8d357f89ec5ba142170 100644
--- a/ipaserver/install/plugins/adtrust.py
+++ b/ipaserver/install/plugins/adtrust.py
@@ -21,6 +21,8 @@ from ipalib import api, errors
 from ipalib import Updater
 from ipapython.dn import DN
 from ipapython.ipa_log_manager import root_logger
+from ipaserver.install import sysupgrade
+
 
 DEFAULT_ID_RANGE_SIZE = 200000
 
@@ -161,5 +163,156 @@ class update_default_trust_view(Updater):
 
         return False, [update]
 
+
+class update_sigden_extdom_broken_config(Updater):
+    """Fix configuration of sidgen and extdom plugins
+
+    Upgrade to IPA 4.2+ cause that sidgen and extdom plugins have improperly
+    configured basedn.
+
+    All trusts which have been added when config was broken must to be
+    re-added manually.
+
+    https://fedorahosted.org/freeipa/ticket/5665
+    """
+
+    sidgen_config_dn = DN("cn=IPA SIDGEN,cn=plugins,cn=config")
+    extdom_config_dn = DN("cn=ipa_extdom_extop,cn=plugins,cn=config")
+
+    def _fix_config(self):
+        """Due upgrade error configuration of sidgen and extdom plugins may
+        contain literally "$SUFFIX" value instead of real DN in nsslapd-basedn
+        attribute
+
+        :return: True if config was fixed, False if fix is not needed
+        """
+        ldap = self.api.Backend.ldap2
+        basedn_attr = 'nsslapd-basedn'
+        modified = False
+
+        for dn in (self.sidgen_config_dn, self.extdom_config_dn):
+            try:
+                entry = ldap.get_entry(dn, attrs_list=[basedn_attr])
+            except errors.NotFound:
+                self.log.debug("configuration for %s not found, skipping", dn)
+            else:
+                configured_suffix = entry.single_value.get(basedn_attr)
+                if configured_suffix is None:
+                    raise RuntimeError(
+                        "Missing attribute {attr} in {dn}".format(
+                            attr=basedn_attr, dn=dn
+                        )
+                    )
+                elif configured_suffix == "$SUFFIX":
+                    # configured value is wrong, fix it
+                    entry.single_value[basedn_attr] = str(self.api.env.basedn)
+                    self.log.debug("updating attribute %s of %s to correct "
+                                   "value %s", basedn_attr, dn,
+                                   self.api.env.basedn)
+                    ldap.update_entry(entry)
+                    modified = True
+                else:
+                    self.log.debug("configured basedn for %s is okay", dn)
+
+        return modified
+
+    def execute(self, **options):
+        if sysupgrade.get_upgrade_state('sidgen', 'config_basedn_updated'):
+            self.log.debug("Already done, skipping")
+            return False, ()
+
+        restart = False
+        if self._fix_config():
+            sysupgrade.set_upgrade_state('sidgen', 'update_sids', True)
+            restart = True  # DS has to be restarted to apply changes
+
+        sysupgrade.set_upgrade_state('sidgen', 'config_basedn_updated', True)
+        return restart, ()
+
+
+class update_sids(Updater):
+    """SIDs may be not created properly if bug with wrong configuration for
+    sidgen and extdom plugins is effective
+
+    This must be run after "update_sigden_extdom_broken_config"
+    https://fedorahosted.org/freeipa/ticket/5665
+    """
+    sidgen_config_dn = DN("cn=IPA SIDGEN,cn=plugins,cn=config")
+
+    def execute(self, **options):
+        ldap = self.api.Backend.ldap2
+
+        if sysupgrade.get_upgrade_state('sidgen', 'update_sids') is not True:
+            self.log.debug("SIDs do not need to be generated")
+            return False, ()
+
+        # check if IPA domain for AD trust has been created, and if we need to
+        # regenerate missing SIDs if attribute 'ipaNTSecurityIdentifier'
+        domain_IPA_AD_dn = DN(
+            ('cn', self.api.env.domain),
+            self.api.env.container_cifsdomains,
+            self.api.env.basedn)
+        attr_name = 'ipaNTSecurityIdentifier'
+
+        try:
+            entry = ldap.get_entry(domain_IPA_AD_dn, attrs_list=[attr_name])
+        except errors.NotFound:
+            self.log.debug("IPA domain object %s is not configured",
+                           domain_IPA_AD_dn)
+            sysupgrade.set_upgrade_state('sidgen', 'update_sids', False)
+            return False, ()
+        else:
+            if not entry.single_value.get(attr_name):
+                # we need to run sidgen task
+                sidgen_task_dn = DN(
+                    "cn=generate domain sid,cn=ipa-sidgen-task,cn=tasks,"
+                    "cn=config")
+                sidgen_tasks_attr = {
+                    "objectclass": ["top", "extensibleObject"],
+                    "cn": ["sidgen"],
+                    "delay": [0],
+                    "nsslapd-basedn": [self.api.env.basedn],
+                }
+
+                task_entry = ldap.make_entry(sidgen_task_dn,
+                                             **sidgen_tasks_attr)
+                try:
+                    ldap.add_entry(task_entry)
+                except errors.DuplicateEntry:
+                    self.log.debug("sidgen task already created")
+                else:
+                    self.log.debug("sidgen task has been created")
+
+        # we have to check all trusts domains which may been affected by the
+        # bug. Symptom is missing 'ipaNTSecurityIdentifier' attribute
+
+        base_dn = DN(self.api.env.container_adtrusts, self.api.env.basedn)
+        try:
+            trust_domain_entries, truncated = ldap.find_entries(
+                base_dn=base_dn,
+                scope=ldap.SCOPE_ONELEVEL,
+                attrs_list=["cn"],
+                # more types of trusts can be stored under cn=trusts, we need
+                # the type with ipaNTTrustPartner attribute
+                filter="(!(%s=*))" % attr_name
+            )
+        except errors.NotFound:
+            pass
+        else:
+            if truncated:
+                self.log.warning("update_sids: Search results were truncated")
+
+            for entry in trust_domain_entries:
+                domain = entry.single_value["cn"]
+                self.log.error(
+                    "Your trust to %s is broken. Please re-create it by "
+                    "running 'ipa trust-add' again.", domain)
+
+        sysupgrade.set_upgrade_state('sidgen', 'update_sids', False)
+        return False, ()
+
+
 api.register(update_default_range)
 api.register(update_default_trust_view)
+api.register(update_sids)
+api.register(update_sigden_extdom_broken_config)
diff --git a/ipaserver/install/server/upgrade.py b/ipaserver/install/server/upgrade.py
index 455b28acc3aedbefb22ee2e294ceab031d253348..61f33c9bd99db8581897f812767cb869301ad5f0 100644
--- a/ipaserver/install/server/upgrade.py
+++ b/ipaserver/install/server/upgrade.py
@@ -1369,8 +1369,8 @@ def ds_enable_sidgen_extdom_plugins(ds):
         root_logger.debug('sidgen and extdom plugins are enabled already')
         return
 
-    ds.add_sidgen_plugin()
-    ds.add_extdom_plugin()
+    ds.add_sidgen_plugin(api.env.basedn)
+    ds.add_extdom_plugin(api.env.basedn)
     sysupgrade.set_upgrade_state('ds', 'enable_ds_sidgen_extdom_plugins', True)
 
 def ca_upgrade_schema(ca):
-- 
2.5.0

From 14e41eb89a837ad75002e007a6e79ac2ac0bd545 Mon Sep 17 00:00:00 2001
From: Martin Basti <mba...@redhat.com>
Date: Mon, 22 Feb 2016 17:36:01 +0100
Subject: [PATCH 2/4] trusts: use ipaNTTrustPartner attribute to detect trust
 entries

Trust entries were found by presence of ipaNTSecurityIdentifier
attribute. Unfortunately this attribute might not be there due the bug.
As replacement for this, attribute ipaNTTrustPartner can be used.

Note: other non trust entries located in cn=trusts subtree can be
cross-realm principals.

https://fedorahosted.org/freeipa/ticket/5665
---
 ipalib/plugins/trust.py              | 7 +++++--
 ipaserver/install/plugins/adtrust.py | 2 +-
 2 files changed, 6 insertions(+), 3 deletions(-)

diff --git a/ipalib/plugins/trust.py b/ipalib/plugins/trust.py
index 6451041484b34c922fc1fbf5699beee8e2e8ba47..c490544a0b03afd609a0301a0fcf90f23feb19a2 100644
--- a/ipalib/plugins/trust.py
+++ b/ipalib/plugins/trust.py
@@ -563,8 +563,11 @@ class trust(LDAPObject):
                 rules=ldap.MATCH_ALL
             )
 
+            # more type of objects can be located in subtree (for example
+            # cross-realm principals). we need this attr do detect trust
+            # entries
             trustfilter = ldap.combine_filters(
-                (trustfilter, "ipaNTSecurityIdentifier=*"),
+                (trustfilter, "ipaNTTrustPartner=*"),
                 rules=ldap.MATCH_ALL
             )
 
@@ -1036,7 +1039,7 @@ class trust_find(LDAPSearch):
     # search needs to be done on a sub-tree scope
     def pre_callback(self, ldap, filters, attrs_list, base_dn, scope, *args, **options):
         # list only trust, not trust domains
-        trust_filter = '(ipaNTSecurityIdentifier=*)'
+        trust_filter = '(ipaNTTrustPartner=*)'
         filter = ldap.combine_filters((filters, trust_filter), rules=ldap.MATCH_ALL)
         return (filter, base_dn, ldap.SCOPE_SUBTREE)
 
diff --git a/ipaserver/install/plugins/adtrust.py b/ipaserver/install/plugins/adtrust.py
index 5b81b2efd5be63f45b02b8d357f89ec5ba142170..ce58d7f171bd448dc767f92bbc32346a14f5b2ea 100644
--- a/ipaserver/install/plugins/adtrust.py
+++ b/ipaserver/install/plugins/adtrust.py
@@ -294,7 +294,7 @@ class update_sids(Updater):
                 attrs_list=["cn"],
                 # more types of trusts can be stored under cn=trusts, we need
                 # the type with ipaNTTrustPartner attribute
-                filter="(!(%s=*))" % attr_name
+                filter="(&(ipaNTTrustPartner=*)(!(%s=*)))" % attr_name
             )
         except errors.NotFound:
             pass
-- 
2.5.0

From ac5a0f90d0dcfe3bda913913fd470298eaa41dbf Mon Sep 17 00:00:00 2001
From: Martin Basti <mba...@redhat.com>
Date: Fri, 19 Feb 2016 14:55:34 +0100
Subject: [PATCH 3/4] Warn user if trust is broken

Detect missing ipaNTSecurityIdentifier and print message for a user,
that the trust is broken as result of trust-show and trust-find commands.

https://fedorahosted.org/freeipa/ticket/5665
---
 ipalib/messages.py      | 11 +++++++++++
 ipalib/plugins/trust.py | 41 +++++++++++++++++++++++++++++++++++++++++
 2 files changed, 52 insertions(+)

diff --git a/ipalib/messages.py b/ipalib/messages.py
index e43584b108eda0055419f605c4c0c1893ec9a6d0..dbbc34ab14e0ed339bda93db379d70d95e7336ff 100644
--- a/ipalib/messages.py
+++ b/ipalib/messages.py
@@ -341,6 +341,17 @@ class SearchResultTruncated(PublicMessage):
     format = _("Search result has been truncated to configured search limit.")
 
 
+class BrokenTrust(PublicMessage):
+    """
+    **13018** Trust for a specified domain is broken
+    """
+
+    errno = 13018
+    type = "warning"
+    format = _("Your trust to %(domain)s is broken. Please re-create it by "
+               "running 'ipa trust-add' again.")
+
+
 def iter_messages(variables, base):
     """Return a tuple with all subclasses
     """
diff --git a/ipalib/plugins/trust.py b/ipalib/plugins/trust.py
index c490544a0b03afd609a0301a0fcf90f23feb19a2..d3957aea2b252bdb01dc64956f5e487516784eb1 100644
--- a/ipalib/plugins/trust.py
+++ b/ipalib/plugins/trust.py
@@ -20,6 +20,9 @@
 
 import six
 
+from ipalib.messages import (
+    add_message,
+    BrokenTrust)
 from ipalib.plugable import Registry
 from ipalib.plugins.baseldap import (
     pkey_to_value,
@@ -586,6 +589,30 @@ class trust(LDAPObject):
 
         return make_trust_dn(self.env, trust_type, DN(*sdn))
 
+    def warning_if_ad_trust_dom_have_missing_SID(self, result, **options):
+        """Due bug https://fedorahosted.org/freeipa/ticket/5665 there might be
+        AD trust domain without generated SID, warn user about it.
+        """
+        ldap = self.api.Backend.ldap2
+
+        try:
+            entries, truncated = ldap.find_entries(
+                base_dn=DN(self.container_dn, self.api.env.basedn),
+                attrs_list=['cn'],
+                filter='(&(ipaNTTrustPartner=*)'
+                       '(!(ipaNTSecurityIdentifier=*)))',
+            )
+        except errors.NotFound:
+            pass
+        else:
+            for entry in entries:
+                 add_message(
+                    options['version'],
+                    result,
+                    BrokenTrust(domain=entry.single_value['cn'])
+                 )
+
+
 @register()
 class trust_add(LDAPCreate):
     __doc__ = _('''
@@ -1043,6 +1070,13 @@ class trust_find(LDAPSearch):
         filter = ldap.combine_filters((filters, trust_filter), rules=ldap.MATCH_ALL)
         return (filter, base_dn, ldap.SCOPE_SUBTREE)
 
+    def execute(self, *args, **options):
+        result = super(trust_find, self).execute(*args, **options)
+
+        self.obj.warning_if_ad_trust_dom_have_missing_SID(result, **options)
+
+        return result
+
     def post_callback(self, ldap, entries, truncated, *args, **options):
         if options.get('pkey_only', False):
             return truncated
@@ -1062,6 +1096,13 @@ class trust_show(LDAPRetrieve):
     has_output_params = LDAPRetrieve.has_output_params + trust_output_params +\
                         (Str('ipanttrusttype'), Str('ipanttrustdirection'))
 
+    def execute(self, *keys, **options):
+        result = super(trust_show, self).execute(*keys, **options)
+
+        self.obj.warning_if_ad_trust_dom_have_missing_SID(result, **options)
+
+        return result
+
     def post_callback(self, ldap, dn, entry_attrs, *keys, **options):
 
         assert isinstance(dn, DN)
-- 
2.5.0

From 2ef1396d64bde2f996693e459f27126be6cc8c57 Mon Sep 17 00:00:00 2001
From: Martin Basti <mba...@redhat.com>
Date: Tue, 23 Feb 2016 10:37:47 +0100
Subject: [PATCH 4/4] fix upgrade: wait for proper DS socket after DS restart

DS restart executed by upgrade plugin causes that upgrade framework
is waiting for the improper socket. It leads to TimeoutError because
DS is not listening on 389 port during upgrade. This commit fixes the issue.

Required for: https://fedorahosted.org/freeipa/ticket/5665
---
 ipaserver/install/ldapupdate.py | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/ipaserver/install/ldapupdate.py b/ipaserver/install/ldapupdate.py
index 95e35f6976422e97c1344604483aecaf6e86f5d9..32fa4e25bdfed11987ae81282b6f4bd3fd206733 100644
--- a/ipaserver/install/ldapupdate.py
+++ b/ipaserver/install/ldapupdate.py
@@ -43,7 +43,6 @@ from ipaplatform.paths import paths
 from ipaplatform import services
 from ipapython.dn import DN
 from ipapython.ipa_log_manager import log_mgr
-from ipapython.ipautil import wait_for_open_socket
 
 if six.PY3:
     unicode = str
@@ -945,5 +944,4 @@ class LDAPUpdate:
     def restart_ds(self):
         dirsrv = services.knownservices.dirsrv
         self.log.debug('Restarting directory server to apply updates')
-        dirsrv.restart()
-        wait_for_open_socket(self.socket_name)
+        dirsrv.restart(ldapi=self.ldapi)
-- 
2.5.0

-- 
Manage your subscription for the Freeipa-devel mailing list:
https://www.redhat.com/mailman/listinfo/freeipa-devel
Contribute to FreeIPA: http://www.freeipa.org/page/Contribute/Code

Reply via email to