Subject: [nfsv4] ACLs and modes

From: Sam Falkner <[email-masked]>
Date: Tue, 22 Aug 2006 21:49:56 -0600

The ACL section in minorversion1 draft -06 will have explicitly  
stated requirements about ACLs and modes, with the algorithms moved  
into an appendix.  The algorithms in the appendix meet the  
requirements in the ACL section, so no semantic changes have been  
made.  In particular, the ACL section still recommends keeping the  
ACL and the mode in sync.  In this email, "mode" means what it means  
in RFC 3530 and minorversion1: "read/write/execute permission for  
owner/group/other".

If we want to keep the ACL and mode in sync, it follows that  
something must be done with an existing ACL upon setting a mode.  The  
most basic thing to do is to throw away any existing ACL.  There are  
some who don't want to take this approach, one problem being that  
create-time inheritance isn't secure unless there's a scheme for a  
mode affecting an ACL.  So a fundamental question is, how do you "fix  
up" an ACL to accomodate the new mode?

Andreas' recent email, with the subject "NFSv4 ACLs: (acl, masks)  
pairs", covers some details about one way to do it: introducing a new  
file attribute that affects ACL processing.  The recent ACL meetings  
in Broomfield did not reach the consensus that this is the way to  
solve the problem.

In fact, there are at least four ways to do it.

1) throw away the ACL

2) introduce a mask attribute

3) use DENY ACEs to augment the ACL

4) use DENY ACEs to augment the ACL, but introduce a new ACE flag to  
tag these special DENY ACEs

Most vendors are currently doing (1).  Andreas proposes (2).  The  
algorithms in the appendix implement (3).  As mentioned in the  
Broomfield meeting minutes, Bruce prefers that masking not be done  
heuristically, but rather with protocol enhancements: this would  
include (2) and (4).

(1) and (3) do not require changing the over-the-wire protocol.   
Windows servers can implement them 100% on a native Windows  
filesystem.  Multi-protocol servers benefit, since everything is  
visible to CIFS clients as well as NFS clients.  NFSv4.0 clients and  
servers benefit, since they would be on equal ground with 4.1.

If the world moves away from modes and toward ACLs, I think (3) has  
the best fit.  If there is an unsolvable problem with (3), and we  
really did have to add to the over-the-wire protocol, then I would  
prefer (4).

Two complaints have been made about (3).  One is that following a  
chmod, the current algorithms in the appendix end up with an ACL that  
has DENY ACEs following ALLOW ACEs, which confuses Windows ACL GUIs.   
This can be fixed.  I have planned to submit an I-D detailing a new  
algorithm similar to the old, but producing windows-acl-gui-friendly  
ACLs.  So this is a non-issue with regard to (3).

The other complaint is that applying a new mode can change DENY ACEs,  
but what if that's not what the end user wanted?  So let's detail  
which DENY ACEs are changed, and when.

Briefly (see the new ACL section for more details), the requirement  
is to grant supplemental users no more permission than the  
owner_group upon setting a new mode.  So if an ACL gives samf read/ 
write/exec, and the file is chmoded 600, samf won't have any access.   
If the file is later chmoded 664, samf will have read/write, but not  
exec.

The algorithms in the appendix achieve this by adding or modifying  
DENY ACEs upon setting a new mode.  So if we start with the ACL  
fragment:

...
[email-masked]:READ_DATA/WRITE_DATA/EXECUTE::ALLOW
...

Then a chmod of 600 results in

...
[email-masked]:READ_DATA/WRITE_DATA/EXECUTE::DENY
[email-masked]:READ_DATA/WRITE_DATA/EXECUTE::ALLOW
...

Then a future chmod to 664 results in

...
[email-masked]:EXECUTE::DENY
[email-masked]:READ_DATA/WRITE_DATA/EXECUTE::ALLOW
...

Notice that we changed the DENY ACE in place.  That is where the  
argument arises: what if an end user doesn't want it messed with,  
even in the face of a chmod?

The algorithms in the appendix will change a DENY ACE only under the  
following circumstances:

