Softpanorama
May the source be with you, but remember the KISS principle ;-)

Contents Bulletin Scripting in shell and Perl Network troubleshooting History Humor

Solaris ACLs

News See also Recommended Links Mini-tutorial Recommended Papers Internals Modification of ls to display ACLS
The ACL mask getfacl, setfacl Using dtfile for viewing ACLs Perl interface ACL Permissions for Directories NFS ZFS
Horror Stories Solaris by Stanislav Lem  Tips History Random Findings Humor Etc

There are two types of ACLs in Solaris:

ACL exist in a separate universe from Unix regular permissions and are not displayed by default by commands such as ls (but ls does indicates whether they are present or not). In essence this is an extension of a Unix group mechanism (multiple groups, each with a separate permissions set can be assigned to a file). In this framework the assigning access of a file to a particular user can be viewed as assignment of permissions to a group with just one member (trivial group). For more detailed discussion see Slightly Skeptical view on Unix Access Control Lists (ACLs)

As inability to assign files to multiple groups was a serious drawback of Unix from day  one, an ACL can enhance file security by enabling you to define file permissions for additional groups. For directories it also enables you to define default permissions.

ACL behaves differently for files and directories (only directories have additional set of so called "default permissions").

ACL behaves differently for files and directories (only directories have additional set of so called "default permissions"). For directories it is possible to define default ACL permissions.

The Solaris 9 ACL facility is compliant with the abandoned POSIX 1003.6 specification. Interoperation with other platforms is limited: Linux has weak implementation with many non-compliant utilities (for example GNU tar is "ACL-blind"), HP-UX and AIX both have slightly different implementations (AIX 5.3 supports NFSv4 ACLs)

Solaris 9 implementation works with the Solaris UFS as well as with Solaris NFS version 2 and 3. In case of NFS the ACLs will only work under Solaris NFS server. So for networked filesystems, both the NFS server and the client must be running Solaris.

ACLs generally breaks GNU utilities so for files with ACL the results produced by GNU coreutils ported to Solaris 9 (GNU ls, etc) cannot be trusted in Solaris.

While ACL are file based they are essentially user-oriented: For each file you can define a list of additional users (pseudo-owners) and groups (pseudo-groups) that will have a certain level of access: read, write, or execute access permissions

ACLs grant "higher-level" access rights that have priority over regular file permissions.

Solaris 9 implementation is based on the concept of shadow inodes: when you create an ACL, the existing inode points to a newly allocated inode called a shadow inode. When a specific ACL entry is placed on the ACL list, the shadow inode contains a pointer to a data block containing the list of ACL entries. That permits utilities that does not understand ACLs work correctly with files that have ACLs set. In this case, for example when you are using gnu tar instead of Solaris tar, they will strip all your ACL information.

You can use the ls -l command to see which files or directories have an ACL entry. If a file has an ACL entry, a plus (+) sign appears at the end of the permission field.

There are two separate commands for working with ACLsy:

Running getfacl on a normal file provides mapping of regular permissions to ACL world:

% cd /usr/tmp
% touch foo
% ls -l foo
-rw-r--r--   1 pbg      staff          0 Jul 22 13:35 foo

% getfacl foo
# file: foo
# owner: pbg
# group: staff
user::rw-
group::r--              #effective:r--
mask:rwx
other:r--

The user, group and other information is a straightforward display of the permission bits for those fields.

It is also important to note that ACLs "stick" to a file during copy and rename operations that are performed using regular Solaris commands like cp and mv. To remove the ACL from a file use setfacl -d for each entry. When the last entry is removed, the "+" disappears from the file's ls display.

Setting ACLs for the user

To set an ACL for a file foo, use the command setfacl:

% setfacl -m user:jeff:rw- foo

% ls -l foo
-rw-r--r--+  1 pbg      staff          0 Jul 22 13:52 foo

% getfacl foo

# file: foo
# owner: pbg
# group: staff
user::rw-
user:jeff:rw-           #effective:r--
group::r--              #effective:r--
mask:r--
other:r--

The -m option tells setfacl that I want to modify the ACLs for the file. You can specify only those attributes that you need to change. It looks like man page statement "When using the -m option to modify a default ACL, you must specify a complete default ACL (user, group, other, mask, and any additional entries) the first time" is incorrect:

 -m acl_entries

Adds one or more new ACL entries to the file, and/or modifies one or more existing ACL entries on the file. If an entry already exists for a specified uid or gid, the specified permissions will replace the current permissions. If an entry does not exist for the specified uid or gid, an entry will be created. When using the -m option to modify a default ACL, you must specify a complete default ACL (user, group, other, mask, and any additional entries) the first time.

Use the -s option to set the entire mode, but then you must type in the user, group, and other access bits as well:

 % setfacl -s user::rw-,group::r--,other:---,mask:rw-,user:jeff:rw- foo 

To set general user, group, and other permissions, use the field::perms identifier. To set ACLs for individual users and groups, use the field:uid or gid:perms identifier.

But back to our previous example. Notice that the effective access for user Jeff is unchanged, he can still only read the file, not write to it. That's the result of the mask being applied to his permissions. To grant Jeff the access desired, I need to:

% setfacl -m mask:rw- foo
% getfacl foo 

# file: foo
# owner: pbg
# group: staff
user::rw-
user:jeff:rw-           #effective:rw-
group::r--              #effective:r--
mask:rw-
other:r-- 

Now Jeff has read and write permissions to the file, while all others have only read access. Of note is the slight change in behavior of the ls command. Any file with specific ACL information is shown with a + at the end of the permission field. Unfortunately, find doesn't seem to have an option to find all files with ACL lists.

By now, your warning bells are probably going off. A hacker, having broken into your system, could use the ACL facility to create backdoors. These back doors are very difficult to spot -- only inspection of ls output will identify the target files.

Fortunately, the programming interface to Solaris ACLs allows the creation of utilities to search for files with access control lists. See Module Documentation - SolarisACL 0.06 -- Perl module for Access of Solaris ACLs

Default ACL for the directory

Using the ACL facility on a directory adds some new twists. As well as setting an ACL for the directory, you can set a default ACL for the directory. This default ACL is used to set the ACL on every file created within the directory. The only way I managed to get directory ACLs to work was using the -s option with a very-long parameter string:

 % setfacl -s user::rwx,group::rw-,mask:r--,other:rw-,default:user::rw-,\
default:group::r-x,default:mask:rwx,default:other:r-x bar

% ls -ld bar
drwxr--rw-+  2 pbg      staff        512 Jul 22 14:11 bar

% getfacl bar

# file: bar
# owner: pbg
# group: staff
user::rwx
group::rw-              #effective:r--
mask:r--
other:rw-
default:user::rw-
default:group::r-x
default:mask:rwx
default:other:r-x 

Note:

I found that the FIRST time default ACLs are set, all of user, group, other and mask defaults must be set. This means that the first setfacl for a directory could be for instance:

$ setfacl -m d:u::rwx,d:o:---,d:g::---,d:m:rwx facltest/
Once these four default ACLs have been set, subsequent "normal" calls to setfacl can be made, such as:
$ setfacl -m default:user:myself:rwx facltest/

Now set a default ACL, and create a file in the directory:

 % setfacl -m default:user:jeff:rwx bar

% getfacl bar

# file: bar
# owner: pbg
# group: staff
user::rwx
group::rw-              #effective:r--
mask:r--
other:rw-
default:user::rw-
default:user:jeff:rwx
default:group::r-x
default:mask:rwx
default:other:r-x
default:user::rw-
default:user:jeff:rwx
default:group::r-x
default:mask:rwx
default:other:r-x

% touch bar/test

% getfacl bar/test

# file: bar/test
# owner: pbg
# group: staff
user::rw-
user:jeff:rwx           #effective:r--
group::r--              #effective:r--
mask:r-- 
other:r-- 

There are several other aspects of ACLs, including deleting ACLs and using abbreviations and permission bit numbers (rather than symbols). This information is provided on the appropriate manual pages. You'll get a similar error if you try to use ACLs in a swapfs-based directory (such as /tmp). Finally, there's a "non-feature" of ACLs when used with Solaris tar. Solaris tar itself works well with files that have associated ACLs. Unfortunately, the tar file is not always readable under other OSes. You might be better off using GNU tar instead.

