diff options
author | J. Bruce Fields <bfields@citi.umich.edu> | 2007-02-16 04:28:37 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-02-16 11:14:01 -0500 |
commit | 3160a711ef754758e7f85ae371cf900252c1a392 (patch) | |
tree | d8c9e37b72c60c8b2c673bb4101bfbc9743a4163 /fs/nfsd/nfs4acl.c | |
parent | bec50c47aaf6f1f9247f1860547ab394a0802a4c (diff) |
[PATCH] knfsd: nfsd4: fix handling of directories without default ACLs
When setting an ACL that lacks inheritable ACEs on a directory, we should set
a default ACL of zero length, not a default ACL with all bits denied.
Signed-off-by: "J. Bruce Fields" <bfields@citi.umich.edu>
Signed-off-by: Neil Brown <neilb@suse.de>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs/nfsd/nfs4acl.c')
-rw-r--r-- | fs/nfsd/nfs4acl.c | 21 |
1 files changed, 20 insertions, 1 deletions
diff --git a/fs/nfsd/nfs4acl.c b/fs/nfsd/nfs4acl.c index 0a69cce33efe..832673b14587 100644 --- a/fs/nfsd/nfs4acl.c +++ b/fs/nfsd/nfs4acl.c | |||
@@ -416,6 +416,7 @@ struct posix_ace_state_array { | |||
416 | * calculated so far: */ | 416 | * calculated so far: */ |
417 | 417 | ||
418 | struct posix_acl_state { | 418 | struct posix_acl_state { |
419 | int empty; | ||
419 | struct posix_ace_state owner; | 420 | struct posix_ace_state owner; |
420 | struct posix_ace_state group; | 421 | struct posix_ace_state group; |
421 | struct posix_ace_state other; | 422 | struct posix_ace_state other; |
@@ -431,6 +432,7 @@ init_state(struct posix_acl_state *state, int cnt) | |||
431 | int alloc; | 432 | int alloc; |
432 | 433 | ||
433 | memset(state, 0, sizeof(struct posix_acl_state)); | 434 | memset(state, 0, sizeof(struct posix_acl_state)); |
435 | state->empty = 1; | ||
434 | /* | 436 | /* |
435 | * In the worst case, each individual acl could be for a distinct | 437 | * In the worst case, each individual acl could be for a distinct |
436 | * named user or group, but we don't no which, so we allocate | 438 | * named user or group, but we don't no which, so we allocate |
@@ -498,6 +500,20 @@ posix_state_to_acl(struct posix_acl_state *state, unsigned int flags) | |||
498 | int nace; | 500 | int nace; |
499 | int i, error = 0; | 501 | int i, error = 0; |
500 | 502 | ||
503 | /* | ||
504 | * ACLs with no ACEs are treated differently in the inheritable | ||
505 | * and effective cases: when there are no inheritable ACEs, we | ||
506 | * set a zero-length default posix acl: | ||
507 | */ | ||
508 | if (state->empty && (flags & NFS4_ACL_TYPE_DEFAULT)) { | ||
509 | pacl = posix_acl_alloc(0, GFP_KERNEL); | ||
510 | return pacl ? pacl : ERR_PTR(-ENOMEM); | ||
511 | } | ||
512 | /* | ||
513 | * When there are no effective ACEs, the following will end | ||
514 | * up setting a 3-element effective posix ACL with all | ||
515 | * permissions zero. | ||
516 | */ | ||
501 | nace = 4 + state->users->n + state->groups->n; | 517 | nace = 4 + state->users->n + state->groups->n; |
502 | pacl = posix_acl_alloc(nace, GFP_KERNEL); | 518 | pacl = posix_acl_alloc(nace, GFP_KERNEL); |
503 | if (!pacl) | 519 | if (!pacl) |
@@ -613,6 +629,8 @@ static void process_one_v4_ace(struct posix_acl_state *state, | |||
613 | u32 mask = ace->access_mask; | 629 | u32 mask = ace->access_mask; |
614 | int i; | 630 | int i; |
615 | 631 | ||
632 | state->empty = 0; | ||
633 | |||
616 | switch (ace2type(ace)) { | 634 | switch (ace2type(ace)) { |
617 | case ACL_USER_OBJ: | 635 | case ACL_USER_OBJ: |
618 | if (ace->type == NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE) { | 636 | if (ace->type == NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE) { |
@@ -717,7 +735,8 @@ int nfs4_acl_nfsv4_to_posix(struct nfs4_acl *acl, struct posix_acl **pacl, | |||
717 | ret = PTR_ERR(*pacl); | 735 | ret = PTR_ERR(*pacl); |
718 | goto out_dstate; | 736 | goto out_dstate; |
719 | } | 737 | } |
720 | *dpacl = posix_state_to_acl(&default_acl_state, flags); | 738 | *dpacl = posix_state_to_acl(&default_acl_state, |
739 | flags | NFS4_ACL_TYPE_DEFAULT); | ||
721 | if (IS_ERR(*dpacl)) { | 740 | if (IS_ERR(*dpacl)) { |
722 | ret = PTR_ERR(*dpacl); | 741 | ret = PTR_ERR(*dpacl); |
723 | posix_acl_release(*pacl); | 742 | posix_acl_release(*pacl); |