X-Git-Url: https://git.decadent.org.uk/gitweb/?p=nfs-utils.git;a=blobdiff_plain;f=utils%2Fmountd%2Fcache.c;h=6cf24ceb4f9f9d3b919cbe1c24cbc22e290945a5;hp=6947203c0f9b91ee362458602a405173f3a816f6;hb=74a8f33de5f26d6bab11d5299318035d65bd60d0;hpb=e91ff0175602cc56f223f1d92de6511099fa40d1 diff --git a/utils/mountd/cache.c b/utils/mountd/cache.c index 6947203..6cf24ce 100644 --- a/utils/mountd/cache.c +++ b/utils/mountd/cache.c @@ -21,11 +21,14 @@ #include #include #include +#include +#include #include "misc.h" #include "nfslib.h" #include "exportfs.h" #include "mountd.h" #include "xmalloc.h" +#include "fsloc.h" #include "blkid/blkid.h" @@ -101,6 +104,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; i path lookup can be quite expensive as it + * potentially stats and reads lots of devices, and some of those + * might have spun-down. The Answer is not likely to + * change underneath us, and an 'exportfs -f' can always + * remove this from the kernel, so use a really log + * timeout. Maybe this should be configurable on the command + * line. + */ + qword_printint(f, 0x7fffffff); if (found) qword_print(f, found->e_path); qword_eol(f); @@ -372,6 +430,29 @@ void nfsd_fh(FILE *f) return; } +static void write_fsloc(FILE *f, struct exportent *ep, char *path) +{ + struct servers *servers; + + if (ep->e_fslocmethod == FSLOC_NONE) + return; + + servers = replicas_lookup(ep->e_fslocmethod, ep->e_fslocdata, path); + if (!servers) + return; + qword_print(f, "fsloc"); + qword_printint(f, servers->h_num); + if (servers->h_num >= 0) { + int i; + for (i=0; ih_num; i++) { + qword_print(f, servers->h_mp[i]->h_host); + qword_print(f, servers->h_mp[i]->h_path); + } + } + qword_printint(f, servers->h_referral); + release_replicas(servers); +} + static int dump_to_cache(FILE *f, char *domain, char *path, struct exportent *exp) { qword_print(f, domain); @@ -382,6 +463,7 @@ static int dump_to_cache(FILE *f, char *domain, char *path, struct exportent *ex qword_printint(f, exp->e_anonuid); qword_printint(f, exp->e_anongid); qword_printint(f, exp->e_fsid); + write_fsloc(f, exp, path); if (exp->e_uuid == NULL) { char u[16]; if (get_uuid(exp->e_path, NULL, 16, u)) { @@ -462,16 +544,20 @@ struct { 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].cache_handle == auth_unix_gid) + continue; sprintf(path, "/proc/net/rpc/%s/channel", cachelist[i].cache_name); cachelist[i].f = fopen(path, "r+"); } @@ -526,12 +612,6 @@ int cache_export(nfs_export *exp) int err; FILE *f; - 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; - } - f = fopen("/proc/net/rpc/auth.unix.ip/channel", "w"); if (!f) return -1;