Cover V13, i09

Article

sep2004.tar

Linux ACLs

Nicholas Kirsch

Why use Access Control Lists (ACLs)? Aren't traditional Unix file permissions enough for any situation? Consider, for example, a semester-long software engineering course in which 30 students work in three-member teams on two projects. With traditional Unix permissions, each team/project combination would require a group, because all the team members must be able to collaborate, but teams must be isolated. Additionally, the professor needs access to project files for grading and for remote assistance. With this setup, the systems administrator would need to create 20 unique groups for each semester. If there were four such courses, there would be 80 groups; and if there were four projects, there would be 160 groups. With standard Unix permissions, the students cannot administer the groups themselves and the permissions are not flexible enough to allow the students to share their files with only members of their teams. This obviously becomes a management nightmare and a lot of work for the administrator.

Another example in which Unix permissions are inadequate is a mail server at a typical ISP. The ISP has a mail process that runs as user mail and file system quotas are enforced on both individuals (users) and organizations (groups). The mail process must be able to read and write the spool files, but not allow other users to read those same files (we assume no security flaws in the mail process). The admin is forced to make the mail spool files belong to the mail group while the files themselves are owned by the specific users. The admin can only (automatically) enforce quotas for users and not groups in this scenario, which is a potential loss of revenue for the ISP, who would prefer the more stringent of the group/user quotas to be enforced.

Linux supports POSIX ACLs in the stock 2.6 kernel. Linux implements ACLs based on two POSIX drafts -- 1003.1e and 1003.2c -- even though official sponsorship of those drafts was withdrawn in 1998. FreeBSD and Solaris also have almost identical ACL semantics.

Advantages

POSIX ACLs provide three enhancements over traditional Unix permissions: flexible access ACLs, default ACLs, and a restrictive mask. It is important to note that they only enhance, not change, the traditional semantics, with the exception of group permissions.

There are five types of entities for which POSIX access ACLs provide permission control:

  • the file's owner
  • named users that are not the file's owner
  • the file's group
  • named groups that are not the file's group
  • and everyone else

With POSIX ACLs, an unlimited number of named user or group permissions can be supported. A default list of ACLs can be set on a directory so that each file (or directory) created also has those ACLs. The restrictive mask defines the maximum access rights for any users beyond the file's owner, all groups, and others. If a named user ACL has more lenient permissions than the mask, the enforced permissions will be that of the mask.

Using ACLs can ease the management nightmare of the abovementioned situations. A directory can be created for each team, and default ACLs can set read/write/execute permissions for each team member and read/execute permissions for the professor and assistants. All students can be in the same group, which will be useful for allowing read access to handouts.

You could also use ACLs to allow the ISP to gather maximum revenue using the quota system. Each user's spool file would be created with the appropriate user and group ownership so that quotas would be correctly tracked and enforced for both individuals and the organization. A single ACL allowing the mail daemon read/write access would be sufficient. I am assuming that the spool files will be created in advance or a helper setuid root utility will be run by the mail server to create the spool and set the necessary ACLs.

Linux supports POSIX ACLs on several popular file systems -- ext2, ext3, jfs (IBM's journaling file system), and xfs (SGI's journaling file system). I have read that patches are available for other file systems (such as ReiserFS), but those are experimental and your mileage may vary. Most mainstream distributions (Red Hat, SUSE, Mandrake, etc.) will come with a stock kernel with ACLs enabled. Many distributions (e.g., SUSE 9.x) still shipping with the 2.4 kernel already have ACL patches applied.

Assuming you have one of the available file systems, you can check for ACL support by looking for the "acl" flag as a mount option. For example:

# mount
/dev/hda3 on / type ext3 (rw)
It isn't present, so remount the file system with ACL support:

# mount -o remount, acl /
/dev/hda3 on / type ext3 (rw, acl)
If the file system or kernel doesn't support ACLs, you would see this instead:

# mount -o remount,acl /usr/src/
mount: /usr/src not mounted already, or bad option
ACLs can easily be enabled by recompiling your kernel with five flags (since ACL support can be enabled by default via mount options in /etc/fstab, you can choose which file systems are mounted with ACL support):

