NFS server: Generic uid and gid remapping for AUTH_SYS
There are various NFS deployments where it is desired to be able to extend the existing root/root_mapping share_nfs(1m) options to allow generic user remapping.
For example, we had a case where we would like to have the root user from client1 mapped at the server to user jack, while root from client2 should be mapped at the server to user jill.
The traditional share options allows either root=client1,root_mapping=jack to satisfy client1, or root=client2,root_mapping=jill to satisfy client2. It is not possible to combine such options somehow to make it working as desired.
To solve this issue we introduce the generic user and group remapping using two new share_nfs options uidmap and gidmap. The above use case is easily implementable using the following setup:
Here is the relevant part of the share_nfs(1m) man page related to uidmap (gidmap is similar):
uidmap=mapping[~mapping]... Where mapping is: [clnt]:[srv]:access_list Allows to remap the user ID (uid) in the incoming request to some other uid. This effectively changes the user's identity presented to the NFS server. For clients where the uid in the incoming request is clnt and the client matches the access_list, change the user ID to srv. If clnt is asterisk (*), all users are mapped by this rule. If clnt is omitted, all unknown users are mapped by this rule. If srv is set to -1, access is denied. If srv is omitted, the uid is mapped to UID_NOBODY. All mappings are evaluated in the specified order until a match is found. Both root= and root_mapping= options (if specified) are evaluated before the uidmap= option. The uidmap= option is skipped in a case the client matches the root= option. The uidmap= option is evaluated before the anon= option. This option is supported only for AUTH_SYS.
Updated by Marcel Telka about 7 years ago
During the implementation I had to solve a design issue related to rdonly() macro.
The new version of nfsauth_access() requires the original cred as it was arrived over the wire to check whether the access is allowed or not (and to find the uid/gid where to remap to). The original rdonly() macro called nfsauth_access(), but in this stage the original cred is no longer available (it was already remapped in checkauth()), so I had to change the rdonly() calls in all rfs_*()/rfs3_*() functions. Fortunately, the exactly same nfsauth_access() call is done before the rfs_*()/rfs3_*() functions are called. It is done in checkauth(). And it is done with the original cred.
So, why not to abuse the nfsauth_access() call in checkauth() to remember the returned ro status and reuse it in rfs_*()/rfs3_*() ?
As a result, I solved the design problem I had, but I also improved the performance a bit (the nfsauth_access() is called once, not twice). IOW, this change alone would improve the NFS implementation and it would be a good thing to do even without this fix, but nobody noticed this yet. Yes, I partly did this as a "while the patient is open", but the change was enforced and required by this fix.
Updated by Electric Monk about 7 years ago
- Status changed from In Progress to Closed
- % Done changed from 0 to 100
commit 5cb0d67909d9970a3e7adbea9422ca3fc88000bf Author: Marcel Telka <email@example.com> Date: 2014-07-08T13:32:37.000Z 4943 NFS server: Generic uid and gid remapping for AUTH_SYS Reviewed by: Jan Kryl <firstname.lastname@example.org> Reviewed by: Dan McDonald <email@example.com> Approved by: Garrett D'Amore <firstname.lastname@example.org>