From 0ccd87f413d3452afe8bb53a10a4b76a6ed1ba53 Mon Sep 17 00:00:00 2001 From: Ian Kent Date: Tue, 13 May 2025 12:29:57 +0800 Subject: [PATCH] - Add fix for Jira RHEL-85615. --- ...1.8-always-recreate-credential-cache.patch | 132 ++++++++++++++++++ ...fix-always-recreate-credential-cache.patch | 36 +++++ autofs.spec | 14 +- 3 files changed, 181 insertions(+), 1 deletion(-) create mode 100644 autofs-5.1.8-always-recreate-credential-cache.patch create mode 100644 autofs-5.1.9-fix-always-recreate-credential-cache.patch diff --git a/autofs-5.1.8-always-recreate-credential-cache.patch b/autofs-5.1.8-always-recreate-credential-cache.patch new file mode 100644 index 0000000..eda7b44 --- /dev/null +++ b/autofs-5.1.8-always-recreate-credential-cache.patch @@ -0,0 +1,132 @@ +autofs-5.1.8 - always recreate credential cache + +From: Ian Collier + +In recent Kerberos revisions when a TGT expires autofs will fail to +renew the ticket. + +Expired creds are being pulled out of the cache and in that case the patched +version clears the cache to remove the expired creds. + +If the cache is already in use, try to pull out a cred and then if that +was successful and the cred is expired, clear the cache. + +So this fixes the behaviour I was seeing, since that was happening because +expired creds were being pulled out of the cache and in that case the patched +version clears the cache to remove the expired creds. + +What sort of race conditions might happen here? + + - If the function is called very late during the validity of a ticket, it + might expire after the decision not to clear the cache. In that case, + the behaviour is the same as the unpatched version, but this is highly + unlikely because do_kinit is not supposed to happen while there is a + valid ticket. + + - If two or more threads decide to call do_kinit at about the same time: + it's protected by a mutex, so one of the calls will happen first; this + call will clear the cache and add a new ticket. When the others kick + in, the cache won't be cleared because it's only cleared if we can + find an expired ticket in the cache and any such ticket was removed + when the first do_kinit happened. + + - If one thread does do_kinit while another thread is trying to do a lookup: + if the current ticket is expired then the lookup would have failed anyway; + if it's not expired then we won't clear the cache. + + - If there is both an expired and a valid ticket in the cache: + this only happens if two or more do_kinits clashed and stored tickets + with different expiration times, and if the current time is between those + times. The current bug happens because krb5 cache retrieval is returning + the earliest (i.e. expired) ticket. When that's the case then do_kinit + will clear the cache because when it tests the cache it will pull the + expired cred - and it needs to do this because otherwise all lookups are + failing (that's the bug). In a case where krb5 cache retrieval returns + the valid ticket, it doesn't matter that the cache is not cleared because + any subsequent lookups will use that valid ticket. + +Signed-off-by: Ian Collier +--- + CHANGELOG | 1 + modules/cyrus-sasl.c | 53 +++++++++++++++++++++++++++++++++++++++------------ + 2 files changed, 42 insertions(+), 12 deletions(-) + +--- autofs-5.1.7.orig/CHANGELOG ++++ autofs-5.1.7/CHANGELOG +@@ -184,6 +184,7 @@ + - Fix incompatible function pointer types in cyrus-sasl module. + - fix handling of ignored offsets. + - fix invalidated map entry handling in hosts module. ++- always recreate credential cache. + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +--- autofs-5.1.7.orig/modules/cyrus-sasl.c ++++ autofs-5.1.7/modules/cyrus-sasl.c +@@ -509,6 +509,46 @@ sasl_do_kinit(unsigned logopt, struct lo + debug(logopt, "Using tgs name %s", tgs_name); + + memset(&my_creds, 0, sizeof(my_creds)); ++ ++ if (krb5cc_in_use++ == 0) { ++ /* tell the cache what the default principal is */ ++ ret = krb5_cc_initialize(ctxt->krb5ctxt, ++ ctxt->krb5_ccache, krb5_client_princ); ++ ++ if (ret) { ++ --krb5cc_in_use; ++ error(logopt, ++ "krb5_cc_initialize failed with error %d", ret); ++ goto out_cleanup_unparse; ++ } ++ } ++ else { ++ krb5_creds match_creds, out_creds; ++ time_t now = monotonic_time(NULL); ++ ++ /* even if the cache is in use, we will clear it if it ++ * contains an expired credential for our principal, ++ * because Kerberos doesn't always work well with caches ++ * that contain both expired and valid credentials ++ */ ++ memset(&match_creds, 0, sizeof match_creds); ++ match_creds.client = krb5_client_princ; ++ match_creds.server = tgs_princ; ++ ret = krb5_cc_retrieve_cred(ctxt->krb5ctxt, ctxt->krb5_ccache, ++ 0, &match_creds, &out_creds); ++ if (ret == 0 && (time_t) out_creds.times.endtime < now) { ++ debug(logopt, ++ "calling krb5_cc_initialize to clear expired tickets"); ++ ret = krb5_cc_initialize(ctxt->krb5ctxt, ++ ctxt->krb5_ccache, krb5_client_princ); ++ if (ret) ++ warn(logopt, ++ "krb5_cc_initialize failed with error %d " ++ "while trying to clear existing cache", ++ ret); ++ } ++ } ++ + ret = krb5_get_init_creds_keytab(ctxt->krb5ctxt, &my_creds, + krb5_client_princ, + NULL /*keytab*/, +@@ -521,18 +561,7 @@ sasl_do_kinit(unsigned logopt, struct lo + goto out_cleanup_unparse; + } + +- if (krb5cc_in_use++ == 0) +- /* tell the cache what the default principal is */ +- ret = krb5_cc_initialize(ctxt->krb5ctxt, +- ctxt->krb5_ccache, krb5_client_princ); +- +- if (ret) { +- error(logopt, +- "krb5_cc_initialize failed with error %d", ret); +- goto out_cleanup_creds; +- } +- +- /* and store credentials for that principal */ ++ /* and store credentials for our principal */ + ret = krb5_cc_store_cred(ctxt->krb5ctxt, ctxt->krb5_ccache, &my_creds); + if (ret) { + error(logopt, diff --git a/autofs-5.1.9-fix-always-recreate-credential-cache.patch b/autofs-5.1.9-fix-always-recreate-credential-cache.patch new file mode 100644 index 0000000..291eb1b --- /dev/null +++ b/autofs-5.1.9-fix-always-recreate-credential-cache.patch @@ -0,0 +1,36 @@ +autofs-5.1.9 - fix always recreate credential cache + +From: Ian Kent + +When I aplied the original patch from Ian Collier for this I changed +the credential end time comparison to be against the time returned from +monotomic_time(). But this isn't the same as the calander time returned +from time() which Ian used in his original patch. + +Signed-off-by: Ian Kent < raven@themaw.net> +--- + CHANGELOG | 1 + + modules/cyrus-sasl.c | 2 +- + 2 files changed, 2 insertions(+), 1 deletion(-) + +--- autofs-5.1.7.orig/CHANGELOG ++++ autofs-5.1.7/CHANGELOG +@@ -185,6 +185,7 @@ + - fix handling of ignored offsets. + - fix invalidated map entry handling in hosts module. + - always recreate credential cache. ++- fix always recreate credential cache. + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +--- autofs-5.1.7.orig/modules/cyrus-sasl.c ++++ autofs-5.1.7/modules/cyrus-sasl.c +@@ -524,7 +524,7 @@ sasl_do_kinit(unsigned logopt, struct lo + } + else { + krb5_creds match_creds, out_creds; +- time_t now = monotonic_time(NULL); ++ time_t now = time(NULL); + + /* even if the cache is in use, we will clear it if it + * contains an expired credential for our principal, diff --git a/autofs.spec b/autofs.spec index ce3ddb6..206d4f9 100644 --- a/autofs.spec +++ b/autofs.spec @@ -12,7 +12,7 @@ Summary: A tool for automatically mounting and unmounting filesystems Name: autofs Version: 5.1.7 -Release: 64%{?dist} +Release: 65%{?dist} Epoch: 1 License: GPLv2+ Source: https://www.kernel.org/pub/linux/daemons/autofs/v5/autofs-%{version}-2.tar.gz @@ -229,6 +229,10 @@ Patch209: autofs-5.1.9-Fix-incompatible-function-pointer-types-in-cyrus-sasl-mod Patch210: autofs-5.1.9-fix-handling-of-ignored-offsets.patch Patch211: autofs-5.1.9-fix-invalidated-map-entry-handling-in-hosts-module.patch +#JIRA: RHEL-85615 +Patch212: autofs-5.1.8-always-recreate-credential-cache.patch +Patch213: autofs-5.1.9-fix-always-recreate-credential-cache.patch + %if %{with_systemd} BuildRequires: systemd-units BuildRequires: systemd-devel @@ -489,6 +493,8 @@ echo %{version}-%{release} > .version %patch -P 209 -p1 %patch -P 210 -p1 %patch -P 211 -p1 +%patch -P 212 -p1 +%patch -P 213 -p1 %build LDFLAGS=-Wl,-z,now @@ -597,6 +603,12 @@ fi %dir /etc/auto.master.d %changelog +* Tue May 13 2025 Ian Kent - 1:5.1.7-65 +- RHEL-85615 - autofs fails to mount shares when using kerberised LDAP + - always recreate credential cache. + - fix always recreate credential cache. +-Resolves: RHEL-85615 + * Wed May 07 2025 Ian Kent - 1:5.1.7-64 - RHEL-81885 - autofs: segfault while dereferencing null mapent - fix handling of ignored offsets.