You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
97 lines
4.2 KiB
97 lines
4.2 KiB
From 8f70ad82a645ccb7fb1677d260baa5e4112890d4 Mon Sep 17 00:00:00 2001 |
|
From: Greg Hudson <ghudson@mit.edu> |
|
Date: Mon, 7 Jun 2021 13:27:29 -0400 |
|
Subject: [PATCH] Fix some principal realm canonicalization cases |
|
|
|
The no_hostrealm and subst_defrealm flags in struct canonprinc were |
|
only applied when dns_canonicalize_hostname=fallback; in the other |
|
cases, the initial krb5_sname_to_principal() result is treated as |
|
canonical. For no_hostrealm this limitation doesn't currently matter, |
|
because all uses pass a principal with no realm as input. However, |
|
subst_defrealm is used to convert the referral realm to the default |
|
realm in krb5_get_init_creds_keytab(), krb5_cc_cache_match(), and |
|
gss_acquire_cred() when it needs to check the desired name against a |
|
specified ccache. |
|
|
|
In k5_canonprinc(), if the input principal is a |
|
krb5_sname_to_principal() result and fallback isn't in effect, apply |
|
subst_defrealm. Document in os-proto.h that no_hostrealm doesn't |
|
remove an existing realm and that krb5_sname_to_principal() may |
|
already have looked one up. |
|
|
|
ticket: 9011 (new) |
|
(cherry picked from commit c077d0c6430c4ac163443aacc03d14d206a4cbb8) |
|
(cherry picked from commit 5ae9bc98f23aeaa2ce17debe5a9b0cf1130e54ed) |
|
--- |
|
src/lib/krb5/os/os-proto.h | 13 +++++++++---- |
|
src/lib/krb5/os/sn2princ.c | 24 +++++++++++++++++++++--- |
|
2 files changed, 30 insertions(+), 7 deletions(-) |
|
|
|
diff --git a/src/lib/krb5/os/os-proto.h b/src/lib/krb5/os/os-proto.h |
|
index 7d5e7978f..a985f2aec 100644 |
|
--- a/src/lib/krb5/os/os-proto.h |
|
+++ b/src/lib/krb5/os/os-proto.h |
|
@@ -85,10 +85,15 @@ struct sendto_callback_info { |
|
|
|
/* |
|
* Initialize with all zeros except for princ. Set no_hostrealm to disable |
|
- * host-to-realm lookup, which ordinarily happens after canonicalizing the host |
|
- * part. Set subst_defrealm to substitute the default realm for the referral |
|
- * realm after realm lookup (this has no effect if no_hostrealm is set). Free |
|
- * with free_canonprinc() when done. |
|
+ * host-to-realm lookup, which ordinarily happens during fallback processing |
|
+ * after canonicalizing the host part. Set subst_defrealm to substitute the |
|
+ * default realm for the referral realm after realm lookup. Do not set both |
|
+ * flags. Free with free_canonprinc() when done. |
|
+ * |
|
+ * no_hostrealm only applies if fallback processing is in use |
|
+ * (dns_canonicalize_hostname = fallback). It will not remove the realm if |
|
+ * krb5_sname_to_principal() already canonicalized the hostname and looked up a |
|
+ * realm. subst_defrealm applies whether or not fallback processing is in use. |
|
*/ |
|
struct canonprinc { |
|
krb5_const_principal princ; |
|
diff --git a/src/lib/krb5/os/sn2princ.c b/src/lib/krb5/os/sn2princ.c |
|
index c99b7da17..93c155932 100644 |
|
--- a/src/lib/krb5/os/sn2princ.c |
|
+++ b/src/lib/krb5/os/sn2princ.c |
|
@@ -271,18 +271,36 @@ krb5_error_code |
|
k5_canonprinc(krb5_context context, struct canonprinc *iter, |
|
krb5_const_principal *princ_out) |
|
{ |
|
+ krb5_error_code ret; |
|
int step = ++iter->step; |
|
|
|
*princ_out = NULL; |
|
|
|
- /* If we're not doing fallback, the input principal is canonical. */ |
|
- if (context->dns_canonicalize_hostname != CANONHOST_FALLBACK || |
|
- iter->princ->type != KRB5_NT_SRV_HST || iter->princ->length != 2 || |
|
+ /* If the hostname isn't from krb5_sname_to_principal(), the input |
|
+ * principal is canonical. */ |
|
+ if (iter->princ->type != KRB5_NT_SRV_HST || iter->princ->length != 2 || |
|
iter->princ->data[1].length == 0) { |
|
*princ_out = (step == 1) ? iter->princ : NULL; |
|
return 0; |
|
} |
|
|
|
+ /* If we're not doing fallback, the hostname is canonical, but we may need |
|
+ * to substitute the default realm. */ |
|
+ if (context->dns_canonicalize_hostname != CANONHOST_FALLBACK) { |
|
+ if (step > 1) |
|
+ return 0; |
|
+ iter->copy = *iter->princ; |
|
+ if (iter->subst_defrealm && iter->copy.realm.length == 0) { |
|
+ ret = krb5_get_default_realm(context, &iter->realm); |
|
+ if (ret) |
|
+ return ret; |
|
+ iter->copy = *iter->princ; |
|
+ iter->copy.realm = string2data(iter->realm); |
|
+ } |
|
+ *princ_out = &iter->copy; |
|
+ return 0; |
|
+ } |
|
+ |
|
/* Canonicalize without DNS at step 1, with DNS at step 2. */ |
|
if (step > 2) |
|
return 0;
|
|
|