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.
Client membership an “administrative” group, which defaults to
system:administrators
(PTS ID well-known as-204
). (ADMIN) (See6e167d4:src/viced/viced.c:/SystemId
for 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:
OWNERREAD
,OWNERWRITE
,OWNEREXEC
)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
S_ISUID
(04000
) andS_ISGID
(02000
).
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.
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 src/viced/afsfileprocs.c:/^GetRights
.
Todo
Which has not yet been audited to verify its conformance.
Implicit Permissions¶
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
fs setacl
sectionDROPBOXES
; CODE: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 setacl
that 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 of6e167d4
.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
6e167d4
.
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
VolumeOwner
at6e167d4:src/viced/afsfileprocs.c:1108
in the store (andCHK_STOREACL
) branch ofsrc/viced/afsfileprocs.c:/^Check_PermissionRights
.Note
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
-implicit
argument, which defaults to Lookup. See6e167d4:src/viced/afsfileprocs.c:778
(in/^GetRights
) and6e167d4: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/^GetRights
and so does not affect the use of ACL)Members of the administrative group (ADMIN) additionally implicitly have Administrate permission (
6e167d4:src/viced/afsfileprocs.c:1107
in/^Check_PermissionRights
) and others. Membership testing is performed bysrc/viced/viced.c:/^VanillaUser
and this is called in several places. (This, too, is not implemented in/^GetRights
and so does not affect the use of ACL)Todo
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:/^SRXAFSS_CreateFile
or
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. (
src/viced/afsfileprocs.c:/^SAFSS_MakeDir
, specifically6e167d4:src/viced/afsfileprocs.c:4484
.)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 particular6e167d4:src/viced/afsfileprocs.c:1921
).The MODE is set to
0777
. That is, the UMODE and GMODE bits are made all-permissive; theS_IRWXO
bits are also all-permissive, but recall that these bits are ignored. (src/viced/afsfileprocs.c:/^Update_TargetVnodeStatus
, in particular6e167d4:src/viced/afsfileprocs.c:1680
)The client PTS ID is used to set the UID. (
src/viced/afsfileprocs.c:/^Update_TargetVnodeStatus
, in particular6e167d4:src/viced/afsfileprocs.c:1681
)
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
0777
unless the requesting client is an ADMIN. For details, see the internals of vnode update.Warning
This should perhaps be moderately alarming!
Because the create operations
MakeDir
,Symlink
, andCreateFile
all simply callCheckWriteMode
and then pass their givenstruct AFSStoreStatus
parameters toUpdate_TargetVnodeStatus
, it is possible to create objects with arbitrary UID and GID; the checks that would be done on aStoreStatus
call (inCheck_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
SETOWNER
onCreateFile
. They do, however, requestSETGROUP
, which is permitted, making a likely laughingstock of most GID values.The author of this document is deeply confused as to why
Check_PermissionRights
then refuses to change GID fields (and possibly UID fields as well!); see below.
Client Operations¶
The current AFS file server RPC interface is defined in
src/fsint/afsint.xg
and enumerates the following 41 RPCs:
Data fetch calls:
FetchData
(130) andFetchData64
(65537)Metadata fetch calls:
FetchACL
(131) andFetchStatus
(132)Data store calls:
StoreData
(133) andStoreData64
(65538)Metadata store calls:
StoreACL
(134),StoreStatus
(135),BulkStatus
(155), andInlineBulkStatus
(65536).Deletion calls:
RemoveFile
(136) andRemoveDir
(142)Creation calls:
CreateFile
(137) andMakeDir
(141)Rename
(138)Link calls:
Symlink
(139),Link
(140), andDFSSymlink
(163)“Old” locking calls:
OldSetLock
(143),OldExtendLock
(144),OldReleaseLock
(145)“New” locking calls:
SetLock
(156),ExtendLock
(157),ReleaseLock
(158)Callback manipulation calls:
GiveUpCallBacks
(147)GiveUpAllCallBacks
(65539)CallBackRxConnAddr
(65541)Other:
GetStatistics
(146)GetVolumeInfo
(148)GetVolumeStatus
(149)SetVolumeStatus
(150)GetRootVolume
(151)CheckToken
(152)GetTime
(153)NGetVolumeInfo
(154)XStatsVersion
(159)GetXStats
(160)Lookup
(161)FlushCPS
(162)FsCmd
(220)GetCapabilities
(65540)
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:
SETOWNER
to adjust the UIDSETGROUP
to adjust the GIDSETMODE
to adjust the MODE
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
at6e167d4:src/viced/afsfileprocs.c:2989
SAFSS_StoreStatus
at6e167d4:src/viced/afsfileprocs.c:3200
SAFSS_CreateFile
at6e167d4:src/viced/afsfileprocs.c:3464
SAFSS_Symlink
at6e167d4:src/viced/afsfileprocs.c:4131
SAFSS_MakeDir
at6e167d4:src/viced/afsfileprocs.c:4489
This function modifies the request in several ways as a result of permissions:
If the originating call is
StoreData64
(see6e167d4: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, at6e167d4: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; see6e167d4: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 withCREATE_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. (See6e167d4: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 (at6e167d4:src/viced/afsfileprocs.c:3307
),CreateFile
requires insert rights (at6e167d4:src/viced/afsfileprocs.c:3488
);Rename
performs two such calls, requiring delete rights in the old directory (at6e167d4:src/viced/afsfileprocs.c:3644
) and insert rights in the new (at6e167d4: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 (at6e167d4:src/viced/afsfileprocs.c:4094
),Link
requires insert rights in the directory where the link will be created (at6e167d4:src/viced/afsfileprocs.c:4276
),RemoveDir
requires delete rights of the containing directory (at6e167d4:src/viced/afsfileprocs.c:4613
),MakeDir
can be built with one of two permissions models (see6e167d4:src/viced/afsfileprocs.c:4455
):Require both insert and write rights in the containing directory, if built with
-DDIRCREATE_NEED_WRITE
(not default), orRequire 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
(andFetchData
) at6e167d4:src/viced/afsfileprocs.c:2325
FetchACL
at6e167d4:src/viced/afsfileprocs.c:2466
FetchStatus
at6e167d4:src/viced/afsfileprocs.c:2544
BulkStatus
at6e167d4:src/viced/afsfileprocs.c:2644
InlineBulkStatus
at6e167d4:src/viced/afsfileprocs.c:2788
StoreData64
(andStoreData
) at6e167d4:src/viced/afsfileprocs.c:2956
StoreACL
at6e167d4:src/viced/afsfileprocs.c:3100
StoreStatus
at6e167d4: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 haveOWNERREAD
orOWNEREXEC
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
orS_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.