From Linux NFS
Introduction to NFSv4 ACLs
Some NFSv2 and v3 implementations support ACLs based on POSIX draft ACLs which depend on a searate rpc program (instead of being part of the NFS protocol itself).
The NFSv4 protocol includes integrated support for ACLs which are similar to those used by Windows. NFSv4 ACLs are richer than POSIX draft ACLs--any POSIX ACL can be represented by an NFSv4 ACL with almost the same semantics, whereas the reverse is not true.
- rfc3530 (especially section 5.11)]
- POSIX draft ACLs: POSIX ACLs aren't really POSIX--they were never accepted--but some variation of them is implemented on many operating systems, including Linux.
- The Linux man pages, specifically, acl(5), setfacl(1), getfacl(1), and setxattr(2).
- The POSIX<->NFSv4 mapping draft, which explains how we map between POSIX and NFSv4 ACLs.
- The CITI NFSv4 project page, which has links to modified linux acl utilities with preliminary NFSv4 support
- draft-falkner-nfsv4-acls-00.txt, which suggests some clarifications to the NFSv4 ACL specification, and addresses some issues for NFSv4 implementors on UNIXy systems, including, for example, details on interactions with chmod.
Design of the linux NFSv4 ACL implementation
None of the filesystems which the linux server exports support NFSv4 ACLs. However, many of them do support POSIX ACLs. So we map NFSv4 ACLs to POSIX ACLs and store POSIX ACLs in the filesystem. The mapping is imperfect, and prevents the server from accepting the full range of NFSv4 ACLs. We could instead store NFSv4 ACLs somewhere else--say in a separate extended attribute used only by the NFSv4 server. However, this would prevent our ACLs from being enforced against local users of the same filesystem. The code to perform this mapping on the server side is in the kernel, in fs/nfsd/nfs4acl.c.
The client can also map between NFSv4 and POSIX ACLs, to allow it to support existing POSIX ACL interfaces. However it does this mapping in userspace; the kernel deals only in NFSv4 ACLs, which it exposes through a special extended attribute ("system.nfs4_acl"). Applications that use the POSIX ACL interfaces need to use a version of libacl that has been modified to do POSIX<->NFSv4 ACL mapping. But since userspace also has full access to the raw NFSv4 ACL, we can also provide utilities that get and set NFSv4 ACLs directly, without the need for mapping.
The data in the system.nfs4_acl attribute consists of the raw xdr data which the client receives from the server as the value of the "acl" attribute. It is up to userspace to do xdr decoding and encoding.
The ACL Interoperability Problem
We now have three ACL models to deal with: NFSv4, Windows, and "POSIX ACLs"/mode bits. And we have to decide what to do with them all in the face of existing users, tools, and system interfaces that assume one or the other.
A server has to store ACL's persistently on its filesystem. There are immense advantages to storing those ACL's using whatever ACL's the filesystem and operating system support, because that will ensure that they are automatically enforced against other applications and protocol services using the same filesystem.
Some servers are therefore translating to and from their native format. Others are implementing NFSv4 ACL's in the filesystem.
The client in theory has a simpler problem--it can always provide its own application for manipulating ACLs. However:
- Some applications (Microsoft Word was mentioned as one) manipulate ACL's directly (on temporary files? Examples might be useful here.)
- Users may have experience with existing ACL models and tools, which may be better integrated into important tools (like Microsoft Explorer)
- Administrators may have built up scripts that manipulate or check ACL's.
For this reason client implementers may have to deal with non-NFSv4 ACL's as well.
NFSv4 and Windows ACLs
The two ACL models are essentially the same, with some minor differences:
- RFC3530 says that if an ACL neither allows nor denies a certain mode bit, then behavior is undefined. But users of Windows ACLs expect them to deny by default.
- Windows documentation suggests that if some but not all requested access bits have been allowed, then DENY aces will still apply even if they only deny bits among those already allowed. This has the somewhat bizarre result that an ACL can allow certain permissions individually but deny them in combination. The NFSv4 ACL algorithm doesn't have this property.
A bigger (and perhaps more important!) difference is in the names, which we're ignoring for now.
The new OSX ACLs seem to be essentially identical to Windows ACLs.
We know of no concerted effort to implement NFSv4/Windows ACLs on Linux filesystems, but Solaris and AIX also both seem to be adding support for NFSv4 ACLs. Two Sun developers have an internet draft draft-falkner-nfsv4-acls-00.txt which proposes more precise semantics for NFSv4 ACLs and deals with mode-bit mapping and other issues of particular interest for NFSv4 ACL implementors on POSIX systems.
In practice many Windows applications (such as Explorer) may use only a small subset of Windows ACLs, and may not deal well with ACLs outside of that subset; for example, they generally want to sort all DENY ACE's before ALLOW ACE's. See this msdn documentation.
As noted above, these aren't really POSIX, though they've been implemented on lots of operating systems, including Solaris and Linux. See the POSIX draft for detailed documentation.
NFSv4/Windows ACLs are more fine-grained than POSIX ACLs.
The popularity and flexibility of Windows/NFSv4 ACLs makes it tempting to just ignore POSIX ACLs. However,
- The flexibility of Windows ACL's could make them harder to use them correctly. People with experience suggested that in practice users do have trouble. (Any references to published evidence here would be useful. Windows Access Control Demystified studies ACL misconfiguration problems, though the specific problems identified seem to be with access bits not relevant to file system permissions.)
- POSIX ACL's are what are currently available on Linux and some other platforms, so we can expect that they are what developers are currently coding to; thus even if they aren't widely used now, they may be in a few years (by which time file managers have built-in support for them, etc.).
AFS, DCE, AIX, ???
AFS ACLs may be a particular issue here at CITI since we have AFS volumes that we'll want to transfer to NFSv4 at some point. But fortunately that will probably only require a one-time translation; we're not going to try to provide simultaneous NFSv4 and AFS acess....
The POSIX<->NFSv4 mapping draft), which is what the linux client and server implement, takes a very strict approach: POSIX ACLs are mapped on the fly to NFSv4 ACLs, but attempts to get or set NFSv4 ACLs fail unless they are precisely equal to a POSIX-mapped NFSv4 ACL. Since NFSv4 ACLs are much finer-grained, almost all NFSv4 ACLs will fail to map to a POSIX ACL.
This approach has a few disadvantages:
- The NFSv4 ACLs produced by this mapping are hard to read, and are impossible for users to manipulate without software that understands the mapping to aid them. Thus a user modifying the ACLs through an application that doesn't treat them as POSIX ACLs will almost certainly produce an ACL that can no longer be read by applications that expect POSIX ACLs.
- An NFSv4 server like Linux with backend POSIX ACLs can accept only a very limited subset of ACLs, probably impossible to generate without software that understands the mapping.
Strict mapping between Windows and NFSv4 ACLs is much easier; probably all that's necessary is the addition or subtraction of a "DENY EVERYONE@" ACE at the end of each ACL. This might also cause problems, though.
See Jeremy Allison's presentation for a description of a mapping used to store and retrieve NFSv4 ACLs from a backend that supports only POSIX ACLs. This mapping always succeeds, sacrificing some semantics instead.
Rather than try to map mode bits into ACLs, AFS just ignores mode bits entirely--it allows you to set and get them, but they have no effect.
User tools need to fail gracefully when mapping fails; e.g. they should be able to give the user a helpful error message and give them the option of overwriting the ACL completely or leaving it alone.