1) the two ACEs are adjacent
2) the "who" values are the same
3) the flags are the same
4) the first is a DENY, the second is an ALLOW
5) the access_mask of the DENY is a subset of the access_mask of the  
ALLOW

Then, the DENY is only affected if it is denying a permission that is  
being granted to the owner_group in the new incoming mode.  Condition  
number (1) may be relaxed in a future algorithm, to make ACLs that  
are more friendly to the Windows ACL GUI.

I am of the opinion that it is vanishingly unlikely that an end user  
would first create such a construct in an ACL, and then be upset when  
a chmod is performed such that permissions are given to the  
owner_group that are undesirable to give to samf.  In other words,  
suppose you don't want samf to read, write or exec, but rather than  
delete or modify the ALLOW ACE, you stick a DENY in front and leave  
the ALLOW, and then you become upset when a chmod 660 grants read/ 
write to samf as well as the owning group.

But let's say that there is some rational way that the above scenario  
is a problem.  Instead of the five conditions listed above, you could  
add a flag to the DENY ACE, saying "this ACE was introduced through a  
chmod, and it may be altered in a future chmod".    An ACL editor  
would never set this flag, but it would carry it along in a read/ 
modify/write of an ACL.  An obvious disadvantage is that this new  
flag won't be visible to CIFS clients; so a CIFS client doing read/ 
modify/write will make the DENY ACE immutable as far as a future  
chmod goes.

* * *

Let's restate the four ways we've been discussing to augment an ACL  
upon chmod:

1) throw away the ACL

2) introduce a new file attribute to hold a mask

3) use DENY ACEs to augment the ACL

4) use DENY ACEs to augment the ACL, but introduce a new ACE flag to  
tag these special DENY ACEs

(1) has security issues with create-time inheritance.  (2) and (4)  
change the over-the-wire protocol in ways that are different than  
Windows, CIFS, and NFSv4.0.  I vote for (3).

- Sam

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

---

From: [email-masked]
Date: Wed, 23 Aug 2006 13:00:44 -0400

>> -----Original Message-----
>> From: Sam Falkner [mailto:[email-masked]] 
>> Sent: Tuesday, August 22, 2006 23:50
>> To: [email-masked]
>> Subject: [nfsv4] ACLs and modes
>> 

The alternative, which we adopted is to rewrite the ACL, but 
preserve the inherited ACEs

>> servers benefit, since they would be on equal ground with 4.1.

Because of interoperability and simplicity reasons, option 1 is the
preferable solution, with option 3 a viable alternative
for vendors who would like to implement both options.

>> ACLs.  So this is a non-issue with regard to (3).

I agree that this can be easily fixed.

---

From: "J. Bruce Fields" <[email-masked]>
Date: Wed, 23 Aug 2006 13:16:12 -0400

On Tue, Aug 22, 2006 at 09:49:56PM -0600, Sam Falkner wrote:
> So a fundamental question is, how do you "fix  up" an ACL to
> accomodate the new mode?

That's the wrong question.  Everyone wants a chmod to affect the ACL
somehow--after I do a

	chmod 600

the server had better not permit anything to users other than the owner.

The tricky point is that some people want the sequence

	chmod 600
	chmod 644

to *restore* permissions that the ACL used to give to other users.

My position is: fine.  If you want to do that locally on the server, go
ahead.  If you want to actually expose the mechanism that you use to do
this stuff, to the point where you can even allow a client in the know
to do a read-modify-write in the middle:

	chmod 600
	getacl
	setacl
	chmod 644

and still get some permissions restored, then I'm OK with that too.  But
I am not willing to "tunnel" this extra information over the ACL
protocol itself.

If we're going to do this stuff, then we need entirely separate (and
optional) protocol mechanism for it, so we can ensure that only
consenting servers and clients ever have to see it.

--b.

---

From: "J. Bruce Fields" <[email-masked]>
Date: Wed, 23 Aug 2006 13:17:49 -0400

> preserve the inherited ACEs

So you end up with something like this?:

	OWNER@:owner bits::ALLOW
	GROUP@:group bits::ALLOW
	EVERYONE@:other bits::ALLOW
	inherited ACEs here?

--b.

---