ACL Permissions for Directories

You can set default ACL entries on a directory that apply to files subsequently created within the directories. Files created in a directory that has default ACL entries will have the same ACL entries as the directory. When you set default ACL entries for specific users and groups on a directory for the first time, you must also set default ACL entries for the owner, owner's group, others, and the mask.


Top updates

Shop Amazon Cyber Monday Deals Week
Google Search


NEWS CONTENTS

Old News ;-)

ACL!... Bless You by Ben Rockwood

Aug 22, 2006

Access Control Lists, or ACL's, can also often abbreviated as PITA (if you don't know what that means, ask your local SA). I've largely ignored ACL's because they aren't used very often, around me anyway, and I just feel that they are often a big pain. Thankfully someone realizes my pain and things are getting much better thanks to NFSv4 ACL's and ZFS. So lets take a couple minutes to talk about ACL's, why they are a necessary evil, and review how they are used.

So, ACL's are what we use to set permissions on a file. ACL's exist because the age old UNIX permission scheme (rwxr-xr-x, or 755) is far to limited to solve every concern all of the time. Thus we were curs...blessed with POSIX-draft ACL's. This is where those horrible old commands getfacl and setfacl come in. These commands, as the names imply, get or set file ACL's. Let take a look at a plain ol' file on UFS:

benr@aeon ~$ touch somefile
benr@aeon ~$ ls -l somefile 
-rw-r--r--   1 benr     other          0 Aug 22 00:10 somefile
benr@aeon ~$ umask
0022

So, UNIX 101 for review. We created an empty file. The traditional UNIX permision scheme uses 4 numbers to represent permissions, 3 for user, group, and other, and the fourth to act as a special flag for certain conditions (such as the "sticky bit", setuid, setgid). Our umask defines what our default permissions should be on new files, the mask is compared against 666 for files and 777 for directories. The scheme goes 4 for read, 2 for write, and 1 for execute. When 4 octets are specified, the first octet has the scheme 4 for setuid, 2 for setgid, and 1 for the sticky bit. Therefore, 4755 would designate a permission where the file has setuid (4) set, full permissions (4, read, plus 2, write, plus 1, execute, is 7) to the owner, read and execute to the group (4, read, plus 1, execute, is 5), and then read and execute to other. And so back to our umask, with a umask of 0022, new files are created in 666 mode and therefore result in a default permission of 644, or r+w to the owner, r to group and r to everyone, as seen above. Okey, there's the 20 second recap of stuff you should already know.

So in most cases this scheme works out well enough, a file needs an owner, and when multiple users need access you just create a group. Most people realize there is a problem when they want to add a second group to the file, or if they wish to add a second owner to avoid creating a group when they only need it in this one case. The most common answer is to simply give write access to everyone and turn a blind eye... a method which, somewhat sadly, works all too often. I'm sure every admin at one point pulled out the ol' 777 in an emergancy case, but hopefully thats an extremely limited occurance. You did put those perms back later, right? (If you feel guilty, feel free to go fix those bad perms now.)

ACL's allow us to go beyond this simple permission scheme, and they come in two varieties: POSIX ACL's and NFSv4 ACL's.

POSIX-draft ACL's are what we've had for some time. In this scheme we consider the standard UNIX permissions as a minimal ACL. We can use the getfacl command to view and setfacl to set the ACL. In addition to the miminal permissions of user, group, and other, we can also insert other "masked" permissions which are there but hidden away from what you see via the ls command. Files that have these masked permissions in place are denoted by a "+" in the ls -l output. The most interesting thing here is that we can set additional "named users" with permissions, effectively allowing a single file to have multiple owners without a group, the same thing can be done with a group. Lets take a look at what this looks like:

$ touch myfile
$ ls -l myfile 
-rw-r--r--   1 benr     other          0 Aug 22 01:14 myfile
$ getfacl myfile 

# file: myfile
# owner: benr
# group: other
user::rw-
group::r--              #effective:r--
mask:rwx
other:r--
$ setfacl -m user:tamr:rwx myfile 
root@aeon /$ getfacl myfile 

# file: myfile
# owner: benr
# group: other
user::rw-
user:tamr:rwx           #effective:r--
group::r--              #effective:r--
mask:r--
other:r--
$ ls -l myfile 
-rw-r--r--+  1 benr     other          0 Aug 22 01:14 myfile

Notice that "+" that appeared after I set the ACL. The "benr" user is said to be the "default owner" just as "other" is the "default group", and thus the ones displayed in the ls output.

While POSIX ACL's can make life easier, they sure are a pain to manage. When we're talking about a single file its not a big deal but when we need to work with large numbers of files, like we do in the real world, things get more tricky and getfacl and setfacl aren't really great tools.

When NFSv4 was being developed it was clear that POSIX-draft ACL's weren't going to cut it anymore, both because they are limited and also because they don't jive well with CIFS which makes for some major problems when accessing files with ACL's from both CIFS and NFS clients. "But I don't use NFSv4!" You say... did I mention that ZFS uses NFSv4 style ACL's?

NFSv4 ACL's have some major advantages over POSIX, not the least of which is that we can use ls and chmod to control them, leaving the *facl tools on the scrap heap. With ls simply add the -v switch. The following is a standard files ACL entries on ZFS:

benr@aeon ~$ touch file
benr@aeon ~$ ls -v file 
-rw-r--r--   1 benr     other          0 Aug 22 01:32 file
     0:owner@:execute:deny
     1:owner@:read_data/write_data/append_data/write_xattr/write_attributes
         /write_acl/write_owner:allow
     2:group@:write_data/append_data/execute:deny
     3:group@:read_data:allow
     4:everyone@:write_data/append_data/write_xattr/execute/write_attributes
         /write_acl/write_owner:deny
     5:everyone@:read_data/read_xattr/read_attributes/read_acl/synchronize
         :allow

Much more complete. You'll notice that owner, group, and everyone are represented here and that they have much more granular permissions. Furthermore, each comes in an accept and deny flavor. Its thus very clear what is and isn't allowed and you have much more control.

I want to highlight something you might easily ignore or neglect to notice. Standard UNIX perms use "other" while NFSv4 perms use "everyone". There is a simple but important distinction: everyone means just that, everyone, while other means everyone except the owner and group. With "other" permisions its possible that the file owner himself couldn't edit a file with 007 permisions.

Lets look more closely at those new granular permisions:

Wow, that's a lot of granularity. Solaris allows us to use these permissions to explicitly allow or deny access to one or more owners, one or more groups, or everyone. Interestingly, the NFSv4 ACL standard also provides an AUDIT case, in which matching permissions flagged as AUDIT would be inserted into an audit trail, which would be pretty sweet but its not supported by Solaris at this time, which is funny because the NFSv4 ACL standard was written by Sun.

Setting the ACL is done by means of chmod. chmod has the ability to modify Access Control Entities (ACE), which are indexed in the ls output. By passing A followed by the ACE index number you can modify existing entries. By using A+ you can add a new ACE. So on and so forth. Lets try it:

benr@aeon ~$ touch file
benr@aeon ~$ ls -v file 
-rw-r--r--   1 benr     other          0 Aug 23 03:07 file
     0:owner@:execute:deny
     1:owner@:read_data/write_data/append_data/write_xattr/write_attributes
         /write_acl/write_owner:allow
     2:group@:write_data/append_data/execute:deny
     3:group@:read_data:allow
     4:everyone@:write_data/append_data/write_xattr/execute/write_attributes
         /write_acl/write_owner:deny
     5:everyone@:read_data/read_xattr/read_attributes/read_acl/synchronize
         :allow
benr@aeon ~$ chmod A0=owner@::deny file
benr@aeon ~$ chmod A1=owner@:read_data/write_data/append_data/write_xattr/write_attributes/write_acl/write_owner/execute:allow file
benr@aeon ~$ ls -v file 
-rwxr--r--   1 benr     other          0 Aug 23 03:07 file
     0:owner@::deny
     1:owner@:read_data/write_data/append_data/write_xattr/execute
         /write_attributes/write_acl/write_owner:allow
     2:group@:write_data/append_data/execute:deny
     3:group@:read_data:allow
     4:everyone@:write_data/append_data/write_xattr/execute/write_attributes
         /write_acl/write_owner:deny
     5:everyone@:read_data/read_xattr/read_attributes/read_acl/synchronize
         :allow

