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.
104 lines
4.2 KiB
104 lines
4.2 KiB
From 92a4b760d741494dacbb4d9db4cf2db9e3b01f2c Mon Sep 17 00:00:00 2001 |
|
From: Greg Hudson <ghudson@mit.edu> |
|
Date: Mon, 29 Mar 2021 14:32:56 -0400 |
|
Subject: [PATCH] Fix KCM flag transmission for remove_cred |
|
|
|
MIT krb5 uses low bits for KRB5_TC flags, while Heimdal uses high bits |
|
so that the same flag word can also hold KRB5_GC flags. Add a mapping |
|
function and send the Heimdal flag values when performing a |
|
remove_cred operation. |
|
|
|
ticket: 8995 |
|
(cherry picked from commit 11a82cf424f9c905bb73680c64524f087090d4ef) |
|
(cherry picked from commit 04f0de4420508161ce439f262f2761ff51a07ab0) |
|
--- |
|
src/include/kcm.h | 19 +++++++++++++++++++ |
|
src/lib/krb5/ccache/cc_kcm.c | 36 +++++++++++++++++++++++++++++++++++- |
|
2 files changed, 54 insertions(+), 1 deletion(-) |
|
|
|
diff --git a/src/include/kcm.h b/src/include/kcm.h |
|
index e4140c3a0..9b66f1cbd 100644 |
|
--- a/src/include/kcm.h |
|
+++ b/src/include/kcm.h |
|
@@ -56,8 +56,27 @@ |
|
* are marshalled as zero-terminated strings. Principals and credentials are |
|
* marshalled in the v4 FILE ccache format. UUIDs are 16 bytes. UUID lists |
|
* are not delimited, so nothing can come after them. |
|
+ * |
|
+ * Flag words must use Heimdal flag values, which are not the same as MIT krb5 |
|
+ * values for KRB5_GC and KRB5_TC constants. The same flag word may contain |
|
+ * both kinds of flags in Heimdal, but not in MIT krb5. Defines for the |
|
+ * applicable Heimdal flag values are given below using KCM_GC and KCM_TC |
|
+ * prefixes. |
|
*/ |
|
|
|
+#define KCM_GC_CACHED (1U << 0) |
|
+ |
|
+#define KCM_TC_DONT_MATCH_REALM (1U << 31) |
|
+#define KCM_TC_MATCH_KEYTYPE (1U << 30) |
|
+#define KCM_TC_MATCH_SRV_NAMEONLY (1U << 29) |
|
+#define KCM_TC_MATCH_FLAGS_EXACT (1U << 28) |
|
+#define KCM_TC_MATCH_FLAGS (1U << 27) |
|
+#define KCM_TC_MATCH_TIMES_EXACT (1U << 26) |
|
+#define KCM_TC_MATCH_TIMES (1U << 25) |
|
+#define KCM_TC_MATCH_AUTHDATA (1U << 24) |
|
+#define KCM_TC_MATCH_2ND_TKT (1U << 23) |
|
+#define KCM_TC_MATCH_IS_SKEY (1U << 22) |
|
+ |
|
/* Opcodes without comments are currently unused in the MIT client |
|
* implementation. */ |
|
typedef enum kcm_opcode { |
|
diff --git a/src/lib/krb5/ccache/cc_kcm.c b/src/lib/krb5/ccache/cc_kcm.c |
|
index 772928e4d..1f81a2190 100644 |
|
--- a/src/lib/krb5/ccache/cc_kcm.c |
|
+++ b/src/lib/krb5/ccache/cc_kcm.c |
|
@@ -110,6 +110,40 @@ map_invalid(krb5_error_code code) |
|
KRB5_KCM_MALFORMED_REPLY : code; |
|
} |
|
|
|
+/* |
|
+ * Map an MIT krb5 KRB5_TC flag word to the equivalent Heimdal flag word. Note |
|
+ * that there is no MIT krb5 equivalent for Heimdal's KRB5_TC_DONT_MATCH_REALM |
|
+ * (which is like KRB5_TC_MATCH_SRV_NAMEONLY but also applies to the client |
|
+ * principal) and no Heimdal equivalent for MIT krb5's KRB5_TC_SUPPORTED_KTYPES |
|
+ * (which matches against enctypes from the krb5_context rather than the |
|
+ * matching cred). |
|
+ */ |
|
+static inline krb5_flags |
|
+map_tcflags(krb5_flags mitflags) |
|
+{ |
|
+ krb5_flags heimflags = 0; |
|
+ |
|
+ if (mitflags & KRB5_TC_MATCH_TIMES) |
|
+ heimflags |= KCM_TC_MATCH_TIMES; |
|
+ if (mitflags & KRB5_TC_MATCH_IS_SKEY) |
|
+ heimflags |= KCM_TC_MATCH_IS_SKEY; |
|
+ if (mitflags & KRB5_TC_MATCH_FLAGS) |
|
+ heimflags |= KCM_TC_MATCH_FLAGS; |
|
+ if (mitflags & KRB5_TC_MATCH_TIMES_EXACT) |
|
+ heimflags |= KCM_TC_MATCH_TIMES_EXACT; |
|
+ if (mitflags & KRB5_TC_MATCH_FLAGS_EXACT) |
|
+ heimflags |= KCM_TC_MATCH_FLAGS_EXACT; |
|
+ if (mitflags & KRB5_TC_MATCH_AUTHDATA) |
|
+ heimflags |= KCM_TC_MATCH_AUTHDATA; |
|
+ if (mitflags & KRB5_TC_MATCH_SRV_NAMEONLY) |
|
+ heimflags |= KCM_TC_MATCH_SRV_NAMEONLY; |
|
+ if (mitflags & KRB5_TC_MATCH_2ND_TKT) |
|
+ heimflags |= KCM_TC_MATCH_2ND_TKT; |
|
+ if (mitflags & KRB5_TC_MATCH_KTYPE) |
|
+ heimflags |= KCM_TC_MATCH_KEYTYPE; |
|
+ return heimflags; |
|
+} |
|
+ |
|
/* Begin a request for the given opcode. If cache is non-null, supply the |
|
* cache name as a request parameter. */ |
|
static void |
|
@@ -936,7 +970,7 @@ kcm_remove_cred(krb5_context context, krb5_ccache cache, krb5_flags flags, |
|
struct kcmreq req; |
|
|
|
kcmreq_init(&req, KCM_OP_REMOVE_CRED, cache); |
|
- k5_buf_add_uint32_be(&req.reqbuf, flags); |
|
+ k5_buf_add_uint32_be(&req.reqbuf, map_tcflags(flags)); |
|
k5_marshal_mcred(&req.reqbuf, mcred); |
|
ret = cache_call(context, cache, &req); |
|
kcmreq_free(&req);
|
|
|