Commit 73d8bde5 authored by Chuck Lever's avatar Chuck Lever Committed by Trond Myklebust

NFS: Never use user credentials for lease renewal

Never try to use a non-UID 0 user credential for lease management,
as that credential can change out from under us.  The server will
block NFSv4 lease recovery with NFS4ERR_CLID_INUSE.

Since the mechanism to acquire a credential for lease management
is now the same for all minor versions, replace the minor version-
specific callout with a single function.
Signed-off-by: default avatarChuck Lever <chuck.lever@oracle.com>
Signed-off-by: default avatarTrond Myklebust <Trond.Myklebust@netapp.com>
parent d688f7b8
...@@ -193,7 +193,6 @@ struct nfs4_state_recovery_ops { ...@@ -193,7 +193,6 @@ struct nfs4_state_recovery_ops {
int (*recover_open)(struct nfs4_state_owner *, struct nfs4_state *); int (*recover_open)(struct nfs4_state_owner *, struct nfs4_state *);
int (*recover_lock)(struct nfs4_state *, struct file_lock *); int (*recover_lock)(struct nfs4_state *, struct file_lock *);
int (*establish_clid)(struct nfs_client *, struct rpc_cred *); int (*establish_clid)(struct nfs_client *, struct rpc_cred *);
struct rpc_cred * (*get_clid_cred)(struct nfs_client *);
int (*reclaim_complete)(struct nfs_client *, struct rpc_cred *); int (*reclaim_complete)(struct nfs_client *, struct rpc_cred *);
int (*detect_trunking)(struct nfs_client *, struct nfs_client **, int (*detect_trunking)(struct nfs_client *, struct nfs_client **,
struct rpc_cred *); struct rpc_cred *);
...@@ -319,7 +318,7 @@ extern void nfs4_kill_renewd(struct nfs_client *); ...@@ -319,7 +318,7 @@ extern void nfs4_kill_renewd(struct nfs_client *);
extern void nfs4_renew_state(struct work_struct *); extern void nfs4_renew_state(struct work_struct *);
/* nfs4state.c */ /* nfs4state.c */
struct rpc_cred *nfs4_get_setclientid_cred(struct nfs_client *clp); struct rpc_cred *nfs4_get_clid_cred(struct nfs_client *clp);
struct rpc_cred *nfs4_get_machine_cred_locked(struct nfs_client *clp); struct rpc_cred *nfs4_get_machine_cred_locked(struct nfs_client *clp);
struct rpc_cred *nfs4_get_renew_cred_locked(struct nfs_client *clp); struct rpc_cred *nfs4_get_renew_cred_locked(struct nfs_client *clp);
int nfs4_discover_server_trunking(struct nfs_client *clp, int nfs4_discover_server_trunking(struct nfs_client *clp,
...@@ -327,7 +326,6 @@ int nfs4_discover_server_trunking(struct nfs_client *clp, ...@@ -327,7 +326,6 @@ int nfs4_discover_server_trunking(struct nfs_client *clp,
int nfs40_discover_server_trunking(struct nfs_client *clp, int nfs40_discover_server_trunking(struct nfs_client *clp,
struct nfs_client **, struct rpc_cred *); struct nfs_client **, struct rpc_cred *);
#if defined(CONFIG_NFS_V4_1) #if defined(CONFIG_NFS_V4_1)
struct rpc_cred *nfs4_get_exchange_id_cred(struct nfs_client *clp);
int nfs41_discover_server_trunking(struct nfs_client *clp, int nfs41_discover_server_trunking(struct nfs_client *clp,
struct nfs_client **, struct rpc_cred *); struct nfs_client **, struct rpc_cred *);
extern void nfs4_schedule_session_recovery(struct nfs4_session *, int); extern void nfs4_schedule_session_recovery(struct nfs4_session *, int);
......
...@@ -6069,7 +6069,7 @@ int nfs4_destroy_clientid(struct nfs_client *clp) ...@@ -6069,7 +6069,7 @@ int nfs4_destroy_clientid(struct nfs_client *clp)
goto out; goto out;
if (clp->cl_preserve_clid) if (clp->cl_preserve_clid)
goto out; goto out;
cred = nfs4_get_exchange_id_cred(clp); cred = nfs4_get_clid_cred(clp);
ret = nfs4_proc_destroy_clientid(clp, cred); ret = nfs4_proc_destroy_clientid(clp, cred);
if (cred) if (cred)
put_rpccred(cred); put_rpccred(cred);
...@@ -7363,7 +7363,6 @@ static const struct nfs4_state_recovery_ops nfs40_reboot_recovery_ops = { ...@@ -7363,7 +7363,6 @@ static const struct nfs4_state_recovery_ops nfs40_reboot_recovery_ops = {
.recover_open = nfs4_open_reclaim, .recover_open = nfs4_open_reclaim,
.recover_lock = nfs4_lock_reclaim, .recover_lock = nfs4_lock_reclaim,
.establish_clid = nfs4_init_clientid, .establish_clid = nfs4_init_clientid,
.get_clid_cred = nfs4_get_setclientid_cred,
.detect_trunking = nfs40_discover_server_trunking, .detect_trunking = nfs40_discover_server_trunking,
}; };
...@@ -7374,7 +7373,6 @@ static const struct nfs4_state_recovery_ops nfs41_reboot_recovery_ops = { ...@@ -7374,7 +7373,6 @@ static const struct nfs4_state_recovery_ops nfs41_reboot_recovery_ops = {
.recover_open = nfs4_open_reclaim, .recover_open = nfs4_open_reclaim,
.recover_lock = nfs4_lock_reclaim, .recover_lock = nfs4_lock_reclaim,
.establish_clid = nfs41_init_clientid, .establish_clid = nfs41_init_clientid,
.get_clid_cred = nfs4_get_exchange_id_cred,
.reclaim_complete = nfs41_proc_reclaim_complete, .reclaim_complete = nfs41_proc_reclaim_complete,
.detect_trunking = nfs41_discover_server_trunking, .detect_trunking = nfs41_discover_server_trunking,
}; };
...@@ -7386,7 +7384,6 @@ static const struct nfs4_state_recovery_ops nfs40_nograce_recovery_ops = { ...@@ -7386,7 +7384,6 @@ static const struct nfs4_state_recovery_ops nfs40_nograce_recovery_ops = {
.recover_open = nfs4_open_expired, .recover_open = nfs4_open_expired,
.recover_lock = nfs4_lock_expired, .recover_lock = nfs4_lock_expired,
.establish_clid = nfs4_init_clientid, .establish_clid = nfs4_init_clientid,
.get_clid_cred = nfs4_get_setclientid_cred,
}; };
#if defined(CONFIG_NFS_V4_1) #if defined(CONFIG_NFS_V4_1)
...@@ -7396,7 +7393,6 @@ static const struct nfs4_state_recovery_ops nfs41_nograce_recovery_ops = { ...@@ -7396,7 +7393,6 @@ static const struct nfs4_state_recovery_ops nfs41_nograce_recovery_ops = {
.recover_open = nfs41_open_expired, .recover_open = nfs41_open_expired,
.recover_lock = nfs41_lock_expired, .recover_lock = nfs41_lock_expired,
.establish_clid = nfs41_init_clientid, .establish_clid = nfs41_init_clientid,
.get_clid_cred = nfs4_get_exchange_id_cred,
}; };
#endif /* CONFIG_NFS_V4_1 */ #endif /* CONFIG_NFS_V4_1 */
......
...@@ -441,7 +441,7 @@ void nfs4_destroy_session(struct nfs4_session *session) ...@@ -441,7 +441,7 @@ void nfs4_destroy_session(struct nfs4_session *session)
struct rpc_xprt *xprt; struct rpc_xprt *xprt;
struct rpc_cred *cred; struct rpc_cred *cred;
cred = nfs4_get_exchange_id_cred(session->clp); cred = nfs4_get_clid_cred(session->clp);
nfs4_proc_destroy_session(session, cred); nfs4_proc_destroy_session(session, cred);
if (cred) if (cred)
put_rpccred(cred); put_rpccred(cred);
......
...@@ -352,62 +352,21 @@ int nfs41_discover_server_trunking(struct nfs_client *clp, ...@@ -352,62 +352,21 @@ int nfs41_discover_server_trunking(struct nfs_client *clp,
return nfs41_walk_client_list(clp, result, cred); return nfs41_walk_client_list(clp, result, cred);
} }
struct rpc_cred *nfs4_get_exchange_id_cred(struct nfs_client *clp)
{
struct rpc_cred *cred;
spin_lock(&clp->cl_lock);
cred = nfs4_get_machine_cred_locked(clp);
spin_unlock(&clp->cl_lock);
return cred;
}
#endif /* CONFIG_NFS_V4_1 */ #endif /* CONFIG_NFS_V4_1 */
static struct rpc_cred *
nfs4_get_setclientid_cred_server(struct nfs_server *server)
{
struct nfs_client *clp = server->nfs_client;
struct rpc_cred *cred = NULL;
struct nfs4_state_owner *sp;
struct rb_node *pos;
spin_lock(&clp->cl_lock);
pos = rb_first(&server->state_owners);
if (pos != NULL) {
sp = rb_entry(pos, struct nfs4_state_owner, so_server_node);
cred = get_rpccred(sp->so_cred);
}
spin_unlock(&clp->cl_lock);
return cred;
}
/** /**
* nfs4_get_setclientid_cred - Acquire credential for a setclientid operation * nfs4_get_clid_cred - Acquire credential for a setclientid operation
* @clp: client state handle * @clp: client state handle
* *
* Returns an rpc_cred with reference count bumped, or NULL. * Returns an rpc_cred with reference count bumped, or NULL.
*/ */
struct rpc_cred *nfs4_get_setclientid_cred(struct nfs_client *clp) struct rpc_cred *nfs4_get_clid_cred(struct nfs_client *clp)
{ {
struct nfs_server *server;
struct rpc_cred *cred; struct rpc_cred *cred;
spin_lock(&clp->cl_lock); spin_lock(&clp->cl_lock);
cred = nfs4_get_machine_cred_locked(clp); cred = nfs4_get_machine_cred_locked(clp);
spin_unlock(&clp->cl_lock); spin_unlock(&clp->cl_lock);
if (cred != NULL)
goto out;
rcu_read_lock();
list_for_each_entry_rcu(server, &clp->cl_superblocks, client_link) {
cred = nfs4_get_setclientid_cred_server(server);
if (cred != NULL)
break;
}
rcu_read_unlock();
out:
return cred; return cred;
} }
...@@ -1631,7 +1590,7 @@ static void nfs4_state_end_reclaim_reboot(struct nfs_client *clp) ...@@ -1631,7 +1590,7 @@ static void nfs4_state_end_reclaim_reboot(struct nfs_client *clp)
if (!nfs4_state_clear_reclaim_reboot(clp)) if (!nfs4_state_clear_reclaim_reboot(clp))
return; return;
ops = clp->cl_mvops->reboot_recovery_ops; ops = clp->cl_mvops->reboot_recovery_ops;
cred = ops->get_clid_cred(clp); cred = nfs4_get_clid_cred(clp);
nfs4_reclaim_complete(clp, ops, cred); nfs4_reclaim_complete(clp, ops, cred);
put_rpccred(cred); put_rpccred(cred);
} }
...@@ -1745,7 +1704,7 @@ static int nfs4_check_lease(struct nfs_client *clp) ...@@ -1745,7 +1704,7 @@ static int nfs4_check_lease(struct nfs_client *clp)
cred = ops->get_state_renewal_cred_locked(clp); cred = ops->get_state_renewal_cred_locked(clp);
spin_unlock(&clp->cl_lock); spin_unlock(&clp->cl_lock);
if (cred == NULL) { if (cred == NULL) {
cred = nfs4_get_setclientid_cred(clp); cred = nfs4_get_clid_cred(clp);
status = -ENOKEY; status = -ENOKEY;
if (cred == NULL) if (cred == NULL)
goto out; goto out;
...@@ -1817,7 +1776,7 @@ static int nfs4_establish_lease(struct nfs_client *clp) ...@@ -1817,7 +1776,7 @@ static int nfs4_establish_lease(struct nfs_client *clp)
clp->cl_mvops->reboot_recovery_ops; clp->cl_mvops->reboot_recovery_ops;
int status; int status;
cred = ops->get_clid_cred(clp); cred = nfs4_get_clid_cred(clp);
if (cred == NULL) if (cred == NULL)
return -ENOENT; return -ENOENT;
status = ops->establish_clid(clp, cred); status = ops->establish_clid(clp, cred);
...@@ -1891,7 +1850,7 @@ int nfs4_discover_server_trunking(struct nfs_client *clp, ...@@ -1891,7 +1850,7 @@ int nfs4_discover_server_trunking(struct nfs_client *clp,
mutex_lock(&nfs_clid_init_mutex); mutex_lock(&nfs_clid_init_mutex);
again: again:
status = -ENOENT; status = -ENOENT;
cred = ops->get_clid_cred(clp); cred = nfs4_get_clid_cred(clp);
if (cred == NULL) if (cred == NULL)
goto out_unlock; goto out_unlock;
...@@ -2069,7 +2028,7 @@ static int nfs4_reset_session(struct nfs_client *clp) ...@@ -2069,7 +2028,7 @@ static int nfs4_reset_session(struct nfs_client *clp)
if (!nfs4_has_session(clp)) if (!nfs4_has_session(clp))
return 0; return 0;
nfs4_begin_drain_session(clp); nfs4_begin_drain_session(clp);
cred = nfs4_get_exchange_id_cred(clp); cred = nfs4_get_clid_cred(clp);
status = nfs4_proc_destroy_session(clp->cl_session, cred); status = nfs4_proc_destroy_session(clp->cl_session, cred);
switch (status) { switch (status) {
case 0: case 0:
...@@ -2112,7 +2071,7 @@ static int nfs4_bind_conn_to_session(struct nfs_client *clp) ...@@ -2112,7 +2071,7 @@ static int nfs4_bind_conn_to_session(struct nfs_client *clp)
if (!nfs4_has_session(clp)) if (!nfs4_has_session(clp))
return 0; return 0;
nfs4_begin_drain_session(clp); nfs4_begin_drain_session(clp);
cred = nfs4_get_exchange_id_cred(clp); cred = nfs4_get_clid_cred(clp);
ret = nfs4_proc_bind_conn_to_session(clp, cred); ret = nfs4_proc_bind_conn_to_session(clp, cred);
if (cred) if (cred)
put_rpccred(cred); put_rpccred(cred);
......
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