I'm only scratching the surface here. My intent isn't to highlight every in and out of ACL's, new and old, but hopefully to remind you that they are here, extremely powerful and perhaps even, on occasion, useful! Someday when your in a jam you might just find that ACL's are the answer your looking for.

For more information, check out the following resources:


- - C O M M E N T S - -

Things get even messier with old-style ACLs when you want to set default ACL settings on all files that show up in a directory, including new ones. You first have to set up default settings, then modify those to add extra users for instane, so you have to do multiple operations to get that done. If there is an existing directory structure under that in which you want the same default ACLs, you’ll probably have to do that double operation on all the directories. Manually. Ick.

The only sane way to do that is to script, otherwise you’ll be typing for miles. So far, for the occasions where I needed to use ACL’s, I’ve made a root-owned script in which I set up every *facl command I need on the system, and put that in a standardized place on all systems. This is good also if you want to make sure you can re-set ACL’s fast at a later date (say, when an upgrade wipes your ACL settings or something equally funny…)

ACL’s do give nice granularity when it comes to setting permissions, and they can be invaluable, albeit annoying.

ZFS ACLs by Mark Shellenbaum

Nov 16, 2005 | Mark Shellenbaum's Weblog

The ZFS file system uses a pure ACL model, that is compliant with the NFSv4 ACL model. What is meant by pure ACL model, is that every file always has an ACL, unlike file systems such as UFS that have either an ACL or it has permission bits. All access control decisions are governed by a file's ACL. All file's still have permission bits, but they are constructed by analyzing a file's ACL.

NFSv4 ACL Overview
The ACL model in NFSv4 is similar to the Windows ACL model. The NFSv4 ACL model supports a rich set of access permissions and inheritance controls. An ACL in this model is composed of an array of access control entries (ACE). Each ACE specifies the permissions, access type, inheritance flags and to whom the entry applies. In the NFSv4 model the "who" argument of each ACE, may be either a username or groupname. There are also a set of commonly know names, such as "owner@", "group@", "everyone@". These abstractions are used by UNIX variant operating systems to indicate if the ACE is for the file owner, file group owner or for the world. The everyone@ entry is not equivalent to the POSIX "other" class, it really is everyone. The complete description of the NFSv4 ACL model is availabe in Section 5.11 of the NFSv4 protocol specification.
NFSv4 Access Permissions
Permission
Description
read_data
Permission to read the data of the file
list_data
Permission to list the contents of a directory

write_data
Permission to modify the file's data anywhere in the file's offset range. This includes the ability to grow the file or write to an arbitrary offset.
add_file
Permission to add a new file to a directory
append_data
The ability to modify the data, but only starting at EOF.
add_subdirectory
Permission to create a subdirectory to a directory
read_xattr
The ability to read the extended attributes of a file or to do a lookup in the extended attributes directory.
write_xattr
The ability to create extended attributes or write to the extended attributes directory.
execute
Permission to execute a file
delete_child
Permission to delete a file within a directory
read_attributes
The ability to read basic attributes (non-ACLs) of a file. Basic attributes are considered the stat(2) level attributes.
write_attributes
Permission to change the times associated with a file or directory to an arbitrary value
delete
Permission to delete a file
read_acl
Permission to read the ACL
write_acl
Permission to write a file's ACL
write_owner
Permission to change the owner or the ability to execute chown(1) or chgrp(1)
synchronize
Permission to access a file locally at the server with synchronous reads and writes.

NFSv4 Inheritance flags
Inheritance Flag
Description
file_inherit
Can be place on a directory and indicates that this ACE should be added to each new non-directory file created.
dir_inherit
Can be placed on a directory and indicates that this ACE should be added to each new directory created.
inherit_only
Placed on a directory, but does not apply to the directory itself, only to newly created files and directories. This flag requires file_inherit and or dir_inherit to indicate what to inherit.
no_propagate
Placed on directories and indicates that ACL entries should only be inherited to one level of the tree. This flag requires file_inherit and or dir_inherit to indicate what to inherit.

NFSv4 ACLs vs POSIX
The difficult part of using the NFSv4 ACL model was trying to still preserve POSIX compliance in the file system. POSIX allows for what it calls "additonal" and "alternate" access methods. An additional access method is defined to be layered upon the file permission bits, but they can only further restrict the standard access control mechanism. The alternate file access control mechanism is defined to be independent of the file permission bits and which if enabled on a file may either restrict or extend the permissions of a given user. Another major distinction between the additional and alternate access control mechanisms is that, any alternate file access control mechanism must be disabled after the file permission bits are changed with a chmod(2). Additional mechanisms do not need to be disabled when a chmod is done.

Most vendors that have implemented NFSv4 ACLs have taken the approach of "discarding" ACLs during a chmod(2). This is a bit heavy handed, since a user went through the trouble of crafting a bunch of ACLs, only to have chmod(2) come through and destroy all of their hard work. It was this single issue that was the biggest hurdle to POSIX compliance with ZFS in implementing NFSv4 ACLs. In order to achieve this Sam, Lisa and I spent far too long trying to come up with a model that would preserve as much of the original ACL, while still being useful. What we came up with is a model that retains additional access methods, and disabled, but doesn't delete alternate access controls. Sam and Lisa have filed an internet draft which has the details about the chmod(2) algorithm and how to make NFSv4 ACLs POSIX complient.

So whats cool about this
Lets assume we have the following directory /sandbox/test.dir.
Its initial ACL looks like:

% ls -dv test.dir
drwxr-xr-x 2 ongk bin 2 Nov 15 14:11 test.dir
0:owner@::deny
1:owner@:list_directory/read_data/add_file/write_data/add_subdirectory
/append_data/write_xattr/execute/write_attributes/write_acl
/write_owner:allow
2:group@:add_file/write_data/add_subdirectory/append_data:deny
3:group@:list_directory/read_data/execute:allow
4:everyone@:add_file/write_data/add_subdirectory/append_data/write_xattr
/write_attributes/write_acl/write_owner:deny
5:everyone@:list_directory/read_data/read_xattr/execute/read_attributes
/read_acl/synchronize:allow


Now if I want to give "marks" the ability to create files, but not subdirectories in this
directory then the following ACL would achieve this.

First lets make sure "marks" can't currently create files/directories

$ mkdir /sandbox/bucket/test.dir/dir.1
mkdir: Failed to make directory "/sandbox/test.dir/dir.1"; Permission denied

$ touch /sandbox/test.dir/file.1
touch: /sandbox/test.dir/file.1 cannot create

Now lets give marks add_file permission

% chmod A+user:marks:add_file:allow /sandbox/test.di
% ls -dv test.dir
drwxr-xr-x+ 2 ongk bin 2 Nov 15 14:11 test.dir
0:user:marks:add_file/write_data:allow
1:owner@::deny
2:owner@:list_directory/read_data/add_file/write_data/add_subdirectory
/append_data/write_xattr/execute/write_attributes/write_acl
/write_owner:allow
3:group@:add_file/write_data/add_subdirectory/append_data:deny
4:group@:list_directory/read_data/execute:allow
5:everyone@:add_file/write_data/add_subdirectory/append_data/write_xattr
/write_attributes/write_acl/write_owner:deny
6:everyone@:list_directory/read_data/read_xattr/execute/read_attributes
/read_acl/synchronize:allow

Now lets see if it works for user "marks"

$ id
uid=76928(marks) gid=10(staff)

$ touch file.1
$ ls -v file.1
-rw-r--r-- 1 marks staff 0 Nov 15 10:12 file.1
0:owner@:execute:deny
1:owner@:read_data/write_data/append_data/write_xattr/write_attributes
/write_acl/write_owner:allow
2:group@:write_data/append_data/execute:deny
3:group@:read_data:allow
4:everyone@:write_data/append_data/write_xattr/execute/write_attributes
/write_acl/write_owner:deny
5:everyone@:read_data/read_xattr/read_attributes/read_acl/synchronize
:allow

