|
What did NFSv4 change in the user/group attributes representation?
NFSv4 introduces the use of UTF8 strings for user and group
attributes instead of the old NFSv3 way of an 32-bit unsigned int - which
is really the UNIX uid/gid. We now have the form:
"user|group@domain"
This makes intuitive sense (for larger networks), better matches Window's SIDs,
and more importantly solves the "scalability" of user/group (see example below).
An example where this is quite useful
If two companies merged and were now housed under the same administrative
domain, but existed under a different DNS/NIS/LDAP/etc domain, then its
quite possible that both companies used some of the exact same uids/gids -
but they of course refer to different user/groups. By enforcing the domain
as part of the attribute, NFSv4 allows the uids/gids to remain the same, but
the OTW representation will be different, and everything works:
joe@companyA.com is internally represented as uid 1000 from CompanyA.
bob@companyB.com is internally represented as uid 1000 from CompanyB.
CompanyA merges with CompanyB. To ease the transition, all of CompanyA's
machines are separated out as DNS domain companyA.companyB.com. All
companyB's machines are left in DNS domain companyB.com.
In NFSv3, we would just pass user "1000" OTW; in NFSv4, we pass
"joe@companyA.com" OTW. Within the companyB.com DNS domain, its not
obvious whether "1000" represents joe or bob, but it is obvious
"joe@companyA.com" is not bob. And this is obvious and detected within
NFSv4, no need for a special proprietary protocol/solution to do the
uid/gid mappings.
Real access
One thing to remember is that access (including ACLs) are evaluated by the
server and are based on the RPC credentials, not on the user/group attrs. So
if the user/group attr is not recognizable (for example, server couldn't find
a proper mapping, so translates to "nobody"), then only apps/commands that
depend on that attribute will fail.
So a properly written application will use access(2) to perform permission
checks, and will not rely on the mode bits or uid/gid from stat(2).
It should be noted though, that even if the client cannot accurately determine
the user/group attribute, properly written applications will still run
successfully - since they're permission checks are done on the RPC cred, not
on the user/group attribute.
So what does Solaris do?
Solaris currently only handles one NFSv4 domain. If the client or server
receives an user/group string that does not match its domain, it will map that
user/group into uid/gid "nobody" (60001). In the future Solaris may support
multiple domains, domain equivalence, or a mapping of users between domains.
As an example, assume a flat uid numberspace, user "eric"'s uid is 1000, the
client resides in DNS domain xxx.sun.com and therefore1 has
NFSMAPID_DOMAIN set to xxx.sun.com, and the server resides in DNS domain
yyy.sun.com and has NFSMAPID_DOMAIN also as yyy.sun.com.
If a client contacts the server, "eric@xxx.sun.com" is passed OTW, and the
server will not be able to map "eric@xxx.sun.com" to uid 1000, since the
domains don't match. The server will translate this to "nobody".
1 Note, below I will explain the use of a DNS TXT RR that we use to
solve this problem (and are proposing via the IETF for others to use as well).
Algorithm
So the OTW representation is set, but if we're talking Solaris client to
Solaris server, then end to end, we will need to translate a uid to
user@domain at the client, and then user@domain to uid at the server.
So how does Solaris figure out what its NFSv4 domain is?
Solaris allows each "node" to explicitly set its own NFSv4 domain, derive
its NFSv4 domain from a common name service domain, or to acquire the
NFSv4 domain from a DNS network service. Explicitly setting the domain
doesn't scale, so we encourage customers to use their existing
DNS (or NIS/NIS+/LDAP/etc) domain as their NFSv4 domain. In the case where
a site has multiple name service domains (such as some nodes using DNS whereas
other nodes only use NIS), but keep a flat or non-overlapping numberspace,
we recommend the third option - acquiring the NFSv4 domain via DNS and
a RR.
With the common default configurations, customers should not have to
explicitly define the NFSv4 domain. The automatic algorithm that is used should
be sufficient.
Here is the Solaris algorithm for this mapping:
if (NFSMAPID_DOMAIN2 is uncommented/set in /etc/default/nfs)
use it and return;
if (DNS is configured)
lookup TXT RR3
if (TXT RR)
use it and return;
if (DNS domainname)
use it and return;
if (non-DNS domainname: NIS/NIS+/LDAP/etc)
strip leading component;
use it and return;
Otherwise, send OTW stringified uid/gids4
2NFSMAPID_DOMAIN is a Solaris variable - see nfs(4). Also note,
that when this is not manualy set, Solaris will automatically figure out
a NFSv4 domain (as described above), but when it does the automatic figuring
it does NOT set the variable NFSMAPID_DOMAIN in /etc/default/nfs -- it leaves
it alone.
3
The TXT resource record we use is:
_nfsv4idmapdomain.sun.com
and will be explained in full detail in a forthcoming Internet draft.
4Section 5.8 goes into detail of why using stringified uids/gids
is not recommended and mentions how the server should handle them:
"
A server is not obligated to accept such a string, but may return
NFS4ERR_BADOWNER instead. To avoid this mechanism being used to subvert user
and group translation, so that a client might pass all of the owners and groups
in numeric form, a server SHOULD return an NFS4ERR_BADOWNER error when there
is a valid translation for the user or owner designated in this way.
"
However, there are useful in cases where no domain is discernable - such as
a diskless client that needs to access its boot files over the net before its
domain is set.
Debugging
So if you do see the user/group popping up as "nobody", make sure that
the client and server have matching domains for NFSv4. You can do this
easily by looking at:
/var/run/nfs4_domain
or running this simple dtrace script which shows what's being sent OTW:
#!/usr/sbin/dtrace -s
#pragma D option quiet
sdt::nfs_idmap_str_uid:nfs4-str-uid
{
printf("DOMAIN FOR OWNER: %s\n", stringof(arg0));
}
sdt::nfs_idmap_str_gid:nfs4-str-gid
{
printf("DOMAIN FOR OWNER_GROUP: %s\n", stringof(arg0));
}
(2005-11-14 17:04:31.0/2005-01-28 11:04:18.0)
Permalink
Trackback: http://blogs.sun.com/erickustarz/en_US/entry/nfsmapid_domain
|
Posted by Octave Orgeron on March 23, 2005 at 03:25 PM PST #
Posted by Ryan Lubke on October 18, 2005 at 07:21 AM PDT #
Posted by ML Starkey on March 29, 2006 at 01:10 PM PST #
Support folks for whom? In general i think its a great idea, just would like to know who's referencing it.
Can you send an email to nfs-discuss@opensolaris.org saying who wants to reference it and what a SRDB is :)? If that doesn't jive, you can send me a private email
Posted by eric kustarz on March 29, 2006 at 01:22 PM PST #
Posted by Suresh on April 04, 2006 at 05:00 AM PDT #
This is a good question for others to see, so please post at nfs-discuss@opensolaris.org
Posted by eric kustarz on April 04, 2006 at 04:49 PM PDT #
Posted by Al Hopper on November 03, 2006 at 04:23 PM PST #