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: Chuck Lever <chuck.lever@oracle.com> Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
This commit is contained in:
Родитель
72f4dc117b
Коммит
fb15b26f8b
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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];
|
||||
unsigned int num_flavors;
|
||||
struct nfs4_secinfo4 flavors[0];
|
||||
};
|
||||
|
||||
struct nfs4_secinfo_arg {
|
||||
|
|
|
@ -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: */
|
||||
|
|
|
@ -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,
|
||||
|
|
Загрузка…
Ссылка в новой задаче