diff options
author | Dan Goodliffe <dan@randomdan.homeip.net> | 2021-12-15 00:20:23 +0000 |
---|---|---|
committer | Dan Goodliffe <dan@randomdan.homeip.net> | 2021-12-15 00:20:23 +0000 |
commit | a38270df3ddad2ac60524a40eb986ab37e473c04 (patch) | |
tree | 2b0ff976a616fb970e62b93b3ffb52517efc1343 /netfs/fuse | |
parent | Add missing include (diff) | |
parent | Bump to C++20, required by new Slicer (diff) | |
download | netfs-a38270df3ddad2ac60524a40eb986ab37e473c04.tar.bz2 netfs-a38270df3ddad2ac60524a40eb986ab37e473c04.tar.xz netfs-a38270df3ddad2ac60524a40eb986ab37e473c04.zip |
Psycho-rebased branch mapper on top of netfs-1.4netfs-1.4.0.1-mark
Diffstat (limited to 'netfs/fuse')
-rw-r--r-- | netfs/fuse/Jamfile.jam | 28 | ||||
-rw-r--r-- | netfs/fuse/fuseApp.cpp | 36 | ||||
-rw-r--r-- | netfs/fuse/fuseApp.h | 2 | ||||
-rw-r--r-- | netfs/fuse/fuseApp.impl.h | 3 | ||||
-rw-r--r-- | netfs/fuse/fuseConfig.ice | 4 | ||||
-rw-r--r-- | netfs/fuse/fuseDirs.cpp | 11 | ||||
-rw-r--r-- | netfs/fuse/fuseFiles.cpp | 2 | ||||
-rw-r--r-- | netfs/fuse/fuseMappers.ice | 23 | ||||
-rw-r--r-- | netfs/fuse/fuseMappersImpl.cpp | 74 | ||||
-rw-r--r-- | netfs/fuse/fuseMappersImpl.h | 33 |
10 files changed, 192 insertions, 24 deletions
diff --git a/netfs/fuse/Jamfile.jam b/netfs/fuse/Jamfile.jam index 14338d5..4d000be 100644 --- a/netfs/fuse/Jamfile.jam +++ b/netfs/fuse/Jamfile.jam @@ -1,34 +1,48 @@ import package ; lib Glacier2 : : <name>Glacier2++11 ; +constant FUSE_VER : 35 ; + +rule iceobj ( name : ice ) { + obj $(name) : $(ice) : + <toolset>tidy:<checker>none + <library>../ice//netfs-api + <implicit-dependency>../ice//netfs-api + <library>..//slicer + <include>. + ; +} +iceobj fuseConfig : fuseConfig.ice ; +iceobj fuseMappers : fuseMappers.ice ; -obj fuseConfig : fuseConfig.ice : - <toolset>tidy:<checker>none - <library>../ice//netfs-api - <implicit-dependency>../ice//netfs-api -; lib netfs-client-configuration : fuseConfig + fuseMappers fuseConfig.ice + fuseMappers.ice fuseConfigImpl.cpp + fuseMappersImpl.cpp : <slicer>pure <library>../ice//netfs-api + <library>../lib//netfs-common <implicit-dependency>../ice//netfs-api <implicit-dependency>fuseConfig <library>..//Ice <library>..//slicer <library>..//adhocutil + <include>. : : <library>..//Ice <library>..//slicer + <include>. ; lib netfs-client : netfs-client-configuration [ glob *.cpp : fuseConfigImpl.cpp netfs.cpp ] : - <define>FUSE_USE_VERSION=35 + <define>FUSE_USE_VERSION=$(FUSE_VER) <implicit-dependency>../ice//netfs-api <library>netfs-client-configuration <implicit-dependency>netfs-client-configuration @@ -42,7 +56,7 @@ lib netfs-client : <library>..//slicer-xml <use>../..//fuse : : - <define>FUSE_USE_VERSION=31 + <define>FUSE_USE_VERSION=$(FUSE_VER) <include>. <library>../ice//netfs-api <library>Glacier2 diff --git a/netfs/fuse/fuseApp.cpp b/netfs/fuse/fuseApp.cpp index 41f86ef..b6d59b1 100644 --- a/netfs/fuse/fuseApp.cpp +++ b/netfs/fuse/fuseApp.cpp @@ -2,11 +2,13 @@ #include "cache.impl.h" #include "fuseDirs.h" #include "fuseFiles.h" +#include "fuseMappersImpl.h" #include "lockHelpers.h" #include <Glacier2/Router.h> #include <boost/lexical_cast.hpp> #include <compileTimeFormatter.h> #include <cstring> +#include <defaultMapper.h> #include <entCache.h> #include <safeMapFind.h> #include <slicer/slicer.h> @@ -17,10 +19,7 @@ namespace AdHoc { template class CallCacheable<struct stat, std::string>; } -NetFS::FuseApp::FuseApp(Ice::StringSeq && a) : - iceArgs(std::move(a)), sessionOpened(false), openHandleId(0), converter(userLookup, groupLookup) -{ -} +NetFS::FuseApp::FuseApp(Ice::StringSeq && a) : iceArgs(std::move(a)), sessionOpened(false), openHandleId(0) { } NetFS::FuseApp::~FuseApp() { @@ -80,7 +79,11 @@ NetFS::FuseApp::init(struct fuse_conn_info *, struct fuse_config *) fcr = configureFromFile(arg.substr(0, colon), arg.substr(colon + 1)); } } + if (!fcr->Mapper) { + fcr->Mapper = std::make_shared<Mapping::DefaultMapper>(); + } BOOST_ASSERT(fcr); + converter.mapper = fcr->Mapper; return this; } @@ -109,7 +112,26 @@ NetFS::FuseApp::configureFromUri(const std::string & uriString) setting = boost::lexical_cast<std::remove_reference_t<decltype(setting)>>(p->second); } }; + auto setWith = [&uri](const auto & param, auto & setting, auto && f) { + if (auto p = uri.query.find(param); p != uri.query.end()) { + setting = f(p->second); + } + }; set("async", r->Async); + setWith("mapper", r->Mapper, [&set, &setWith](auto && m) -> NetFS::Mapping::MapperPtr { + if (m == "hide") { + return std::make_shared<NetFS::Client::HideUnknownMapperImpl>(); + } + else if (m == "mask") { + auto mi = std::make_shared<NetFS::Client::MaskUnknownMapperImpl>(); + set("mapper.unknownuser", mi->UnknownUser); + set("mapper.unknowngroup", mi->UnknownGroup); + setWith("mapper.usermask", mi->UserMask, Client::from_octal); + setWith("mapper.groupmask", mi->GroupMask, Client::from_octal); + return mi; + } + return {}; + }); return r; } @@ -274,8 +296,6 @@ NetFS::ReqEnv NetFS::FuseApp::reqEnv() { struct fuse_context * c = fuse_get_context(); - NetFS::ReqEnv re; - userLookup.getName(c->uid, &re.user); - groupLookup.getName(c->gid, &re.grp); - return re; + const auto t = converter.mapper->mapFileSystem(c->uid, c->gid); + return {t.username, t.groupname}; } diff --git a/netfs/fuse/fuseApp.h b/netfs/fuse/fuseApp.h index 80deed2..9eafb7f 100644 --- a/netfs/fuse/fuseApp.h +++ b/netfs/fuse/fuseApp.h @@ -111,8 +111,6 @@ namespace NetFS { OpenFiles openFiles; int openHandleId; - EntCache<User> userLookup; - EntCache<Group> groupLookup; EntryTypeConverter converter; using StatCache = AdHoc::Cache<struct stat, std::string>; diff --git a/netfs/fuse/fuseApp.impl.h b/netfs/fuse/fuseApp.impl.h index e433ee7..9947f36 100644 --- a/netfs/fuse/fuseApp.impl.h +++ b/netfs/fuse/fuseApp.impl.h @@ -12,8 +12,7 @@ namespace NetFS { { auto & map = getMap<Handle>(); Lock(_proxymaplock); - while (map.find(fh = ++openHandleId) != map.end()) - ; + while (map.find(fh = ++openHandleId) != map.end()) { } map.emplace(fh, std::make_shared<typename Handle::element_type>(params...)); } diff --git a/netfs/fuse/fuseConfig.ice b/netfs/fuse/fuseConfig.ice index 52116ea..ea489ac 100644 --- a/netfs/fuse/fuseConfig.ice +++ b/netfs/fuse/fuseConfig.ice @@ -1,4 +1,5 @@ #include <exceptions.ice> +#include <mapper.ice> module NetFS { module Client { @@ -20,6 +21,9 @@ module NetFS { ["slicer:name:async"] bool Async = false; + + ["slicer:name:mapper"] + Mapping::Mapper Mapper; }; ["slicer:key:name","slicer:value:resource","slicer:item:resource"] diff --git a/netfs/fuse/fuseDirs.cpp b/netfs/fuse/fuseDirs.cpp index c1a91bd..d23f5d7 100644 --- a/netfs/fuse/fuseDirs.cpp +++ b/netfs/fuse/fuseDirs.cpp @@ -50,13 +50,16 @@ namespace NetFS { auto expiry = time(nullptr) + 2; if (flags == FUSE_READDIR_PLUS) { for (const auto & e : od->remote->listdir()) { - filler(buf, e.first.c_str(), nullptr, 0, FUSE_FILL_DIR_PLUS); - std::string k(path + e.first); - statCache.remove(k); - statCache.add(k, converter.convert(e.second), expiry); + if (auto stat = converter.convert(e.second); stat.st_mode) { + filler(buf, e.first.c_str(), nullptr, 0, FUSE_FILL_DIR_PLUS); + std::string k(path + e.first); + statCache.remove(k); + statCache.add(k, std::move(stat), expiry); + } } } else { + // Standard read dir cannot know the local system cannot represent the inode for (const auto & e : od->remote->readdir()) { filler(buf, e.c_str(), nullptr, 0, (fuse_fill_dir_flags)0); } diff --git a/netfs/fuse/fuseFiles.cpp b/netfs/fuse/fuseFiles.cpp index 0a59252..8014732 100644 --- a/netfs/fuse/fuseFiles.cpp +++ b/netfs/fuse/fuseFiles.cpp @@ -256,7 +256,7 @@ namespace NetFS { *s = converter.convert(volume->getattr(reqEnv(), p)); } } - return 0; + return s->st_mode ? 0 : -ENOENT; } catch (SystemError & e) { return -e.syserrno; diff --git a/netfs/fuse/fuseMappers.ice b/netfs/fuse/fuseMappers.ice new file mode 100644 index 0000000..0eb5ea5 --- /dev/null +++ b/netfs/fuse/fuseMappers.ice @@ -0,0 +1,23 @@ +#include <mapper.ice> + +["slicer:include:fuseMappersImpl.h"] +module NetFS { + module Client { + ["slicer:implementation:NetFS.Client.HideUnknownMapperImpl","slicer:typename:hide"] + local class HideUnknownMapper extends Mapping::Mapper { + + }; + ["slicer:implementation:NetFS.Client.MaskUnknownMapperImpl","slicer:typename:mask"] + local class MaskUnknownMapper extends Mapping::Mapper { + ["slicer:name:unknownuser"] + string UnknownUser = "nobody"; + ["slicer:name:unknowngroup"] + string UnknownGroup = "nogroup"; + ["slicer:name:usermask","slicer:conversion:std.string:NetFS.Client.from_octal:NetFS.Client.to_octal:nodeclare"] + int UserMask = 0700; + ["slicer:name:groupmask","slicer:conversion:std.string:NetFS.Client.from_octal:NetFS.Client.to_octal:nodeclare"] + int GroupMask = 0070; + }; + }; +}; + diff --git a/netfs/fuse/fuseMappersImpl.cpp b/netfs/fuse/fuseMappersImpl.cpp new file mode 100644 index 0000000..c7fef9e --- /dev/null +++ b/netfs/fuse/fuseMappersImpl.cpp @@ -0,0 +1,74 @@ +#include "fuseMappersImpl.h" +#include <entCache.h> + +namespace NetFS::Client { + constexpr int MASK_EVERYTHING = ~0; + static_assert(MASK_EVERYTHING == static_cast<int>(0xFFFFFFFF)); + + Mapping::FileSystem + HideUnknownMapperImpl::mapTransport(const std::string & un, const std::string & gn) + { + auto u = users->getEntry(un); + auto g = groups->getEntry(gn); + if (!u || !g) { + return {0, 0, MASK_EVERYTHING}; + } + return {static_cast<int>(u->id), static_cast<int>(g->id), 0}; + } + + Mapping::Transport + HideUnknownMapperImpl::mapFileSystem(int uid, int gid) + { + auto u = users->getEntry(uid); + auto g = groups->getEntry(gid); + if (!u || !g) { + throw NetFS::SystemError(EPERM); + } + return {u->name, g->name, 0}; + } + + Mapping::FileSystem + MaskUnknownMapperImpl::mapTransport(const std::string & un, const std::string & gn) + { + int mask = 0; + auto apply = [&mask](const auto & resolver, const auto & entry, const auto & fallbackentry, auto entrymask) { + auto e = resolver->getEntry(entry); + if (!e) { + e = resolver->getEntry(fallbackentry); + if (!e) { + throw NetFS::SystemError(EPERM); + } + mask |= entrymask; + } + return e; + }; + auto u = apply(users, un, UnknownUser, UserMask); + auto g = apply(groups, gn, UnknownGroup, GroupMask); + return {static_cast<int>(u->id), static_cast<int>(g->id), mask}; + } + + Mapping::Transport + MaskUnknownMapperImpl::mapFileSystem(int uid, int gid) + { + auto u = users->getEntry(uid); + auto g = groups->getEntry(gid); + if (!u || !g) { + throw NetFS::SystemError(EPERM); + } + return {u->name, g->name, 0}; + } + + Ice::Int + from_octal(const std::string & in) + { + return std::stoi(in, nullptr, 8); + } + + std::string + to_octal(const Ice::Int & in) + { + std::stringstream s; + s << std::oct << in; + return s.str(); + } +} diff --git a/netfs/fuse/fuseMappersImpl.h b/netfs/fuse/fuseMappersImpl.h new file mode 100644 index 0000000..fd9e2aa --- /dev/null +++ b/netfs/fuse/fuseMappersImpl.h @@ -0,0 +1,33 @@ +#ifndef NETFS_MAPPING_CLIENTIMPL_H +#define NETFS_MAPPING_CLIENTIMPL_H + +#include "baseMapper.h" +#include "entries.h" +#include "entryResolver.h" +#include <fuseMappers.h> +#include <visibility.h> + +namespace NetFS { + namespace Client { + std::string to_octal(const Ice::Int &); + Ice::Int from_octal(const std::string &); + + class DLL_PUBLIC HideUnknownMapperImpl : public HideUnknownMapper, Mapping::BaseMapper { + public: + using BaseMapper::BaseMapper; + + Mapping::Transport mapFileSystem(int uid, int gid) override; + Mapping::FileSystem mapTransport(const std::string & un, const std::string & gn) override; + }; + + class DLL_PUBLIC MaskUnknownMapperImpl : public MaskUnknownMapper, Mapping::BaseMapper { + public: + using BaseMapper::BaseMapper; + + Mapping::Transport mapFileSystem(int uid, int gid) override; + Mapping::FileSystem mapTransport(const std::string & un, const std::string & gn) override; + }; + } +} + +#endif |