SUNRPC: Define rpcsec_gss_info structure
authorChuck Lever <chuck.lever@oracle.com>
Sat, 16 Mar 2013 19:54:34 +0000 (15:54 -0400)
committerTrond Myklebust <Trond.Myklebust@netapp.com>
Fri, 29 Mar 2013 19:42:56 +0000 (15:42 -0400)
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>
fs/nfs/nfs4namespace.c
fs/nfs/nfs4xdr.c
include/linux/nfs_xdr.h
include/linux/sunrpc/gss_api.h
net/sunrpc/auth_gss/gss_krb5_mech.c

index 0dd766079e1ca34feb26ba2da2dafafeb1e24060..88231c92317c4338c61bc4dfbaac5dc216859879 100644 (file)
@@ -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;
                }
index 0b744895b9e19e80841abd899f6937585d1d209e..a38fd179c34f12fe7c4750e44820b38e41074283 100644 (file)
@@ -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))
index c1ca1f3f4935b27d288cedd7c20a8b9d61d42157..b759467741eb82e1788dec80bf5c2e106cce59e4 100644 (file)
@@ -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 {
index a19e2547ae6aba4481ba4cd01f5bdbbf7545de22..98950e5a887763759082115a7234d97e12e0c9c2 100644 (file)
@@ -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: */
index d3611f11a8dfc0767ab5736a87740a68f7645f8d..61d36ce3b366d71e0068abe016beff5473659209 100644 (file)
@@ -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,