Go to the first, previous, next, last section, table of contents.


Managing ACLs

Access control lists are extended file permissions. They allow you to open or close a file to a named list of users (without having to create a special group for those users). They also allow you to open or close a file for a named list of groups. Several unix-like operating systems have had access control lists for some time; but they do not seem to have caught on.

There is a number of reasons for this dawdling in the past. The tools for setting ACLs are generally interactive and awkward to use. Because a named list of users would lead to excessive verbosity in an ls -l listing, one does not normally see them. There is therefore the danger that the hidden information would lead to undetected blunders in opening files to the wrong users. ACLs are also different on every vendor's filesystems and they don't work over intersystem NFS. In spite of these reservations, ACLs are a great idea. Here at Oslo College, it seems that users are continually asking how they can open a file just for the one or two persons they wish to collaborate with. They have grown used to Novell/PC networks which embraced the technology from Apollo/NCS much earlier. Previously the Unix answer to users has always been: go ask the system administrator to make a special group for you. Then do the `chmod' thing. And then they would say: so what's so great about this Unix then?

Addressing this lack of standardization has been the job of a POSIX draft committee. Some vendors have made their implementations in the image of this draft. Solaris 2.6 has a good implementation. In spite of this, even these systems have only awkard tools for manipulating ACLs. Not the kind of thing you want to be around much, if you have better things to do. But the incompatibility argument applies only to multiple vendor headbutting. Some institutions who share data on a global basis opt for advanced solutions to network filesystems, such as AFS and DFS. Filesystems such as DCE's DFS make extensive use of file ACLs, and they are not operating system specific. Even so, DFS provides only interactive tools for examining and setting file permissions, and this is of little use to system administrators who would rather relegate that sort of thing to a script.

The need for this kind of thing is clear. Systems which make use of ACLs for security can be brought to their knees by changing a few ACLs. Take the Apollo/Domain OS as an example. All one needs to do to kill the system is to change a few ACLs and forget what they were supposed to be. Suddenly the system is crippled, nothing works. The only solution, if you don't have a backup, is to remove all of the security. Unix has a simpler security philosophy when it comes to the operating system files, but ACLs would be a valuable addition to the security of our data.

A cfengine bare-bones file-checking program looks like this:

#
# Free format cfengine program
#

 control:

   ActionSequence - ( files )

 files:

   classes::

     /directory/file  mode=644 
                      owner=mark,ds
                      group=users,adm
                      acl=zap 
                      action=fixplain

  # ... more below

This program simply checks the permissions and ownership of the named file. The regular file mode, owner and group are specified straightforwardly. The new feature here is the acl directive. It is a deceptively simply looking animal, but it hides a wealth of complexity. The zap is, of course, not an access control list. Rather, cfengine uses a system of aliases to refer to ACLs, so that the clutter of the complex ACL definitions does not impair the clarity of a file command. An ACL alias is defined in a separate part of the program which looks like this:

 # ...contd

 acl:

   { zap

   method:append
   fstype:solaris
   user:rmz:rwx
   user:len:r
   }

As you can see, an ACL is a compound object--a bundle of information which specifies which users have which permissions. Because ACLs are lists the alias objects must also know whether the items are to be appended to an existing list or whether they are to replace an existing list. Also, since the permission bits, general options and programming interfaces are all different for each type of filesystem, we have to tell cfengine what the filesystem type is.

It is possible to associate several ACL aliases with a file. When cfengine checks a files with ACLs, it reads the existing ACL and compares it to the new one. Files are only modified if they do not conform to the specification in the cfengine program. Let's look at a complete example:

 files:

   $(HOME)/myfile acl=acl_alias1 action=fixall

 acl:

   { acl_alias1

   method:append
   fstype:solaris
   user:len:rwx
   }

ACLs are viewed in Solaris with the command `getfacl'. Suppose that, before running this program, our test-file had permissions

   user:*:rwx
   user:mark:rwx           #effective:r-x
   group:*:r-x              #effective:r-x
   mask:r-x
   other:r-x
   default_user:rw-
   default_group:r--
   default_mask:-w-
   default_other:rwx

