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.
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”.
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.
Client membership an “administrative” group, which defaults to
system:administrators(PTS ID well-known as
-204). (ADMIN) (See
6e167d4:src/viced/viced.c:/SystemIdfor details of group selection.)
Client rights as specified in the ACL of the directory containing the target. (ACL)
The UNIX owner UID field (holding a PTS ID) of the target of the operation. (UID)
The UNIX user permission flags of the target of the operation. (UMODE, part of the UNIX MODE bits:
The UNIX owner UID field of the root directory of the volume containing the target. This field holds a PTS ID which is said to be the volume owner. (VOLUID)
The UNIX mode special bits (SPEC), notably
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:
GROUPREXEC) of the target of the
Note that all other UNIX mode bits (
and above) are ignored. (If
USE_GROUP_PERMS is disabled, which is the
S_IRWXG bits are also ignored.)
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.
Adjust this ACL
Enumerate the objects.
Fetch the contents of file objects.
Mutate the contents of file objects.
Create new objects.
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
6e167d4:venus/fs.c:/^PRights [there is a patch
pending that would make this
Unallocated bits are communicated during ACL operations but ignored during
server processing (indeed,
prints out the field with the
sprintf format code
libacl/aclprocs.c:/^acl_Internalize_pr dually uses
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.
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.
The same process is repeated on the negative ACL entries, computing a set of negative permissions.
The final result is the postive permissions bitwise-anded with the negation of the negative permissions.
This is implemented in
Which has not yet been audited to verify its conformance.
The insert flag is intended to allow users to also establish the contents of file objects; as such it confers the rights to write to file objects whose UID matches the client’s PTS ID. (Specified in the manual for
6e167d4:src/viced/afsfileprocs.c:1080) There are some caveats relevant here:
The manual pages describe “dropbox” permissions (list & insert) as conferring the ability to write a file’s contents once and never again. This is at best viewed as a suggestion of client cache manager behavior; it is not possible to implement this in OpenAFS as the server has no notion of opened or closed files, so the description given in this document above is more accurate from a server and protocol perspective.
It appears to be permitted, from the documentation of
fs setaclthat a server may, but is not obligated to, refuse read requests by anonymous clients of files whose containing directory confers “dropbox” permissions to any PTS ID. This does not appear to be implemented in the present OpenAFS source code, as of
The same paragraph as above suggests that the server is permitted to fail creation or write requests from anonymous clients even if the permissions calculated would (otherwise) permit it. This does not appear to be implemented in the present OpenAFS source code, as of
The VOLUID PTS ID implicitly has Administrate permission on all directories contained in that volume. This cannot be removed, even with negative access list entries. See the call to
6e167d4:src/viced/afsfileprocs.c:1108in the store (and
CHK_STOREACL) branch of
In prior releases, the UID PTS ID of each directory also had implicit Administrate permission within that directory, but this is no longer true.
Members of the administrative group (ADMIN) implicitly have all permissions specified by the server’s
-implicitargument, which defaults to Lookup. See
6e167d4:src/viced/viced.c:133. Note that this impacts every condition that tests ACL in this document.
Members of the administrative group (ADMIN) may additionally implicitly have Lookup permission for certain tests if the server is compiled with
-DADMIN_IMPLICIT_LOOKUP(not default). (This is not implemented in
/^GetRightsand so does not affect the use of ACL)
Members of the administrative group (ADMIN) additionally implicitly have Administrate permission (
/^Check_PermissionRights) and others. Membership testing is performed by
src/viced/viced.c:/^VanillaUserand this is called in several places. (This, too, is not implemented in
/^GetRightsand so does not affect the use of ACL)
Which should be enumerated here!
Default Permissions and Ownership¶
The act of creating an object is complicated and is orchestrated by
src/viced/afsfileprocs.c:/^SRXAFS_MakeDir as appropriate. See below for
details, but an attempt at a short story is:
Whenever a directory is created, it inherits the ACL from its parent directory. (
Whenever an object of any type is created
The GID is inherited from the parent object: (overseen by
src/viced/afsfileprocs.c:/^Alloc_NewVnode; see in particular
The MODE is set to
0777. That is, the UMODE and GMODE bits are made all-permissive; the
S_IRWXObits are also all-permissive, but recall that these bits are ignored. (
src/viced/afsfileprocs.c:/^Update_TargetVnodeStatus, in particular
The client PTS ID is used to set the UID. (
src/viced/afsfileprocs.c:/^Update_TargetVnodeStatus, in particular
All creation operations allow the client to additionally specify metadata about the object to be created, notably including UID, GID, and MODE. If requested at creation, these operations will be performed, with some caveats: UID and GID may be changed arbitrarily, but MODE will always be restricted to a subset of
0777unless the requesting client is an ADMIN. For details, see the internals of vnode update.
This should perhaps be moderately alarming!
Because the create operations
CreateFileall simply call
CheckWriteModeand then pass their given
struct AFSStoreStatusparameters to
Update_TargetVnodeStatus, it is possible to create objects with arbitrary UID and GID; the checks that would be done on a
Check_PermissionRights) are bypassed.
It is worth pointing out, perhaps, that the only reason that existing AFS deployments end up with UID being equal to the creating client’s PTS ID is because the existing CMs do not request
CreateFile. They do, however, request
SETGROUP, which is permitted, making a likely laughingstock of most GID values.
The author of this document is deeply confused as to why
Check_PermissionRightsthen refuses to change GID fields (and possibly UID fields as well!); see below.
The current AFS file server RPC interface is defined in
src/fsint/afsint.xg and enumerates the following 41 RPCs:
Data fetch calls:
Metadata fetch calls:
Data store calls:
Metadata store calls:
“Old” locking calls:
“New” locking calls:
Callback manipulation calls:
Many mutation calls (
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:
SETOWNERto adjust the UID
SETGROUPto adjust the GID
SETMODEto adjust the MODE
While the remainder (
FSYNC) do not.
Client Operations Vs Required Permissions¶
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:
This function modifies the request in several ways as a result of permissions:
If the originating call is
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_SETOWNERin the incoming status mask; see
6e167d4:src/viced/afsfileprocs.c:1749and 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_SETMODEin the incoming status mask) AND the server is built with
CREATE_SGUID_ADMIN_ONLYdefined (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
The contained permissions checks would all be overridden if the
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
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
MODE bit is set. In particular,
RemoveFilerequires delete rights (at
CreateFilerequires insert rights (at
Renameperforms 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!),
Symlinkrequires insert rights in the directory where the link will be created (at
Linkrequires insert rights in the directory where the link will be created (at
RemoveDirrequires delete rights of the containing directory (at
MakeDircan be built with one of two permissions models (see
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,
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:1030and 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
-DADMIN_IMPLICIT_LOOKUPis defined and the client is not an ADMIN, and the client is not the VOLUID.
Phrased positively, this succeeds if the ACL grants
-DADMIN_IMPLICIT_LOOKUPis 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_PERMSis not in effect and the client does not match UID and the client is not an ADMIN and the MODE bits do have
This is documented as a “kludge” to handle the case when MODE is
0(possibly from creation) and the UID is set incorrectly.
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_PERMSbeing in effect generalizes this test…
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
Reading an ACL or status information while being an ADMIN will never fail.
Write operations are no better; see
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
aor the client matches the VOLUID. (
A store of status which changes UID or GID will fail unless the client is an ADMIN (
A store which mutates the SPEC bits
S_ISGIDwill fail unless the client is an ADMIN (
A store of data will fail unless the ACL grants the client
-DUSE_GROUP_PERMSinduces some complexity at this point…
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 (
A store of status to a directory will fail without the ACL granting both
A store of status to a file will fail without the ACL granting
A store that has not yet failed will succeed.