2017-12-07 19:43:31

by Drew Leske

[permalink] [raw]
Subject: Non-root chown, NFSv4 ACLs

Hi all,

I have been unable to find clear information on this so apologies if =
this is a poor question for this mailing list.

I have an NFS fileserver exporting to a client system where a web =
service manages files on behalf of logged-in users. In order to do =
this, the service must be able to manipulate ownership of files and =
directories, but it is undesirable to run the web service as root. The =
web service is given the `CAP_CHOWN` capability through `setcap(8)`. =
This works fine on a local filesystem but does not work under NFS.

I have replicated this on a test server mounting as either NFS v3 or v4. =
To test, I make a copy of `/bin/chown` and give it the `CAP_CHOWN` =
capability. On a local filesystem, I can then, as myself, change the =
ownership of a file to some other user. On the NFS-mounted filesystem, =
I get `Operation not permitted`. I have tried this on v3 and v4 to the =
same result. (On v4.1 I receive =E2=80=9CInvalid argument=E2=80=9D =
whether as an unprivileged user or as root=E2=80=94I have not looked =
further into this as I suspect it=E2=80=99s irrelevant to my current =
problem.)

In looking into ACLs to see if they may provide the answer, I came =
across the NFSv4 ACE permission of `o` for ownership. This seemed to me =
to be exactly what I needed. Unfortunately, while this permission =
appears to be accepted, it is not applied and has no effect: subsequent =
calls to `nfs4_getfacl` show no change, and ownership changes are still =
disallowed. I have tried enabling ACLs and user extended attributes on =
the exported filesystem, but they appear to have no effect.