From: "J. Bruce Fields" <[email-masked]>
Date: Wed, 23 Aug 2006 13:45:35 -0400

> 5) the access_mask of the DENY is a subset of the access_mask of the  

I don't care how unlikely this is; we should never require this kind of
rare case.  Unusual corner cases like these are security holes waiting
to happen.

We shouldn't have cases where a chmod after a setacl may sometimes (in
.0001% of all cases) elevate permissions unexpectedly.

The only time when we should allow a chmod to elevate unrelated
permissions is when either:

	1) it's restoring permissions removed by a previous chmod (with
	   *no* intervening setacl), or

	2) the user and client have explicitly indicated that they
	   understand this mask business, by using an optional protocol
	   designed for the purpose.

> are more friendly to the Windows ACL GUI.

I think that may be tricky; it's likely to be common that the
permissions given to named users are less than those given to the file
owner, and there may be no way to lift the DENY ACEs for those users
above the owner's ace without risking denying stuff to the owner too.

--b.

---

From: Sam Falkner <[email-masked]>
Date: Wed, 23 Aug 2006 12:00:05 -0600

> the server had better not permit anything to users other than the  

The ACL section requires this.

> to *restore* permissions that the ACL used to give to other users.

The ACL section does not require this.  It allows it, but doesn't  
require it.

> I am not willing to "tunnel" this extra information over the ACL

In other words, not use heuristics on the ACL to restore when the  
chmod-644 happens.  Again, the ACL section doesn't require this.

> consenting servers and clients ever have to see it.

My position is: I'm against adding new things to the v4 protocol that  
would be invisible to NFSv4.0 and CIFS, and unimplementable on Windows.

* * *

By the way, your examples shed light on the question nicely -- thanks.

- Sam

---

From: "J. Bruce Fields" <[email-masked]>
Date: Wed, 23 Aug 2006 15:40:12 -0400

> The ACL section does not require this.  It allows it, but doesn't  

The protocol doesn't require this masking behavior.  But unix-y servers
keep doing it.

If we're willing to give up on doing it entirely, great--I'm happy.
But we're not actually doing that....  So apparently masking is required
if certain servers are going to get NFSv4 ACL's supported natively on
their filesystems.

That being the case, the question is how to make sure these server's
masking behavior has the minimum impact on clients and servers that
don't care about it.

> would be invisible to NFSv4.0 and CIFS, and unimplementable on Windows.

Windows/CIFS are never going to implement any of this anyway, nor should
they.  We're lucky to get mode bits out of them at all, and they're
certainly not going to bend over backwards to support the sort of chmod
600/chmod 644 behavior we're talking about.

That's why the proper way to support this behavior is with an entirely
optional and distinct protocol mechanism that they never have to know
about, rather than something that requires additional manipulations of
the ACL's that they do see.

--b.

---

From: "J. Bruce Fields" <[email-masked]>
Date: Wed, 23 Aug 2006 16:33:52 -0400

> above the owner's ace without risking denying stuff to the owner too.

To elaborate: representing the mask in the ACL generally requires doing
stuff like replacing every single ALLOW ACE for a named user or group by
a DENY/ALLOW pair.  So you're taking an ACL like (using simplified mode
bits for readability):

	OWNER@   :rw-::ALLOW
	bfields  :rw-::ALLOW
	friends  :rw-::ALLOW

and after a chmod 644 making it:

	OWNER@   :rw-::ALLOW
	bfields  :-wx::DENY
	bfields  :rw-::ALLOW
	friends  :-wx::DENY
	friends  :rw-::ALLOW

It's going to be fun trying to figure out how to move those DENY's.

I'd *much* rather a chmod 644 just:

	OWNER@   :rw-::ALLOW
	bfields  :r--::ALLOW
	friends  :r--::ALLOW

and then store the mask on the side somewhere if you care.

--b.

---

From: "J. Bruce Fields" <[email-masked]>
Date: Wed, 23 Aug 2006 16:52:29 -0400

