aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/nfsd/export.c56
-rw-r--r--include/linux/nfsd/export.h17
2 files changed, 71 insertions, 2 deletions
diff --git a/fs/nfsd/export.c b/fs/nfsd/export.c
index d4accdcb53a2..fbbbcc5a2fa3 100644
--- a/fs/nfsd/export.c
+++ b/fs/nfsd/export.c
@@ -33,6 +33,8 @@
33#include <linux/nfsd/nfsfh.h> 33#include <linux/nfsd/nfsfh.h>
34#include <linux/nfsd/syscall.h> 34#include <linux/nfsd/syscall.h>
35#include <linux/lockd/bind.h> 35#include <linux/lockd/bind.h>
36#include <linux/sunrpc/msg_prot.h>
37#include <linux/sunrpc/gss_api.h>
36 38
37#define NFSDDBG_FACILITY NFSDDBG_EXPORT 39#define NFSDDBG_FACILITY NFSDDBG_EXPORT
38 40
@@ -452,8 +454,48 @@ out_free_all:
452 return err; 454 return err;
453} 455}
454 456
457static int secinfo_parse(char **mesg, char *buf, struct svc_export *exp)
458{
459 int listsize, err;
460 struct exp_flavor_info *f;
461
462 err = get_int(mesg, &listsize);
463 if (err)
464 return err;
465 if (listsize < 0 || listsize > MAX_SECINFO_LIST)
466 return -EINVAL;
467
468 for (f = exp->ex_flavors; f < exp->ex_flavors + listsize; f++) {
469 err = get_int(mesg, &f->pseudoflavor);
470 if (err)
471 return err;
472 /*
473 * Just a quick sanity check; we could also try to check
474 * whether this pseudoflavor is supported, but at worst
475 * an unsupported pseudoflavor on the export would just
476 * be a pseudoflavor that won't match the flavor of any
477 * authenticated request. The administrator will
478 * probably discover the problem when someone fails to
479 * authenticate.
480 */
481 if (f->pseudoflavor < 0)
482 return -EINVAL;
483 err = get_int(mesg, &f->flags);
484 if (err)
485 return err;
486 /* Only some flags are allowed to differ between flavors: */
487 if (~NFSEXP_SECINFO_FLAGS & (f->flags ^ exp->ex_flags))
488 return -EINVAL;
489 }
490 exp->ex_nflavors = listsize;
491 return 0;
492}
493
455#else /* CONFIG_NFSD_V4 */ 494#else /* CONFIG_NFSD_V4 */
456static inline int fsloc_parse(char **mesg, char *buf, struct nfsd4_fs_locations *fsloc) { return 0; } 495static inline int
496fsloc_parse(char **mesg, char *buf, struct nfsd4_fs_locations *fsloc){return 0;}
497static inline int
498secinfo_parse(char **mesg, char *buf, struct svc_export *exp) { return 0; }
457#endif 499#endif
458 500
459static int svc_export_parse(struct cache_detail *cd, char *mesg, int mlen) 501static int svc_export_parse(struct cache_detail *cd, char *mesg, int mlen)
@@ -477,6 +519,9 @@ static int svc_export_parse(struct cache_detail *cd, char *mesg, int mlen)
477 519
478 exp.ex_uuid = NULL; 520 exp.ex_uuid = NULL;
479 521
522 /* secinfo */
523 exp.ex_nflavors = 0;
524
480 if (mesg[mlen-1] != '\n') 525 if (mesg[mlen-1] != '\n')
481 return -EINVAL; 526 return -EINVAL;
482 mesg[mlen-1] = 0; 527 mesg[mlen-1] = 0;
@@ -554,7 +599,9 @@ static int svc_export_parse(struct cache_detail *cd, char *mesg, int mlen)
554 if (exp.ex_uuid == NULL) 599 if (exp.ex_uuid == NULL)
555 err = -ENOMEM; 600 err = -ENOMEM;
556 } 601 }
557 } else 602 } else if (strcmp(buf, "secinfo") == 0)
603 err = secinfo_parse(&mesg, buf, &exp);
604 else
558 /* quietly ignore unknown words and anything 605 /* quietly ignore unknown words and anything
559 * following. Newer user-space can try to set 606 * following. Newer user-space can try to set
560 * new values, then see what the result was. 607 * new values, then see what the result was.
@@ -655,6 +702,7 @@ static void export_update(struct cache_head *cnew, struct cache_head *citem)
655{ 702{
656 struct svc_export *new = container_of(cnew, struct svc_export, h); 703 struct svc_export *new = container_of(cnew, struct svc_export, h);
657 struct svc_export *item = container_of(citem, struct svc_export, h); 704 struct svc_export *item = container_of(citem, struct svc_export, h);
705 int i;
658 706
659 new->ex_flags = item->ex_flags; 707 new->ex_flags = item->ex_flags;
660 new->ex_anon_uid = item->ex_anon_uid; 708 new->ex_anon_uid = item->ex_anon_uid;
@@ -670,6 +718,10 @@ static void export_update(struct cache_head *cnew, struct cache_head *citem)
670 item->ex_fslocs.locations_count = 0; 718 item->ex_fslocs.locations_count = 0;
671 new->ex_fslocs.migrated = item->ex_fslocs.migrated; 719 new->ex_fslocs.migrated = item->ex_fslocs.migrated;
672 item->ex_fslocs.migrated = 0; 720 item->ex_fslocs.migrated = 0;
721 new->ex_nflavors = item->ex_nflavors;
722 for (i = 0; i < MAX_SECINFO_LIST; i++) {
723 new->ex_flavors[i] = item->ex_flavors[i];
724 }
673} 725}
674 726
675static struct cache_head *svc_export_alloc(void) 727static struct cache_head *svc_export_alloc(void)
diff --git a/include/linux/nfsd/export.h b/include/linux/nfsd/export.h
index 9f62d6182d32..736f0eafcedf 100644
--- a/include/linux/nfsd/export.h
+++ b/include/linux/nfsd/export.h
@@ -42,6 +42,8 @@
42#define NFSEXP_NOACL 0x8000 /* reserved for possible ACL related use */ 42#define NFSEXP_NOACL 0x8000 /* reserved for possible ACL related use */
43#define NFSEXP_ALLFLAGS 0xFE3F 43#define NFSEXP_ALLFLAGS 0xFE3F
44 44
45/* The flags that may vary depending on security flavor: */
46#define NFSEXP_SECINFO_FLAGS 0
45 47
46#ifdef __KERNEL__ 48#ifdef __KERNEL__
47 49
@@ -64,6 +66,19 @@ struct nfsd4_fs_locations {
64 int migrated; 66 int migrated;
65}; 67};
66 68
69/*
70 * We keep an array of pseudoflavors with the export, in order from most
71 * to least preferred. For the forseeable future, we don't expect more
72 * than the eight pseudoflavors null, unix, krb5, krb5i, krb5p, skpm3,
73 * spkm3i, and spkm3p (and using all 8 at once should be rare).
74 */
75#define MAX_SECINFO_LIST 8
76
77struct exp_flavor_info {
78 u32 pseudoflavor;
79 u32 flags;
80};
81
67struct svc_export { 82struct svc_export {
68 struct cache_head h; 83 struct cache_head h;
69 struct auth_domain * ex_client; 84 struct auth_domain * ex_client;
@@ -76,6 +91,8 @@ struct svc_export {
76 int ex_fsid; 91 int ex_fsid;
77 unsigned char * ex_uuid; /* 16 byte fsid */ 92 unsigned char * ex_uuid; /* 16 byte fsid */
78 struct nfsd4_fs_locations ex_fslocs; 93 struct nfsd4_fs_locations ex_fslocs;
94 int ex_nflavors;
95 struct exp_flavor_info ex_flavors[MAX_SECINFO_LIST];
79}; 96};
80 97
81/* an "export key" (expkey) maps a filehandlefragement to an 98/* an "export key" (expkey) maps a filehandlefragement to an