[LWN Logo]

Date: Sun, 19 Dec 1999 23:26:59 +0100
From: Andreas Gruenbacher <a.gruenbacher@infosys.tuwien.ac.at>
To: Linux ACL Developers List <acl-devel@bestbits.at>,
Subject: [ACL-Devel] Proposed ACL system calls

This is a multi-part message in MIME format.
--------------B9FF50AC2BDFD1474904BE62
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

Dear all,

I want to propose two access control list system calls for inclusion into the
standard kernel.

This proposal includes the specification for the generic system calls, and for
Posix-style ACLs as the first implemented ACL system. I will call the ACL system
(Posix ACLs vs. Netware, AFS, NTFS, ...) the ACL class.

I have experimented with different designs, starting with a Posix-only version
during the last couple of weeks/months. We also had lengthy discussions in the
ACL-Devel mailing list, <acl-devel@bestbits.at>. (There's a list archive at
<http://acl.bestbits.at/acl-devel/>;.)

The design I propose here turned out to be flexible, and easy to use and
implement. The ACL manipulation system calls are not very performance critical.
The system calls are designed to support various ACL classes. The Posix ACL
class parameters are designed to map easily to the Posix libary functions.

The system call and VFS layer is very thin (<100 LOC without comments).

In the kernel, the system calls shoult invoke a new operation in struct
inode_operations. The actual ACL class handling shall then be performed in the
filesystems, just like the mkdir system call (just as one example).

I have attached a manual page describing the system call interface.

[Btw, I have named the system calls kacl() and kfacl() just so
 that the names don't clash too easily with variable names and
 the Solaris system calls acl() and facl().] 


There are two independent implementations of Posix ACLs for ext2 at the moment,
with incompatible system calls and implementations. My hope is to close the gap
between these implementations. An identical system call interface would allow us
to use the same tools for both implementations, as a starting point.

I also have an implementation of the Posix 1003.1e Draft Standard 17 ACL library
functions. These functions can be used for portable applications. The library
should be fairly easily portable to other OSes as well.
While DS17 is withdrawn, and the standardization effort discontinued, other UNIX
ACL implementations are based on DS17 or earlier drafts.


Looking forward to hearing your comments,

Andreas

------------------------------------------------------------------------
 Andreas Gruenbacher, a.gruenbacher@computer.org
 Contact information: http://www.infosys.tuwien.ac.at/~agruenba
--------------B9FF50AC2BDFD1474904BE62
Content-Type: text/plain; charset=iso-8859-1;
 name="kacl.txt"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: inline;
 filename="kacl.txt"




ACL(2)                                                     ACL(2)


NAME
       kacl, kfacl - manipulate access control lists for files

SYNOPSIS
       #include <acl/acl.h>
       #include <acl/acl_posix.h>

       int  kacl(const  char  *pathp,  int cmd, void *acl,
                 size_t size);

       int kfacl(int filedes, int cmd, void *acl, size_t size);

DESCRIPTION
       These system calls manipulate access control lists  (ACLs)
       for  files  and  directories.  kacl manipulates the ACL of
       the named file pathp.  kfacl is identical to acl, only the
       ACL  of  the  open  file  with  file descriptor filedes is
       manipulated.

       Setting ACLs is granted to the file owner and users  capa=AD
       ble  of  CAP_FOWNER (usually, this is the root user only).
       All other operations  require  list  access  to  the  file
       (i.e.,  read access to the directory the file is contained
       in).

       The acl parameter points to a structure describing an ACL,
       and  depends  on the ACL class.  The size parameter speci=AD
       fies the size of that structure.

       The cmd parameter is set to the requested  operation.  The
       following  generic  operations on access control lists are
       defined. For the ACL_CLASS_POSIX class, additional  opera=AD
       tions are defined.

       ACL_CMD_GET
           Retrieve the ACL of a file.

       ACL_CMD_SET
           Set the ACL of a file. The old ACL is replaced.

       ACL_CMD_CLASS
           Query if a specific ACL class is supported for a file.
           The acl parameter must point to  a  variable  of  type
           int.   The  value of this variable is the ACL class in
           question. The size parameter must be  >=3D  sizeof(int).
           Currently,  the only class defined is ACL_CLASS_POSIX.

       ACL_CMD_QUOTA
           Determine the disk  space  allocated  (in  bytes)  for
           access  control  lists  associated  with  a  file. The
           parameters acl and size are ignored.


   Posix-style ACLs (ACL_CLASS_POSIX)
       The ACL_CLASS_POSIX class  supports  Posix  1003.1e  Draft
       Standard 17 compliant access control lists. (Other classes
       may be added in the future).

       A pointer to a variable of  the  following  type  must  be
       passed  in  the acl parameter to the kacl and kfacl system
       calls for Posix-style ACLs.

              typedef struct {
                  int                a_class =3D ACL_CLASS_POSIX;
                  int                a_type;
                  unsigned int       a_size;
                  acl_posix_entry_t  *a_entries;
              } acl_posix_t;

       The  size  system  call   parameter   must   be   set   to
       sizeof(acl_posix_t).  The  a_class  field  must  be set to
       ACL_CLASS_POSIX.

       The a_type field specifies which ACL to modify. It is  set
       to ACL_TYPE_ACCESS or ACL_TYPE_DEFAULT.

       The a_entries parameter points to a buffer of ACL entries.
       For the ACL_CMD_SET operation, the buffer must  contain  a
       valid  ACL.  For  the ACL_CMD_GET operation, the buffer is
       filled with the ACL of the file. For all other operations,
       the  a_entries  field is ignored.  The a_size field speci=AD
       fies the size (in bytes)  of  the  buffer  pointed  to  by
       a_entries.

       The ACL entries have the following type:

              typedef struct {
                  short           e_tag;
                  unsigned short  e_perm;
                  unsigned int    e_id;
              } acl_posix_entry_t;


       The  e_tag  field  contains the entry tag type. The e_perm
       field contains the permissions  associated  with  the  ACL
       entry.  The e_id field contains an undefined value, a user
       identifier or a group identifer, depending on the value of
       the  a_tag  field.  The  folowing  values  for a_tag.  are
       defined.


       ACL_USER_OBJ
           This entry corresponds to the file owner  permissions,
           and  is  required  for nonempty ACLs. For ACL_CMD_SET,
           the value of e_id is ignored. For ACL_CMD_GET, e_id is
           set to the uid of the file owner.

       ACL_USER
           This  entry  defines  discretionary access permissions
           for a user.  e_id is the user identifier of that user.
           An ACL may contain more than one ACL_USER entry.

       ACL_GROUP_OBJ
           This  entry  corresponds  to  the owning group permis=AD
           sions,  and  is  required  for  nonempty   ACLs.   For
           ACL_CMD_SET,   the  value  of  e_id  is  ignored.  For
           ACL_CMD_GET, e_id is set to the  group  identifier  of
           the owning group.

       ACL_GROUP
           This  entry  defines  discretionary access permissions
           for a group.  e_id is the  group  identifier  of  that
           group.  An  ACL  may  contain  more than one ACL_GROUP
           entry.

       ACL_MASK
           This is the ACL mask entry (see acl(5)).   If  an  ACL
           contains  ACL_USER  or ACL_GROUP entries, the ACL_MASK
           entry is required. If an ACL contains the  three  base
           entries  ACL_USER_OBJ, ACL_GROUP_OBJ and ACL_OTHER, it
           may also contain an ACL_MASK entry.

       ACL_OTHER
           This entry correcponds to the  permissions  of  others
           (the  ``world''  permissions),  and  is  required  for
           nonempty ACLs. The value of e_id is ignored/undefined.

       For  the  ACL_CMD_SET  operation,  the  ACL entries in the
       a_entries buffer must be ordered according to the  follow=AD
       ing rules:

       =B7   The  ACL  entries  must be in the same order as intro=AD
           duced above.

       =B7   All ACL_USER entries must  be  ordered  by  increasing
           user identifier.

       =B7   All  ACL_GROUP  entries  must be ordered by increasing
           group identifier.

       The ACL_CMD_GET operation returns the ACL entries in  pre=AD
       cisely that order.

       The  e_perm field of an ACL entry is a bitwise combination
       of the following values. These permissions are interpreted
       identically to the read, write and execute permission bits
       of the file mode permission bits.

       ACL_READ
           The entity described by the ACL entry has read  access
           for a file.

       ACL_WRITE
           The entity described by the ACL entry has write access
           to a file.

       ACL_EXECUTE
           The entity described by  the  ACL  entry  has  execute
           access for a file.

       The  generic  ACL operations have the following effect for
       Posix-style ACLs.

       ACL_CMD_GET
           Depending on the a_type field of the buffer passed  by
           the acl parameter, get the ACL or the default ACL of a
           file.

       ACL_CMD_SET
           Depending on the a_type field of the buffer passed  by
           the acl parameter, set the ACL or the default ACL of a
           file.

       ACL_CMD_CLASS
           No class-specific behavior.

       ACL_CMD_QUOTA
           No class-specific behavior.

       For Posix-style ACLs, the following two additional  opera=AD
       tions are defined.

       ACL_CMD_POSIX_WHICH
           Query  which  ACL  types  are  defined for a file. The
           return value of the system call is a bitwise  combina=AD
           tion  of  ACL_TYPE_ACCESS (if the file has an ACL) and
           ACL_TYPE_DEFAULT (if the file has a default ACL). Only
           directories can have default ACLs.

       ACL_CMD_POSIX_SIZE
           Determine  the buffer size required (in bytes) for the
           ACL entries of the file. If the system call  succeeds,
           the     return     value     is    a    multiple    of
           sizeof(acl_posix_entry_t).  The a_entries buffer  must
           be  at  least  this  big  for a successive ACL_CMD_GET
           operation to succeed.


RETURN VALUE
       On success, a value >=3D 0 is  returned.  On  error,  -1  is
       returned, and errno is set appropriately.

       For  the  ACL_CLASS_POSIX class, the operations return the
       following values.

       ACL_CMD_GET
           On success, the  number  of  entries  in  the  ACL  is
           returned. On error, -1 is returned.

       ACL_CMD_SET
           On success, 0 is returned. On error, -1 is returned.

       ACL_CMD_CLASS
           If   the   a_class  field  is  ACL_CLASS_POSIX,  0  is
           returned. Otherwise, -1 is returned, and errno is  set
           to EINVAL.

       ACL_CMD_QUOTA
           On  success,  the number of bytes allocated for access
           control lists is returned. On error, -1 is returned.

       ACL_CMD_POSIX_WHICH
           On success, a bitwise combination  of  ACL_TYPE_ACCESS
           and  ACL_TYPE_DEFAULT  is  returned.  On  error, -1 is
           returned.

       ACL_CMD_POSIX_SIZE
           On success, the minimum number of bytes  required  for
           the  a_entries  buffer  to  hold  all  ACL  entries is
           returned. On error, -1 is returned.


EXAMPLE
       The following piece of code copies a Posix-style ACL  from
       ``file1''  to  ``file2''  (all  error handling omitted for
       brevity).

              #include <acl/acl.h>
              #include <acl/acl_posix.h>

              acl_posix_t posix_acl;
              memset(&posix_acl, 0, sizeof(acl_posix_t));
              posix_acl.a_class =3D ACL_CLASS_POSIX;
              posix_acl.a_type =3D ACL_TYPE_ACCESS;

              kacl("file1", ACL_CMD_POSIX_SIZE,
                   &posix_acl, sizeof(acl_posix_t));
              posix_acl.a_entries =3D (acl_posix_t *)malloc(posix_acl.a_s=
ize);
              kacl("file1", ACL_CMD_GET,
                   &posix_acl, sizeof(acl_posix_t));
              kacl("file2", ACL_CMD_SET,
                   &posix_acl, sizeof(acl_posix_t));


AUTHOR
       Andreas Gruenbacher, <a.gruenbacher@computer.org>.

       Please send your bug reports, suggested features and  com=AD
       ments to the above address.


SEE ALSO
       getfacl(1), setfacl(1), acl(5)

       Posix 1003.1e DS17 ACL library functions, <sys/acl.h>.

       Posix        1003.1e        Draft       Standard       17,
       http://www.guug.de/~winni/posix.1e/download.html


Andreas Gruenbacher      ACL System Calls                       1



--------------B9FF50AC2BDFD1474904BE62--

-------------------------------------------------------------------------
Linux ACL Developers List ---  http://acl.bestbits.at/

To unsubscribe, send a message with `unsubscribe acl-devel'
in the message body to majordomo@bestbits.at.
-------------------------------------------------------------------------