diff options
author | Martin Kosek <mkosek@redhat.com> | 2012-10-01 16:49:34 +0200 |
---|---|---|
committer | Rob Crittenden <rcritten@redhat.com> | 2012-10-02 15:17:42 -0400 |
commit | 0c2d0bb2b0f6b56f57b592ffc8784a0dfa1c9a48 (patch) | |
tree | a936c43b8313ac0bbf4d284aefc40fce716372b9 /ipaserver/install/plugins | |
parent | 682edbf2152aa2dce2f6350226bffc6ebc2526c1 (diff) | |
download | freeipa-0c2d0bb2b0f6b56f57b592ffc8784a0dfa1c9a48.tar.gz freeipa-0c2d0bb2b0f6b56f57b592ffc8784a0dfa1c9a48.tar.xz freeipa-0c2d0bb2b0f6b56f57b592ffc8784a0dfa1c9a48.zip |
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
Diffstat (limited to 'ipaserver/install/plugins')
-rw-r--r-- | ipaserver/install/plugins/Makefile.am | 1 | ||||
-rw-r--r-- | ipaserver/install/plugins/update_services.py | 95 |
2 files changed, 96 insertions, 0 deletions
diff --git a/ipaserver/install/plugins/Makefile.am b/ipaserver/install/plugins/Makefile.am index 9670273c8..d29103a90 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 000000000..c384af52f --- /dev/null +++ b/ipaserver/install/plugins/update_services.py @@ -0,0 +1,95 @@ +# Authors: +# Martin Kosek <mkosek@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) |