dcsimg

Halt! Who Goes There?

Linux's venerable 'read-write-execute' file permissions scheme works well when access rights align with the users and groups on the system. But if you want to grant access rights, say, to multiple users who are not in the same group, or want to grant access rights to multiple groups, the system fails miserably. Access control lists (ACLs) are much more flexible. Here's how to use ACLs -- a much better way to grant permissions.

If you’ve spent even a little time with a Linux system, you’re probably quite familiar with Linux’s file permission scheme. In a nutshell, you may read, write, or execute a file (or in the case of a directory, search the directory) only if you have the proper permission. Furthermore, the traditional Linux read, write, and execute permissions are distinct, and each of those rights can be granted separately to the owner (a user) of the file, to the group that owns the file, and to other, which represents users other than the owner and users in the named group. Linux commands like chmod, chown, and chgrp affect the permissions and change the owners of files.

In general, Linux’s simple permission scheme works well and is especially effective when access rights align with the users and groups on the system. But if you want to grant access rights to lists of users that do not belong to an existing group, the system fails miserably.

For example, if you want to share one of your personal files, phones.txt, with every member of your group, say, staff, you can grant that access with two commands: chown staff phones.txt; chmod g+r phones.txt. However, if you want to give read access to friends.txt to Debbie and Bo, and read access to colleagues.txt to Bo and Abby, you’d have to create two different groups with Bo in each one. (Or, perhaps its more accurate to say that your system administrator would have to create the groups.)

As you can see, managing permissions through “special interest groups” is terribly inconvenient, and worse, it doesn’t scale. A more flexible scheme is Access Control Lists, or ACLs. Instead of capturing permissions in just a few flags, ACLs record permissions in an individual and extensible list of access rights that are attached to each file or directory. Access control rights can be assigned to a specific user, a specific group, or to multiple users or groups in any combination. In a sense, ACLs are like the “Will Call” list at the hottest club in town: if you’re not on the access control list, you don’t get in.

Reusing the example above, if you want to give access to friends.txt to Debbie and Bo, you simply grant read access to both users. No (administrative) group is needed. Need to grant access to a third user? Simply give that user the appropriate access rights. In a sense, ACLs enhance security because ACLs can implement access policy directly, even if the policy is different for every file on the system.

And ACLs can be used to build advanced system applications like Samba, which, like its progenitor, Windows, requires ACLs. (For more information on how Samba uses ACLs, see “ACL Support in Samba” on page 26.) Let’s see how ACLs work and see how to use them.

Like Sticky Notes for Files

File access control lists and Extended Attributes (EAs) are new additions to the Linux kernel, and are currently supported by the Ext2, Ext3, JFS, ReiserFS, and XFS file systems. You’ve already seen what an ACL is for; EAs are simply the underlying mechanism used to record ACLs.

An EA consists of a name/value pair, and is used to associate arbitrary pieces of file meta-data, or data about data, with a file or directory. EAs are not a part of the file’s data. Instead, EAs are maintained separately, and are automatically managed by the file system.

More than one EA can be attached to a specific file or directory, and an EA can store system objects (such as access control lists or the capabilities of an executable) and user objects (such as the MIME type or character set of a file). Applications can define and associate extended attributes with a file object (remember, a directory is just a special file) through file system function calls.

Extended attributes can be used to store almost anything. You can maintain a file’s history; categorize the contents of the file (such as text, icons, bitmaps); record the version of the file; append additional data; or do all of the above.

For example, Figure One shows five extended attributes (Version, File Type, Additional Data, Install, and History) of My_File.









acls_01
Figure One: A file with five Extended Attributes

With EAs in place, ACLs are relatively easy to implement. An Access Control Entry, or ACE, is an individual entry in an ACL. Each ACE is a triple defined by an entry type, either group or user; a group name, username, numeric UID, or numeric GID, depending on the value of the first field;

and the access permission or right (read, write, execute) associated with the ACE.

So, in the abstract, giving Debbie permission to read friends. txt means that the ACL attached to friends.txt contains the ACE (user, debbie, read). Currently, ACLs are the only Linux feature dependent on EAs. Other operating systems have had EAs for several years, and the use of EAs on those systems is much broader.

Loosing Controls without Losing Control

ACLs let you maintain fine-grained control over your files. With ACLs, you can avoid the risk of granting privileges too widely. Let’s see how to query and set ACLs.




Listing One: A script to add Extended Attributes to a large group of files