Now lets make sure "marks" can't create directories.

$ mkdir dir.1
mkdir: Failed to make directory "dir.1"; Permission denied

The write_owner permission is handled in a special way. It allows for a user to "take" ownership of a file. The following example will help illustrate this. With the write_owner a user can only do a chown(2) to himself or to a group that he is a member of.

We will start out with the following file.

% ls -v file.test
-rw-r--r-- 1 ongk staff 0 Nov 15 14:22 file.test
0:owner@:execute:deny
1:owner@:read_data/write_data/append_data/write_xattr/write_attributes
/write_acl/write_owner:allow
2:group@:write_data/append_data/execute:deny
3:group@:read_data:allow
4:everyone@:write_data/append_data/write_xattr/execute/write_attributes
/write_acl/write_owner:deny
5:everyone@:read_data/read_xattr/read_attributes/read_acl/synchronize
:allow

Now if user "marks" tries to chown(2) the file to himself he will get an error.

$ chown marks file.test
chown: file.test: Not owner

$ chgrp staff file.test
chgrp: file.test: Not owner

Now lets give "marks" explicit write_owner permission.

% chmod A+user:marks:write_owner:allow file.test
% ls -v file.test
-rw-r--r--+ 1 ongk staff 0 Nov 15 14:22 file.test
0:user:marks:write_owner:allow
1:owner@:execute:deny
2:owner@:read_data/write_data/append_data/write_xattr/write_attributes
/write_acl/write_owner:allow
3:group@:write_data/append_data/execute:deny
4:group@:read_data:allow
5:everyone@:write_data/append_data/write_xattr/execute/write_attributes
/write_acl/write_owner:deny
6:everyone@:read_data/read_xattr/read_attributes/read_acl/synchronize
:allow

Now lets see who "marks" can chown the file to.

$ id
uid=76928(marks) gid=10(staff)
$ groups
staff storage
$ chown bin file.test
chown: file.test: Not owner

So "marks" can't give the file away.

$ chown marks:staff file.test

Now lets look at an example to show how a user can be granted special delete permissions. ZFS doesn't create any delete permissions when a file is created, instead it uses write_data/execute for permission to write to a directory and execute to search the directory.

Lets first create a read-only directory and then give "marks" the ability to delete files.

% ls -dv test.dir
dr-xr-xr-x 2 ongk bin 2 Nov 15 14:11 test.dir
0:owner@:add_file/write_data/add_subdirectory/append_data:deny
1:owner@:list_directory/read_data/write_xattr/execute/write_attributes
/write_acl/write_owner:allow
2:group@:add_file/write_data/add_subdirectory/append_data:deny
3:group@:list_directory/read_data/execute:allow
4:everyone@:add_file/write_data/add_subdirectory/append_data/write_xattr
/write_attributes/write_acl/write_owner:deny
5:everyone@:list_directory/read_data/read_xattr/execute/read_attributes
/read_acl/synchronize:allow


Now the directory has the following files:

% ls -l
total 3
-r--r--r-- 1 ongk bin 0 Nov 15 14:28 file.1
-r--r--r-- 1 ongk bin 0 Nov 15 14:28 file.2
-r--r--r-- 1 ongk bin 0 Nov 15 14:28 file.3

Now lets see if "marks" can delete any of the files?

$ rm file.1
rm: file.1: override protection 444 (yes/no)? y
rm: file.1 not removed: Permission denied

Now lets give "marks" delete permission on just file.1

% chmod A+user:marks:delete:allow file.1
% ls -v file.1
-r--r--r--+ 1 ongk bin 0 Nov 15 14:28 file.1
0:user:marks:delete:allow
1:owner@:write_data/append_data/execute:deny
2:owner@:read_data/write_xattr/write_attributes/write_acl/write_owner
:allow
3:group@:write_data/append_data/execute:deny
4:group@:read_data:allow
5:everyone@:write_data/append_data/write_xattr/execute/write_attributes
/write_acl/write_owner:deny
6:everyone@:read_data/read_xattr/read_attributes/read_acl/synchronize
:allow


$ rm file.1
rm: file.1: override protection 444 (yes/no)? y

Lets see what a chmod(1) that changes the mode would do to a file with a ZFS ACL.
We will start out with the following ACL which gives user bin read_data and write_data permission.

$ ls -v file.1
-rw-r--r--+ 1 marks staff 0 Nov 15 10:12 file.1
0:user:bin:read_data/write_data:allow
1:owner@:execute:deny
2:owner@:read_data/write_data/append_data/write_xattr/write_attributes
/write_acl/write_owner:allow
3:group@:write_data/append_data/execute:deny
4:group@:read_data:allow
5:everyone@:write_data/append_data/write_xattr/execute/write_attributes
/write_acl/write_owner:deny
6:everyone@:read_data/read_xattr/read_attributes/read_acl/synchronize
:allow


$ chmod 640 file.1
$ ls -v file.1
-rw-r-----+ 1 marks staff 0 Nov 15 10:12 file.1
0:user:bin:write_data:deny
1:user:bin:read_data/write_data:allow
2:owner@:execute:deny
3:owner@:read_data/write_data/append_data/write_xattr/write_attributes
/write_acl/write_owner:allow
4:group@:write_data/append_data/execute:deny
5:group@:read_data:allow
6:everyone@:read_data/write_data/append_data/write_xattr/execute
/write_attributes/write_acl/write_owner:deny
7:everyone@:read_xattr/read_attributes/read_acl/synchronize:allow


In this example ZFS has prepended a deny ACE to take away write_data permission. This
is an example of disabling "alternate" access methods. More details about
how ACEs are disabled are described in internet draft.

The ZFS admin guide and the chmod(1) manpages have many more examples of setting ACLs and how the inheritance model works.

With the ZFS ACL model access control is no longer limited to the simple "rwx" model that UNIX has used since its inception.

Lisa Week's Weblog

Over the last several months, I've been doing a lot of work with NFSv4 ACLs. First, I worked with Sam to get NFSv4 ACL support into Solaris 10. The major portion of this work involved implementing the pieces to be able to pass ACLs over-the-wire as defined by section 5.11 of the NFSv4 specification (RFC3530) and the translators (code to translate from UFS (or also referred to as POSIX-draft) ACLs to NFSv4 ACLs and back). At that point, Solaris was further along with regard to ACLs than it ever had been, but was still not able to support the full semantics of NFSv4 ACLs. So...here comes ZFS!

After getting the support for NFSv4 ACLs into Solaris 10, I started working on the ZFS ACL model with Mark and Sam. So, you might wonder why a couple of NFS people (Sam and I) would be working with ZFS (Mark) on the ZFS ACL model...well that is a good question. The reason for that is because ZFS has implemented native NFSv4 ACLs. This is really exciting because it is the first time that Solaris is able to support the full semantics of NFSv4 ACLs as defined by RFC3530.

In order to implement native NFSv4 ACLs in ZFS, there were a lot of problems we had to overcome. Some of the biggest struggles were ambiguities in the NFSv4 specification and the requirement for ZFS to be POSIX compliant. These problems have been captured in an Internet Draft submitted by Sam and me on October 14, 2005.

ACLs in the Computer Industry:

What makes NFSv4 ACLs so special...so special to have the shiny, new ZFS implement them? No previous attempt to specify a standard for ACLs has succeeded, therefore, we've seen a lot of different (non-standard) ACL models in the industry. With NFS Version 4, we now have an IETF approved standard for ACLs.

As well as being a standard, the NFSv4 ACL model is very powerful. It has a rich set of inheritance properties as well as a rich set of permission bits outside of just read, write and execute (as explained in the Access mask bits section below). And for the Solaris NFSv4 implementation this means better interoperability with other vendor's NFSv4 implementations.

ACLs in Solaris:

Like I said before, ZFS has native NFSv4 ACLs! This means that ZFS can fully support the semantics as defined by the NFSv4 specification (with the exception of a couple things, but that will be mentioned later).

What makes up an ACL?

ACLs are made up of zero or more Access Control Entries (ACEs). Each ACE has multiple components and they are as follows:

