Most of vendor's servers implemeted some form of option B).
Option A) limits the client's ability to read all other ACEs in the ACL. It is a not very good choice. Option B) provides more information to client than option C). On an AIX client, the ACL display utility will display the received who string without interpreting them. As a result, option B) will work very well on a AIX client. On clients which have to map the string name into an id, if servers chooses to implement option B, clients can map invalid name strings to "nobody".
Options:
A) Only child file has the ACE
B) All offspring files have the ACE.
option B) may meet user's needs better.
Hummingbird and EMC have implemented option B). AIX has implemented option A). After studding the options, AIX decides to change its implementation from option A) to option B).
Here is some detailed information on option B) implementation: When a directory has an ACE4_FILE_INHERIT_ACE ACE, its child directory will have equivalent ACE with ACE4_INHERIT_ONLY_ACE and ACE4_FILE_INHERIT_ACE flags. As a result, it grandchild file will receive the ACE.
example:
parent:
allow guest read ACE4_FILE_INHERIT_ACE
child dir:
allow guest read ACE4_INHERIT_ONLY_ACE
and ACE4_FILE_INHERIT_ACE
grandchild file
allow guest read ACE4_FILE_INHERIT_ACE
Option A) sounds like a more logical solution, but option B) is the more user friendly solution. When parent directory does not have an inheritable ACE, it is likely that the server does not support inherence or the user forgot to set the inherit flag.
Most all vendors implemented or will implement
option B).
The agreement is that when special who is used, the ACE4_IDENTIFIER_GROUP flag should be ignored. On an AIX client, any end user can specify an ACE with special who (GROUP@) though the ACL library API. Users won't know whether the ACE4_IDENTIFIER_GROUP bit is required. It is better for the server to ignore the bit.
Some vendors implemented option A). But at Connecthon, most of them agreed that we will switch to option B).
AIX server allows file owner to read and write ACL. It seems to be a good idea for other vendors to follow the same policy.
Assume that a file's owner is guest@domain.com
and there are both OWNER@ and guest@domain.com ACEs.
A) only OWNER@ ACEs are used to generate owner
permission bit MODE4_*USR.
B) both OWNER@ and guest@domain.com are used
to generate owner permission bit MODE4_*USR.
Option A) is prefered over option B). If file's
owner is changed later, with option A), the mode bits are still correct.
Netapp and AIX both implement option A).
option B) is a more sensible solution, but the algorithm is hard to define. At this time, both AIX and Netapp implement option A). Hummingbird implements option B).
When a server receives mode and ACL in one SETATTR
operation, at the end of the operation the SUID, SGID, and SVTX bits in
the file's mode and the file's ACL need to match the data received from
SETATTR operation. Also they need to be set in an atomic fashion (all or
none) in case of system crash. One common code mistake is to consider ACL
and mode separately. It may result in one override the other's change.
A) Reject the ACL and return NFS4ERR_INVAL to
the client.
B) Store an ACL with zero number of ACEs. It
means no user has access to the file except root, owner. (Server may allow
file owner and super user rights to read/write ACL, even when ACL denies
all right).
C) Delete the ACL and use other means (mode bits)
to control access.
After talking to Saadia and Bruce, we think B) is the right answer. However, AIX currently implements A) and we don't plan to change it anytime soon.
We agree that option C) is not the right answer. Setting an ACL with zero number of ACEs should not grant more permission than an ACL with one ACE such as "allow admin read_attribute". Option C) will grant everyone permission to read attribute. On an UNIX machine, if we remove ACL, the only thing we can use to enforce access checking is the mode bits. A file with mode permission bit -------- grant some permission to everyone by default. An example is permssion to read file ACL ans attributes.
One question is what is the proper method for a client to remove ACL and return to mode bits only state? On netApp server and AIX server, SETATTR with mode bits without ACL will remove the file's ACL, but other vendors do not do this.
In AIX, option A) is used. There are two reasons for this. First, the server does not know weather the user's intention is B) or C) when it receives an ACL with no ACE. Second, it is hard to convince everyone that option B) is the right choice over option C).
We recommend option B). ACEs with permission mask equal to zero are needed as a place holder for Linux clients or servers to work. Linux client maps posix ACL to NFS4 ACL. Linux server maps NFS4 ACL received from the wire to POSIX before storing it. The NFS4 ACL generated by linux client and accepted by linux server follow a very strict format. Linux client may generate this type of ACEs. Sometime, clients have to add zero permission mask ACE in order for that ACL to meet the linux server input ACL format restrictions.
IBM, NetApp, Linux, EMC, Hummingbird server and client implemet option B).
A) A file/directory can be removed only if the
process has both ACE4_DELETE_CHILD and ACE4_DELETE permissions.
B) ACE4_DELETE overrides ACE4_DELETE_CHILD. When
an ACL explicitly specifies ACE4_DELETE in ALLOW ACE(s) or DENY ACE(s),
ACE4_DELETE take precedence over ACE4_DELETE_CHILD. If ACE4_DELETE is unspecified,
then ACE4_DELETE_CHILD defines the permission. In the case both are not
specified, deny is the default.
AIX currently implements A). Hummingbird currently
implements B). Netapp will implement B).
OWNER@ always allow:
ACE4_WRITE_ACL | ACE4_WRITE_ATTRIBUTES | ACE4_WRITE_NAMED_ATTRIBUTES
| ACE4_READ_ACL | ACE4_READ_ATTRIBUTES | ACE4_READ_NAMED_ATTRIBUTES | ACE4_DELETE
GROUP@ and EVERYONE@ always allow:
ACE4_READ_ACL | ACE4_READ_ATTRIBUTES | ACE4_READ_NAMED_ATTRIBUTES
| ACE4_DELETE
mask bits are related to "r', "w" and "x".
For Directory:
read: ACE4_LIST_DIRECTORY
write: ACE4_ADD_FILE
| ACE4_ADD_SUBDIRECTORY | ACE4_DELETE_CHILD
execute: ACE4_EXECUTE
For File:
read: ACE4_READ_DATA
write: ACE4_WRITE_DATA
| ACE4_APPEND_DATA | ACE4_DELETE_CHILD (optional )
execute: ACE4_EXECUTE
note: None of the above ( i.e. OWNER, GROUP and EVERYONE) is allowed for WRITE_OWNER. Only the root user has the privilege for that operation.
UNIX mode is mapped into 6 NFS4 aces.
allow OWNER@ owner_allow_mask
deny OWER@ all_mask&~owner_allow_mask
allow GROUP@ group_allow_mask
deny GROUP@ all_mask&~group_allow_mask
allow EVERYONE@ everyone_allow_mask
deny EVERYONE@ all_mask&~everyone_allow_mask
The following definitions in RFC are intend to
guide the mode to NFS4 acl mapping, but it does not match any discussed
algorithm. It needs to be changed.
> /*
> * ACE4_GENERIC_READ -- defined as combination
of
> * ACE4_READ_ACL
|
> * ACE4_READ_DATA
|
> * ACE4_READ_ATTRIBUTES
|
> * ACE4_READ_NAMED_ATTRIBUTES
|
> * ACE4_SYNCHRONIZE
> */
> /*
> * ACE4_GENERIC_WRITE -- defined as combination
of
> * ACE4_WRITE_DATA
|
> * ACE4_WRITE_ATTRIBUTES
|
> * ACE4_WRITE_NAMED_ATTRIBUTES
|
> * ACE4_WRITE_ACL
|
> * ACE4_APPEND_DATA
|
> * ACE4_SYNCHRONIZE
> */
>
> /*
> * ACE4_GENERIC_EXECUTE -- defined as
combination of
> * ACE4_EXECUTE
|
> * ACE4_SYNCHRONIZE
> */
> #define ACE4_GENERIC_ALL
(ACE4_GENERIC_READ | \
>
ACE4_GENERIC_WRITE | \
>
ACE4_GENERIC_EXECUTE | \
>
ACE4_DELETE | \
>
ACE4_DELETE_CHILD | \
>
ACE4_WRITE_OWNER)
>