How to Configure Access Control Lists (ACLs) in Solaris

Standard UNIX file protection provides read, write, and execute permissions for the three user classes: file owner, file group, and others. ACLs provide greater data access control for each file or directory. ACLs enable you to control file permissions more finely.

Limitations of the Basic UNIX Permissions

Standard UNIX file permissions do not allow the owner of the file or directory to grant or deny access to other users.

ACL Benefits

An ACL is used by the owner of a file or directory to grant or deny specific user access, by using the three user classes of user, group, and other.

ACL Commands

The table below shows you which command and options to enter when you want to view or set ACLs for a file or directory.

Command and Option Description
getfacl filename(s) Displays ACL entries for files
setfacl acl_entries filename Configures ACL entries on files

Viewing ACL Entries

Each ACL entry has the following syntax:

entry-type:[UID or GID]:perm

where:

  • entry-type – Specifies the scope of the file permissions to the owner, owner’s group, specific users, additional groups, or the AC mask.
  • UID or GID – Specifies the user’s name or user’s identification number (UID), or the group’s name or group’s identification number(GID).
  • perm – Symbolically specifies permissions for entry-type by using r, w, x, and -, or by using octal values from 0 to 7

You use the getfacl command to display the contents of ACL entries for a file or directory. The syntax of the command is:

getfacl [-a] filename1 [filename2 ...]

where: -a - Displays the file name, file owner, file group, and ACL entries for the specified file or directory. filename - Specifies one or more files or directories.

$ getfacl file1
$ file: file1
$ owner: userc
$ group: sysadmin
user::rw
group::r--          #effective:r--
mask:r--
other:r--
$

ACL Entry Types

The table below shows ACL syntax types.

Entry Type Description
u[ser]::perm The permissions for the file owner.
g[roup]::perm The permissions for the owner’s group
o[ther]:perm The permissions for users other than the owner or members of the owner’s group.
u[ser]:UID:perm or u[ser]:username:perm The permissions for a specific user. The username must exist in the /etc/passwd file.
g[roup]:GID:perm or g[roup]:groupname:perm The permissions for a specific group. The groupname must exist in the /etc/group file.
m[ask]:perm The ACL mask indicates the maximum effective permissions allowed for all specified users and groups. The mask does not set the permissions for the owner or others. You can use the mask as a quick way to change effective permissions for all the specific users and groups.

Determining if a File Has an ACL

There are two types of ACLs: trivial and non-trivial. You can use the ’ls -l’ command to see which files or directories have a non-trivial ACL entry. The ls command does not display the actual list of ACL entries. To display the list of ACL entries, use the getfacl command. When viewing the output of the ls -l command, if a file has an non-trivial ACL entry, a plus (+) sign appears at the end of the permission field.


$ pwd
/export/home/userc

$ ls -l
total 0
-rw-r--r--  1 userc      staff    0 Jan 22 13:40 file1
-rw-r--r--+ 1 userc      staff    0 Jan 22 13:40 file2

In this example, the lack of a + sign for the file1 file shows that it possesses a trivial ACL entry. The presence of a + sign for the file2 file indicates that this file has a non-trivial ACL entry. This indicates that permissions were customized. The following examples show the output of the getfacl command:

$ getfacl file1
# file: file1
# owner: userc
# group: sysadmin
user::rw
group::r--            #effective:r--
mask:r--
other:r--

No custom ACL entries are configured, hence the ACL is trivial. The permissions listed in the output from the getfacl command are the same as the current permissions for the file or directory.

$ getfacl file2
# file: file2
# owner: userc
# group: sysadmin
user::rw-
user:usera:rwx         #effective:r--
group::r--             #effective:r--
mask:r--
other:r--

If a custom ACL entry is configured, the ACL is non-trivial. The file2 file has a custom ACL entry for the usera user. The usera user is given a custom ACL entry that permits read, write, and execute permissions (rwx) for file2. However, the ACL mask on file2 allows only read permission (r–). Therefore, usera has an effective permission of only r–.

The setfacl Command

The table below shows you which command and options to enter when you want to administer ACLs for a file or directory.

Command/Option Description
# setfacl -m acl_entries filename Creates or modifies ACL entries on files
# setfacl -s acl_entries filename Substitutes new ACL entries for old ACL entries
# setfacl -d acl_entries filename Deletes one or more ACL entries on files
# setfacl -r filename Recalculates the ACL mask based on the ACL entries, when used with the -m or -s option

Configuring ACLs by Using the Command Line