On Wed, Aug 23, 2006 at 02:20:34PM -0600, Sam Falkner wrote:
> I don't follow this line of reasoning at all.  I say again, it's not  
> required.  You're free to implement native NFSv4 ACLs without the  
> "chmod 600/chmod 644" behavior.  AIX does.  Solaris does, with a ZFS  
> mount option.

OK, I'm happy to hear that.  (Is that mount option the default?)

> The question is this: is it worth extending the protocol to achieve  
> the "chmod 600/chmod 644" behavior.  I say that it causes more  
> problems than it solves.

What problems do you see it as causing?  It's optional, easy to
implement, and easy to ignore.

The one minor problem it solves is this: if your server's exported
filesystem supports masks (as apparently some do or will), then
exporting those masks allows a client to predict what will happen after
a chmod, whereas the ACL on its own would not (without also knowing the
previous history of chmod's).

Clients (like Windows clients) that never do chmod's will never care.
Maybe unix-like clients will, I don't know.

> No changes need to be made to the ACL section, unless we do decide to  
> add to the protocol to expose a mask attribute.

Sure, though it sounds like we should at least replace the example
algorithms by algorithms that don't go out of their way to imperfectly
emulate the mask attribute.

--b.

---

From: Sam Falkner <[email-masked]>
Date: Wed, 23 Aug 2006 15:36:07 -0600

> OK, I'm happy to hear that.  (Is that mount option the default?)

Nope.

> implement, and easy to ignore.

It's adding more complexity to NFSv4.  That's fine, if there is a  
consensus that it's the way to solve the problem, and that the  
problem is worth solving.

- Sam

---

From: "J. Bruce Fields" <[email-masked]>
Date: Wed, 23 Aug 2006 17:47:37 -0400

> >OK, I'm happy to hear that.  (Is that mount option the default?)

So, the obvious question, to get back to what Mario asked--why not?  Why
insist on this chmod 600/chmod 644 behavior by default even when
starting completely from scratch with native NFSv4 ACLs?

Way back in the mists of time were there lots of users complaining about
losing ACLs on chmod?

> problem is worth solving.

Well, obviously I have a very strong opinion on the first question, not
so much on the second:

	- If we care about masks (in particular, if servers are going to
	  implement the things anyway), then we should do them with extra
	  protocol, not ACL manipulations that add more DENY's.

	- If we don't care about masks, I can live with that.

--b.

---

From: Sam Falkner <[email-masked]>
Date: Wed, 23 Aug 2006 14:20:34 -0600

> The protocol doesn't require this masking behavior.  But unix-y  

AIX doesn't.

> If we're willing to give up on doing it entirely, great--I'm happy.

You're certainly free to give up on doing it.

- Sam

---

From: Andreas Gruenbacher <[email-masked]>
Date: Sat, 26 Aug 2006 22:47:32 +0200

On Wednesday 23 August 2006 19:00, [email-masked] wrote:
> >> chmod, the current algorithms in the appendix end up with an ACL
> >> that has DENY ACEs following ALLOW ACEs, which confuses Windows
> >> ACL GUIs. This can be fixed.  I have planned to submit an I-D detailing
> >> a new algorithm similar to the old, but producing
> >> windows-acl-gui-friendly ACLs.  So this is a non-issue with regard to
> >> (3).  
>

I disagree -- (3) cannot be fixed to produce "Windows-friendly" ACLs. Here is 
a counter example:

	OWNER@:READ_DATA/WRITE_DATA::ALLOW
	GROUP@:READ_DATA/WRITE_DATA::ALLOW
	EVERYONE@:READ_DATA::ALLOW

When mode 0644 is applied to the ACL, Sam's masking algorithm causes a 
GROUP@:WRITE_DATA::DENY ACE to be prepended to the GROUP@ ALLOW ACE, i.e.,

	...
	GROUP@:WRITE_DATA::DENY
	GROUP@:READ_DATA/WRITE_DATA::ALLOW
	...

Moving this DENY ACE before all ALLOW ACEs will invariably deny principals 
that match both OWNER@ and GROUP@ ACEs WRITE_DATA access.

Andreas

-- 
Andreas Gruenbacher <[email-masked]>
Novell / SUSE Labs

---

From: Andreas Gruenbacher <[email-masked]>
Date: Sun, 27 Aug 2006 00:08:23 +0200

On Wednesday 23 August 2006 23:36, Sam Falkner wrote:
> >>> That's why the proper way to support this behavior is with an
> >>> entirely optional and distinct protocol mechanism that they never
> >>> have to know about, rather than something that requires additional
> >>> manipulations of the ACL's that they do see.
> >>

So you think that the chmod 600/chmod 644 problem is worth solving (as 
otherwise you wouldn't have implemented the DENY ACE masking in ZFS), but you 
are against solving it in a way that allows clients to decide if they want to 
be bothered with it?

> It's adding more complexity to NFSv4.

First, the (acl, masks) approach can be implemented server-side with or 
without exposing the masks to clients: if the masks are not exposed (e.g., 
with NFSv4.0 clients), the server needs to presented the client an ACL that 
has the masks applied.

Second, allowing clients to retrieve the masks as an optional file attribute 
has the advantage that files can be copied between systems that care without 
loss of information.

Third, servers and/or clients that don't care can simply ignore the new 
attribute. I claim that this adds a very small amount of complexity, and only 
to participants that actually care.

On the other hand, the recommendation in the informational algorithms of 
injecting DENY ACEs throughout the ACL and presenting unsuspecting clients 
with an ACL that has alternating DENY and ALLOW ACEs does drastically change 
what clients will see quite: the Windows ACL editor moves DENY ACEs before 
ALLOW ACEs, and so it will royally screw up on those ACLs. The guesswork that 
is required on the server to figure out which DENY ACEs to update upon a 
successive chmod doesn't make this approach any more attractive to me.

> That's fine, if there is a consensus that it's the way to solve the problem,

This is one way to solve the problem, and my posting regarding (acl, masks) 
pairs should have gone a long way in showing why it is a very reasonable 
approach that can be implemented easily. The approach does not interfere with 
any other approaches that may exist to solve the same problem, so we have 
nothing to lose.

A complete implementation of the (acl, masks) pair approach, including a 
relatively simple and very well-behaving algorithm for applying masks to an 
arbitrary NFSv4 ACL, can be found at http://www.suse.de/~agruen/nfs4acl/, by 
the way. Those interested may want to check file fs/nfs4acl_compat.c in 
patches/ext3-nfs4acl.diff in the tarball.

> and that the problem is worth solving.

I very much think that the problem is worth solving. Others may disagree, but 
that doesn't mean it's justified to force those that do care to not solve the 
problem in a straightforward, clean and simple way. The proposed approach 
does not disadvantage those that do not care, or preclude other approaches.

Andreas

---

From: Sam Falkner <[email-masked]>
Date: Sun, 27 Aug 2006 09:32:30 -0600

On Aug 26, 2006, at 2:47 PM, Andreas Gruenbacher wrote:

> GROUP@:WRITE_DATA::DENY ACE to be prepended to the GROUP@ ALLOW ACE,

No it doesn't.  :-)  And please don't discredit the other people who  
worked on the algorithm by calling it "Sam's masking algorithm"; thanks.

But we're talking about a new algorithm.  That's what I was talking  
about, and I believe that's what Mario was talking about.

- Sam

---

From: Andreas Gruenbacher <[email-masked]>
Date: Sun, 27 Aug 2006 18:13:03 +0200

On Sunday 27 August 2006 17:32, Sam Falkner wrote:
> No it doesn't.  :-)

So how are you planning on inserting the required GROUP@:WRITE_DATA::DENY ACE 
before the OWNER@ ALLOW ACE without denying processes that are both the owner 
and the owning group WRITE_DATA? My point still holds.

After giving this exampleI realized that Bruce already gave an example that 
shows the same problem in the same thread on Wed, 23 Aug 2006 16:33:52 -0400.

So once again, this cannot be fixed.

> And please don't discredit the other people who 

Sorry about that; please make it "the algorithm that Sam is advocating".

> about, and I believe that's what Mario was talking about.

Sam, please show this alleged new algorithm that solves this problem, and 
you'll get full credit for fixing the unfixable.

Thanks,
Andreas