Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a14017db authored by Chuck Lever's avatar Chuck Lever Committed by Trond Myklebust
Browse files

NFS: add XDR decoder for mountd version 3 auth-flavor lists



Introduce an xdr_stream-based XDR decoder that can unpack the auth-
flavor list returned in a MNT3 reply.

The nfs_mount() function's caller allocates an array, and passes the
size and a pointer to it.  The decoder decodes all the flavors it can
into the array, and returns the number of decoded flavors.

If the caller is not interested in the auth flavors, it can pass a
value of zero as the size of the pre-allocated array.

Signed-off-by: default avatarChuck Lever <chuck.lever@oracle.com>
Signed-off-by: default avatarTrond Myklebust <Trond.Myklebust@netapp.com>
parent 4fdcd996
Loading
Loading
Loading
Loading
+6 −0
Original line number Original line Diff line number Diff line
@@ -29,6 +29,12 @@ struct nfs_clone_mount {
	rpc_authflavor_t authflavor;
	rpc_authflavor_t authflavor;
};
};


/*
 * Note: RFC 1813 doesn't limit the number of auth flavors that
 * a server can return, so make something up.
 */
#define NFS_MAX_SECFLAVORS	(12)

/*
/*
 * In-kernel mount arguments
 * In-kernel mount arguments
 */
 */
+37 −0
Original line number Original line Diff line number Diff line
@@ -33,6 +33,7 @@
#define MNT_fhs_status_sz	(1)
#define MNT_fhs_status_sz	(1)
#define MNT_fhandle_sz		XDR_QUADLEN(NFS2_FHSIZE)
#define MNT_fhandle_sz		XDR_QUADLEN(NFS2_FHSIZE)
#define MNT_fhandle3_sz		(1 + XDR_QUADLEN(NFS3_FHSIZE))
#define MNT_fhandle3_sz		(1 + XDR_QUADLEN(NFS3_FHSIZE))
#define MNT_authflav3_sz	(1 + NFS_MAX_SECFLAVORS)


/*
/*
 * XDR argument and result sizes
 * XDR argument and result sizes
@@ -122,6 +123,8 @@ static struct {
struct mountres {
struct mountres {
	int errno;
	int errno;
	struct nfs_fh *fh;
	struct nfs_fh *fh;
	unsigned int *auth_count;
	rpc_authflavor_t *auth_flavors;
};
};


struct mnt_fhstatus {
struct mnt_fhstatus {
@@ -334,6 +337,40 @@ static int decode_fhandle3(struct xdr_stream *xdr, struct mountres *res)
	return 0;
	return 0;
}
}


static int decode_auth_flavors(struct xdr_stream *xdr, struct mountres *res)
{
	rpc_authflavor_t *flavors = res->auth_flavors;
	unsigned int *count = res->auth_count;
	u32 entries, i;
	__be32 *p;

	if (*count == 0)
		return 0;

	p = xdr_inline_decode(xdr, sizeof(entries));
	if (unlikely(p == NULL))
		return -EIO;
	entries = ntohl(*p);
	dprintk("NFS: received %u auth flavors\n", entries);
	if (entries > NFS_MAX_SECFLAVORS)
		entries = NFS_MAX_SECFLAVORS;

	p = xdr_inline_decode(xdr, sizeof(u32) * entries);
	if (unlikely(p == NULL))
		return -EIO;

	if (entries > *count)
		entries = *count;

	for (i = 0; i < entries; i++) {
		flavors[i] = ntohl(*p++);
		dprintk("NFS:\tflavor %u: %d\n", i, flavors[i]);
	}
	*count = i;

	return 0;
}

static int xdr_decode_fhstatus3(struct rpc_rqst *req, __be32 *p,
static int xdr_decode_fhstatus3(struct rpc_rqst *req, __be32 *p,
				struct mnt_fhstatus *res)
				struct mnt_fhstatus *res)
{
{