This is meant to be an informative document of the current behavior of OpenAFS file servers’ permission management logic. It is being written in hopes of its ultimate utility towards a normative specification document.

Note

We will often need to refer to line numbers of the code; for the sake of consistency, we will always tag these with the git revision control hash (abbreviated, thankfully) so that there is no risk of ambiguity even as this document and the code undergo parallel revisions.

References are given by [git revision:]file name[:command], where “command” is either a line number or a / followed by a POSIX regex. Due to AFS source conventions, function names will often appear as “f.c:/^Func”.

Descriptive Vocabulary

The OpenAFS file server logic checks several bits of data within the system when it makes a permission decision. Below, we will use certain shorthands for these fields.

Optionally, the server may be compiled with -DUSE_GROUP_PERMS (it is not by default) which brings in additional checks of the UNIX group owner (GID) and permission flags (GMODE, part of the UNIX MODE bits: GROUPREAD, GROUPWRITE, GROUPREXEC) of the target of the operation.

Note that all other UNIX mode bits (S_IRWXO, S_ISVTX, and 010000 and above) are ignored. (If USE_GROUP_PERMS is disabled, which is the default, the S_IRWXG bits are also ignored.)

Permission Flags

OpenAFS defines several ACL flags. Much of this information is available in the manual pages for fs setacl and fs listacl but is reproduced here for completeness. Each directory object has its associated ACL, which is a collection of Positive and Negative Access List Entries, which are in turn a pair of a PTS identity and a set of permission flags.

The permission flags defined are as follows; in all cases, the direct object of the definition is restricted to those objects in the current directory.

Administrate

Adjust this ACL

Lookup

Enumerate the objects.

Delete

Remove objects.

Read

Fetch the contents of file objects.

Write

Mutate the contents of file objects.

Insert

Create new objects.

locK

Acquire locks on files.

A - H

Eight flag bits defined solely for user applications’ use. These are (intended to be) uninterpreted by AFS itself.

These flags are stored by the AFS file server in a 32-bit word thus (see libacl/prs_fs.h and 6e167d4:venus/fs.c:/^PRights [there is a patch pending that would make this libacl/aclprint.c]):

H

G

F

E

D

C

B

A

a

k

d

l

i

w

r

Unallocated bits are communicated during ACL operations but ignored during server processing (indeed, libacl/aclprocs.c:/^acl_Externalize_pr simply prints out the field with the sprintf format code %d; libacl/aclprocs.c:/^acl_Internalize_pr dually uses sscanf %d).

Interpreting an ACL

The AFS User Guide, in section “The AFS ACL Permissions”, details the process of computing the rights conferred by a given ACL a given PTS ID. A slight formalization is attempted here.

  1. The permissions of each entry which names either

    • the given ID explicitly or

    • a group to which that ID belongs

    are ORed together to compute positive permissions. That is, if any entry asserts a flag, that flag is asserted at the end of this scan.

  2. The same process is repeated on the negative ACL entries, computing a set of negative permissions.

  3. The final result is the postive permissions bitwise-anded with the negation of the negative permissions.

This is implemented in src/viced/afsfileprocs.c:/^GetRights.

Todo

Which has not yet been audited to verify its conformance.

Implicit Permissions

Default Permissions and Ownership

The act of creating an object is complicated and is orchestrated by src/viced/afsfileprocs.c:/^SRXAFSS_CreateFile or src/viced/afsfileprocs.c:/^SRXAFS_MakeDir as appropriate. See below for details, but an attempt at a short story is:

Client Operations

The current AFS file server RPC interface is defined in src/fsint/afsint.xg and enumerates the following 41 RPCs:

Many mutation calls (StoreStatus, CreateFile, Symlink, and MakeDir) take a struct AFSStoreStatus which specifies a bitmask of features to be changed, which is drawn from a set defined at 6e167d4:src/fsint/afsint.xg:116. Three flags concern us:

While the remainder (MODTIME, SETSEGSIZE, and FSYNC) do not.

Client Operations Vs Required Permissions

Update Internals

