diff options
author | Chuck Lever <chuck.lever@oracle.com> | 2013-07-24 12:28:28 -0400 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2013-08-07 13:05:10 -0400 |
commit | d688f7b8f62857c252b886fa16e8b38b83cfaf7e (patch) | |
tree | 4e404f49e105802f979e9344c8268c48b33518e2 | |
parent | 6da1a034362f86e157e251e65394f0b6570e3e3a (diff) |
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: Chuck Lever <chuck.lever@oracle.com>
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
-rw-r--r-- | fs/nfs/nfs4state.c | 19 |
1 files changed, 18 insertions, 1 deletions
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c index ad1a7533ce6d..f27760b1b06f 100644 --- a/fs/nfs/nfs4state.c +++ b/fs/nfs/nfs4state.c | |||
@@ -154,6 +154,19 @@ struct rpc_cred *nfs4_get_machine_cred_locked(struct nfs_client *clp) | |||
154 | return cred; | 154 | return cred; |
155 | } | 155 | } |
156 | 156 | ||
157 | static void nfs4_root_machine_cred(struct nfs_client *clp) | ||
158 | { | ||
159 | struct rpc_cred *cred, *new; | ||
160 | |||
161 | new = rpc_lookup_machine_cred(NULL); | ||
162 | spin_lock(&clp->cl_lock); | ||
163 | cred = clp->cl_machine_cred; | ||
164 | clp->cl_machine_cred = new; | ||
165 | spin_unlock(&clp->cl_lock); | ||
166 | if (cred != NULL) | ||
167 | put_rpccred(cred); | ||
168 | } | ||
169 | |||
157 | static struct rpc_cred * | 170 | static struct rpc_cred * |
158 | nfs4_get_renew_cred_server_locked(struct nfs_server *server) | 171 | nfs4_get_renew_cred_server_locked(struct nfs_server *server) |
159 | { | 172 | { |
@@ -1896,7 +1909,11 @@ again: | |||
1896 | __func__, status); | 1909 | __func__, status); |
1897 | goto again; | 1910 | goto again; |
1898 | case -EACCES: | 1911 | case -EACCES: |
1899 | if (i++) | 1912 | if (i++ == 0) { |
1913 | nfs4_root_machine_cred(clp); | ||
1914 | goto again; | ||
1915 | } | ||
1916 | if (i > 2) | ||
1900 | break; | 1917 | break; |
1901 | case -NFS4ERR_CLID_INUSE: | 1918 | case -NFS4ERR_CLID_INUSE: |
1902 | case -NFS4ERR_WRONGSEC: | 1919 | case -NFS4ERR_WRONGSEC: |