1.) Type component:
The type component of the ACE defines the type of ACE. There
are four types of ACEs: ALLOW, DENY, AUDIT, ALARM.


The ALLOW type ACEs permit access.
The DENY type ACES restrict access.
The AUDIT type ACEs audit accesses.
The ALARM type ACEs alarm accesses.

The ALLOW and DENY type of ACEs are implemented in ZFS.
AUDIT and ALARM type of ACEs are not yet implemented in ZFS.

The possibilities of the AUDIT and ALARM type ACEs are described below. I
wanted to explain the flags that need to be used in conjunction with them before
going into any detail on what they do, therefore, I gave this description its own
section.

2.) Access mask bits component:
The access mask bit component of the ACE defines the accesses
that are controlled by the ACE.

There are two categories of access mask bits:
1.) The bits that control the access to the file
i.e. write_data, read_data, write_attributes, read_attributes
2.) The bits that control the management of the file
i.e. write_acl, write_owner

For an explanation of what each of the access mask bits actually control in ZFS,
check out Mark's blog.

3.) Flags component:
There are three categories of flags:
1.) The bits that define inheritance properties of an ACE.
i.e. file_inherit, directory_inherit, inherit_only,
no_propagate_inherit
Again, for an explanation of these flags, check out Mark's blog.
2.) The bits that define whether or not the ACE applies to a user or group
i.e. identifier_group
3.) The bits that work in conjunction with the AUDIT and ALARM type ACEs
i.e. successful_access_flag, failed_access_flag.
ZFS doesn't support these flags since they don't support AUDIT and
ALARM type ACEs.

4.) who component:
The who component defines the entity that the ACE applies to.

For NFSv4, this component is a string identifier and it can be a user, group or
special identifier (OWNER@, GROUP@, EVERYONE@). An important thing to
note about the EVERYONE@ special identifier is that it literally means everyone
including the file's owner and owning group. EVERYONE@ is not equivalent to
the UNIX other entity. (If you are curious as to why NFSv4 uses strings rather
than integers (uids/gids), check out Eric's blog.)

For ZFS, this component is an integer (uid/gid).

What do AUDIT and ALARM ACE types do?

The AUDIT and ALARM type of ACES trigger an audit or alarm event upon the successful or failed accesses depending on the presence of the successful/failed access flags (described above) as defined in the access mask bits of the ACE. The ACEs of type AUDIT and ALARM don't play a role when doing access checks on a file. They only define an action to happen in the event that a certain access is attempted.

For example, lets say we have the following ACL:

lisagab:write_data::deny
lisagab:write_data:failed_access_flag:alarm
The first ACE affects the access that user, "lisagab", has to the file. The second ACE says if user, "lisagab", attempts to access this file for writing and fails, trigger an alarm event.

One important thing to remember is the fact that what we do in the event of auditing or alarming is still undefined. Although, you can think of it like this: when the access in question happens, auditing could be the logging the event to a file and alarming could be the sending of an email to an administrator.

How is access checking done?

To quote the NFSv4 specification:
 To determine if a request succeeds, each nfsace4 entry is processed
 in order by the server. Only ACEs which have a "who" that matches
 the requester are considered. Each ACE is processed until all of the
 bits of the requester's access have been ALLOWED. Once a bit (see
 below) has been ALLOWED by an ACCESS_ALLOWED_ACE, it is no longer
 considered in the processing of later ACEs. If an ACCESS_DENIED_ACE
 is encountered where the requester's access still has unALLOWED bits
 in common with the "access_mask" of the ACE, the request is denied.
What this means is:

The most important thing to note about access checking with NFSv4 ACLs is that it is very order dependent. If a request for access is made, each ACE in the ACL is traversed in order. The first ACE that matches the who of the requester and defines the access that is being requested is honored.

For example, lets say user, "lisagab", is requesting the ability to read the data of file, "foo" and "foo" has the following ACL:

everyone@:read_data::allow
lisagab:write_data::deny

lisagab would be allowed the ability to read_data because lisagab is covered by "everyone@".

Another thing that is important to know is that the access determined is cumulative.

For example, lets say user, "lisagab", is requesting the ability to read and write the data of file, "bar" and "bar" has the following ACL:

lisagab:read_data::allow
lisagab:write_data::allow

lisagab would be allowed the ability to read_data and write_data.

How to use ZFS/NFSv4 ACLs on Solaris:

Many of you may remember the setfacl(1) and getfacl(1) commands. Well, those are still around, but won't help you much with manipulating ZFS or pure NFSv4 ACLs. Those commands are only capable of manipulating the POSIX-draft ACLs as implemented by UFS.

As a part of the ZFS putback, Mark has modified the chmod(1) and ls(1) command line utilities in order to manipulate ACLs on Solaris.

chmod(1) and ls(1) now give us the ability to manipulate ZFS/NFSv4 ACLs. Interestingly enough, these utilities can also manipulate POSIX-draft ACLs so, now there is a one stop shop for all your ACL needs.

[Aug 2, 2006] Softpanorama feedback

Thank you for valuable information about ACLs on your webpage! Thanks to you I found exactly what I was looking for, which was default ACLs on new files in a directory. I did however also find a small "error" on the page http://www.softpanorama.org/Solaris/ACL/index.shtml. In the paragraph starting with "Using the ACL facility on a directory adds some new twists", it says that setting the entire ACL is the only way you have been able to make it work. By reading the setfacl man page carefully, I found that the FIRST time default ACLs are set, all of user, group, other and mask defaults must be set. This means that the first setfacl for a directory could be for instance:

$ setfacl -m d:u::rwx,d:o:---,d:g::---,d:m:rwx facltest/
Once these four default ACLs have been set, subsequent "normal" calls to setfacl can be made, such as:
$ setfacl -m default:user:myself:rwx facltest/
Best regards, Boye

Module Documentation - SolarisACL 0.06

Perl module for Access of Solaris ACLs

something or another… » lsacl - Solaris ACL’s for mere mortals.

The classical user/group/everyone file permissions that the UNIX world has been used to the last 30 years, is pretty much an assumed. Nowadays, however, many UNIX implementations allow for granular file access control lists. Most UNIX administrator's still avoid them because they are not as apparent to them when doing a file listing.

I decided to be different. I wrote a tool to enhance the standard "ls" command into displaying file ACL's.

The absence of an easy way to see file permissions is one of the reasons why Windows Administrators tend to use ACL's more than UNIX ones. Windows Administrator's also tend to view and audit their file permissions much much less than UNIX administrator's. It's hidden away in several menu's, whereas they are always in your face when displaying files in UNIX.

Other than messing around on AIX in 1994, I had managed to avoid file ACL's under UNIX up until last year when we consolidated half a dozen HP servers to a Sun Cluster at work. Suddenly, permissions got complex. I don't really mean that complex, but on the HP's we used to have world writeable directories! HERR GUD!

So, when we sat down to implement file permissions on the Sun side, and got much whining from the DBA's and System Administrator's on the fact that we needed to use ACL's, I decided to make life easier for them.

I wrote this tool for Solaris, written in ruby named lsacl. It wraps around the ls command, and when it detects an ACL, runs getfacl and fakes it's own ls lines to go along with it. Because it wraps around ls, you can actually set an alias for ls to always run lsacl.

Here is what normal ls looks like:

% /bin/ls -lad samba 
drwxrwxr-x+  2 oracle   blahuser      96 May  6 14:52 samba

and the getfacl output for that directory:

% getfacl samba
# file: samba
# owner: oracle
# group: blahuser
user::rwx
group::rwx              #effective:rwx
group:blahsmb:rwx               #effective:rwx
mask:rwx
other:r-x
default:user::rw-
default:user:oracle:rw-
default:group::---
default:mask:rw-
default:other:---

Rather than depending on the user to figure all of that out however, lsacl makes it easy. My ls is aliased to it, so for me it's just:

% lsacl -lad samba
drwxrwxr-x+  2 oracle   blahuser      96 May  6 14:52 samba
A---rwxr-x+  2 -        blahsmb      ACL May  6 14:52 samba

