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

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
...@@ -138,23 +138,23 @@ rpc_authflavor_t nfs_find_best_sec(struct nfs4_secinfo_flavors *flavors) ...@@ -138,23 +138,23 @@ rpc_authflavor_t nfs_find_best_sec(struct nfs4_secinfo_flavors *flavors)
{ {
struct gss_api_mech *mech; struct gss_api_mech *mech;
struct xdr_netobj oid; struct xdr_netobj oid;
int i; unsigned int i;
rpc_authflavor_t pseudoflavor = RPC_AUTH_UNIX; rpc_authflavor_t pseudoflavor = RPC_AUTH_UNIX;
for (i = 0; i < flavors->num_flavors; i++) { for (i = 0; i < flavors->num_flavors; i++) {
struct nfs4_secinfo_flavor *flavor; struct nfs4_secinfo4 *flavor = &flavors->flavors[i];
flavor = &flavors->flavors[i];
if (flavor->flavor == RPC_AUTH_NULL || flavor->flavor == RPC_AUTH_UNIX) { if (flavor->flavor == RPC_AUTH_NULL || flavor->flavor == RPC_AUTH_UNIX) {
pseudoflavor = flavor->flavor; pseudoflavor = flavor->flavor;
break; break;
} else if (flavor->flavor == RPC_AUTH_GSS) { } else if (flavor->flavor == RPC_AUTH_GSS) {
oid.len = flavor->gss.sec_oid4.len; oid.len = flavor->flavor_info.oid.len;
oid.data = flavor->gss.sec_oid4.data; oid.data = flavor->flavor_info.oid.data;
mech = gss_mech_get_by_OID(&oid); mech = gss_mech_get_by_OID(&oid);
if (!mech) if (!mech)
continue; continue;
pseudoflavor = gss_svc_to_pseudoflavor(mech, flavor->gss.service); pseudoflavor = gss_svc_to_pseudoflavor(mech,
flavor->flavor_info.service);
gss_mech_put(mech); gss_mech_put(mech);
break; break;
} }
......
...@@ -5205,27 +5205,30 @@ static int decode_delegreturn(struct xdr_stream *xdr) ...@@ -5205,27 +5205,30 @@ static int decode_delegreturn(struct xdr_stream *xdr)
return decode_op_hdr(xdr, OP_DELEGRETURN); 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; __be32 *p;
p = xdr_inline_decode(xdr, 4); p = xdr_inline_decode(xdr, 4);
if (unlikely(!p)) if (unlikely(!p))
goto out_overflow; goto out_overflow;
flavor->gss.sec_oid4.len = be32_to_cpup(p); oid_len = be32_to_cpup(p);
if (flavor->gss.sec_oid4.len > GSS_OID_MAX_LEN) if (oid_len > GSS_OID_MAX_LEN)
goto out_err; goto out_err;
p = xdr_inline_decode(xdr, flavor->gss.sec_oid4.len); p = xdr_inline_decode(xdr, oid_len);
if (unlikely(!p)) if (unlikely(!p))
goto out_overflow; 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); p = xdr_inline_decode(xdr, 8);
if (unlikely(!p)) if (unlikely(!p))
goto out_overflow; goto out_overflow;
flavor->gss.qop4 = be32_to_cpup(p++); flavor->flavor_info.qop = be32_to_cpup(p++);
flavor->gss.service = be32_to_cpup(p); flavor->flavor_info.service = be32_to_cpup(p);
return 0; return 0;
...@@ -5238,10 +5241,10 @@ static int decode_secinfo_gss(struct xdr_stream *xdr, struct nfs4_secinfo_flavor ...@@ -5238,10 +5241,10 @@ static int decode_secinfo_gss(struct xdr_stream *xdr, struct nfs4_secinfo_flavor
static int decode_secinfo_common(struct xdr_stream *xdr, struct nfs4_secinfo_res *res) 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; int status;
__be32 *p; __be32 *p;
int i, num_flavors;
p = xdr_inline_decode(xdr, 4); p = xdr_inline_decode(xdr, 4);
if (unlikely(!p)) if (unlikely(!p))
......
...@@ -1049,25 +1049,14 @@ struct nfs4_fs_locations_res { ...@@ -1049,25 +1049,14 @@ struct nfs4_fs_locations_res {
struct nfs4_fs_locations *fs_locations; struct nfs4_fs_locations *fs_locations;
}; };
struct nfs4_secinfo_oid { struct nfs4_secinfo4 {
unsigned int len; u32 flavor;
char data[GSS_OID_MAX_LEN]; struct rpcsec_gss_info flavor_info;
};
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_secinfo_flavors { struct nfs4_secinfo_flavors {
unsigned int num_flavors; unsigned int num_flavors;
struct nfs4_secinfo_flavor flavors[0]; struct nfs4_secinfo4 flavors[0];
}; };
struct nfs4_secinfo_arg { struct nfs4_secinfo_arg {
......
...@@ -25,10 +25,20 @@ struct gss_ctx { ...@@ -25,10 +25,20 @@ struct gss_ctx {
#define GSS_C_NO_BUFFER ((struct xdr_netobj) 0) #define GSS_C_NO_BUFFER ((struct xdr_netobj) 0)
#define GSS_C_NO_CONTEXT ((struct gss_ctx *) 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? */ /*XXX arbitrary length - is this set somewhere? */
#define GSS_OID_MAX_LEN 32 #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 /* gss-api prototypes; note that these are somewhat simplified versions of
* the prototypes specified in RFC 2744. */ * the prototypes specified in RFC 2744. */
...@@ -76,7 +86,7 @@ struct pf_desc { ...@@ -76,7 +86,7 @@ struct pf_desc {
struct gss_api_mech { struct gss_api_mech {
struct list_head gm_list; struct list_head gm_list;
struct module *gm_owner; struct module *gm_owner;
struct xdr_netobj gm_oid; struct rpcsec_gss_oid gm_oid;
char *gm_name; char *gm_name;
const struct gss_api_ops *gm_ops; const struct gss_api_ops *gm_ops;
/* pseudoflavors supported by this mechanism: */ /* pseudoflavors supported by this mechanism: */
......
...@@ -754,7 +754,7 @@ MODULE_ALIAS("rpc-auth-gss-390005"); ...@@ -754,7 +754,7 @@ MODULE_ALIAS("rpc-auth-gss-390005");
static struct gss_api_mech gss_kerberos_mech = { static struct gss_api_mech gss_kerberos_mech = {
.gm_name = "krb5", .gm_name = "krb5",
.gm_owner = THIS_MODULE, .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_ops = &gss_kerberos_ops,
.gm_pf_num = ARRAY_SIZE(gss_kerberos_pfs), .gm_pf_num = ARRAY_SIZE(gss_kerberos_pfs),
.gm_pfs = gss_kerberos_pfs, .gm_pfs = gss_kerberos_pfs,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment