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

From: "Noveck, Dave" <[email-masked]>
Date: Mon, 17 Jun 2002 20:03:23 -0700

Peter Astrand wrote: 
>On Fri, 14 Jun 2002, Noveck, Dave wrote:
>
> > > > 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.
> > >
> > > Really? Where can I find this in the spec?
> > 
> > It isn't in the spec.  It is an inference that goes approximately as
> > follows:
> > 
> >      Mike says he believes that most servers will use numeric uid's.
> > 
> >      Unix clients use numeric uid's in well established API's and
> >      will continue to do so for a long time to come.
> > 
> >      If a client starts with a numeric uid, and converts that to a 
> >      string and the server does not have a numeric id corresponding
> >      to that string, the server cannot return the same string to the
> >      client and the client will not be able to convert the string it
> 
> The server can return the same string, if it uses EAs or metadata db.

True.

> > > 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. 
> > 
> > 
> > You say that the server "SHOULD" preserve the string.  I can't argue
> > with that.  Of course it should.  It should, except when it can't.  But
> > what does that mean?  Then you have your "at least" clause, which refers
> > to the uid/name mapping, which is really outside the scope of spec since
> > refers to aspects of a UNIX implementation.

> You're right. This text is not ment to be included in the spec as is, I'm 
> just trying to communicate my view of model that looks good to me. 

I just think it's important to separate out the spec issues about which we
have to come to consensus soon, from the other stuff about which we are
free to argue about as long as we like, or simply agree to disagree.

> > What I mean is that the string should always be preserved in a
> > SETATTR-GETATTR sequence if there is no administrative action is taken in
> > between. If an administrator is changing the uid/name mapping between 
> > SETATTR and GETATTR there is not much we can do about it. After all, he 
> > chould do a chown() as well. 

So we can distinguish the statements that if there is no administrative 
action, if you do a SETATTR-GETATTR, the string:

a) MUST be preserved
b) should always be preserved
c) SHOULD be preserved

So how does b) differ from c)? c) is what I believe should be in the spec.

> > You have an implementation in mind, as outlined below.  You are saying
> > that wierd behavior that results from the mapping changing is OK, but
> > that which results from a bad setup is not OK.
>
> Yes, pretty much so. If the server can detect bad setups, which can lead
> to wierd behavior, it should not be silent about it. Detecting bad setups
> in the UNIX/uid case is possible.

I'm not sure it's as easy to detect as you think.  See below.

As far as being silent, I intend to be driven by what the user wants.  My
experience is that you will always find people who set up their systems in ways
that you would never do, for what seem to them to be good reasons.  Noting
a potential problem once is fine, but repeated and annoying errors is something 
that people object to.
  
> > Why not leave this as a quality-of-
> > implementation issue.  The server SHOULD return what was stored (or what's
> > an attribute for) and leave it at that. 
>
> Yes, the spec can probably not be more specific than this. 

I think that sounds like consensus to me.

> > > 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
> ...
> > > -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. 
> > 
> > I agree that it is "not impossible" but I would say those words with a
> > somewhat different intonation.
> > 
> > I think this is an unreasonable burden to place on implementations,
> > especially at this late date.  I know there are people who are thinking
> > about plans to QA and ship.  I think we should avoid substantive changes 
> > with large implications for implementations, unless they are absolutely 
> > required.  The spec is not closed so we can make changes and this is a
> > judgement call but people have invested considerable time developing 
> > under the assumption that existing fs's which do not store strings are 
> > OK and can be adapted to the details of the V4 protocol.
> > 
> > Being able to store arbitrary usernames when almost all curent clients
> > will use a fixed set is unreasonable.  The protocol allows a server to
>
> I think you are right. I haven't considered release dates, protocol 
> changes implications and such; I've just looked at how good model it is 
> possible to achieve. 
> 
> If we reach consensus on that the principle of the model I've described is 
> the way to go, at least we know which goal to work towards. 

I think we know where we want to go: to a scheme which can handle multiple
domains and doesn't require dependence on agreement bewteen the client and
the server on a limited set of known user names.

What I like about your idea of storing exceptional owner-strings while having
most files in terms of uid/gid is that it can get you to the desired
state of affairs in a reasonable timeframe, rather than when auth-sys is
gone.

I have the feeling that once users gets past the kick-the-tires phase
of V4, they are going to want something like this, and people will implement
it.

> Maybe it's possible to relax some of my requirements and end up with 
> something that is implementable right now without too much effort. Such a 
> "relaxed model" could be:

> >>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. 
>
> This general idea could still hold. 

> >>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.

> We can recommend servers to accept all users (and recommend the use of EAs 
> or metadata db for systems that store uids), but still allow 
> NFS4ERR_BADOWNER for servers. 

I have trouble recommending (in the sense of "SHOULD") this.  I suspect that
each of the authors of the spec is going to be associated with a server
that doesn't do this (at least if they are thinking of shipping soon).  Given
that, saying you SHOULD do X while doing ~X, seems like it would put us in the 
position of hypocrites.

I think the spec could explain all the benefits that would accrue from adopting
an approach that allowed all user string to be stored, bu leave this as an
implementation choice. 

> >>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.

This gets into the deatils of how a mapping information might be cached
when fetched using some mapping service.

Suppose I have two users dave and david with same uid 128.  Now if I
try to do a getuid("david") and make the approriate RPC of the mapping service,
and get the fact that the uid corresponding to "david" is 128, what do I
cache?  One possible implementation is just cache the forward mapping but
another possibility is to cache the association between "david" and 128
so that the subsequent getname(128) is almost certain to return "david".
Similarly if you started with "dave".

In practical terms, I'm not sure how important this is.  If I have an
environment in which "dave" and "david" are synonymouns and map to the
same uid on the client.  Then the fact that the client gets "dave" when
"david" was stored or vice versa isn't of much practical significance.
 
>>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.

Again, I think we are getting into implementation detail that not only
shouldn't be in the spec, but couldn't possibly be in the spec.  Trying to
get the point where you could discuss what you are talking about would
basically involve a chapter specifying (and arguing about) lots of stuff
that just isn't in the current scope of the spec.  It ain't going to happen.

> We could recommend servers to try to detect bad setups which leads to 
> "weird behaviour".

I have no problems with this. 

> >>4) What should the server do for a GETATTR on a file with a unknown uid?  
> >>Log and return an (server) error.

> I think this could still hold.

I think it can be allowed behavior.

I don't think it can be a requirement or even a "SHOULD".  I would consider 
this highly anti-social server behavior even if it is allowed.  I create a
file with a given uid in v3 and then I can't even do an ls in v4?  

One way of resolving is to say that the server may return an error but
accommodate the server who doesn't want to return an error by allowing him 
to return a name, i.e. for the server, being the authoritative source of his
names to simply not have uid's without names.  So, if 4711 has no username
in his /etc/passwd or NIS, he can return the name 4711 as the username. 

> >>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.
> 
> > This sounds like a reasonable implementation for servers that want to
> > implement this but it should nt be required.  I think it is totally
> > reasonable for a server to say it does not support any ownership of
> > files by owners from another domain, returning NFS4ERR_BADOWNER.

> Yes, in a "relaxed model", I agree.

I don't know about this "'relaxed model'"?  I think the spec can just define
what you have to do and should do and leave it at that.  As far as the server
only handling a single domain, I don't think we need to denigrate it.  It's
obvious that suppporting multiple domains is better than supporting one,
all other things (TTM etc) being equal. 

> > > 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 think this should still hold, even in a "relaxed model". The important
> part is that servers should not interpret/convert the uid in username
> strings of typ "#uid" or "uid" as a real uid. I think that is simple
> wrong, and will make it necessary to syncronize users & uids between
> servers and clients, forever.

> So, with servers that does not support arbitrary user names (does note
> have EAs or metadata db), will it be impossible to store these "#uid"
> escaped owner strings? Yes, sometimes. 

> One method of solving this problem is to simply get rid of unknown uids:
> The naming service can define mappings for all uids. So, if you ask for
> the "unused uid" 4711, the naming service will give you the username
> strings "#4711". And a lookup of the username "#4711" will give you uid
> 4711. If both the server and the client uses this naming service, there
> will be no problem with storing "unknown" uids (because they aren't any
> unknown uids any longer)

