Skip to content

Commit

Permalink
NFS: Use "krb5i" to establish NFSv4 state whenever possible
Browse files Browse the repository at this point in the history
Currently our client uses AUTH_UNIX for state management on Kerberos
NFS mounts in some cases.  For example, if the first mount of a
server specifies "sec=sys," the SETCLIENTID operation is performed
with AUTH_UNIX.  Subsequent mounts using stronger security flavors
can not change the flavor used for lease establishment.  This might
be less security than an administrator was expecting.

Dave Noveck's migration issues draft recommends the use of an
integrity-protecting security flavor for the SETCLIENTID operation.
Let's ignore the mount's sec= setting and use krb5i as the default
security flavor for SETCLIENTID.

If our client can't establish a GSS context (eg. because it doesn't
have a keytab or the server doesn't support Kerberos) we fall back
to using AUTH_NULL.  For an operation that requires a
machine credential (which never represents a particular user)
AUTH_NULL is as secure as AUTH_UNIX.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
  • Loading branch information
Chuck Lever authored and Trond Myklebust committed Mar 29, 2013
1 parent c4eafe1 commit 4edaa30
Show file tree
Hide file tree
Showing 2 changed files with 6 additions and 33 deletions.
2 changes: 1 addition & 1 deletion fs/nfs/nfs4client.c
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ struct nfs_client *nfs4_init_client(struct nfs_client *clp,
clp->rpc_ops = &nfs_v4_clientops;

__set_bit(NFS_CS_DISCRTRY, &clp->cl_flags);
error = nfs_create_rpc_client(clp, timeparms, authflavour);
error = nfs_create_rpc_client(clp, timeparms, RPC_AUTH_GSS_KRB5I);
if (error < 0)
goto error;

Expand Down
37 changes: 5 additions & 32 deletions fs/nfs/nfs4state.c
Original file line number Diff line number Diff line change
Expand Up @@ -1866,26 +1866,13 @@ int nfs4_discover_server_trunking(struct nfs_client *clp,
{
const struct nfs4_state_recovery_ops *ops =
clp->cl_mvops->reboot_recovery_ops;
rpc_authflavor_t *flavors, flav, save;
struct rpc_clnt *clnt;
struct rpc_cred *cred;
int i, len, status;
int i, status;

dprintk("NFS: %s: testing '%s'\n", __func__, clp->cl_hostname);

len = NFS_MAX_SECFLAVORS;
flavors = kcalloc(len, sizeof(*flavors), GFP_KERNEL);
if (flavors == NULL) {
status = -ENOMEM;
goto out;
}
len = rpcauth_list_flavors(flavors, len);
if (len < 0) {
status = len;
goto out_free;
}
clnt = clp->cl_rpcclient;
save = clnt->cl_auth->au_flavor;
i = 0;

mutex_lock(&nfs_clid_init_mutex);
Expand All @@ -1900,12 +1887,6 @@ int nfs4_discover_server_trunking(struct nfs_client *clp,
switch (status) {
case 0:
break;

case -EACCES:
if (clp->cl_machine_cred == NULL)
break;
/* Handle case where the user hasn't set up machine creds */
nfs4_clear_machine_cred(clp);
case -NFS4ERR_DELAY:
case -ETIMEDOUT:
case -EAGAIN:
Expand All @@ -1914,17 +1895,12 @@ int nfs4_discover_server_trunking(struct nfs_client *clp,
dprintk("NFS: %s after status %d, retrying\n",
__func__, status);
goto again;

case -EACCES:
if (i++)
break;
case -NFS4ERR_CLID_INUSE:
case -NFS4ERR_WRONGSEC:
status = -EPERM;
if (i >= len)
break;

flav = flavors[i++];
if (flav == save)
flav = flavors[i++];
clnt = rpc_clone_client_set_auth(clnt, flav);
clnt = rpc_clone_client_set_auth(clnt, RPC_AUTH_NULL);
if (IS_ERR(clnt)) {
status = PTR_ERR(clnt);
break;
Expand All @@ -1944,9 +1920,6 @@ int nfs4_discover_server_trunking(struct nfs_client *clp,

out_unlock:
mutex_unlock(&nfs_clid_init_mutex);
out_free:
kfree(flavors);
out:
dprintk("NFS: %s: status = %d\n", __func__, status);
return status;
}
Expand Down

0 comments on commit 4edaa30

Please sign in to comment.