diff options
Diffstat (limited to 'fs/nfsd')
-rw-r--r-- | fs/nfsd/nfs4acl.c | 50 |
1 files changed, 1 insertions, 49 deletions
diff --git a/fs/nfsd/nfs4acl.c b/fs/nfsd/nfs4acl.c index 59fd76651781..eaf4605a4b9e 100644 --- a/fs/nfsd/nfs4acl.c +++ b/fs/nfsd/nfs4acl.c | |||
@@ -499,43 +499,13 @@ static inline void add_to_mask(struct posix_acl_state *state, struct posix_ace_s | |||
499 | state->mask.allow |= astate->allow; | 499 | state->mask.allow |= astate->allow; |
500 | } | 500 | } |
501 | 501 | ||
502 | /* | ||
503 | * Certain bits (SYNCHRONIZE, DELETE, WRITE_OWNER, READ/WRITE_NAMED_ATTRS, | ||
504 | * READ_ATTRIBUTES, READ_ACL) are currently unenforceable and don't translate | ||
505 | * to traditional read/write/execute permissions. | ||
506 | * | ||
507 | * It's problematic to reject acls that use certain mode bits, because it | ||
508 | * places the burden on users to learn the rules about which bits one | ||
509 | * particular server sets, without giving the user a lot of help--we return an | ||
510 | * error that could mean any number of different things. To make matters | ||
511 | * worse, the problematic bits might be introduced by some application that's | ||
512 | * automatically mapping from some other acl model. | ||
513 | * | ||
514 | * So wherever possible we accept anything, possibly erring on the side of | ||
515 | * denying more permissions than necessary. | ||
516 | * | ||
517 | * However we do reject *explicit* DENY's of a few bits representing | ||
518 | * permissions we could never deny: | ||
519 | */ | ||
520 | |||
521 | static inline int check_deny(u32 mask, int isowner) | ||
522 | { | ||
523 | if (mask & (NFS4_ACE_READ_ATTRIBUTES | NFS4_ACE_READ_ACL)) | ||
524 | return -EINVAL; | ||
525 | if (!isowner) | ||
526 | return 0; | ||
527 | if (mask & (NFS4_ACE_WRITE_ATTRIBUTES | NFS4_ACE_WRITE_ACL)) | ||
528 | return -EINVAL; | ||
529 | return 0; | ||
530 | } | ||
531 | |||
532 | static struct posix_acl * | 502 | static struct posix_acl * |
533 | posix_state_to_acl(struct posix_acl_state *state, unsigned int flags) | 503 | posix_state_to_acl(struct posix_acl_state *state, unsigned int flags) |
534 | { | 504 | { |
535 | struct posix_acl_entry *pace; | 505 | struct posix_acl_entry *pace; |
536 | struct posix_acl *pacl; | 506 | struct posix_acl *pacl; |
537 | int nace; | 507 | int nace; |
538 | int i, error = 0; | 508 | int i; |
539 | 509 | ||
540 | /* | 510 | /* |
541 | * ACLs with no ACEs are treated differently in the inheritable | 511 | * ACLs with no ACEs are treated differently in the inheritable |
@@ -560,17 +530,11 @@ posix_state_to_acl(struct posix_acl_state *state, unsigned int flags) | |||
560 | 530 | ||
561 | pace = pacl->a_entries; | 531 | pace = pacl->a_entries; |
562 | pace->e_tag = ACL_USER_OBJ; | 532 | pace->e_tag = ACL_USER_OBJ; |
563 | error = check_deny(state->owner.deny, 1); | ||
564 | if (error) | ||
565 | goto out_err; | ||
566 | low_mode_from_nfs4(state->owner.allow, &pace->e_perm, flags); | 533 | low_mode_from_nfs4(state->owner.allow, &pace->e_perm, flags); |
567 | 534 | ||
568 | for (i=0; i < state->users->n; i++) { | 535 | for (i=0; i < state->users->n; i++) { |
569 | pace++; | 536 | pace++; |
570 | pace->e_tag = ACL_USER; | 537 | pace->e_tag = ACL_USER; |
571 | error = check_deny(state->users->aces[i].perms.deny, 0); | ||
572 | if (error) | ||
573 | goto out_err; | ||
574 | low_mode_from_nfs4(state->users->aces[i].perms.allow, | 538 | low_mode_from_nfs4(state->users->aces[i].perms.allow, |
575 | &pace->e_perm, flags); | 539 | &pace->e_perm, flags); |
576 | pace->e_uid = state->users->aces[i].uid; | 540 | pace->e_uid = state->users->aces[i].uid; |
@@ -579,18 +543,12 @@ posix_state_to_acl(struct posix_acl_state *state, unsigned int flags) | |||
579 | 543 | ||
580 | pace++; | 544 | pace++; |
581 | pace->e_tag = ACL_GROUP_OBJ; | 545 | pace->e_tag = ACL_GROUP_OBJ; |
582 | error = check_deny(state->group.deny, 0); | ||
583 | if (error) | ||
584 | goto out_err; | ||
585 | low_mode_from_nfs4(state->group.allow, &pace->e_perm, flags); | 546 | low_mode_from_nfs4(state->group.allow, &pace->e_perm, flags); |
586 | add_to_mask(state, &state->group); | 547 | add_to_mask(state, &state->group); |
587 | 548 | ||
588 | for (i=0; i < state->groups->n; i++) { | 549 | for (i=0; i < state->groups->n; i++) { |
589 | pace++; | 550 | pace++; |
590 | pace->e_tag = ACL_GROUP; | 551 | pace->e_tag = ACL_GROUP; |
591 | error = check_deny(state->groups->aces[i].perms.deny, 0); | ||
592 | if (error) | ||
593 | goto out_err; | ||
594 | low_mode_from_nfs4(state->groups->aces[i].perms.allow, | 552 | low_mode_from_nfs4(state->groups->aces[i].perms.allow, |
595 | &pace->e_perm, flags); | 553 | &pace->e_perm, flags); |
596 | pace->e_gid = state->groups->aces[i].gid; | 554 | pace->e_gid = state->groups->aces[i].gid; |
@@ -605,15 +563,9 @@ posix_state_to_acl(struct posix_acl_state *state, unsigned int flags) | |||
605 | 563 | ||
606 | pace++; | 564 | pace++; |
607 | pace->e_tag = ACL_OTHER; | 565 | pace->e_tag = ACL_OTHER; |
608 | error = check_deny(state->other.deny, 0); | ||
609 | if (error) | ||
610 | goto out_err; | ||
611 | low_mode_from_nfs4(state->other.allow, &pace->e_perm, flags); | 566 | low_mode_from_nfs4(state->other.allow, &pace->e_perm, flags); |
612 | 567 | ||
613 | return pacl; | 568 | return pacl; |
614 | out_err: | ||
615 | posix_acl_release(pacl); | ||
616 | return ERR_PTR(error); | ||
617 | } | 569 | } |
618 | 570 | ||
619 | static inline void allow_bits(struct posix_ace_state *astate, u32 mask) | 571 | static inline void allow_bits(struct posix_ace_state *astate, u32 mask) |