After the cfengine run, the ACL would become:

   user:*:rwx
   user:mark:rwx           #effective:r-x
   user:len:rwx            #effective:r-x
   group:*:r-x              #effective:r-x
   mask:r-x
   other:r-x
   default_user:rw-
   default_group:r--
   default_mask:-w-
   default_other:rwx

Suppose we wanted to to remove 'w' bit for user `jacobs', or make sure that it was never there.

	{ acl_alias1

	method:append
	fstype:solaris
	user:jacobs:-w
	}

Note that the method used here is append. That means that, whatever other access permissions we might have granted on this file, the user `jacobs' (a known cracker) will have no write permissions on the file. Had we used the method overwrite above, we would have eliminated all other access permissions for every user and added the above. If we really wanted to burn `jacobs', we could remove all rights to the file like this


  user:jacobs:noaccess

The keyword noaccess removes all bits. Note that this is not necessarily the same as doing a -rwx, since some filesystems, like DFS, have more bits than this. Then, if we want to forgive and forget, the ACLs may be removed for jacobs with the syntax

  user:jacobs:default

In Solaris, files inherit default ACLs from the directory they lie in; these are modified by the umask setting to generate their own default mask.

DFS ACLs look a little different. They are examined with the `acl_edit' command or with

dcecp -c acl show <filename>

In order to effect changes to the DFS, you have to perform a DCE login to obtain authentication cookies. The user `cell_admin' is a special user account for administrating a local DFS cell. Suppose we have a file with the following DCE ACL:

  mask_obj:r-x---
  user_obj:rwxcid
  user:cell_admin:r--c-- #effective:r-----
  group_obj:r-x--d       #effective:r-x---
  other_obj:r-x---

Now we want to add `wx' permissions for user `cell_admin', and add new entries with `rx' permissons for group acct-admin and user `root'. This is done with the following ACL alias:


   { acl_alias2

   method:append
   fstype:dfs
   user:/.../iu.hioslo.no/cell_admin:wx
   group:/.../iu.hioslo.no/acct-admin:rx
   user:/.../iu.hioslo.no/root:rx
   user:*:-x
   }

The local cell name `/.../iu.hioslo.no' is required here. Cfengine can not presently change ACLs in other cells remotely, but if your cfengine program covers all of the cell servers, then this is no limitation, since you can still centralize all your ACLs in one place. It is just that the execution and checking takes place at distributed locations. This is the beauty of cfengine. After running cfengine, with the above program snippet, the ACL then becomes:

  mask_obj:r-x---
  user_obj:rwcid
  user:cell_admin:rwxc-- #effective:r-x---
  user:root:r-x--       #effective:r-x---
  group_obj:r-x--d       #effective:r-x---
  group:acct-admin:r-x---
  other_bj:r-x---

For the sake of simplicity we have only used standard Unix bits `rwx' here, but more complicated examples may be found in DFS. For example,


 user:mark:+rwx,-cid

which sets the read, write, execute flags, but removes the control, insert and delete flags. In the DFS, files inherit the inital object ACL of their parent directory, while new directories inherit the initial container object.

The objects referred to in DFS as user_obj, group_obj and so forth refer to the owner of a file. i.e. they are equivalent to the same commands acting on the user who owns the file concerned. To make the cfengine user-interface less cryptic and more in tune with the POSIX form, we have dropped the `_obj' suffices. A user field of `*' is a simple abbreviation for the owner of the file.

A problem with any system of lists is that one can generate a sequence which does one thing, and then undoes it and redoes something else, all in the same contradictory list. To avoid this kind of accidental interaction, cfengine insists that each user has only one ACE (access control entry), i.e. that all the permissions for a given user be in one entry.


Go to the first, previous, next, last section, table of contents.