We had a user report that for an export shared with sec=krb5*, any changes in user credentials(ex: add user to a secondary group) take some time before they take effect over the NFS share. The problem was determined to be caused by the svcgssd process caching the user credentials. The user credentials were initially cached for an unlimited amount of time. There was some improvement in this behaviour with the commit svcgssd: use the actual context expiration for cache commit eb3a145789b9eedd39b56e1d76f412435abaa747 The cache expiration time is now set to the time for which the kerberos ticket is valid. However this is still considered too long. The proposed solution is to allow administrators to explicitly set a timeout for which the cache is valid. This is similar to changes which went into gssd, the corresponding client side program. The patch adds a -t <timeout> option to rpc.svcgssd so that the server's administrator can specify an expiry timeout for the cached context. After this timeout, an upcall is made to obtain the new user credentials. The default, timeout 0 results in the old behaviour. Signed-off-bye: Sachin Prabhu <sprabhu@xxxxxxxxxx> diff --git a/utils/gssd/svcgssd.c b/utils/gssd/svcgssd.c index 1afff9e..db99ea3 100644 --- a/utils/gssd/svcgssd.c +++ b/utils/gssd/svcgssd.c @@ -70,6 +70,8 @@ */ int pipefds[2] = { -1, -1}; +unsigned int context_timeout = 0; + static void mydaemon(int nochdir, int noclose) { @@ -167,7 +169,7 @@ sig_hup(int signal) static void usage(char *progname) { - fprintf(stderr, "usage: %s [-n] [-f] [-v] [-r] [-i] [-p principal]\n", + fprintf(stderr, "usage: %s [-n] [-f] [-v] [-r] [-i] [-p principal] [-t timeout]\n", progname); exit(1); } @@ -185,7 +187,7 @@ main(int argc, char *argv[]) char *progname; char *principal = NULL; - while ((opt = getopt(argc, argv, "fivrnp:")) != -1) { + while ((opt = getopt(argc, argv, "fivrnp:t:")) != -1) { switch (opt) { case 'f': fg = 1; @@ -205,6 +207,9 @@ main(int argc, char *argv[]) case 'p': principal = optarg; break; + case 't': + context_timeout = atoi(optarg); + break; default: usage(argv[0]); break; diff --git a/utils/gssd/svcgssd.h b/utils/gssd/svcgssd.h index 9a2e2e8..869fb63 100644 --- a/utils/gssd/svcgssd.h +++ b/utils/gssd/svcgssd.h @@ -40,4 +40,6 @@ void gssd_run(void); #define GSSD_SERVICE_NAME "nfs" +extern unsigned int context_timeout; + #endif /* _RPC_SVCGSSD_H_ */ diff --git a/utils/gssd/svcgssd.man b/utils/gssd/svcgssd.man index 7b2de6b..3688af0 100644 --- a/utils/gssd/svcgssd.man +++ b/utils/gssd/svcgssd.man @@ -45,6 +45,14 @@ Use the system default credentials .RI (host/ FQDN @ REALM ) rather than the default .RI nfs/ FQDN @ REALM . +.TP +.B -t timeout +Timeout, in seconds, for kernel gss contexts. This option allows you to force +new kernel contexts to be negotiated after +.I timeout +seconds, which allows changing Kerberos tickets and identities frequently. +The default is no explicit timeout, which means the kernel context will live +the lifetime of the Kerberos service ticket used in its creation. .SH SEE ALSO .BR rpc.gssd(8), .SH AUTHORS diff --git a/utils/gssd/svcgssd_proc.c b/utils/gssd/svcgssd_proc.c index c714d99..dae10ca 100644 --- a/utils/gssd/svcgssd_proc.c +++ b/utils/gssd/svcgssd_proc.c @@ -497,6 +497,10 @@ handle_nullreq(FILE *f) { /* We no longer need the gss context */ gss_delete_sec_context(&ignore_min_stat, &ctx, &ignore_out_tok); + /* If timeout set, override context timeout */ + if (context_timeout) + ctx_endtime = time(0) + context_timeout; + do_svc_downcall(&out_handle, &cred, mech, &ctx_token, ctx_endtime, hostbased_name); continue_needed: -- To unsubscribe from this list: send the line "unsubscribe linux-nfs" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html