From 944011f65513aa4c1b69fa92e0f51b8aef7c1cbc Mon Sep 17 00:00:00 2001 From: Neil Brown Date: Mon, 12 Feb 2007 16:30:23 +1100 Subject: [PATCH] Support group-id looks for kernels that ask for them. With "-g" mountd will listen for uid -> gidlist requests from the kernel and provide the required mapping. This is specific to AUTH_USER (aka AUTH_SYS) and is designed to overcome the 16-gid limit in the AUTH_UNIX protocol. --- support/nfs/cacheio.c | 1 + utils/mountd/cache.c | 57 +++++++++++++++++++++++++++++++++++++++-- utils/mountd/mountd.c | 9 +++++-- utils/mountd/mountd.man | 15 +++++++++++ 4 files changed, 78 insertions(+), 4 deletions(-) diff --git a/support/nfs/cacheio.c b/support/nfs/cacheio.c index 4df80a6..a76915b 100644 --- a/support/nfs/cacheio.c +++ b/support/nfs/cacheio.c @@ -256,6 +256,7 @@ cache_flush(int force) */ static char *cachelist[] = { "auth.unix.ip", + "auth.unix.gid", "nfsd.fh", "nfsd.export", NULL diff --git a/utils/mountd/cache.c b/utils/mountd/cache.c index 6947203..629d567 100644 --- a/utils/mountd/cache.c +++ b/utils/mountd/cache.c @@ -21,6 +21,8 @@ #include #include #include +#include +#include #include "misc.h" #include "nfslib.h" #include "exportfs.h" @@ -101,6 +103,53 @@ void auth_unix_ip(FILE *f) } +void auth_unix_gid(FILE *f) +{ + /* Request are + * uid + * reply is + * uid expiry count list of group ids + */ + int uid; + struct passwd *pw; + gid_t glist[100], *groups = glist; + int ngroups = 100; + int rv, i; + char *cp; + + if (readline(fileno(f), &lbuf, &lbuflen) != 1) + return; + + cp = lbuf; + if (qword_get_int(&cp, &uid) != 0) + return; + + pw = getpwuid(uid); + if (!pw) + rv = -1; + else { + rv = getgrouplist(pw->pw_name, pw->pw_gid, groups, &ngroups); + if (rv == -1 && ngroups >= 100) { + groups = malloc(sizeof(gid_t)*ngroups); + if (!groups) + rv = -1; + else + rv = getgrouplist(pw->pw_name, pw->pw_gid, + groups, &ngroups); + } + } + qword_printint(f, uid); + qword_printint(f, time(0)+30*60); + if (rv >= 0) { + qword_printint(f, ngroups); + for (i=0; im_export.e_maptype != CLE_MAP_IDENT) { xlog(L_ERROR, "%s: unsupported mapping; kernel supports only 'identity' (default)", exp->m_export.m_path); - return; + return -1; } f = fopen("/proc/net/rpc/auth.unix.ip/channel", "w"); diff --git a/utils/mountd/mountd.c b/utils/mountd/mountd.c index 5204faa..fc9a73c 100644 --- a/utils/mountd/mountd.c +++ b/utils/mountd/mountd.c @@ -39,6 +39,7 @@ static struct nfs_fh_len *get_rootfh(struct svc_req *, dirpath *, mountstat3 *, int reverse_resolve = 0; int new_cache = 0; +int manage_gids; /* PRC: a high-availability callout program can be specified with -H * When this is done, the program will receive callouts whenever clients @@ -68,6 +69,7 @@ static struct option longopts[] = { "state-directory-path", 1, 0, 's' }, { "num-threads", 1, 0, 't' }, { "reverse-lookup", 0, 0, 'r' }, + { "manage-gids", 0, 0, 'g' }, { NULL, 0, 0, 0 } }; @@ -567,8 +569,11 @@ main(int argc, char **argv) /* Parse the command line options and arguments. */ opterr = 0; - while ((c = getopt_long(argc, argv, "o:nFd:f:p:P:hH:N:V:vrs:t:", longopts, NULL)) != EOF) + while ((c = getopt_long(argc, argv, "o:nFd:f:p:P:hH:N:V:vrs:t:g", longopts, NULL)) != EOF) switch (c) { + case 'g': + manage_gids = 1; + break; case 'o': descriptors = atoi(optarg); if (descriptors <= 0) { @@ -746,6 +751,6 @@ usage(const char *prog, int n) " [-p|--port port] [-V version|--nfs-version version]\n" " [-N version|--no-nfs-version version] [-n|--no-tcp]\n" " [-H ha-callout-prog] [-s|--state-directory-path path]\n" -" [-t num|--num-threads=num]\n", prog); +" [-g|--manage-gids] [-t num|--num-threads=num]\n", prog); exit(n); } diff --git a/utils/mountd/mountd.man b/utils/mountd/mountd.man index 70166c1..f8646d4 100644 --- a/utils/mountd/mountd.man +++ b/utils/mountd/mountd.man @@ -143,6 +143,21 @@ can support both NFS version 2 and the newer version 3. Print the version of .B rpc.mountd and exit. +.TP +.B \-g " or " \-\-manage-gids +Accept requests from the kernel to map user id numbers into lists of +group id numbers for use in access control. An NFS request will +normally (except when using Kerberos or other cryptographic +authentication) contains a user-id and a list of group-ids. Due to a +limitation in the NFS protocol, at most 16 groups ids can be listed. +If you use the +.B \-g +flag, then the list of group ids received from the client will be +replaced by a list of group ids determined by an appropriate lookup on +the server. Note that the 'primary' group id is not affected so a +.I newgroup +command on the client will still be effective. This function requires +a Linux Kernel with version at least 2.6.21. .SH TCP_WRAPPERS SUPPORT This -- 2.39.5