Subject: Re: id's as strings in the spec

From: "William A.(Andy) Adamson" <[email-masked]>
Date: Thu, 13 Jun 2002 17:44:25 -0400

> Peter Astrand wrote: 
> > On Mon, 10 Jun 2002, Noveck, Dave wrote:
> 
> > > However, we realize that in real life, most servers will
> > > store traditional numeric id's for a number of good reasons
> > > (e.g. supporting auth_sys and interacting with v2/v3).  As 
> > > a result, when you SETATTR OWNER and GETATTR it back, you
> > > may not get back the value you set.  
> >
> > It would be nice to always get back what you stored.
> 
> Yes it would.
> 
> > > I think there are some aspects of this non-invertability that
> > > aren't particularly troublesome.  If it happens that there
> > > are a few names that map to the same numeric id, because they
> > > are truly synonyms then a SETATTR-GETATTR sequence is going 
> > > to change things, unlike for more normal attributes.  There's 
> > > not much to do about this but  note that it can happen.
> > 
> > I'm probably a bit naive right know, but what about not
> > allowing/recommending several names to map to the same numeric id? It's 
> > not recommended to have several users with the same uid on UNIX systems 
> > either, at least most people consider this a bad idea. 
> 
> I agree it's a bad idea.  

i disagree.

if you don't allow mapping of several names to a single uid, how do you get 
around the problem of different name formats for different rpcsec_gss 
mechanisms?
x509 DN's, available as an SPKM3 name, and kerberos v5 names have different 
formats, both can legally represent the same user (uid) and  both security 
mechanisms are supported buy rfc3010.

> The question is how far we can mandate
> goodness, while keeping the implementation burden for v4 within
> bounds.  If we tell the server that he needs to guarantee that two
> username will never have the same map to the same uid (even when
> the administrator changes a uid for some reason), means that what
> he has to implement for himself is very significant as oppposed to
> making NIS calls and getting something that most of the time has
> the desirable propertied, but without guarantees.
> 
> In practical terms, the only way that the server can guarantee
> that the id you store will be the one you get back, is to stote
> the string in the local fs, which may not be possible, and if 
> possible, may not be desirable (interaction with v2/v3, etc.).
>
> > > The troublesome case is the large number of strings that 
> > > have no numeric id.  In fact, almost all of the more than
> > > 128**(2**32) possible strings, have no such numric id.  Under
> > > normal circumstances, the client will be able to avoid presenting
> > > any like this, but not always.  So what is the server to do?
> > ...
> > > I think in these cases, we want an error.  The spec should 
> > > define a NFS4ERR_BADOWNER error for non-recognized strings.  
> > > Then at least, if there's a setup problem, it can be called 
> > > to people's attention, and fixed.
> >
> > I agree. 
sounds reasonable. of course, the server in most cases would not have a user
associated with all possible uid/gid either, so this same error could also be 
returned for non-recognized numbers.

> 
> > > Now let's consider the complementary problem.  It may also be 
> > > the case that GETATTR (or READDIR) encounters a numeric id 
> > > for which there is currently no string defined.  This may be 
> > > the result of deleted users or simply the fact that v2/v3 and
> > > local file systems allow you to set owner and group to any
> > > numeric value.  An error here would be highly undesirable. One 
> > > thing to do is to map these to nobody.  The problem is that 
> > > this makes the semantics of a directory to local disk different
> > > from v2/v3.  One might copy a file, even to local disk, and 
> > > as a result change the ownership of files with obsolete or 
> > > other not-currently-set-up users.  
> 
> > You are thinking about the case when root are copying files around, for 
> > example, and ownership is normally preserved?
> 
> > The ownership is at least preserved from the v4 point of view, if you use 
> > an anonymous user.
> 
> Right but the v4 point of view is not the same as the point of
> view of client OS. 
> 
> > >I, at least, would find 
> > > this annoying as a user.  
> > 
> > OTOH, this should only happen if your setup is wrong.
> 
> I have a set of users.  My setup is fine.

i have a set of users each with multiple names mapped to single uids. my setup 
is fine.

