On 07/12/2016 02:00 PM, Martin Babinsky wrote:
On 07/12/2016 01:05 PM, Alexander Bokovoy wrote:
On Mon, 11 Jul 2016, Martin Babinsky wrote:
From 185bde00a76459430d95ff207bf1fb3fe31e811a Mon Sep 17 00:00:00 2001
From: Martin Babinsky <mbabi...@redhat.com>
Date: Fri, 1 Jul 2016 18:09:04 +0200
Subject: [PATCH] Preserve user principal aliases during rename operation

When a MODRDN is performed on the user entry, the MODRDN plugin resets
krbPrincipalName and krbCanonicalName to the value constructed from
uid. In
doing so, hovewer, any principal aliases added to the krbPrincipalName
wiped clean. In this patch old aliases are fetched before the MODRDN
takes place and inserted back after it is performed.

This also preserves previous user logins which can be used further for
authentication as aliases.

ipaserver/plugins/baseuser.py | 46
1 file changed, 46 insertions(+)

diff --git a/ipaserver/plugins/baseuser.py

--- a/ipaserver/plugins/baseuser.py
+++ b/ipaserver/plugins/baseuser.py
@@ -498,6 +498,50 @@ class baseuser_mod(LDAPUpdate):
                            len =
+    def preserve_krbprincipalname_pre(self, ldap, entry_attrs, *keys,
+        """
+        preserve user principal aliases during rename operation. This
is the
+        pre-callback part of this. Another method called during
+        shall insert the principals back
+        """
+        if options.get('rename', None) is None:
+            return
+        try:
+            old_entry = ldap.get_entry(
+                entry_attrs.dn, attrs_list=(
+                    'krbprincipalname', 'krbcanonicalname'))
+            if 'krbcanonicalname' not in old_entry:
+                return
+        except errors.NotFound:
+            self.obj.handle_not_found(*keys)
+        self.context.krbprincipalname = old_entry.get(
+            'krbprincipalname', [])
+    def preserve_krbprincipalname_post(self, ldap, entry_attrs,
+        """
+        Insert the preserved aliases back to the user entry during
+        operation
+        """
+        if options.get('rename', None) is None or not hasattr(
+                self.context, 'krbprincipalname'):
+            return
+        obj_pkey = self.obj.get_primary_key_from_dn(entry_attrs.dn)
+        canonical_name = entry_attrs['krbcanonicalname'][0]
+        principals_to_add = tuple(p for p in
self.context.krbprincipalname if
+                                  p != canonical_name)
+        if principals_to_add:
+            result = self.api.Command.user_add_principal(
+                obj_pkey, principals_to_add)['result']
+            entry_attrs['krbprincipalname'] =
result.get('krbprincipalname', [])
    def check_mail(self, entry_attrs):
        if 'mail' in entry_attrs:
            entry_attrs['mail'] =
@@ -557,9 +601,11 @@ class baseuser_mod(LDAPUpdate):

        self.check_objectclass(ldap, dn, entry_attrs)
+        self.preserve_krbprincipalname_pre(ldap, entry_attrs, *keys,

    def post_common_callback(self, ldap, dn, entry_attrs, *keys,
        assert isinstance(dn, DN)
+        self.preserve_krbprincipalname_post(ldap, entry_attrs,
        if options.get('random', False):
                entry_attrs['randompassword'] =
unicode(getattr(context, 'randompassword'))

The approach looks good.

For the record, we also support aliases for hosts and service kerberos
principals but we don't support rename options for them, so there is no
need to add similar logic there.

That's right, I have updated the corresponding section of the design
page [1] for future reference.


Adding Simo to the loop since he is not convinced that this is the right behavior. As I see it, it seems to not be a security issue but more of a different expectations about the perceived correct behavior in this particular situation.

I can see the use case in keeping the old aliases, e.g. keeping the old credentials after legal name change, but I can also see the available space for user principal names piling up and cluttering quickly in large organizations.

Martin^3 Babinsky

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

Reply via email to