Quotas and access control for NewCore


History:

  0.01  09-Feb-94  First notes following discussions with JRe
  0.02  10-Feb-94  Includes results of further discussions with JRe
  0.03  11-Feb-94  Section 2 replaced following meeting with JRe, JRo, KR
                   New sections 3 & 4 give draft proposal for access control
  0.04  02-Mar-94  Outstanding issue added after discussion with OL


Outstanding issues:

  Should we consider making access control *much* simpler? Two classes of
   people, owner can always read/write, just three states for public access
   control. Perhaps this coupled with controlled sharing of file hierarchies
   (a la Acorn Access) is all that is required.



1  What support should NewCore provide?


We make the assumption that any system for controlling allocation of disc
space or access to files will be based on file ownership, and so the minimal
level of support from NewCore must be to provide facilities for the storage
and retrieval of an object's "owner".

This minimal level of support is sufficient to support, for example, file
server software which would take responsibility for:

  - authenticating users ("logon")
  - maintaining allocations and quotas on a per-user basis
  - setting a file's owner according to the user who created it
  - checking access rights

However, although it is sufficient it may not be adequate. Consider how
server software might go about checking whether user JOHN has the right to
read a file $.dir1.dir2.notes: to check this out the server must ask FSw for
public and owner access rights (and owner) for each of $, $.dir1, $.dir1.dir2
and $.dir1.dir2.notes in turn.

This example strongly suggests that NewCore itself should take responsibility
for checking access rights, and thus needs to know at all times who is the
current "user".


In theory, such support is not necessary for quotas: server software can
maintain private tables of space used, since all filing system requests
controlled by the server pass through it. In practice, it is far safer and
more convenient if space accounting takes place inside NewCore; other
advantages include:

  - "hidden space" (directories, part-filled sectors etc.) can be accounted
     for, if desired;

  - quota support on a stand-alone machine is feasible (this could be useful
     in a cooperative domestic or classroom context where each user of the
     machine is allocated his own space).



2  Passing the user to NewCore


We assume the existence of a separate service module which maintains
information about the current user, and which provides a SWI to gain access
to this information; NewCore will call this SWI whenever it needs to find
out who is the current user.

Such a service module might provide calls along the following lines:

  token = Authenticate_User(user_name, password, finger_prints, ...)
  Set_User(token); /* sets new current user and preserves previous user */
  Restore_User();  /* restores previous current user (nesting?) */
  Get_UserName(buff, len);  /* to read current user's name */

Note the use of tokens which helps to make it possible to switch amongst a
number of previously authenticated users quickly; for example, file server
software will need to set a different current user prior to each filing
system operation and then restore the previous user afterwards.



3  Access control models - a brief survey


In the Unix model, a user (strictly a process) may be able to act in one or
more of the following roles with respect to a particular file or directory:

  - as owner - if his userid is the same as that recorded as the owner of the
               object;
  - as group member - if he belongs to a group whose groupid is the same as
               that recorded as the group associated with the object;
  - as a member of the public.

Associated with the object are three access control bits for each role; these
are as follows:

  - read access    => can read a file
                      can list the contents of a directory (ie determine the
                       names of the objects within the directory)

  - write access   => can write to, extend or truncate a file
                      can create or delete objects within a directory

  - execute access => can load a file to execute as a program
                      can look within a directory for a specific object (ie
                       you can access the object if you know its name)


RISC OS has a different model. Detailed behaviour is filing-system dependent,
but the basic options available to play with are defined by eight attribute
bits held with each object. The following notes are gleaned mostly from the
PRM, backed-up by some experimentation.

FileSwitch defines these eight attribute bits as follows:

  bit        meaning if set

   0         owner read access
   1         owner write access
   2         "owner execute only - BBC ADFS - or private - SJ Research" [??]
   3         owner locked against deletion
   4         public read access
   5         public write access
   6              undefined
   7         public locked against deletion

At present, the Filer allows just 5 of these bits - 0,1,3,4,5 - to be set.

The PRM also states:

  - FileCore-based filing systems ignore bits 4 and 5
  - Bits 2, 6 and 7 may be used in future for expansion [implying that they
     are not used at present]