> 
> I read in a tar tape that happens to have uid's that I don't have
> in my /etc/passwd.  My setup has not become wrong.
> 
> If I make a change to something and generate the tar tape, on local
> disk or v2 or v3, the only change to the tape will be the change
> I made.  I'd like v4 when used on systems like unix/linux that
> have this traditional behavior, not to interfere with it, even though
> in retrospect, we might decide that exporting numeric id's in that
> fashion was not particularly good choice.
> 
> > >One way that this could be dealt with,
> > > with the spec as it stands, is for the server to return something
> > > like 12345@your-domain but that is not guaranteed to avoid conflict,
> > > since the user 12345 (with numeric id 54321 perhaps) might exist. 
> > > You could do something like 12345@gimme-those-old-time-numeric-
> > > ids.tm (after making a suitable payment to the government of 
> > > Turkmenistan), but I'd like to propose that the spec define a 
> > > more standard escape for this type of situation, something like 
> > > 12345@#.  
> > 
> > Another idea is #12345. 
> 
> > > Further they may accept @# id's (for a SETATTR) if there 
> > > is no other string form id which maps to the same local 
> > > filesystem owner.  They may (SHOULD?) restrict this to 
> > > users with appropriate priviliges, and give others 
> > > NFS4ERR_BADOWNER.  They MUST reject (with NFS4ERR_BADOWNER)
> > > @# id's if there is another string form id which maps to 
> > > that same local filesystem owner.  
> 
> > It seems to me that the client may have a hard time knowing if there is
> > another string form for the owner and what that me be. 
> 
> If client cannot take a numeric id and determine what the matching
> username is, then the whole approach of owners as strings cannot
> work.  It's based on the idea that through some unspecified mechanism
> the client and the server can maintain agreement on the valid set 
> of usernames.
> 
> > Your proposal also
> > means that owner-strings like 12345@# can become invalid to use for a
> > client all of a sudden, if a string-form of that user is created on the
> > server.
> 
> I don't see that as a problem.  I only use such strings when I can't
> map a numeric id to a string.  When I can map such an id, I will be able
> to send the appropriate string and should stop sending the numeric form.
> 
> > I haven't thought about these issues much, but my general feeling is that
> > either we should allow the use of the 12345@#-strings all the time or not
> > at all. Not at all would be preferred, since the concept of UIDs does not
> > belong in the v4 spec.
> 
> Yes but the reality exists.  v2 and v3 are out there and had that concept
> and a lot of stuff has been built up assuming it, such as many local file
> systems that will exist for a long time.
> 
> 
> > >      Mapping that map lots of strings to the same id or restricting
> > >      the range of valid string by returning an error.
> 
> > I prefer recommending/enforcing an one-to-one mapping. 
> 

a one to one mapping won't work given the multiple per file security flavors.

> Recommending is one thing but how do you enforce it?
> 
> > >      What to do about id's in the fs that don't map to any string.  
> > >      Numeric id escape or something else?  (what?)
> > 
> > I prefer an anonymous user string (preferably specified by the spec), but 
> > this is probably just because I haven't understood your explainations why 
> > this is a bad idea :-)
> 
> You've expressed the reason just above.  You'd like one-to-one mappings but
> mapping lots of stuff to a single anonymous user is a very-many-to-one
> mapping.
> 
> 
>  
>  
> 
>  
>

---

From: "Noveck, Dave" <[email-masked]>
Date: Thu, 13 Jun 2002 13:34:09 -0700

Yes it would.

> either, at least most people consider this a bad idea. 

I agree it's a bad idea.  The question is how far we can mandate

---

From: Spencer Shepler <[email-masked]>
Date: Thu, 13 Jun 2002 18:47:43 -0500

> possible, may not be desirable (interaction with v2/v3, etc.).

I agree that we can not place this requirement within the scope of the
NFSv4 protocol and must leave it to a suggestion in
implementation/configuration practice.

-- 
Spencer

---

From: Peter Åstrand <[email-masked]>
Date: Fri, 14 Jun 2002 19:46:33 +0200 (CEST)

> > > other not-currently-set-up users.  

I'm not convinced that your approach with "12345" usernames works. 
Consider what happens if the server and the client does not have the same 
uid/username mapping: You read in a file from tape with uid 4711, which 
does not exist on the client. The client contructs the username "4711" and 
sends over the wire. The server stores the file with uid 4711. Then the 
client does GETATTR. The server, which has a local user with uid 4711, now 
returns "[email-masked]" instead of "4711". The local client does not 
know anything about "[email-masked]", and cannot translate this back 
to uid 4711.

So, the idea of letting the server interpreting "4711" username strings 
does not work if the client and the server does not have the same 
uid/username mappings. And as far as I understand, v4 does not mandate 
that they must. I thought the whole idea of string based usernames was to 
eliminate the need for syncronizing uids between servers and clients. 

> the client and the server can maintain agreement on the valid set 

Really? Where can I find this in the spec?

After thinking about these issues, I (currently :-) believe that this is 
the way to go:

