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.
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 |
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.
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.
|
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.
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.

Figure
1. Viewing files 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).

Figure
3. Starting eiciel directly

Figure
4. Opening a file 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:
dru is a member of; similar to chgrpls -l
|
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.

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--
|
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.

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.

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.
|
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.

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.

Figure 10. Files and the default directory ACL
|
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.
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.