Add a cap on credential lifetime for Kerberized NFS.

The kernel RPCSEC_GSS code sets the credential (called a client) lifetime
to the lifetime of the Kerberos ticket, which is typically several hours.
As such, when a user's credentials change such as being added to a new group,
it can take several hours for this change to be recognized by the NFS server.
This patch adds a sysctl called kern.rpc.gss.lifetime_max which can be set
by a sysadmin to put a cap on the time to expire for the credentials, so that
a sysadmin can reduce the timeout.
It also fixes a bug, where time_uptime is added twice when GSS_C_INDEFINITE
is returned for a lifetime. This has no effect in practice, sine Kerberos
never does this.

Tested by:	pen@lysator.liu.se
PR:		242132
Submitted by:	pen@lysator.liu.se
MFC after:	2 weeks
This commit is contained in:
Rick Macklem 2019-11-28 02:05:31 +00:00
parent 81c2e8a6f2
commit 04cb0c38eb

View File

@ -173,6 +173,7 @@ struct svc_rpc_gss_cookedcred {
#define CLIENT_MAX 1024
u_int svc_rpc_gss_client_max = CLIENT_MAX;
u_int svc_rpc_gss_client_hash_size = CLIENT_HASH_SIZE;
u_int svc_rpc_gss_lifetime_max = 0;
SYSCTL_NODE(_kern, OID_AUTO, rpc, CTLFLAG_RW, 0, "RPC");
SYSCTL_NODE(_kern_rpc, OID_AUTO, gss, CTLFLAG_RW, 0, "GSS");
@ -185,6 +186,10 @@ SYSCTL_UINT(_kern_rpc_gss, OID_AUTO, client_hash, CTLFLAG_RDTUN,
&svc_rpc_gss_client_hash_size, 0,
"Size of rpc-gss client hash table");
SYSCTL_UINT(_kern_rpc_gss, OID_AUTO, lifetime_max, CTLFLAG_RW,
&svc_rpc_gss_lifetime_max, 0,
"Maximum lifetime (seconds) of rpc-gss clients");
static u_int svc_rpc_gss_client_count;
SYSCTL_UINT(_kern_rpc_gss, OID_AUTO, client_count, CTLFLAG_RD,
&svc_rpc_gss_client_count, 0,
@ -956,8 +961,15 @@ svc_rpc_gss_accept_sec_context(struct svc_rpc_gss_client *client,
* that out).
*/
if (cred_lifetime == GSS_C_INDEFINITE)
cred_lifetime = time_uptime + 24*60*60;
cred_lifetime = 24*60*60;
/*
* Cap cred_lifetime if sysctl kern.rpc.gss.lifetime_max is set.
*/
if (svc_rpc_gss_lifetime_max > 0 && cred_lifetime >
svc_rpc_gss_lifetime_max)
cred_lifetime = svc_rpc_gss_lifetime_max;
client->cl_expiration = time_uptime + cred_lifetime;
/*