diff -wcr ./unfs3-0.9.22-orig/attr.c unfs3-0.9.22/attr.c *** ./unfs3-0.9.22-orig/attr.c 2008-01-03 09:27:24.000000000 +0100 --- unfs3-0.9.22/attr.c 2013-09-16 02:15:53.000000000 +0200 *************** *** 167,174 **** result.post_op_attr_u.attributes.gid = 0; } else { /* Normal case */ ! result.post_op_attr_u.attributes.uid = buf.st_uid; ! result.post_op_attr_u.attributes.gid = buf.st_gid; } result.post_op_attr_u.attributes.size = buf.st_size; --- 167,174 ---- result.post_op_attr_u.attributes.gid = 0; } else { /* Normal case */ ! result.post_op_attr_u.attributes.uid = mangle_uid (buf.st_uid); ! result.post_op_attr_u.attributes.gid = mangle_gid (buf.st_gid); } result.post_op_attr_u.attributes.size = buf.st_size; diff -wcr ./unfs3-0.9.22-orig/Config/exports.h unfs3-0.9.22/Config/exports.h *** ./unfs3-0.9.22-orig/Config/exports.h 2007-09-03 21:52:48.000000000 +0200 --- unfs3-0.9.22/Config/exports.h 2013-09-12 22:37:03.000000000 +0200 *************** *** 8,13 **** --- 8,14 ---- #define UNFS3_EXPORTS_H #include "../mount.h" /* exports type */ + #include "../map_static.h" #define OPT_NO_ROOT_SQUASH 1 #define OPT_ALL_SQUASH 2 *************** *** 23,28 **** --- 24,30 ---- /* Options cache */ extern int exports_opts; const char *export_path; + struct map_static *export_map_static; extern uint32 export_fsid; extern uint32 export_password_hash; diff -wcr ./unfs3-0.9.22-orig/Config/exports.y unfs3-0.9.22/Config/exports.y *** ./unfs3-0.9.22-orig/Config/exports.y 2008-08-17 16:20:44.000000000 +0200 --- unfs3-0.9.22/Config/exports.y 2013-09-12 22:37:06.000000000 +0200 *************** *** 26,31 **** --- 26,32 ---- #include "../mount.h" #include "../daemon.h" #include "../backend.h" + #include "../map_static.h" #include "exports.h" #ifndef PATH_MAX *************** *** 56,61 **** --- 57,63 ---- struct in_addr mask; uint32 anonuid; uint32 anongid; + struct map_static *map_static; struct e_host *next; } e_host; *************** *** 432,437 **** --- 434,441 ---- cur_host.anonuid = atoi(val); } else if (strcmp(opt,"anongid") == 0) { cur_host.anongid = atoi(val); + } else if (strcmp(opt, "map_static") == 0) { + cur_host.map_static = read_map_static (val); } else { logmsg(LOG_WARNING, "Warning: unknown exports option `%s' ignored", opt); *************** *** 695,700 **** --- 699,705 ---- /* options cache */ int exports_opts = -1; const char *export_path = NULL; + struct map_static *export_map_static = NULL; uint32 export_fsid = 0; uint32 export_password_hash = 0; *************** *** 711,716 **** --- 716,722 ---- exports_opts = -1; export_path = NULL; export_fsid = 0; + export_map_static = NULL; last_anonuid = ANON_NOTSPECIAL; last_anongid = ANON_NOTSPECIAL; *************** *** 739,744 **** --- 745,751 ---- if (cur_host) { exports_opts = cur_host->options; export_path = list->path; + export_map_static = cur_host->map_static; export_fsid = list->fsid; last_len = strlen(list->path); last_anonuid = cur_host->anonuid; diff -wcr ./unfs3-0.9.22-orig/Makefile.in unfs3-0.9.22/Makefile.in *** ./unfs3-0.9.22-orig/Makefile.in 2007-12-05 20:11:28.000000000 +0100 --- unfs3-0.9.22/Makefile.in 2013-09-16 00:35:48.000000000 +0200 *************** *** 7,15 **** MAKE = make SOURCES = attr.c daemon.c error.c fd_cache.c fh.c fh_cache.c locate.c \ ! md5.c mount.c nfs.c password.c readdir.c user.c xdr.c winsupport.c OBJS = attr.o daemon.o error.o fd_cache.o fh.o fh_cache.o locate.o \ ! md5.o mount.o nfs.o password.o readdir.o user.o xdr.o winsupport.o CONFOBJ = Config/lib.a EXTRAOBJ = @EXTRAOBJ@ LDFLAGS = @LDFLAGS@ @LIBS@ @LEXLIB@ --- 7,17 ---- MAKE = make SOURCES = attr.c daemon.c error.c fd_cache.c fh.c fh_cache.c locate.c \ ! md5.c mount.c nfs.c password.c readdir.c user.c xdr.c winsupport.c \ ! map_static.c OBJS = attr.o daemon.o error.o fd_cache.o fh.o fh_cache.o locate.o \ ! md5.o mount.o nfs.o password.o readdir.o user.o xdr.o winsupport.o \ ! map_static.o CONFOBJ = Config/lib.a EXTRAOBJ = @EXTRAOBJ@ LDFLAGS = @LDFLAGS@ @LIBS@ @LEXLIB@ *************** *** 152,157 **** --- 154,161 ---- unfs3-$(VERSION)/configure.ac \ unfs3-$(VERSION)/mount.h \ unfs3-$(VERSION)/readdir.c \ + unfs3-$(VERSION)/map_static.c \ + unfs3-$(VERSION)/map_static.h \ unfs3-$(VERSION)/user.h) rm -rf /tmp/unfs3-make-dist-dir diff -wcr ./unfs3-0.9.22-orig/nfs.c unfs3-0.9.22/nfs.c *** ./unfs3-0.9.22-orig/nfs.c 2009-01-04 14:39:39.000000000 +0100 --- unfs3-0.9.22/nfs.c 2013-09-16 01:40:58.000000000 +0200 *************** *** 173,178 **** --- 173,180 ---- pre = get_pre_cached(); result.status = join(in_sync(argp->guard, pre), exports_rw()); + printf ("SETATTR %s\n", path); + if (result.status == NFS3_OK) result.status = set_attr(path, argp->object, argp->new_attributes); diff -wcr ./unfs3-0.9.22-orig/nfs.h unfs3-0.9.22/nfs.h *** ./unfs3-0.9.22-orig/nfs.h 2007-01-05 16:08:12.000000000 +0100 --- unfs3-0.9.22/nfs.h 2013-09-12 22:14:38.000000000 +0200 *************** *** 55,61 **** --- 55,67 ---- #if HAVE_UINT32 == 0 #if HAVE_XDR_U_LONG == 1 + #if 1 || (ULONG_MAX == 4294967295U) typedef u_long uint32; + #elif UINT_MAX == 4294967295U + typedef unsigned int uint32; + #else + #error Hugh?! + #endif #else typedef uint32_t uint32; #endif *************** *** 63,69 **** --- 69,82 ---- #if HAVE_INT32 == 0 #if HAVE_XDR_LONG == 1 + #if 1 || (ULONG_MAX == 4294967295U) typedef long int32; + #elif UINT_MAX == 4294967295U + // this breaks for some reasons! + typedef int int32; + #else + #error Hugh?! + #endif #else typedef int32_t int32; #endif diff -wcr ./unfs3-0.9.22-orig/unfsd.init unfs3-0.9.22/unfsd.init *** ./unfs3-0.9.22-orig/unfsd.init 2007-06-16 21:26:16.000000000 +0200 --- unfs3-0.9.22/unfsd.init 2014-10-24 18:23:42.606591381 +0200 *************** *** 21,27 **** case "$1" in 'start') echo "Starting" ${description} ! /usr/sbin/unfsd -i ${pidfile} RETVAL=$? if [ "${RETVAL}" = "0" ]; then touch ${lockfile} >/dev/null 2>&1 --- 21,27 ---- case "$1" in 'start') echo "Starting" ${description} ! /opt/unfs/sbin/unfsd -i ${pidfile} RETVAL=$? if [ "${RETVAL}" = "0" ]; then touch ${lockfile} >/dev/null 2>&1 diff -wcr ./unfs3-0.9.22-orig/user.c unfs3-0.9.22/user.c *** ./unfs3-0.9.22-orig/user.c 2008-02-16 20:49:50.000000000 +0100 --- unfs3-0.9.22/user.c 2013-09-16 01:30:19.000000000 +0200 *************** *** 25,30 **** --- 25,32 ---- #include "backend.h" #include "Config/exports.h" + #define DEBUG_MAP 1 + /* user and group id we squash to */ static uid_t squash_uid = 65534; static gid_t squash_gid = 65534; *************** *** 72,81 **** --- 74,91 ---- int mangle_uid (int id) { int squash = squash_uid; + int id2; if (exports_anonuid() != ANON_NOTSPECIAL) squash = exports_anonuid(); + id2 = map_static_uid_L2R (export_map_static, id); + #if DEBUG_MAP + printf ("uid L(%d) -> R(%d)\n", id, id2); + #endif + if (id2 != -1) + return (id2 == -2) ? squash : id2; + return mangle(id, squash); } *************** *** 85,94 **** --- 95,112 ---- int mangle_gid(int id) { int squash = squash_gid; + int id2; if (exports_anongid() != ANON_NOTSPECIAL) squash = exports_anongid(); + id2 = map_static_gid_L2R (export_map_static, id); + #if DEBUG_MAP + printf ("gid L(%d) -> R(%d)\n", id, id2); + #endif + if (id2 != -1) + return (id2 == -2) ? squash : id2; + return mangle(id, squash); } *************** *** 99,110 **** --- 117,141 ---- { struct authunix_parms *auth = (void *) req->rq_clntcred; int squash = squash_uid; + int id = auth->aup_uid; + int id2; + #if 0 if (exports_anonuid() != ANON_NOTSPECIAL) squash = exports_anonuid(); + #endif if (req->rq_cred.oa_flavor == AUTH_UNIX) + { + id2 = map_static_uid_R2L (export_map_static, id); + #if 0 && DEBUG_MAP + printf ("uid R(%d) -> L(%d)\n", id, id2); + #endif + if (id2 != -1) + return (id2 == -2) ? squash_uid : id2; + return mangle(auth->aup_uid, squash); + } else return squash; /* fallback if no uid given */ } *************** *** 116,131 **** { struct authunix_parms *auth = (void *) req->rq_clntcred; int squash = squash_gid; if (exports_anongid() != ANON_NOTSPECIAL) squash = exports_anongid(); if (req->rq_cred.oa_flavor == AUTH_UNIX) ! return mangle(auth->aup_gid, squash); else return squash; /* fallback if no gid given */ } /* * check whether a request comes from a given user id */ --- 147,221 ---- { struct authunix_parms *auth = (void *) req->rq_clntcred; int squash = squash_gid; + int id = auth->aup_gid; + int id2; + #if 0 if (exports_anongid() != ANON_NOTSPECIAL) squash = exports_anongid(); + #endif if (req->rq_cred.oa_flavor == AUTH_UNIX) ! { ! id2 = map_static_gid_R2L (export_map_static, id); ! #if 0 && DEBUG_MAP ! printf ("gid R(%d) -> L(%d)\n", id, id2); ! #endif ! if (id2 != -1) ! return (id2 == -2) ? squash_gid : id2; ! ! return mangle (id, squash); ! } else return squash; /* fallback if no gid given */ } + static int effective_anon_gid (void) + { + if (exports_anongid() != ANON_NOTSPECIAL) + return exports_anongid(); + else + return squash_gid; + } + + static int effective_anon_uid (void) + { + if (exports_anonuid() != ANON_NOTSPECIAL) + return exports_anonuid(); + else + return squash_uid; + } + + static void get_ugid (struct svc_req *req, int *uid_out, int *gid_out) + { + struct authunix_parms *auth = (void *) req->rq_clntcred; + int r_uid = auth->aup_uid; + int r_gid = auth->aup_gid; + int uid, gid; + + if (req->rq_cred.oa_flavor == AUTH_UNIX) + { + uid = map_static_uid_R2L (export_map_static, r_uid); + if ((uid == -1) || (uid == -2)) + { + uid = effective_anon_uid (); + gid = effective_anon_gid (); + } + else + { + gid = uid; /* Linux */ + } + } + else + { + uid = effective_anon_uid (); + gid = effective_anon_gid (); + } + + *uid_out = uid; + *gid_out = gid; + } + /* * check whether a request comes from a given user id */ *************** *** 210,218 **** backend_setegid(0); backend_seteuid(0); ! gid = backend_setegid(get_gid(req)); aid = switch_groups(req); ! uid = backend_seteuid(get_uid(req)); if (uid == -1 || gid == -1 || aid == -1) { logmsg(LOG_EMERG, "euid/egid switching failed, aborting"); --- 300,315 ---- backend_setegid(0); backend_seteuid(0); ! ! get_ugid (req, &uid, &gid); ! printf ("R(%d,%d) -> L(%d,%d)\n", ! (int)((struct authunix_parms*)req->rq_clntcred)->aup_uid, ! (int)((struct authunix_parms*)req->rq_clntcred)->aup_gid, ! uid, gid); ! ! gid = backend_setegid(gid); aid = switch_groups(req); ! uid = backend_seteuid(uid); if (uid == -1 || gid == -1 || aid == -1) { logmsg(LOG_EMERG, "euid/egid switching failed, aborting"); diff -wcr ./unfs3-0.9.22-orig/xdr.c unfs3-0.9.22/xdr.c *** ./unfs3-0.9.22-orig/xdr.c 2008-02-16 20:56:07.000000000 +0100 --- unfs3-0.9.22/xdr.c 2013-09-12 22:26:47.000000000 +0200 *************** *** 195,202 **** --- 195,209 ---- #if HAVE_XDR_UINT32 == 0 && HAVE_XDR_U_LONG == 1 bool_t xdr_uint32(XDR * xdrs, uint32 * objp) { + #if ULONG_MAX == 4294967295U if (!xdr_u_long (xdrs, objp)) return FALSE; + #elif UINT_MAX == 4294967295U + if (!xdr_u_int /*long*/ (xdrs, objp)) + return FALSE; + #else + #error hugh? + #endif return TRUE; } #endif *************** *** 204,211 **** --- 211,225 ---- #if HAVE_XDR_INT32 == 0 && HAVE_XDR_LONG == 1 bool_t xdr_int32(XDR * xdrs, int32 * objp) { + #if ULONG_MAX == 4294967295U if (!xdr_long (xdrs, objp)) return FALSE; + #elif UINT_MAX == 4294967295U + if (!xdr_int /*long*/ (xdrs, objp)) + return FALSE; + #else + #error huh? + #endif return TRUE; } #endif *************** *** 261,269 **** bool_t xdr_uid3(XDR * xdrs, uid3 * objp) { ! if (!xdr_uint32(xdrs, objp)) ! return FALSE; ! return TRUE; } bool_t xdr_gid3(XDR * xdrs, gid3 * objp) --- 275,281 ---- bool_t xdr_uid3(XDR * xdrs, uid3 * objp) { ! return xdr_uint32(xdrs, objp); } bool_t xdr_gid3(XDR * xdrs, gid3 * objp)