I believe that the server can accommodate otherwise-unknown uid's by
defining some name, e.g. #4711 for them.  Leaving aside the issue of
having a special form for such names, it can do that within the spec 
as it stands.

Now I don't know about this reference to "the naming service".  What does
this mean as far as the spec is concerned.  If I use NIS, it is not
going to do this for me and propagate it to the clients so that we can
all agree, will it?

I guess the issue is, if the server does this, how are the clients to know
that #4711 really means the uid 4711.  "It's obvious" is the obvious 
answer but it probably isn't right.  I guess the whole idea of having the
these be special is so that the spec can give the appropriate hint without
using the word uid.

I've just reread the last paragraph of section 5.6.  I think this is what it
is trying to do, although I may just be imagining it.
 
> Anyway, if none of these methods are used, they server may reject owner
> strings of typ "#4711" with NFS4ERR_BADOWNER, which in turn means that you
> cannot use "unknown uids" at clients (so if you do untar + tar, you may
> end up changing uids).

Sure.  If the server doesn't understand them, or doesn't want to understand
them, it may do that.

> I think this is a reasonable sacrifice. When v4 servers starts to 
> implement support for arbitrary owner strings (which should be recommeded 
> by the spec, IMHO) (with the help from EAs or metadata db), this 
> problem will go away. 

Maybe I'm not understanding what "this problem" is, but I think the problem 
will only go away when people stop using v2,v3, and auth-sys, as well as
implementing servers which can store arbitrary strings.  Another element of
the problem will only go away when UNIX API's stop being uid/gid-centric.
The problem is that the whole world lives by uid/gid and v4 has to accommodate
itself to that world. 

> The answers to Daves original questions with this scheme "relaxed model" 
> would be:
>
> >     Mapping that map lots of strings to the same id or restricting
> >     the range of valid string by returning an error.
> 
> Restricting to the range of valid strings by returning an error. 
> 
> >     What to do about id's in the fs that don't map to any string.  
> >     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?

> My latest idea is "4711#example.com" (@ replaced with #). Just "4711",
> without the domain name, is also fine with me, but increases the risk of
> collisions.

> It feels like Daves and my model are beginning to get closer. 

Kind of scary, huh?

>The difference between our models is:

> >Anyway, I would propose that servers may return @# id's if there is
> >no other way to encode the user identification present in the local
> >filesystem but MUST not otherwise.

> I don't agree here, I want an error. 

I don't really see that you do.  You seem to be saying that returning #4711
(or something like it) is OK, if that come from the  "naming service".  
Suppose the server returns #4711 for a file that has uid 4711, and he is
using NIS and NIS returned to him "never heard of uid 4711".  So that's not
OK?  Or is it OK if he says "I have my own NIS+++ name service that front-ends
NIS and converts 'never heard of it' to the string #nnnn".  Is that now OK?
Why or why not?

> >* 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.

> No, servers should never translate a uid number in these escaped 4711@#
> strings to a real uid, blindly.

If a server translates 4711 to the uid 4711, how do I know (from the spec
point of view) if it did it blindly or not?
 
> If the naming service (at the server)  
> includes this strange user 4711@#, or the server accepts arbitrary owner
> strings (because it uses EAs or other mechanism) the owner will be
> accepted, otherwise rejected with NFS4ERR_BADOWNER.

So let me turn your statement around to determine what the naming service is
doing, since I have no independent access to it.

If the owner is accepted and the server rejects some owner strings (which I
can determine by actually trying a bunch) so it doesn't accept arbitrary
ones, then if it accepts 4711, then the naming service must include the
name 4711, at least from the server's point of view.

> By using the naming service, administrators can choose if the want to
> accept escaped uid owners like 4711@#, or not. I think this is better than
> specifying that UNIX-based v4 servers should always translate 4711@# to
> uid 4711. It should be legal for UNIX-based servers to store files owned 
> by the owner "4711@#" under uid 4711+65535, for example. 

The problem again is not UNIX-based servers.  It is servers that support
v2, v3, or auth-sys, or have UNIX-like local fs's.  These are the servers
that may have files with arbitrary numeric uid/gid values.  

I think, as far as the spec is concerned, it is servers that can choose
or not to accept special uid's, or a server can allow the admistrator to
select that behavior.  The naming service and its possible relationship
to what admistrators define is not something we are specifying.

As far as the server which adds 64K to uid's, I don't see going out of our
to outlaw it.  Depending on how things turn out when we actually draft the
relvant section that may be natural or not.

I expect peer-pressure to do fine, if the spec doesn't.  If I have file with
uid 4711 and someone copies it from my server to yours and winds up with a
file with uid 65535+4711, as visible with an ls over v3, he is going to be 
awfully confused.  But when he find out that you are arbitrarily adding 65K,
I don't the think the fact that you and I are both equally compliant with the
spec is going to prevent him from thinking that you are wrong to do that.

I've come to the conclusion that the proper way for me to proceed is to try
to draft a replacement section 5.6, and then we can use that as the basis for
further argument.  I think we need to focus the discussion on what can 
conceivably be in the spec, rather than arguing about implementation choices,
where boundaries of the naming service are, etc.

---

From: Peter Astrand <[email-masked]>
Date: Tue, 18 Jun 2002 23:48:35 +0200 (CEST)

> free to argue about as long as we like, or simply agree to disagree.

Agree. 

> So how does b) differ from c)? c) is what I believe should be in the spec.