Isn't that pleasant? The file ACL's in our cluster are now accessible by normal users. Our DBA's are no longer scared. We can now run permissions comparison's on different instances by just diffing the output of lsacl, rather than ls and praying the ACL's are the same.

We've been using this script for about a year here, I just made some cosmetic changes to it today and thought I'd let the world see it. Feel free to download lsacl, edit it, redistribute it, whatever. It requires ruby to be installed, and probably only works with Solaris, as I don't know how ls outputs ACL's on other UNIX implementations.

POSIX_ACLs_shells

Minimizing Host Exploitation by Reducing Access to "Popular" Executables by Use of POSIX ACL's Limited Publishing: 02/25/2003
Overview

This document provides a solution to reduce the effectiveness of most buffer overrun exploits by preventing the effective user id of the compromised process from accessing a shell or other "popular" process from which to pursue his/her attack. This is an extremely simple technique utilizing POSIX ACL's (Access Control Lists) and does not introduce any additional load on a modern OS.

Credits

Concept: Kristofer Spinka (kspinka@style.net) Proof of Concept: TBD

Concept

This works as is on Linux and Solaris, however RedHat temporarily removed support for getxattr()/setxattr() which actually implements "setfacl -m"; I think they had a stability problem. It works as expected on Solaris, but of course, it's Solaris. If you encounter non-standard limitations on other platforms, please provide feedback.

  1. First make a dummy shell for testing and verification
     vi shell.c:
    -----------
    #include <unistd.h>
    
    int
    main(int argc, char *argv[])
    {
          write(1, "shell started!\n", 15);
          return 1;
    }
    -----------
        gcc -o shell shell.c
    
  2. Create a "web server user" for testing. This is only temporary, we will remove it after testing.
         become root
         groupadd -g 57470 facltest
         useradd -c "setfacl test account" -d /tmp/facltest -g facltest -s /bin/bash -m -u 57470 facltest
         passwd facltest (set a password for the account)
         drop root
         
  3. Execute setfacl -m u:facltest:--- shell

    This will remove all permissions for user "nobody" from the file "shell".

  4. su - facltest attempt to execute "shell" created in step 1
  5. Cleanup test environment. userdel -r facltest groupdel facltest
  6. Apply facl's to all shells or other "popular" executables on your system for the account used to run network servies one by one, for example:
         setfacl -m u:nobody:--- /bin/ash
         setfacl -m u:nobody:--- /bin/bash
         setfacl -m u:nobody:--- /bin/csh
         setfacl -m u:nobody:--- /bin/sh
         setfacl -m u:nobody:--- /usr/bin/es
         setfacl -m u:nobody:--- /usr/bin/ksh
         setfacl -m u:nobody:--- /bin/ksh
         setfacl -m u:nobody:--- /usr/bin/rc
         setfacl -m u:nobody:--- /usr/bin/tcsh
         setfacl -m u:nobody:--- /bin/tcsh
         setfacl -m u:nobody:--- /usr/bin/zsh
         setfacl -m u:nobody:--- /bin/sash
         setfacl -m u:nobody:--- /bin/zsh
         setfacl -m u:nobody:--- /usr/bin/esh
         setfacl -m u:nobody:--- /bin/dash
    

    You should repeat this for *all* user accounts that run your network services, for example, the user account that httpd runs as, the user account named runs as, the user account sendmail runs as, etc.

ACL Interactions With Microsoft

Microsoft Windows has its own version of access control lists. When PC users Citrix MetaFrame users write files from Windows to the BCG storage server via samba, the Microsoft ACL associated with a file is translated to a Unix ACL. Sometimes this is done only by setting the standard Unix permissions.

In other cases, the Solaris ACL system described above is used. An ACL is usually set when a file's "Properties->Security" menu is modified. For example, if you grant another user access to a file through Windows, you'll find a '+' sign on the permissions when you list it from Solaris. You can remove the ACL with rmacl command described above, but then the user to whom you granted access from Windows will no longer be able to access the file.

Recommended Links

Softpanorama Top Visited

Softpanorama Recommended

Using dtfile for viewing ACLs

The dtfile file manager provides an easy, graphical interface to managing Solaris ACLs. Under the Selected-Properties menu there is a button to "Show Access Control List". Here permissions for a particular user or group can be added to or removed from a file. The program makes sure the mask setting is correct to give the intended permissions. This program is part of the CDE desktop environment. It can be launched form the command line via:

docs.sun.com Trusted Solaris User's Guide/Setting Permissions and Access Control Lists

To Display the Properties Dialog Box for a File or Folder

To View the Basic Information of a File or Folder

To View or Change a File or Folder's Basic Permissions

To View a File or Folder's ACL Entries

To Add an ACL Entry

To Change an ACL Entry

To Delete an ACL Entry

Internals

Controlling permissions with ACLs - SunWorld - June 1998

The kernel implementation of ACLs requires a means of storing the ACLs on disk, as well as an incore representation for opened files. The linkage to a file's ACLS begins with the inode. A pointer, i_shadow, is defined in the file's inode and is set as a pointer to a shadow inode when an ACL is created for a file. The shadow inode is not a special type of inode; it is not defined by a specific shadow inode data structure. Rather, it is a generic UFS inode used for a special purpose -- that purpose being to provide a means of storing file ACL information on disk.

The representation of file ACLs in memory involves several data structures that are rooted at the memory resident inode for the file, in a pointer called i_ufs_acl. The i_ufs_acl pointer references a data structure that represents a memory resident shadow inode, the si structure. There are many fields in a generic UFS inode that are not required when the inode is used as a shadow inode, so it does not make sense to cache an entire inode in memory when it is a shadow inode. The si structure defines the shadow inode fields that are of use in the implementation of ACLs.

There is further linkage of additional kernel data structures from the si structure that are used by the kernel for ACLs. Reference Figure 1 for the complete picture.


The incore shadow inode structure contains various fields that the kernel uses for its implementation of ACLs. The s_signature field is used to store a unique signature for the ACL. The signature is generated when ACLs are first created for a file, and a shadow inode must be retrieved or allocated from the cache (see below). The signature is simply a checksum of the various ACL objects (users, groups, etc.) that exist for the file and provide an easy way for the kernel to locate an ACL in the shadow inode cache when it invokes a search. Other fields in the incore shadow inode are similar to other kernel data structures we've looked at in past columns -- we have a reference count (s_ref), a flag field (s_flag), and a lock for protection against unsynchronized, concurrent access (s_lock).

The remaining structures linked to and from the incore shadow inode are the ic_acl (incore acl) and ufs_ic_acl structures, in which the actual ACL objects are stored. As per Figure 1, the incore shadow inode contains two ic_acl structures: one for the ACLs (s_a) and one for the default ACLs (s_d), if any exist. Each ic_acl structure entry is actually a pointer to a ufs_ic_acl, of which there is one for the owner, group, other, and each user and group for which a specific ACL entry has been created.

The kernel does a couple optimizations in its ACL implementation. First, shadow inodes are cached in memory. Second, shadow inodes are shared when appropriate. This means that a group of files that have the same owner and the same ACLs defined for every file will reference the same shadow inode for the storage and retrieval of the ACL objects in each file. This would be the case, for example, if a default ACL were defined by a user for a directory, and files started being added to that directory. Every file with the same owner would have the same ACL unless explicitly changed via setfacl(1)).

This system uses kernel memory more effectively, as we're not replicating the same kind of information (i.e., ACLs) in the kernel. Utilization of file system resources is also minimized this way: As long as the file has the same owner and the ACLs defined are identical the kernel doesn't have to allocate a shadow inode for every file that has an ACL (resulting in the same signature, as above).

A couple of counters are maintained by the kernel for maintaining shadow inode cache hits and misses: si_cachehit and si_cachemiss. I am not aware of any bundled shell command that makes this information available, but it can be examined using adb(1) as follows.

# adb -k /dev/ksyms /dev/mem	** note you must be root, type this to invoke adb 
physmem fdde			** adb returns this when invoked
si_cachehit/D			** type this. 
si_cachehit:			** adb returned this
si_cachehit:    2187		** adb returned this
				** type carriage return here
si_cachemiss:			** adb returned this
si_cachemiss:   13		** adb returned this

$q				** type this to exit adb

# 

