mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2025-01-04 12:16:41 +00:00
SUNRPC: Teach server to recognize RPC_AUTH_TLS
Initial support for the RPC_AUTH_TLS authentication flavor enables NFSD to eventually accept an RPC_AUTH_TLS probe from clients. This patch simply prevents NFSD from rejecting these probes completely. In the meantime, graft this support in now so that RPC_AUTH_TLS support keeps up with generic code and API changes in the RPC server. Down the road, server-side transport implementations will populate xpo_start_tls when they can support RPC-with-TLS. For example, TCP will eventually populate it, but RDMA won't. Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
This commit is contained in:
parent
37902c6313
commit
74aaf96fea
@ -28,6 +28,7 @@ struct svc_xprt_ops {
|
|||||||
void (*xpo_free)(struct svc_xprt *);
|
void (*xpo_free)(struct svc_xprt *);
|
||||||
void (*xpo_secure_port)(struct svc_rqst *rqstp);
|
void (*xpo_secure_port)(struct svc_rqst *rqstp);
|
||||||
void (*xpo_kill_temp_xprt)(struct svc_xprt *);
|
void (*xpo_kill_temp_xprt)(struct svc_xprt *);
|
||||||
|
void (*xpo_start_tls)(struct svc_xprt *);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct svc_xprt_class {
|
struct svc_xprt_class {
|
||||||
|
@ -31,10 +31,12 @@
|
|||||||
*/
|
*/
|
||||||
extern struct auth_ops svcauth_null;
|
extern struct auth_ops svcauth_null;
|
||||||
extern struct auth_ops svcauth_unix;
|
extern struct auth_ops svcauth_unix;
|
||||||
|
extern struct auth_ops svcauth_tls;
|
||||||
|
|
||||||
static struct auth_ops __rcu *authtab[RPC_AUTH_MAXFLAVOR] = {
|
static struct auth_ops __rcu *authtab[RPC_AUTH_MAXFLAVOR] = {
|
||||||
[RPC_AUTH_NULL] = (struct auth_ops __force __rcu *)&svcauth_null,
|
[RPC_AUTH_NULL] = (struct auth_ops __force __rcu *)&svcauth_null,
|
||||||
[RPC_AUTH_UNIX] = (struct auth_ops __force __rcu *)&svcauth_unix,
|
[RPC_AUTH_UNIX] = (struct auth_ops __force __rcu *)&svcauth_unix,
|
||||||
|
[RPC_AUTH_TLS] = (struct auth_ops __force __rcu *)&svcauth_tls,
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct auth_ops *
|
static struct auth_ops *
|
||||||
|
@ -37,6 +37,7 @@ struct unix_domain {
|
|||||||
|
|
||||||
extern struct auth_ops svcauth_null;
|
extern struct auth_ops svcauth_null;
|
||||||
extern struct auth_ops svcauth_unix;
|
extern struct auth_ops svcauth_unix;
|
||||||
|
extern struct auth_ops svcauth_tls;
|
||||||
|
|
||||||
static void svcauth_unix_domain_release_rcu(struct rcu_head *head)
|
static void svcauth_unix_domain_release_rcu(struct rcu_head *head)
|
||||||
{
|
{
|
||||||
@ -788,6 +789,65 @@ struct auth_ops svcauth_null = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
svcauth_tls_accept(struct svc_rqst *rqstp)
|
||||||
|
{
|
||||||
|
struct svc_cred *cred = &rqstp->rq_cred;
|
||||||
|
struct kvec *argv = rqstp->rq_arg.head;
|
||||||
|
struct kvec *resv = rqstp->rq_res.head;
|
||||||
|
|
||||||
|
if (argv->iov_len < XDR_UNIT * 3)
|
||||||
|
return SVC_GARBAGE;
|
||||||
|
|
||||||
|
/* Call's cred length */
|
||||||
|
if (svc_getu32(argv) != xdr_zero) {
|
||||||
|
rqstp->rq_auth_stat = rpc_autherr_badcred;
|
||||||
|
return SVC_DENIED;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Call's verifier flavor and its length */
|
||||||
|
if (svc_getu32(argv) != rpc_auth_null ||
|
||||||
|
svc_getu32(argv) != xdr_zero) {
|
||||||
|
rqstp->rq_auth_stat = rpc_autherr_badverf;
|
||||||
|
return SVC_DENIED;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* AUTH_TLS is not valid on non-NULL procedures */
|
||||||
|
if (rqstp->rq_proc != 0) {
|
||||||
|
rqstp->rq_auth_stat = rpc_autherr_badcred;
|
||||||
|
return SVC_DENIED;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Mapping to nobody uid/gid is required */
|
||||||
|
cred->cr_uid = INVALID_UID;
|
||||||
|
cred->cr_gid = INVALID_GID;
|
||||||
|
cred->cr_group_info = groups_alloc(0);
|
||||||
|
if (cred->cr_group_info == NULL)
|
||||||
|
return SVC_CLOSE; /* kmalloc failure - client must retry */
|
||||||
|
|
||||||
|
/* Reply's verifier */
|
||||||
|
svc_putnl(resv, RPC_AUTH_NULL);
|
||||||
|
if (rqstp->rq_xprt->xpt_ops->xpo_start_tls) {
|
||||||
|
svc_putnl(resv, 8);
|
||||||
|
memcpy(resv->iov_base + resv->iov_len, "STARTTLS", 8);
|
||||||
|
resv->iov_len += 8;
|
||||||
|
} else
|
||||||
|
svc_putnl(resv, 0);
|
||||||
|
|
||||||
|
rqstp->rq_cred.cr_flavor = RPC_AUTH_TLS;
|
||||||
|
return SVC_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct auth_ops svcauth_tls = {
|
||||||
|
.name = "tls",
|
||||||
|
.owner = THIS_MODULE,
|
||||||
|
.flavour = RPC_AUTH_TLS,
|
||||||
|
.accept = svcauth_tls_accept,
|
||||||
|
.release = svcauth_null_release,
|
||||||
|
.set_client = svcauth_unix_set_client,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
svcauth_unix_accept(struct svc_rqst *rqstp)
|
svcauth_unix_accept(struct svc_rqst *rqstp)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user