Department of Electrical Engineering and Computer Science


NFSv4 ACLs (Access Control Lists) are now the default mechanism to manipulate access controls on EECS, network-mounted filesystems when not using traditional UNIX permissions. However, POSIX ACLs are still the method to use on local filesystems, such as /local_scratch.


nfs4_setfacl -- This is the main command that you will use. This is used to add, remove, or modify the ACL of a file. There are 4 options of real interest, though there are others (see the nfs4_setfacl(1) man page, or run the command with -H to see all available options).

nfs4_getfacl -- This command is very simple: it prints out the ACL of the file or directory you give it. Note that it can only take one file/directory at a time.


An ACE, or Access Control Entry, is a single control statement, indicating the access of a specific entity (a user or group usually). In other words, an ACL is a list of ACEs. This article will discuss some simple and common options for an ACE, but for a full description, see the nfs4_acl(5) man page.

We will begin with the structure of an ACE:

[access type]:[flags]:[principal]:[permissions]

All parts are required for every operation, though the [flags] section may be empty.

[access type] -- Given the type of storage systems that EECS uses, there is only one real access type: A (for Allow). This means that if the given principal requires the permissions specified in the ACE, the operation will be granted.

[flags] -- Again, given the backend EECS uses, there are only two (sets of) flags one should consider using.

[principal] -- The principal is the entity to which the ACE refers (the name comes from Kerberos). This can be interpreted as a user or a group, depending on the presence or absence of the g flag in the [flags] field. The field can be specified as follows:

[permissions] -- While there are a wealth of permissions possible with NFSv4 ACLs, only a few subsets apply to EECS systems. Luckily, the nfs4_setfacl command recognizes certain short-cuts, which should be familiar to Linux users, and are the only ones discussed here.

Examples and Notes

  1. As mentioned above, the permissions outlined in this article are short-cuts for the actual permissions. For certain operations, like removing an ACE, the real permissions must be specified exactly. Additionally, if, in setting an ACE, you use the real permissions, you must specify all of them that make up a given meta-control like read. In general, for setting ACEs, it is recommended you stick with the short-cuts. If you are unsure, use the --test flag to see what your operation would do.
  2. Inherited permissions are a particularly tricky case for a variety of technical reasons which are beyond the scope of this article. Yet, here are a few caveats if you need to use them.
    1. When specifying the flags fdi, you must specify all of them. If you do not, you will not create the inherited ACE.
    2. Once you create a single inherited ACE, all other (non-inherited) ACEs already specified will be copied into a set of inherited ones. You should take the time to review this and correct any which do not grant access as you would like, but you cannot remove them.
    3. This is very important: once you have created your ACL with inherited access controls, you must then set the group field of your umask(2) to something permissive enough to allow any extra principals in your inherited list (other than the OWNER@, GROUP@, and EVERYONE@) to have the access you would like. Take a moment to let that sink in. For example, if you have an ACE like A:fdi:joeuser(at) on a directory, then you need to set your umask to at most 007 (e.g. with a command like "umask 007"). If instead you only gave joeuser the RX permissions, you could set your umask to 027. No, it does not make any sense, and yes it is a bug, but it is not likely to be fixed soon.
  3. Fixing permissions that have gotten out-of-whack is a potentially frustrating process. If you find yourself in such a situation, first breathe, then I would recommend opening the ACL in edit mode (the -e option to nfs4_setfacl) and removing all the non-standard permissions (everything other than the non-inherited OWNER@, GROUP@, and EVERYONE@ entries), and starting over. It may be easier than fixing.

Example: Give joeuser read permissions to the file file1 you want to share with them:

$ nfs4_setfacl -a "A::joeuser(at)" file1

Example: Allow the webserver to access your personal web directory, and all files underneath:

$ find ~/webhome -type d -exec nfs4_setfacl -a "A::userweb(at)" {} \;$ find ~/webhome -type f -exec nfs4_setfacl -a "A::userweb(at)" {} \;

Example: Give your research group, research1, read access to your project directory project1:

$ find project1 -type d -exec nfs4_setfacl -a "A:g:research1(at)" {} \;$ find project1 -type f -exec nfs4_setfacl -a "A:g:research1(at)" {} \;

Example: This one is more complicated; set up a shared, central git repository that you (user1) and joeuser can both push and pull from:

$ mkdir -m 700 sharedrepo.git$ nfs4_setfacl -a "A::user1(at)" sharedrepo.git$ nfs4_setfacl -a "A::joeuser(at)" sharedrepo.git$ nfs4_setfacl -a "A:fdi:OWNER@:RWX" sharedrepo.git$ nfs4_setfacl -a "A:fdi:user1(at)" sharedrepo.git$ nfs4_setfacl -a "A:fdi:joeuser(at)" sharedrepo.git$ nfs4_getfacl sharedrepo.gitA::OWNER@:rwaDxtTcCy
$ umask 007$ git init --bare --shared=group sharedrepo.git

As always, if you have questions, a more complicated scenario, or just need someone to look over your shoulder, feel free to contact the EECS IT Staff, and we will do our best to get you going.


The University of Tennessee, Knoxville. Big Orange. Big Ideas.

Knoxville, Tennessee 37996 | 865-974-1000
The flagship campus of the University of Tennessee System