NOTE: The NFS server should not do subtree checking: for linux servers make sure there is a "no_subtree_check" option in /etc/export lines, e.g: /home clientname(rw,no_root_squash,async,no_subtree_check) NOTE2: The patch only works for NFS v2 and v3. v4 is unchanged. NOTE3: rpc.mountd -g option on the server might be an alternative. It requires a statically assigned secondary grouplist which must be identical on server and clients for all users, e.g. via NIS. NFS/RPC with more than 16 groups per user ========================================= The patch is useful when users are member of more than 16 groups on a Linux NFS client. The patch bypasses this protocol imposed limit in a compatible manner (i.e. no server patching). All patches are distributed under the GNU General Public License. For details, see the COPYING file (copied from the Linux source). Theory of operation =================== NFS is based on RPC. RPC comes in a number of flavors. The patch deals with SUNRPC based on AUTH_UNIX authentication, a popular authentication flavor for NFS. The NFS client has to tell the server who is doing an operation and the server will do the permission checking. The identity is composed of euid (fsuid), egid and the secondary group list. The latter will be truncated to 16 groups by RPC and that's where NFS breaks. Linux 2.4.x has a standard limit of 32 groups (like most other UNIces) and these are already too many for NFS. Some sysadmins would even like to raise the limit well beyond 32, for example 256 groups per user. If you want to do that, change limits.h and asm/param.h and recompile kernel, glibc and shadow-utils. Linux 2.6.x has a limit of 65536 groups which seems enough in most cases :). But now onto NFS: It is fairly simple to predict the group id's which might make a difference in an operation on NFS on the client system, assuming the NFS server does permission checking conform UNIX. This is not a bad assumption when NFS uses RPC with AUTH_UNIX authentication. Pathnames at system call time are not handled in one NFS operation (NFS != WebNFS) but by a series of NFS lookups. Therefor the maximum number of groups required at any specific point in time is 3 at most: see nfs_rename(). Patch version 3.x ================= The patch maintains a cache of the 16 most recently used group id's. This cache is updated before executing the NFS operation. The cache is kept sorted by group number because the RPC layer compares group lists when it looks for a matching credential in its own cache. The purpose of the cache is not to "guess groups" or something but to prepare for so-called short credentials which could reduce network bandwidth. That hasn't been investigated any further. Patch version 4.x ================= Group id cache is gone. At the top NFS layer the group ids of "interesting" file-system objects are collected (max 3, mostly 1) and passed downwards. The VFS credential (auth_cred) will be extended with group information right before using it for looking up an RPC credential in the cache. When current->group_info contains 16 or less groups then all groups are added. This has been the traditional behavior. When there is no group id information passed downwards then at most 16 groups are added which is traditional behavior too. Otherwise, only groups present in _both_ group information passed downwards and the secondary group list will be added to the VFS credential (i.e. group lists are intersected). The patch has become significantly larger, mostly due to restructuring and some cleanups: - removed broken_suid mount option (merged in 2.6.12) - reduced the number of rpc_message instantiations. BUG REPORTS ----------- If you think something didn't work as expected then it would be helpful if you mail it to and possibly include a relevant section of /var/log/messages after reproducing the problem with echo 16 >/proc/sys/sunrpc/rpc_debug echo 17 >/proc/sys/sunrpc/nfs_debug It is probably best to try to reproduce the problem with the "noac" mount option. TODO ---- - Merge minor cleanups with mainline. RESTRICTIONS ------------ - Won't work in combination with ACLs. - nfs_idmap_new(): interaction with id mapping? Changelog ========= 2014-05-18 version 4.61 fixes a gid_t/kgid_t mixup, relevant when multiple namespaces exist for uid/gid numbers (a.k.a. user namespaces). Namespaces/nfs-ngroups feature combination remains untested. 2013-03-15 version 4.60 fixes an Oops for NFSv4 - Atomic open (which is v4 specific) starts out with a negative dentry. The NFS version check to enable the nfs-ngroups patch for v<=3 now uses the superblock instead of the inode in this case. 2011-08-17 Version 4.59 fixes a couple of harmless compilation warnings. 2009-01-01 Updated patch for 2.6.27.10 2008-10-26 nfs-ngroups 4.58 for 2.6.27 and 2.6.26. - EXPORT_SYMBOL_GPL(rpcauth_lookupcred) was missing. This broke compiling as a module. Removed 2.6.27-4.57 version. 2008-10-23 nfs-ngroups 4.57 for 2.6.27 - Replaced a couple of NULL ptr tests on `cred' by PTR_ERR: Fix an Oops when the machine runs out of memory in a very particular way. This hasn't happened yet but at least in theory it's possible. 2008-08-07 nfs-ngroups 4.56 for 2.6.26 - Minor restructuring to handle introduction of auth_generic.c. 2008-02-12 nfs-ngroups 4.55 for 2.6.24 - Fixed the >16 groups issue for locking over NFS. 2005-06-26 nfs-ngroups 4.54 for 2.6.12 2005-06-13 nfs-ngroups 4.54 for 2.6.12-rc6 - avoid partially working feature for NFSv4: it could cause confusion. 2005-03-06 nfs-ngroups 4.53 for 2.6.11 2005-02-14 nfs-ngroups 4.53 for 2.6.11-rc4 - fixed CONFIG_NFSD_V4 compilation breakage. 2005-02-12 nfs-ngroups 4.52 for 2.6.11-rc4 2005-02-07 nfs-ngroups 4.52 for 2.6.11-rc3 2005-02-07 nfs-ngroups 4.52 for 2.6.10 - fixed SETATTR: need another gid for truncate. - added some debug 2005-02-04 nfs-ngroups 4.51 for 2.6.10 - fixed SETATTR: need gid for chown(new gid) 2005-02-03 nfs-ngroups 4.50 for 2.6.10 - It compiles but hasn't been tested. 2002-05-26 nfs-ngroups 3.98 for 2.4.19-pre8 - fixed "too many groups" warnings. They were false alarm caused by not allocating the group id cache when the group is equal to fsgid. - fixed sys_setgroups16(). Ouch. Appearently I missed the introduction of the 16/32 bit uid/gid split.