diff --git a/examples/99-nfs-client.conf.in b/examples/99-nfs-client.conf.in
index c0985d9e..9dd1891c 100644
--- a/examples/99-nfs-client.conf.in
+++ b/examples/99-nfs-client.conf.in
@@ -7,3 +7,4 @@
allow_any_uid = yes
trusted = yes
euid = 0
+ min_lifetime = 60
diff --git a/man/gssproxy.conf.5.xml b/man/gssproxy.conf.5.xml
index 67dce68f..f02b1d37 100644
--- a/man/gssproxy.conf.5.xml
+++ b/man/gssproxy.conf.5.xml
@@ -331,6 +331,21 @@
+
+ min_lifetime (integer)
+
+ Minimum lifetime of a cached credential, in seconds.
+ If non-zero, when gssproxy is deciding whether to use
+ a cached credential, it will compare the lifetime of the
+ cached credential to this value. If the lifetime of the
+ cached credential is lower, gssproxy will treat the cached
+ credential as expired and will attempt to obtain a new
+ credential.
+
+ Default: min_lifetime = 15
+
+
+
program (string)
diff --git a/src/gp_config.c b/src/gp_config.c
index 4cda5796..a0afa736 100644
--- a/src/gp_config.c
+++ b/src/gp_config.c
@@ -32,6 +32,7 @@ struct gp_flag_def flag_names[] = {
#define DEFAULT_FILTERED_FLAGS GSS_C_DELEG_FLAG
#define DEFAULT_ENFORCED_FLAGS 0
+#define DEFAULT_MIN_LIFETIME 15
static void free_str_array(const char ***a, int *count)
{
@@ -538,6 +539,17 @@ static int load_services(struct gp_config *cfg, struct gp_ini_context *ctx)
goto done;
}
}
+
+ cfg->svcs[n]->min_lifetime = DEFAULT_MIN_LIFETIME;
+ ret = gp_config_get_int(ctx, secname, "min_lifetime", &valnum);
+ if (ret == 0) {
+ if (valnum >= 0) {
+ cfg->svcs[n]->min_lifetime = valnum;
+ } else {
+ GPDEBUG("Invalid value '%d' for min_lifetime in [%s], ignoring.\n",
+ valnum, secname);
+ }
+ }
}
safefree(secname);
}
diff --git a/src/gp_creds.c b/src/gp_creds.c
index 92a6f134..843d1a38 100644
--- a/src/gp_creds.c
+++ b/src/gp_creds.c
@@ -492,6 +492,7 @@ static int gp_get_cred_environment(struct gp_call_ctx *gpcall,
}
static uint32_t gp_check_cred(uint32_t *min,
+ struct gp_service *svc,
gss_cred_id_t in_cred,
gssx_name *desired_name,
gss_cred_usage_t cred_usage)
@@ -563,7 +564,14 @@ static uint32_t gp_check_cred(uint32_t *min,
if (lifetime == 0) {
ret_maj = GSS_S_CREDENTIALS_EXPIRED;
} else {
- ret_maj = GSS_S_COMPLETE;
+ if (svc->min_lifetime && lifetime < svc->min_lifetime) {
+ GPDEBUG("%s: lifetime (%u) less than min_lifetime (%u) "
+ "for service \"%s\" - returning\n",
+ __func__, lifetime, svc->min_lifetime, svc->name);
+ ret_maj = GSS_S_CREDENTIALS_EXPIRED;
+ } else {
+ ret_maj = GSS_S_COMPLETE;
+ }
}
done:
@@ -622,7 +630,7 @@ uint32_t gp_add_krb5_creds(uint32_t *min,
* function completely */
/* just check if it is a valid krb5 cred */
- ret_maj = gp_check_cred(&ret_min, in_cred, desired_name, cred_usage);
+ ret_maj = gp_check_cred(&ret_min, gpcall->service, in_cred, desired_name, cred_usage);
if (ret_maj == GSS_S_COMPLETE) {
return GSS_S_COMPLETE;
} else if (ret_maj == GSS_S_CREDENTIALS_EXPIRED ||
diff --git a/src/gp_proxy.h b/src/gp_proxy.h
index 3f58a437..f56d6404 100644
--- a/src/gp_proxy.h
+++ b/src/gp_proxy.h
@@ -45,6 +45,7 @@ struct gp_service {
gss_cred_usage_t cred_usage;
uint32_t filter_flags;
uint32_t enforce_flags;
+ uint32_t min_lifetime;
char *program;
uint32_t mechs;