#! /bin/bash

find linux-2.4.20 | while read F; do
INO=$(ls -di $F | sed -e ‘s/^ *//’ | cut ?f1 ?d ‘ ‘);
setfattr ?n user.ino ?v $INO $F;
done

The commands getfacl, setfacl, getfattr, and setfattr display and manipulate ACLs and EAs. getfacl examines ACLs for files and directories, while setfacl sets those ACLs. getfattr and setfattr examine and set EAs, respectively.

In this first example, the user best is given read and write access to a file named status.


# ls -l status
-rw-r–r– 1 smith peons 627 Jun 21 10:21 status
# setfacl -m u:best:rw status
# getfacl status
# file: status
# owner: smith
# group: peons
user::rw-
user:best:rw-
group::r–
mask:rw-
other:r–

The -m switch to setfacl specifies an ACL. Here the ACL u:best:rw grants read and write (rw) access to the user (u:) best.

getfacl displays ACLs and other file information. The first three lines show the file’s name (status), the file’s owner (smith), and the group owner (status). The line user:rw- (and the lines group::r– and other:r–) simply reflect the file mode permission bits. user:best:rw- is the new, named user ACL. You can also create named group ACLs.

Interestingly, the traditional Linux permissions and the ACL coexist. The group owner, peons, can still read the file, as can everyone else. The owner of the file, smith, and the user best can read and write the file.

The line mask:rw- is somewhat special: it displays the effective rights mask. This entry limits the effective rights granted to all groups and to named users. (The file owner and others permissions are not affected by the effective rights mask; all other entries are.)

In the next example, let’s use the Linux kernel source files (actually, any large tarball suffices), and see how to set and view a set of EAs on a large group of files. To prepare for the example, download linux-2.4.20.tar.gz from a kernel mirror into a subdirectory called /usr/src. Make sure that the directory /usr/src/linux-2.4.20 doesn’t exist, and then use the following commands to unpack the tarball:


# cd /usr/src
# tar -zxvf linux-2.4.20.tar.gz

At this point, all of the files in /usr/src/linux-2.4.20 are owned by user and group root. The script in Listing One, xattr. script, creates unique extended attributes for each file. Specifically, it creates an EA named user.ino for each file, and sets the value of that EA to the inode number of the file. The setfattr command does all the heavy lifting.

Run the script and then change your directory to the top of the source tree:


# ./xattr.script
# cd linux-2.4.20

getfattr can be used to view the extended attributes. Try the command on the file named Makefile.


# getfattr -d Makefile
user.ino=”1399000″

The next command creates ACLs on all of the files in the linux-2.4.20 directory. Go back to /usr/src/ and then type the find command shown below.




ACL Support in Samba


To make Samba as portable as possible, the designers of Samba decided against a custom implementation of ACLs. Instead, each Samba server converts NT ACL specifications (sent via MS-RPC) into a POSIX ACL, and then converts that neutral ACL into an ACL that’s platform-specific. A conceptual illustration of Samba’s ACL subsystem is shown in Figure Two.









acls_02
Figure TWO: Overview of Samba’s POSIX ACL support

If the Samba server’s underlying file system supports ACLs, and the POSIX ACL can be converted to a native ACL, Windows users can manipulate server-side ACLs on the Samba server using common Windows NT commands.

Samba 2.2 included support for ACLs, but up until now, Samba hasn’t had a way to store ACLs directly on the file system, since there was no ACL support available for Linux. That’s no longer an issue, and Samba will preserve NTFS ACLs rather than mapping ACL permissions to the less-flexible, standard Unix permissions. (Windows NT and Windows 2000 use ACLs to set permissions on files and directories. That scheme offers a much finer-grained control over permissions than the traditional “one user, one group” solution that most Unix systems use.)

Native ACL support, in combination with winbind, allows a Linux-based system to “assimilate” Windows NT users, groups, and ACL permissions. Quite an impressive solution!



# cd /usr/src
# find linux-2.4.20 -type f | xargs setfacl


-m u:best:rw

Then, to view the ACL of Makefile, use getfacl as before.


# cd linux-2.4.20
# getfacl Makefile
# file: Makefile
# owner: 573
# group: 573
user::rw-
user:best:rw-
group::rw-
mask::rw-
other::r–

By default, files and directories do not have any EAs or ACLs. However, you can set a default ACL on a directory, and then all files and directories created within that directory inherit its ACL. For example, the linux-2.4.20 subdirectory looks like this after the previous sets of commands have been run.


# cd /usr/src
# getfacl linux-2.4.20
# file: linux-2.4.20
# owner: 573
# group: 573
user::rwx
group::r-x
other::r-x

Running the command…


# find linux-2.4.20 -type d | xargs


setfacl -m u:best:rwx,d:u:best:rwx

…changes the directory linux-2.4.20 to look like this:


# getfacl linux-2.4.20
# file: linux-2.4.20
# owner: 573
# group: 573
user::rwx
user:best:rw-
group::r-x
mask::rwx
other::r-x
default:user::rwx
default:user:best:rwx
default:group::r-x
default:mask::rwx
default:other::r-x

Now, any file or directory created within linux-2.4.20 automatically inherits the ACEs marked with default. Furthermore, if a directory is created within linux-2.4.20, then the default ACL of the new directory is initialized to the default ACL of linux-2.4.20.

Better than “RWX”

Let’s look at a more complicated scenario that demonstrates the power of ACLs. (The following example is based on Andreas Grünbacher’s ACL documentation found online at http://acl.bestbits.at. Andreas is a long-time contributor to the ACL code.)

Toys4U is a small toy maker. Linux is used as its main file server. The system administrator of Toys4U is named andy. One particular team, the Toolies, focuses on the development of new toys. The Toolies keep all their shared data in the subdirectory /home/toolies/shared. joe is the administrator of the Toolies team. Other members are lisa, mark, and tom.

The Toolies decide upon the following access policies:

Inside the shared directory, all Toolies should have read access.

* joe, being the Toolies administrator, should have full access to all subdirectories of shared, as well as to any files in any of these directories.

Each Toolies project should have its own project-specific subdirectory in shared.

And each person who is working on a specific project shall have full access to that project’s subdirectory in shared.




Listing Two: The Toolies file structure


% ls -l /home/toolies








drwx——2 joetoolies1024 Sep 25 12:47
drwx——2 lisatoolie1024 Sep 25 12:47 lisa
drwx——2 marktoolies1024 Sep 25 13:23 mark
drwxr-x—2 joetoolie1024 Sep 25 12:48 shared
drwx——2 tomtoolies1024 Sep 25 12:48 tom

% ls -l /home/toolies/shared




drwxrwx—2 joebig1024 Sep 25 14:09 big
drwxrwx—2 joepricey1024 Sep 25 14:09 pricey

Now, two brand new toys are being developed: “Big” and “Pricey.” lisa is working on Big; tom is working on Pricey; and mark is working on both. The teams and their associations are summarized in Table One. So, the Toolies folder would have the structure shown in Listing Two.




Table One: The Toolies organizational structure









User name

Groups (primary group in bold) Function

andy

users

System administrator

joe

toolies, big, pricey

Toolies administrator

lisa

toolies, big

Toolie

tom

toolies, pricey

Toolie

mark

toolies, big, pricey

Toolie


So, here are the problems:

1. lisa doesn’t have read access to /home/toolies/shared/pricey.

2. tom doesn’t have read access to /home/toolies/shared/big.

3. joe doesn’t have write access to files that others create in any project subdirectory.

Of course, the first two problems could be solved by granting everyone read access to the /home/toolies/shared directory tree using the “others” permission bits (making the directory tree world readable). Since nobody else but Toolies have access to the /home/toolies directory, this is safe. However, one would need to take great care of the other permissions of the /home/toolies directory. Later, it would be impossible to make anything in the Toolies directory world-readable. Finally, the third problem has no clean solution within the traditional system of Linux file permissions.

With ACLs, there is a better solution. If the system supported ACLs, the /home/toolies/shared subdirectories can be made readable for Toolies, and fully accessible for the respective project group. For joe’s administrative rights, a separate ACL entry is needed.

The command setfacl -m g:toolies:rx * grants read access to the Toolies (in addition to the existing permissions of other users and groups).

The ACL entries of the two project subdirectories now contain the following ACL entries:


% cd /home/toolies/shared; % getfacl *
# file: big
# owner: joe
# group: big
user::rwx
group::rwx
group:toolies:r-x
mask:rwx
other:—

# file: pricey
# owner: joe
# group: pricey
user::rwx
group::rwx
group:toolies:r-x
mask:rwx
other:—

Now when files are created inside one of the /home/toolies/shared subdirectories, the file owner and group are set to the creator and the creator’s current active group, respectively (the active group can be changed using sg). Here, lisa is creating a file in /home/toolies/shared/big:


lisa % cd /home/toolies/shared/big
lisa % umask
022
lisa > touch file1
lisa > getfacl file1
# file: file1
# owner: lisa
# group: big
user::rw-
group::r–
other:—

You might notice that the group permissions are set to r– — that’s because of the umask, 022.




Packages for ACLs and EAs

There are two key utility packages for ACLs and EAs. The first package is acl, and it contains getfacl and setfacl. The next package is attr, which contains getfattr and setfattr. To determine if you have both packages installed and to find the version number of each package, use rpm -qf. The name of the packages and the level of the packages on your system should be similar to the following:



# rpm -qf /usr/bin/getfacl
acl-2.0.19-12
# rpm -qf /usr/bin/getfattr
attr-2.0.11-12

For a complete list of patches and source versions of the packages that have been enhanced to support ACLs and EAs, see Andreas Grüenbacher’s web page at http://acl.bestbits.at. (Thanks to Andreas for all of the work he has done to add ACLs and EAs to Linux.)


Obviously, the ACL settings are not applied to new files. So neither the Toolies nor joe get their proper rights. This can be changed using a default ACL. Here’s how to do that.


joe % cd /home/toolies/shared
joe % setfacl -m
d:u:joe:rwx,d:g:toolies:rx *

Now the ACLs of the two subdirectories contain the following entries:


joe % cd /home/toolies/shared
joe % getfacl *
# file: big
# owner: joe
# group: big
user::rwx
group::rwx
group:toolies:r-x
mask:rwx
other:—
default:user::rwx
default:user:joe:rwx
default:group::rwx
default:group:toolies:r-x
default:mask:rwx
default:other:—
# file: pricey
# owner: joe
# group: pricey
user::rwx
group::rwx
group:toolies:r-x
mask:rwx
other:—
default:user::rwx
default:user:joe:rwx
default:group::rwx
default:group:toolies:r-x
default:mask:rwx
default:other:—

Once the default ACL is set and lisa creates a file in /home/ toolies/shared/big, the umask no longer influences the permissions of new files.


lisa % cd /home/toolies/shared/big
lisa % umask
022
lisa % touch file2
lisa % getfacl file2
# file: file2
# owner: lisa
# group: big
user::rw-
user:joe:rwx#effective:rw-
group::rwx#effective:rw-
group:toolies:r-x#effective:r–
mask:rw-
other:—




Distributions with ACLs and EAs

SuSE 8.0 was one of the first Linux distributions to support both EAs and ACLs, and most current versions of Linux distributions are ACL-enabled by default. The table below shows the availability of ACLs in some of the major distributions.









DISTRIBUTION

USERKERNELFILE SYSTEMS W/ACLS

Red Hat AS 2.1

No

No

No

Red Hat 9.0

No

Yes

None

United Linux 1.0

Yes

Yes

Ext2,Ext3,JFS,ReiserFS,XFS

SuSE 8.1

Yes

Yes

Ext2,Ext3,JFS,ReiserFS,XFS

SuSE 8.2

Yes

Yes

Ext2,Ext3,JFS,ReiserFS,XFS


Red Hat 9.0 has utility support and libraries for EAs and ACLs, but doesn’t have kernel or file system support since Red Hat found a problem in Ext3 caused by the ACL/EA patch. Red Hat’s solution was to remove the file system and kernel support for now.

If you want to patch the kernel to add ACL and EA support, see the sidebar, “Building the Kernel and the JFS File System with ACLs” for instructions on how to do it.


Some ACL-Biters

Before you start using ACLs in a production system make sure that you verify that all of the common system utilities that you use day-to-day have been enhanced to support extended attributes and access control lists. You wouldn’t want to start using both ACLs and EAs and lose them when you copy files or back up the data on your system.

For example, a common package that system administrators use to backup and restore data is tar. However, at the time this article was written, tar has yet to be enhanced to support ACLs or EAs.

Fortunately, the star (“S tar“) package (available from http://freshmeat.net/projects/star) is a tar variant that does support ACLs and EAs. (The developers of star also claim that it is very fast, and is compliant with POSIX tar. You might want to switch to star for all of your archiving needs.)




Building the Kernel and the JFS File System with ACLs

If your distribution lacks kernel and file system support for ACLs, here’s how to build a kernel and a file system from source and patches.

EA system calls were first included in the 2.4.20 kernel, so let’s use the same kernel source code used in the earlier examples. Start with the linux-2.4-20.tar.gz tarball and unpack it using the following commands:


# cd /usr/src
# tar -zxvf linux-2.4.20.tar.gz

Now download the kernel patches for ACL and EA support from http://acl.bestbits.at. At the time of writing, the latest version is 0.8.58. The EA patches can be found in ea-2.4.20-0.8.58. diff.gz, and the ACL patches are in acl-2.4.20-0.8.57.diff.gz. These patches also add EA/ACL support for the Ext2 and Ext3 file systems.

Create a directory called 0.8.58, place both files into that directory, and unpack the files.


# mkdir 0.8.58
# gunzip /usr/src/0.8.58/ea-2.4.20-0.8.58.diff.gz
# gunzip /usr/src/0.8.58/acl-2.4.20-0.8.57.diff.gz

Now apply each of these patches to the 2.4.20 kernel. Remember to change to the top level of the kernel source tree.


# cd /usr/src/linux-2.4.20
# patch -p1 < /usr/src/0.8.58/ea-2.4.20-0.8.58.diff
# patch -p1 < /usr/src/0.8.58/acl-2.4.20-0.8.57.diff

Next, let’s patch the Journaling File System to add ACLs. Download the ACL patch for JFS from the JFS web page at http://oss.software.ibm.com/developerworks/opensource/jfs. The patch is available under the “Get the Source” link. Name this patch jfsacl.diff, and store it in /usr/src/0.8.58/. Now apply that patch to the kernel.


# patch -p1 < /usr/src/0.8.58/jfsacl.diff

Now, you need to configure the kernel to enable ACLs and JFS. All these options can be set by going to the File system section of the configuration menu.


JFS filesystem support (CONFIG_JFS_FS=y)
JFS Posix ACL support (CONFIG_JFS_POSIX_ACL=y)

With the source code patched and configured, build the kernel.

1. To recompile the kernel (in /usr/src/linux-2.4.20/), run the command:


# make dep && make clean && make bzImage

2. Recompile and install modules (only if you have added other options as modules)


# make modules && make modules_install

3. Install the kernel.


# cp arch/i386/boot/bzImage /boot/acl-bzImage
# cp System.map /boot/acl-System.map
# ln -s /boot/acl-System.map /boot/System.map

Finally, update the boot loader on your system to boot this new kernel. If you are using lilo, update /etc/lilo.conf with the new kernel. Add an entry like the one that follows and an acl entry should appear at the lilo boot prompt:


image=/boot/acl-bzImage
label=acl
read-only
root=/dev/hda5 # Change to your root partition

Be sure to specify the correct root partition, then run


# lilo

…to make the system aware of the new kernel. Reboot and select the acl kernel to boot the new image.


OF ACLS AND EAS

Both ACLs and EAs support have been accepted into the 2.5.x development tree of kernel. Also, Ext2, and the journaling file systems Ext3, XFS, and JFS have both features included. With this basic support included, additional applications will be developed over time. NFS version 4 has ACL support included in the protocol, and this version will be commonplace in the near future.

Access Control Lists enhance the traditional Linux file permissions scheme by creating more flexibility and fine-grained control over file and directory access. ACLs are very useful in environments where changing or adding groups is not readily available. Samba is another key solution that benefits by having ACLs being able to be stored by the file systems.




Resources


Extended Attributes & Access Control Lists — http://acl.bestbits.at

Man pages for ACLs: http://acl.bestbits.at/man/man.shtml

2.4.x kernel patch for ACL support for ext2/ext3 — http://acl.bestbits.at

2.4. x kernel patch for ACL support for XFS — http://oss.sgi.com/projects/xfs

2.4. x kernel patch for ACL support for JFS — http://oss.software.ibm.com/jfs

POSIX 1003.1e/1003.2c Draft Standard 17 (withdrawn) — http://www.suse.de/~agruen/acl/posix/posix.html

Samba: http://www.samba.org

Star http://freshmeat.net/projects/star




Steve Best works in the Linux Technology Center of IBM in Austin, Texas. He is currently working on the Journaled File System (JFS) for Linux project. Steve has done extensive work in operating system development, focusing on file systems, internationalization, and security. He can be reached at sbest @us.ibm.com.

Fatal error: Call to undefined function aa_author_bios() in /opt/apache/dms/b2b/linux-mag.com/site/www/htdocs/wp-content/themes/linuxmag/single.php on line 62