svcrpc: store gss mech in svc_cred

Store a pointer to the gss mechanism used in the rq_cred and cl_cred.
This will make it easier to enforce SP4_MACH_CRED, which needs to
compare the mechanism used on the exchange_id with that used on
protected operations.

Signed-off-by: J. Bruce Fields <bfields@redhat.com>
This commit is contained in:
J. Bruce Fields 2013-05-14 16:07:13 -04:00
parent 4423406391
commit 0dc1531aca
5 changed files with 14 additions and 4 deletions

View file

@ -1188,6 +1188,9 @@ static int copy_cred(struct svc_cred *target, struct svc_cred *source)
target->cr_gid = source->cr_gid; target->cr_gid = source->cr_gid;
target->cr_group_info = source->cr_group_info; target->cr_group_info = source->cr_group_info;
get_group_info(target->cr_group_info); get_group_info(target->cr_group_info);
target->cr_gss_mech = source->cr_gss_mech;
if (source->cr_gss_mech)
gss_mech_get(source->cr_gss_mech);
return 0; return 0;
} }

View file

@ -151,6 +151,8 @@ struct gss_api_mech *gss_mech_get_by_pseudoflavor(u32);
/* Fill in an array with a list of supported pseudoflavors */ /* Fill in an array with a list of supported pseudoflavors */
int gss_mech_list_pseudoflavors(rpc_authflavor_t *, int); int gss_mech_list_pseudoflavors(rpc_authflavor_t *, int);
struct gss_api_mech * gss_mech_get(struct gss_api_mech *);
/* For every successful gss_mech_get or gss_mech_get_by_* call there must be a /* For every successful gss_mech_get or gss_mech_get_by_* call there must be a
* corresponding call to gss_mech_put. */ * corresponding call to gss_mech_put. */
void gss_mech_put(struct gss_api_mech *); void gss_mech_put(struct gss_api_mech *);

View file

@ -14,6 +14,7 @@
#include <linux/string.h> #include <linux/string.h>
#include <linux/sunrpc/msg_prot.h> #include <linux/sunrpc/msg_prot.h>
#include <linux/sunrpc/cache.h> #include <linux/sunrpc/cache.h>
#include <linux/sunrpc/gss_api.h>
#include <linux/hash.h> #include <linux/hash.h>
#include <linux/cred.h> #include <linux/cred.h>
@ -23,6 +24,7 @@ struct svc_cred {
struct group_info *cr_group_info; struct group_info *cr_group_info;
u32 cr_flavor; /* pseudoflavor */ u32 cr_flavor; /* pseudoflavor */
char *cr_principal; /* for gss */ char *cr_principal; /* for gss */
struct gss_api_mech *cr_gss_mech;
}; };
static inline void init_svc_cred(struct svc_cred *cred) static inline void init_svc_cred(struct svc_cred *cred)
@ -37,6 +39,8 @@ static inline void free_svc_cred(struct svc_cred *cred)
if (cred->cr_group_info) if (cred->cr_group_info)
put_group_info(cred->cr_group_info); put_group_info(cred->cr_group_info);
kfree(cred->cr_principal); kfree(cred->cr_principal);
gss_mech_put(cred->cr_gss_mech);
init_svc_cred(cred);
} }
struct svc_rqst; /* forward decl */ struct svc_rqst; /* forward decl */

View file

@ -139,11 +139,12 @@ void gss_mech_unregister(struct gss_api_mech *gm)
} }
EXPORT_SYMBOL_GPL(gss_mech_unregister); EXPORT_SYMBOL_GPL(gss_mech_unregister);
static struct gss_api_mech *gss_mech_get(struct gss_api_mech *gm) struct gss_api_mech *gss_mech_get(struct gss_api_mech *gm)
{ {
__module_get(gm->gm_owner); __module_get(gm->gm_owner);
return gm; return gm;
} }
EXPORT_SYMBOL(gss_mech_get);
static struct gss_api_mech * static struct gss_api_mech *
_gss_mech_get_by_name(const char *name) _gss_mech_get_by_name(const char *name)
@ -360,6 +361,7 @@ gss_pseudoflavor_to_service(struct gss_api_mech *gm, u32 pseudoflavor)
} }
return 0; return 0;
} }
EXPORT_SYMBOL(gss_pseudoflavor_to_service);
char * char *
gss_service_to_auth_domain_name(struct gss_api_mech *gm, u32 service) gss_service_to_auth_domain_name(struct gss_api_mech *gm, u32 service)
@ -379,6 +381,7 @@ gss_mech_put(struct gss_api_mech * gm)
if (gm) if (gm)
module_put(gm->gm_owner); module_put(gm->gm_owner);
} }
EXPORT_SYMBOL(gss_mech_put);
/* The mech could probably be determined from the token instead, but it's just /* The mech could probably be determined from the token instead, but it's just
* as easy for now to pass it in. */ * as easy for now to pass it in. */

View file

@ -391,7 +391,6 @@ update_rsc(struct cache_head *cnew, struct cache_head *ctmp)
memset(&new->seqdata, 0, sizeof(new->seqdata)); memset(&new->seqdata, 0, sizeof(new->seqdata));
spin_lock_init(&new->seqdata.sd_lock); spin_lock_init(&new->seqdata.sd_lock);
new->cred = tmp->cred; new->cred = tmp->cred;
new->cred.cr_principal = tmp->cred.cr_principal;
init_svc_cred(&tmp->cred); init_svc_cred(&tmp->cred);
} }
@ -485,7 +484,7 @@ static int rsc_parse(struct cache_detail *cd,
len = qword_get(&mesg, buf, mlen); len = qword_get(&mesg, buf, mlen);
if (len < 0) if (len < 0)
goto out; goto out;
gm = gss_mech_get_by_name(buf); gm = rsci.cred.cr_gss_mech = gss_mech_get_by_name(buf);
status = -EOPNOTSUPP; status = -EOPNOTSUPP;
if (!gm) if (!gm)
goto out; goto out;
@ -515,7 +514,6 @@ static int rsc_parse(struct cache_detail *cd,
rscp = rsc_update(cd, &rsci, rscp); rscp = rsc_update(cd, &rsci, rscp);
status = 0; status = 0;
out: out:
gss_mech_put(gm);
rsc_free(&rsci); rsc_free(&rsci);
if (rscp) if (rscp)
cache_put(&rscp->h, cd); cache_put(&rscp->h, cd);