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: