NFSMAPID_DOMAIN

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));
}
Comments:

Thanks for the Dtrace script, it helped me figure out what the NFSv4 domain was on our netapps:)

Posted by Octave Orgeron on March 23, 2005 at 07:25 AM PST #

This is great stuff! In fact, it helped me troubleshoot an NFS issue I was having.

Posted by Ryan Lubke on October 18, 2005 at 12:21 AM PDT #

we support folks have been directed to this blog entry to answer this very FAQ. Can this be made into an infodoc or SRDB? Or can we have permission to create this as an infodoc or SRDB?

Posted by ML Starkey on March 29, 2006 at 05:10 AM 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 05:22 AM PST #

This article is very useful. I need a clarification. I have different users with same UIDs in client and server (assume same dns domain)ex. user joe has uid 1000 in Client and user bob has uid 1000 in Server What is the expected behaviour? what if i create a file as user joe on client will show on the server?

Posted by Suresh on April 03, 2006 at 10:00 PM 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 09:49 AM PDT #

Excellent document - well written and very useful. Thanks Eric.

Posted by Al Hopper on November 03, 2006 at 08:23 AM PST #

Post a Comment:
  • HTML Syntax: NOT allowed
About

erickustarz

Search

Categories
Archives
« April 2014
SunMonTueWedThuFriSat
  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
   
       
Today