Blob Blame History Raw
From 1dfba16f6d46a2811d0230f28abf0ea4621bfde2 Mon Sep 17 00:00:00 2001
From: Martin Babinsky <mbabinsk@redhat.com>
Date: Thu, 28 Jul 2016 10:42:58 +0200
Subject: [PATCH] re-set canonical principal name on migrated users

The migration procedure has been updated to re-set `krbcanonicalname`
attribute on migrated users as well as `krbprincipalname` so that migration
from FreeIPA versions supporting principal aliases does not break subsequent
authentication of migrated users.

https://fedorahosted.org/freeipa/ticket/6101

Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
---
 ipaserver/plugins/migration.py | 41 ++++++++++++++++++++++++++++-------------
 1 file changed, 28 insertions(+), 13 deletions(-)

diff --git a/ipaserver/plugins/migration.py b/ipaserver/plugins/migration.py
index 7f634a7ccf8c49a4c8e0cc3fe2b2dce84b5cadff..404c4aeb08ff2ee018799af3a9224bec93c26f82 100644
--- a/ipaserver/plugins/migration.py
+++ b/ipaserver/plugins/migration.py
@@ -36,6 +36,7 @@ if api.env.in_server and api.env.context in ['lite', 'server']:
 from ipalib import _
 from ipapython.dn import DN
 from ipapython.ipautil import write_tmp_file
+from ipapython.kerberos import Principal
 import datetime
 from ipaplatform.paths import paths
 
@@ -152,6 +153,32 @@ _supported_scopes = {u'base': SCOPE_BASE, u'onelevel': SCOPE_ONELEVEL, u'subtree
 _default_scope = u'onelevel'
 
 
+def _create_kerberos_principals(ldap, pkey, entry_attrs, failed):
+    """
+    Create 'krbprincipalname' and 'krbcanonicalname' attributes for incoming
+    user entry or skip it if there already is a user with such principal name.
+    The code does not search for `krbcanonicalname` since we assume that the
+    canonical principal name is always contained among values of
+    `krbprincipalname` attribute.Both `krbprincipalname` and `krbcanonicalname`
+    are set to default value generated from uid and realm.
+
+    Note: the migration does not currently preserve principal aliases
+    """
+    principal = Principal((pkey,), realm=api.env.realm)
+    try:
+        ldap.find_entry_by_attr(
+            'krbprincipalname', principal, 'krbprincipalaux', [''],
+            DN(api.env.container_user, api.env.basedn)
+        )
+    except errors.NotFound:
+        entry_attrs['krbprincipalname'] = principal
+        entry_attrs['krbcanonicalname'] = principal
+    except errors.LimitsExceeded:
+        failed[pkey] = unicode(_krb_failed_msg % unicode(principal))
+    else:
+        failed[pkey] = unicode(_krb_err_msg % unicode(principal))
+
+
 def _pre_migrate_user(ldap, pkey, dn, entry_attrs, failed, config, ctx, **kwargs):
     assert isinstance(dn, DN)
     attr_blacklist = ['krbprincipalkey','memberofindirect','memberindirect']
@@ -217,19 +244,7 @@ def _pre_migrate_user(ldap, pkey, dn, entry_attrs, failed, config, ctx, **kwargs
             except ValueError:  # object class not present
                 pass
 
-    # generate a principal name and check if it isn't already taken
-    principal = u'%s@%s' % (pkey, api.env.realm)
-    try:
-        ldap.find_entry_by_attr(
-            'krbprincipalname', principal, 'krbprincipalaux', [''],
-            DN(api.env.container_user, api.env.basedn)
-        )
-    except errors.NotFound:
-        entry_attrs['krbprincipalname'] = principal
-    except errors.LimitsExceeded:
-        failed[pkey] = unicode(_krb_failed_msg % principal)
-    else:
-        failed[pkey] = unicode(_krb_err_msg % principal)
+    _create_kerberos_principals(ldap, pkey, entry_attrs, failed)
 
     # Fix any attributes with DN syntax that point to entries in the old
     # tree
-- 
2.7.4