You can set ACLs by using the command line or the File Manager GUI. You can launch the File Manager GUI by using the /usr/dt/bin/dtfile command. These tools enable you to do the following:

  • Modify an ACL
  • Substitute an ACL
  • Delete an ACL
  • Recalculate an ACL mask

The ACL permission bits define specific user or specific group permissions that are available, subject to the ACL mask. The ACL mask defines the maximum set of effective permissions that are available for an ACL entry. An ACL mask setting of rw– (or octal number 6) on a file permits read and write permission on the file but does not permit execute permission on this file.

Configuring or Modifying an ACL

The most common method used to configure an ACL is to modify the ACL. To modify ACL entries on a file, use the setfacl command. The syntax of the command is:

# setfacl -m acl_entry filename

where: -m - Modifies the existing ACL entry. acl_entry - Specifies a list of modifications to apply to ACLs for one or more files, directories, or both. filename - Specifies one or more files or directories.

The following example shows you how to add a new ACL entry to a file with existing ACL entries.

$ getfacl file2
# file: file2
# owner: userc
# group: sysadmin
user::rw
user:usera:rwx        #effective:r--
group::r--            #effective:r--
mask:r--
other:r--

$ setfacl -m u:userb:7 file2
$ getfacl file2
# file: file2
# owner: userc
# group: sysadmin
user::rwuser:
usera:rwx         #effective:r--
user:userb:rwx    #effective:r--
group::r--        #effective:r--
mask:r--
other:r--

Even though the ACL entries for usera and userb request read, write, and execute permissions, the ACL mask does not allow write and execute permissions for both entries. From the previous example you can see that although usera and userb have rwx permission on file2 they have effectively only read permission. The following example shows you how to modify the mask.

$ setfacl -m m:rwx file2
$getfacl file2
# file: file2
# owner: userc
# group: sysadmin
user::rwuser:
usera:rwx        #effective:rwx
user:userb:rwx   #effective:rwx
group::r--       #effective:rwx
mask:rwx
other:r--

Recalculating an ACL Mask

You can control globally the effective permissions of a custom ACL entry by using the ACL mask. Examples in this post show that the ACL mask sometimes does not provide the requested permissions that you set to be effective. You recalculate the ACL mask to provide all of the requested permissions in the list of ACL entries to be effective. After recalculating the ACL mask, the effective permission of each ACL entry provides the full set of requested permissions for that entry.

The following example shows how to recalculate the ACL mask entry:

 setfacl -r -m acl_entry filename...

where: -r - Recalculates the ACL mask entry to allow maximum effective permissions for every ACL entry. -m - Modifies the existing ACL entry. acl_entry - Specifies a list of modifications to apply to the ACLs for one or more files, directories, or both. ACL entries can also be added, modified, or deleted in addition to the recalculation of the mask. filename - Specifies one or more files or directories.

Caution: Using the chmod command on a file that already has an ACL on it will recalculate the mask. Take care that access to a resource is not denied or incorrect access is not granted.

$ getfacl file1
# file: file1
# owner: userc
# group: sysadmin
user::rwx
user:usera:rwx            #effective:rw
group::rw-                #effective:rwmask:rw
other:r--
$ setfacl -r -m u:usera:7 file1
$ getfacl file1
# file: file1
# owner: userc
# group: sysadmin
user::rwx
user:usera:rwx          #effective:rwx
group::rw-              #effective:rw
mask:rwx
other:r--

An example of the effect of using the chmod command on a file that already has an ACL set.

$ getfacl testfile
# file: testfile
# owner: user1
# group: staff
user::rwuser:
user2:rw- #effective:r--
group::r-- #effective:r--
mask:r--
other:r--
$ chmod 664 testfile
$ getfacl testfile
# file: testfile
# owner: user1
# group: staff
user::rw
user:user2:rw-         #effective:rw
group::rw-             #effective:rw
mask:rw
other:r--

By changing the group permission to read-write, this has recalculated the mask and given user2 read and write permission for the testfile.

Substituting an ACL

To replace the entire ACL for a file from the command line, you must specify at least the basic set of ACL entries: user, group, other, and ACL mask permissions. Use the setfacl command with the following options to substitute an ACL on a file:

$ setfacl -s u::perm,g::perm,o:perm,m:perm,[u:UID:perm],[g:GID:perm] filename

where: -s - Specifies a substitution is being made for the entire ACL contents. acl_entry - Specifies which ACL entry (from a list of one or more ACL entries) to modify on the file or directory. filename - Specifies one or more files or directories.

The following example shows that no non-trivial ACL entries currently exist on file1 and file2:

$ ls -l
total 0
-rw-r--r--      1 userc    sysadmin     0 Apr 18 15:44 file1
-rw-r--r--      1 userc    sysadmin     0 Apr 18 15:44 file2