Agree. 

> a potential problem once is fine, but repeated and annoying errors is something 

OTOH, people don't like surprises either. If servers allows
non-one-to-one-mappings between names and uid, and the client and server
does not use the same mapping, this can result that a SETATTR("dave")  
actually makes "spencer" own the file. 

Anyway, back to the spec: The spec should probably not talk about error
logging, this is implementation details. To me, it sounds like a good idea
to put a note about that it may be a good idea for uid-based servers to do
the "bad setups detection" into the spec, maybe under some IMPLEMENTATION
heading. But I'm not sure; I haven't much experience of IETF specs so I'm
a bit unsure about what really belongs in the spec and not.

> I think that sounds like consensus to me.

Yes, agree. 

> the server on a limited set of known user names.

Yes, exactly. 

> of V4, they are going to want something like this, and people will implement

Yes, probably. 

> an approach that allowed all user string to be stored, bu leave this as an

Sounds good to me. After looking at RFC2119, I think this is more of an
"MAY/OPTIONAL" than "SHOULD/RECOMMENDED".

> "david" was stored or vice versa isn't of much practical significance.

Yes, in this case, it doesn't matter that much. But in other cases, such 
as when the server and the client does not have the same mapping, it would 
matter. I think it's safer to use separate caches for "forward" and 
"backward" mappings. Of course, this is implementation details. 

> shouldn't be in the spec, but couldn't possibly be in the spec.  Trying to

Agree. 

> I have no problems with this. 

Great. 

> file with a given uid in v3 and then I can't even do an ls in v4?  

To me, the important part is that the server "keeps it promises": Getting
a username from a GETATTR means an implicit promise that you should be
able to use the same name in a SETATTR. So, if the server accepts
SETATTR(owner=#4711), it can return #4711 for GETATTR(owner) as well. 

Btw, as far as I know, the spec doesn't say anything about if
SETATTR(owner) always should accept the name from GETATTR(owner). Maybe it
should? This issue is in a way the opposite of SETATTR-GETATTR
preservation (which we agree on).

> I don't know about this "'relaxed model'"?  

Sorry, my fault. I just mean my adjusted list of descriptions of my model. 

>I think the spec can just define
> what you have to do and should do and leave it at that.  

Yes, this is what I mean as well. 

>As far as the server

Yes, I agree. 

> having a special form for such names, it can do that within the spec 

Yes, this is exactly what I mean. 

> NIS and converts 'never heard of it' to the string #nnnn".  Is that now OK?

My original idea was:
Ok if it came from NIS
Ok if it came from a NIS+++ frontend
Not Ok otherwise. 

But since a NIS+++ can be considered as either a part of the translation
service or the v4 server software, my argument is kind of strange. Forgive
me, I'm confused.

So, I agree with you on this one. You have convinced me, #4711 owners can 
be interpreted by servers as well. 

> where boundaries of the naming service are, etc.

Sounds great!

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