Esempio n. 1
0
static int nfs_callback_authenticate(struct svc_rqst *rqstp)
{
	struct nfs_client *clp;
	RPC_IFDEBUG(char buf[RPC_MAX_ADDRBUFLEN]);
	int ret = SVC_OK;

	/* Don't talk to strangers */
	clp = nfs_find_client(svc_addr(rqstp), 4);
	if (clp == NULL)
		return SVC_DROP;

	dprintk("%s: %s NFSv4 callback!\n", __func__,
			svc_print_addr(rqstp, buf, sizeof(buf)));

	switch (rqstp->rq_authop->flavour) {
		case RPC_AUTH_NULL:
			if (rqstp->rq_proc != CB_NULL)
				ret = SVC_DENIED;
			break;
		case RPC_AUTH_UNIX:
			break;
		case RPC_AUTH_GSS:
			ret = check_gss_callback_principal(clp, rqstp);
			break;
		default:
			ret = SVC_DENIED;
	}
	nfs_put_client(clp);
	return ret;
}
Esempio n. 2
0
static __be32 nfs4_callback_compound(struct svc_rqst *rqstp, void *argp, void *resp)
{
	struct cb_compound_hdr_arg hdr_arg = { 0 };
	struct cb_compound_hdr_res hdr_res = { NULL };
	struct xdr_stream xdr_in, xdr_out;
	__be32 *p, status;
	struct cb_process_state cps = {
		.drc_status = 0,
		.clp = NULL,
		.slotid = NFS4_NO_SLOT,
		.net = rqstp->rq_xprt->xpt_net,
	};
	unsigned int nops = 0;

	dprintk("%s: start\n", __func__);

	xdr_init_decode(&xdr_in, &rqstp->rq_arg, rqstp->rq_arg.head[0].iov_base);

	p = (__be32*)((char *)rqstp->rq_res.head[0].iov_base + rqstp->rq_res.head[0].iov_len);
	xdr_init_encode(&xdr_out, &rqstp->rq_res, p);

	status = decode_compound_hdr_arg(&xdr_in, &hdr_arg);
	if (status == __constant_htonl(NFS4ERR_RESOURCE))
		return rpc_garbage_args;

	if (hdr_arg.minorversion == 0) {
		cps.clp = nfs4_find_client_ident(rqstp->rq_xprt->xpt_net, hdr_arg.cb_ident);
		if (!cps.clp || !check_gss_callback_principal(cps.clp, rqstp))
			return rpc_drop_reply;
	}

	hdr_res.taglen = hdr_arg.taglen;
	hdr_res.tag = hdr_arg.tag;
	if (encode_compound_hdr_res(&xdr_out, &hdr_res) != 0)
		return rpc_system_err;

	while (status == 0 && nops != hdr_arg.nops) {
		status = process_op(hdr_arg.minorversion, nops, rqstp,
				    &xdr_in, argp, &xdr_out, resp, &cps);
		nops++;
	}

	if (unlikely(status == htonl(NFS4ERR_RESOURCE_HDR))) {
		status = htonl(NFS4ERR_RESOURCE);
		nops--;
	}

	*hdr_res.status = status;
	*hdr_res.nops = htonl(nops);
	nfs4_cb_free_slot(&cps);
	nfs_put_client(cps.clp);
	dprintk("%s: done, status = %u\n", __func__, ntohl(status));
	return rpc_success;
}

static struct callback_op callback_ops[] = {
	[0] = {
		.res_maxsize = CB_OP_HDR_RES_MAXSZ,
	},
Esempio n. 3
0
/*
 * Decode, process and encode a COMPOUND
 */
static __be32 nfs4_callback_compound(struct svc_rqst *rqstp, void *argp, void *resp)
{
	struct cb_compound_hdr_arg hdr_arg = { 0 };
	struct cb_compound_hdr_res hdr_res = { NULL };
	struct xdr_stream xdr_in, xdr_out;
	__be32 *p, status;
	struct cb_process_state cps = {
		.drc_status = 0,
		.clp = NULL,
		.net = SVC_NET(rqstp),
	};
	unsigned int nops = 0;

	dprintk("%s: start\n", __func__);

	xdr_init_decode(&xdr_in, &rqstp->rq_arg, rqstp->rq_arg.head[0].iov_base);

	p = (__be32*)((char *)rqstp->rq_res.head[0].iov_base + rqstp->rq_res.head[0].iov_len);
	xdr_init_encode(&xdr_out, &rqstp->rq_res, p);

	status = decode_compound_hdr_arg(&xdr_in, &hdr_arg);
	if (status == htonl(NFS4ERR_RESOURCE))
		return rpc_garbage_args;

	if (hdr_arg.minorversion == 0) {
		cps.clp = nfs4_find_client_ident(SVC_NET(rqstp), hdr_arg.cb_ident);
		if (!cps.clp || !check_gss_callback_principal(cps.clp, rqstp))
			goto out_invalidcred;
	}

	cps.minorversion = hdr_arg.minorversion;
	hdr_res.taglen = hdr_arg.taglen;
	hdr_res.tag = hdr_arg.tag;
	if (encode_compound_hdr_res(&xdr_out, &hdr_res) != 0)
		return rpc_system_err;

	while (status == 0 && nops != hdr_arg.nops) {
		status = process_op(nops, rqstp, &xdr_in,
				    argp, &xdr_out, resp, &cps);
		nops++;
	}

	/* Buffer overflow in decode_ops_hdr or encode_ops_hdr. Return
	* resource error in cb_compound status without returning op */
	if (unlikely(status == htonl(NFS4ERR_RESOURCE_HDR))) {
		status = htonl(NFS4ERR_RESOURCE);
		nops--;
	}

	*hdr_res.status = status;
	*hdr_res.nops = htonl(nops);
	nfs4_cb_free_slot(&cps);
	nfs_put_client(cps.clp);
	dprintk("%s: done, status = %u\n", __func__, ntohl(status));
	return rpc_success;

out_invalidcred:
	pr_warn_ratelimited("NFS: NFSv4 callback contains invalid cred\n");
	return rpc_autherr_badcred;
}

/*
 * Define NFS4 callback COMPOUND ops.
 */
static struct callback_op callback_ops[] = {
	[0] = {
		.res_maxsize = CB_OP_HDR_RES_MAXSZ,
	},