aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfsd
diff options
context:
space:
mode:
authorJ. Bruce Fields <bfields@citi.umich.edu>2007-02-16 04:28:37 -0500
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-02-16 11:14:01 -0500
commit3160a711ef754758e7f85ae371cf900252c1a392 (patch)
treed8c9e37b72c60c8b2c673bb4101bfbc9743a4163 /fs/nfsd
parentbec50c47aaf6f1f9247f1860547ab394a0802a4c (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')
-rw-r--r--fs/nfsd/nfs4acl.c21
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
418struct posix_acl_state { 418struct 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);