AFS to NFSv4 ACL conversion
From Linux NFS
Sources:
https://docs.openafs.org/UserGuide/HDRWQ46.html https://www.auristor.com/documentation/man/linux/7/auristorfs_acls.html
directory:
(l)ookup (i)nsert (d)elete (a)dminister
file:
(r)ead (w)rite loc(k)
Perms set only on directories in AFS, also allowed on files, symlinks, mount points in auristor. r/w/k perms on directory control files in that directory that don't have an ACL set.
So in auristor it's possible for a file to not have any ACL set.
I assume that directories do have ACLs set, and new subdirectories inherit same permissions as parents.
Both also allow 8 additional application-defined permissions A-H which I think we'll ignore. (If necessary, write a v4 protocol extension.)
"Negative permissions" always take precedence.
Auristor docs state that "i" is equivalent to "w" permissions when applied to a file. That rule is so strange I'm inclined to ignore it.
Anyway, AFS->NFSv4 translation algorithm:
Given a directory: Start with an empty NFSv4 ACL. Iterate through the ACEs of the AFS ACL one at a time, negative ACEs first. For each ACE:
If the AFS ACE is a negative ACE, any new NFSv4 ACEs generated in this step should be ACCESS_DENIED_ACE, otherwise ACCESS_ALLOWED_ACE.
Create two NFSv4 ACEs, one with ACE4_DIRECTORY_INHERIT_ACE set, the other with NFS4_ACE_INHERIT_ONLY_ACE and NFS4_ACE_FILE_INHERIT_ACE set.
On the first ACE, set mode bits as follows:
l->ACE4_EXECUTE|ACE4_READ_DATA i->ACE4_WRITE_DATA|ACE4_APPEND_DATA d->ACE4_DELETE_CHILD a->ACE4_WRITE_ACL
On the second ACE, set mode bits as follows:
r->ACE4_READ_DATA w->ACE4_WRITE_DATA|ACE4_APPEND_DATA a->ACE4_WRITE_ACL.
Given a file: the same, but create only one ACE, with no inheritance
bits set. If the source file has no AFS ACL, then the ACL on the
destination file should be exactly what it would be if it was inherited
from its parent. If the source file has an ACL, then determine the
access bits on each destination as above, ignoring any l, i, or d bits.
In addition, if the destination NFSv4 server supports the dacl
attribute, then set ACE4_INHERITED_ACE on all ACEs when the source file
has no AFS ACL, and set ACL4_PROTECTED on any flag on any ACL for which
the source file has an AFS ACL set.
I don't think there's any way to handle loc(k) correctly. It should be just ignored and documented. ACE4_SYNCHRONIZE is vaguely similar but in practice it won't do the right thing on any NFSv4 server. A Linux server will ignore it, and a server that supports it probably uses read or write opens to decide permissions to lock, as is traditional for linux/unix.
Failures on mapping to NFSv4 ACLs:
- Without server (and client userspace tool) support for the NFSv4.1 DACL attribute and automatic inheritance, changes to directories won't automatically propagate to children. This is different from AFS, where the directory ACL controls permissions on all clients (and Auristor, where that's still the default behavior although files may optionally have their own ACLs).
Failures on mapping to POSIX ACLs as implemented on Linux:
- POSIX ACLs are unable to distinguish between insert and delete. The mapping should default to erring on the side of restrictiveness, and deny directory write permissions when insert and delete are not both permitted. - POSIX ACLs inherit parent permissions only on creation, there's no way to emulate AFS behavior. - POSIX ACL inheritance is very different: directories have an "access ACL" (which determines permissions) and a "default ACL" (which is inherited by children). The default ACL is inherited by both files and directories, and POSIX ACLs use the same bit for, for example, directory modification and file write. This means, for example, it's not possible to set an inheritable ACL giving child files write permission but denying modification permissions to child directories. In such cases by default we should err on the side of denying both permissions.
Whenever we're unable to map permissions exactly, we should default to erring on the side of denying permissions, and warning the user. A conversion tool may provide ways to override that default and the warnings. Care must be taken to prevent warnings from being unmanageable. When converting large filesystems, we should provide a readable summary and give the user a way to get the details if necessary.
TODO:
- interactions with mode bits: in the past I believe AFS simply ignored mode bits, allowing us to ignore them on conversion. I think that may no longer be true for AFS (or at least for Auristor). - user & group naming - file owners and groups