On 10/02/2012 03:04 PM, Martin Kosek wrote:
> On 10/02/2012 12:19 PM, Petr Viktorin wrote:
>> On 10/01/2012 05:28 PM, Martin Kosek wrote:
>>>> From IPA 3.0, services have by default ipakrbprincipal objectclass which
>>> allows ipakrbprincipalalias attribute used for case-insensitive principal
>>> searches. However, as services created in previous version do not have
>>> this objectclass (and attribute), they are not listed in service list
>>> produced by service-find.
>>>
>>> Treat the ipakrbprincipal as optional to avoid missing services in
>>> service-find command. Add flag to service-mod command which can fill
>>> ipakrbprincipalalias attribute when case-insensitive principal searches
>>> for a 2.x service are required.
>>>
>>> https://fedorahosted.org/freeipa/ticket/3106
>>
>> This works, I'm getting all services now & the tests pass.
>>
>>>
>>> -----
>>>
>>> I am still pondering about a right way to fill ipakrbprincipalalias used in 
>>> for
>>> IPA 3.0 case-insensitive searches, so far I implemented this command:
>>>
>>> ipa service-mod PRINCIPAL --update-principal-alias
>>>
>>> But I am thinking it may be a better approach to generalize it and do 
>>> something
>>> like that:
>>>
>>> ipa service-mod PRINCIPAL --upgrade/--update
>>>
>>> This command would do a general update of service entry to an up-to-date 3.0
>>> style, in this case it could do 2 things:
>>> * fill ipakrbprincipalalias
>>> * fill ipakrbauthzdata (based on default value in IPA config).
>>
>> I don't think you're generalizing enough; `service-mod --upgrade` isn't that
>> different from `service-mod --update-principal-alias --update-authzdata`.
>> Scripting this to happen for all services could be a nuisance, though. There
>> should be a way to upgrade all services at once, and since we already have
>> ipa-ldap-updater for it, it should run as part of that.
>>
>> I think we should keep ipakrbprincipal optional, in case the upgrade goes 
>> wrong.
>>
> 
> I agree. I created an upgrade plugin which should update all services and fill
> ipakrbprincipalalias during upgrade (attached). I tested 2.2 -> 3.0 upgrade 
> and
> it worked fine.
> 
> Martin
> 

There was a glitch in the loop repeating the update when LDAP limits are hit -
thanks Petr Viktorin for noticing the issue. It is working now, I tried with 10
affected services and search limit set to 1 entry - and the loop executed 10
times as it was supposed to.

I also disabled size/time limits for the search in the upgrade plugin. But it
would also work if default IPA search limits (100 entries) are used, it should
just make things faster.

Martin
From 1a4bd467bda9eb668aead2514b431c6b949c4a5d Mon Sep 17 00:00:00 2001
From: Martin Kosek <mko...@redhat.com>
Date: Mon, 1 Oct 2012 16:49:34 +0200
Subject: [PATCH] Fill ipakrbprincipalalias on upgrades

From IPA 3.0, services have by default ipakrbprincipal objectclass which
allows ipakrbprincipalalias attribute used for case-insensitive principal
searches. However, services created in previous version do not have
this objectclass (and attribute) and thus case-insensitive searches
may return inconsistent results.

Fill ipakrbprincipalalias on upgrades for all 2.x services. Also treat
Treat the ipakrbprincipal as optional to avoid missing services in
service-find command if the upgrade fails for any reason.

https://fedorahosted.org/freeipa/ticket/3106
---
 ipalib/plugins/service.py                    |  7 +-
 ipaserver/install/plugins/Makefile.am        |  1 +
 ipaserver/install/plugins/update_services.py | 95 ++++++++++++++++++++++++++++
 3 files changed, 102 insertions(+), 1 deletion(-)
 create mode 100644 ipaserver/install/plugins/update_services.py

diff --git a/ipalib/plugins/service.py b/ipalib/plugins/service.py
index a7201f525941023fb5caa8610836156a6df79bab..551990d7cabc4cfa331a019edb721bdfc99a6b2d 100644
--- a/ipalib/plugins/service.py
+++ b/ipalib/plugins/service.py
@@ -218,8 +218,9 @@ class service(LDAPObject):
     object_name_plural = _('services')
     object_class = [
         'krbprincipal', 'krbprincipalaux', 'krbticketpolicyaux', 'ipaobject',
-        'ipaservice', 'pkiuser', 'ipakrbprincipal'
+        'ipaservice', 'pkiuser'
     ]
