krb5 commit: Fix KCM flag transmission for remove_cred

Greg Hudson <[email protected]>
Newsgroups gmane.comp.encryption.kerberos.cvs
Message-ID <[email protected]>
https://github.com/krb5/krb5/commit/11a82cf424f9c905bb73680c64524f087090d4ef
commit 11a82cf424f9c905bb73680c64524f087090d4ef
Author: Greg Hudson <[email protected]>
Date:   Mon Mar 29 14:32:56 2021 -0400

    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

 src/include/kcm.h            |   19 +++++++++++++++++++
 src/lib/krb5/ccache/cc_kcm.c |   36 +++++++++++++++++++++++++++++++++++-
 2 files changed, 54 insertions(+), 1 deletions(-)

diff --git a/src/include/kcm.h b/src/include/kcm.h
index e4140c3..9b66f1c 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 772928e..1f81a21 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);
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.