Solaris Access Control Lists
by SecurityFocus Inc.
last updated Monday, March 6, 2000



Articles and General Resources in this Section

Subscribe to the FOCUS-Sun Mail List
by Security Focus Inc.

Installing Solaris
by Security-Focus.com

Securing Solaris
by Security-Focus.com

Solaris File Access Control Lists
by Security-Focus.com

Solaris and inetd.conf Part 1
by Hal Flynn

Solaris and inetd.conf Part 2
by Hal Flynn

Solaris Default Processes and init.d Pt. I
by Hal Flynn

Solaris Default Processes and init.d Pt. II
by Hal Flynn

Solaris Default Processes and init.d Pt. III
by Hal Flynn

IP Filter Basics
by Jeremy Rauch

IP Filter Basic Part 2
by Jeremy Rauch

RBAC Pt. 1
by Hal Flynn

RBAC Pt. 2
by Hal Flynn

RBAC Pt. 3
by Hal Flynn


Relevant Links

Subscribe to the FOCUS-sun Mailing List
by Security Focus Inc.

Docs.sun.com
Sun

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

  • ACL's should not be used in places where removing the setuid bit altogether would be wise. Nor should they be used in place of patching a system.
  • Always keep the full command line of how you set the ACL in a shell script. This makes it easy to restore the lists should a patch overwrite them.
  • A simple shell script can go a long way in determining what files have ACL's on them, and who has access to what:
    
    #!/bin/sh
    TEMPDIR="/tmp/ACL"
    umask 077
    rm -rf $TEMPDIR
    mkdir $TEMPDIR
    if [ $? != 0 ]; then
      echo "Directory $TEMPDIR does not exist"
    fi
    
    find . -name \* -exec ls -l {} \;| grep '[drwx]*\+ '|tr -s ' ' | 
    cut -f9 -d' ' > $TEMPDIR/acldfiles
    
    for i in `cat $TEMPDIR/acldfiles`
    do
            getfacl $i >> $TEMPDIR/Report
    done
    
    

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.



Privacy Statement
Copyright © 1999-2001 SecurityFocus.com