1) The server SHOULD preserve the string in a SETATTR-GETATTR sequence
(at least as long as the server uid/name mapping is not changed). I 
believe that this is necessary to avoid all sorts of strange cases. 

2) How should the server handle a SETATTR for a "unknown" user? I think
there are no "invalid users" from the v4 point of view. The server should
accept ALL username strings, regardless of wether there is a local uid
mapping or not. So, I think NFS4ERR_BADOWNER is a bad idea (yes, I've
changed my mind...). The question is of course how servers that stores
uids in the filesystem should deal with this. I suggest that they can use,
for example, the method described by Marius
(http://playground.sun.com/pub/nfsv4/nfsv4-wg-archive/2002/0209.html):  
Files owned by "unknown" users can be stored under a special uid (like
-2). The real username then has to be stored somewhere else, for example
in an extended attribute (EA) or some other, local database.

Of course, the implementation burden is a bit higher, but not impossible I 
think. 

3) Is it OK to have several usernames for the same uid in NFSv4? Sure,
since the v4 spec does not talk about uids. But you must still ensure that
a SETATTR-GETATTR sequence preserves the username. The easy way to ensure 
this is not to have several users with the same uid, or several uids for 
the same user. 

In practice, UNIX-based servers can detect "wrong setups" by using 
"reverse lookups", in a way similiar to what sshd does with domains & 
IPs: 

On all SETATTR("someuser") requests, the server can assert that
getname(getuid("someuser")) == "someuser". If not, then you have two users
with the same uid. The server logs and returns an error.

On all GETATTR(someuid) requests, the server can assert that 
getuid(getname(someuid)) == someuid. If not, you have several uids for the 
same user. The server logs and returns an error.

4) What should the server do for a GETATTR on a file with a unknown uid?  
Log and return an (server) error. This will only happen if the
uid/username mapping is removed on the server.

5) What about users from different domains? When the server recieves an
userstring (like "[email-masked]"), it should first check if the domain
part matches the servers local domain. If it does, the domain part is
stripped off and the username ("joe") is used. If this username is
unknown, or the domain-part didn't match, the user is treated as an
"unknown" user. The username is stored in EAs or separate metadata
database.

6) Should a special "UID string form" username (like "4711") be included
in the v4 spec? Yes, but this form should not be interpreted by servers;
only by clients. Servers should treat these strange usernames just like
any other unknown username (that is, use EAs or metadata database). (Well,
of course, it's also possible to allocate uids for some of these strange
names. For example, a server can allocate uids 65535-131070 to usernames
"[email-masked]"-"[email-masked]", and use uids < 65535 for normal
usernames.)

Clients can translate from this special form to uids. 

I think this special form should also include the domain name, like
"[email-masked]". This will prevent collisions for clients in different
domains. There is still a chance of collisions if there are several
clients in the same domain that does not have syncronized uid/users
mapping, but I think we can live with that.

I have probably missed something, but to me, it looks like this scheme 
would solve most problems:

* Servers will always return the same username in GETATTR as was used in 
SETATTR

* Clients can store files with "unknown" uids, for example, when reading 
in files via tar from tape. 

>     the range of valid string by returning an error.

A third approach: All strings are valid. 

>     Numeric id escape or something else?  (what?)

When the server finds a file in it's local fs that don't map to any string
(on the server), return an error. When clients need to store files with 
uids that don't map to any string (on the client), the client can use the 
escape mechanism. 

>     If special escapes, what are rules on when thay may be used?

I prefer "[email-masked]", but "4711" is also fine with me.  
"[email-masked]" will prevent using usernames beginning with #, but I
don't think that will upset many users.

-- 
Peter Åstrand                Telephone: +46-13-21 46 00
Cendio Systems               E-mail: [email-masked]
Teknikringen 3
583 30 Linköping
Sweden

---

From: Spencer Shepler <[email-masked]>
Date: Fri, 14 Jun 2002 17:37:45 -0500

> know anything about "[email-masked]", and cannot translate this back 

Your scenario is possible.  However it requires two things: the server
must allow the creation/SETATTR of owner on objects that where the
"owner" does not match that of the RPC credential.  Second, it must
allow the mapping of simple "12345" to a uid of 12345.  The server may
not allow this to happen and may choose (based on implementation or
configuration) to instead map 12345 to "nobody" or to reject the
request entirely.

> eliminate the need for syncronizing uids between servers and clients. 

