this patch is my suggestion to solve
https://fedorahosted.org/freeipa/ticket/4844 .

The original issue in the ticket has two part. One is a loop in libkrb5
which is already fixed. The other is to handle canonicalization better.

The general way to allow canonicalization on a principal is to add the
attributes 'krbcanonicalname'[1] and 'ipakrbprincipalalias' together
with the objectclass 'ipaKrbPrincipal' to the user object. Then the IPA
KDB backend will use 'ipakrbprincipalalias' for case in-sensitive
matches and  the principal from 'krbcanonicalname' will be the canonical
principal used further on. The 'krbPrincipalName' is not suitable for
either because it has caseExact* matching rules and is a multivalue
attribute [2].

What I got from the comments in the ticket and the related bugzilla
ticket is that it should be possible to get a TGT for a user even if the
realm is given in lower-case if canonicalization is enabled. Please note
that the client can only send such request because we have
'dns_lookup_kdc = true' in krb.conf and DNS is case in-sensitive. If you
set 'dns_lookup_kdc = false' the client will fail immediately without
sending a request at all, because it is not able to find a KDC for the
lower-case realm.

On the server-side the request is processed because of
http://k5wiki.kerberos.org/wiki/Projects/Aliases which made parts of
processing case in-sensitive.

With the attached patch a second lookup is done if the lookup with the
original input returned no result, canonicalization is
enabled and the realm from the original input matches the IPA realm case
in-sensitive. For the second lookup the realm is replace with the IPA
realm. This approach adds a bit redundant code but does not add extra
processing requests which would be successful before.

Without the patch
kinit    ipauser@IPA.REALM -> success
kinit -C ipauser@IPA.REALM -> success
kinit    ipauser@ipa.realm -> failure
kinit -C ipauser@ipa.realm -> failure

With the patch
kinit    ipauser@IPA.REALM -> success
kinit -C ipauser@IPA.REALM -> success
kinit    ipauser@ipa.realm -> success
kinit -C ipauser@ipa.realm -> success

where 'ipa.realm' can be replace by mixed case version like 'iPa.ReAlM'
as well.


[1] I was not able to add 'krbcanonicalname' as admin user because of an
ACI denial. I wonder if this is expected or if the ACI rules should be
extended here?

[2] We might to skip the requirement that 'krbcanonicalname' must exists
if 'ipaKrbPrincipal' only has a single value but canonicalization will
fail immediately if someone adds a second value so I guess it would be
more safe to keep it as it is.

From 39744160f1779cf8e5ff00531b432c88fc53200b Mon Sep 17 00:00:00 2001
From: Sumit Bose <sb...@redhat.com>
Date: Tue, 21 Jul 2015 12:12:56 +0200
Subject: [PATCH] IPA KDB: allow case in-sensitive realm in AS request

If the canonicalization flag is set the realm of the client principal in
an AS request (kinit) may only match case in-sensitive.

Resolves https://fedorahosted.org/freeipa/ticket/4844
 daemons/ipa-kdb/ipa_kdb_principals.c | 31 ++++++++++++++++++++++++++++++-
 1 file changed, 30 insertions(+), 1 deletion(-)

diff --git a/daemons/ipa-kdb/ipa_kdb_principals.c 
--- a/daemons/ipa-kdb/ipa_kdb_principals.c
+++ b/daemons/ipa-kdb/ipa_kdb_principals.c
@@ -1026,6 +1026,8 @@ krb5_error_code ipadb_get_principal(krb5_context kcontext,
     LDAPMessage *res = NULL;
     LDAPMessage *lentry;
     uint32_t pol;
+    size_t realm_len;
+    char *p;
     ipactx = ipadb_get_context(kcontext);
     if (!ipactx) {
@@ -1044,7 +1046,34 @@ krb5_error_code ipadb_get_principal(krb5_context 
     kerr = ipadb_find_principal(kcontext, flags, res, &principal, &lentry);
     if (kerr != 0) {
-        goto done;
+        realm_len = strlen(ipactx->realm);
+        /* If canonicalization is enabled and the realm only differs in case
+         * from the IPA realm retry with the correct case. */
+        if (kerr == KRB5_KDB_NOENTRY
+                && (flags & KRB5_KDB_FLAG_ALIAS_OK) != 0
+                && krb5_princ_realm(kcontext, search_for)->length == realm_len
+                && strncasecmp(krb5_princ_realm(kcontext,search_for)->data,
+                               ipactx->realm, realm_len) == 0) {
+            p = strchr(principal, '@');
+            if (p == NULL || *(++p + realm_len) != '\0') {
+                goto done;
+            }
+            memcpy(p, ipactx->realm, realm_len);
+            kerr = ipadb_fetch_principals(ipactx, flags, principal, &res);
+            if (kerr != 0) {
+                goto done;
+            }
+            kerr = ipadb_find_principal(kcontext, flags, res, &principal,
+                                        &lentry);
+            if (kerr != 0) {
+                goto done;
+            }
+        } else {
+            goto done;
+        }
     kerr = ipadb_parse_ldap_entry(kcontext, principal, lentry, entry, &pol);

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

Reply via email to