You can do some quick arithmetic to calculate your ACL cache hit rate: 2187 + 13 = 2200 cache references. 2187 / 2200 * 100 = 99.41, thus our example shows a 99.41 percent cache hit rate. The shadow inode (ACL) cache is not tunable. There are no kernel variables that can be set in the /etc/system file in increase or decrease the shadow inode cache.

When an ACL is created for a file, the kernel first searches the shadow inode cache to see if a resident shadow inode exists that could be used, based on the shadow inode signature. In the case of a cache hit, the pointer linkage is done, and the reference count for the shadow inode (s_ref) is incremented. If no shadow inode exists, the kernel calls the same ufs_ialloc() (allocate a UFS inode) routine that's used for allocating inodes for newly created files. Once the inode is allocated, the i_shadow pointer in the file's original inode is set to point to it, and the i_mode field in the newly allocated shadow inode is set to IFSHAD, indicating that this inode is a shadow inode.

ACL information and access is linked to the vnode layer, such that the kernel can provide a generic set of file system interfaces to access ACL data, keeping the VFS/Vnode layer consistent with its original design intention (see earlier columns for more information on vnodes). The system defines VOP_GETSECATTR and VOP_SETSECATTR operations (get_secondary_attributes and set_secondary_attributes) for accessing file ACL information through the standard VFS/Vnode interface. A data structure for this purpose is defined in vnode.h, the vsecattr structure, which, when initialized, will point to the ACL entries and default ACL entries for the file that the vnode is allocated to. The kernel actually checks for the existence of VOP_GETSECATTR and VOP_SETSECATTR in the vfs operations structure for a file system to determine if a particular file system supports ACLs.

On disk, the ACLs are stored the same way as file data is, referenced through the direct and indirect block pointers in the inode. Thus, the blocks pointed to by the shadow inode's i_db[] array will hold the actual ACL objects. The kernel defines a maximum of number of ACL entries that can be created per file of 1024 (1k). Given that each ACL entry only occupies 12 bytes, the actual storage of ACLs on disk typically does not require very much space, although a lot of files with a large number of unique ACL entries per file could add up (and that's not even counting inode allocation). If you're looking at a file system and trying to account for used data blocks and inodes, don't forget to consider ACL use.

That's a wrap for this month. Next month we'll cover large files in Solaris.

Modification of ls to display ACL "in-line"

something or another… » lsacl - Solaris ACL’s for mere mortals.

The classical user/group/everyone file permissions that the UNIX world has been used to the last 30 years, is pretty much an assumed. Nowadays, however, many UNIX implementations allow for granular file access control lists. Most UNIX administrator’s still avoid them because they are not as apparent to them when doing a file listing.

I decided to be different. I wrote a tool to enhance the standard “ls” command into displaying file ACL’s.

The absence of an easy way to see file permissions is one of the reasons why Windows Administrators tend to use ACL’s more than UNIX ones. Windows Administrator’s also tend to view and audit their file permissions much much less than UNIX administrator’s. It’s hidden away in several menu’s, whereas they are always in your face when displaying files in UNIX.

Other than messing around on AIX in 1994, I had managed to avoid file ACL’s under UNIX up until last year when we consolidated half a dozen HP servers to a Sun Cluster at work. Suddenly, permissions got complex. I don’t really mean that complex, but on the HP’s we used to have world writeable directories! HERR GUD!

So, when we sat down to implement file permissions on the Sun side, and got much whining from the DBA’s and System Administrator’s on the fact that we needed to use ACL’s, I decided to make life easier for them.

I wrote this tool for Solaris, written in ruby named lsacl. It wraps around the ls command, and when it detects an ACL, runs getfacl and fakes it’s own ls lines to go along with it. Because it wraps around ls, you can actually set an alias for ls to always run lsacl.

Here is what normal ls looks like:

% /bin/ls -lad samba
drwxrwxr-x+  2 oracle   blahuser      96 May  6 14:52 samba

and the getfacl output for that directory:

% getfacl samba
# file: samba
# owner: oracle
# group: blahuser
user::rwx
group::rwx              #effective:rwx
group:blahsmb:rwx               #effective:rwx
mask:rwx
other:r-x
default:user::rw-
default:user:oracle:rw-
default:group::---
default:mask:rw-
default:other:---

Rather than depending on the user to figure all of that out however, lsacl makes it easy. My ls is aliased to it, so for me it’s just:

% lsacl -lad samba
drwxrwxr-x+  2 oracle   blahuser      96 May  6 14:52 samba
A---rwxr-x+  2 -        blahsmb      ACL May  6 14:52 samba

Isn’t that pleasant? The file ACL’s in our cluster are now accessible by normal users. Our DBA’s are no longer scared. We can now run permissions comparison’s on different instances by just diffing the output of lsacl, rather than ls and praying the ACL’s are the same.

We’ve been using this script for about a year here, I just made some cosmetic changes to it today and thought I’d let the world see it. Feel free to download lsacl, edit it, redistribute it, whatever. It requires ruby to be installed, and probably only works with Solaris, as I don’t know how ls outputs ACL’s on other UNIX implementations.

Perl interface

Module Documentation - SolarisACL 0.06 Solaris::ACL - Perl extension for reading and setting Solaris Access Control Lists for files

  use Solaris::ACL;
  ($acl, $default_acl) = getfacl("path/to/file");
  setfacl("path/to/file", $acl [, $default_acl]);

This module provides access to the system level acl(2) call, allowing efficient setting and reading of Access Control Lists (ACLs) in perl.

ACL provides the following functions:

setfacl($path, $acl [, $default_acl])
Set the ACL of the file or directory named by $path to that specified by $acl. If $path names a directory, then the optional $default_acl argument can also be passed to specify the default ACL for the directory. See "ACL structure" for information on how the $acl and $default_acl hashes should be constructed.
getfacl($file_name)
Return a reference to a hash containing information about the file's ACL. If the file is a directory with a default ACL, then a list is returned, with the first entry being a hash reference to the ACL, and the second being a hash reference to the default ACL. See "Accessing ACL structures" for information on how to access these hashes, and "ACL structure" for information on how these hashes are internally constructed.

The structures returned by the getfacl call are blessed into the Solaris::ACL package, and can be inspected and changed using methods from that class. In most cases, the same method can be used for inspecting or setting values; a value is set if data is given to set it with; otherwise, it is inspected and returned. The following accessor methods are defined:

uperm
gperm
operm
mask
Without an argument, each of these methods returns the permission for the corresponding entity (user, group, other, or file mask). With an argument, they set the permission to that argument. For example:
  $user_perm = $acl->uperm;  # find out current owner permissions.
  $acl->operm(5);            # give others read-execute permissions.

If no mask is set in the ACL, mask returns -1.

users
groups
Without arguments, return a list of users (by uid) or groups (by gid) with special ACL access. When passed a uid/gid as an argument, return the permission for the given user/group, or -1 if no permission is set in the ACL. When passed a uid/gid and a permission, give the specified user/group the indicated permission; if the permission is -1, remove any permissions for the specified user/group.
calc_mask
Calculate the mask for the acl, as would the -r flag of setfacl.
equal($acl2)
Check to see if the acl is equal to $acl2. Returns 1 if equal, 0 otherwise.
Solaris::ACL->new($mode)
Create a new blessed acl with permissions for user, group and other determined by mode.