I understand that NFSv4 ACLs are not fully supported in Linux due to the =
inoperability with POSIX ACLs, however, a Linux-NFS wiki page on ACLs =
(http://wiki.linux-nfs.org/wiki/index.php/ACLs) describing the existing =
mapping of NFSv4 ACLs to POSIX ACLs states that while the mapping is =
imperfect, =E2=80=9Cit accepts most NFSv4 ACLs=E2=80=9D and states the =
only exceptions have to do with explicit denies.

I have looked briefly at the `richacls` project, but that=E2=80=99s not =
provided by either of the OS distributions I may use (Ubuntu or CentOS), =
and I don=E2=80=99t know either of the following:

1. Should it be possible for a user to be able to change the ownership =
of a file or directory over NFS, using Linux `CAP_CHOWN`?

2. Should the NFSv4 ACL =E2=80=9Cownership=E2=80=9D permission be =
settable in my environment?

There are two fileservers. On one, the exported filesystem is ZFS; on =
the other (where I am doing most of my testing), the exported filesystem =
is ext4.

At this stage I am open to using either NFS v3 or v4, and have tried =
both. =20

A possible workaround is to have the software call an SUID copy of =
`chown` that is only available to the user ID of the web service, but =
this is less desirable.

Any tips, information or guidance on this would be greatly appreciated.

Thanks,
Drew.

----
Drew Leske=20
Senior Software Developer
D=C3=A9veloppeur de logiciel principal
[email protected]=20






2017-12-07 20:05:15

by Frank Filz

[permalink] [raw]
Subject: RE: Non-root chown, NFSv4 ACLs

> I have been unable to find clear information on this so apologies if this=
is a
> poor question for this mailing list.
>
> I have an NFS fileserver exporting to a client system where a web service=

> manages files on behalf of logged-in users. In order to do this, the ser=
vice
> must be able to manipulate ownership of files and directories, but it is
> undesirable to run the web service as root. The web service is given the=

> `CAP_CHOWN` capability through `setcap(8)`. This works fine on a local
> filesystem but does not work under NFS.
>
> I have replicated this on a test server mounting as either NFS v3 or v4. =
To
> test, I make a copy of `/bin/chown` and give it the `CAP_CHOWN` capabilit=
y.
> On a local filesystem, I can then, as myself, change the ownership of a f=
ile to
> some other user. On the NFS-mounted filesystem, I get `Operation not
> permitted`. I have tried this on v3 and v4 to the same result. (On v4.1=
I
> receive =E2=80=9CInvalid argument=E2=80=9D whether as an unprivileged use=
r or as root=E2=80=94I
> have not looked further into this as I suspect it=E2=80=99s irrelevant to=
my current
> problem.)
>
> In looking into ACLs to see if they may provide the answer, I came across=
the
> NFSv4 ACE permission of `o` for ownership. This seemed to me to be exact=
ly
> what I needed. Unfortunately, while this permission appears to be
> accepted, it is not applied and has no effect: subsequent calls to
> `nfs4_getfacl` show no change, and ownership changes are still disallowed=
=2E I
> have tried enabling ACLs and user extended attributes on the exported
> filesystem, but they appear to have no effect.
>
> I understand that NFSv4 ACLs are not fully supported in Linux due to the
> inoperability with POSIX ACLs, however, a Linux-NFS wiki page on ACLs
> (http://wiki.linux-nfs.org/wiki/index.php/ACLs) describing the existing
> mapping of NFSv4 ACLs to POSIX ACLs states that while the mapping is
> imperfect, =E2=80=9Cit accepts most NFSv4 ACLs=E2=80=9D and states the on=
ly exceptions have
> to do with explicit denies.
>
> I have looked briefly at the `richacls` project, but that=E2=80=99s not p=
rovided by
> either of the OS distributions I may use (Ubuntu or CentOS), and I don=E2=
=80=99t
> know either of the following:
>
> 1. Should it be possible for a user to be able to change the ownership of=
a file
> or directory over NFS, using Linux `CAP_CHOWN`?
>
> 2. Should the NFSv4 ACL =E2=80=9Cownership=E2=80=9D permission be settabl=
e in my
> environment?
>
> There are two fileservers. On one, the exported filesystem is ZFS; on th=
e
> other (where I am doing most of my testing), the exported filesystem is e=
xt4.
>
> At this stage I am open to using either NFS v3 or v4, and have tried both=
=2E
>
> A possible workaround is to have the software call an SUID copy of `chown=
`
> that is only available to the user ID of the web service, but this is les=
s
> desirable.

I think this may be your only solution. NFS/RPC has no way to communicate p=
ermission CAPs to the server.

If CAPs could be user based as well as process based, then you could grant =
the web service's user ID the appropriate CAPs on the server.

NFS v4 ACLs could help, however, they are imperfect since a file owner coul=
d remove the ACE that allows the web service's user ID to change ownership.=


Frank


---
This email has been checked for viruses by Avast antivirus software.
https://www.avast.com/antivirus


2017-12-07 20:21:02

by Drew Leske

[permalink] [raw]
Subject: Re: Non-root chown, NFSv4 ACLs


>> A possible workaround is to have the software call an SUID copy of =
`chown`
>> that is only available to the user ID of the web service, but this is =
less
>> desirable.
>=20
> I think this may be your only solution. NFS/RPC has no way to =
communicate permission CAPs to the server.
>=20
> If CAPs could be user based as well as process based, then you could =
grant the web service's user ID the appropriate CAPs on the server.
>=20
> NFS v4 ACLs could help, however, they are imperfect since a file owner =
could remove the ACE that allows the web service's user ID to change =
ownership.

Frank, thanks for your response. On the CAPs, I figured as much, but =
wondered if there was a way to assign the capability on the server=E2=80=94=
but I believe it=E2=80=99s only process-based, so I=E2=80=99d have to =
assign it to nfsd. However nfsd runs as root and so already has the =
capability. So in essence it seems NFS is the gatekeeper here, a =
thought which appears to be borne out by the traffic I=E2=80=99m seeing =
via `nfstrace`=E2=80=94NFS server returns a permissions error to the =
client. So I wonder how to make the NFS server be okay with that user =
changing the ownership of files?

You are right about the file owners being able to remove the ACE however =
in this particular context the users would not have this ability via the =
web service, and when mounting the filesystem themselves would probably =
not have access to the commands, or know how to use them, or want to; =
and in any case would be warned against doing so.

Drew.=

2017-12-07 21:34:19

by J. Bruce Fields

[permalink] [raw]
Subject: Re: Non-root chown, NFSv4 ACLs

On Thu, Dec 07, 2017 at 11:43:28AM -0800, Drew Leske wrote:
> I have replicated this on a test server mounting as either NFS v3 or
> v4. To test, I make a copy of `/bin/chown` and give it the
> `CAP_CHOWN` capability. On a local filesystem, I can then, as myself,
> change the ownership of a file to some other user. On the NFS-mounted
> filesystem, I get `Operation not permitted`.

Yeah, as others have said, the protocol just gives the client no way to
say "this rpc call is being made by a process that has the CAP_CHOWN
capability". All the server gets is a uid and some gids (or a krb5
principal).

The relevant code for knfsd is in fs/nfsd/auth.c:nfsd_setuser(). It
just temporarily changes the credentials that the current nfsd process
runs with to credentials taken from what the client provided in the rpc
call.

I guess in theory we could provide some way to tell the server that a
certain user to get CAP_CHOWN. Doesn't that it mean it could
effectively access anything by chowning it to its own uid and the
chowning it back? Maybe we'd want some more restrictive capability. Or
maybe you'd be OK with just mapping the user to root.

In theory I wonder if the structured privileges in rfc 7861 could be
used to communicate capabilities?

> I have tried this on v3 and v4 to the same result. (On v4.1 I receive
> “Invalid argument” whether as an unprivileged user or as root—I have
> not looked further into this as I suspect it’s irrelevant to my
> current problem.)

Huh. Chown as root on 4.1 works for me on latest upstream. Hard to
think why 4.1 would make a difference.

--b.

> In looking into ACLs to see if they may provide the answer, I came across the NFSv4 ACE permission of `o` for ownership. This seemed to me to be exactly what I needed. Unfortunately, while this permission appears to be accepted, it is not applied and has no effect: subsequent calls to `nfs4_getfacl` show no change, and ownership changes are still disallowed. I have tried enabling ACLs and user extended attributes on the exported filesystem, but they appear to have no effect.
>
> I understand that NFSv4 ACLs are not fully supported in Linux due to the inoperability with POSIX ACLs, however, a Linux-NFS wiki page on ACLs (http://wiki.linux-nfs.org/wiki/index.php/ACLs) describing the existing mapping of NFSv4 ACLs to POSIX ACLs states that while the mapping is imperfect, “it accepts most NFSv4 ACLs” and states the only exceptions have to do with explicit denies.
>
> I have looked briefly at the `richacls` project, but that’s not provided by either of the OS distributions I may use (Ubuntu or CentOS), and I don’t know either of the following:
>
> 1. Should it be possible for a user to be able to change the ownership of a file or directory over NFS, using Linux `CAP_CHOWN`?
>
> 2. Should the NFSv4 ACL “ownership” permission be settable in my environment?
>
> There are two fileservers. On one, the exported filesystem is ZFS; on the other (where I am doing most of my testing), the exported filesystem is ext4.
>
> At this stage I am open to using either NFS v3 or v4, and have tried both.
>
> A possible workaround is to have the software call an SUID copy of `chown` that is only available to the user ID of the web service, but this is less desirable.
>
> Any tips, information or guidance on this would be greatly appreciated.
>
> Thanks,
> Drew.
>
> ----
> Drew Leske
> Senior Software Developer
> Développeur de logiciel principal
> [email protected]
>
>
>
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
> the body of a message to [email protected]
> More majordomo info at http://vger.kernel.org/majordomo-info.html

2017-12-07 22:54:26

by Drew Leske

[permalink] [raw]
Subject: Re: Non-root chown, NFSv4 ACLs


> Yeah, as others have said, the protocol just gives the client no way =
to
> say "this rpc call is being made by a process that has the CAP_CHOWN
> capability". All the server gets is a uid and some gids (or a krb5
> principal).

That answers that, then. Thank you (and Frank earlier) for clarifying =
that for me.

> I guess in theory we could provide some way to tell the server that a
> certain user to get CAP_CHOWN. Doesn't that it mean it could
> effectively access anything by chowning it to its own uid and the
> chowning it back? Maybe we'd want some more restrictive capability. =
Or
> maybe you'd be OK with just mapping the user to root.

In this context, and I don=E2=80=99t see a lot of use cases for this, =
the web service=E2=80=99s user can do whatever it wants, and basically =
acts like root. On my list of things to try for this case is to map the =
user to root on the server, so that effectively that ID can do whatever =
it wants. I don=E2=80=99t know if this will work and I don=E2=80=99t =
believe it=E2=80=99s a good solution for a couple of different reasons =
(for example, it would apply to other filesystems exported by the =
fileserver).

> Huh. Chown as root on 4.1 works for me on latest upstream. Hard to
> think why 4.1 would make a difference.

If I find anything interesting there I will let you know but I believe =
it to be a red herring. Actually, I just rebuilt the exported =
filesystem and I=E2=80=99m now able to do this with 4.1, so perhaps it =
has to do with the stuff I was playing around with for ACLs.

>> In looking into ACLs to see if they may provide the answer, I came =
across the NFSv4 ACE permission of `o` for ownership. This seemed to me =
to be exactly what I needed. Unfortunately, while this permission =
appears to be accepted, it is not applied and has no effect: subsequent =
calls to `nfs4_getfacl` show no change, and ownership changes are still =
disallowed. I have tried enabling ACLs and user extended attributes on =
the exported filesystem, but they appear to have no effect.
>>=20
>> I understand that NFSv4 ACLs are not fully supported in Linux due to =
the inoperability with POSIX ACLs, however, a Linux-NFS wiki page on =
ACLs (http://wiki.linux-nfs.org/wiki/index.php/ACLs) describing the =
existing mapping of NFSv4 ACLs to POSIX ACLs states that while the =
mapping is imperfect, =E2=80=9Cit accepts most NFSv4 ACLs=E2=80=9D and =
states the only exceptions have to do with explicit denies.

The remaining question for me then is around the NFSv4 ACL and the =
ownership change permission, and whether I should be able to get that to =
work, especially on a stock system. I know there are some issues with =
mapping NFSv4 ACLs to so-called =E2=80=9CPOSIX=E2=80=9D ACLs, but I =
didn=E2=80=99t see anything in the documentation to suggest it isn=E2=80=99=
t implemented. Should I expect this to work without installing the =
richacls software?

Here=E2=80=99s an example of me trying the NFSv4 ACLs for this:

[testdir1] nfs4_getfacl drewsfile
A::OWNER@:rwatTcCy
A::GROUP@:rwatcy
A::EVERYONE@:rtcy
[testdir1] nfs4_setfacl -a A::OWNER@:o drewsfile
[testdir1] nfs4_getfacl drewsfile
A::OWNER@:rwatTcCy
A::GROUP@:rwatcy
A::EVERYONE@:rtcy

So it is accepted, but fails to apply. Here=E2=80=99s trying to assign =
a garbage permission:

[testdir1] nfs4_setfacl -a A::OWNER@:p drewsfile
Bad Ace Mask:p
Failed while inserting ACE(s) (at index 1).

Is this because of the mapping to POSIX ACLs, which has no provision for =
ownership management by non-root users? Does this require the richacls =
software?

Thanks,
Drew.


2017-12-07 23:15:06

by J. Bruce Fields

[permalink] [raw]
Subject: Re: Non-root chown, NFSv4 ACLs

On Thu, Dec 07, 2017 at 02:54:22PM -0800, Drew Leske wrote:
> The remaining question for me then is around the NFSv4 ACL and the
> ownership change permission, and whether I should be able to get that
> to work, especially on a stock system.

No. When you set an ACL, the server just translates that ACL to the
closet POSIX ACL it can find. And the filesystem code just enforces
that POSIX ACL. POSIX ACLs have no equivalent to WRITE_OWNER. I can't
remember what the code in fs/nfsd/nfs4acl.c does--the only choices would
be to either ignore the bit or fail, I think it does the former.

(In theory knfsd could store the full v4 ACL in an extended attribute
and do its own enforcement on the side--I think Samba can do something
like this. This seems complicated to me and I'd rather add richacl
support to the filesystems, but that effort has stalled.)

> I know there are some issues
> with mapping NFSv4 ACLs to so-called “POSIX” ACLs, but I didn’t see
> anything in the documentation to suggest it isn’t implemented. Should
> I expect this to work without installing the richacls software?

You'd have to actually apply the richacls kernel patch. I think you'd
find that more trouble than it's worth.

--b.

2017-12-09 00:53:12

by Drew Leske

[permalink] [raw]
Subject: Re: Non-root chown, NFSv4 ACLs


> (In theory knfsd could store the full v4 ACL in an extended attribute
> and do its own enforcement on the side--I think Samba can do something
> like this. This seems complicated to me and I'd rather add richacl
> support to the filesystems, but that effort has stalled.)


I=E2=80=99m sorry to hear that, I looked at the Git repository =
(https://github.com/andreas-gruenbacher/richacl) and it looked like =
things were slowing down, and the richacl site linked to here and there =
is 404.

Thanks very much for sharing your expertise.

Drew.

----
Drew Leske=20
Senior Software Developer
D=C3=A9veloppeur de logiciel principal


2017-12-13 20:28:04

by Drew Leske

[permalink] [raw]
Subject: Re: Non-root chown, NFSv4 ACLs

>> The remaining question for me then is around the NFSv4 ACL and the
>> ownership change permission, and whether I should be able to get that
>> to work, especially on a stock system.
>=20
> No. When you set an ACL, the server just translates that ACL to the
> closet POSIX ACL it can find. And the filesystem code just enforces
> that POSIX ACL. POSIX ACLs have no equivalent to WRITE_OWNER. I =
can't
> remember what the code in fs/nfsd/nfs4acl.c does--the only choices =
would
> be to either ignore the bit or fail, I think it does the former.

It does the former. The POSIX ACL is stored in a short and the bit for =
NFS4_ACE_WRITE_OWNER is 0x80000, so it just drops off.

> (In theory knfsd could store the full v4 ACL in an extended attribute
> and do its own enforcement on the side--I think Samba can do something
> like this. This seems complicated to me and I'd rather add richacl
> support to the filesystems, but that effort has stalled.)

It seems complicated and would split the POSIX ACL code from the NFSv4 =
ACL code, with little benefit for most people, with more risk due to the =
extra code to be maintained. Given that all the translation code is =
already in place, I would be more inclined to leave it as is and maybe =
store, in addition and optionally, the untranslated NFSv4 ACL =
separately, so enforcement, which currently works, is left alone in the =
implementation and representation, which is lacking due to the =
retranslation back from POSIX ACL to NFSv4 ACL, can be switched on at =
the server if desired and passed back to the clients. But I digress...

I've been looking at this over the last couple of days with the idea of =
storing the WRITE_OWNER permission as additional extended attribute on =
the exported filesystem, initially as an array of UIDs/GIDs. I think =
this should be workable: POSIX ACLs are stored as extended attributes =
and so this would be in addition to that.

Does this seem like a reasonable approach?

Would there be much interest in this, if implemented?

Cheers,
Drew.


Drew Leske
[email protected]




2017-12-19 17:18:33

by J. Bruce Fields

[permalink] [raw]
Subject: Re: Non-root chown, NFSv4 ACLs

On Wed, Dec 13, 2017 at 12:28:01PM -0800, Drew Leske wrote:
> >> The remaining question for me then is around the NFSv4 ACL and the
> >> ownership change permission, and whether I should be able to get that
> >> to work, especially on a stock system.
> >
> > No. When you set an ACL, the server just translates that ACL to the
> > closet POSIX ACL it can find. And the filesystem code just enforces
> > that POSIX ACL. POSIX ACLs have no equivalent to WRITE_OWNER. I can't
> > remember what the code in fs/nfsd/nfs4acl.c does--the only choices would
> > be to either ignore the bit or fail, I think it does the former.
>
> It does the former. The POSIX ACL is stored in a short and the bit for NFS4_ACE_WRITE_OWNER is 0x80000, so it just drops off.
>
> > (In theory knfsd could store the full v4 ACL in an extended attribute
> > and do its own enforcement on the side--I think Samba can do something
> > like this. This seems complicated to me and I'd rather add richacl
> > support to the filesystems, but that effort has stalled.)
>
> It seems complicated and would split the POSIX ACL code from the NFSv4 ACL code, with little benefit for most people, with more risk due to the extra code to be maintained. Given that all the translation code is already in place, I would be more inclined to leave it as is and maybe store, in addition and optionally, the untranslated NFSv4 ACL separately, so enforcement, which currently works, is left alone in the implementation and representation, which is lacking due to the retranslation back from POSIX ACL to NFSv4 ACL, can be switched on at the server if desired and passed back to the clients. But I digress...
>
> I've been looking at this over the last couple of days with the idea of storing the WRITE_OWNER permission as additional extended attribute on the exported filesystem, initially as an array of UIDs/GIDs. I think this should be workable: POSIX ACLs are stored as extended attributes and so this would be in addition to that.
>
> Does this seem like a reasonable approach?
>
> Would there be much interest in this, if implemented?

I don't know. I think it would be awkward to map from NFSv4 or SMB ACLs
to that, so I don't know that it would get adoption by Samba or knfsd.

There may be some simpler solution for your own use case.

--b.