draft-ietf-nfsv4-acl-mapping-03.txt | draft-ietf-nfsv4-acl-mapping-04.txt | |||
---|---|---|---|---|
Network Working Group Marius Aamodt Eriksen | ||||
Internet Draft J. Bruce Fields | Network Working Group M. Eriksen | |||
Document: draft-ietf-nfsv4-acl-mapping-03.txt February 2005 | Internet-Draft J. Fields | |||
Expires: November 16, 2006 CITI | ||||
May 15, 2006 | ||||
Mapping Between NFSv4 and Posix Draft ACLs | Mapping Between NFSv4 and Posix Draft ACLs | |||
draft-ietf-nfsv4-acl-mapping-04 | ||||
Status of this Memo | Status of this Memo | |||
By submitting this Internet-Draft, I certify that any applicable | By submitting this Internet-Draft, each author represents that any | |||
patent or other IPR claims of which I am aware have been disclosed, | applicable patent or other IPR claims of which he or she is aware | |||
or will be disclosed, and any of which I become aware will be dis- | have been or will be disclosed, and any of which he or she becomes | |||
closed, in accordance with RFC 3668. | aware will be disclosed, in accordance with Section 6 of BCP 79. | |||
This document is an Internet-Draft and is in full conformance with | ||||
all provisions of Section 10 of RFC2026. | ||||
Internet-Drafts are working documents of the Internet Engineering | Internet-Drafts are working documents of the Internet Engineering | |||
Task Force (IETF), its areas, and its working groups. Note that | Task Force (IETF), its areas, and its working groups. Note that | |||
other groups may also distribute working documents as Internet- | other groups may also distribute working documents as Internet- | |||
Drafts. | Drafts. | |||
Internet-Drafts are draft documents valid for a maximum of six months | Internet-Drafts are draft documents valid for a maximum of six months | |||
and may be updated, replaced, or obsoleted by other documents at any | and may be updated, replaced, or obsoleted by other documents at any | |||
time. It is inappropriate to use Internet- Drafts as reference mate- | time. It is inappropriate to use Internet-Drafts as reference | |||
rial or to cite them other than as "work in progress." | material or to cite them other than as "work in progress." | |||
The list of current Internet-Drafts can be accessed at | The list of current Internet-Drafts can be accessed at | |||
http://www.ietf.org/ietf/1id-abstracts.txt | http://www.ietf.org/ietf/1id-abstracts.txt. | |||
The list of Internet-Draft Shadow Directories can be accessed at | The list of Internet-Draft Shadow Directories can be accessed at | |||
http://www.ietf.org/shadow.html. | http://www.ietf.org/shadow.html. | |||
"Copyright (C) The Internet Society (2002-2004). All Rights | This Internet-Draft will expire on November 16, 2006. | |||
Reserved." | ||||
Abstract | ||||
NFS version 4 [rfc3530] (NFSv4) specifies a flavor of Access Control | ||||
Lists (ACLs) resembling Windows NT ACLs. A number of operating sys- | ||||
tems use a different flavor of ACL based on a withdrawn POSIX draft. | ||||
NFSv4 clients and servers on such operating systems may wish to map | ||||
Mapping NFSv4 ACLs February 2005 | ||||
between NFSv4 ACLs and their native ACLs. To this end, we describe a | ||||
mapping from POSIX draft ACLs to a subset of NFSv4 ACLs. | ||||
Mapping NFSv4 ACLs February 2005 | Copyright Notice | |||
Table of Contents | Copyright (C) The Internet Society (2006). | |||
1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 4 | Abstract | |||
2. NFSv4 ACLs . . . . . . . . . . . . . . . . . . . . . . . . . 4 | ||||
3. POSIX ACLs . . . . . . . . . . . . . . . . . . . . . . . . . 5 | ||||
4. Mapping POSIX ACLs to NFSv4 ACLs . . . . . . . . . . . . . . 6 | ||||
5. Using the Mapping in NFSv4 Implementations . . . . . . . . . 9 | ||||
6. Security Considerations . . . . . . . . . . . . . . . . . 11 | ||||
7. Bibliography . . . . . . . . . . . . . . . . . . . . . . . 12 | ||||
8. Author's Address . . . . . . . . . . . . . . . . . . . . . 13 | ||||
9. Copyright . . . . . . . . . . . . . . . . . . . . . . . . 13 | ||||
Mapping NFSv4 ACLs February 2005 | A number of filesystems and applications support ACLs based on a | |||
withdrawn POSIX draft [2]. Those ACLs differ significantly from NFS | ||||
version 4 (NFSv4) ACLs [1]. We describe how to translate between the | ||||
two types of ACLs. | ||||
1. Introduction | 1. Introduction | |||
Access Control Lists (ACLs) are used to specify fine-grained access | Access Control Lists (ACLs) are used to specify fine-grained access | |||
rights to file system objects. An ACL is a list of Access Control | rights to file system objects. An ACL is a list of Access Control | |||
Entries (ACEs), each specifying an entity (such as a user) and some | Entries (ACEs), each specifying an entity (such as a user) and some | |||
level of access for that entity. | level of access for that entity. | |||
In the following sections we describe two ACL models: NFSv4 ACLs, and | In the following sections we describe two ACL models: NFSv4 ACLs, and | |||
ACLs based on a withdrawn POSIX draft. We will refer to the latter | ACLs based on a withdrawn POSIX draft. We will refer to the latter | |||
as "POSIX ACLs". Since NFSv4 ACLs are more fine-grained than POSIX | as "POSIX ACLs". Since NFSv4 ACLs are more fine-grained than POSIX | |||
ACLs, it is not possible in general to map an arbitrary NFSv4 ACL to | ACLs, it is not possible in general to map an arbitrary NFSv4 ACL to | |||
a POSIX ACL with the same semantics. However, it is possible to map | a POSIX ACL with the same semantics. However, it is possible to map | |||
any POSIX ACL to a NFSv4 ACL with nearly identical semantics. We | any POSIX ACL to a NFSv4 ACL with nearly identical semantics, and it | |||
will describe such a mapping, and discuss its use in NFSv4 clients | is possible to map any NFSv4 ACL to a POSIX ACL in a way that | |||
and servers. | preserves certain guarantees. We will explain how to do this, and | |||
give guidelines for clients and servers performing such translation. | ||||
2. NFSv4 ACLs | 2. NFSv4 ACLs | |||
An NFSv4 ACL is an ordered sequence of ACEs, each having an entity, a | An NFSv4 ACL is an ordered sequence of ACEs, each having an entity, a | |||
type, some flags, and an access mask. | type, some flags, and an access mask. | |||
The entity may be the name of a user or group, or may be one of a | The entity may be the name of a user or group, or may be one of a | |||
small set of special entities. Among the special entities are | small set of special entities. Among the special entities are | |||
"OWNER@" (the current owner of the file), "GROUP@" (the group associ- | "OWNER@" (the current owner of the file), "GROUP@" (the group | |||
ated with the file), and "EVERYONE@". | associated with the file), and "EVERYONE@". | |||
The type may be ALLOW or DENY. (AUDIT or ALARM are also allowed, but | The type may be ALLOW or DENY. (AUDIT or ALARM are also allowed, but | |||
they are not relevant to our discussion). | they are not relevant to our discussion). | |||
The access mask has 14 separate bits, including bits to control read, | The access mask has 14 separate bits, including bits to control read, | |||
write, execute, append, ACL modification, file owner modification, | write, execute, append, ACL modification, file owner modification, | |||
etc.; consult [rfc3530] for the full list. | etc.; consult [1] for the full list. | |||
Of the flags, four are relevant here. The ACE4_IDENTIFIER_GROUP flag | Of the flags, four are relevant here. The ACE4_IDENTIFIER_GROUP flag | |||
is used to indicate that the entity name is the name of a group. The | is used to indicate that the entity name is the name of a group. The | |||
other three concern inheritance: ACE4_DIRECTORY_INHERIT_ACE indicates | other three concern inheritance: ACE4_DIRECTORY_INHERIT_ACE indicates | |||
that the ACE should be added to new subdirectories of the directory; | that the ACE should be added to new subdirectories of the directory; | |||
ACE4_FILE_INHERIT_ACE does the same for new files; and | ACE4_FILE_INHERIT_ACE does the same for new files; and | |||
ACE4_INHERIT_ONLY indicates that the ACE should be ignored when | ACE4_INHERIT_ONLY indicates that the ACE should be ignored when | |||
determining access to the directory itself. | determining access to the directory itself. | |||
The NFSv4 ACL permission-checking algorithm is straightforward. | The NFSv4 ACL permission-checking algorithm is straightforward. | |||
Assume a a requester asks for access, as specified by a single bit in | Assume a a requester asks for access, as specified by a single bit in | |||
Mapping NFSv4 ACLs February 2005 | ||||
the access bitmask. We allow the access if the first ACE in the ACL | the access bitmask. We allow the access if the first ACE in the ACL | |||
that matches the requester and that has that bit set is an ALLOW ACE, | that matches the requester and that has that bit set is an ALLOW ACE, | |||
and we deny the access if the first such ACE is a DENY ACE. If no | and we deny the access if the first such ACE is a DENY ACE. If no | |||
matching ACE has the bit in question set, behaviour is undefined. If | matching ACE has the bit in question set, behaviour is undefined. If | |||
an access mask consisting of more than one bit is requested, it suc- | an access mask consisting of more than one bit is requested, it | |||
ceeds if and only if each bit in the mask is allowed. | succeeds if and only if each bit in the mask is allowed. | |||
We refer the reader to [rfc3530] for further details. | We refer the reader to [1] for further details. | |||
3. POSIX ACLs | 3. POSIX ACLs | |||
A number of operating systems implement ACLs based on the withdrawn | A number of operating systems implement ACLs based on the withdrawn | |||
POSIX 1003.1e/1003.2c Draft Standard 17 [posixacl]. We will refer to | POSIX 1003.1e/1003.2c Draft Standard 17 [2]. We will refer to such | |||
such ACLs as "POSIX ACLs". | ACLs as "POSIX ACLs". | |||
POSIX ACLs use access masks with only the traditional "read", | POSIX ACLs use access masks with only the traditional "read", | |||
"write", and "execute" bits. Each ACE in a POSIX ACL is one of five | "write", and "execute" bits. Each ACE in a POSIX ACL is one of five | |||
types: ACL_USER_OBJ, ACL_USER, ACL_GROUP_OBJ, ACL_GROUP, ACL_MASK, | types: ACL_USER_OBJ, ACL_USER, ACL_GROUP_OBJ, ACL_GROUP, ACL_MASK, | |||
and ACL_OTHER. Each ACL_USER ACE has a uid associated with it, and | and ACL_OTHER. Each ACL_USER ACE has a uid associated with it, and | |||
each ACL_GROUP ACE has a gid associated with it. Every POSIX ACL | each ACL_GROUP ACE has a gid associated with it. Every POSIX ACL | |||
must have exactly one ACL_USER_OBJ, ACL_GROUP, and ACL_OTHER ACE, and | must have exactly one ACL_USER_OBJ, ACL_GROUP_OBJ, and ACL_OTHER ACE, | |||
at most one ACL_MASK ACE. The ACL_MASK ACE is required if the ACL | and at most one ACL_MASK ACE. The ACL_MASK ACE is required if the | |||
has any ACL_USER or ACL_GROUP ACEs. There may not be two ACL_USER | ACL has any ACL_USER or ACL_GROUP ACEs. There may not be two | |||
ACEs with the same uid, and there may not be two ACL_GROUP ACEs with | ACL_USER ACEs with the same uid, and there may not be two ACL_GROUP | |||
the same gid. | ACEs with the same gid. | |||
Given a POSIX ACL and a requester asking for access, permission is | Given a POSIX ACL and a requester asking for access, permission is | |||
determined as follows: | determined as follows: | |||
1) If the requester is the file owner, then allow or deny access | 1. If the requester is the file owner, then allow or deny access | |||
depending on whether the ACL_USER_OBJ ACE allows or denies it. | depending on whether the ACL_USER_OBJ ACE allows or denies it. | |||
Otherwise, | Otherwise, | |||
2) if the requester's uid matches the uid of one of the ACL_USER | 2. if the requester's uid matches the uid of one of the ACL_USER | |||
ACEs, then allow or deny access depending on whether the | ACEs, then allow or deny access depending on whether the | |||
ACL_USER_OBJ ACE allows or denies it. Otherwise, | ACL_USER_OBJ ACE allows or denies it. Otherwise, | |||
3) Consider the set of all ACL_GROUP ACEs whose gid the requester is | 3. Consider the set of all ACL_GROUP ACEs whose gid the requester is | |||
a member of. Add to that set the ACL_GROUP_OBJ ACE, if the | a member of. Add to that set the ACL_GROUP_OBJ ACE, if the | |||
requester is also a member of the file's group. Allow access if | requester is also a member of the file's group. Allow access if | |||
any ACE in the resulting set allows access. If the set of match- | any ACE in the resulting set allows access. If the set of | |||
ing ACEs is nonempty, and none allow access, then deny access. | matching ACEs is nonempty, and none allow access, then deny | |||
Otherwise, if the set of matching ACEs is empty, | access. Otherwise, if the set of matching ACEs is empty, | |||
Mapping NFSv4 ACLs February 2005 | ||||
4) if the requester's access mask is allowed by the ACL_OTHER ACE, | 4. if the requester's access mask is allowed by the ACL_OTHER ACE, | |||
then grant access. Otherwise, deny access. | then grant access. Otherwise, deny access. | |||
The above description omits one detail: in steps (2) and (3), the | The above description omits one detail: in steps (2) and (3), the | |||
requested bits must be granted both by the matching ACE and by the | requested bits must be granted both by the matching ACE and by the | |||
ACL_MASK ACE. The ACL_MASK ACE thus limits the maximum permissions | ACL_MASK ACE. The ACL_MASK ACE thus limits the maximum permissions | |||
which may be granted by any ACL_USER or ACL_GROUP ACE, or by the | which may be granted by any ACL_USER or ACL_GROUP ACE, or by the | |||
ACL_GROUP_OBJ ACE. | ACL_GROUP_OBJ ACE. | |||
Each file may have a single POSIX ACL associated with it, used to | Each file may have a single POSIX ACL associated with it, used to | |||
determine access to that file. Directories, however, may have two | determine access to that file. Directories, however, may have two | |||
ACLs: one, the "access ACL", used to determine access to the direc- | ACLs: one, the "access ACL", used to determine access to the | |||
tory, and one, the "default ACL", used only as the ACL to be inher- | directory, and one, the "default ACL", used only as the ACL to be | |||
ited by newly created objects in the directory. | inherited by newly created objects in the directory. | |||
4. Mapping POSIX ACLs to NFSv4 ACLs | 4. Ordering of NFSv4 and POSIX ACLs | |||
POSIX ACLs are unordered--the order in which the POSIX access- | ||||
checking algorithm considers the entries is determined entirely by | ||||
the type of the entries, so the entries don't need to be kept in any | ||||
particular order. | ||||
By contrast, the meaning of an NFSv4 ACL can be dramatically changed | ||||
by modifying the order that the entries are listed in. | ||||
In the following, we will say that an NFSv4 ACL is in the "canonical | ||||
order" if its entries are ordered in the order that the POSIX | ||||
algorithm would consider them. That is, with all OWNER@ entries | ||||
first, followed by user entries, followed by GROUP@ entries, followed | ||||
by group entries, with all EVERYONE@ entries at the end. | ||||
5. A Minor Eccentrity of POSIX ACLs | ||||
We will see below that it is possible to find an NFSv4 ACL with | ||||
precisely the same effect as any given POSIX ACL, with one extremely | ||||
minor exception: if a requester that is a member of more than one | ||||
group listed in the ACL requests multiple bits simultaneously, the | ||||
POSIX algorithm requires all of the bits to be granted simultaneously | ||||
by one of the group ACEs. Thus a POSIX ACL such as | ||||
ACL_USER_OBJ: --- | ||||
ACL_GROUP_OBJ: --- | ||||
g1: r-- | ||||
g2: -w- | ||||
ACL_MASK: rw- | ||||
ACL_OTHER: --- | ||||
will prevent a user that is a member of groups g1 and g2 from opening | ||||
a file for both read and write, even though read and write would be | ||||
individually permitted. | ||||
The NFSv4 ACL permission-checking algorithm has the property that it | ||||
permits a group of bits whenever it would permit each bit | ||||
individually, so it is impossible to mimic this behaviour with an | ||||
NFSv4 ACL. | ||||
6. Mapping POSIX ACLs to NFSv4 ACLs | ||||
6.1. Requirements | ||||
In the next section we give an example of a mapping of POSIX ACLs | ||||
into NFSv4 ACLs. We permit a server or client to use a different | ||||
mapping, provided the mapping meets the following requirements: | ||||
It must map the POSIX ACL to an NFSv4 ACL with identical access | ||||
semantics, ignoring the minor exception described in the previous | ||||
section. | ||||
It must map the read mode bit to ACE4_READ_DATA, the write bit to | ||||
ACE4_WRITE_DATA and ACE4_APPEND_DATA (and ACE4_DELETE_CHILD for | ||||
directories), and the EXECUTE bit to ACE4_EXECUTE. It should also | ||||
allow ACE4_READ_ACL, ACE4_READ_ATTRIBUTES, and ACE4_SYNCHRONIZE | ||||
unconditionally, and allow ACE4_WRITE_ACL and ACE4_WRITE_ATTRIBUTES | ||||
to the owner. The handling of other NFSv4 mode bits may depend on | ||||
the implementation, but it is preferable to leave them unused. | ||||
It should avoid using DENY ACEs. If DENY ACEs are required, it | ||||
should attempt to place them at the beginning. (This is not always | ||||
possible.) | ||||
For simplicity's sake, the translator may choose to handle the mask | ||||
by first applying it to the USER, GROUP, and GROUP_OBJ ACEs, and then | ||||
mapping the resulting ACL. However, that will result in an ACL from | ||||
which it is impossible to determine the original value of the mask or | ||||
of the masked USER, GROUP, and GROUP_OBJ bitmasks. If the resulting | ||||
ACL is later translated back to a POSIX ACL, the translator will | ||||
assume that the value of the mask is the union of the bitmasks | ||||
permitted to any USER, GROUP, or GROUP_OBJ. If that would be | ||||
incorrect, the original translation should not modify the bitmasks of | ||||
the USER, GROUP, and GROUP_OBJ bitmasks, and should instead use | ||||
additional DENY ACEs as necessary to give the effect of the mask. It | ||||
should also arrange for the first GROUP@ ACE to be a DENY ACE whose | ||||
bitmask is determined by the mask, allowing that ACE to be used to | ||||
determine the original mask value. | ||||
6.2. Example POSIX->NFSv4 Mapping | ||||
We now describe an algorithm which maps any POSIX ACL to an NFSv4 ACL | We now describe an algorithm which maps any POSIX ACL to an NFSv4 ACL | |||
with the same semantics. | with the same semantics, meeting the above requirements. | |||
First, translate the uid's and gid's on the ACL_USER and ACL_GROUP | First, translate the uid's and gid's on the ACL_USER and ACL_GROUP | |||
ACEs into NFSv4 names. This is an implementation-dependent process. | ACEs into NFSv4 names, using directory services, etc., as | |||
It might be done, for example, by consulting a directory service or a | appropriate, and translate ACL_USER_OBJ, ACL_GROUP_OBJ, and ACL_OTHER | |||
password file. Also, the special ACL_USER_OBJ, ACL_GROUP_OBJ, and | to the special NFSv4 names "OWNER@", "GROUP@", and "EVERYONE@", | |||
ACL_OTHER ACEs must be translated to NFSv4 ACEs with the special | respectively. | |||
entities "OWNER@", "GROUP@", and "EVERYONE@", respectively. | ||||
Next, map each POSIX ACE (excepting any mask ACE) in the given POSIX | Next, map each POSIX ACE (excepting any mask ACE) in the given POSIX | |||
ACL to an NFSv4 ALLOW ACE with an entity determined as above, and | ACL to an NFSv4 ALLOW ACE with an entity determined as above, and | |||
with a bitmask determined from the permission bits on the POSIX ACE | with a bitmask determined from the permission bits on the POSIX ACE | |||
as follows: | as follows: | |||
1) If the read bit is set in the POSIX ACE, then set ACE4_READ_DATA. | 1. If the read bit is set in the POSIX ACE, then set ACE4_READ_DATA. | |||
2) If the write bit is set in the POSIX ACE, then set ACE4_WRITE_DATA | 2. If the write bit is set in the POSIX ACE, then set | |||
and ACE4_APPEND_DATA. If the object carrying the ACL is a direc- | ACE4_WRITE_DATA and ACE4_APPEND_DATA. If the object carrying the | |||
tory, set ACE4_DELETE_CHILD as well. | ACL is a directory, set ACE4_DELETE_CHILD as well. | |||
3) If the execute bit is set in the POSIX ACE, then set ACE4_EXECUTE. | 3. If the execute bit is set in the POSIX ACE, then set | |||
ACE4_EXECUTE. | ||||
4) Set ACE4_READ_ACL, ACE4_READ_ATTRIBUTES, and ACE4_SYNCHRONIZE | 4. Set ACE4_READ_ACL, ACE4_READ_ATTRIBUTES, and ACE4_SYNCHRONIZE | |||
unconditionally. | unconditionally. | |||
5) If the ACE is for the special "OWNER@" entity, set ACE4_WRITE_ACL | 5. If the ACE is for the special "OWNER@" entity, set ACE4_WRITE_ACL | |||
and ACE4_WRITE_ATTRIBUTES. | and ACE4_WRITE_ATTRIBUTES. | |||
Mapping NFSv4 ACLs February 2005 | 6. Clear all other bits in the NFSv4 bitmask. | |||
6) Clear all other bits in the NFSv4 bitmask. | ||||
In addition, we set the GROUP flag in each ACE which corresponds to a | In addition, we set the GROUP flag in each ACE which corresponds to a | |||
named group (but not in the GROUP@ ACE, or any of the other special | named group (but not in the GROUP@ ACE, or any of the other special | |||
entity ACEs). At this point, we've replaced the POSIX ACL by an | entity ACEs). | |||
NFSv4 ACL with the same number of ACEs (ignoring any mask ACE). To | ||||
emulate the POSIX ACL permission-checking algorithm, we need to mod- | ||||
ify the ACL further, as follows: | ||||
1) Order the ACL so that the OWNER@ ACE is the first ACE of the ACL, | ||||
followed by any user ACEs, followed by the GROUP@ ACE, followed by | ||||
any group ACEs, and ending finally with the EVERYONE@ ACE. | ||||
2) The POSIX algorithm stops as soon as the requester matches an | At this point, we've replaced the POSIX ACL by an NFSv4 ACL with the | |||
ACL_USER_OBJ, ACL_OTHER, or ACL_USER ACE. To emulate this | same number of ACEs (ignoring any mask ACE), all of them ALLOW ACEs. | |||
behaviour, add a single DENY ACE after each ALLOW ACE for OWNER@, | ||||
EVERYONE@, or any named user. The DENY ACE should have the same | ||||
entity and flags as the corresponding ALLOW ACE. The bitmask on | ||||
the DENY ACE should be the bitwise NOT of the bitmask on the ALLOW | ||||
ACE, except that the ACE4_WRITE_OWNER and ACE4_DELETE bits should | ||||
be cleared, and the ACE4_DELETE_CHILD bit should be cleared on | ||||
non-directories. (Also, in the xdr-encoded ACL that is transmit- | ||||
ted, all bits not defined in the protocol should be cleared.) | ||||
3) Unlike the other ACEs in step 2, all of the ACL_GROUP_OBJ and | Order this NFSv4 ACL in the canonical order: OWNER@, users, GROUP@, | |||
ACL_GROUP ACEs are consulted by the POSIX algorithm before deter- | groups, then EVERYONE@. | |||
mining permissions. However, if the requester matches any one of | ||||
them, then it must deny any permissions they do not allow. To | ||||
emulate this behaviour, instead of adding a single DENY after each | ||||
corresponding GROUP@ or named group ACE, we insert a list of DENY | ||||
ACEs at the end of the list of GROUP@ and named group ACEs. Each | ||||
DENY ACE is determined from its corresponding ALLOW ACE exactly as | ||||
in step 2, and should occur in the inserted list in the same posi- | ||||
tion as the corresponding ALLOW ACE occurs in the list of ALLOW | ||||
ACEs. | ||||
4) Finally, we enforce the POSIX mask ACE by prepending each ALLOW | If the bitmasks in the resulting ACEs are non-increasing (so no ACE | |||
ACE for a named user, GROUP@, or named group, with a single DENY | allows a bit not allowed by a previous ACE), then we can skip the | |||
ACE whose entity and flags are the same as those for the corre- | next step. | |||
sponding ALLOW ACE, but whose bitmask is the inverse of the bit- | ||||
mask determined from the mask ACE, with the inverse calculated as | ||||
described in step 2. | ||||
As an example, take a POSIX ACL with two named users (u1 and u2) and | Otherwise, we need to insert additional DENY ACE's to emulate the | |||
two named groups (g1 and g2), in addition to the required | first-match semantics of the POSIX ACL permission-checking algorithm: | |||
ACL_USER_OBJ, ACL_GROUP_OBJ, ACL_OTHER, and ACL_MASK ACEs. | ||||
Such an ACL will map to an NFSv4 ACL of the form | 1. If an ACL_USER_OBJ, ACL_OTHER, or ACL_USER ACE fails to grant | |||
some permissions that are granted later in the ACL, then that ACE | ||||
must be prepended by a single DENY ACE. The DENY ACE should have | ||||
the same entity and flags as the corresponding ALLOW ACE, but the | ||||
bitmask on the DENY ACE should be the bitwise NOT of the bitmask | ||||
on the ALLOW ACE, except that the ACE4_WRITE_OWNER, ACE4_DELETE, | ||||
ACE4_READ_NAMED_ATTRIBUTES, ACE4_WRITE_NAMED_ATTRIBUTES bits | ||||
should be cleared, and the ACE4_DELETE_CHILD bit should be | ||||
cleared on non-directories. (Also, in the xdr-encoded ACL that | ||||
is transmitted, all bits not defined in the protocol should be | ||||
cleared.) | ||||
Mapping NFSv4 ACLs February 2005 | 2. All of the ACL_GROUP_OBJ and ACL_GROUP ACEs are consulted by the | |||
POSIX algorithm before determining permissions. To emulate this | ||||
behaviour, instead of adding a single DENY before corresponding | ||||
GROUP@ or named group ACEs, we insert a list of DENY ACEs after | ||||
the list of GROUP@ and named group ACEs. Each DENY ACE is | ||||
determined from its corresponding ALLOW ACE exactly as in the | ||||
previous step. As before, these DENY aces should only be added | ||||
when they are necessitated by an ACE that is less permissive than | ||||
the final EVERYONE@ ace. | ||||
ALLOW OWNER@ | Finally, we enforce the POSIX mask ACE by prepending each ALLOW ACE | |||
DENY OWNER@ | for a named user, GROUP@, or named group, with a single DENY ACE | |||
DENY u1 (mask) | whose entity and flags are the same as those for the corresponding | |||
ALLOW u1 | ALLOW ACE, but whose bitmask is the inverse of the bitmask determined | |||
DENY u1 | from the mask ACE, with the inverse calculated as described above. | |||
DENY u2 (mask) | In the case of named users, these DENY aces may be coalesced with any | |||
ALLOW u2 | existing prepended DENY aces. The DENY aces are omitted entirely if | |||
DENY u2 | they would have no affect, or if the mask ACE has the same bitmask as | |||
DENY GROUP@ (mask) | the maximum of the affected ACEs. (With the one exception that if | |||
ALLOW GROUP@ | the POSIX ACL posesses exactly 4 ACEs, then a mask-derived DENY ace | |||
DENY g1 (mask) | should be inserted before the GROUP@ ace, even if it would not | |||
ALLOW g1 | otherwise be.) | |||
DENY g2 (mask) | ||||
ALLOW g2 | ||||
DENY GROUP@ | ||||
DENY g1 | ||||
DENY g2 | ||||
ALLOW EVERYONE@ | ||||
DENY EVERYONE@ | ||||
where the ACEs marked with (mask) are those whose bitmask are deter- | Regardless of what scheme is used to represent the mask, the receiver | |||
mined from the ACL_MASK ACE as described in step 4 above. | will use the first GROUP@ DENY ace to determine the value of the mask | |||
(if it is different from the union of the bitmasks on the affected | ||||
ACEs), and use the relevant ALLOWs to determine the pre-mask values | ||||
of user and group ACEs. | ||||
In general, a POSIX ACL with m named users and n named groups will | The implementation may also choose to just mask out the bitmasks on | |||
map to an NFSv4 ACL with (3*(m + n) + 7) ACLs, unless m and n are | the relevant ALLOW ACEs. This will produce a simpler ACL (in | |||
both zero, in which case the result will have either 6 or 7 ACLs, | particular, an ACL that usually requires no DENY ACE's), at the | |||
depending on whether the original ACL had an ACL_MASK ACE. | expense of losing some ACL information after a chmod. | |||
On directories with default ACLs, we translate the default ACL as | On directories with default ACLs, we translate the default ACL as | |||
above, but set the ACE4_INHERIT_ONLY_ACE, ACE4_DIRECTORY_INHERIT_ACE, | above, but set the ACE4_INHERIT_ONLY_ACE, ACE4_DIRECTORY_INHERIT_ACE, | |||
and ACE4_FILE_INHERIT_ACE flags on every ACE in the resulting ACL. | and ACE4_FILE_INHERIT_ACE flags on every ACE in the resulting ACL. | |||
On directories with both default and access ACLs, we translate the | On directories with both default and access ACLs, we translate the | |||
two ACLs and then concatenate them. The order of the concatenation | two ACLs and then concatenate them. The order of the concatenation | |||
is unimportant. | is unimportant. | |||
There is one extremely minor inaccuracy in this mapping: if a | 7. Mapping NFSv4 ACLs to POSIX ACLs | |||
requester that is a member of more than one group listed in the ACL | ||||
requests multiple bits simultaneously, the POSIX algorithm requires | ||||
all of the bits to be granted simultaneously by one of the group | ||||
ACEs. Thus a POSIX ACL such as | ||||
ACL_USER_OBJ: --- | 7.1. Requirements | |||
ACL_GROUP_OBJ: --- | ||||
g1: r-- | ||||
g2: -w- | ||||
ACL_MASK: rw- | ||||
ACL_OTHER: --- | ||||
Mapping NFSv4 ACLs February 2005 | Any mapping of NFSv4 ACLs to POSIX ACLs must map any NFSv4 ACL that | |||
is semantically equivalent to a POSIX ACL (with the exception of the | ||||
"minor inaccuracy" mentioned above) to the equivalent POSIX ACL. It | ||||
should also extract the mask correctly; as the mask doesn't affect | ||||
the semantics of the NFSv4 ACL, and as there is more than one way the | ||||
mask might be encoded, we require a convention for this. | ||||
Specifically: we require that the mask be computed as the bitmask | ||||
used on the first GROUP@ DENY ACE which precedes any GROUP@ allow | ||||
ACE, unless no such DENY ACE exists, in which case the mask must be | ||||
computed as the union of the bitmasks allowed to all named users, | ||||
groups, and GROUP@ (where by the "bitmask allowed to" an entity we | ||||
mean the maximum bitmask that the ACL would permit to any user | ||||
matching the entity). | ||||
will prevent a user that is a member of groups g1 and g2 from opening | Implementations may vary in how they deal with NFSv4 ACLs that are | |||
a file for both read and write, even though read and write would be | not precisely semantically equivalent to any POSIX ACL. In | |||
individually permitted. | particular they may return errors for such ACLs instead of attempting | |||
to map them. However, when possible without compromising security, | ||||
they should attempt to be forgiving. | ||||
The NFSv4 ACL permission-checking algorithm has the property that it | The language of [1] allows a server some flexibility in handling ACLs | |||
permits a group of bits whenever it would permit each bit individu- | that it cannot enforce completely accurately, as long as it adheres | |||
ally, so it is impossible to mimic this behaviour with an NFSv4 ACL. | to "the guiding principle... that the server must not accept ACLs | |||
that appear to make [a file] more secure than it really is." | ||||
5. Using the Mapping in NFSv4 Implementations | Note that an NFSv4 ACL consisting entirely of ALLOW ACLs can always | |||
be transformed into a POSIX-equivalent ACL by first sorting it into | ||||
the canonical order, and then inserting DENY ACEs as necessary to | ||||
ensure POSIX first-match semantics. Since inserting DENY ACEs can | ||||
only restrict access, it is safe for a server to do this. | ||||
Examination of the algorithm described in the previous section shows | We require any server to accept, at least, any NFSv4 ACL that | |||
that no information is lost; the original POSIX ACL can be recon- | consists entirely of ALLOW ACLs. | |||
structed from the mapped NFSv4 ACL. Thus we also have a way to map | ||||
NFSv4 ACLs to POSIX ACLs in the case where the NFSv4 ACL is precisely | ||||
in the format of an ACL produced by the algorithm above. | ||||
The algorithm can therefore be used to implement a subset of the | Clients should also be at least as forgiving, to promote | |||
NFSv4 ACL model. This may be useful to NFSv4 clients and servers | interoperability when heterogeneous clients share files. | |||
with preexisting system interfaces that support POSIX ACLs and that | ||||
cannot be modified to support NFSv4 ACLs. | ||||
A server, for example, that wishes to export via NFSv4 a filesystem | 7.2. Example NFSv4->POSIX Mapping | |||
that supports only POSIX ACLs, may use this mapping to answer client | ||||
requests for existing ACLs by translating POSIX ACLs on its filesys- | ||||
tem to NFSv4 ACLs to send to the client. However, when a client | ||||
attempts to set an ACL, the server faces a problem. If the given ACL | ||||
is not in precisely the format of an ACL produced by this mapping, | ||||
then the server may be required to return an error to avoid inaccu- | ||||
rately representing the client's intention. The correct error to | ||||
return in this case is NFS4ERR_ATTRNOTSUPP. | ||||
In the case where a client sets an ACL that leaves certain bits nei- | We now give an example of an algorithm that meets the above | |||
ther allowed nor denied, the server may choose to allow or deny those | requirements. We assume it is to be used by a server mapping client- | |||
bits as necessary to make mapping possible. In some situations it | provided NFSv4 ACLs to POSIX ACLs it can store in its filesystem, so | |||
may also be possible for a server to map the ACL if it adds a DENY | the translation errs on the side of making the ACL less permissive. | |||
ACE or denies a few additional bits. The language of [rfc3530] | ||||
allows a server some flexibility in handling ACLs that it cannot | ||||
enforce completely accurately, as long as it adheres to "the guiding | ||||
principle... that the server must not accept ACLs that appear to make | ||||
[a file] more secure than it really is." | ||||
Given the choice, as long as the "guiding principle" is not violated, | Given an NFSv4 ACL, first calculate the mask by taking the bitmask | |||
servers should opt to be forgiving. The complexity of the | from the first GROUP@ DENY ACE from the original NFSv4 ACL, if it | |||
POSIX<->NFSv4 mapping makes difficult the task of generating ACLs | exists. After doing so, remove that DENY ACE, and clear the bits in | |||
its bitmask from any DENY ACE for a named user, group, or GROUP@ | ||||
which precedes an ALLOW ACE for the same entity. | ||||
Mapping NFSv4 ACLs February 2005 | In the case where there is no such GROUP@ DENY ACE, continue through | |||
the rest of the algorithm and then calculate the mask as the union of | ||||
the calculated permissions of all named users, group, and the | ||||
GROUP_OBJ ACE. | ||||
that will satisfy a server using the mapping. By making the mapping | Given an NFSv4 ACL, sort it into canonical order (OWNER@ ACEs first, | |||
more forgiving, the server can simplify that task, improving interop- | then user ACEs, then GROUP@ ACEs, then group ACEs, then EVERYONE@ | |||
erability. | ACEs.) Also, sort the GROUP@ and group ACEs that all ALLOW ACEs | |||
precede all DENY ACEs. To do so, take advantage of the following | ||||
observations: | ||||
Servers that implement the full NFSv4 protocol should also handle | 1. If two consecutive ACEs are either both ALLOW ACEs, or both DENY | |||
carefully ACLs that leave bits neither allowed nor denied. It is | ACEs, then we can swap their order without changing the effect of | |||
better to fall back on some reasonable default rather than to always | the ACL. | |||
allow or always deny. A client that, for example, sets | ||||
ACE4_WRITE_DATA but leaves unspecified ACE4_APPEND_DATA probably does | ||||
so because its system interfaces are incapable of independently rep- | ||||
resenting ACE4_APPEND_DATA, not because it intends to deny | ||||
ACE4_APPEND_DATA. By leaving the bit unspecified, the client leaves | ||||
the server the opportunity to provide the reasonable default of set- | ||||
ting it to match ACE4_WRITE_DATA. | ||||
Similar issues exist when a client uses NFSv4 ACLs to implement user | 2. If it would be impossible for a single user to match both of the | |||
interfaces that only deal in POSIX ACLs. When the client translates | entities on two consecutive ACEs, then we can swap their order | |||
ACLs received from the server to POSIX ACLs, some flexibility may | without changing the effect of the ACL. | |||
help interopability, but the client must take care not to represent | ||||
any ACLs as stricter than they really are. Clients that provide | ||||
access to the full set of NFSv4 ACLs may also wish to provide users | ||||
with utilities to generate and interpret POSIX-mapped NFSv4 ACLs, to | ||||
aid users working with servers using the POSIX mapping. | ||||
Mapping NFSv4 ACLs February 2005 | 3. If an ALLOW ACE is immediately followed by a DENY ACE, then | |||
swapping the order of the two ACEs will not make the ACL any more | ||||
permissive. | ||||
6. Security Considerations | 4. If a DENY ACE is immediately followed by an ALLOW ACE, then | |||
swapping the order of the two ACEs will not make the ACL any more | ||||
permissive, *if* we modify the bitmask on the ALLOW ACE by | ||||
clearing any bits that are set in the DENY ACE. | ||||
The second observation is the trickiest: it may usually be safe to | ||||
assume that two distinct user names cannot match the same user. An | ||||
implementation with knowledge about group memberships or about the | ||||
current value of the file owner might also use that information, but | ||||
if it does so it will produce a translation that is no longer | ||||
accurate after owners or group memberships change. | ||||
Fortunately, observations 1, 3, and 4 are sufficient to sort any ACL | ||||
into canonical order, so a paranoid implementation can simply ignore | ||||
number 2 completely, while an implementation willing to sacrifice | ||||
some accuracy may choose to do something more complex. | ||||
Ensure that the resulting ACL posesses at least one each of OWNER@, | ||||
GROUP@, and EVERYONE@ ACEs, by inserting an ALLOW ACE with a zero | ||||
bitmask if necessary in the correct position. | ||||
Next, for each entity, calculate a bitmask for that entity as | ||||
follows: Starting with the first ACE for that entity (ignoring all | ||||
previous ACEs), perform the NFSv4 ACL-checking algorithm for a user | ||||
that is assumed to match the entity on every DENY ACE that a user | ||||
matching the given entity might match, but is assumed to match only | ||||
those entities on ALLOW ACEs that *any* user matching the current | ||||
entity must match. | ||||
Finally, construct the POSIX ACL by translating NFSv4 entity names to | ||||
uid's and gid's (and handling special entities in the obvious way), | ||||
then assign a POSIX bitmask determined by the NFSv4 bitmask | ||||
calculated in the previous step; the bitmask calculation should use | ||||
the inverse of the mapping described previously in the POSIX-to-NFSv4 | ||||
mapping, erring on the side of denying bits if it cannot determine a | ||||
sensible mapping. However, if certain bits simply cannot be mapped | ||||
in a reasonable way to mode bits, the server may simply ignore them | ||||
rather than returning an error. (For example, the server should deny | ||||
write if either ACE4_WRITE_DATA or ACE4_APPEND_DATA are denied. But | ||||
it may choose to ignore ACE4_READ_ATTRIBUTES entirely.) | ||||
The resulting mapping errs on the side of creating a more restrictive | ||||
ACE. However it can be modified to produce a mapping that errs on | ||||
the side of permissiveness, for the purposes of translating a server- | ||||
provided NFSv4 ACL to a POSIX ACL to present to a user or | ||||
application, as follows: | ||||
1. When sorting ACEs, ALLOW ACEs can always be moved towards the | ||||
start of the ACL, but a DENY ACE can be moved towards the start | ||||
of the ACL only as long as we clear any of the DENY ACE's bitmask | ||||
bits that are set in the intervening ALLOW ACEs. | ||||
2. When calculating the NFSv4 bitmask for each entity, err on the | ||||
side of assuming that ALLOW ACEs apply and that DENY ACEs don't, | ||||
with the one exception that when calculating the GROUP@ and named | ||||
group bitmasks, ALLOW ACEs for groups other than the one under | ||||
consideration should be ignored. | ||||
3. When mapping the NFSv4 bitmask to POSIX mode bits, err on the | ||||
side of allowing access. | ||||
8. Security Considerations | ||||
Any automatic mapping from one ACL model to another must provide | Any automatic mapping from one ACL model to another must provide | |||
guarantees as to how the mapping affects the meaning of ACLs, or risk | guarantees as to how the mapping affects the meaning of ACLs, or risk | |||
misleading users about the permissions set on filesystem objects. | misleading users about the permissions set on filesystem objects. | |||
For this reason, caution is recommended when implementing this map- | For this reason, caution is recommended when implementing this | |||
ping. It is better to return errors than to break any such guaran- | mapping. It is better to return errors than to break any such | |||
tees. | guarantees. | |||
Note also that this ACL mapping requires mapping between NFSv4 user- | That said, there may be cases where small losses in accuracy can | |||
names and local id's. When the mapping of id's depends on remote | avoid dramatic interoperability and usability problems; as long as | |||
the losses in accuracy are clearly documented, these tradeoffs may be | ||||
found acceptable. | ||||
For example, a server unable to support all of the NFSv4 mode bits | ||||
does not have a way to communicate its exact limitations to clients, | ||||
so clients (and users) may be unable to recover from such errors. | ||||
For this reason we recommend ignoring bitmask bits that the server is | ||||
completely unable to map to mode bits, and advertising this fact | ||||
loudly in the server documentation. If this is considered | ||||
insufficient, we should add to the NFSv4 protocol additional | ||||
attributes necessary to advertise the server's limitations. | ||||
Note also that this ACL mapping requires mapping between NFSv4 | ||||
usernames and local id's. When the mapping of id's depends on remote | ||||
services, the method used for the mapping must be at least as secure | services, the method used for the mapping must be at least as secure | |||
as the method used to set or get ACLs. | as the method used to set or get ACLs. | |||
Mapping NFSv4 ACLs February 2005 | 9. References | |||
7. Bibliography | ||||
[rfc3530] | [1] Shepler, S., Callaghan, B., Robinson, D., Thurlow, R., Beame, | |||
Shepler, S. et. al., "NFS version 4 Protocol", April 2003. | C., Eisler, M., and D. Noveck, "Network File System (NFS) | |||
version 4 Protocol", RFC 3530, April 2003. | ||||
http://www.ietf.org/rfc/rfc3530.txt | [2] Institute of Electrical and Electronics Engineers, Inc., "IEEE | |||
Draft P1003.1e", October 1997, | ||||
<http://wt.xpilot.org/publications/posix.1e/download.html>. | ||||
[posixacl] | Authors' Addresses | |||
IEEE, "IEEE Draft P1003.1e", October 1997 (last draft). | ||||
http://wt.xpilot.org/publications/posix.1e/download.html | Marius Aamodt Eriksen | |||
U. of Michigan Center for Information Technology Integration | ||||
Mapping NFSv4 ACLs February 2005 | Email: marius@citi.umich.edu | |||
8. Author's Address | J. Bruce Fields | |||
U. of Michigan Center for Information Technology Integration | ||||
Address comments related to this memorandum to: | Email: marius@citi.umich.edu | |||
marius@umich.edu bfields@umich.edu | Intellectual Property Statement | |||
Marius Aamodt Eriksen | The IETF takes no position regarding the validity or scope of any | |||
J. Bruce Fields | Intellectual Property Rights or other rights that might be claimed to | |||
University of Michigan / CITI | pertain to the implementation or use of the technology described in | |||
535 West William | this document or the extent to which any license under such rights | |||
Ann Arbor, Michigan | might or might not be available; nor does it represent that it has | |||
made any independent effort to identify any such rights. Information | ||||
on the procedures with respect to rights in RFC documents can be | ||||
found in BCP 78 and BCP 79. | ||||
E-mail: marius@umich.edu | Copies of IPR disclosures made to the IETF Secretariat and any | |||
E-mail: bfields@umich.edu | assurances of licenses to be made available, or the result of an | |||
attempt made to obtain a general license or permission for the use of | ||||
such proprietary rights by implementers or users of this | ||||
specification can be obtained from the IETF on-line IPR repository at | ||||
http://www.ietf.org/ipr. | ||||
9. Copyright | The IETF invites any interested party to bring to its attention any | |||
copyrights, patents or patent applications, or other proprietary | ||||
rights that may cover technology that may be required to implement | ||||
this standard. Please address the information to the IETF at | ||||
ietf-ipr@ietf.org. | ||||
Copyright (C) The Internet Society (2004). This document is subject | Disclaimer of Validity | |||
to the rights, licenses and restrictions contained in BCP 78, and | ||||
except as set forth therein, the authors retain all their rights. | ||||
This document and the information contained herein are provided on an | This document and the information contained herein are provided on an | |||
"AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS | "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS | |||
OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY AND THE INTERNET | OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY AND THE INTERNET | |||
ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, | ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, | |||
INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFOR- | INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE | |||
MATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES | INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED | |||
OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. | WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. | |||
Copyright Statement | ||||
Copyright (C) The Internet Society (2006). This document is subject | ||||
to the rights, licenses and restrictions contained in BCP 78, and | ||||
except as set forth therein, the authors retain all their rights. | ||||
Acknowledgment | ||||
Funding for the RFC Editor function is currently provided by the | ||||
Internet Society. | ||||
End of changes. 76 change blocks. | ||||
254 lines changed or deleted | 371 lines changed or added | |||
This html diff was produced by rfcdiff 1.31. The latest version is available from http://www.levkowetz.com/ietf/tools/rfcdiff/ |