Access Control Lists

If you've used Linux for a long time, you're probably quite familiar with file permissions. Indeed, managing permissions is a critical part of managing a Linux system.

If you’ve used Linux for a long time, you’re probably quite familiar with file permissions. Indeed, managing permissions is a critical part of managing a Linux system.

In general, you should provide minimal access whenever possible. Every user (or group) should have just enough permissions and no more.

However, providing appropriate permissions to each user is often complicated by the permission scheme itself. Unix permissions — the model for Linux permissions — were designed in a day and age when computers were still relatively new and when the security implications of the Unix scheme had yet to be fully considered. Thus, Unix’s “legacy” permissions can be limiting in today’s world, particularly on multi-user systems.

Of particular note, an ordinary user has very limited abilities to grant access to his or her files to others. A user can give any combination of read, write, and execute permissions to the himself, the file’s group, and the world, and he can reassign the group of the file. But what if that user (say, amy) wants to give three other users (say, david, theo, and lola) read access to her file, while preventing others from reading the same file? This task is easy if the system has a group that consists only of the three target users: amy just assigns the file to that group and gives group read access to the file. However, this task is impossible for amy (and any other ordinary user) if no group holds solely the target users. (Of course, the superuser could create such a group if desired, providing a way around this limitation. However, ad hoc access rules remain impossible because an ordinary user cannot create groups.)

To overcome this limitation, Linux has implemented support for access control lists (ACLs). ACLs serve as an extension to traditional Unix permissions, giving end-users the ability to specify special access rights to a file. To use ACLs, though, you must use particular Linux filesystems and enable special features. You may also need to download and install special ACL utilities. And your users must also know how to access and use ACLs.

ACL Prerequisites

The earliest versions of Linux couldn’t support ACLs. To add the feature, several key things had to be changed:

* KERNEL SECURITY FEATURES. The Linux kernel is ultimately responsible for granting or denying access to files, so ACL features had to be added to the kernel.

* FILESYSTEM DATA STRUCTURES. To define ACLs, the underlying disk filesystem must persist the ACLs associated with each file. Persistence of ACLs was missing from the earliest versions of common Linux filesystems, such as ext2fs, so persistence had to be added, too.

* USER UTILITIES. Of course, for ACLs to do any good, user tools to create, view, and modify ACLs are needed, too. These tools had to be written.

The former two prerequisites (kernel security features and filesystem data structures) need kernel modifications. All 2.6.x kernels support ACLs, and adding ACL support to 2.4.x kernels is possible with the application of a patch. (Typically, you need only patch the kernel with an ACL-enabled filesystem.) This article assumes that you’re working with a 2.6.x kernel.

Figure One: Using Access Control Lists (ACLs) requires adding ACL support to the filesystem you use

To add the necessary kernel features, check your kernel’s filesystem configuration area. For instance, Figure One shows the kernel filesystem configuration area when you run make menuconfig in the kernel source tree.

At press time, ext2fs, ext3fs, JFS, and XFS all support ACLs, but require you to explicitly specify that feature. (ext2fs and ext3fs both place this option under the “Extended Attributes” option, so you must enable that option one first.) ReiserFS doesn’t currently support ACLs, although patches to add this support do exist. ACL support is also available for NFS, but of course, the server must support ACLs on the filesystem it serves, and you must use NFSv3 or later (NFSv2 doesn’t support the necessary calls). Non-Linux filesystems also lack ACL support (some, such as NTFS, do support ACLs, but the Linux kernel cannot yet manage them).

When you select these kernel filesystem options, all the necessary kernel features are enabled to fully support ACLs. Of course, you must recompile your kernel and reboot the computer before any changes work.

Some distributions ship with ACL support enabled, so you might not need to recompile your kernel. Check your documentation or your current kernel configuration if you’re unsure.

If you’re using an older kernel or want to apply a ReiserFS patch, check http://acl.bestbits.at. This site hosts pointers to patches, utilities, and other ACL-related files and information.

Most ordinary programs don’t need to be modified to support ACLs. Programs simply continue to receive the same error messages from the kernel when file access permission is denied, and are granted access to programs based on ACLs just as when the underlying Unix permissions grant access. An exception to this rule is if the program gives users the ability to view or modify permissions. Such programs give limited or no access to ACLs unless the programs are modified to explicitly support them.

It’s important to realize that ACLs supplement — not replace — Unix permissions. You can continue to use Unix permissions on a system that supports ACLs, and in fact many (perhaps most) files have no need for ACLs. For instance, chances are you won’t need to set ACLs on most program executable files and system configuration files. The primary use of ACLs is to give users finer control over their own files.

ACL Features

So, precisely how do ACLs work? They enable you to set read, write, and execute permissions on files, but unlike standard Unix permissions, which support these permissions only for the owner, the group, and all other users, ACLs allow you to set unique permissions for any user or group by name or by numeric ID (a user ID or group ID number). In fact, once ACL support is in place, you can consider Unix permissions to be a subset of ACLs, using special names to set default permissions for the owner, the group, and all other users.

The ACL tools use some of the same conventions for accessing permissions as do the older Unix-style permissions tools, such as chmod. Specifically, permissions are identified using a three-character string that represents the presence or absence of read, write, and execute permissions. If a position contains an r, w, or x character (depending on the position), then read, write, or execute permission is granted. If the position contains a dash (-), though, that permission is denied.

For instance, rw- gives read and write but not execute permission to a file, while r-x gives read and execute, but not write, permission.

ACL Support Tools

