Subject: Re: [nfsv4] automatic inheritance

From: "J. Bruce Fields" <[email-masked]>
Date: Thu, 2 Nov 2006 16:09:14 -0500

On Thu, Nov 02, 2006 at 10:42:39AM -0800, Yoder, Alan wrote:
> Is separating the DACL and SACL ACEs, as Windows
> does, out of the question at this point?  I'm
> trying to think about this, and that seems like
> far the best solution so far.

I think it's not out of the question; I've been meaning to write a
revision that does this.  I'll try to get out new language tonight.

I think the idea is to add two new attributes, sacl and dalc, which
would replace the current acl attribute (though we must ensure it's easy
for a server to support all three).

They would be identical to the current acl attribute, except that audit
and alarm aces would go into the sacl and allow/deny into the dacl.  And
we'd add a new flag at the top level, so instead of being a simple
nfsace4<>, the sacl and dacl would each look like

	struct nfsacl4 {
		uint32_t flags;
		nfsace4<> acelist;
	}

and then we could stick the acl_protected and acl_auto_inherit bits in
the flags field instead of requiring separate attributes.

--b.

_______________________________________________
nfsv4 mailing list
[email-masked]
https://www1.ietf.org/mailman/listinfo/nfsv4

---

From: "Yoder, Alan" <[email-masked]>
Date: Thu, 2 Nov 2006 10:42:39 -0800

Alan 

> -----Original Message-----
> From: J. Bruce Fields [mailto:[email-masked]] 
> Sent: Friday, October 06, 2006 4:31 PM
> To: [email-masked]
> Subject: Re: [nfsv4] automatic inheritance
> 
> On Fri, Oct 06, 2006 at 07:21:16PM -0400, J. Bruce Fields wrote:
> > Here's my attempt at specifying automatic inheritance.  
> It's in the form
> > of a diff against the -07 source.  I hope that's not too annoying to
> > read....  Skip down to the section titled "Automatic 
> Inheritance" for
> > the meat of it.
> 
> By the way, one known issue: Mike Eisler pointed out one subtle
> difference between NFSv4 and NT ACLs during the last conference call,
> which is that Windows separates the "DACL" (ALLOW and DENY ACEs) from
> the "SACL" (AUDIT and ALARM ACEs), whereas we lump them all 
> together in
> one object.
> 
> There's some concern this could cause problems, for example 
> if a client
> that doesn't understand AUDIT and ALARM ACEs discards them when it
> modifies the ACL.
> 
> This also affects automatic inheritance, which in Windows can be
> controlled separately for DACLs and SACLs; for example, automatic
> inheritance might be turned on for one but not the other.  
> I've ignored
> this problem for now....
> 
> --b.
>

---

From: "J. Bruce Fields" <[email-masked]>
Date: Thu, 2 Nov 2006 22:51:04 -0500

> revision that does this.  I'll try to get out new language tonight.

OK, here's my attempt.  Again, I hope the form of a diff (this time
against the -08 sources) isn't too awkward to read.

My feeling on the dacl (ALLOW and DENY) / sacl (AUDIT and ALARM)
separation is that it isn't really necessary if we aren't doing
automatic inheritance: if you have a user or system interface that
doesn't understand AUDIT or ALARM ACEs, then it should be easy to
implement the interface using a read-modify-write that preserves any
AUDIT or ALARM ACEs.  Maybe I'm missing something.

But if our goal is to support applications using the automatic
inheritance features introduced in Windows 2000, then I guess we do have
to give them independent control over automatic inheritance for the two
types of acl, since Windows gives them that control.

Introducing the sacl and dacl as new file attributes actually allows
some minor simplification of the handling of backwards compatibility.

As usual, any review (especially from people with experience with
Windows ACLs) is greatly appreciated.

--b.

---

 dotx.d/head.x                         |   27 ++++++
 nfsv41_middle_fileattributes.xml      |   15 +++
 nfsv41_middle_fileattributes_acls.xml |  137 +++++++++++++++++++++++++++++++++-
 3 files changed, 177 insertions(+), 2 deletions(-)

diff --git a/dotx.d/head.x b/dotx.d/head.x
index 064a774..7b8a722 100755
--- a/dotx.d/head.x
+++ b/dotx.d/head.x
@@ -266,6 +266,7 @@ const ACE4_INHERIT_ONLY_ACE		= 0x0000000
 const ACE4_SUCCESSFUL_ACCESS_ACE_FLAG	= 0x00000010;
 const ACE4_FAILED_ACCESS_ACE_FLAG	= 0x00000020;
 const ACE4_IDENTIFIER_GROUP		= 0x00000040;
