ONLamp.com    
 Published on ONLamp.com (http://www.onlamp.com/)
 See this if you're having trouble printing code examples


FreeBSD Basics

Using FreeBSD's ACLs

by Dru Lavigne
09/22/2005

Five years ago (gee, has it really been that long?), I wrote a series of articles on understanding Unix permissions. Since then, FreeBSD has implemented something known as ACLs (Access Control Lists).

ACLs came to BSD as part of the TrustedBSD project. As the name suggests, they give a user finer access control over permissions.

Why Would I Want to Use ACLs?

While ACLs don't change the standard Unix permissions of (r)ead, (w)rite, and e(x)ecute, they do give you better control over whom those permissions affect. Here's a simple example--as a regular user, create a test file in the system's temporary directory:

% touch /tmp/test
% ls -l /tmp/test
-rw-r--r--  1 dru  dru  0 Jul 26 15:43 /tmp/test

I've chosen this directory as all users have write access here and it is a good place to test out permissions. However, don't keep important files here, because they are likely to disappear, depending on how the system administrator has configured the cleaning of this directory!

Related Reading

Mastering FreeBSD and OpenBSD Security
By Yanek Korff, Paco Hope, Bruce Potter

In this example, the creator of the file, dru, has rw access; anyone in the group dru has r access; and everyone else has r access. Note that when you create a user in FreeBSD, you also get a group of the same name with that user as the only member.

Now suppose that I need to give the users rob and toby write access to this file. As the permissions stand now, they might be able to open the file in an editor, but they won't be able to save any changes, as they are neither the user dru nor a member of the dru group. They fall into other, which has read permission only.

Before ACLs, the typical solution to this dilemma was to modify group memberships. I could, for example, ask the system administrator to add rob and toby to the dru group. I could then use chmod to add write permission to the dru group for this file. This is slightly better than giving write permission to other, as that would allow anyone on the system to write to that file.

Alternatively, the system administrator could carefully plan out which users need access to which files and then create groups and assign users to those groups. Then, assuming a user belonged to the required group, she could use the chgrp command on the files she created in order to change group ownership.

Neither system is perfect, however. For one, it requires bugging the system administrator, which is inconvenient when all you want to do is share your own files. Further, consider another scenario. Suppose that dru, rob, and toby have all been made members of the newly created workgroup group. All three group members can write to any files with write permission for workgroup, regardless of which one originally created the file. But what if dru wants rob to write to one of these files but not toby?

This is starting to sound pretty complicated, isn't it? Fortunately, this is the reason behind ACLs. Without having to ask the administrator to make a bunch of groups or having to use chgrp, dru can easily pick and choose through her files and decide which files rob gets write access to; she can also give toby write access to a different set of files.

This article shows how you, as the system administrator, can prepare a FreeBSD system for ACLs. I'll then demonstrate a GUI utility, which will allow your users to easily control the ACLs on their own files. Finally, I'll show you how to back up files containing ACLs.

Preparing the System

If you're using FreeBSD 5.1 or later, ACL support is already built into your kernel and UFS2 filesystem.

(With earlier versions of FreeBSD, see Daniel Harris's article on ACLs for instructions for compiling ACL support into FreeBSD.)

You simply need to decide on which filesystem(s) you wish to use ACLs:

# df
Filesystem  1K-blocks    Used   Avail Capacity  Mounted on
/dev/ad0s1a    253678   35764  197620    15%    /
devfs               1       1       0   100%    /dev
/dev/ad0s1e    253678      22  233362     0%    /tmp
/dev/ad0s1f   8077406 3045460 4385754    41%    /usr
/dev/ad0s1d    253678   21048  212336     9%    /var

On my system, I wanted to enable ACLs only for users, so I configured only the /usr filesystem.

The FreeBSD handbook explains the advantages of using the tunefs command to enable ACLs. The disadvantage is that it requires bringing the system down to single-user mode and unmounting the filesystem. Choose a time that will least impact users; once you're sure no one is connected to the system, use the following:

# shutdown now
Enter full pathname of shell or RETURN for /bin/sh: 

# /sbin/umount /usr
# /sbin/tunefs -a enable /dev/ad0s1f
tunefs: ACLs set
# /sbin/mount /usr

Use your output from df to know the name of the device on which you wish to enable ACLs (-a).

Then, to see if it worked:

# /sbin/mount
/dev/ad0s1a on / (ufs, local)
devfs on /dev (devfs, local)
/dev/ad0s1e on /tmp (ufs, local, soft-updates)
/dev/ad0s1f on /usr (ufs, local, soft-updates, acls)
/dev/ad0s1d on /var (ufs, local, soft-updates)

And to bring the system back to multiuser mode:

# exit

That's it. ACLs are now enabled on /usr.

Installing the GUI

If you do a Google search for "FreeBSD acl," you'll find several articles and how-tos. Each of these gives examples on using the main ACL command line utilities, getfacl and setfacl, such as Greg Czaplinski's excellent Working with ACLs in FreeBSD 5.x.

While getfacl is straightforward, the syntax for setfacl can get a bit hairy--more than enough to scare off most of your users. Here, a GUI is beneficial, as it allows users to easily determine and control who has what permissions.

eiciel provides an intuitive GUI and is available as a FreeBSD package or port. It also works on Linux systems and is a part of the Nautilus file manager, which among other things adds a properties sheet to files, allowing a user to easily view and manage file permissions, icons, and the Open With utility.

You can quickly add the binary package using:

# pkg_add -r eiciel

Once you have installed the package, leave the superuser account and enter an X session as a regular user.

Accessing the GUI

There are two ways to access the newly installed ACL GUI. One is to start nautilus; see Figure 1. The user dru has three files in her home directory called test, file1, and myfile. Figure 2 shows what happens when the user right-clicks on test and selects Properties from the menu.

viewing files in Nautilus
Figure 1. Viewing files in Nautilus

viewing file properties in Nautilus
Figure 2. Viewing file properties in Nautilus

The eiciel installation has added an Access Control List tab to Nautilus. You can see from the figure that this tab provides a GUI representation of the following permission set:

% ls -l test
-rw-r--r--  1 dru  dru  0 Jul 27 09:09 test

The other method is to start eiciel directly (Figure 3). Click on the Open button to select the test file (Figure 4), which will show the ACLs window (Figure 5).

starting eiciel directly
Figure 3. Starting eiciel directly

opening a file in eiciel
Figure 4. Opening a file in eiciel

editing ACLs in eiciel
Figure 5. Editing ACLs in eiciel

I prefer to use the nautilus method, as it also includes the Permissions tab, which allows me to view and change:

Understanding ACL Masks

Look again at the bottom portion of Figure 2. Here, you can view the users and groups on the system. Double-clicking on the user rob will add two items to the top portion, or Access Control List, of the screen as shown in Figure 6.

adding to a user's ACL
Figure 6. Adding to a user's ACL

Note: Future versions of eiciel will include a check box to exclude system accounts.

Notice that the entries for rob and mask have full rwx permissions, which is more than dru has as the owner of the file. What is happening here? By double-clicking on rob, I added an ACL, which I can verify with a long listing on my home directory:

% ls -l
drwx------  2 dru  dru   512 Jul 26 10:35 Desktop
-rw-r--r--  1 dru  dru     0 Jul 27  9:22 file1
-rw-r--r--  1 dru  dru     0 Jul 27  9:22 myfile
-rw-r--r--+ 1 dru  dru     0 Jul 27 10:03 test

See that + at the end of the permission set for test? That indicates that an ACL has been set on that file. I can view it with getfacl:

% getfacl test
#file:test
#owner:1001
#group:1001
user::rw-
user:rob:rwx
group::r--
mask::rwx
other::r--

That output is basically the text representation of Figure 6.

Why did rob get rwx, and what is this mask entry? By definition, an ACL mask determines the maximum allowable permissions. It's worth doing two things to make sure you understand that fully.

First, uncheck the execute permission from the rob entry. Note that I can give rob any combination of read, write, or execute that I desire. From the perspective of the person using this GUI, she can simply double-click on the user to add them, and uncheck the permissions she doesn't want the user to have.

What happens if you change that mask entry? Put rob back as rwx, but remove execute from mask. As soon as you do that, the execute permission next to rob, or any other user with execute, will display a red exclamation mark. The GUI also displays a message that a red exclamation mark means "an ineffective permission."

This makes sense if you go back to the definition of an ACL mask. Now the maximum allowable permission set is rw, meaning that anyone who appears to have execute really doesn't. While the GUI gives a nice visual, getfacl will also indicate the effective permissions:

% getfacl test
#file:test
#owner:1001
#group:1001
user::rw-
user:rob:rwx	# effective: rw-
group::r--
mask::rw-
other::r--

Understanding Directory ACLs

A file can have only one ACL, its "access ACL." Most users will be happy with the ability to fine-tune the permissions on the files they create, as demonstrated in the previous section.

Directories are more complex, as they can have up to three types of ACLs:

The current FreeBSD implementation supports only the first two types of directory ACLs, so double-check the effective permissions on any files you create in directories containing ACLs.

To see how this works, create a directory called folder.

Note: If you're planning on setting an ACL on a directory, do so before you add any files or subdirectories to that directory. This is because only objects created after the ACL can inherit the ACL. If you add an ACL to a directory that already contains files or subdirectories, always double-check that they contain the desired ACLs.

Look at the ACL properties for folder (Figure 7). It looks similar to a file, except the Default ACL button is no longer grayed out and there is a new Default check box under the Participants list.

ACL properties for the new directory
Figure 7. ACL properties for the new directory

The User, Group, and Other permissions affect access to the directory itself and therefore represent the first type of ACL or the access ACL.

adding Default ACL properties
Figure 8. Adding default ACL properties

Click on that Default ACL button. As Figure 8 shows, there are now four additional entries. These represent the second type of ACL, or the default directory ACL, and affect only subdirectories. Verify this by creating a subfolder and file:

% getfacl folder
#file:folder
#owner:1001
#group:1001
user::rwx
group::r-x
other::r-x

% mkdir folder/subfolder
% touch folder/testfile
% ls -l folder
drwxr-xr-x+ 2 dru  dru  512 Jul 27 12:23 subfolder
-rw-r--r--+ 1 dru  dru    0 Jul 27 12:23 testfile

Notice that subfolder inherited the directory permissions but testfile did not.

Adding a User to a Directory ACL

If I go back to folder properties and add rob, will he have write access to folder/subfolder/ and folder/testfile? Good for you if you answered no. This change to the directory ACL will affect only subdirectories or files created after the change.

I also have a choice when I add rob. If I just double-click on rob, I give only rob access to the directory. In other words, I change the first type of ACL. However, if I first check the Default box and then double-click on rob, I change the second type of access, or affect rob's permissions on the subdirectories I create. I can actually add rob both ways. If the icon has a D over it, it affects subdirectories; if it doesn't, it affects access only to this directory.

For demonstration purposes, add both versions of rob and leave them with the default rwx permissions. To see the effect, create another test subdirectory and file:

% mkdir folder/subfolder2
% touch folder/testfile2

Figure 9 shows the effective ACLs. As expected, the default directory ACL, represented by the rob icon with a D, inherited rwx from the parent directory. Note that the access ACL, represented by the rob icon without a D, shows that w is an ineffective permission. In other words, because it represented access only to the parent directory, it doesn't give rob any inherited permissions on this subdirectory; therefore, rob is subject to the permissions any other user would be on this subdirectory. However, you can override this by checking the write box in the mask. If you do change the mask, double-check the other users on your screen to make sure you don't inadvertently give write access to a user who shouldn't have it.

effective ACLs
Figure 9. Effective ACLs

Once the explanation of the permissions in folder/subfolder2 makes sense to you, take a look at testfile2 as seen in Figure 10. Note that there isn't any rob icon with a D. This is because files don't inherit the default directory ACL. Because there isn't any current support for a default access ACL, rob doesn't inherit any permissions at all from either the directory or subdirectory and is subject to the same permissions as any other user. Again, the way to modify this is to modify the mask (remember, it represents the maximum possible permissions) and double-check that the new mask value doesn't give other users more permissions than you intend.

files and the default directory ACL
Figure 10. Files and the default directory ACL

Backing Up ACLs

One of the things you need to be aware of if you plan to use ACLs is that most backup utilities will correctly backup files containing ACLs, and even restore those files, but not their ACLs. A good solution to this is to install /usr/ports/archivers/star from the ports collection. If you've ever used tar, it won't take long to train yourself to add a few extra switches to catch all of those ACLs.

In this example, the superuser has made a backup directory for dru outside of her home directory so she can store backups of her home directory.

# mkdir -p /usr/backups/dru
# chmod dru:dru /usr/backups/dru
# exit

Next, dru backs up her home directory, which contains files with ACLs:

% whoami
dru
% cd
% star -cv -Hexustar -acl -f /usr/backups/dru/home.tgz .

Next, dru will try a test restore in a temporary directory in her home directory:

% mkdir ~/tmp
% cd ~/tmp
% star -xv -Hexustar -acl -f home.tgz

Note: If you try to restore to a filesystem that doesn't have ACLs enabled, star will complain but will still restore the files minus the ACLs.

Conclusion

Many users either haven't yet heard of the benefits of ACLs or believe them to be difficult to use. Spend a half an hour showing your users how to use eiciel and star, and they'll wonder how they ever lived without ACLs.

Dru Lavigne is a network and systems administrator, IT instructor, author and international speaker. She has over a decade of experience administering and teaching Netware, Microsoft, Cisco, Checkpoint, SCO, Solaris, Linux, and BSD systems. A prolific author, she pens the popular FreeBSD Basics column for O'Reilly and is author of BSD Hacks and The Best of FreeBSD Basics.


Read more FreeBSD Basics columns.

Return to the BSD DevCenter

Copyright © 2009 O'Reilly Media, Inc.