SUNRPC/nfs: Fix return value for nfs4_callback_compound()
RPC server procedures are normally expected to return a __be32 encoded
status value of type 'enum rpc_accept_stat', however at least one function
wants to return an authentication status of type 'enum rpc_auth_stat'
in the case where authentication fails.
This patch adds functionality to allow this.
Fixes: a4e187d83d
("NFS: Don't drop CB requests with invalid principals")
Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
This commit is contained in:
parent
8a9f4f4124
commit
83dd59a0b9
|
@ -983,7 +983,7 @@ static __be32 nfs4_callback_compound(struct svc_rqst *rqstp)
|
|||
|
||||
out_invalidcred:
|
||||
pr_warn_ratelimited("NFS: NFSv4 callback contains invalid cred\n");
|
||||
return rpc_autherr_badcred;
|
||||
return svc_return_autherr(rqstp, rpc_autherr_badcred);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -271,6 +271,7 @@ struct svc_rqst {
|
|||
#define RQ_VICTIM (5) /* about to be shut down */
|
||||
#define RQ_BUSY (6) /* request is busy */
|
||||
#define RQ_DATA (7) /* request has data */
|
||||
#define RQ_AUTHERR (8) /* Request status is auth error */
|
||||
unsigned long rq_flags; /* flags field */
|
||||
ktime_t rq_qtime; /* enqueue time */
|
||||
|
||||
|
@ -504,6 +505,7 @@ unsigned int svc_fill_write_vector(struct svc_rqst *rqstp,
|
|||
char *svc_fill_symlink_pathname(struct svc_rqst *rqstp,
|
||||
struct kvec *first, void *p,
|
||||
size_t total);
|
||||
__be32 svc_return_autherr(struct svc_rqst *rqstp, __be32 auth_err);
|
||||
|
||||
#define RPC_MAX_ADDRBUFLEN (63U)
|
||||
|
||||
|
|
|
@ -1144,6 +1144,22 @@ void svc_printk(struct svc_rqst *rqstp, const char *fmt, ...)
|
|||
static __printf(2,3) void svc_printk(struct svc_rqst *rqstp, const char *fmt, ...) {}
|
||||
#endif
|
||||
|
||||
__be32
|
||||
svc_return_autherr(struct svc_rqst *rqstp, __be32 auth_err)
|
||||
{
|
||||
set_bit(RQ_AUTHERR, &rqstp->rq_flags);
|
||||
return auth_err;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(svc_return_autherr);
|
||||
|
||||
static __be32
|
||||
svc_get_autherr(struct svc_rqst *rqstp, __be32 *statp)
|
||||
{
|
||||
if (test_and_clear_bit(RQ_AUTHERR, &rqstp->rq_flags))
|
||||
return *statp;
|
||||
return rpc_auth_ok;
|
||||
}
|
||||
|
||||
/*
|
||||
* Common routine for processing the RPC request.
|
||||
*/
|
||||
|
@ -1290,11 +1306,9 @@ svc_process_common(struct svc_rqst *rqstp, struct kvec *argv, struct kvec *resv)
|
|||
procp->pc_release(rqstp);
|
||||
goto dropit;
|
||||
}
|
||||
if (*statp == rpc_autherr_badcred) {
|
||||
if (procp->pc_release)
|
||||
procp->pc_release(rqstp);
|
||||
goto err_bad_auth;
|
||||
}
|
||||
auth_stat = svc_get_autherr(rqstp, statp);
|
||||
if (auth_stat != rpc_auth_ok)
|
||||
goto err_release_bad_auth;
|
||||
if (*statp == rpc_success && procp->pc_encode &&
|
||||
!procp->pc_encode(rqstp, resv->iov_base + resv->iov_len)) {
|
||||
dprintk("svc: failed to encode reply\n");
|
||||
|
@ -1351,6 +1365,9 @@ err_bad_rpc:
|
|||
svc_putnl(resv, 2);
|
||||
goto sendit;
|
||||
|
||||
err_release_bad_auth:
|
||||
if (procp->pc_release)
|
||||
procp->pc_release(rqstp);
|
||||
err_bad_auth:
|
||||
dprintk("svc: authentication failed (%d)\n", ntohl(auth_stat));
|
||||
serv->sv_stats->rpcbadauth++;
|
||||
|
|
Loading…
Reference in a new issue