File 0001-cifs-utils-Skip-TGT-check-if-valid-service-ticket-is.patch of Package cifs-utils.41102

From af76bf2a11a060afdfd97104617a701d19d5890d Mon Sep 17 00:00:00 2001
From: Bharath SM <bharathsm@microsoft.com>
Date: Tue, 26 Nov 2024 22:57:44 +0530
Subject: [PATCH] cifs-utils: Skip TGT check if valid service ticket is already
 available

When handling upcalls from the kernel for SMB session setup requests using
Kerberos authentication, if the credential cache already contains a valid
service ticket, it can be used directly without checking for the TGT again.

Signed-off-by: Bharath SM <bharathsm@microsoft.com>
Reviewed-by: Shyam Prasad N <sprasad@microsoft.com>
Acked-by: Alexander Bokovoy <ab@samba.org>
Signed-off-by: Steve French <stfrench@microsoft.com>
Signed-off-by: Henrique Carvalho <henrique.carvalho@suse.com>
---
 cifs.upcall.c |   67 +++++++++++++++++++++++++++++++++++++++++++++++++++-------
 1 file changed, 60 insertions(+), 7 deletions(-)

--- a/cifs.upcall.c
+++ b/cifs.upcall.c
@@ -536,11 +536,6 @@
 		syslog(LOG_DEBUG, "%s: default ccache is %s\n", __func__, cachename);
 		krb5_free_string(context, cachename);
 	}
-
-	if (!get_tgt_time(cc)) {
-		krb5_cc_close(context, cc);
-		cc = NULL;
-	}
 	return cc;
 }
 
@@ -620,6 +615,51 @@
 	goto out;
 }
 
+#define CIFS_SERVICE_NAME "cifs"
+
+static krb5_error_code check_service_ticket_exists(krb5_ccache ccache,
+		const char *hostname) {
+
+	krb5_error_code rc;
+	krb5_creds mcreds, out_creds;
+
+	memset(&mcreds, 0, sizeof(mcreds));
+
+	rc = krb5_cc_get_principal(context, ccache, &mcreds.client);
+	if (rc) {
+		syslog(LOG_DEBUG, "%s: unable to get client principal from cache: %s",
+					__func__, krb5_get_error_message(context, rc));
+		return rc;
+	}
+
+	rc = krb5_sname_to_principal(context, hostname, CIFS_SERVICE_NAME,
+			KRB5_NT_UNKNOWN, &mcreds.server);
+	if (rc) {
+		syslog(LOG_DEBUG, "%s: unable to convert service name (%s) to principal: %s",
+					__func__, hostname, krb5_get_error_message(context, rc));
+		krb5_free_principal(context, mcreds.client);
+		return rc;
+	}
+
+	rc = krb5_timeofday(context, &mcreds.times.endtime);
+	if (rc) {
+		syslog(LOG_DEBUG, "%s: unable to get time: %s",
+			__func__, krb5_get_error_message(context, rc));
+		goto out_free_principal;
+	}
+
+	rc = krb5_cc_retrieve_cred(context, ccache, KRB5_TC_MATCH_TIMES, &mcreds, &out_creds);
+
+	if (!rc)
+		krb5_free_cred_contents(context, &out_creds);
+
+out_free_principal:
+	krb5_free_principal(context, mcreds.server);
+	krb5_free_principal(context, mcreds.client);
+
+	return rc;
+}
+
 static int
 cifs_krb5_get_req(const char *host, krb5_ccache ccache,
 		  DATA_BLOB * mechtoken, DATA_BLOB * sess_key)
@@ -1365,7 +1405,22 @@
 		goto out;
 	}
 
+        host = arg->hostname;
 	ccache = get_existing_cc(env_cachename);
+	if (ccache != NULL) {
+		rc = check_service_ticket_exists(ccache, host);
+		if(rc == 0) {
+			 syslog(LOG_DEBUG, "%s: valid service ticket exists in credential cache",
+					 __func__);
+		} else {
+			 if (!get_tgt_time(ccache)) {
+				syslog(LOG_DEBUG, "%s: valid TGT is not present in credential cache",
+						__func__);
+				krb5_cc_close(context, ccache);
+				ccache = NULL;
+			}
+		}
+	}
 	/* Couldn't find credcache? Try to use keytab */
 	if (ccache == NULL && arg->username[0] != '\0')
 		ccache = init_cc_from_keytab(keytab_name, arg->username);
@@ -1375,8 +1430,6 @@
 		goto out;
 	}
 
-	host = arg->hostname;
-
 	// do mech specific authorization
 	switch (arg->sec) {
 	case MS_KRB5:
openSUSE Build Service is sponsored by