[PATCH 04/16] nfsd4: parse secinfo information in exports downcall

Trond Myklebust trond.myklebust at fys.uio.no
Fri May 18 18:07:59 EDT 2007


On Fri, 2007-05-18 at 17:27 -0400, J. Bruce Fields wrote:
> From: andros at citi.umich.edu <andros at citi.umich.edu>
> 
> We add a list of pseudoflavors to each export downcall, which will be used
> both as a list of security flavors allowed on that export, and (in the
> order given) as the list of pseudoflavors to return on secinfo calls.
> 
> This patch parses the new downcall information and adds it to the export
> structure, but doesn't use it for anything yet.
> 
> Signed-off-by: J. Bruce Fields <bfields at citi.umich.edu>
> Signed-off-by: Andy Adamson <andros at citi.umich.edu>
> ---
>  fs/nfsd/export.c            |   49 ++++++++++++++++++++++++++++++++++++++++++-
>  include/linux/nfsd/export.h |   15 +++++++++++++
>  2 files changed, 63 insertions(+), 1 deletions(-)
> 
> diff --git a/fs/nfsd/export.c b/fs/nfsd/export.c
> index 2f503c7..ed30ccc 100644
> --- a/fs/nfsd/export.c
> +++ b/fs/nfsd/export.c
> @@ -32,6 +32,8 @@
>  #include <linux/nfsd/nfsfh.h>
>  #include <linux/nfsd/syscall.h>
>  #include <linux/lockd/bind.h>
> +#include <linux/sunrpc/msg_prot.h>
> +#include <linux/sunrpc/gss_api.h>
>  
>  #define NFSDDBG_FACILITY	NFSDDBG_EXPORT
>  
> @@ -451,8 +453,43 @@ out_free_all:
>  	return err;
>  }
>  
> +static int secinfo_parse(char **mesg, char *buf, struct svc_export *exp)
> +{
> +	int listsize, err;
> +	struct exp_flavor_info *f;
> +
> +	err = get_int(mesg, &listsize);
> +	if (err)
> +		return err;
> +	if (listsize < 0 || listsize > MAX_SECINFO_LIST)
> +		return -EINVAL;
> +
> +	for (f=exp->ex_flavors; f < exp->ex_flavors + listsize; f++) {
> +		err = get_int(mesg, &f->pseudoflavor);
> +		if (err)
> +			return err;
> +		/*
> +		 * Just a quick sanity check; we could also try to check
> +		 * whether this pseudoflavor is supported, but at worst
> +		 * an unsupported pseudoflavor on the export would just
> +		 * be a pseudoflavor that won't match the flavor of any
> +		 * authenticated request.  The administrator will
> +		 * probably discover the problem when someone fails to
> +		 * authenticate.
> +		 */
> +		if (f->pseudoflavor < 0)
> +			return -EINVAL;
> +		err = get_int(mesg, &f->flags);
> +		if (err)
> +			return err;
> +	}
> +	exp->ex_nflavors = listsize;
> +	return 0;
> +}
> +
>  #else /* CONFIG_NFSD_V4 */
>  static inline int fsloc_parse(char **mesg, char *buf, struct nfsd4_fs_locations *fsloc) { return 0; }
> +static inline int secinfo_parse(char **mesg, char *buf, struct svc_export *exp) { return 0; }
>  #endif
>  
>  static int svc_export_parse(struct cache_detail *cd, char *mesg, int mlen)
> @@ -476,6 +513,9 @@ static int svc_export_parse(struct cache_detail *cd, char *mesg, int mlen)
>  
>  	exp.ex_uuid = NULL;
>  
> +	/* secinfo */
> +	exp.ex_nflavors = 0;
> +
>  	if (mesg[mlen-1] != '\n')
>  		return -EINVAL;
>  	mesg[mlen-1] = 0;
> @@ -553,7 +593,9 @@ static int svc_export_parse(struct cache_detail *cd, char *mesg, int mlen)
>  					if (exp.ex_uuid == NULL)
>  						err = -ENOMEM;
>  				}
> -			} else
> +			} if (strcmp(buf, "secinfo") == 0)
			 ^^^ else if (

or you will cause fsloc and uuid to fall into the 'can't parse' case.

> +				err = secinfo_parse(&mesg, buf, &exp);
> +			else
>  				/* quietly ignore unknown words and anything
>  				 * following. Newer user-space can try to set
>  				 * new values, then see what the result was.
> @@ -654,6 +696,7 @@ static void export_update(struct cache_head *cnew, struct cache_head *citem)
>  {
>  	struct svc_export *new = container_of(cnew, struct svc_export, h);
>  	struct svc_export *item = container_of(citem, struct svc_export, h);
> +	int i;
>  
>  	new->ex_flags = item->ex_flags;
>  	new->ex_anon_uid = item->ex_anon_uid;
> @@ -669,6 +712,10 @@ static void export_update(struct cache_head *cnew, struct cache_head *citem)
>  	item->ex_fslocs.locations_count = 0;
>  	new->ex_fslocs.migrated = item->ex_fslocs.migrated;
>  	item->ex_fslocs.migrated = 0;
> +	new->ex_nflavors = item->ex_nflavors;
> +	for (i = 0; i < MAX_SECINFO_LIST; i++){
> +		new->ex_flavors[i] = item->ex_flavors[i];
> +	}
>  }
>  
>  static struct cache_head *svc_export_alloc(void)
> diff --git a/include/linux/nfsd/export.h b/include/linux/nfsd/export.h
> index 9f62d61..d97a268 100644
> --- a/include/linux/nfsd/export.h
> +++ b/include/linux/nfsd/export.h
> @@ -64,6 +64,19 @@ struct nfsd4_fs_locations {
>  	int migrated;
>  };
>  
> +/*
> + * We keep an array of pseudoflavors with the export, in order from most
> + * to least preferred.  For the forseeable future, we don't expect more
> + * than the eight pseudoflavors null, unix, krb5, krb5i, krb5p, skpm3,
> + * spkm3i, and spkm3p (and using all 8 at once should be rare).
> + */
> +#define MAX_SECINFO_LIST	8
> +
> +struct exp_flavor_info {
> +	u32	pseudoflavor;
> +	u32	flags;
> +};
> +
>  struct svc_export {
>  	struct cache_head	h;
>  	struct auth_domain *	ex_client;
> @@ -76,6 +89,8 @@ struct svc_export {
>  	int			ex_fsid;
>  	unsigned char *		ex_uuid; /* 16 byte fsid */
>  	struct nfsd4_fs_locations ex_fslocs;
> +	int			ex_nflavors;
> +	struct exp_flavor_info	ex_flavors[MAX_SECINFO_LIST];
>  };
>  
>  /* an "export key" (expkey) maps a filehandlefragement to an



More information about the NFSv4 mailing list