Commit d688f7b8 authored by Chuck Lever's avatar Chuck Lever Committed by Trond Myklebust

NFS: Use root's credential for lease management when keytab is missing

Commit 05f4c350 "NFS: Discover NFSv4 server trunking when mounting"
Fri Sep 14 17:24:32 2012 introduced Uniform Client String support,
which forces our NFS client to establish a client ID immediately
during a mount operation rather than waiting until a user wants to
open a file.

Normally machine credentials (eg. from a keytab) are used to perform
a mount operation that is protected by Kerberos.  Before 05fc350,
SETCLIENTID used a machine credential, or fell back to a regular
user's credential if no keytab is available.

On clients that don't have a keytab, performing SETCLIENTID early
means there's no user credential to fall back on, since no regular
user has kinit'd yet.  05f4c350 seems to have broken the ability
to mount with sec=krb5 on clients that don't have a keytab in
kernels 3.7 - 3.10.

To address this regression, commit 4edaa308 (NFS: Use "krb5i" to
establish NFSv4 state whenever possible), Sat Mar 16 15:56:20 2013,
was merged in 3.10.  This commit forces the NFS client to fall back
to AUTH_SYS for lease management operations if no keytab is
available.

Neil Brown noticed that, since root is required to kinit to do a
sec=krb5 mount when a client doesn't have a keytab, we can try to
use root's Kerberos credential before AUTH_SYS.

Now, when determining a principal and flavor to use for lease
management, the NFS client tries in this order:

  1.  Flavor: AUTH_GSS, krb5i
      Principal: service principal (via keytab)

  2.  Flavor: AUTH_GSS, krb5i
      Principal: user principal established for UID 0 (via kinit)

  3.  Flavor: AUTH_SYS
      Principal: UID 0 / GID 0
Signed-off-by: default avatarChuck Lever <chuck.lever@oracle.com>
Signed-off-by: default avatarTrond Myklebust <Trond.Myklebust@netapp.com>
parent 6da1a034
...@@ -154,6 +154,19 @@ struct rpc_cred *nfs4_get_machine_cred_locked(struct nfs_client *clp) ...@@ -154,6 +154,19 @@ struct rpc_cred *nfs4_get_machine_cred_locked(struct nfs_client *clp)
return cred; return cred;
} }
static void nfs4_root_machine_cred(struct nfs_client *clp)
{
struct rpc_cred *cred, *new;
new = rpc_lookup_machine_cred(NULL);
spin_lock(&clp->cl_lock);
cred = clp->cl_machine_cred;
clp->cl_machine_cred = new;
spin_unlock(&clp->cl_lock);
if (cred != NULL)
put_rpccred(cred);
}
static struct rpc_cred * static struct rpc_cred *
nfs4_get_renew_cred_server_locked(struct nfs_server *server) nfs4_get_renew_cred_server_locked(struct nfs_server *server)
{ {
...@@ -1896,7 +1909,11 @@ int nfs4_discover_server_trunking(struct nfs_client *clp, ...@@ -1896,7 +1909,11 @@ int nfs4_discover_server_trunking(struct nfs_client *clp,
__func__, status); __func__, status);
goto again; goto again;
case -EACCES: case -EACCES:
if (i++) if (i++ == 0) {
nfs4_root_machine_cred(clp);
goto again;
}
if (i > 2)
break; break;
case -NFS4ERR_CLID_INUSE: case -NFS4ERR_CLID_INUSE:
case -NFS4ERR_WRONGSEC: case -NFS4ERR_WRONGSEC:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment