Solaris File Access Control Lists
One of the most convenient security features included with Solaris is also one
of the least understood features. That feature is file access control lists,
commonly referred to as FACLs or more generically, ACLs.
ACL's? Why Haven't I heard of this?
What are ACL's, you say? Unix natively has a basic file protection scheme
based on the concept of user/owner, group and other. Every file has a single owner
and a single group associated with it. The owner of the file controls the
permissions on it, and can dictate what group of people can access it, assuming
they too are in that group of people, and what kind of operations the rest of
the world can perform on it. Users cannot arbitrarily create groups; this is
dictated by the contents of the /etc/passwd and /etc/group file. These basic
protections work well under most circumstances, but they have their drawbacks.
As users cannot create groups, it often becomes an all-or-nothing situation
with permissions on files and directories. If I want to give my friend Jon
access to a file I own, and only Jon, there's no way I can do it with basic
permissions, unless a group exists that only the two of us are in. From the
administration perspective, a similar headache exists. A company that has
separate groups of administrators, all of whom have some administrative duties
on various machines, either has to create several groups, which can get
awkward and confusing, or turn to ACLs.
ACLs, in a nutshell, are a set of attributes on a file that specifies what
specific users, or groups of users, can do to a file or directory. A file with
basic permissions set still has an ACL attribute. The owner of the file
corresponds to the 2nd, 3rd and fourth permissions, the group the fifth, sixth
and seventh, and everyone else to the eighth, ninth and tenth.
UNAGI:/usr/bin(33) getfacl su
# file: su
# owner: root
# group: sys
user::r-x
group::--x #effective:--x
mask:--x
other:--x
UNAGI:/usr/bin(209) ls -l su
-r-s--x--x 1 root sys 17976 Oct 6 1998 su*
These are equivalent. In the case of the getfacl output, user is the owner
of the file, which is in this case root. Group corresponds to sys, and other,
obviously, is all users not root or in group sys. Mask bears some explanation.
The mask value is the highest level of permission users other than the owner
can have on the binary. In a normal situation, this will be set to the
highest permission available to 'other' and 'group' in that location -- this
can vary based on the permission of the parent directory. For instance, in
the /tmp directory, which is mode 1777, the mask for a file will be rwx by
default, whereas in normally permissioned directory (rwx for the owner, and
some or no permissions for group and other) it will be based on the group
value of the umask. For instance:
UNAGI:/export/home/jed(69) umask
77
UNAGI:/export/home/jed(70) touch testfile
UNAGI:/export/home/jed(71) ls -l testfile
-rw------- 1 jed staff 0 Feb 12 02:26 testfile
UNAGI:/export/home/jed(72) getfacl testfile
# file: testfile
# owner: jed
# group: staff
user::rw-
group::--- #effective:---
mask:---
other:---
UNAGI:/export/home/jed(73) umask 022
UNAGI:/export/home/jed(74) touch testfile2
UNAGI:/export/home/jed(75) ls -l testfile2
-rw-r--r-- 1 jed staff 0 Feb 12 02:26 testfile2
UNAGI:/export/home/jed(77) getfacl testfile2
# file: testfile2
# owner: jed
# group: staff
user::rw-
group::r-- #effective:r--
mask:r--
other:r--
UNAGI:/export/home/jed(80) umask 072
UNAGI:/export/home/jed(82) touch testfile3
UNAGI:/export/home/jed(83) ls -l testfile3
-rw----r-- 1 jed staff 0 Feb 12 02:27 testfile3
UNAGI:/export/home/jed(84) getfacl testfile3
# file: testfile3
# owner: jed
# group: staff
user::rw-
group::--- #effective:---
mask:---
other:r--
So Why ACL's?
File ACL's give a finer level and degree of accountability. Groups can become
unwieldy when there are dozens of people in them. Individuals can also be
in a maximum of 16 groups in Solaris 7 and prior. In a highly granular system,
this number could prove inadequate. We want people to be able to operate only
those utilities we want them to, and grant access to them strictly based on
ACL's. This gives us ultimate accountability, and a situation will never arise
where adding a person to a group will give them too much access.
What to ACL?
What to ACL is a touchy subject. For starters, ACL'ing all setuid programs
that a general user population doesn't need access to, but specific administrators
do. Does a specific user run the dump and restore system on the machine?
These are normally setuid root to allow any user to perform a dump. There
have been a number of buffer overflows found in the ufsdump/ufsrestore "suite"
of tools, so it's safe to say these should not be run by the
general user population. They could be run by root, but that might require
giving the tape backup person the root password. It could be run from cron,
but what if something goes wrong, or a restore needs to be done? This is a perfect case for
using ACL's. These binaries can be left setuid, their 'other' and 'group'
permissions stripped, and specific ACL's added.
# pwd
/usr/lib/fs/ufs
# ls -l ufs*
-r-s--x--x 1 root tty 174496 Sep 2 04:31 ufsdump*
-r-s--x--x 1 root bin 857460 Sep 2 04:31 ufsrestore*
UNAGI:/usr/lib/fs/ufs(9) getfacl ufsdump
# file: ufsdump
# owner: root
# group: tty
user::r-x
group::--x #effective:--x
mask:--x
other:--x
UNAGI:/usr/lib/fs/ufs(10) getfacl ufsrestore
# file: ufsrestore
# owner: root
# group: bin
user::r-x
group::--x #effective:--x
mask:--x
other:--x
# setfacl -m user:dump:--x,mask:--x,group::---,other:--- ufsrestore
# setfacl -m user:dump:--x,mask:--x,group::---,other:--- ufsdump
# getfacl ufsrestore
# file: ufsrestore
# owner: root
# group: bin
user::r-x
user:dump:--x #effective:--x
group::--- #effective:---
mask:--x
other:---
# getfacl ufsdump
# file: ufsdump
# owner: root
# group: tty
user::r-x
user:dump:--x #effective:--x
group::--- #effective:---
mask:--x
other:---
We check existing facl's using the getfacl command. The setfacl
command is used to alter these facl's. Getfacl is a simple command,
normally used with no options, and a file name its only argument.
Additional options are documented in the man page. Setfacl is slightly
more complex. It can be used to set the files ACL, removing whatever
was there
before (the -s option), modify the existing ACL (the -m option), delete
entries from the ACL list (the -d option), or set an ACL from a file
(the -f
option. For this option, the output from a getfacl command can be fed
as the
file).
The above example first gets the ACL's, and then modifies the existing
ACL using the -m flag. Now user 'dump' can run ufsdump and ufsrestore,
without the need for
the root password. Other users cannot run these utilities.
Not all users need to run X, OpenWindows, or CDE utilities. Specific users
may be allowed to run xterm's, but not xlock. When we know exactly who should
be allowed to do specific things to specific directories or binaries, ACL's
often present the easiest way to do so.
ACL Tips
Where to start?
It's hard to know where to start with ACL's. To that end, a simple perl
program is included with this article. It has 9 categories of setuid binaries
by default, and simplifies setting large quantities of ACL's. By no means
does this script make it so all setuid programs are protected; it only attempts
to ACL those binaries commonly left setuid. It's called
setacls.tar.gz. It has only been tested on Solaris 7. If
you actually use it, please let me know, and if there are changes you've made,
or would like to see made, also let me know.
Further Info
Additional information about ACL's is available on the getfacl and setfacl
man pages. Docs.sun.com has tons of
documentation on every facet of Solaris, including ACL's.
|