richacl (7) - Linux Manuals
richacl: Rich Access Control Lists
Command to display richacl
manual in Linux: $ man 7 richacl
NAME
richacl - Rich Access Control Lists
DESCRIPTION
Rich Access Control Lists (RichACLs) are an extension of the traditional POSIX
file permission model to support
NFSv4 Access Control Lists <URL:
https://tools.ietf.org/rfc/rfc5661.txt >
on local and remote-mounted filesystems.
A RichACL can always be translated into an equivalent NFSv4 ACL which grants
the same permissions.
RichACLs can be enabled on supported local filesystems (currently, ext4 and
XFS). The in-kernel NFSv4 server and client also include RichACL support.
Enabling RichACLs disables POSIX Access Control Lists; the two ACL models
cannot coexist on the same filesystem.
When used on a filesystem that does not support RichACLs, the
getrichacl(1)
and
setrichacl(1)
utilities will operate on the file permission bits instead:
getrichacl(1)
will display the file permission bits as a RichACL; when a RichACL
is set with
setrichacl(1)
which can be represented exactly by the file permission bits,
setrichacl(1)
will set the file permission bits instead. An attempt to set a RichACL that
cannot be represented exactly by the file permission bits results in an error.
This man-page describes the structure, concepts and algorithms involved in RichACLs. For examples, please refer to
richaclex(7).
Structure of RichACLs
RichACLs consist of a number of ACL entries, three file masks, and a set of
flags specifying attributes of the ACL as a whole (by contrast with the
per-ACL-entry flags described below).
Each of the ACL entries allows or denies some permissions to a particular user,
group, or special identifier. An ACL entry consists of four fields:
- •
-
A tag which specifies the user, group, or special identifier the entry applies
to. Special identifiers can be the file owner
(owner@),
the owning group
(group@),
or everyone
(everyone@).
- •
-
A set of permissions the entry allows or denies.
- •
-
A set of flags that indicate whether the user or group identifier is mapped or
unmapped, and whether the entry has been and can be inherited.
- •
-
A type field indicating whether the entry allows or denies the permissions
specified in the second field.
The owner, group, and other file masks further control which permissions the
ACL grants, subject to the
masked (m)
and
write_through (w)
ACL flags: when the permissions of a file or directory are changed with
chmod(2),
the file masks are set based on the new file mode, and the
masked
and
write_through
ACL flags are set. Likewise, when a new file or directory inherits an ACL from
its parent directory, the file masks are set to the intersection between the
permissions granted by the inherited ACL and the
mode
parameter as given to
open(2), mkdir(2),
and similar, and the
masked
ACL flag is set. In both cases, the file masks limit the permissions that the
ACL will grant.
The purpose of the file masks is to allow traditional POSIX applications which
are unaware of RichACLs to place limits on the permissions granted by the
RichACL without causing the ACL entries to be modified. Without the file mask,
the only alternative would be for the kernel to directly modify the ACL
entries. However, this latter approach could have a "hysteresis effect",
whereby a RichACL-unaware application that performs a transition from one file
mode to another file mode and then back to the original file mode could cause
destruction of the permission information in ACL entries. When creating files
or directories, the
mode
parameter to
open(2), mkdir(2),
and similar would have the same effect.
Note that entries with the identifier
everyone@
apply to all processes, whereas the "other" file permissions and
"other" (ACL_OTHER) entries in POSIX ACLs apply to all processes
which are not the owner, are not in the owning group, and do not match a user
or group mentioned in the ACL.
Unlike POSIX ACLs, RichACLs do not have separate "access" ACLs that
define the access permissions and "default" ACLs that define the
inheritable permissions. Instead, flags on each ACL entry determine whether
the entry is effective during access checks and/or inheritable.
ACL flags
The following ACL flags are defined:
- masked (m)
-
When set, the file masks define upper limits on the permissions the ACL may
grant. When not set, the file masks are ignored.
- write_through (w)
-
When this flag and the
masked
flag are both set, the owner and other file masks define the actual permissions
granted to the file owner and to others instead of defining an upper limit.
When the
masked
flag is not set, the
write_through
flag has no effect.
- auto_inherit (a)
-
Automatic Inheritance is enabled. See
Automatic Inheritance.
- protected (p)
-
The ACL is protected from modification by Automatic
Inheritance.
- defaulted (d)
-
Indicates that the ACL has been assigned in an application-dependent way when
the file or directory was created; it has neither been inherited nor set
explicitly. ACLs of files created on Linux will never have the
defaulted
flag set, but the flag may be set on files created on or copied over from
other operating systems. When this flag is set for an ACL, Automatic
Inheritance will completely replace the ACL.
ACL entry flags
The following flags on ACL entries are defined:
- file_inherit (f)
-
When this flag appears in the ACL entry of a directory, then:
-
- •
-
That entry is inherited by new files created in the directory such that the
permissions of the entry apply to the file (the inheritance flags of the
inherited entry are cleared).
- •
-
The entry is is inherited by new subdirectories created in the directory such
that the permissions of the entry will apply to new files created in the
subdirectory.
- dir_inherit (d)
-
When this flag appears in the ACL entry of a directory, then that entry is
inherited by new subdirectories created in the directory such that the
permissions of the entry apply to the subdirectory (the
inherit_only
flag is cleared).
- no_propagate (n)
-
Inheritance stops at the next subdirectory level. When a file or directory
inherits an entry that has this flag set, the
file_inherit, dir_inherit, no_propagate, and inherit_only
flags are cleared.
- inherit_only (i)
-
The entry defines inheritable permissions only and is ignored for access
checking. When a file or directory inherits an entry that has this flag set,
the flag is cleared.
- inherited (a)
-
The entry has been automatically inherited from the parent directory.
- unmapped (u)
-
The user or group identifier is a textual string and is not mapped to a numeric
user or group identifier. ACLs with unmapped identifiers can occur on NFSv4
mounted filesystems when the client cannot determine numeric user or group
identifiers for some of the NFSv4 user [at] domain or group [at] domain who values. They
cannot be assigned to local files or directories.
Permissions
The following permissions are defined for RichACL entries and for the three
file masks:
- read_data / list_directory (r)
-
For a file: read the data of the file.
For a directory: list the contents of the directory.
- write_data / add_file (w)
-
For a file: modify the data of the file; does not include opening the file in
append mode.
For a directory: add a new file in the directory.
- append_data / add_subdirectory (p)
-
For a file: open the file in append mode.
For a directory: create a subdirectory in the directory.
- execute (x)
-
For a file: execute the file.
For a directory: traverse (search) the directory.
- delete_child (d)
-
Delete a file or directory within a directory. This permission is meaningful
only for directories.
- delete (D)
-
Delete the file or directory.
- read_attributes (a)
-
Read basic attributes of a file or directory (see
stat(2)).
This permission is defined by NFSv4. It is stored, but ignored. Reading basic
attributes of files and directories is always allowed on Linux.
- write_attributes (A)
-
Change the times associated with a file or directory to an arbitrary value.
This permission is always implicitly granted to the file owner.
- read_acl (c)
-
Read the ACL of a file or directory. Like reading the basic file attributes (the
read_attributes
permission), reading ACLs is always allowed on Linux.
- write_acl (C)
-
Change the ACL or file mode of a file or directory.
- write_owner (o)
-
Take ownership of a file or directory. Change the owning group of a file or
directory to a group of which the calling process is a member.
-
-
read_named_attrs (R), write_named_attrs (W), synchronize (S), write_retention (e), write_retention_hold (E)
These permissions are defined by NFSv4 and NFSv4.1. They are stored, but ignored.
For the
r, w, and p
permissions, which have different long forms for files and directories, the
getrichacl(1)
utility will output the appropriate form(s) depending on the context.
The
setrichacl(1)
utility will accept either form for any file type.
Text form
The common textual representation of a RichACL consists of the colon-separated
fields of the ACL flags, file masks, and ACL entries in the following
format:
- flags:acl_flags
-
The ACL flags.
- owner:perm::mask, group:perm::mask, other:perm::mask
-
The file masks and their permissions.
- who:perm:flags:allow, who:perm:flags:deny
-
For each ACL entry, who the entry applies to, the permissions of the entry, the
entry flags, and the entry type. The who field is one of the following:
-
- •
-
One of the special identifiers:
owner@, group@, or everyone@,
- •
-
A
user: or u:
prefix followed by a user name or user ID that designates a specific user,
- •
-
A
group: or g:
prefix followed by a group name or group ID that designates a specific group.
The ACL flags, file masks, and ACL entries are comma, whitespace, or newline
separated.
Flags and permissions have single-letter as well as long forms, as listed under
ACL flags,
ACL entry flags,
and
Permissions.
When the single-letter forms are used, the flags or permissions are
concatenated. When the long forms are used, the flags or permissions are
separated by slashes. To align permissions or flags vertically, dashes can be
used for padding.
Setting and modifying file permissions
The access permissions for a file can either be set by assigning an Access
Control List
(setrichacl(1))
or by changing the file mode permission bits
(chmod(1)).
In addition, a file can inherit an ACL from its parent directory at creation
time as described under
Permissions at file-creation time.
Assigning an Access Control List
When assigning an ACL to a file, unless explicitly specified, the owner, group,
and other file masks will be computed from the ACL entries as described in
the section
Computing the maximum file masks.
The owner, group, and other file mode permission bits are then each set from
the owner, group, and other file mask as follows:
- •
-
If the file mask includes the
r
permission, the read
file mode permission bit will be set.
- •
-
If the file mask includes the
w
or
p
permission, the write file mode permission bit will be set.
- •
-
If the file mask includes the
x
permission, the execute file mode permission bit will be set.
If the ACL can be represented exactly by the file mode permission bits, the
file permission bits are set to match the ACL and no ACL is stored. (When the
ACL of a file is requested which doesn't have an ACL, the file mode permission
bits are converted into an equivalent ACL.)
Changing the file mode permission bits
When changing the file mode permission bits with
chmod(1),
the owner, group, and other file permission bits are set to the permission bits
in the new mode, and the owner, group, and other file masks are set based on
the new mode bits as follows:
- •
-
If the read bit in a set of permissions is set, the
r
permission in the corresponding file mask will be set.
- •
-
If the write bit in a set of permissions is set, the
w
and
p
permissions in the corresponding file mask will be set.
- •
-
If the execute bit in a set of permissions is set, the
x
permission in the corresponding file mask will be set.
In addition, the
masked
and
write_through
ACL flags are set. This has the
effect of limiting the permissions granted by the ACL to the file mode
permission bits; in addition, the owner is granted the owner mode bits and
others are granted the other mode bits. If the
auto_inherit
flag is set, the
protected
flag is also set to prevent the Automatic Inheritance algorithm from modifying
the ACL.
Permissions at file-creation time
When a directory has any inheritable ACL entries, the following
happens when a file or directory is created inside that directory:
- 1.
-
A file created inside that directory will inherit all of the ACL entries that
have the
file_inherit
flag set, and all inheritance-related flags in the inherited entries flag will
be cleared.
-
A subdirectory created inside that directory will inherit all of the ACL
entries that either have the
dir_inherit
flag set, or the
file_inherit
flag set and the
no_propagate
flag not set. Entries whose
dir_inherit
flag is set will have their
inherit_only
flag cleared, and entries whose
dir_inherit
flag is not set will have their
inherit_only
flag set. Finally, entries whose
no_propagate
flag is set will have all inheritance-related flags cleared.
- 2.
-
If the parent directory's ACL has the
auto_inherit
flag set, then the inherited ACL will have its
auto_inherit
flag set, and all entries will have their
inherited
flag set. Otherwise, the
auto_inherit
and
inherited
flags are cleared.
- 3.
-
The three file masks are computed from the inherited ACL as described in
the section
Computing the maximum file masks.
- 4.
-
The three sets of permissions for the owner, the group, and for others in
the mode parameter as given to
open(2),
mkdir(2),
and similar are converted into sets of RichACL permissions. The correspondence
between mask flags and RichACL permission bits is described in the section
Changing the file mode permission bits.
Any RichACL permissions not included in those sets are
removed from the owner, group, and other file masks. The file mode permission
bits are then computed from the file masks as described in the section
Assigning an Access Control List.
The process umask (see
umask(2))
is ignored.
- 5.
-
The
masked
ACL flag is set. The
write_through
ACL flag remains cleared. In addition, if the
auto_inherit
flag of the inherited ACL is set, the
protected
flag is also set to prevent the Automatic Inheritance algorithm from modifying
the ACL.
When a directory does not have inheritable ACL entries, files and directories
created inside that directory will not be assigned Access Control Lists and the
file mode permission bits will be set to (mode & ~umask) where
mode is the mode argument of the relevant system call and umask is
the process umask (see
umask(2)).
Automatic Inheritance
Automatic Inheritance is a mechanism that allows permission changes to
propagate from a directory to files and subdirectories inside that directory,
recursively. Propagation is carried out by the process changing the directory
permissions (usually,
setrichacl(1));
it happens without user intervention albeit not entirely automatically.
A significant limitation of the Automatic Inheritance feature is that this
mechanism works only as long as files are created without explicitly specifying
the file permissions to use. The standard system calls for creating files and
directories
(open(2),
mkdir(2),
mknod(2),
and so on) all have mandatory mode parameters which define the maximum allowed
permissions of the new files. To take account of this restriction, the
protected
ACL flag must be set if the
inherited
flag is set. This effectively disables Automatic Inheritance for that
particular file.
Notwithstanding the aforementioned limitation, Automatic Inheritance still
remains useful for network protocols like NFSv4 and SMB, which both support
creating files and directories without defining their permissions. These
protocols can implement those operations by using the standard system calls and
by then undoing the effect of applying the mode parameters.
When the ACL of a directory is changed, the following happens for each entry
("child") inside that directory:
- 1.
-
If the entry is a symbolic link, skip the child.
- 2.
-
If the
auto_inherit
flag of the entry's ACL is not set or the
protected
flag is set, skip the child.
- 3.
-
With the child's ACL:
-
- a)
-
If the
defaulted
flag is set, replace the ACL with an empty ACL
with the
auto_inherit
flag set.
- b)
-
Delete all entries which have the
inherited
flag set.
- c)
-
Append all entries inherited from the parent directory according to step 1 of
the algorithm described under
Permissions at file-creation time.
Set the
inherited
flag of each of these entries.
- d)
-
Recompute the file masks as decribed in the section
Computing the maximum file masks.
- 4.
-
If the child is a directory, recursively apply this algorithm.
Access check algorithm
When a process requests a particular kind of access (expressed as a set of
RichACL permissions) to a file, the following algorithm determines whether the
access is granted or denied:
- 1.
-
If the
masked
ACL flag is set, then:
-
- a)
-
If the
write_through
ACL flag is set, then:
-
- •
-
If the requesting process is the file owner, then access is granted if the
owner mask includes the requested permissions, and is otherwise denied.
- •
-
If the requesting process is not the file owner and it is in the owning group or matches any ACL entries other than
everyone@,
proceed to step b).
- •
-
If the requesting process is not the file owner, is not in the owning group,
and no ACL entries other than
everyone@
match the process, then access is granted if the other mask includes the
requested permissions, and is otherwise denied.
- b)
-
If any of the following is true:
-
- •
-
the requesting process is the file owner and the owner mask does not include all
requested permissions,
- •
-
the requesting process is not the file owner and it is in the owning group or
matches any ACL entries other than
everyone@,
and the group mask does not include all requested permissions,
- •
-
the requesting process is not the file owner, not in the owning group, it
matches no ACL entries other than
everyone@,
and the other mask does not include all requested permissions,
then access is denied.
- 2.
-
Upon reaching this point, the determination of whether or not access is granted
is made by scanning all ACL entries to see if one or more applicable entries
together grant a cumulative set of permissions that matches the requested
permissions or there is an applicable entry that explicitly denies one or more
of the requested permissions. The scan of all ACL entries begins by first
initializing the set of remaining permissions (i.e., those that have not yet
been satisfied during the scan) to be the set of requested permissions. Then
the ACL entries are scanned
in order,
and for each entry:
-
- a)
-
If the
inherit_only
or
unmapped
flags are set, continue with the next ACL entry.
- b)
-
If any of the following is true:
-
- •
-
the entry's identifier is
owner@
and the requesting process is the file owner,
- •
-
the entry's identifier is
group@
and the requesting process is in the owning group,
- •
-
the entry's identifier is a user and the requesting process is owned by that
user,
- •
-
the entry's identifier is a group and the requesting process is a member in
that group,
- •
-
the entry's identifier is
everyone@,
then the entry matches the process; proceed to the next step. Otherwise,
continue with the next ACL entry.
- c)
-
If the entry denies any of the remaining permissions, access is denied.
- d)
-
If the entry allows any of the remaining permissions, then:
-
- •
-
If the
masked
ACL flag is set and the entry's identifier is not
owner@
or
everyone@
or is a user entry matching the file owner, remove all permissions from the
remaining permissions which are both allowed by the entry and included in the
group mask,
- •
-
Otherwise, remove all permissions from the remaining permissions which are
allowed by the entry.
- 3.
-
If there are no more remaining permissions, access is allowed. Otherwise,
access is denied.
In this algorithm, a process can gain the permissions it requires by
accumulating them from multiple RichACL entries. This is in contrast with
POSIX ACLs, where access is only granted if an ACL entry exists that matches
the requesting process and includes all the requested permissions.
Computing the maximum file masks
When setting an ACL and no file masks have been explicitly specified and when
inheriting an ACL from the parent directory (as described in the section
Permissions at file-creation time),
the following algorithm is used for computing the file masks:
- 1.
-
Clear the owner, group, and other file masks. Remember which permissions have
already been processed (initially, the empty set).
- 2.
-
For each ACL entry:
-
- •
-
If the
inherit_only
flag is set, skip the entry.
- •
-
Otherwise, compute which permissions the entry allows or denies that have not
been processed yet (the remaining permissions).
- •
-
If the entry is an
owner@
entry, add the remaining permissions to the owner mask for
allow
entries, and remove the remaining permissions from the owner mask for
deny
entries.
- •
-
Otherwise, if the entry is an
everyone@
entry, proceed as with
owner@
entries but add or remove the remaining permissions from the owner, group, and
other file masks.
- •
-
Otherwise, proceed as with
owner@
entries but add or remove the remaining permissions from the owner and group
file masks.
- •
-
Add the entry's permissions to the processed permissions.
The resulting file masks represent the ACL as closely as possible. With these
file masks, the effective permissions that the ACL grants will be the same when
the
masked
flag is set as when it is not set.
AUTHOR
Written by Andreas Grünbacher <agruenba [at] redhat.com>.
Please send your bug reports, suggested features and comments to the above address.
CONFORMING TO
Rich Access Control Lists are Linux-specific.