09606e
From c6847f012b326a7e27dbe79d8df0faafdeb2dbef Mon Sep 17 00:00:00 2001
09606e
From: Scott Mayhew <smayhew@redhat.com>
09606e
Date: Thu, 2 Sep 2021 12:44:27 -0400
09606e
Subject: [PATCH] Add an option for minimum lifetime
09606e
09606e
It's possible for gssproxy to return a cached credential with a very
09606e
small remaining lifetime.  This can be problematic for NFS clients since
09606e
it requires a round trip to the NFS server to establish a GSS context.
09606e
Add a min_lifetime option that represents the lowest value that the
09606e
lifetime of the cached credential can be.  Any lower than that, and
09606e
gp_check_cred() returns GSS_S_CREDENTIALS_EXPIRED, so that
09606e
gp_add_krb5_creds() is forced to try to obtain a new credential.
09606e
09606e
Signed-off-by: Scott Mayhew <smayhew@redhat.com>
09606e
[antorres@redhat.com: adjusted lines number for man diff]
09606e
---
09606e
 examples/99-nfs-client.conf.in |  1 +
09606e
 man/gssproxy.conf.5.xml        | 15 +++++++++++++++
09606e
 src/gp_config.c                | 12 ++++++++++++
09606e
 src/gp_creds.c                 | 12 ++++++++++--
09606e
 src/gp_proxy.h                 |  1 +
09606e
 5 files changed, 39 insertions(+), 2 deletions(-)
09606e
09606e
diff --git a/examples/99-nfs-client.conf.in b/examples/99-nfs-client.conf.in
09606e
index c0985d9..9dd1891 100644
09606e
--- a/examples/99-nfs-client.conf.in
09606e
+++ b/examples/99-nfs-client.conf.in
09606e
@@ -7,3 +7,4 @@
09606e
   allow_any_uid = yes
09606e
   trusted = yes
09606e
   euid = 0
09606e
+  min_lifetime = 60
09606e
diff --git a/man/gssproxy.conf.5.xml b/man/gssproxy.conf.5.xml
09606e
index de846b4..af6ca18 100644
09606e
--- a/man/gssproxy.conf.5.xml
09606e
+++ b/man/gssproxy.conf.5.xml
09606e
@@ -348,6 +348,21 @@
09606e
                     </listitem>
09606e
                     </varlistentry>
09606e
 
09606e
+                <varlistentry>
09606e
+                    <term>min_lifetime (integer)</term>
09606e
+                    <listitem>
09606e
+                        <para>Minimum lifetime of a cached credential, in seconds.</para>
09606e
+                        <para>If non-zero, when gssproxy is deciding whether to use
09606e
+                            a cached credential, it will compare the lifetime of the
09606e
+                            cached credential to this value.  If the lifetime of the
09606e
+                            cached credential is lower, gssproxy will treat the cached
09606e
+                            credential as expired and will attempt to obtain a new
09606e
+                            credential.
09606e
+                        </para>
09606e
+                        <para>Default: min_lifetime = 15</para>
09606e
+                    </listitem>
09606e
+                </varlistentry>
09606e
+
09606e
                 <varlistentry>
09606e
                     <term>program (string)</term>
09606e
                     <listitem>
09606e
diff --git a/src/gp_config.c b/src/gp_config.c
09606e
index 4cda579..a0afa73 100644
09606e
--- a/src/gp_config.c
09606e
+++ b/src/gp_config.c
09606e
@@ -32,6 +32,7 @@ struct gp_flag_def flag_names[] = {
09606e
 
09606e
 #define DEFAULT_FILTERED_FLAGS GSS_C_DELEG_FLAG
09606e
 #define DEFAULT_ENFORCED_FLAGS 0
09606e
+#define DEFAULT_MIN_LIFETIME 15
09606e
 
09606e
 static void free_str_array(const char ***a, int *count)
09606e
 {
09606e
@@ -538,6 +539,17 @@ static int load_services(struct gp_config *cfg, struct gp_ini_context *ctx)
09606e
                     goto done;
09606e
                 }
09606e
             }
09606e
+
09606e
+            cfg->svcs[n]->min_lifetime = DEFAULT_MIN_LIFETIME;
09606e
+            ret = gp_config_get_int(ctx, secname, "min_lifetime", &valnum);
09606e
+            if (ret == 0) {
09606e
+                if (valnum >= 0) {
09606e
+                    cfg->svcs[n]->min_lifetime = valnum;
09606e
+                } else {
09606e
+                    GPDEBUG("Invalid value '%d' for min_lifetime in [%s], ignoring.\n",
09606e
+                            valnum, secname);
09606e
+                }
09606e
+            }
09606e
         }
09606e
         safefree(secname);
09606e
     }
09606e
diff --git a/src/gp_creds.c b/src/gp_creds.c
09606e
index 92a6f13..843d1a3 100644
09606e
--- a/src/gp_creds.c
09606e
+++ b/src/gp_creds.c
09606e
@@ -492,6 +492,7 @@ done:
09606e
 }
09606e
 
09606e
 static uint32_t gp_check_cred(uint32_t *min,
09606e
+                              struct gp_service *svc,
09606e
                               gss_cred_id_t in_cred,
09606e
                               gssx_name *desired_name,
09606e
                               gss_cred_usage_t cred_usage)
09606e
@@ -563,7 +564,14 @@ static uint32_t gp_check_cred(uint32_t *min,
09606e
     if (lifetime == 0) {
09606e
         ret_maj = GSS_S_CREDENTIALS_EXPIRED;
09606e
     } else {
09606e
-        ret_maj = GSS_S_COMPLETE;
09606e
+        if (svc->min_lifetime && lifetime < svc->min_lifetime) {
09606e
+            GPDEBUG("%s: lifetime (%u) less than min_lifetime (%u) "
09606e
+                    "for service \"%s\" - returning\n",
09606e
+                    __func__, lifetime, svc->min_lifetime, svc->name);
09606e
+            ret_maj = GSS_S_CREDENTIALS_EXPIRED;
09606e
+        } else {
09606e
+            ret_maj = GSS_S_COMPLETE;
09606e
+        }
09606e
     }
09606e
 
09606e
 done:
09606e
@@ -622,7 +630,7 @@ uint32_t gp_add_krb5_creds(uint32_t *min,
09606e
          * function completely */
09606e
 
09606e
         /* just check if it is a valid krb5 cred */
09606e
-        ret_maj = gp_check_cred(&ret_min, in_cred, desired_name, cred_usage);
09606e
+        ret_maj = gp_check_cred(&ret_min, gpcall->service, in_cred, desired_name, cred_usage);
09606e
         if (ret_maj == GSS_S_COMPLETE) {
09606e
             return GSS_S_COMPLETE;
09606e
         } else if (ret_maj == GSS_S_CREDENTIALS_EXPIRED ||
09606e
diff --git a/src/gp_proxy.h b/src/gp_proxy.h
09606e
index 3f58a43..f56d640 100644
09606e
--- a/src/gp_proxy.h
09606e
+++ b/src/gp_proxy.h
09606e
@@ -45,6 +45,7 @@ struct gp_service {
09606e
     gss_cred_usage_t cred_usage;
09606e
     uint32_t filter_flags;
09606e
     uint32_t enforce_flags;
09606e
+    uint32_t min_lifetime;
09606e
     char *program;
09606e
 
09606e
     uint32_t mechs;
09606e
-- 
09606e
2.31.1
09606e