To display the trivial ACL permissions for file1, enter the getfacl command:

$ getfacl file1
# file: file1
# owner: userc
# group: sysadmin
user::rw
group::r--       #effective:r--
mask:r--
other:r--

The following example shows you how to substitute an ACL on the file named file1. The ACL permissions are configured as follows:

  • The file owner has read, write, and execute permissions
  • The group has read and write permissions
  • The other users have read-only permissions
  • The user named usera has read, write, and execute permissions on the file
  • The ACL mask has read and write permissions
  • The user named usera has read, write, and execute permissions

Perform the setfacl command with the following options to substitute an ACL on file1:

$ setfacl -s u::rwx,g::rw-,o:r--,m:rw-,u:usera:rwx file1

The ls -l command shows that an ACL exists on the file named file1.

$ ls -l
total 0
-rwxrw-r--+ 1 userc    sysadmin   0 Apr 18 15:44 file1
-rw-r--r-- 1 userc     sysadmin   0 Apr 18 15:44 file2

$ getfacl file1
# file: file1
# owner: userc
# group: sysadmin
user::rwx
user:usera:rwx            #effective:rw
group::rw-                #effective:rw
mask:
rwother:
r--

The following example shows how to substitute an ACL on the file2 file, using octal notations to establish the ACL entries. Before you replace the entire ACL, use the getfacl command to display the ACL for file2.

$ getfacl file2
# file: file2
# owner: userc
# group: sysadmin
user::rw
group::r--              #effective:r--
mask:r--
other:r--
$ setfacl -s u::7,g::6,o:4,m:6,u:usera:7 file2

After you substitute the ACL permissions using the setfacl command, use the ls -l command to verify if an ACL exists on the file named file2.

$ ls -l
total 0
-rwxrw-r--+ 1 userc sysadmin 0 Apr 18 15:44 file1
-rwxrw-r--+ 1 userc sysadmin 0 Apr 18 15:44 file2

The output of the getfacl command on file1 and file2 shows the ACLs are identical, regardless of which method is used to create the ACL.

$ getfacl file1 file2
# file: file1
# owner: userc
# group: sysadmin
user::rwx
user:usera:rwx        #effective:rw
group::rw-            #effective:rw
mask:rw
other:r--

# file: file2
# owner: userc
# group: sysadmin
user::rwx
user:usera:rwx       #effective:rw
group::rw-           #effective:rw
mask:rw
other:r--

Deleting an ACL

You use the setfacl command to delete an ACL. When deleting an ACL, you specify the entry-type and the UID or GID that you want to delete. You cannot delete the ACL entries for the file owner, file group owner, or the ACL mask. The syntax of the command is:

$ setfacl -d acl_entry filename

where: -d - Deletes one or more acl_entry arguments. acl_entry - Specifies which ACL entry to delete in the file or directory. filename - Specifies the file or directory from which to delete the acl_entry argument.

The outputs of the ‘pwd’ and ’ls -l’ commands show the current working directory and its contents.

$ pwd
/export/home/userc
$ ls -l
total 0
-rw-r--r--   1 userc staff 0 Jan 22 13:40 file1
-rw-r--r--+ 1  userc staff 0 Jan 22 13:40 file2

The output of the getfacl command shows the current ACL configuration for file2.

$ getfacl file2
# file: file2
# owner: userc
# group: sysadmin
user::rw
user:usera:rwx       #effective:r--
user:userb:rwx       #effective:r--
group::r--           #effective:r--
mask:r--
other:r--

The following example shows how to delete an ACL entry from the file named file2:

$ setfacl -d u:usera file2

The output from the ’ls -l’ command shows that the deleted ACL entry was not the only ACL entry on the file2 file. To verify this output, perform the getfacl command.

$ ls -l
total 0
-rw-r--r-- 1 userc    staff      0 Jan 22 13:40 file1
-rw-r--r--+ 1 userc   staff     0 Jan 22 13:40 file2

The ACL entry for usera is deleted, but the ACL entry for userb remains.

$ getfacl file2
# file: file2
# owner: userc
# group: sysadmin
user::rwuser:
userb:rwx #effective:r--
group::r-- #effective:r--
mask:r--
other:r--

When you remove the last ACL entry on a file, the output of the ls -l command reports that the file has a trivial ACL (shown by the absence of a + symbol in the output).

$ setfacl -d u:userb file2

$ ls -l
total 0
-rw-r--r-- 1 userc staff 0 Jan 22 13:40 file1
-rw-r--r-- 1 userc staff 0 Jan 22 13:40 file2