diff options
Diffstat (limited to 'fs/nfsd/export.c')
-rw-r--r-- | fs/nfsd/export.c | 56 |
1 files changed, 54 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 | ||
457 | static 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 */ |
456 | static inline int fsloc_parse(char **mesg, char *buf, struct nfsd4_fs_locations *fsloc) { return 0; } | 495 | static inline int |
496 | fsloc_parse(char **mesg, char *buf, struct nfsd4_fs_locations *fsloc){return 0;} | ||
497 | static inline int | ||
498 | secinfo_parse(char **mesg, char *buf, struct svc_export *exp) { return 0; } | ||
457 | #endif | 499 | #endif |
458 | 500 | ||
459 | static int svc_export_parse(struct cache_detail *cd, char *mesg, int mlen) | 501 | static 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 | ||
675 | static struct cache_head *svc_export_alloc(void) | 727 | static struct cache_head *svc_export_alloc(void) |