Before we discuss pre-flight permissions checks, we focus on src/viced/afsfileprocs.c:/^Update_TargetVnodeStatus, which serves to actually carry out writes to vnode status fields but also contains some permission logic. This function is called by most mutation functions:

  • common_StoreData64 at 6e167d4:src/viced/afsfileprocs.c:2989

  • SAFSS_StoreStatus at 6e167d4:src/viced/afsfileprocs.c:3200

  • SAFSS_CreateFile at 6e167d4:src/viced/afsfileprocs.c:3464

  • SAFSS_Symlink at 6e167d4:src/viced/afsfileprocs.c:4131

  • SAFSS_MakeDir at 6e167d4:src/viced/afsfileprocs.c:4489

This function modifies the request in several ways as a result of permissions:

  • If the originating call is StoreData64 (see 6e167d4:src/viced/afsfileprocs.c:1729 and following):

    • The setuid SPEC bit is cleared unless the requestor is an ADMIN.

    • If the server has been compiled -DCREATE_SGUID_ADMIN_ONLY (which it is, by default, at 6e167d4:src/viced/afsfileprocs.c:152), the setgid SPEC bit is cleared unless the requestor is an ADMIN.

  • If the originating call requests a set of ownership (UID) (by asserting AFS_SETOWNER in the incoming status mask; see 6e167d4:src/viced/afsfileprocs.c:1749 and following), the same tests and clearings as the previous point are applied.

    Note that changes of GID are always performed if requested, and will not cause any bits (most notably S_ISGID) to be cleared.

  • If the originating call requests a set of all MODE bits (by asserting AFS_SETMODE in the incoming status mask) AND the server is built with CREATE_SGUID_ADMIN_ONLY defined (which it is by default) AND the caller is not ADMIN, the MODE bits are restricted to the three RWX triples (i.e., all SPEC bits are cleared). This has the effect of prohibiting all users other than ADMIN from setting the masked bits. (See 6e167d4:src/viced/afsfileprocs.c:1767 and following.)

The contained permissions checks would all be overridden if the remote flag is set (which it isn’t in any existing call) as part of the effort towards RW replication.

Simpler Client Operations

A separate pre-flight permissions check exists for many operations, a relatively simple src/viced/afsfileprocs.c:/^CheckWriteMode, which succeeds so long as the operation is targeted at a read-write volume, the caller has the required rights (as indicated in call) in the containing directory ACL, and either the target is a directory or the OWNERWRITE MODE bit is set. In particular,

  • RemoveFile requires delete rights (at 6e167d4:src/viced/afsfileprocs.c:3307),

  • CreateFile requires insert rights (at 6e167d4:src/viced/afsfileprocs.c:3488);

  • Rename performs two such calls, requiring delete rights in the old directory (at 6e167d4:src/viced/afsfileprocs.c:3644) and insert rights in the new (at 6e167d4:src/viced/afsfileprocs.c:3647) (Note that these may be the same!),

  • Symlink requires insert rights in the directory where the link will be created (at 6e167d4:src/viced/afsfileprocs.c:4094),

  • Link requires insert rights in the directory where the link will be created (at 6e167d4:src/viced/afsfileprocs.c:4276),

  • RemoveDir requires delete rights of the containing directory (at 6e167d4:src/viced/afsfileprocs.c:4613),

  • MakeDir can be built with one of two permissions models (see 6e167d4:src/viced/afsfileprocs.c:4455):

    • Require both insert and write rights in the containing directory, if built with -DDIRCREATE_NEED_WRITE (not default), or

    • Require just insert rights, otherwise.

    By default, the latter strategy is used. The justification for the former strategy hinged on the old implicit Administrate permission given to the owner of a directory, which is no longer the case (see Implicit Admin on Dir).

Complex Client Operations

