6. Access Control Attributes
Access Control Lists (ACLs) are file attributes that specify fine- grained access control. This section covers the "acl", "aclsupport", and "mode" file attributes, and their interactions. Note that file attributes may apply to any file system object.6.1. Goals
ACLs and modes represent two well-established models for specifying permissions. This section specifies requirements that attempt to meet the following goals: o If a server supports the mode attribute, it should provide reasonable semantics to clients that only set and retrieve the mode attribute. o If a server supports ACL attributes, it should provide reasonable semantics to clients that only set and retrieve those attributes. o On servers that support the mode attribute, if ACL attributes have never been set on an object, via inheritance or explicitly, the behavior should be traditional UNIX-like behavior. o On servers that support the mode attribute, if the ACL attributes have been previously set on an object, either explicitly or via inheritance: * Setting only the mode attribute should effectively control the traditional UNIX-like permissions of read, write, and execute on owner, owner_group, and other.
* Setting only the mode attribute should provide reasonable
security. For example, setting a mode of 000 should be enough
to ensure that future opens for read or write by any principal
fail, regardless of a previously existing or inherited ACL.
o When a mode attribute is set on an object, the ACL attributes may
need to be modified so as to not conflict with the new mode. In
such cases, it is desirable that the ACL keep as much information
as possible. This includes information about inheritance, AUDIT
and ALARM access control entries (ACEs), and permissions granted
and denied that do not conflict with the new mode.
6.2. File Attributes Discussion
Support for each of the ACL attributes is RECOMMENDED and not
required, since file systems accessed using NFSv4 might not
support ACLs.
6.2.1. Attribute 12: acl
The NFSv4.0 ACL attribute contains an array of ACEs that are
associated with the file system object. Although the client can read
and write the acl attribute, the server is responsible for using the
ACL to perform access control. The client can use the OPEN or ACCESS
operations to check access without modifying or reading data or
metadata.
The NFS ACE structure is defined as follows:
typedef uint32_t acetype4;
typedef uint32_t aceflag4;
typedef uint32_t acemask4;
struct nfsace4 {
acetype4 type;
aceflag4 flag;
acemask4 access_mask;
utf8str_mixed who;
};
To determine if a request succeeds, the server processes each nfsace4
entry in order. Only ACEs that have a "who" that matches the
requester are considered. Each ACE is processed until all of the
bits of the requester's access have been ALLOWED. Once a bit (see
below) has been ALLOWED by an ACCESS_ALLOWED_ACE, it is no longer
considered in the processing of later ACEs. If an ACCESS_DENIED_ACE
is encountered where the requester's access still has unALLOWED bits in common with the "access_mask" of the ACE, the request is denied. When the ACL is fully processed, if there are bits in the requester's mask that have not been ALLOWED or DENIED, access is denied. Unlike the ALLOW and DENY ACE types, the ALARM and AUDIT ACE types do not affect a requester's access and instead are for triggering events as a result of a requester's access attempt. Therefore, AUDIT and ALARM ACEs are processed only after processing ALLOW and DENY ACEs. The NFSv4.0 ACL model is quite rich. Some server platforms may provide access control functionality that goes beyond the UNIX-style mode attribute but that is not as rich as the NFS ACL model. So that users can take advantage of this more limited functionality, the server may support the acl attributes by mapping between its ACL model and the NFSv4.0 ACL model. Servers must ensure that the ACL they actually store or enforce is at least as strict as the NFSv4 ACL that was set. It is tempting to accomplish this by rejecting any ACL that falls outside the small set that can be represented accurately. However, such an approach can render ACLs unusable without special client-side knowledge of the server's mapping, which defeats the purpose of having a common NFSv4 ACL protocol. Therefore, servers should accept every ACL that they can without compromising security. To help accomplish this, servers may make a special exception, in the case of unsupported permission bits, to the rule that bits not ALLOWED or DENIED by an ACL must be denied. For example, a UNIX- style server might choose to silently allow read attribute permissions even though an ACL does not explicitly allow those permissions. (An ACL that explicitly denies permission to read attributes should still result in a denial.) The situation is complicated by the fact that a server may have multiple modules that enforce ACLs. For example, the enforcement for NFSv4.0 access may be different from, but not weaker than, the enforcement for local access, and both may be different from the enforcement for access through other protocols such as Server Message Block (SMB) [MS-SMB]. So it may be useful for a server to accept an ACL even if not all of its modules are able to support it. The guiding principle with regard to NFSv4 access is that the server must not accept ACLs that give an appearance of more restricted access to a file than what is actually enforced.
6.2.1.1. ACE Type
The constants used for the type field (acetype4) are as follows: const ACE4_ACCESS_ALLOWED_ACE_TYPE = 0x00000000; const ACE4_ACCESS_DENIED_ACE_TYPE = 0x00000001; const ACE4_SYSTEM_AUDIT_ACE_TYPE = 0x00000002; const ACE4_SYSTEM_ALARM_ACE_TYPE = 0x00000003; All four bit types are permitted in the acl attribute. +------------------------------+--------------+---------------------+ | Value | Abbreviation | Description | +------------------------------+--------------+---------------------+ | ACE4_ACCESS_ALLOWED_ACE_TYPE | ALLOW | Explicitly grants | | | | the access defined | | | | in acemask4 to the | | | | file or directory. | | | | | | ACE4_ACCESS_DENIED_ACE_TYPE | DENY | Explicitly denies | | | | the access defined | | | | in acemask4 to the | | | | file or directory. | | | | | | ACE4_SYSTEM_AUDIT_ACE_TYPE | AUDIT | LOG (in a system- | | | | dependent way) any | | | | access attempt to a | | | | file or directory | | | | that uses any of | | | | the access methods | | | | specified in | | | | acemask4. | | | | | | ACE4_SYSTEM_ALARM_ACE_TYPE | ALARM | Generate a system | | | | ALARM (system | | | | dependent) when any | | | | access attempt is | | | | made to a file or | | | | directory for the | | | | access methods | | | | specified in | | | | acemask4. | +------------------------------+--------------+---------------------+ The "Abbreviation" column denotes how the types will be referred to throughout the rest of this section.
6.2.1.2. Attribute 13: aclsupport
A server need not support all of the above ACE types. This attribute indicates which ACE types are supported for the current file system. The bitmask constants used to represent the above definitions within the aclsupport attribute are as follows: const ACL4_SUPPORT_ALLOW_ACL = 0x00000001; const ACL4_SUPPORT_DENY_ACL = 0x00000002; const ACL4_SUPPORT_AUDIT_ACL = 0x00000004; const ACL4_SUPPORT_ALARM_ACL = 0x00000008; Servers that support either the ALLOW or DENY ACE type SHOULD support both ALLOW and DENY ACE types. Clients should not attempt to set an ACE unless the server claims support for that ACE type. If the server receives a request to set an ACE that it cannot store, it MUST reject the request with NFS4ERR_ATTRNOTSUPP. If the server receives a request to set an ACE that it can store but cannot enforce, the server SHOULD reject the request with NFS4ERR_ATTRNOTSUPP.6.2.1.3. ACE Access Mask
The bitmask constants used for the access mask field are as follows: const ACE4_READ_DATA = 0x00000001; const ACE4_LIST_DIRECTORY = 0x00000001; const ACE4_WRITE_DATA = 0x00000002; const ACE4_ADD_FILE = 0x00000002; const ACE4_APPEND_DATA = 0x00000004; const ACE4_ADD_SUBDIRECTORY = 0x00000004; const ACE4_READ_NAMED_ATTRS = 0x00000008; const ACE4_WRITE_NAMED_ATTRS = 0x00000010; const ACE4_EXECUTE = 0x00000020; const ACE4_DELETE_CHILD = 0x00000040; const ACE4_READ_ATTRIBUTES = 0x00000080; const ACE4_WRITE_ATTRIBUTES = 0x00000100; const ACE4_DELETE = 0x00010000; const ACE4_READ_ACL = 0x00020000; const ACE4_WRITE_ACL = 0x00040000; const ACE4_WRITE_OWNER = 0x00080000; const ACE4_SYNCHRONIZE = 0x00100000;
Note that some masks have coincident values -- for example, ACE4_READ_DATA and ACE4_LIST_DIRECTORY. The mask entries ACE4_LIST_DIRECTORY, ACE4_ADD_FILE, and ACE4_ADD_SUBDIRECTORY are intended to be used with directory objects, while ACE4_READ_DATA, ACE4_WRITE_DATA, and ACE4_APPEND_DATA are intended to be used with non-directory objects.6.2.1.3.1. Discussion of Mask Attributes
ACE4_READ_DATA Operation(s) affected: READ OPEN Discussion: Permission to read the data of the file. Servers SHOULD allow a user the ability to read the data of the file when only the ACE4_EXECUTE access mask bit is set. ACE4_LIST_DIRECTORY Operation(s) affected: READDIR Discussion: Permission to list the contents of a directory. ACE4_WRITE_DATA Operation(s) affected: WRITE OPEN SETATTR of size Discussion: Permission to modify a file's data.
ACE4_ADD_FILE
Operation(s) affected:
CREATE
LINK
OPEN
RENAME
Discussion:
Permission to add a new file in a directory. The CREATE
operation is affected when nfs_ftype4 is NF4LNK, NF4BLK,
NF4CHR, NF4SOCK, or NF4FIFO. (NF4DIR is not listed because it
is covered by ACE4_ADD_SUBDIRECTORY.) OPEN is affected when
used to create a regular file. LINK and RENAME are always
affected.
ACE4_APPEND_DATA
Operation(s) affected:
WRITE
OPEN
SETATTR of size
Discussion:
The ability to modify a file's data, but only starting at EOF.
This allows for the notion of append-only files, by allowing
ACE4_APPEND_DATA and denying ACE4_WRITE_DATA to the same user
or group. If a file has an ACL such as the one described above
and a WRITE request is made for somewhere other than EOF, the
server SHOULD return NFS4ERR_ACCESS.
ACE4_ADD_SUBDIRECTORY
Operation(s) affected:
CREATE
RENAME
Discussion:
Permission to create a subdirectory in a directory. The CREATE
operation is affected when nfs_ftype4 is NF4DIR. The RENAME
operation is always affected.
ACE4_READ_NAMED_ATTRS
Operation(s) affected:
OPENATTR
Discussion:
Permission to read the named attributes of a file or to look up
the named attributes directory. OPENATTR is affected when it
is not used to create a named attribute directory. This is
when 1) createdir is TRUE but a named attribute directory
already exists or 2) createdir is FALSE.
ACE4_WRITE_NAMED_ATTRS
Operation(s) affected:
OPENATTR
Discussion:
Permission to write the named attributes of a file or to create
a named attribute directory. OPENATTR is affected when it is
used to create a named attribute directory. This is when
createdir is TRUE and no named attribute directory exists. The
ability to check whether or not a named attribute directory
exists depends on the ability to look it up; therefore, users
also need the ACE4_READ_NAMED_ATTRS permission in order to
create a named attribute directory.
ACE4_EXECUTE
Operation(s) affected:
READ
Discussion:
Permission to execute a file.
Servers SHOULD allow a user the ability to read the data of the
file when only the ACE4_EXECUTE access mask bit is set. This
is because there is no way to execute a file without reading
the contents. Though a server may treat ACE4_EXECUTE and
ACE4_READ_DATA bits identically when deciding to permit a READ
operation, it SHOULD still allow the two bits to be set
independently in ACLs and MUST distinguish between them when
replying to ACCESS operations. In particular, servers SHOULD
NOT silently turn on one of the two bits when the other is set,
as that would make it impossible for the client to correctly
enforce the distinction between read and execute permissions.
As an example, following a SETATTR of the following ACL:
nfsuser:ACE4_EXECUTE:ALLOW
A subsequent GETATTR of ACL for that file SHOULD return:
nfsuser:ACE4_EXECUTE:ALLOW
Rather than:
nfsuser:ACE4_EXECUTE/ACE4_READ_DATA:ALLOW
ACE4_EXECUTE
Operation(s) affected:
LOOKUP
OPEN
REMOVE
RENAME
LINK
CREATE
Discussion:
Permission to traverse/search a directory.
ACE4_DELETE_CHILD
Operation(s) affected:
REMOVE
RENAME
Discussion:
Permission to delete a file or directory within a directory.
See Section 6.2.1.3.2 for information on how ACE4_DELETE and
ACE4_DELETE_CHILD interact.
ACE4_READ_ATTRIBUTES
Operation(s) affected:
GETATTR of file system object attributes
VERIFY
NVERIFY
READDIR
Discussion:
The ability to read basic attributes (non-ACLs) of a file.
On a UNIX system, basic attributes can be thought of as the
stat-level attributes. Allowing this access mask bit would
mean the entity can execute "ls -l" and stat. If a READDIR
operation requests attributes, this mask must be allowed for
the READDIR to succeed.
ACE4_WRITE_ATTRIBUTES
Operation(s) affected:
SETATTR of time_access_set, time_backup, time_create,
time_modify_set, mimetype, hidden, and system
Discussion:
Permission to change the times associated with a file or
directory to an arbitrary value. Also, permission to change
the mimetype, hidden and system attributes. A user having
ACE4_WRITE_DATA or ACE4_WRITE_ATTRIBUTES will be allowed to set
the times associated with a file to the current server time.
ACE4_DELETE
Operation(s) affected:
REMOVE
Discussion:
Permission to delete the file or directory. See
Section 6.2.1.3.2 for information on ACE4_DELETE and
ACE4_DELETE_CHILD interact.
ACE4_READ_ACL
Operation(s) affected:
GETATTR of acl
NVERIFY
VERIFY
Discussion:
Permission to read the ACL.
ACE4_WRITE_ACL
Operation(s) affected:
SETATTR of acl and mode
Discussion:
Permission to write the acl and mode attributes.
ACE4_WRITE_OWNER
Operation(s) affected:
SETATTR of owner and owner_group
Discussion:
Permission to write the owner and owner_group attributes. On
UNIX systems, this is the ability to execute chown() and
chgrp().
ACE4_SYNCHRONIZE
Operation(s) affected:
NONE
Discussion:
Permission to use the file object as a synchronization
primitive for interprocess communication. This permission is
not enforced or interpreted by the NFSv4.0 server on behalf of
the client.
Typically, the ACE4_SYNCHRONIZE permission is only meaningful
on local file systems, i.e., file systems not accessed via
NFSv4.0. The reason that the permission bit exists is that
some operating environments, such as Windows, use
ACE4_SYNCHRONIZE.
For example, if a client copies a file that has
ACE4_SYNCHRONIZE set from a local file system to an NFSv4.0
server, and then later copies the file from the NFSv4.0 server
to a local file system, it is likely that if ACE4_SYNCHRONIZE
was set in the original file, the client will want it set in
the second copy. The first copy will not have the permission
set unless the NFSv4.0 server has the means to set the
ACE4_SYNCHRONIZE bit. The second copy will not have the
permission set unless the NFSv4.0 server has the means to
retrieve the ACE4_SYNCHRONIZE bit.
Server implementations need not provide the granularity of control
that is implied by this list of masks. For example, POSIX-based
systems might not distinguish ACE4_APPEND_DATA (the ability to append
to a file) from ACE4_WRITE_DATA (the ability to modify existing
contents); both masks would be tied to a single "write" permission.
When such a server returns attributes to the client, it would show
both ACE4_APPEND_DATA and ACE4_WRITE_DATA if and only if the write
permission is enabled.
If a server receives a SETATTR request that it cannot accurately
implement, it should err in the direction of more restricted access,
except in the previously discussed cases of execute and read. For
example, suppose a server cannot distinguish overwriting data from
appending new data, as described in the previous paragraph. If a
client submits an ALLOW ACE where ACE4_APPEND_DATA is set but
ACE4_WRITE_DATA is not (or vice versa), the server should either turn
off ACE4_APPEND_DATA or reject the request with NFS4ERR_ATTRNOTSUPP.
6.2.1.3.2. ACE4_DELETE versus ACE4_DELETE_CHILD
Two access mask bits govern the ability to delete a directory entry: ACE4_DELETE on the object itself (the "target") and ACE4_DELETE_CHILD on the containing directory (the "parent"). Many systems also take the "sticky bit" (MODE4_SVTX) on a directory to allow unlink only to a user that owns either the target or the parent; on some such systems, the decision also depends on whether the target is writable. Servers SHOULD allow unlink if either ACE4_DELETE is permitted on the target or ACE4_DELETE_CHILD is permitted on the parent. (Note that this is true even if the parent or target explicitly denies the other of these permissions.) If the ACLs in question neither explicitly ALLOW nor DENY either of the above, and if MODE4_SVTX is not set on the parent, then the server SHOULD allow the removal if and only if ACE4_ADD_FILE is permitted. In the case where MODE4_SVTX is set, the server may also require the remover to own either the parent or the target, or may require the target to be writable. This allows servers to support something close to traditional UNIX-like semantics, with ACE4_ADD_FILE taking the place of the write bit.6.2.1.4. ACE flag
The bitmask constants used for the flag field are as follows: const ACE4_FILE_INHERIT_ACE = 0x00000001; const ACE4_DIRECTORY_INHERIT_ACE = 0x00000002; const ACE4_NO_PROPAGATE_INHERIT_ACE = 0x00000004; const ACE4_INHERIT_ONLY_ACE = 0x00000008; const ACE4_SUCCESSFUL_ACCESS_ACE_FLAG = 0x00000010; const ACE4_FAILED_ACCESS_ACE_FLAG = 0x00000020; const ACE4_IDENTIFIER_GROUP = 0x00000040; A server need not support any of these flags. If the server supports flags that are similar to, but not exactly the same as, these flags, the implementation may define a mapping between the protocol-defined flags and the implementation-defined flags. For example, suppose a client tries to set an ACE with ACE4_FILE_INHERIT_ACE set but not ACE4_DIRECTORY_INHERIT_ACE. If the server does not support any form of ACL inheritance, the server should reject the request with NFS4ERR_ATTRNOTSUPP. If the server
supports a single "inherit ACE" flag that applies to both files and directories, the server may reject the request (i.e., requiring the client to set both the file and directory inheritance flags). The server may also accept the request and silently turn on the ACE4_DIRECTORY_INHERIT_ACE flag.6.2.1.4.1. Discussion of Flag Bits
ACE4_FILE_INHERIT_ACE Any non-directory file in any subdirectory will get this ACE inherited. ACE4_DIRECTORY_INHERIT_ACE Can be placed on a directory and indicates that this ACE should be added to each new directory created. If this flag is set in an ACE in an ACL attribute to be set on a non-directory file system object, the operation attempting to set the ACL SHOULD fail with NFS4ERR_ATTRNOTSUPP. ACE4_INHERIT_ONLY_ACE Can be placed on a directory but does not apply to the directory; ALLOW and DENY ACEs with this bit set do not affect access to the directory, and AUDIT and ALARM ACEs with this bit set do not trigger log or alarm events. Such ACEs only take effect once they are applied (with this bit cleared) to newly created files and directories as specified by the above two flags. If this flag is present on an ACE, but neither ACE4_DIRECTORY_INHERIT_ACE nor ACE4_FILE_INHERIT_ACE is present, then an operation attempting to set such an attribute SHOULD fail with NFS4ERR_ATTRNOTSUPP. ACE4_NO_PROPAGATE_INHERIT_ACE Can be placed on a directory. This flag tells the server that inheritance of this ACE should stop at newly created child directories. ACE4_SUCCESSFUL_ACCESS_ACE_FLAG ACE4_FAILED_ACCESS_ACE_FLAG The ACE4_SUCCESSFUL_ACCESS_ACE_FLAG (SUCCESS) and ACE4_FAILED_ACCESS_ACE_FLAG (FAILED) flag bits may be set only on ACE4_SYSTEM_AUDIT_ACE_TYPE (AUDIT) and ACE4_SYSTEM_ALARM_ACE_TYPE (ALARM) ACE types. If, during the processing of the file's ACL, the server encounters an AUDIT or ALARM ACE that matches the principal attempting the OPEN, the server notes that fact and notes the presence, if any, of the SUCCESS and FAILED flags encountered in the AUDIT or ALARM ACE. Once the server completes the ACL processing, it then notes if the operation succeeded or
failed. If the operation succeeded, and if the SUCCESS flag was
set for a matching AUDIT or ALARM ACE, then the appropriate AUDIT
or ALARM event occurs. If the operation failed, and if the FAILED
flag was set for the matching AUDIT or ALARM ACE, then the
appropriate AUDIT or ALARM event occurs. Either or both of the
SUCCESS or FAILED can be set, but if neither is set, the AUDIT or
ALARM ACE is not useful.
The previously described processing applies to ACCESS operations
even when they return NFS4_OK. For the purposes of AUDIT and
ALARM, we consider an ACCESS operation to be a "failure" if it
fails to return a bit that was requested and supported.
ACE4_IDENTIFIER_GROUP
Indicates that the "who" refers to a GROUP as defined under UNIX
or a GROUP ACCOUNT as defined under Windows. Clients and servers
MUST ignore the ACE4_IDENTIFIER_GROUP flag on ACEs with a who
value equal to one of the special identifiers outlined in
Section 6.2.1.5.
6.2.1.5. ACE Who
The who field of an ACE is an identifier that specifies the principal
or principals to whom the ACE applies. It may refer to a user or a
group, with the flag bit ACE4_IDENTIFIER_GROUP specifying which.
There are several special identifiers that need to be understood
universally, rather than in the context of a particular DNS domain.
Some of these identifiers cannot be understood when an NFS client
accesses the server but have meaning when a local process accesses
the file. The ability to display and modify these permissions is
permitted over NFS, even if none of the access methods on the server
understand the identifiers.
+---------------+---------------------------------------------------+ | Who | Description | +---------------+---------------------------------------------------+ | OWNER | The owner of the file. | | GROUP | The group associated with the file. | | EVERYONE | The world, including the owner and owning group. | | INTERACTIVE | Accessed from an interactive terminal. | | NETWORK | Accessed via the network. | | DIALUP | Accessed as a dialup user to the server. | | BATCH | Accessed from a batch job. | | ANONYMOUS | Accessed without any authentication. | | AUTHENTICATED | Any authenticated user (opposite of ANONYMOUS). | | SERVICE | Access from a system service. | +---------------+---------------------------------------------------+ Table 5: Special Identifiers To avoid conflict, these special identifiers are distinguished by an appended "@" and should appear in the form "xxxx@" (with no domain name after the "@") -- for example, ANONYMOUS@. The ACE4_IDENTIFIER_GROUP flag MUST be ignored on entries with these special identifiers. When encoding entries with these special identifiers, the ACE4_IDENTIFIER_GROUP flag SHOULD be set to zero.6.2.1.5.1. Discussion of EVERYONE@
It is important to note that "EVERYONE@" is not equivalent to the UNIX "other" entity. This is because, by definition, UNIX "other" does not include the owner or owning group of a file. "EVERYONE@" means literally everyone, including the owner or owning group.6.2.2. Attribute 33: mode
The NFSv4.0 mode attribute is based on the UNIX mode bits. The following bits are defined: const MODE4_SUID = 0x800; /* set user id on execution */ const MODE4_SGID = 0x400; /* set group id on execution */ const MODE4_SVTX = 0x200; /* save text even after use */ const MODE4_RUSR = 0x100; /* read permission: owner */ const MODE4_WUSR = 0x080; /* write permission: owner */ const MODE4_XUSR = 0x040; /* execute permission: owner */ const MODE4_RGRP = 0x020; /* read permission: group */ const MODE4_WGRP = 0x010; /* write permission: group */ const MODE4_XGRP = 0x008; /* execute permission: group */
const MODE4_ROTH = 0x004; /* read permission: other */ const MODE4_WOTH = 0x002; /* write permission: other */ const MODE4_XOTH = 0x001; /* execute permission: other */ Bits MODE4_RUSR, MODE4_WUSR, and MODE4_XUSR apply to the principal identified in the owner attribute. Bits MODE4_RGRP, MODE4_WGRP, and MODE4_XGRP apply to principals identified in the owner_group attribute but who are not identified in the owner attribute. Bits MODE4_ROTH, MODE4_WOTH, and MODE4_XOTH apply to any principal that does not match that in the owner attribute and does not have a group matching that of the owner_group attribute. Bits within the mode other than those specified above are not defined by this protocol. A server MUST NOT return bits other than those defined above in a GETATTR or READDIR operation, and it MUST return NFS4ERR_INVAL if bits other than those defined above are set in a SETATTR, CREATE, OPEN, VERIFY, or NVERIFY operation.6.3. Common Methods
The requirements in this section will be referred to in future sections, especially Section 6.4.6.3.1. Interpreting an ACL
6.3.1.1. Server Considerations
The server uses the algorithm described in Section 6.2.1 to determine whether an ACL allows access to an object. However, the ACL may not be the sole determiner of access. For example: o In the case of a file system exported as read-only, the server may deny write permissions even though an object's ACL grants it. o Server implementations MAY grant ACE4_WRITE_ACL and ACE4_READ_ACL permissions to prevent a situation from arising in which there is no valid way to ever modify the ACL. o All servers will allow a user the ability to read the data of the file when only the execute permission is granted (i.e., if the ACL denies the user ACE4_READ_DATA access and allows the user ACE4_EXECUTE, the server will allow the user to read the data of the file).
o Many servers have the notion of owner-override, in which the owner
of the object is allowed to override accesses that are denied by
the ACL. This may be helpful, for example, to allow users
continued access to open files on which the permissions have
changed.
o Many servers have the notion of a "superuser" that has privileges
beyond an ordinary user. The superuser may be able to read or
write data or metadata in ways that would not be permitted by
the ACL.
6.3.1.2. Client Considerations
Clients SHOULD NOT do their own access checks based on their
interpretation of the ACL but rather use the OPEN and ACCESS
operations to do access checks. This allows the client to act on the
results of having the server determine whether or not access should
be granted based on its interpretation of the ACL.
Clients must be aware of situations in which an object's ACL will
define a certain access even though the server will not have adequate
information to enforce it. For example, the server has no way of
determining whether a particular OPEN reflects a user's open for read
access or is done as part of executing the file in question. In such
situations, the client needs to do its part in the enforcement of
access as defined by the ACL. To do this, the client will send the
appropriate ACCESS operation (or use a cached previous determination)
prior to servicing the request of the user or application in order to
determine whether the user or application should be granted the
access requested. For examples in which the ACL may define accesses
that the server does not enforce, see Section 6.3.1.1.
6.3.2. Computing a mode Attribute from an ACL
The following method can be used to calculate the MODE4_R*, MODE4_W*,
and MODE4_X* bits of a mode attribute, based upon an ACL.
First, for each of the special identifiers OWNER@, GROUP@, and
EVERYONE@, evaluate the ACL in order, considering only ALLOW and DENY
ACEs for the identifier EVERYONE@ and for the identifier under
consideration. The result of the evaluation will be an NFSv4 ACL
mask showing exactly which bits are permitted to that identifier.
Then translate the calculated mask for OWNER@, GROUP@, and EVERYONE@
into mode bits for the user, group, and other, respectively, as
follows:
1. Set the read bit (MODE4_RUSR, MODE4_RGRP, or MODE4_ROTH) if and
only if ACE4_READ_DATA is set in the corresponding mask.
2. Set the write bit (MODE4_WUSR, MODE4_WGRP, or MODE4_WOTH) if and
only if ACE4_WRITE_DATA and ACE4_APPEND_DATA are both set in the
corresponding mask.
3. Set the execute bit (MODE4_XUSR, MODE4_XGRP, or MODE4_XOTH), if
and only if ACE4_EXECUTE is set in the corresponding mask.
6.3.2.1. Discussion
Some server implementations also add bits permitted to named users
and groups to the group bits (MODE4_RGRP, MODE4_WGRP, and
MODE4_XGRP).
Implementations are discouraged from doing this, because it has been
found to cause confusion for users who see members of a file's group
denied access that the mode bits appear to allow. (The presence of
DENY ACEs may also lead to such behavior, but DENY ACEs are expected
to be more rarely used.)
The same user confusion seen when fetching the mode also results if
setting the mode does not effectively control permissions for the
owner, group, and other users; this motivates some of the
requirements that follow.
6.4. Requirements
The server that supports both mode and ACL must take care to
synchronize the MODE4_*USR, MODE4_*GRP, and MODE4_*OTH bits with the
ACEs that have respective who fields of "OWNER@", "GROUP@", and
"EVERYONE@" so that the client can see that semantically equivalent
access permissions exist whether the client asks for just the ACL or
any of the owner, owner_group, and mode attributes.
Many requirements refer to Section 6.3.2, but note that the methods
have behaviors specified with "SHOULD". This is intentional, to
avoid invalidating existing implementations that compute the mode
according to the withdrawn POSIX ACL draft ([P1003.1e]), rather than
by actual permissions on owner, group, and other.
6.4.1. Setting the mode and/or ACL Attributes
6.4.1.1. Setting mode and Not ACL
When any of the nine low-order mode bits are changed because the mode attribute was set, and no ACL attribute is explicitly set, the acl attribute must be modified in accordance with the updated value of those bits. This must happen even if the value of the low-order bits is the same after the mode is set as before. Note that any AUDIT or ALARM ACEs are unaffected by changes to the mode. In cases in which the permissions bits are subject to change, the acl attribute MUST be modified such that the mode computed via the method described in Section 6.3.2 yields the low-order nine bits (MODE4_R*, MODE4_W*, MODE4_X*) of the mode attribute as modified by the change attribute. The ACL attributes SHOULD also be modified such that: 1. If MODE4_RGRP is not set, entities explicitly listed in the ACL other than OWNER@ and EVERYONE@ SHOULD NOT be granted ACE4_READ_DATA. 2. If MODE4_WGRP is not set, entities explicitly listed in the ACL other than OWNER@ and EVERYONE@ SHOULD NOT be granted ACE4_WRITE_DATA or ACE4_APPEND_DATA. 3. If MODE4_XGRP is not set, entities explicitly listed in the ACL other than OWNER@ and EVERYONE@ SHOULD NOT be granted ACE4_EXECUTE. Access mask bits other than those listed above, appearing in ALLOW ACEs, MAY also be disabled. Note that ACEs with the flag ACE4_INHERIT_ONLY_ACE set do not affect the permissions of the ACL itself, nor do ACEs of the types AUDIT and ALARM. As such, it is desirable to leave these ACEs unmodified when modifying the ACL attributes. Also note that the requirement may be met by discarding the acl in favor of an ACL that represents the mode and only the mode. This is permitted, but it is preferable for a server to preserve as much of the ACL as possible without violating the above requirements. Discarding the ACL makes it effectively impossible for a file created with a mode attribute to inherit an ACL (see Section 6.4.3).
6.4.1.2. Setting ACL and Not mode
When setting the acl and not setting the mode attribute, the permission bits of the mode need to be derived from the ACL. In this case, the ACL attribute SHOULD be set as given. The nine low-order bits of the mode attribute (MODE4_R*, MODE4_W*, MODE4_X*) MUST be modified to match the result of the method described in Section 6.3.2. The three high-order bits of the mode (MODE4_SUID, MODE4_SGID, MODE4_SVTX) SHOULD remain unchanged.6.4.1.3. Setting Both ACL and mode
When setting both the mode and the acl attribute in the same operation, the attributes MUST be applied in this order: mode, then ACL. The mode-related attribute is set as given, then the ACL attribute is set as given, possibly changing the final mode, as described above in Section 6.4.1.2.6.4.2. Retrieving the mode and/or ACL Attributes
This section applies only to servers that support both the mode and ACL attributes. Some server implementations may have a concept of "objects without ACLs", meaning that all permissions are granted and denied according to the mode attribute, and that no ACL attribute is stored for that object. If an ACL attribute is requested of such a server, the server SHOULD return an ACL that does not conflict with the mode; that is to say, the ACL returned SHOULD represent the nine low-order bits of the mode attribute (MODE4_R*, MODE4_W*, MODE4_X*) as described in Section 6.3.2. For other server implementations, the ACL attribute is always present for every object. Such servers SHOULD store at least the three high-order bits of the mode attribute (MODE4_SUID, MODE4_SGID, MODE4_SVTX). The server SHOULD return a mode attribute if one is requested, and the low-order nine bits of the mode (MODE4_R*, MODE4_W*, MODE4_X*) MUST match the result of applying the method in Section 6.3.2 to the ACL attribute.6.4.3. Creating New Objects
If a server supports any ACL attributes, it may use the ACL attributes on the parent directory to compute an initial ACL attribute for a newly created object. This will be referred to as the inherited ACL within this section. The act of adding one or more
ACEs to the inherited ACL that are based upon ACEs in the parent
directory's ACL will be referred to as inheriting an ACE within this
section.
In the presence or absence of the mode and ACL attributes, the
behavior of CREATE and OPEN SHOULD be:
1. If just the mode is given in the call:
In this case, inheritance SHOULD take place, but the mode MUST be
applied to the inherited ACL as described in Section 6.4.1.1,
thereby modifying the ACL.
2. If just the ACL is given in the call:
In this case, inheritance SHOULD NOT take place, and the ACL as
defined in the CREATE or OPEN will be set without modification,
and the mode modified as in Section 6.4.1.2.
3. If both mode and ACL are given in the call:
In this case, inheritance SHOULD NOT take place, and both
attributes will be set as described in Section 6.4.1.3.
4. If neither mode nor ACL is given in the call:
In the case where an object is being created without any initial
attributes at all, e.g., an OPEN operation with an opentype4 of
OPEN4_CREATE and a createmode4 of EXCLUSIVE4, inheritance SHOULD
NOT take place. Instead, the server SHOULD set permissions to
deny all access to the newly created object. It is expected that
the appropriate client will set the desired attributes in a
subsequent SETATTR operation, and the server SHOULD allow that
operation to succeed, regardless of what permissions the object
is created with. For example, an empty ACL denies all
permissions, but the server should allow the owner's SETATTR to
succeed even though WRITE_ACL is implicitly denied.
In other cases, inheritance SHOULD take place, and no
modifications to the ACL will happen. The mode attribute, if
supported, MUST be as computed via the method described in
Section 6.3.2, with the MODE4_SUID, MODE4_SGID, and MODE4_SVTX
bits clear. If no inheritable ACEs exist on the parent
directory, the rules for creating acl attributes are
implementation defined.
6.4.3.1. The Inherited ACL
If the object being created is not a directory, the inherited ACL SHOULD NOT inherit ACEs from the parent directory ACL unless the ACE4_FILE_INHERIT_FLAG is set. If the object being created is a directory, the inherited ACL should inherit all inheritable ACEs from the parent directory, i.e., those that have the ACE4_FILE_INHERIT_ACE or ACE4_DIRECTORY_INHERIT_ACE flag set. If the inheritable ACE has ACE4_FILE_INHERIT_ACE set, but ACE4_DIRECTORY_INHERIT_ACE is clear, the inherited ACE on the newly created directory MUST have the ACE4_INHERIT_ONLY_ACE flag set to prevent the directory from being affected by ACEs meant for non-directories. When a new directory is created, the server MAY split any inherited ACE that is both inheritable and effective (in other words, that has neither ACE4_INHERIT_ONLY_ACE nor ACE4_NO_PROPAGATE_INHERIT_ACE set) into two ACEs -- one with no inheritance flags, and one with ACE4_INHERIT_ONLY_ACE set. This makes it simpler to modify the effective permissions on the directory without modifying the ACE that is to be inherited to the new directory's children.7. NFS Server Namespace
7.1. Server Exports
On a UNIX server, the namespace describes all the files reachable by pathnames under the root directory or "/". On a Windows server, the namespace constitutes all the files on disks named by mapped disk letters. NFS server administrators rarely make the entire server's file system namespace available to NFS clients. More often, portions of the namespace are made available via an "export" feature. In previous versions of the NFS protocol, the root filehandle for each export is obtained through the MOUNT protocol; the client sends a string that identifies an object in the exported namespace, and the server returns the root filehandle for it. The MOUNT protocol supports an EXPORTS procedure that will enumerate the server's exports.7.2. Browsing Exports
The NFSv4 protocol provides a root filehandle that clients can use to obtain filehandles for these exports via a multi-component LOOKUP. A common user experience is to use a graphical user interface (perhaps a file "Open" dialog window) to find a file via progressive browsing
through a directory tree. The client must be able to move from one export to another export via single-component, progressive LOOKUP operations. This style of browsing is not well supported by the NFSv2 and NFSv3 protocols. The client expects all LOOKUP operations to remain within a single-server file system. For example, the device attribute will not change. This prevents a client from taking namespace paths that span exports. An automounter on the client can obtain a snapshot of the server's namespace using the EXPORTS procedure of the MOUNT protocol. If it understands the server's pathname syntax, it can create an image of the server's namespace on the client. The parts of the namespace that are not exported by the server are filled in with a "pseudo-file system" that allows the user to browse from one mounted file system to another. There is a drawback to this representation of the server's namespace on the client: it is static. If the server administrator adds a new export, the client will be unaware of it.7.3. Server Pseudo-File System
NFSv4 servers avoid this namespace inconsistency by presenting all the exports within the framework of a single-server namespace. An NFSv4 client uses LOOKUP and READDIR operations to browse seamlessly from one export to another. Portions of the server namespace that are not exported are bridged via a "pseudo-file system" that provides a view of exported directories only. A pseudo-file system has a unique fsid and behaves like a normal, read-only file system. Based on the construction of the server's namespace, it is possible that multiple pseudo-file systems may exist. For example: /a pseudo-file system /a/b real file system /a/b/c pseudo-file system /a/b/c/d real file system Each of the pseudo-file systems are considered separate entities and therefore will have a unique fsid.
7.4. Multiple Roots
The DOS and Windows operating environments are sometimes described as having "multiple roots". File systems are commonly represented as disk letters. MacOS represents file systems as top-level names. NFSv4 servers for these platforms can construct a pseudo-file system above these root names so that disk letters or volume names are simply directory names in the pseudo-root.7.5. Filehandle Volatility
The nature of the server's pseudo-file system is that it is a logical representation of file system(s) available from the server. Therefore, the pseudo-file system is most likely constructed dynamically when the server is first instantiated. It is expected that the pseudo-file system may not have an on-disk counterpart from which persistent filehandles could be constructed. Even though it is preferable that the server provide persistent filehandles for the pseudo-file system, the NFS client should expect that pseudo-file system filehandles are volatile. This can be confirmed by checking the associated "fh_expire_type" attribute for those filehandles in question. If the filehandles are volatile, the NFS client must be prepared to recover a filehandle value (e.g., with a multi-component LOOKUP) when receiving an error of NFS4ERR_FHEXPIRED.7.6. Exported Root
If the server's root file system is exported, one might conclude that a pseudo-file system is not needed. This would be wrong. Assume the following file systems on a server: / disk1 (exported) /a disk2 (not exported) /a/b disk3 (exported) Because disk2 is not exported, disk3 cannot be reached with simple LOOKUPs. The server must bridge the gap with a pseudo-file system.7.7. Mount Point Crossing
The server file system environment may be constructed in such a way that one file system contains a directory that is 'covered' or mounted upon by a second file system. For example: /a/b (file system 1) /a/b/c/d (file system 2)
The pseudo-file system for this server may be constructed to
look like:
/ (placeholder/not exported)
/a/b (file system 1)
/a/b/c/d (file system 2)
It is the server's responsibility to present the pseudo-file system
that is complete to the client. If the client sends a LOOKUP request
for the path "/a/b/c/d", the server's response is the filehandle of
the file system "/a/b/c/d". In previous versions of the NFS
protocol, the server would respond with the filehandle of directory
"/a/b/c/d" within the file system "/a/b".
The NFS client will be able to determine if it crosses a server mount
point by a change in the value of the "fsid" attribute.
7.8. Security Policy and Namespace Presentation
Because NFSv4 clients possess the ability to change the security
mechanisms used, after determining what is allowed, by using SECINFO
the server SHOULD NOT present a different view of the namespace based
on the security mechanism being used by a client. Instead, it should
present a consistent view and return NFS4ERR_WRONGSEC if an attempt
is made to access data with an inappropriate security mechanism.
If security considerations make it necessary to hide the existence of
a particular file system, as opposed to all of the data within it,
the server can apply the security policy of a shared resource in the
server's namespace to components of the resource's ancestors. For
example:
/ (placeholder/not exported)
/a/b (file system 1)
/a/b/MySecretProject (file system 2)
The /a/b/MySecretProject directory is a real file system and is the
shared resource. Suppose the security policy for /a/b/
MySecretProject is Kerberos with integrity and it is desired to limit
knowledge of the existence of this file system. In this case, the
server should apply the same security policy to /a/b. This allows
for knowledge of the existence of a file system to be secured when
desirable.
For the case of the use of multiple, disjoint security mechanisms in
the server's resources, applying that sort of policy would result in
the higher-level file system not being accessible using any security
flavor. Therefore, that sort of configuration is not compatible with hiding the existence (as opposed to the contents) from clients using multiple disjoint sets of security flavors. In other circumstances, a desirable policy is for the security of a particular object in the server's namespace to include the union of all security mechanisms of all direct descendants. A common and convenient practice, unless strong security requirements dictate otherwise, is to make the entire pseudo-file system accessible by all of the valid security mechanisms. Where there is concern about the security of data on the network, clients should use strong security mechanisms to access the pseudo-file system in order to prevent man-in-the-middle attacks.