+    possible_objectclasses = ['ipakrbprincipal']
     search_attributes = ['krbprincipalname', 'managedby', 'ipakrbauthzdata']
     default_attributes = ['krbprincipalname', 'usercertificate', 'managedby',
         'ipakrbauthzdata',]
@@ -311,6 +312,10 @@ class service_add(LDAPCreate):
         # schema
         entry_attrs['ipakrbprincipalalias'] = keys[-1]
 
+        # Objectclass ipakrbprincipal providing ipakrbprincipalalias is not in
+        # in a list of default objectclasses, add it manually
+        entry_attrs['objectclass'].append('ipakrbprincipal')
+
         return dn
 
 api.register(service_add)
diff --git a/ipaserver/install/plugins/Makefile.am b/ipaserver/install/plugins/Makefile.am
index 9670273c8cd14c2ec98da9d228664b06289483a1..d29103a90afdffa74d768b3438acb9733b825d53 100644
--- a/ipaserver/install/plugins/Makefile.am
+++ b/ipaserver/install/plugins/Makefile.am
@@ -8,6 +8,7 @@ app_PYTHON = 			\
 	rename_managed.py	\
 	dns.py			\
 	updateclient.py		\
+	update_services.py	\
 	$(NULL)
 
 EXTRA_DIST =			\
diff --git a/ipaserver/install/plugins/update_services.py b/ipaserver/install/plugins/update_services.py
new file mode 100644
index 0000000000000000000000000000000000000000..c384af52fb91692c7f339c5fb2da92ae45984482
--- /dev/null
+++ b/ipaserver/install/plugins/update_services.py
@@ -0,0 +1,95 @@
+# Authors:
+#   Martin Kosek <mko...@redhat.com>
+#
+# Copyright (C) 2012  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/>.
+
+from ipaserver.install.plugins import MIDDLE
+from ipaserver.install.plugins.baseupdate import PostUpdate
+from ipalib import api, errors
+from ipapython.dn import DN
+from ipapython.ipa_log_manager import *
+
+
+class update_service_principalalias(PostUpdate):
+    """
+    Update all services which do not have ipakrbprincipalalias attribute
+    used for case-insensitive principal searches filled. This applies for
+    all services created prior IPA 3.0.
+    """
+    order = MIDDLE
+
+    def execute(self, **options):
+        ldap = self.obj.backend
+
+        base_dn = DN(api.env.container_service, api.env.basedn)
+        search_filter = ("(&(objectclass=krbprincipal)(objectclass=ipaservice)"
+                         "(!(objectclass=ipakrbprincipal)))")
+        root_logger.debug("update_service_principalalias: search for affected "
+                          "services")
+
+        while True:
+            # run the search in loop to avoid issues when LDAP limits are hit
+            # during update
+            try:
+                (entries, truncated) = ldap.find_entries(search_filter,
+                    ['objectclass', 'krbprincipalname'], base_dn,
+                    time_limit=0, size_limit=0)
+            except errors.NotFound:
+                root_logger.debug("update_service_principalalias: no service "
+                                  "to update found")
+                return (False, False, [])
+            except errors.ExecutionError, e:
+                root_logger.error("update_service_principalalias: cannot "
+                                  "retrieve list of affected services: %s", e)
+                return (False, False, [])
+            if not entries:
+                # no entry was returned, rather break than continue cycling
+                root_logger.debug("update_service_principalalias: no service "
+                                  "was returned")
+                return (False, False, [])
+            root_logger.debug("update_service_principalalias: found %d "
+                              "services to update, truncated: %s",
+                              len(entries), truncated)
+
+            error = False
+            for dn, entry in entries:
+                update = {}
+                update['objectclass'] = (entry['objectclass'] +
+                                         ['ipakrbprincipal'])
+                update['ipakrbprincipalalias'] = entry['krbprincipalname']
+                try:
+                    ldap.update_entry(dn, update)
+                except (errors.EmptyModlist, errors.NotFound):
+                    pass
+                except errors.ExecutionError, e:
+                    root_logger.debug("update_service_principalalias: cannot "
+                                      "update service: %s", e)
+                    error = True
+
+            if error:
+                # exit loop to avoid infinite cycles
+                root_logger.error("update_service_principalalias: error(s)"
+                                  "detected during service update")
+                return (False, False, [])
+            elif not truncated:
+                # all affected entries updated, exit the loop
+                root_logger.debug("update_service_principalalias: all affected"
+                                  " services updated")
+                return (False, False, [])
+        return (False, False, [])
+
+api.register(update_service_principalalias)
-- 
1.7.11.4

_______________________________________________
Freeipa-devel mailing list
Freeipa-devel@redhat.com
https://www.redhat.com/mailman/listinfo/freeipa-devel

Reply via email to