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

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

SUNRPC: Define rpcsec_gss_info structure



The NFSv4 SECINFO procedure returns a list of security flavors.  Any
GSS flavor also has a GSS tuple containing an OID, a quality-of-
protection value, and a service value, which specifies a particular
GSS pseudoflavor.

For simplicity and efficiency, I'd like to return each GSS tuple
from the NFSv4 SECINFO XDR decoder and pass it straight into the RPC
client.

Define a data structure that is visible to both the NFS client and
the RPC client.  Take structure and field names from the relevant
standards to avoid confusion.

Signed-off-by: default avatarChuck Lever <chuck.lever@oracle.com>
Signed-off-by: default avatarTrond Myklebust <Trond.Myklebust@netapp.com>
parent 72f4dc11
Loading
Loading
Loading
Loading
+6 −6
Original line number Diff line number Diff line
@@ -138,23 +138,23 @@ rpc_authflavor_t nfs_find_best_sec(struct nfs4_secinfo_flavors *flavors)
{
	struct gss_api_mech *mech;
	struct xdr_netobj oid;
	int i;
	unsigned int i;
	rpc_authflavor_t pseudoflavor = RPC_AUTH_UNIX;

	for (i = 0; i < flavors->num_flavors; i++) {
		struct nfs4_secinfo_flavor *flavor;
		flavor = &flavors->flavors[i];
		struct nfs4_secinfo4 *flavor = &flavors->flavors[i];

		if (flavor->flavor == RPC_AUTH_NULL || flavor->flavor == RPC_AUTH_UNIX) {
			pseudoflavor = flavor->flavor;
			break;
		} else if (flavor->flavor == RPC_AUTH_GSS) {
			oid.len  = flavor->gss.sec_oid4.len;
			oid.data = flavor->gss.sec_oid4.data;
			oid.len  = flavor->flavor_info.oid.len;
			oid.data = flavor->flavor_info.oid.data;
			mech = gss_mech_get_by_OID(&oid);
			if (!mech)
				continue;
			pseudoflavor = gss_svc_to_pseudoflavor(mech, flavor->gss.service);
			pseudoflavor = gss_svc_to_pseudoflavor(mech,
						flavor->flavor_info.service);
			gss_mech_put(mech);
			break;
		}
+12 −9
Original line number Diff line number Diff line
@@ -5205,27 +5205,30 @@ static int decode_delegreturn(struct xdr_stream *xdr)
	return decode_op_hdr(xdr, OP_DELEGRETURN);
}

static int decode_secinfo_gss(struct xdr_stream *xdr, struct nfs4_secinfo_flavor *flavor)
static int decode_secinfo_gss(struct xdr_stream *xdr,
			      struct nfs4_secinfo4 *flavor)
{
	u32 oid_len;
	__be32 *p;

	p = xdr_inline_decode(xdr, 4);
	if (unlikely(!p))
		goto out_overflow;
	flavor->gss.sec_oid4.len = be32_to_cpup(p);
	if (flavor->gss.sec_oid4.len > GSS_OID_MAX_LEN)
	oid_len = be32_to_cpup(p);
	if (oid_len > GSS_OID_MAX_LEN)
		goto out_err;

	p = xdr_inline_decode(xdr, flavor->gss.sec_oid4.len);
	p = xdr_inline_decode(xdr, oid_len);
	if (unlikely(!p))
		goto out_overflow;
	memcpy(flavor->gss.sec_oid4.data, p, flavor->gss.sec_oid4.len);
	memcpy(flavor->flavor_info.oid.data, p, oid_len);
	flavor->flavor_info.oid.len = oid_len;

	p = xdr_inline_decode(xdr, 8);
	if (unlikely(!p))
		goto out_overflow;
	flavor->gss.qop4 = be32_to_cpup(p++);
	flavor->gss.service = be32_to_cpup(p);
	flavor->flavor_info.qop = be32_to_cpup(p++);
	flavor->flavor_info.service = be32_to_cpup(p);

	return 0;

@@ -5238,10 +5241,10 @@ out_err:

static int decode_secinfo_common(struct xdr_stream *xdr, struct nfs4_secinfo_res *res)
{
	struct nfs4_secinfo_flavor *sec_flavor;
	struct nfs4_secinfo4 *sec_flavor;
	unsigned int i, num_flavors;
	int status;
	__be32 *p;
	int i, num_flavors;

	p = xdr_inline_decode(xdr, 4);
	if (unlikely(!p))
+5 −16
Original line number Diff line number Diff line
@@ -1049,25 +1049,14 @@ struct nfs4_fs_locations_res {
	struct nfs4_fs_locations       *fs_locations;
};

struct nfs4_secinfo_oid {
	unsigned int len;
	char data[GSS_OID_MAX_LEN];
};

struct nfs4_secinfo_gss {
	struct nfs4_secinfo_oid sec_oid4;
	unsigned int qop4;
	unsigned int service;
};

struct nfs4_secinfo_flavor {
	unsigned int 		flavor;
	struct nfs4_secinfo_gss	gss;
struct nfs4_secinfo4 {
	u32			flavor;
	struct rpcsec_gss_info	flavor_info;
};

struct nfs4_secinfo_flavors {
	unsigned int		num_flavors;
	struct nfs4_secinfo_flavor flavors[0];
	struct nfs4_secinfo4	flavors[0];
};

struct nfs4_secinfo_arg {
+12 −2
Original line number Diff line number Diff line
@@ -25,10 +25,20 @@ struct gss_ctx {

#define GSS_C_NO_BUFFER		((struct xdr_netobj) 0)
#define GSS_C_NO_CONTEXT	((struct gss_ctx *) 0)
#define GSS_C_NULL_OID		((struct xdr_netobj) 0)

/*XXX  arbitrary length - is this set somewhere? */
#define GSS_OID_MAX_LEN 32
struct rpcsec_gss_oid {
	unsigned int	len;
	u8		data[GSS_OID_MAX_LEN];
};

/* From RFC 3530 */
struct rpcsec_gss_info {
	struct rpcsec_gss_oid	oid;
	u32			qop;
	u32			service;
};

/* gss-api prototypes; note that these are somewhat simplified versions of
 * the prototypes specified in RFC 2744. */
@@ -76,7 +86,7 @@ struct pf_desc {
struct gss_api_mech {
	struct list_head	gm_list;
	struct module		*gm_owner;
	struct xdr_netobj	gm_oid;
	struct rpcsec_gss_oid	gm_oid;
	char			*gm_name;
	const struct gss_api_ops *gm_ops;
	/* pseudoflavors supported by this mechanism: */
+1 −1
Original line number Diff line number Diff line
@@ -754,7 +754,7 @@ MODULE_ALIAS("rpc-auth-gss-390005");
static struct gss_api_mech gss_kerberos_mech = {
	.gm_name	= "krb5",
	.gm_owner	= THIS_MODULE,
	.gm_oid		= {9, (void *)"\x2a\x86\x48\x86\xf7\x12\x01\x02\x02"},
	.gm_oid		= { 9, "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02" },
	.gm_ops		= &gss_kerberos_ops,
	.gm_pf_num	= ARRAY_SIZE(gss_kerberos_pfs),
	.gm_pfs		= gss_kerberos_pfs,