From e68890329f8ab766f9b746351b5c7d2d18d8dd48 Mon Sep 17 00:00:00 2001
From: Greg Hudson <ghudson@mit.edu>
Date: Thu, 27 Jun 2024 07:25:21 -0400
Subject: [PATCH] Change krb5_get_credentials() endtime behavior

Historically, krb5_get_credentials() uses in_creds->times.endtime both
as the TGS request endtime and as a cache lookup criterion.  These
uses are in conflict; setting a TGS request endtime can only serve to
limit the maximum lifetime of the issued ticket, while a cache lookup
endtime restricts the minimum lifetime of an acceptable cached ticket.
The likely outcome is to never use a cached ticket, leading to poor
performance as we add an entry to the cache for each request.

Change to the Heimdal behavior of using in_creds->times.endtime only
as the TGS request endtime.

ticket: 9132 (new)
---
 src/include/krb5/krb5.hin    |  8 ++++----
 src/lib/krb5/krb/get_creds.c | 13 +++++--------
 2 files changed, 9 insertions(+), 12 deletions(-)

diff --git a/src/include/krb5/krb5.hin b/src/include/krb5/krb5.hin
index 7c4fc10dd4..99b637872f 100644
--- a/src/include/krb5/krb5.hin
+++ b/src/include/krb5/krb5.hin
@@ -3043,10 +3043,10 @@ krb5_free_tgt_creds(krb5_context context, krb5_creds **tgts);
  * session key type is specified in @a in_creds->keyblock.enctype, if it is
  * nonzero.
  *
- * The expiration date is specified in @a in_creds->times.endtime.
- * The KDC may return tickets with an earlier expiration date.
- * If @a in_creds->times.endtime is set to 0, the latest possible
- * expiration date will be requested.
+ * If @a in_creds->times.endtime is specified, it is used as the requested
+ * expiration date if a TGS request is made.  If @a in_creds->times.endtime is
+ * set to 0, the latest possible expiration date will be requested.  The KDC or
+ * cache may return a ticket with an earlier expiration date.
  *
  * Any returned ticket and intermediate ticket-granting tickets are stored
  * in @a ccache.
diff --git a/src/lib/krb5/krb/get_creds.c b/src/lib/krb5/krb/get_creds.c
index e0a3b5c..9ad5276 100644
--- a/src/lib/krb5/krb/get_creds.c
+++ b/src/lib/krb5/krb/get_creds.c
@@ -53,18 +53,16 @@ krb5int_construct_matching_creds(krb5_context context, krb5_flags options,
                                  krb5_creds *in_creds, krb5_creds *mcreds,
                                  krb5_flags *fields)
 {
+    krb5_error_code ret;
+
     if (!in_creds || !in_creds->server || !in_creds->client)
         return EINVAL;
 
     memset(mcreds, 0, sizeof(krb5_creds));
     mcreds->magic = KV5M_CREDS;
-    if (in_creds->times.endtime != 0) {
-        mcreds->times.endtime = in_creds->times.endtime;
-    } else {
-        krb5_error_code retval;
-        retval = krb5_timeofday(context, &mcreds->times.endtime);
-        if (retval != 0) return retval;
-    }
+    ret = krb5_timeofday(context, &mcreds->times.endtime);
+    if (ret)
+        return ret;
     mcreds->keyblock = in_creds->keyblock;
     mcreds->authdata = in_creds->authdata;
     mcreds->server = in_creds->server;
@@ -75,7 +73,6 @@ krb5int_construct_matching_creds(krb5_context context, krb5_flags options,
         | KRB5_TC_SUPPORTED_KTYPES;
     if (mcreds->keyblock.enctype) {
         krb5_enctype *ktypes;
-        krb5_error_code ret;
         int i;
 
         *fields |= KRB5_TC_MATCH_KTYPE;
-- 
2.33.0