EXAMPLES

  $acl = new Solaris::ACL(0741);
  $acl->users(scalar(getpwnam("iroberts"),2);
  $acl->users(scalar(getpwnam("rdb"),0);
  $acl->calc_mask;
  $def_acl = new Solaris::ACL(0751);
  setfacl("working_dir", $acl, $def_acl);
  ($acl1, $def_acl1) = getfacl("working_dir");
  print "All is well\n" if($acl->equal($acl1));
  $acl2 = getfacl("working_file");
  print "uids with acls set: ", join(", ", $acl2->users), "\n";
  print "uid 29 had permission ", $acl2->users(29), "\n";
  $acl2->users(29,6);
  $acl2->calc_mask;
  setfacl("working_file", $acl2)
  print "uid 29 now has permission 6\n";
  # to copy an acl from one file or directory to another;
  setfacl($target_file, getfacl($source_file));

RETURN VALUES

setfacl returns TRUE if successful and FALSE if unsuccessful. getfacl, if successful, returns a list containing a reference to the hash describing an acl, and, if there is a default acl, a reference to the hash describing the default acl. If unsuccessful, getfacl returns a null list. If either setfacl or getfacl are unsuccessful, the variable $Solaris::ACL::error is set to a descriptive error string; in addition, if the failure was due to a system error, $! is set.

ACL structure

WARNING: The internal structures described here are subject to change in future versions.

All information passed to setfacl returned from getfacl is in the form of references to hashes. A hash describing an ACL can have the following keys:

uperm, gperm, operm, mask
Each of these keys have values containing permissions for the corresponding entity (user, group, other, mask).
groups, users
Each of these keys (if existent) contain a reference to a hash whose keys are decimal representations of numbers, and whose values contain permissions for the user/group whose uid/gid is the number in the key.

BUGS

No checking is done on data types; bad data will result in strange error message being placed in $Solaris::ACL::errors.

AUTHOR

Ian Robertson <ian@lugh.uchicago.edu>

Random Findings

Solaris ACLs

Under Solaris, the ACL type can be one of the following:

        user
        group
        mask
        other

For directories only
default_user
default_group
default_mask
default_other

A user or group can be specified to the user, group, default_user and default_group types. Solaris ACL permissions are the normal UNIX permissions bits `rwx', where:

    
        r - Grants read privileges.
        w - Grants write privileges.
        x - Grants execute privileges.



Etc

FAIR USE NOTICE This site contains copyrighted material the use of which has not always been specifically authorized by the copyright owner. We are making such material available in our efforts to advance understanding of environmental, political, human rights, economic, democracy, scientific, and social justice issues, etc. We believe this constitutes a 'fair use' of any such copyrighted material as provided for in section 107 of the US Copyright Law. In accordance with Title 17 U.S.C. Section 107, the material on this site is distributed without profit exclusivly for research and educational purposes.   If you wish to use copyrighted material from this site for purposes of your own that go beyond 'fair use', you must obtain permission from the copyright owner.

Society

Groupthink : Two Party System as Polyarchy : Corruption of Regulators : Bureaucracies : Understanding Micromanagers and Control Freaks : Toxic Managers :   Harvard Mafia : Diplomatic Communication : Surviving a Bad Performance Review : Insufficient Retirement Funds as Immanent Problem of Neoliberal Regime : PseudoScience : Who Rules America : Neoliberalism  : The Iron Law of Oligarchy : Libertarian Philosophy

Quotes

War and Peace : Skeptical Finance : John Kenneth Galbraith :Talleyrand : Oscar Wilde : Otto Von Bismarck : Keynes : George Carlin : Skeptics : Propaganda  : SE quotes : Language Design and Programming Quotes : Random IT-related quotesSomerset Maugham : Marcus Aurelius : Kurt Vonnegut : Eric Hoffer : Winston Churchill : Napoleon Bonaparte : Ambrose BierceBernard Shaw : Mark Twain Quotes

Bulletin:

Vol 25, No.12 (December, 2013) Rational Fools vs. Efficient Crooks The efficient markets hypothesis : Political Skeptic Bulletin, 2013 : Unemployment Bulletin, 2010 :  Vol 23, No.10 (October, 2011) An observation about corporate security departments : Slightly Skeptical Euromaydan Chronicles, June 2014 : Greenspan legacy bulletin, 2008 : Vol 25, No.10 (October, 2013) Cryptolocker Trojan (Win32/Crilock.A) : Vol 25, No.08 (August, 2013) Cloud providers as intelligence collection hubs : Financial Humor Bulletin, 2010 : Inequality Bulletin, 2009 : Financial Humor Bulletin, 2008 : Copyleft Problems Bulletin, 2004 : Financial Humor Bulletin, 2011 : Energy Bulletin, 2010 : Malware Protection Bulletin, 2010 : Vol 26, No.1 (January, 2013) Object-Oriented Cult : Political Skeptic Bulletin, 2011 : Vol 23, No.11 (November, 2011) Softpanorama classification of sysadmin horror stories : Vol 25, No.05 (May, 2013) Corporate bullshit as a communication method  : Vol 25, No.06 (June, 2013) A Note on the Relationship of Brooks Law and Conway Law

History:

Fifty glorious years (1950-2000): the triumph of the US computer engineering : Donald Knuth : TAoCP and its Influence of Computer Science : Richard Stallman : Linus Torvalds  : Larry Wall  : John K. Ousterhout : CTSS : Multix OS Unix History : Unix shell history : VI editor : History of pipes concept : Solaris : MS DOSProgramming Languages History : PL/1 : Simula 67 : C : History of GCC developmentScripting Languages : Perl history   : OS History : Mail : DNS : SSH : CPU Instruction Sets : SPARC systems 1987-2006 : Norton Commander : Norton Utilities : Norton Ghost : Frontpage history : Malware Defense History : GNU Screen : OSS early history

Classic books:

The Peter Principle : Parkinson Law : 1984 : The Mythical Man-MonthHow to Solve It by George Polya : The Art of Computer Programming : The Elements of Programming Style : The Unix Hater’s Handbook : The Jargon file : The True Believer : Programming Pearls : The Good Soldier Svejk : The Power Elite

Most popular humor pages:

Manifest of the Softpanorama IT Slacker Society : Ten Commandments of the IT Slackers Society : Computer Humor Collection : BSD Logo Story : The Cuckoo's Egg : IT Slang : C++ Humor : ARE YOU A BBS ADDICT? : The Perl Purity Test : Object oriented programmers of all nations : Financial Humor : Financial Humor Bulletin, 2008 : Financial Humor Bulletin, 2010 : The Most Comprehensive Collection of Editor-related Humor : Programming Language Humor : Goldman Sachs related humor : Greenspan humor : C Humor : Scripting Humor : Real Programmers Humor : Web Humor : GPL-related Humor : OFM Humor : Politically Incorrect Humor : IDS Humor : "Linux Sucks" Humor : Russian Musical Humor : Best Russian Programmer Humor : Microsoft plans to buy Catholic Church : Richard Stallman Related Humor : Admin Humor : Perl-related Humor : Linus Torvalds Related humor : PseudoScience Related Humor : Networking Humor : Shell Humor : Financial Humor Bulletin, 2011 : Financial Humor Bulletin, 2012 : Financial Humor Bulletin, 2013 : Java Humor : Software Engineering Humor : Sun Solaris Related Humor : Education Humor : IBM Humor : Assembler-related Humor : VIM Humor : Computer Viruses Humor : Bright tomorrow is rescheduled to a day after tomorrow : Classic Computer Humor

The Last but not Least


Copyright © 1996-2014 by Dr. Nikolai Bezroukov. www.softpanorama.org was created as a service to the UN Sustainable Development Networking Programme (SDNP) in the author free time. This document is an industrial compilation designed and created exclusively for educational use and is distributed under the Softpanorama Content License. Site uses AdSense so you need to be aware of Google privacy policy. Original materials copyright belong to respective owners. Quotes are made for educational purposes only in compliance with the fair use doctrine.

FAIR USE NOTICE This site contains copyrighted material the use of which has not always been specifically authorized by the copyright owner. We are making such material available to advance understanding of computer science, IT technology, economic, scientific, and social issues. We believe this constitutes a 'fair use' of any such copyrighted material as provided by section 107 of the US Copyright Law according to which such material can be distributed without profit exclusively for research and educational purposes.

This is a Spartan WHYFF (We Help You For Free) site written by people for whom English is not a native language. Grammar and spelling errors should be expected. The site contain some broken links as it develops like a living tree...

You can use PayPal to make a contribution, supporting hosting of this site with different providers to distribute and speed up access. Currently there are two functional mirrors: softpanorama.info (the fastest) and softpanorama.net.

Disclaimer:

The statements, views and opinions presented on this web page are those of the author and are not endorsed by, nor do they necessarily reflect, the opinions of the author present and former employers, SDNP or any other organization the author may be associated with. We do not warrant the correctness of the information provided or its fitness for any purpose.

Last modified: February 19, 2014