[Freeipa-devel] [PATCH 149] IPA KDB: allow case in-sensitive realm in AS request
Sumit Bose
sbose at redhat.com
Tue Jul 21 11:41:14 UTC 2015
Hi,
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 at IPA.REALM -> success
kinit -C ipauser at IPA.REALM -> success
kinit ipauser at ipa.realm -> failure
kinit -C ipauser at ipa.realm -> failure
With the patch
kinit ipauser at IPA.REALM -> success
kinit -C ipauser at IPA.REALM -> success
kinit ipauser at ipa.realm -> success
kinit -C ipauser at ipa.realm -> success
where 'ipa.realm' can be replace by mixed case version like 'iPa.ReAlM'
as well.
bye,
Sumit
[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.
-------------- next part --------------
From 39744160f1779cf8e5ff00531b432c88fc53200b Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose at 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 b/daemons/ipa-kdb/ipa_kdb_principals.c
index b3f8b1ad7784f55f55b4d6edd05f778a9389de27..344d44fb9b20f74615993a561b8b39f34f57cf25 100644
--- 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 kcontext,
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);
--
2.1.0
More information about the Freeipa-devel
mailing list