A file system over a network

© 2010-2014 Dennis Leeuw dleeuw at made-it dot com
License: GPLv2 or later


    1. Mapping GNU/Linux POSIX 1003.1e draft 17 ACL to NFSv4 ACL
    2. Problems and Fixes

Mapping GNU/Linux POSIX 1003.1e draft 17 ACL to NFSv4 ACL

The nfs4 tools package (nfs4_setfacl and nfs4_getfacl) uses an ACE syntax of:

The fields can be described like this:
RFC 3530 RFC 5661 nfs4_tools Remarks
NFSv4 ACE NFSv4.1 ACE type flag permission  
ACL4_SUPPORT_DENY_ACL ACE4_ACCESS_DENIED_ACE_TYPE D   Explicitly denies the access.
ACL4_SUPPORT_AUDIT_ACL ACE4_ACCESS_AUDIT_ACE_TYPE U   LOG any access attempt to a file or directory.
ACL4_SUPPORT_ALARM_ACL ACE4_ACCESS_ALARM_ACE_TYPE L   Generate a system ALARM when any access attempt is made.
ACE4_IDENTIFIER_GROUP ACE4_IDENTIFIER_GROUP g   Indicates that the "who" refers to a GROUP as defined under UNIX.
ACE4_FILE_INHERIT_ACE ACE4_FILE_INHERIT_ACE f Propagate ACE to file in directory.
ACE4_INHERIT_ONLY ACE4_INHERIT_ONLY i Only inherit the ACE, do not evaluate during access.
ACE4_SUCCESSFUL_ACCESS_ACE_FLAG ACE4_SUCCESSFUL_ACCESS_ACE_FLAG S Trigger an alarm/audit when principal is allowed to perform an action covered by permissions.
ACE4_FAILED_ACCESS_ACE_FLAG ACE4_FAILED_ACCESS_ACE_FLAG F Trigger an alarm/audit when principal is prevented from performing an action covered by permissions.
ACE4_READ_DATA ACE4_READ_DATA r Permission to read the data of the file.
ACE4_LIST_DIRECTORY ACE4_LIST_DIRECTORY r Permission to list the contents of a directory.
ACE4_WRITE_DATA ACE4_WRITE_DATA w Permission to modify a file's data.
ACE4_ADD_FILE ACE4_ADD_FILE w Permission to add a new file in a directory.
ACE4_ADD_SUBDIRECTORY ACE4_ADD_SUBDIRECTORY a Permission to create a subdirectory in a directory.
ACE4_APPEND_DATA ACE4_APPEND_DATA a The ability to modify a file's data, but only starting at EOF.
ACE4_DELETE ACE4_DELETE d Permission to delete the file or directory.
ACE4_DELETE_CHILD ACE4_DELETE_CHILD D Permission to delete a file or directory within a directory.
ACE4_EXECUTE ACE4_EXECUTE x Permission to execute a file or permission to traverse/search a directory.
ACE4_WRITE_OWNER ACE4_WRITE_OWNER o Permission to write the owner and owner_group attributes.
ACE4_READ_ACL ACE4_READ_ACL c Permission to read the ACL.
ACE4_WRITE_ACL ACE4_WRITE_ACL C Permission to write the ACL.
ACE4_READ_NAMED_ATTRS n Permission to read the named attributes of a file or to lookup the named attributes directory.
ACE4_WRITE_NAMED_ATTRS N Permission to write the named attributes of a file or to create a named attribute directory.
ACE4_READ_ATTRIBUTES ACE4_READ_ATTRIBUTES t The ability to read basic attributes (non-ACLs) of a file.
ACE4_WRITE_ATTRIBUTES ACE4_WRITE_ATTRIBUTES T The ability to write basic attributes (non-ACLs) of a file.
ACE4_SYNCHRONIZE ACE4_SYNCHRONIZE y Permission to use the file object as a synchronization primitive for interprocess communication.
ACE4_WRITE_RETENTION Permission to modify the durations of event and non-event-based retention. Also permission to enable event and non-event-based retention.
ACE4_WRITE_RETENTION_HOLD Permission to modify the administration retention holds.

To map the draft POSIX ACLs from GNU/Linux to the NFSv4 ACLs we used the

To map the GNU/Linux POSIX ACEs to NFSv4, we need to realize that the NFSv4 tools use the following syntax:

The type is always A, since we want to avoid Deny rules as specified in the IETF Draft document. To write out allow (A) type rules we first want to figure out the flags.

Based on the description on page 3 of the IETF Draft document, groups need to get the g flag. If a default ACE rule exists on GNU/Linux it also means that the ACE should be inherited, both to files and directories. So based on the existence of a default rule we add df flags to our rule.

If the SGID-bit (g+s) is set on the directory it means we need to maintain the groupname on the directory. This is not how NFSv4 ACLs work. What we want is that the group rights are maintained on the directory and its files, thus we add fd flags to the GROUP@ ACE when the SGID-bit is set. Except of course if the fd flags are already set.

If the Sticky-bit (+t) is set on the directory it means only the file owner and the directory owner can delete or rename files. So for the directory with the +t option set we add D for the OWNER@. For files in the directory we set d for the owner, and remove every other d even if the access rights say that one has write access.

user:: lines are converted to OWNER@ lines, group:: lines to GROUP@ lines, and other:: lines are converted to EVERYBODY@ lines. Normal user lines are converted to user@domain lines.

Next we need to maintain the permissions as close as possible. Instead of using a mask line, for which I could not find a corresponing entry in the nfs4_setfacl man-page although a proposal was written in 2006, in NFSv4 we gonna use the effective rights as the basis for the conversion of the user and group rights to their respective NFSv4 ACEs. That being said we can use the conversion rules described in the IETF Draft document to convert the #effective: rights into NFSv4 permission bits.

This should be all to convert from POSIX ACLs to NFS 4.

Problems and Fixes

To overcome the problem of NFS Stale File Handles one should use one of the following procedures:
First try to flush the export table on the server by using:

exportfs -f
If that doesn't help you can try to fix it on the client side by using:
umount /path/to/nfs/share
If you are lucky, this might help. If it succeeds you can remount the share again. (You could have used -o remount too of course.)

If the system reports that the mount is busy, and you know it is not busy with another NFS mount that you mounted on top the stale one, you can use

fuser -fvm /path/to/nfs/share
to see which processes are keeping the system busy and kill them

How ever most of the time brute force is needed by using:

umount -f /path/to/nfs/share

In certain situations, when you for example have NFS shares mounted on NFS shares and you get one or more NFS Stale File Handles, the you can not umount the top share because the underlying one has an NFS Stale File Handle, and the bottom one can not be unmounted because it is busy. The only trick I found to be working is by using:

umount -l /path/to/nfs/share/toplevel1
umount -l /path/to/nfs/share/toplevel2
umount -l /path/to/nfs/share
The /path/to/nfs/share part is the path to the lowest NFS share. This frees this mount point so it can be reused. /etc/mtab however is messed up after this change, /proc/mounts is often better of.