A single function, src/viced/afsfileprocs.c:/^Check_PermissionRights, contains the permission logic for the ten calls comprising fetch and set of data, ACL, and status:

  • FetchData64 (and FetchData) at 6e167d4:src/viced/afsfileprocs.c:2325

  • FetchACL at 6e167d4:src/viced/afsfileprocs.c:2466

  • FetchStatus at 6e167d4:src/viced/afsfileprocs.c:2544

  • BulkStatus at 6e167d4:src/viced/afsfileprocs.c:2644

  • InlineBulkStatus at 6e167d4:src/viced/afsfileprocs.c:2788

  • StoreData64 (and StoreData) at 6e167d4:src/viced/afsfileprocs.c:2956

  • StoreACL at 6e167d4:src/viced/afsfileprocs.c:3100

  • StoreStatus at 6e167d4:src/viced/afsfileprocs.c:3186

The operation of this pre-flight test is somewhat opaque. Here is our current best attempt at its description:

  • Read operations are a mess; see 6e167d4:src/viced/afsfileprocs.c:1030 and following. The code is a series of checks for reasons for the operation to fail.

    • Reading the contents of directories or symlinks fails if the ACL does not grant r, -DADMIN_IMPLICIT_LOOKUP is defined and the client is not an ADMIN, and the client is not the VOLUID.

      Phrased positively, this succeeds if the ACL grants r, -DADMIN_IMPLICIT_LOOKUP is defined and the client is an ADMIN, or the client is the VOLUID.

    • Reading the contents of files fails under the same conditions as for directories, as well as the following conditions:

      • -DUSE_GROUP_PERMS is not in effect and the client does not match UID and the client is not an ADMIN and the MODE bits do have OWNERREAD or OWNEREXEC asserted. (6e167d4:src/viced/afsfileprocs.c:1067)

        This is documented as a “kludge” to handle the case when MODE is 0 (possibly from creation) and the UID is set incorrectly.

        Note

        That is, in net, AFS allows, in addition to administrator and owner, any user’s read request if there are no read UMODE bits asserted. This is, shall we say, a litte different from the usual semantics of UMODE.

      • -DUSE_GROUP_PERMS being in effect generalizes this test…

        Todo

        working here

    • Reading an ACL or status information while not being an ADMIN requires the same conditions as reading the contents of the object, as if it were a directory. (Note that this fact is confusingly encoded in the implementation as || VanillaUser(client).)

    • Reading an ACL or status information while being an ADMIN will never fail.

  • Write operations are no better; see 6e167d4:src/viced/afsfileprocs.c:1079 and following.

    • A store of data to a file, when client matches UID and the ACL grants the client i, is permitted (unless the server is readonly).

    • A store of stat metadata to a file, when client matches UID and the ACL grants the client i, is permitted on a non-readonly server if either:

      • the UID and GID are not being modified.

      • the client is an ADMIN.

    • All other non-data stores are explicitly permitted if the client is an ADMIN (6e167d4:src/viced/afsfileprocs.c:1098) even if the server is readonly.

    • All other stores fail if the server is readonly. (All subsequent tests of this are superfluous and elided from this description.)

    • A store of an ACL is permitted only if the ACL grants a or the client matches the VOLUID. (6e167d4:src/viced/afsfileprocs.c:1107)

    • A store of status which changes UID or GID will fail unless the client is an ADMIN (6e167d4:src/viced/afsfileprocs.c:1111)

    • A store which mutates the SPEC bits S_ISUID or S_ISGID will fail unless the client is an ADMIN (6e167d4:src/viced/afsfileprocs.c:1123)

    • A store of data will fail unless the ACL grants the client w (6e167d4:src/viced/afsfileprocs.c:1142)

    • -DUSE_GROUP_PERMS induces some complexity at this point…

      Todo

      oh yeah, that

    • A store of data to a non-directory (i.e. file or symlink) without the UMODE including write will fail unless the client is an ADMIN (6e167d4:src/viced/afsfileprocs.c:1167)

    • A store of status to a directory will fail without the ACL granting both di (6e167d4:src/viced/afsfileprocs.c:1182)

    • A store of status to a file will fail without the ACL granting w (6e167d4:src/viced/afsfileprocs.c:1186)

    • A store that has not yet failed will succeed.

Todo

Working here.