CONFIG_FS_POSIX_ACL=y           # Required
CONFIG_EXT2_FS_POSIX_ACL=y
CONFIG_EXT3_FS_POSIX_ACL=y
CONFIG_JFS_POSIX_ACL=y
CONFIG_XFS_POSIX_ACL=y
You can either edit the .config kernel configuration file by hand or use your favorite method (make xconfig, make menconfig, etc.) to add the options, in which case they are listed under the "File systems" sub-menu.

setfacl and getfacl

GUI tools like Nautilus (GNOME) and Konqueror (KDE) have minimal or no support for POSIX ACLs, so you must use the command-line tools: setfacl and getfacl. Naturally, I recommend reading the man pages for these tools, but here are some brief examples that should allow you to jump right in and start using ACLs:

Create a file:

# touch test-file
View the current permissions:

# getfacl test-file

# file: test-file
# owner: nick
# group: nick
user::rw-
group::r--
other::r--
Add read permissions for a user, sys:

# setfacl -m user:sys:r test-file
# getfacl test-file
# file: test-file
# owner: nick
# group: nick
user::rw-
user:sys:r--
group::r--
mask::r--
other::r--
Remove all permissions for group adm (if no group ACL for adm is present, then the ACL list is not changed):

# setfacl -x group:adm test-file
Add an entry to the default ACL list on a directory, test-directory:

# setfacl -d -m user:nick:rx test-directory
# getfacl test-directory/
# file: test-directory
# owner: nick
# group: nick
user::rwx
group::r-x
other::r-x
default:user::rwx
default:user:nick:r-x
default:group::r-x
default:mask::r-x
default:other::r-x
Use the mask to deny execute/search permissions for all users and groups except the owner:

# setfacl -m mask:rw test-directory
# getfacl test-directory/
# file: test-directory
# owner: nick
# group: nick
user::rwx
group::r-x                  #effective:r--
mask::rw-
other::r-x
default:user::rwx
default:user:nick:r-x
default:group::r-x
default:mask::r-x
default:other::r-x
If you have an ACL-enabled distribution, then tools such as cp and mv should be updated to support ACLs. However, this is worth double-checking. On my system, I found that /bin/cp did not support ACLs, and they were silently dropped instead. To test, simply diff the output from getfacl (which can also be passed to setfacl to set ACLs). For example:

# cp -p test-file test-file2
# getfacl test-file > test-file.acl
# getfacl test-file2 > test-file2.acl
# diff test-file.acl test-file2.acl
Patches for the coreutils package (provides cat, mv, etc.), which you'll have to apply and recompile if the above test fails, are available at:

http://acl.bestbits.at
Backing up ACLs, however, is another story. Currently, standard dump and GNU tar will not preserve ACLs. If you happen to use XFS, then xfsdump will preserve them. There is also an alternative version of tar, star, which preserves ACLs nicely. Rather than convert to new applications, you can add steps to your typical backup routine to preserve and restore ACLs:

# Before dump or tar
getfacl -R / > /acl.backup

# After restore or untar
setfacl --restore /acl.backup
In my environment, all data is stored on a remote server accessed via NFSv3. While NFSv4 supports ACLs (although not POSIX ACLs), NFSv3 does not. However, there are experimental kernel patches available at http://acl.bestbits.at for kernel versions 2.4 and 2.6 that implement Sun's NFS ACL extension. They work well for me and allow ACLs to be used across the entire file system tree, not just local file systems.

POSIX ACLs do have some serious shortcomings. Default ACLs are set, not inherited, so changing a default ACL will not propagate automatically. Ideally, a provision for both default and inherited ACLs would be provided. ACLs cannot be used to explicitly deny access. In some cases, they can be used to restrict access, but even that is not obvious. The current disparity between NFSv4 and POSIX ACLs should be a yellow flag for those planning on moving to NFSv4 soon. However, I believe that POSIX ACLs are a step in the right direction and can make life a little easier for systems administrators.

References

Stevens, W. Richard. 1992. Advanced Programming in the UNIX Environment. Addison-Wesley Professional.

http://acl.bestbits.at -- man acl(5), setfacl(1), getfacl(1) on Debian sid

Nicholas Kirsch has Bachelor's degrees in Computer Science and Mathematics from the University of Puget Sound and is currently working on his Master's degree in Computer Science at the University of Washington. He works at Isilon Systems as a UNIX software developer on a FreeBSD-based distributed NAS appliance. He also owns and administers a small business providing email and Web-hosting services using Linux servers.