*/
static char *cachelist[] = {
"auth.unix.ip",
+ "auth.unix.gid",
"nfsd.fh",
"nfsd.export",
NULL
#include <fcntl.h>
#include <errno.h>
#include <ctype.h>
+#include <pwd.h>
+#include <grp.h>
#include "misc.h"
#include "nfslib.h"
#include "exportfs.h"
}
+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; i<ngroups; i++)
+ qword_printint(f, groups[i]);
+ }
+ qword_eol(f);
+ if (groups != glist)
+ free(groups);
+}
+
int get_uuid(char *path, char *uuid, int uuidlen, char *u)
{
/* extract hex digits from uuidstr and compose a uuid
FILE *f;
} cachelist[] = {
{ "auth.unix.ip", auth_unix_ip},
+ { "auth.unix.gid", auth_unix_gid},
{ "nfsd.export", nfsd_export},
{ "nfsd.fh", nfsd_fh},
{ NULL, NULL }
};
+extern int manage_gids;
void cache_open(void)
{
int i;
- for (i=0; cachelist[i].cache_name; i++ ){
+ for (i=0; cachelist[i].cache_name; i++ ) {
char path[100];
+ if (!manage_gids && cachelist[i].f == auth_unix_gid)
+ continue;
sprintf(path, "/proc/net/rpc/%s/channel", cachelist[i].cache_name);
cachelist[i].f = fopen(path, "r+");
}
if (exp->m_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");
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
{ "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 }
};
/* 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) {
" [-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);
}
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