However, experiment suggests that bit 7 is always 0 under FileCore, and is
always 1 under NetFS/Level 4; furthermore, if you copy a file from a L4FS to
your hard disc, it retains bit 7 - but this has no effect.

Tentative conclusions are:

  a) Only the following five bits are used by current filing systems:

            0  -  owner read
            1  -  owner write
            3  -  locked
            4  -  public read
            5  -  public write

  b) At least one extra bit (bit 6) is available for a new use by NewCore.

  c) It might be wise to leave bits 2 and 7 well alone!


The manner in which each filing system determines whether an access is to be
treated as an "owner" or "public" access is a property of the filing system:

  ADFS treats all accesses as owner accesses.

  NetFS treats accesses via "&" as owner access and others as public access.

  NFS determines the user from the mount point, and stores that user as the
   owner of a file when it is created. An owner access is one where the user
   and owner match.


I think all filing systems interpret the three access permissions for files
in the same way, with each access type treated independently.


On the other hand, interpretation of access permissions on directories is
far from universal:

  ADFS pays no attention.

  NFS supports whatever the server supports; for example, it is normally the
   case that a user can only create or delete a file if he has write access
   to the directory to contain (or containing) the file.


Where does all this leave NewCore?

  - NewCore can use at least one extra access permission bit if it wishes to.

  - NewCore can interpret access permissions on directories in whatever way
     it pleases.



4  Access control model for NewCore


There are three questions to answer:

  (1) Should NewCore support roles other than "owner" and "public"?

  (2) How should NewCore interpret the five pre-defined access control bits?

  (3) Are there other access control bits which should be supported by
       NewCore?


4.1  New roles

One obvious contender is "member of a group", as provided by Unix systems.
The "group" concept might be implemented as an extension to the "user"
service module described in section 3, with a new interface for NewCore to
call:

    BOOL Is_User_Member_Of_Group(group_name)

and a further set of procedures to set the current group, and to create and
manage tables of group membership.

On the other hand, other modern filing systems have recognised that the
group idea is often not powerful enough to be useful, and have instead
provided more flexible systems in the form of access control lists (where
each file or directory is associated with a list of permissions of the form
<user_name or group_name>  <access permission>).

We do not propose that NewCore support ACLs, and feel that the benefits of
the Unix "group" concept are small in relation to the effort required to
support it; so we propose that no new roles be added to NewCore.


4.2  Interpretation

We propose that the current interpretations of read, write and locked apply
to files, and that read and write permissions on directories are interpreted
as under Unix:

  - read   => can read a file
              can list the contents of a directory

  - write  => can write to, extend or truncate a file
              can create or delete* objects within a directory

                [* subject to the locked bit on the objects concerned]

  - locked => cannot delete a file

By analogy, the locked bit on a directory should prevent the user from
deleting it, but this is already the case unless it has no entries.

 [ Having a bit which says "Cannot delete this directory even if it is empty"
   is consistent but not very useful - perhaps this bit could be redefined
   to support the Unix idea of "only permit access to explicitly-named
   objects". ]


4.3  Other access control bits

Possible candidates are:

  - append    => can add data to the end of a file (but cannot alter existing
                  data within it)
                 can create (but not delete) objects within a directory

  - execute   => can load as program image (but cannot read as data)

  - invisible => do not display in Filer windows

Note that only the first of these can be enforced by NewCore itself.

For the sake of argument, I propose that we use bits 2 and 6 of the current
attribute word for the owner and public "append" bit, and leave the other
bits for possible inclusion in an extended attribute area which will be
introduced with NewCore and which will have its own new FileSwitch interface.


4.4  Extensible access checking

We have noted previously that access checking by higher-level software is
likely to be unacceptably slow - indeed, this is one of the reasons for
deciding to include such checks inside NewCore. On the other hand, we
recognize that the current proposals may appear dated within the lifetime of
NewCore, and that it may be necessary to provide more sophisticated checks
in the future; for example, new requirements may arise from our experience
with shared networking products (such as Acorn Access) as "workgroup"
computing becomes more common-place.

These requirements can be met if we provide the right "hooks" - perhaps by
isolating access checking in a separate module which registers with NewCore
at start-up time [is this the correct architecture?].