+const ACE4_INHERITED_ACE		= 0x00000080;

 /*
@@ -340,6 +341,25 @@ struct nfsace4 {
 };
 
 /*
+ * ACL flag
+ */
+typedef uint32_t aclflag4;
+
+/*
+ * ACL flag values
+ */
+const ACL4_AUTO_INHERIT		= 0x00000001;
+const ACL4_PROTECTED		= 0x00000002;
+
+/*
+ * Version 4.1 Access Control List definition
+ */
+struct nfsacl41 {
+	aclflag4	flag;
+	nfsace4<>	aces;
+};
+
+/*
  * Field definitions for the fattr4_mode attribute
  */
 const MODE4_SUID = 0x800;  /* set user id on execution */
@@ -619,6 +639,11 @@ typedef retention_set4	fattr4_retention_
 typedef retention_get4	fattr4_retentevt_get;
 typedef retention_set4	fattr4_retentevt_set;
 typedef uint64_t	fattr4_retention_hold;
+typedef nfsacl41	fattr4_dacl;
+typedef nfsacl41	fattr4_sacl;
+
+typedef bool		fattr4_acl_auto_inherited;
+typedef bool		fattr4_acl_protected;
 
 /*
  * Mandatory Attributes
@@ -701,6 +726,8 @@ const FATTR4_RETENTION_SET	= 70;
 const FATTR4_RETENTEVT_GET	= 71;
 const FATTR4_RETENTEVT_SET	= 72;
 const FATTR4_RETENTION_HOLD	= 73;
+const FATTR4_DACL		= 74;
+const FATTR4_SACL		= 75;
 
 typedef opaque	attrlist4<>;
 
diff --git a/nfsv41_middle_fileattributes.xml b/nfsv41_middle_fileattributes.xml
index c157784..072ad2c 100755
--- a/nfsv41_middle_fileattributes.xml
+++ b/nfsv41_middle_fileattributes.xml
@@ -175,7 +175,8 @@
 	      space_used, system, time_access, time_backup,
 	      time_create, time_metadata, time_modify,
 	      mounted_on_fileid,
-	      layout_type, layout_hint, layout_blksize, layout_alignment
+	      layout_type, layout_hint, layout_blksize, layout_alignment,
+	      dacl, sacl
 	    </t>
 	  </list>
 	</t>
@@ -324,6 +325,12 @@
 	Ownership" privilege).
       </c>
 
+      <c>dacl</c><c>74</c><c>nfsacl41&lt;></c><c>R/W</c>
+      <c>
+        Automatically inheritable access control list used
+	for determining access to filesystem objects.
+      </c>
+
       <c>dir_notif_delay</c><c>56</c><c>nfstime4</c><c>READ</c>
       <c>
 	notification delays on directory attributes
@@ -552,6 +559,12 @@
         on the file object. SETATTR use only.
       </c>
 
+      <c>sacl</c><c>75</c><c>nfsacl41&lt;></c><c>R/W</c>
+      <c>
+        Automatically inheritable access control list used
+	for auditing.
+      </c>
+
       <c>send_impl_id</c><c>58</c><c>impl_ident4</c><c>WRITE</c>
       <c>
 	Client provides server with its implementation identity via SETATTR.
diff --git a/nfsv41_middle_fileattributes_acls.xml b/nfsv41_middle_fileattributes_acls.xml
index 318b8aa..0bf9527 100755
--- a/nfsv41_middle_fileattributes_acls.xml
+++ b/nfsv41_middle_fileattributes_acls.xml
@@ -582,6 +582,7 @@
            const ACE4_SUCCESSFUL_ACCESS_ACE_FLAG   = 0x00000010;
            const ACE4_FAILED_ACCESS_ACE_FLAG       = 0x00000020;
            const ACE4_IDENTIFIER_GROUP             = 0x00000040;
+	   const ACE4_INHERITED_ACE                = 0x00000080;
                         </artwork>
                     </figure>
                         A server need not support any of these flags. If the
@@ -699,7 +700,22 @@
                                     who value equal to one of the special
                                     identifiers outlined in
                                     <xref target="acewho" />.
-                            </t>
+				</t>
+
+                                <t hangText="ACE4_INHERITED_ACE">
+				    <vspace />
+                                    Indicates that this ACE is inherited from
+				    a parent directory.  A server that supports
+				    automatic inheritance will place
+				    this flag on any ACEs inherited from the
+                                    parent directory when creating a new
+				    object.  Client applications will use this
+				    to perform automatic inheritance.
+				    Clients and servers MUST clear this
+				    bit in the acl attribute; it may only
+				    be used in the dacl and sacl attributes.
+				</t>
+
                         </list>
                     </t>
                 </section>
@@ -1232,6 +1248,125 @@
                     target="setattr" />.
                 </t>
             </section>
+	    
+            <section title="Automatic Inheritance">
+	      <t>In addition to the acl attribute described above, a server
+	        may also choose to support the dacl and sacl attributes.
+		These two attributes are identical to the acl attribute,
+		except that only ALLOW and DENY aces are permitted in the
+		dacl attribute, and only AUDIT and ALARM aces are permitted
+		in the sacl attribute.  Also, the sacl and dacl attributes
+		both have an additional flag field which applies to the
+		entire sacl or dacl; two flag values are defined
+                    <figure>
+                        <artwork>
+	   const ACL4_AUTO_INHERIT                 = 0x00000001;
+	   const ACL4_PROTECTED                    = 0x00000002;
+                        </artwork>
+                    </figure>
+		and all other bits must be cleared.  Finally, the
+		ACE4_INHERITED_ACE flag may be set in the acess of the sacl
+		or dacl (whereas it must always be cleared in the acl).
+	      </t>
+	      <t>
+	        Together these features allow a server to support automatic
+		inheritance, which we now explain in more detail.
+	      </t>
+              <t>
+		Inheritable ACEs are normally inherited by child objects only
+		at the time that the child objects are created; later
+		modifications to inheritable ACEs do not result in
+		modifications to inherited ACEs on descendents.
+              </t>
+              <t>
+		However, the dacl and sacl provide an optional mechanism
+		which allows a client application to propagate changes to
+		inheritable ACEs to an entire directory hierarchy.
+              </t>
+              <t>
+	        A server that supports this performs inheritance at object
+		creation time in the normal way, but also sets the
+		ACE4_INHERITED_ACE flag on any inherited ACEs as they are
+		added to the new object.
+              </t>
+              <t>
+		A client application such as an ACL editor may then propagate
+		changes to inheritable ACEs on a directory by recursively
+		traversing that directory's descendants and modifying each ACL
+		encountered to remove any ACEs with the ACE4_INHERITED_ACE flag
+		and to replace them by the new inheritable ACEs (also with the
+		ACE4_INHERITED_ACE flag set).  It uses the existing ACE
+		inheritance flags in the obvious way to decide which ACEs to
+		propagate.  (Note that it may encounter further inheritable
+		ACEs when descending the directory heirarchy, and that those
+		will also need to be taken into account when propagating
+		inheritable ACEs to further descendants.)
+              </t>
+              <t>
+		The reach of this propogation may be limited in two ways:
+		first, automatic inheritance is not performed from any
+		directory ACL that has the ACL4_AUTO_INHERIT flag
+		cleared; and second, automatic inheritance stops wherever
+		an ACL with the ACL4_PROTECTED flag is set, preventing
+		modification of that ACL and also (if the ACL is set on
+		a directory) of the ACL on any of the object's descendants.
+              </t>
+	      <t>
+	        This propagation is performed independently for the sacl
+		and the dacl attributes; thus the ACL4_AUTO_INHERIT and
+		ACL4_PROTECTED flags may be independently set for the sacl
+		and the dacl, and propagation of one type of acl may continue
+		down a heirarchy even where propagation of the other acl has
+		stopped.
+	      </t>
+	      <t>
+	        New objects should be created with a dacl and a sacl that
+		both have the ACL4_PROTECTED flag cleared and the
+		ACL4_AUTO_INHERIT flag set to the same value as that on,
+		respectively, the sacl or dacl of the parent object.
+	      </t>
+	      <t>
+	        Both the dacl and sacl attributes are optional, and a server
+		may support one without supporting the other.
+	      </t>
+              <t>
+	        A server that supports both the old acl attribute and
+		one or both of the new dacl or sacl attributes must do so
+		in such a way as to keep all three attributes consistent
+		with each other.  Thus the ACEs reported in the acl attribute
+		should be the union of the ACEs reported in the dacl and
+		sacl attributes, except that the ACE4_INHERITED_ACE flag must
+		be cleared from the ACEs in the acl.  And of course a
+		client that queries only the acl will be unable to determine
+		the values of the sacl or dacl flag fields.
+              </t>
+              <t>
+	        When a client performs a SETATTR for the acl attribute,
+		the server SHOULD set the ACL4_PROTECTED flag to true on
+		both the sacl and the dacl.  By using the acl attribute,
+		as opposed to the dacl or sacl attributes, the client signals
+		that it may not understand automatic inheritance, and thus
+		cannot be trusted to set an ACL for which automatic
+		inheritance would make sense.
+              </t>
+              <t>
+		When a client application queries an ACL, modifies it, and sets
+		it again, it should leave any ACEs marked with
+		ACE4_INHERITED_ACE unchanged, in their original order, at the
+		end of the ACL.  If the application is unable to do this, it
+		should set the ACL_PROTECTED flag.  This behavior
+		is not enforced by servers, but violations of this rule may
+		lead to unexpected results when applications perform automatic
+		inheritance.
+              </t>
+              <t>
+		If a server also supports the mode attribute, it SHOULD set the
+		mode in such a way that leaves inherited ACEs unchanged, in
+		their original order, at the end of the ACL.  If it is unable
+		to do so, it SHOULD set the ACL4_PROTECTED flag on the file's
+		dacl.
+              </t>
+            </section>
         </section>
     </section>
 </section>