Manipulating ACLs require ACL-enabled tools. The most basic of these are two new commands, getfacl and setfacl, which retrieve ACL information and change ACL information, respectively. Most modern Linux distributions ship with these tools, but if yours doesn’t, check http://acl.bestbits.at for the updated coreutils package (which replaces fileutils). Alternatively (and perhaps preferably), you might look for an updated package from your distribution’s maintainer. ACL tools are very basic to proper Linux functioning, so you don’t want to risk causing problems by installing the wrong package.

To use getfacl, type its name followed by the name of one or more files. The output is a display of the ACLs associated with each file, including the ACLs that correspond to the basic Unix permissions. Here’s an example:

$ getfacl turkey.txt
# file: turkey.txt
# owner: rodsmith
# group: users

The output of getfacl begins with three lines that start with hash marks (#) and summarize the file’s name and the Unix owner and group for the file.

The next several lines show the ACLs. The lines that begin with user:: (notice the two colons), group::, and other:: show the Unix-style owner, group, and world permissions, respectively. These should match the values you see in a long listing of the file (as in ls -l turkey.txt).

The remaining lines define ACLs. Above, the user: genie:rw- line indicates that the user genie has rw- (read and write) access to the file. Thus, genie can modify this file, although nobody else can (it’s owned by rodsmith and the group and world permissions prevent others from modifying it).

The mask::rw- line describes the ACL mask, which restricts access to ACL users yet doesn’t affect ordinary Unix permissions. For instance, suppose you want to limit the rights granted by ACLs to a group of users. You could then set the mask to the permissions you want. (Setting ACLs is described shortly.)

The more restrictive value of the mask and the specific user’s ACL takes precedence. Ordinarily, the ACL tools automatically set the mask to a value that grants ACL users the permissions required for their level of access, but you can explicitly adjust the mask to do otherwise.

The getfacl command takes a number of options. -R performs a recursive listing of ACLs for all files in a directory tree, and –skip-base omits displaying information on files that use only the base, Unix-style permissions. Consult the getfacl man page for more information on these options.

Displaying ACLs is informative, but to modify them, you need another tool: setfacl. This command is the ACL equivalent of chmod, and in fact you can modify ordinary Unix-style permissions with setfacl. setfacl is more complex than getfacl. Its basic syntax is:

setfacl [options] [{-m|-x} acl_spec]
[{-M|-X} acl_file] file

options modify setfacl‘s behavior in one way or another; a few options are described later. Generally, you’ll specify -m or -M to modify an ACL, and -x or -X to remove an ACL. The lowercase variants (-m and -x) accept an ACL specification on the command line; the uppercase variants (-M and -X) accept the ACL specification in a file. In all cases, the command ends with one or more filenames to be modified.

The trickiest aspect of using setfacl is the ACL specification. The basic form is similar to that shown in the getfacl output, but the user: or group: part of the specification may be omitted if it doesn’t result in an ambiguous specification. You may also omit trailing dash (-) characters from permission specifications, as in rw instead of rw-.

For instance, the following two lines both give the user genie read and write permission to the file turkey.txt:

$ setfacl -m user:genie:rw turkey.txt
$ setfacl -m genie:rw- turkey.txt

You can also set the ordinary Unix permissions using this notation:

$ setfacl -m group::rw turkey.txt

This line gives the group read/write access to turkey.txt. The user:: and other:: codes may be used in place of group:: to set permissions for the file’s owner and the world, respectively.

You can use the mask:: code to set the mask, as described earlier. This can be a handy way to temporarily (or permanently) remove extra permissions granted via ACLs without explicitly removing all of the ACLs. Setting the mask does not affect the standard Unix permissions, though — for instance, you can set mask::— but still grant user, group, or world permissions using the user::, group::, or other:: codes, or the equivalents using chmod.

Deleting ACLs is usually easier than adding them: you use the -x or -X option to setfacl, but you need only specify the user, not the existing ACL for that user:

$ setfacl -x genie turkey.txt
$ setfacl -x user:genie turkey.txt

Issuing either of these commands removes any ACLs for the user genie that might exist on the file turkey.txt. You can’t remove the basic Unix permissions for the owner, group, or world using this technique, although you can set any permissions you like (including none at all) using setfacl -m.

In principle, other programs, such as word processors, mail clients, and so on, could enable you to set ACLs. This could be a feature in file save dialog boxes, much as these programs enable you to set Unix permissions on files they save. Such access is rare, though. If you’d like to see it in a program you use, first consult its documentation; it might be there, hidden away in some obscure dialog box. If you can’t find it, contact the program’s author, or try adding it yourself if you know enough about programming.

ACLs and Samba

One of the advantages of Linux ACLs is that they can help a Linux system interact more effectively with Windows systems. Windows NT/200x/XP supports ACLs that are conceptually similar to Linux ACLs, although some details differ.

Windows ACLs, like Linux ACLs, require the use of an ACL-aware filesystem. In Windows, this is NTFS. (Linux’s NTFS drivers don’t yet support the NTFS ACL features, though.) Windows also supports ACLs when sharing files over the network, but only with an ACL-aware server.

Linux’s Samba file server supports ACLs by default. (Consult the Samba documentation, particularly for the nt acl support parameter, for details.) When used on a traditional Linux filesystem without ACL support, though, this feature only provides access to Unix-style permissions, much as setfacl and getfacl. To fully support ACLs, you can configure file shares on a Linux filesystem that supports ACLs.

In principle, this gives Windows NT/200x/XP clients access to ACLs — at least, enough to set read and write permissions for individual users.

However, because of differences in how the two operating systems treat ACLs, not all features work precisely as Windows users expect. For instance, a Windows user won’t be able to take ownership of a file, because in Linux only root may change a file’s ownership.

Roderick W. Smith is the author or co-author of twelve books, including Linux Power Tools and Advanced Linux Networking. He can be reached at rodsmith@rodsbooks.com.

Comments are closed.