The NFSv4 specification leaves the mechanism unspecified but as you
have suggested it would lead to a useful NFSv4 configuration if the
client and server shared a common mapping framework.  NFSv4's purpose
of having owner and owner_group be a string of the form of user@domain
was to move away from the unix specific uid -- a level of indirection.
An attempt to uplevel the implementation such that identification
would be more meaningful in the end.

If a client and server cross administrative domains, the mappings of
user@domain are not going to match.  At the least NFSv4 can avoid the
confusion of numeric uids overlapping between these administrative
domains since they will be sending/receiving user@domain-client and
user@domain-server.  If domain-client and domain-server are not
equivalent then each side will know about it and can map to something
more useful than could be mapped with numeric uids.

> Really? Where can I find this in the spec?

That is the intent of the specification and through this discussion we
can work on clarifications to ensure we are all working from the same
perspective.

> Of course, the implementation burden is a bit higher, but not impossible I 

My view is that if the server has enough information to process the
RPC credentials, then it should be able to map that user principal to
something that will signify ownership in the local filesystem.  If a
request is made to change ownership and the server doesn't have a
mapping, it is under no obligation to allow the ownership to be
changed to a owner that it doesn't know about.  It can certainly
provide that functionality but must not be required to allow it.

> same user. The server logs and returns an error.

First, you stated at the beginning of this that there was no such
thing as an invalid user and that it should not return an error.  Then
you suggest that the server return an error.  I realize that you are
referring to different scenarios but there may be other reasons that
the server doesn't want to allow SETATTR of a particular owner.

And why must GETATTR fail if there is potential for mapping confusion?
It seems to me that the server can return "nobody" if it really is
that confused.  The real access issue is handled by ACCESS and OPEN
not by who the owner attribute says is the owner.

> uid/username mapping is removed on the server.

But in a multi-protocol environment (NFSv2/v3/v4), a v3 client may
make a request to create a file under AUTH_SYS and the uid has no
mapping.  You have suggested a solution that will create errors were
none existed before.

> "unknown" user. The username is stored in EAs or separate metadata

Or the SETATTR request is rejected.  The client must handle the case
that it receives owner values that it can not map.  What does it do?
I would suggest that it map the user to the local version of "nobody"
and not return an error or try to hide the object.

-- 
Spencer

---

From: Peter Astrand <[email-masked]>
Date: Sat, 15 Jun 2002 10:36:24 +0200 (CEST)

> "owner" does not match that of the RPC credential.  

Ahh, I see. I don't know much about the security stuff, sorry. But the 
case when root are moving files on a client (with AUTH_SYS), this problem 
will occur, right?

>Second, it must

Ok. I thought Daves suggestion was that servers should map "12345" to
12345, and that this should be specified in the spec rather than be an
implementation issue. The nobody-approach will be problematic because the 
semantics will be different from v2/v3, as Dave pointed out. With the 
nobody-approach, it will not be possible to untar + tar files with 
unknown uids on a client, without getting the uids changed. 

> more useful than could be mapped with numeric uids.

Yes. My proposed scheme was an attempt to make it possible for servers to
serve clients from all kinds of domains at the same time, basically
without clients knowing wether the server is in the same domain or not.
The idea is that files owned by users from a different domain than the
servers domain does not have an real uid on the server.

I realize that this may be utopia. 

> provide that functionality but must not be required to allow it.

Are you considering the ACL entry bit WRITE_OWNER? As far as I understand,
this makes it possible to set the owner field to an arbitrary string,
without requiring that this string can be processed as an RPC credential.

> the server doesn't want to allow SETATTR of a particular owner.

Ops :-) If the spec says SHOULD rather than MUST, then... 

> that confused.  The real access issue is handled by ACCESS and OPEN

If it would, then a GETATTR-SETATTR sequence could change the ownership. 
Clients can come up with some string locally, like "unknown", when it 
recieves the error. 

> mapping.  You have suggested a solution that will create errors were

Oh, right. I didn't think of this. But this is no problem, I think: What
I'm suggesting is that v4-GETATTR should fail, not v2/v3-GETATTR. v2/v3
clients can still create files with unknown uids. The newly introduced
error is only for v4, which didn't exist at all before. And v4 clients can
still access the file. As you have pointed out, the access check is not
done by checking the owner string. The only thing not possible will be 
GETATTR for v4 clients, as long as the mapping for this uid is missing. 
The reason for not allowing GETATTR in this case is that we don't have any 
reasonable string to return, and if we make something up, SETATTR will be 
confused.  

So, in practice, this means that v4 clients will not be able to check or 
set the OWNER string for files with unknown uids. Which makes sense to me, 
since there is no owner string defined. 

-- 
/Peter Åstrand <[email-masked]>