From 313006557f1c152b091e208ada416a02e7829d6e Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Sun, 30 Aug 2020 19:22:42 +0100 Subject: Clang format all the code --- Jamroot.jam | 2 ++ netfs/fuse/fuseAppBase.cpp | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/Jamroot.jam b/Jamroot.jam index 1dd6e98..368a244 100644 --- a/Jamroot.jam +++ b/Jamroot.jam @@ -33,7 +33,9 @@ project tidy:hicpp-no-array-decay tidy:performance-* tidy:daemonConfig.h + tidy:slicer-daemonConfig.cpp tidy:fuseConfig.h + tidy:slicer-fuseConfig.cpp tidy:directory.h tidy:exceptions.h tidy:file.h diff --git a/netfs/fuse/fuseAppBase.cpp b/netfs/fuse/fuseAppBase.cpp index f2c1f30..49bb1d9 100644 --- a/netfs/fuse/fuseAppBase.cpp +++ b/netfs/fuse/fuseAppBase.cpp @@ -182,8 +182,8 @@ FuseAppBase::lock(const char *, struct fuse_file_info *, int, struct flock *) { return -ENOSYS; } -// NOLINTNEXTLINE(modernize-avoid-c-arrays, hicpp-avoid-c-arrays) int +// NOLINTNEXTLINE(modernize-avoid-c-arrays, hicpp-avoid-c-arrays) FuseAppBase::utimens(const char *, const struct timespec[2], struct fuse_file_info *) { return -ENOSYS; -- cgit v1.2.3 From fc6e9a3316b608b30b5a25b347774181f1730c59 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Mon, 31 Aug 2020 19:52:11 +0100 Subject: First cut extensible mapper Replaces the weird fallback half implementation with something that looks remotely fit for purpose. --- netfs/daemon/daemonVolume.cpp | 4 ++- netfs/fuse/Jamfile.jam | 4 +++ netfs/fuse/fuseApp.cpp | 16 +++++----- netfs/fuse/fuseApp.h | 2 -- netfs/fuse/fuseConfig.ice | 3 ++ netfs/ice/Jamfile.jam | 6 +++- netfs/ice/entryResolver.h | 20 ------------- netfs/ice/mapper.ice | 31 +++++++++++++++++++ netfs/ice/typeConverter.cpp | 16 +++++----- netfs/ice/typeConverter.h | 11 +++---- netfs/lib/defaultMapper.cpp | 26 ++++++++++++++++ netfs/lib/defaultMapper.h | 21 +++++++++++++ netfs/lib/entCache.h | 31 +++++++++---------- netfs/lib/entCache.impl.h | 70 ++++++------------------------------------- netfs/lib/entryResolver.h | 14 +++++++++ netfs/unittests/Jamfile.jam | 2 +- netfs/unittests/testLib.cpp | 62 ++++---------------------------------- 17 files changed, 157 insertions(+), 182 deletions(-) delete mode 100644 netfs/ice/entryResolver.h create mode 100644 netfs/ice/mapper.ice create mode 100644 netfs/lib/defaultMapper.cpp create mode 100644 netfs/lib/defaultMapper.h create mode 100644 netfs/lib/entryResolver.h diff --git a/netfs/daemon/daemonVolume.cpp b/netfs/daemon/daemonVolume.cpp index 3ae43da..7ae3a1f 100644 --- a/netfs/daemon/daemonVolume.cpp +++ b/netfs/daemon/daemonVolume.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -16,7 +17,8 @@ extern std::map files; VolumeServer::VolumeServer(const std::filesystem::path & r, const EntCache & u, const EntCache & g) : - root(std::filesystem::canonical(r)), userLookup(u), groupLookup(g), converter(u, g) + root(std::filesystem::canonical(r)), userLookup(u), groupLookup(g), + converter(std::make_shared()) { } diff --git a/netfs/fuse/Jamfile.jam b/netfs/fuse/Jamfile.jam index 14338d5..8516d8b 100644 --- a/netfs/fuse/Jamfile.jam +++ b/netfs/fuse/Jamfile.jam @@ -6,6 +6,8 @@ obj fuseConfig : fuseConfig.ice : tidy:none ../ice//netfs-api ../ice//netfs-api + ..//slicer + . ; lib netfs-client-configuration : fuseConfig @@ -19,9 +21,11 @@ lib netfs-client-configuration : ..//Ice ..//slicer ..//adhocutil + . : : ..//Ice ..//slicer + . ; lib netfs-client : diff --git a/netfs/fuse/fuseApp.cpp b/netfs/fuse/fuseApp.cpp index 78a3a03..f0576b3 100644 --- a/netfs/fuse/fuseApp.cpp +++ b/netfs/fuse/fuseApp.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -17,10 +18,7 @@ namespace AdHoc { template class CallCacheable; } -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 +78,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(); + } BOOST_ASSERT(fcr); + converter.mapper = fcr->mapper; return this; } @@ -275,8 +277,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 d373e94..b905b23 100644 --- a/netfs/fuse/fuseApp.h +++ b/netfs/fuse/fuseApp.h @@ -111,8 +111,6 @@ namespace NetFS { OpenFiles openFiles; int openHandleId; - EntCache userLookup; - EntCache groupLookup; EntryTypeConverter converter; using StatCache = AdHoc::Cache; diff --git a/netfs/fuse/fuseConfig.ice b/netfs/fuse/fuseConfig.ice index 52116ea..2d2bf9f 100644 --- a/netfs/fuse/fuseConfig.ice +++ b/netfs/fuse/fuseConfig.ice @@ -1,4 +1,5 @@ #include +#include module NetFS { module Client { @@ -20,6 +21,8 @@ module NetFS { ["slicer:name:async"] bool Async = false; + + Mapping::Mapper mapper; }; ["slicer:key:name","slicer:value:resource","slicer:item:resource"] diff --git a/netfs/ice/Jamfile.jam b/netfs/ice/Jamfile.jam index cfb4f14..a695712 100644 --- a/netfs/ice/Jamfile.jam +++ b/netfs/ice/Jamfile.jam @@ -6,14 +6,18 @@ obj file : file.ice : tidy:none ; obj service : service.ice : tidy:none ; obj types : types.ice : tidy:none ; obj volume : volume.ice : tidy:none ; -alias gen : directory exceptions file service types volume ; +obj mapper : mapper.ice : tidy:none ; +alias gen : directory exceptions file service types volume mapper ; lib netfs-api : gen + mapper.ice [ glob *.cpp ] : ..//Ice ..//pthread ..//adhocutil + ..//slicer gen + pure : : . ..//Ice diff --git a/netfs/ice/entryResolver.h b/netfs/ice/entryResolver.h deleted file mode 100644 index 973af4c..0000000 --- a/netfs/ice/entryResolver.h +++ /dev/null @@ -1,20 +0,0 @@ -#ifndef NETFS_ENTRYRESOLVER_H -#define NETFS_ENTRYRESOLVER_H - -#include -#include - -enum class ResolvedAs : uint8_t { - Real, - Fallback, -}; - -template class EntryResolver { -public: - virtual ~EntryResolver() = default; - - virtual ResolvedAs getID(const name_t &, id_t *) const = 0; - virtual ResolvedAs getName(const id_t &, name_t *) const = 0; -}; - -#endif diff --git a/netfs/ice/mapper.ice b/netfs/ice/mapper.ice new file mode 100644 index 0000000..d2f31e8 --- /dev/null +++ b/netfs/ice/mapper.ice @@ -0,0 +1,31 @@ +#ifndef _MAPPER +#define _MAPPER + +#include "exceptions.ice" + +module NetFS { + module Mapping { + ["slicer:ignore"] + local struct Transport { + string username; + string groupname; + int mask; + }; + + ["slicer:ignore"] + local struct FileSystem { + int uid; + int gid; + int mask; + }; + + local class Mapper { + Transport mapFileSystem(int uid, int gid) throws SystemError; + FileSystem mapTransport(string un, string gn) throws SystemError; + }; + }; + +} + +#endif + diff --git a/netfs/ice/typeConverter.cpp b/netfs/ice/typeConverter.cpp index e365c5d..6b33828 100644 --- a/netfs/ice/typeConverter.cpp +++ b/netfs/ice/typeConverter.cpp @@ -1,7 +1,7 @@ #include "typeConverter.h" #include -EntryTypeConverter::EntryTypeConverter(const UserLookup & u, const GroupLookup & g) : userLookup(u), groupLookup(g) { } +EntryTypeConverter::EntryTypeConverter(NetFS::Mapping::MapperPtr m) : mapper(m) { } // Wrapper function to assure no unexpected corruption occurs // during narrowing assignments. @@ -16,14 +16,15 @@ safeAssign(T & t, const S & s) struct stat EntryTypeConverter::convert(const NetFS::Attr & a) const { + auto map = mapper->mapTransport(a.uid, a.gid); struct stat s { }; s.st_dev = a.dev; s.st_ino = a.inode; - s.st_mode = a.mode; + s.st_mode = a.mode & ~map.mask; s.st_nlink = a.links; - userLookup.getID(a.uid, &s.st_uid); - groupLookup.getID(a.gid, &s.st_gid); + s.st_uid = map.uid; + s.st_gid = map.gid; s.st_rdev = a.rdev; s.st_size = a.size; s.st_blksize = a.blockSize; @@ -62,13 +63,14 @@ TypeConverter::convert(const NetFS::VFS & v) const NetFS::Attr EntryTypeConverter::convert(const struct stat & s) const { + auto map = mapper->mapFileSystem(s.st_uid, s.st_gid); NetFS::Attr a {}; a.dev = s.st_dev; a.inode = s.st_ino; - a.mode = s.st_mode; + a.mode = s.st_mode & ~map.mask; a.links = s.st_nlink; - userLookup.getName(s.st_uid, &a.uid); - groupLookup.getName(s.st_gid, &a.gid); + a.uid = std::move(map.username); + a.gid = std::move(map.groupname); a.rdev = s.st_rdev; a.size = s.st_size; a.blockSize = s.st_blksize; diff --git a/netfs/ice/typeConverter.h b/netfs/ice/typeConverter.h index 3cd2941..0baff2b 100644 --- a/netfs/ice/typeConverter.h +++ b/netfs/ice/typeConverter.h @@ -1,7 +1,7 @@ #ifndef NETFS_TYPECONVERT_H #define NETFS_TYPECONVERT_H -#include "entryResolver.h" +#include #include #include #include @@ -16,17 +16,14 @@ public: class DLL_PUBLIC EntryTypeConverter : public TypeConverter { public: - using UserLookup = EntryResolver; - using GroupLookup = EntryResolver; - EntryTypeConverter(const UserLookup &, const GroupLookup &); + EntryTypeConverter() = default; + EntryTypeConverter(NetFS::Mapping::MapperPtr); // Attributes struct stat convert(const NetFS::Attr &) const; NetFS::Attr convert(const struct stat &) const; -protected: - const UserLookup & userLookup; - const GroupLookup & groupLookup; + NetFS::Mapping::MapperPtr mapper; }; #endif diff --git a/netfs/lib/defaultMapper.cpp b/netfs/lib/defaultMapper.cpp new file mode 100644 index 0000000..1d75e12 --- /dev/null +++ b/netfs/lib/defaultMapper.cpp @@ -0,0 +1,26 @@ +#include "defaultMapper.h" +#include + +namespace NetFS::Mapping { + FileSystem + DefaultMapper::mapTransport(const std::string & un, const std::string & gn) + { + auto u = users.getEntry(un); + auto g = groups.getEntry(gn); + if (!u || !g) { + throw NetFS::SystemError(EPERM); + } + return {static_cast(u->id), static_cast(g->id), 0}; + } + + Transport + DefaultMapper::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}; + } +} diff --git a/netfs/lib/defaultMapper.h b/netfs/lib/defaultMapper.h new file mode 100644 index 0000000..719c7bf --- /dev/null +++ b/netfs/lib/defaultMapper.h @@ -0,0 +1,21 @@ +#ifndef NETFS_MAPPING_DEFAULTIMPL_H +#define NETFS_MAPPING_DEFAULTIMPL_H + +#include "entCache.h" +#include + +namespace NetFS { + namespace Mapping { + class DefaultMapper : public Mapper { + public: + Transport mapFileSystem(int uid, int gid) override; + FileSystem mapTransport(const std::string & un, const std::string & gn) override; + + protected: + UserEntCache users; + GroupEntCache groups; + }; + } +} + +#endif diff --git a/netfs/lib/entCache.h b/netfs/lib/entCache.h index e8c6461..02224f5 100644 --- a/netfs/lib/entCache.h +++ b/netfs/lib/entCache.h @@ -1,11 +1,12 @@ #ifndef ENTCACHE_H #define ENTCACHE_H +#include "entryResolver.h" #include -#include #include #include #include +#include class User { public: @@ -26,11 +27,10 @@ public: std::set members; }; -template class EntCache : public EntryResolver { +template class EntCache : public EntryResolver { public: EntCache(); - EntCache(entry_t fb); - ~EntCache() override; + ~EntCache() noexcept override; SPECIAL_MEMBERS_DEFAULT_MOVE_NO_COPY(EntCache); @@ -38,27 +38,24 @@ public: using name_t = decltype(entry_t::name); using entry_ptr = std::shared_ptr; - struct Resolution : public entry_ptr { - Resolution(entry_ptr, ResolvedAs = ResolvedAs::Real); - ResolvedAs resolution; + [[nodiscard]] entry_ptr inline getEntry(const id_t & i) const noexcept override + { + return getEntryInternal(i); + } + [[nodiscard]] entry_ptr inline getEntry(const name_t & n) const noexcept override + { + return getEntryInternal(n); }; - ResolvedAs getID(const name_t &, id_t *) const override; - ResolvedAs getName(const id_t &, name_t *) const override; - template Resolution getEntry(const key_t &) const; - - void setFallback(entry_t fb); - void clearFallback(); - protected: - void fillCache() const; - template entry_ptr getEntryNoFill(const key_t &) const; + void fillCache() const noexcept; + template[[nodiscard]] entry_ptr getEntryInternal(const key_t &) const noexcept; + template[[nodiscard]] entry_ptr getEntryNoFill(const key_t &) const noexcept; class Ids; std::unique_ptr idcache; mutable std::shared_mutex lock; mutable time_t fillTime {0}; - entry_ptr fallback; }; using UserEntCache = EntCache; diff --git a/netfs/lib/entCache.impl.h b/netfs/lib/entCache.impl.h index 0021f00..6243d7d 100644 --- a/netfs/lib/entCache.impl.h +++ b/netfs/lib/entCache.impl.h @@ -5,7 +5,6 @@ #include #include #include -#include #include #include #include @@ -21,41 +20,12 @@ class EntCache::Ids : }; template EntCache::EntCache() : idcache(std::make_unique()) { } - -template EntCache::EntCache(entry_t fb) : idcache(std::make_unique()) -{ - setFallback(std::move(fb)); -} - -template EntCache::~EntCache() = default; - -template -ResolvedAs -EntCache::getID(const EntCache::name_t & u, EntCache::id_t * target) const -{ - auto e = getEntry(u); - *target = e->id; - return e.resolution; -} - -template -ResolvedAs -EntCache::getName(const EntCache::id_t & u, EntCache::name_t * target) const -{ - auto e = getEntry(u); - *target = e->name; - return e.resolution; -} - -template -EntCache::Resolution::Resolution(entry_ptr e, ResolvedAs res) : entry_ptr(std::move(e)), resolution(res) -{ -} +template EntCache::~EntCache() noexcept = default; template template -typename EntCache::Resolution -EntCache::getEntry(const key_t & key) const +typename EntCache::entry_ptr +EntCache::getEntryInternal(const key_t & key) const noexcept { if (fillTime + 60 > time(nullptr)) { if (auto ent = getEntryNoFill(key)) { @@ -63,19 +33,13 @@ EntCache::getEntry(const key_t & key) const } } fillCache(); - if (auto ent = getEntryNoFill(key)) { - return ent; - } - if (fallback) { - return {fallback, ResolvedAs::Fallback}; - } - throw NetFS::SystemError(EPERM); + return getEntryNoFill(key); } template template typename EntCache::entry_ptr -EntCache::getEntryNoFill(const key_t & key) const +EntCache::getEntryNoFill(const key_t & key) const noexcept { SharedLock(lock); auto & collection = idcache->template get(); @@ -86,27 +50,13 @@ EntCache::getEntryNoFill(const key_t & key) const return nullptr; } -template -void -EntCache::setFallback(entry_t fb) -{ - fallback = std::make_shared(std::move(fb)); -} - -template -void -EntCache::clearFallback() -{ - fallback.reset(); -} - User::User(uid_t u, std::string n, gid_t g) : id(u), name(std::move(n)), group(g) { } const int BUFLEN = 8196; template<> void -EntCache::fillCache() const +EntCache::fillCache() const noexcept { Lock(lock); setpwent(); @@ -125,7 +75,7 @@ Group::Group(gid_t g, std::string n) : id(g), name(std::move(n)) { } template<> void -EntCache::fillCache() const +EntCache::fillCache() const noexcept { Lock(lock); setgrent(); @@ -137,10 +87,8 @@ EntCache::fillCache() const while (getgrent_r(&grpbuf, buf.data(), buf.size(), &grp) == 0) { auto g = std::make_shared(grp->gr_gid, grp->gr_name); for (auto member = grp->gr_mem; *member; member++) { - try { - g->members.insert(instance.getEntry((const name_t &)*member)->id); - } - catch (const NetFS::SystemError &) { + if (auto ent = instance.getEntry((const gid_t &)*member)) { + g->members.insert(ent->id); } } idcache->insert(std::move(g)); diff --git a/netfs/lib/entryResolver.h b/netfs/lib/entryResolver.h new file mode 100644 index 0000000..84eb6ed --- /dev/null +++ b/netfs/lib/entryResolver.h @@ -0,0 +1,14 @@ +#ifndef NETFS_ENTRYRESOLVER_H +#define NETFS_ENTRYRESOLVER_H + +#include + +template class EntryResolver { +public: + virtual ~EntryResolver() noexcept = default; + + virtual std::shared_ptr getEntry(const decltype(entry_t::id) &) const noexcept = 0; + virtual std::shared_ptr getEntry(const decltype(entry_t::name) &) const noexcept = 0; +}; + +#endif diff --git a/netfs/unittests/Jamfile.jam b/netfs/unittests/Jamfile.jam index f1f3dba..18abadd 100644 --- a/netfs/unittests/Jamfile.jam +++ b/netfs/unittests/Jamfile.jam @@ -74,7 +74,6 @@ run testLib.cpp testMocks ; -# explicit testFuse ; run testFuse.cpp : -- : defaultDaemon.xml @@ -82,5 +81,6 @@ run testFuse.cpp BOOST_TEST_DYN_LINK boost_utf testMocks + testCore ; diff --git a/netfs/unittests/testLib.cpp b/netfs/unittests/testLib.cpp index b44ab37..14ea71f 100644 --- a/netfs/unittests/testLib.cpp +++ b/netfs/unittests/testLib.cpp @@ -4,15 +4,6 @@ #include #include -namespace std { - ostream & - operator<<(ostream & strm, const ResolvedAs & r) - { - strm << r; - return strm; - } -} - struct TestEntry { TestEntry(int i, std::string n) : id(i), name(std::move(n)) { } @@ -23,7 +14,7 @@ using TestEntCache = EntCache; template<> void -EntCache::fillCache() const +EntCache::fillCache() const noexcept { Lock(lock); idcache->insert(std::make_shared(1, "user1")); @@ -40,65 +31,22 @@ BOOST_FIXTURE_TEST_SUITE(tec, TestEntCache); BOOST_DATA_TEST_CASE(notfoundid, BadIds, id) { - std::string outname; - BOOST_CHECK_THROW(getName(id, &outname), NetFS::SystemError); -} - -BOOST_DATA_TEST_CASE(notfoundname, BadNames, name) -{ - int outid; - BOOST_CHECK_THROW(getID(name, &outid), NetFS::SystemError); -} - -BOOST_DATA_TEST_CASE(foundid, GoodNames ^ GoodIds, name, id) -{ - std::string outname; - BOOST_CHECK_EQUAL(getName(id, &outname), ResolvedAs::Real); - BOOST_CHECK_EQUAL(name, outname); -} - -BOOST_DATA_TEST_CASE(foundname, GoodNames ^ GoodIds, name, id) -{ - int outid; - BOOST_CHECK_EQUAL(getID(name, &outid), ResolvedAs::Real); - BOOST_CHECK_EQUAL(id, outid); -} - -BOOST_AUTO_TEST_SUITE_END(); - -class TestEntCacheWithFallback : public TestEntCache { -public: - TestEntCacheWithFallback() : TestEntCache({4, "fallback"}) { } -}; - -BOOST_FIXTURE_TEST_SUITE(tecfb, TestEntCacheWithFallback); - -BOOST_DATA_TEST_CASE(notfoundid, BadIds, id) -{ - std::string outname; - BOOST_CHECK_EQUAL(getName(id, &outname), ResolvedAs::Fallback); - BOOST_CHECK_EQUAL(outname, fallback->name); + BOOST_CHECK(!getEntry(id)); } BOOST_DATA_TEST_CASE(notfoundname, BadNames, name) { - int outid; - BOOST_CHECK_EQUAL(getID(name, &outid), ResolvedAs::Fallback); - BOOST_CHECK_EQUAL(outid, fallback->id); + BOOST_CHECK(!getEntry(name)); } BOOST_DATA_TEST_CASE(foundid, GoodNames ^ GoodIds, name, id) { - std::string outname; - BOOST_CHECK_EQUAL(getName(id, &outname), ResolvedAs::Real); - BOOST_CHECK_EQUAL(name, outname); + BOOST_CHECK_EQUAL(getEntry(id)->name, name); } BOOST_DATA_TEST_CASE(foundname, GoodNames ^ GoodIds, name, id) { - int outid; - BOOST_CHECK_EQUAL(getID(name, &outid), ResolvedAs::Real); - BOOST_CHECK_EQUAL(id, outid); + BOOST_CHECK_EQUAL(getEntry(name)->id, id); } BOOST_AUTO_TEST_SUITE_END(); -- cgit v1.2.3 From 4d9b633c79ca86140af90c92b7a732dc0bbbe2bd Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Wed, 2 Sep 2020 00:12:06 +0100 Subject: Tidy up of previous commit of extensible mapper --- Jamroot.jam | 4 ++-- netfs/daemon/daemonService.cpp | 7 ++++++- netfs/daemon/daemonService.h | 7 ++++--- netfs/daemon/daemonVolume.cpp | 7 ++++--- netfs/daemon/daemonVolume.h | 9 +++++---- netfs/daemon/modeCheck.cpp | 5 ++--- netfs/daemon/modeCheck.h | 10 ++++++---- netfs/fuse/fuseApp.impl.h | 3 +-- netfs/ice/typeConverter.cpp | 4 ++-- netfs/lib/defaultMapper.cpp | 19 +++++++++++++++---- netfs/lib/defaultMapper.h | 10 +++++++--- netfs/lib/entCache.cpp | 6 +----- netfs/lib/entCache.h | 25 ------------------------- netfs/lib/entCache.impl.h | 11 +---------- netfs/lib/entries.cpp | 16 ++++++++++++++++ netfs/lib/entries.h | 27 +++++++++++++++++++++++++++ netfs/lib/entryResolver.h | 7 +++++-- 17 files changed, 104 insertions(+), 73 deletions(-) create mode 100644 netfs/lib/entries.cpp create mode 100644 netfs/lib/entries.h diff --git a/Jamroot.jam b/Jamroot.jam index 368a244..af15ca5 100644 --- a/Jamroot.jam +++ b/Jamroot.jam @@ -14,8 +14,7 @@ project 17 hidden "-Wl,-z,defs,--warn-once,--gc-sections" - release:"-flto=3" - release:"-flto=3" + release:on debuggcc:-Wlogical-op debug:extra debug:on @@ -36,6 +35,7 @@ project tidy:slicer-daemonConfig.cpp tidy:fuseConfig.h tidy:slicer-fuseConfig.cpp + tidy:slicer-mapper.cpp tidy:directory.h tidy:exceptions.h tidy:file.h diff --git a/netfs/daemon/daemonService.cpp b/netfs/daemon/daemonService.cpp index 18b050d..6ffcf71 100644 --- a/netfs/daemon/daemonService.cpp +++ b/netfs/daemon/daemonService.cpp @@ -1,9 +1,14 @@ #include "daemonService.h" #include "daemon.h" #include "daemonVolume.h" +#include #include -ServiceServer::ServiceServer(NetFS::Daemon::ConfigurationPtr c) : config(std::move(c)) { } +ServiceServer::ServiceServer(NetFS::Daemon::ConfigurationPtr c) : + userLookup(std::make_shared>()), groupLookup(std::make_shared>()), + config(std::move(c)) +{ +} NetFS::VolumePrxPtr ServiceServer::connect(const std::string share, const std::string authtoken, const Ice::Current & ice) diff --git a/netfs/daemon/daemonService.h b/netfs/daemon/daemonService.h index e0f80ef..753583e 100644 --- a/netfs/daemon/daemonService.h +++ b/netfs/daemon/daemonService.h @@ -2,7 +2,8 @@ #define DAEMONSERVICE_H #include -#include +#include +#include #include class ServiceServer : public NetFS::Service { @@ -12,8 +13,8 @@ public: NetFS::VolumePrxPtr connect(const std::string share, const std::string auth, const Ice::Current &) override; private: - EntCache userLookup; - EntCache groupLookup; + EntryResolverPtr userLookup; + EntryResolverPtr groupLookup; NetFS::Daemon::ConfigurationPtr config; }; diff --git a/netfs/daemon/daemonVolume.cpp b/netfs/daemon/daemonVolume.cpp index 7ae3a1f..ff75e06 100644 --- a/netfs/daemon/daemonVolume.cpp +++ b/netfs/daemon/daemonVolume.cpp @@ -16,9 +16,10 @@ extern std::map files; -VolumeServer::VolumeServer(const std::filesystem::path & r, const EntCache & u, const EntCache & g) : - root(std::filesystem::canonical(r)), userLookup(u), groupLookup(g), - converter(std::make_shared()) +VolumeServer::VolumeServer( + const std::filesystem::path & r, const EntryResolverPtr & u, const EntryResolverPtr & g) : + root(std::filesystem::canonical(r)), + userLookup(*u), groupLookup(*g), converter(std::make_shared(u, g)) { } diff --git a/netfs/daemon/daemonVolume.h b/netfs/daemon/daemonVolume.h index b75c5d6..649d8c2 100644 --- a/netfs/daemon/daemonVolume.h +++ b/netfs/daemon/daemonVolume.h @@ -1,7 +1,8 @@ #ifndef DAEMONVOLUME_H #define DAEMONVOLUME_H -#include +#include +#include #include #include #include @@ -9,7 +10,7 @@ class VolumeServer : public NetFS::Volume { public: - VolumeServer(const std::filesystem::path & root, const EntCache &, const EntCache &); + VolumeServer(const std::filesystem::path & root, const EntryResolverPtr &, const EntryResolverPtr &); NetFS::DirectoryPrxPtr opendir(const NetFS::ReqEnv, std::string path, const Ice::Current &) override; @@ -47,8 +48,8 @@ protected: private: const std::filesystem::path root; - const EntCache & userLookup; - const EntCache & groupLookup; + EntryResolver & userLookup; + EntryResolver & groupLookup; EntryTypeConverter converter; }; diff --git a/netfs/daemon/modeCheck.cpp b/netfs/daemon/modeCheck.cpp index 6e65888..177d9b8 100644 --- a/netfs/daemon/modeCheck.cpp +++ b/netfs/daemon/modeCheck.cpp @@ -1,9 +1,8 @@ #include "modeCheck.h" -#include #include -ModeCheck::ModeCheck(const NetFS::ReqEnv & re, const std::filesystem::path & r, const EntCache & u, - const EntCache & g) : +ModeCheck::ModeCheck(const NetFS::ReqEnv & re, const std::filesystem::path & r, const EntryResolver & u, + const EntryResolver & g) : myu(u.getEntry(re.user)->id), myg(g.getEntry(re.grp)->id), root(r), userLookup(u), groupLookup(g) { diff --git a/netfs/daemon/modeCheck.h b/netfs/daemon/modeCheck.h index 693ad8d..6365816 100644 --- a/netfs/daemon/modeCheck.h +++ b/netfs/daemon/modeCheck.h @@ -1,14 +1,16 @@ #ifndef NETFS_DAEMON_IOHELPERS #define NETFS_DAEMON_IOHELPERS -#include +#include +#include #include #include #include class ModeCheck { public: - ModeCheck(const NetFS::ReqEnv & re, const std::filesystem::path &, const EntCache &, const EntCache &); + ModeCheck(const NetFS::ReqEnv & re, const std::filesystem::path &, const EntryResolver &, + const EntryResolver &); void AssertReadParent(const std::filesystem::path &) const; void AssertRead(const std::filesystem::path &) const; @@ -27,8 +29,8 @@ public: private: static struct stat lstat(const std::filesystem::path &); - const EntCache & userLookup; - const EntCache & groupLookup; + const EntryResolver & userLookup; + const EntryResolver & groupLookup; }; #endif 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(); Lock(_proxymaplock); - while (map.find(fh = ++openHandleId) != map.end()) - ; + while (map.find(fh = ++openHandleId) != map.end()) { } map.emplace(fh, std::make_shared(params...)); } diff --git a/netfs/ice/typeConverter.cpp b/netfs/ice/typeConverter.cpp index 6b33828..b1ade2b 100644 --- a/netfs/ice/typeConverter.cpp +++ b/netfs/ice/typeConverter.cpp @@ -1,7 +1,7 @@ #include "typeConverter.h" #include -EntryTypeConverter::EntryTypeConverter(NetFS::Mapping::MapperPtr m) : mapper(m) { } +EntryTypeConverter::EntryTypeConverter(NetFS::Mapping::MapperPtr m) : mapper(std::move(m)) { } // Wrapper function to assure no unexpected corruption occurs // during narrowing assignments. @@ -67,7 +67,7 @@ EntryTypeConverter::convert(const struct stat & s) const NetFS::Attr a {}; a.dev = s.st_dev; a.inode = s.st_ino; - a.mode = s.st_mode & ~map.mask; + safeAssign(a.mode, s.st_mode & ~map.mask); a.links = s.st_nlink; a.uid = std::move(map.username); a.gid = std::move(map.groupname); diff --git a/netfs/lib/defaultMapper.cpp b/netfs/lib/defaultMapper.cpp index 1d75e12..27b20d3 100644 --- a/netfs/lib/defaultMapper.cpp +++ b/netfs/lib/defaultMapper.cpp @@ -1,12 +1,23 @@ #include "defaultMapper.h" +#include "entCache.h" #include namespace NetFS::Mapping { + DefaultMapper::DefaultMapper() : + DefaultMapper(std::make_shared>(), std::make_shared>()) + { + } + + DefaultMapper::DefaultMapper(EntryResolverPtr u, EntryResolverPtr g) : + users(std::move(u)), groups(std::move(g)) + { + } + FileSystem DefaultMapper::mapTransport(const std::string & un, const std::string & gn) { - auto u = users.getEntry(un); - auto g = groups.getEntry(gn); + auto u = users->getEntry(un); + auto g = groups->getEntry(gn); if (!u || !g) { throw NetFS::SystemError(EPERM); } @@ -16,8 +27,8 @@ namespace NetFS::Mapping { Transport DefaultMapper::mapFileSystem(int uid, int gid) { - auto u = users.getEntry(uid); - auto g = groups.getEntry(gid); + auto u = users->getEntry(uid); + auto g = groups->getEntry(gid); if (!u || !g) { throw NetFS::SystemError(EPERM); } diff --git a/netfs/lib/defaultMapper.h b/netfs/lib/defaultMapper.h index 719c7bf..214f9ed 100644 --- a/netfs/lib/defaultMapper.h +++ b/netfs/lib/defaultMapper.h @@ -1,19 +1,23 @@ #ifndef NETFS_MAPPING_DEFAULTIMPL_H #define NETFS_MAPPING_DEFAULTIMPL_H -#include "entCache.h" +#include "entries.h" +#include "entryResolver.h" #include namespace NetFS { namespace Mapping { class DefaultMapper : public Mapper { public: + DefaultMapper(); + DefaultMapper(EntryResolverPtr users, EntryResolverPtr groups); + Transport mapFileSystem(int uid, int gid) override; FileSystem mapTransport(const std::string & un, const std::string & gn) override; protected: - UserEntCache users; - GroupEntCache groups; + EntryResolverPtr users; + EntryResolverPtr groups; }; } } diff --git a/netfs/lib/entCache.cpp b/netfs/lib/entCache.cpp index d9f61df..e1a20a5 100644 --- a/netfs/lib/entCache.cpp +++ b/netfs/lib/entCache.cpp @@ -1,9 +1,5 @@ #include "entCache.impl.h" - -static_assert(std::is_nothrow_move_constructible_v); -static_assert(std::is_nothrow_move_assignable_v); -static_assert(std::is_nothrow_move_constructible_v); -static_assert(std::is_nothrow_move_assignable_v); +#include "entries.h" template class EntCache; template class EntCache; diff --git a/netfs/lib/entCache.h b/netfs/lib/entCache.h index 02224f5..7a9a3ef 100644 --- a/netfs/lib/entCache.h +++ b/netfs/lib/entCache.h @@ -3,29 +3,7 @@ #include "entryResolver.h" #include -#include #include -#include -#include - -class User { -public: - User(uid_t, std::string, gid_t); - uid_t id; - std::string name; - gid_t group; -}; - -class Group { -public: - Group(gid_t, std::string); - - bool hasMember(uid_t) const; - - gid_t id; - std::string name; - std::set members; -}; template class EntCache : public EntryResolver { public: @@ -58,7 +36,4 @@ protected: mutable time_t fillTime {0}; }; -using UserEntCache = EntCache; -using GroupEntCache = EntCache; - #endif diff --git a/netfs/lib/entCache.impl.h b/netfs/lib/entCache.impl.h index 6243d7d..ad8fb33 100644 --- a/netfs/lib/entCache.impl.h +++ b/netfs/lib/entCache.impl.h @@ -2,6 +2,7 @@ #define ENTCACHE_IMPL_H #include "entCache.h" +#include "entries.h" #include #include #include @@ -50,8 +51,6 @@ EntCache::getEntryNoFill(const key_t & key) const noexcept return nullptr; } -User::User(uid_t u, std::string n, gid_t g) : id(u), name(std::move(n)), group(g) { } - const int BUFLEN = 8196; template<> @@ -71,8 +70,6 @@ EntCache::fillCache() const noexcept time(&fillTime); } -Group::Group(gid_t g, std::string n) : id(g), name(std::move(n)) { } - template<> void EntCache::fillCache() const noexcept @@ -97,10 +94,4 @@ EntCache::fillCache() const noexcept time(&fillTime); } -bool -Group::hasMember(uid_t u) const -{ - return (members.find(u) != members.end()); -} - #endif diff --git a/netfs/lib/entries.cpp b/netfs/lib/entries.cpp new file mode 100644 index 0000000..bde15e6 --- /dev/null +++ b/netfs/lib/entries.cpp @@ -0,0 +1,16 @@ +#include "entries.h" + +static_assert(std::is_nothrow_move_constructible_v); +static_assert(std::is_nothrow_move_assignable_v); +static_assert(std::is_nothrow_move_constructible_v); +static_assert(std::is_nothrow_move_assignable_v); + +User::User(uid_t u, std::string n, gid_t g) : id(u), name(std::move(n)), group(g) { } + +Group::Group(gid_t g, std::string n) : id(g), name(std::move(n)) { } + +bool +Group::hasMember(uid_t u) const noexcept +{ + return (members.find(u) != members.end()); +} diff --git a/netfs/lib/entries.h b/netfs/lib/entries.h new file mode 100644 index 0000000..6e032e1 --- /dev/null +++ b/netfs/lib/entries.h @@ -0,0 +1,27 @@ +#ifndef ENTRIES_H +#define ENTRIES_H + +#include +#include +#include + +class User { +public: + User(uid_t, std::string, gid_t); + uid_t id; + std::string name; + gid_t group; +}; + +class Group { +public: + Group(gid_t, std::string); + + bool hasMember(uid_t) const noexcept; + + gid_t id; + std::string name; + std::set members; +}; + +#endif diff --git a/netfs/lib/entryResolver.h b/netfs/lib/entryResolver.h index 84eb6ed..86aaace 100644 --- a/netfs/lib/entryResolver.h +++ b/netfs/lib/entryResolver.h @@ -6,9 +6,12 @@ template class EntryResolver { public: virtual ~EntryResolver() noexcept = default; + using EntryPtr = std::shared_ptr; - virtual std::shared_ptr getEntry(const decltype(entry_t::id) &) const noexcept = 0; - virtual std::shared_ptr getEntry(const decltype(entry_t::name) &) const noexcept = 0; + virtual EntryPtr getEntry(const decltype(entry_t::id) &) const noexcept = 0; + virtual EntryPtr getEntry(const decltype(entry_t::name) &) const noexcept = 0; }; +template using EntryResolverPtr = std::shared_ptr>; + #endif -- cgit v1.2.3 From f3dc6a708d4fc8cde49bacb69a5b5ac052594930 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Sat, 5 Sep 2020 17:46:50 +0100 Subject: Single FUSE version definition --- netfs/fuse/Jamfile.jam | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/netfs/fuse/Jamfile.jam b/netfs/fuse/Jamfile.jam index 8516d8b..d700c37 100644 --- a/netfs/fuse/Jamfile.jam +++ b/netfs/fuse/Jamfile.jam @@ -1,6 +1,7 @@ import package ; lib Glacier2 : : Glacier2++11 ; +constant FUSE_VER : 35 ; obj fuseConfig : fuseConfig.ice : tidy:none @@ -32,7 +33,7 @@ lib netfs-client : netfs-client-configuration [ glob *.cpp : fuseConfigImpl.cpp netfs.cpp ] : - FUSE_USE_VERSION=35 + FUSE_USE_VERSION=$(FUSE_VER) ../ice//netfs-api netfs-client-configuration netfs-client-configuration @@ -46,7 +47,7 @@ lib netfs-client : ..//slicer-xml ../..//fuse : : - FUSE_USE_VERSION=31 + FUSE_USE_VERSION=$(FUSE_VER) . ../ice//netfs-api Glacier2 -- cgit v1.2.3 From 615c32991893ee43f274f80535d04489dd71bf0a Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Sun, 6 Sep 2020 00:16:30 +0100 Subject: Support mapper rejection signalled by 0 st_mode --- netfs/fuse/fuseDirs.cpp | 11 +++++++---- netfs/fuse/fuseFiles.cpp | 2 +- 2 files changed, 8 insertions(+), 5 deletions(-) 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; -- cgit v1.2.3 From 1cd8302a4ba6e4553738a1547de37af12a6aa35f Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Sun, 6 Sep 2020 00:17:45 +0100 Subject: Add the HideUnknown mapper This mapper hides inodes for which the user and/or group cannot be mapped to local entries --- netfs/fuse/Jamfile.jam | 23 ++++++++++++++++------- netfs/fuse/fuseApp.cpp | 12 ++++++++++++ netfs/fuse/fuseMappers.ice | 12 ++++++++++++ netfs/fuse/fuseMappersImpl.cpp | 36 ++++++++++++++++++++++++++++++++++++ netfs/fuse/fuseMappersImpl.h | 25 +++++++++++++++++++++++++ 5 files changed, 101 insertions(+), 7 deletions(-) create mode 100644 netfs/fuse/fuseMappers.ice create mode 100644 netfs/fuse/fuseMappersImpl.cpp create mode 100644 netfs/fuse/fuseMappersImpl.h diff --git a/netfs/fuse/Jamfile.jam b/netfs/fuse/Jamfile.jam index d700c37..4d000be 100644 --- a/netfs/fuse/Jamfile.jam +++ b/netfs/fuse/Jamfile.jam @@ -3,20 +3,29 @@ import package ; lib Glacier2 : : Glacier2++11 ; constant FUSE_VER : 35 ; -obj fuseConfig : fuseConfig.ice : - tidy:none - ../ice//netfs-api - ../ice//netfs-api - ..//slicer - . -; +rule iceobj ( name : ice ) { + obj $(name) : $(ice) : + tidy:none + ../ice//netfs-api + ../ice//netfs-api + ..//slicer + . + ; +} +iceobj fuseConfig : fuseConfig.ice ; +iceobj fuseMappers : fuseMappers.ice ; + lib netfs-client-configuration : fuseConfig + fuseMappers fuseConfig.ice + fuseMappers.ice fuseConfigImpl.cpp + fuseMappersImpl.cpp : pure ../ice//netfs-api + ../lib//netfs-common ../ice//netfs-api fuseConfig ..//Ice diff --git a/netfs/fuse/fuseApp.cpp b/netfs/fuse/fuseApp.cpp index f0576b3..ff1585a 100644 --- a/netfs/fuse/fuseApp.cpp +++ b/netfs/fuse/fuseApp.cpp @@ -2,6 +2,7 @@ #include "cache.impl.h" #include "fuseDirs.h" #include "fuseFiles.h" +#include "fuseMappersImpl.h" #include "lockHelpers.h" #include #include @@ -111,7 +112,18 @@ NetFS::FuseApp::configureFromUri(const std::string & uriString) setting = boost::lexical_cast>(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, [](auto && m) -> NetFS::Mapping::MapperPtr { + if (m == "hide") { + return std::make_shared(); + } + return {}; + }); return r; } diff --git a/netfs/fuse/fuseMappers.ice b/netfs/fuse/fuseMappers.ice new file mode 100644 index 0000000..6945eec --- /dev/null +++ b/netfs/fuse/fuseMappers.ice @@ -0,0 +1,12 @@ +#include + +["slicer:include:fuseMappersImpl.h"] +module NetFS { + module Client { + ["slicer:implementation:NetFS.Client.HideUnknownMapperImpl"] + local class HideUnknownMapper extends Mapping::Mapper { + + }; + }; +}; + diff --git a/netfs/fuse/fuseMappersImpl.cpp b/netfs/fuse/fuseMappersImpl.cpp new file mode 100644 index 0000000..9a99eca --- /dev/null +++ b/netfs/fuse/fuseMappersImpl.cpp @@ -0,0 +1,36 @@ +#include "fuseMappersImpl.h" +#include + +namespace NetFS::Client { + HideUnknownMapperImpl::HideUnknownMapperImpl() : + HideUnknownMapperImpl(std::make_shared>(), std::make_shared>()) + { + } + + HideUnknownMapperImpl::HideUnknownMapperImpl(EntryResolverPtr u, EntryResolverPtr g) : + users(std::move(u)), groups(std::move(g)) + { + } + + 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, 0xFFFFFFF}; + } + return {static_cast(u->id), static_cast(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}; + } +} diff --git a/netfs/fuse/fuseMappersImpl.h b/netfs/fuse/fuseMappersImpl.h new file mode 100644 index 0000000..4b0677f --- /dev/null +++ b/netfs/fuse/fuseMappersImpl.h @@ -0,0 +1,25 @@ +#ifndef NETFS_MAPPING_CLIENTIMPL_H +#define NETFS_MAPPING_CLIENTIMPL_H + +#include "entries.h" +#include "entryResolver.h" +#include + +namespace NetFS { + namespace Client { + class HideUnknownMapperImpl : public HideUnknownMapper { + public: + HideUnknownMapperImpl(); + HideUnknownMapperImpl(EntryResolverPtr u, EntryResolverPtr g); + + Mapping::Transport mapFileSystem(int uid, int gid) override; + Mapping::FileSystem mapTransport(const std::string & un, const std::string & gn) override; + + protected: + EntryResolverPtr users; + EntryResolverPtr groups; + }; + } +} + +#endif -- cgit v1.2.3 From 3606662bbe5a8ff38220ecbc4d7d927a231f8a2f Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Wed, 9 Sep 2020 20:49:42 +0100 Subject: Add test for Group::hasMember --- netfs/unittests/testLib.cpp | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/netfs/unittests/testLib.cpp b/netfs/unittests/testLib.cpp index 14ea71f..ba3ef44 100644 --- a/netfs/unittests/testLib.cpp +++ b/netfs/unittests/testLib.cpp @@ -50,3 +50,18 @@ BOOST_DATA_TEST_CASE(foundname, GoodNames ^ GoodIds, name, id) } BOOST_AUTO_TEST_SUITE_END(); + +BOOST_AUTO_TEST_CASE(group_membership) +{ + Group g(0, "root"); + g.members.insert(0); + g.members.insert(1); + g.members.insert(5); + + BOOST_REQUIRE_EQUAL(3, g.members.size()); + BOOST_CHECK(g.hasMember(0)); + BOOST_CHECK(g.hasMember(1)); + BOOST_CHECK(g.hasMember(5)); + BOOST_CHECK(!g.hasMember(3)); + BOOST_CHECK(!g.hasMember(6)); +} -- cgit v1.2.3 From 087419efdc1032a0e05c73c4273762d10d68c555 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Wed, 9 Sep 2020 21:11:42 +0100 Subject: Fix group membership loading --- netfs/lib/entCache.impl.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/netfs/lib/entCache.impl.h b/netfs/lib/entCache.impl.h index ad8fb33..6523d32 100644 --- a/netfs/lib/entCache.impl.h +++ b/netfs/lib/entCache.impl.h @@ -84,7 +84,7 @@ EntCache::fillCache() const noexcept while (getgrent_r(&grpbuf, buf.data(), buf.size(), &grp) == 0) { auto g = std::make_shared(grp->gr_gid, grp->gr_name); for (auto member = grp->gr_mem; *member; member++) { - if (auto ent = instance.getEntry((const gid_t &)*member)) { + if (auto ent = instance.getEntry(*member)) { g->members.insert(ent->id); } } -- cgit v1.2.3 From e238261578c19d3736727f599852e8868d60688d Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Wed, 9 Sep 2020 21:18:29 +0100 Subject: Test EntCache basics for User and Group --- netfs/unittests/testLib.cpp | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/netfs/unittests/testLib.cpp b/netfs/unittests/testLib.cpp index ba3ef44..2985c93 100644 --- a/netfs/unittests/testLib.cpp +++ b/netfs/unittests/testLib.cpp @@ -65,3 +65,28 @@ BOOST_AUTO_TEST_CASE(group_membership) BOOST_CHECK(!g.hasMember(3)); BOOST_CHECK(!g.hasMember(6)); } + +// These tests make some assumptions about local system users +BOOST_FIXTURE_TEST_CASE(usercache, EntCache) +{ + auto root = getEntry(0); + BOOST_REQUIRE(root); + BOOST_CHECK_EQUAL(root->id, 0); + BOOST_CHECK_EQUAL(root->name, "root"); + BOOST_CHECK_EQUAL(root->group, 0); + + auto rootByName = getEntry(root->name); + BOOST_REQUIRE_EQUAL(root, rootByName); +} + +BOOST_FIXTURE_TEST_CASE(groupcache, EntCache) +{ + auto root = getEntry(0); + BOOST_REQUIRE(root); + BOOST_CHECK_EQUAL(root->id, 0); + BOOST_CHECK_EQUAL(root->name, "root"); + BOOST_CHECK(root->hasMember(0)); + + auto rootByName = getEntry(root->name); + BOOST_REQUIRE_EQUAL(root, rootByName); +} -- cgit v1.2.3 From 3a43c8b0f26280b55e15f40122c86ed17222c0c7 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Wed, 16 Sep 2020 00:09:40 +0100 Subject: Concrete entcache types Allows specific constructor for group cache that takes a user cache --- netfs/daemon/daemonService.cpp | 2 +- netfs/fuse/fuseMappersImpl.cpp | 2 +- netfs/lib/defaultMapper.cpp | 2 +- netfs/lib/entCache.h | 16 +++++++++- netfs/lib/entCache.impl.h | 11 ++++--- netfs/unittests/testLib.cpp | 67 ++++++++++++++++++++++++++++++------------ 6 files changed, 72 insertions(+), 28 deletions(-) diff --git a/netfs/daemon/daemonService.cpp b/netfs/daemon/daemonService.cpp index 6ffcf71..38d40c7 100644 --- a/netfs/daemon/daemonService.cpp +++ b/netfs/daemon/daemonService.cpp @@ -5,7 +5,7 @@ #include ServiceServer::ServiceServer(NetFS::Daemon::ConfigurationPtr c) : - userLookup(std::make_shared>()), groupLookup(std::make_shared>()), + userLookup(std::make_shared()), groupLookup(std::make_shared(userLookup)), config(std::move(c)) { } diff --git a/netfs/fuse/fuseMappersImpl.cpp b/netfs/fuse/fuseMappersImpl.cpp index 9a99eca..9e82b74 100644 --- a/netfs/fuse/fuseMappersImpl.cpp +++ b/netfs/fuse/fuseMappersImpl.cpp @@ -3,7 +3,7 @@ namespace NetFS::Client { HideUnknownMapperImpl::HideUnknownMapperImpl() : - HideUnknownMapperImpl(std::make_shared>(), std::make_shared>()) + users(std::make_shared()), groups(std::make_shared(users)) { } diff --git a/netfs/lib/defaultMapper.cpp b/netfs/lib/defaultMapper.cpp index 27b20d3..865cca1 100644 --- a/netfs/lib/defaultMapper.cpp +++ b/netfs/lib/defaultMapper.cpp @@ -4,7 +4,7 @@ namespace NetFS::Mapping { DefaultMapper::DefaultMapper() : - DefaultMapper(std::make_shared>(), std::make_shared>()) + users(std::make_shared()), groups(std::make_shared(users)) { } diff --git a/netfs/lib/entCache.h b/netfs/lib/entCache.h index 7a9a3ef..e394b05 100644 --- a/netfs/lib/entCache.h +++ b/netfs/lib/entCache.h @@ -1,6 +1,7 @@ #ifndef ENTCACHE_H #define ENTCACHE_H +#include "entries.h" #include "entryResolver.h" #include #include @@ -26,7 +27,7 @@ public: }; protected: - void fillCache() const noexcept; + virtual void fillCache() const noexcept = 0; template[[nodiscard]] entry_ptr getEntryInternal(const key_t &) const noexcept; template[[nodiscard]] entry_ptr getEntryNoFill(const key_t &) const noexcept; @@ -36,4 +37,17 @@ protected: mutable time_t fillTime {0}; }; +class UserEntCache : public EntCache { + void fillCache() const noexcept override; +}; + +class GroupEntCache : public EntCache { +public: + GroupEntCache(EntryResolverPtr); + +private: + void fillCache() const noexcept override; + EntryResolverPtr users; +}; + #endif diff --git a/netfs/lib/entCache.impl.h b/netfs/lib/entCache.impl.h index 6523d32..1d7bbc7 100644 --- a/netfs/lib/entCache.impl.h +++ b/netfs/lib/entCache.impl.h @@ -53,9 +53,8 @@ EntCache::getEntryNoFill(const key_t & key) const noexcept const int BUFLEN = 8196; -template<> void -EntCache::fillCache() const noexcept +UserEntCache::fillCache() const noexcept { Lock(lock); setpwent(); @@ -70,9 +69,10 @@ EntCache::fillCache() const noexcept time(&fillTime); } -template<> +GroupEntCache::GroupEntCache(EntryResolverPtr u) : users(std::move(u)) { } + void -EntCache::fillCache() const noexcept +GroupEntCache::fillCache() const noexcept { Lock(lock); setgrent(); @@ -80,11 +80,10 @@ EntCache::fillCache() const noexcept idcache->clear(); struct group grpbuf { }, *grp; - EntCache instance; while (getgrent_r(&grpbuf, buf.data(), buf.size(), &grp) == 0) { auto g = std::make_shared(grp->gr_gid, grp->gr_name); for (auto member = grp->gr_mem; *member; member++) { - if (auto ent = instance.getEntry(*member)) { + if (auto ent = users->getEntry(*member)) { g->members.insert(ent->id); } } diff --git a/netfs/unittests/testLib.cpp b/netfs/unittests/testLib.cpp index 2985c93..d46b072 100644 --- a/netfs/unittests/testLib.cpp +++ b/netfs/unittests/testLib.cpp @@ -1,26 +1,20 @@ #define BOOST_TEST_MODULE TestNetFSLib #include #include +#include #include #include -struct TestEntry { - TestEntry(int i, std::string n) : id(i), name(std::move(n)) { } - - int id; - std::string name; +class TestEntCache : public EntCache { + void + fillCache() const noexcept override + { + Lock(lock); + idcache->insert(std::make_shared(1, "user1", 1)); + idcache->insert(std::make_shared(2, "user2", 1)); + idcache->insert(std::make_shared(3, "user3", 1)); + } }; -using TestEntCache = EntCache; - -template<> -void -EntCache::fillCache() const noexcept -{ - Lock(lock); - idcache->insert(std::make_shared(1, "user1")); - idcache->insert(std::make_shared(2, "user2")); - idcache->insert(std::make_shared(3, "user3")); -} const auto GoodIds = boost::unit_test::data::make({1, 2, 3}); const auto BadIds = boost::unit_test::data::make({0, -1, 10}); @@ -67,7 +61,7 @@ BOOST_AUTO_TEST_CASE(group_membership) } // These tests make some assumptions about local system users -BOOST_FIXTURE_TEST_CASE(usercache, EntCache) +BOOST_FIXTURE_TEST_CASE(usercache, UserEntCache) { auto root = getEntry(0); BOOST_REQUIRE(root); @@ -79,7 +73,11 @@ BOOST_FIXTURE_TEST_CASE(usercache, EntCache) BOOST_REQUIRE_EQUAL(root, rootByName); } -BOOST_FIXTURE_TEST_CASE(groupcache, EntCache) +struct TestGroupEntCache : public GroupEntCache { + TestGroupEntCache() : GroupEntCache(std::make_shared()) { } +}; + +BOOST_FIXTURE_TEST_CASE(groupcache, TestGroupEntCache) { auto root = getEntry(0); BOOST_REQUIRE(root); @@ -90,3 +88,36 @@ BOOST_FIXTURE_TEST_CASE(groupcache, EntCache) auto rootByName = getEntry(root->name); BOOST_REQUIRE_EQUAL(root, rootByName); } + +BOOST_FIXTURE_TEST_SUITE(dm, NetFS::Mapping::DefaultMapper); + +BOOST_AUTO_TEST_CASE(good_maptransport) +{ + auto fs = mapTransport("root", "root"); + BOOST_CHECK_EQUAL(0, fs.uid); + BOOST_CHECK_EQUAL(0, fs.gid); + BOOST_CHECK_EQUAL(0, fs.mask); +} + +BOOST_AUTO_TEST_CASE(good_mapfs) +{ + auto tn = mapFileSystem(0, 0); + BOOST_CHECK_EQUAL("root", tn.username); + BOOST_CHECK_EQUAL("root", tn.groupname); +} + +BOOST_AUTO_TEST_CASE(bad_maptransport) +{ + BOOST_REQUIRE_THROW(mapTransport("root", ""), NetFS::SystemError); + BOOST_REQUIRE_THROW(mapTransport("", "root"), NetFS::SystemError); + BOOST_REQUIRE_THROW(mapTransport("", ""), NetFS::SystemError); +} + +BOOST_AUTO_TEST_CASE(bad_mapfilesystem) +{ + BOOST_REQUIRE_THROW(mapFileSystem(0, -1), NetFS::SystemError); + BOOST_REQUIRE_THROW(mapFileSystem(-1, 0), NetFS::SystemError); + BOOST_REQUIRE_THROW(mapFileSystem(-1, -1), NetFS::SystemError); +} + +BOOST_AUTO_TEST_SUITE_END(); -- cgit v1.2.3 From 98f5f9e905c050f2f934fdcdac8c2bc1899cf5b3 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Wed, 16 Sep 2020 00:44:34 +0100 Subject: Progressive constructors for mappers --- netfs/fuse/fuseMappersImpl.cpp | 6 ++++-- netfs/fuse/fuseMappersImpl.h | 1 + netfs/lib/defaultMapper.cpp | 6 ++++-- netfs/lib/defaultMapper.h | 1 + 4 files changed, 10 insertions(+), 4 deletions(-) diff --git a/netfs/fuse/fuseMappersImpl.cpp b/netfs/fuse/fuseMappersImpl.cpp index 9e82b74..87266b1 100644 --- a/netfs/fuse/fuseMappersImpl.cpp +++ b/netfs/fuse/fuseMappersImpl.cpp @@ -2,8 +2,10 @@ #include namespace NetFS::Client { - HideUnknownMapperImpl::HideUnknownMapperImpl() : - users(std::make_shared()), groups(std::make_shared(users)) + HideUnknownMapperImpl::HideUnknownMapperImpl() : HideUnknownMapperImpl(std::make_shared()) { } + + HideUnknownMapperImpl::HideUnknownMapperImpl(EntryResolverPtr u) : + HideUnknownMapperImpl(std::move(u), std::make_shared(u)) { } diff --git a/netfs/fuse/fuseMappersImpl.h b/netfs/fuse/fuseMappersImpl.h index 4b0677f..b8e87f4 100644 --- a/netfs/fuse/fuseMappersImpl.h +++ b/netfs/fuse/fuseMappersImpl.h @@ -10,6 +10,7 @@ namespace NetFS { class HideUnknownMapperImpl : public HideUnknownMapper { public: HideUnknownMapperImpl(); + HideUnknownMapperImpl(EntryResolverPtr u); HideUnknownMapperImpl(EntryResolverPtr u, EntryResolverPtr g); Mapping::Transport mapFileSystem(int uid, int gid) override; diff --git a/netfs/lib/defaultMapper.cpp b/netfs/lib/defaultMapper.cpp index 865cca1..d20f7ba 100644 --- a/netfs/lib/defaultMapper.cpp +++ b/netfs/lib/defaultMapper.cpp @@ -3,8 +3,10 @@ #include namespace NetFS::Mapping { - DefaultMapper::DefaultMapper() : - users(std::make_shared()), groups(std::make_shared(users)) + DefaultMapper::DefaultMapper() : DefaultMapper(std::make_shared()) { } + + DefaultMapper::DefaultMapper(EntryResolverPtr u) : + DefaultMapper(std::move(u), std::make_shared(u)) { } diff --git a/netfs/lib/defaultMapper.h b/netfs/lib/defaultMapper.h index 214f9ed..5a5c335 100644 --- a/netfs/lib/defaultMapper.h +++ b/netfs/lib/defaultMapper.h @@ -10,6 +10,7 @@ namespace NetFS { class DefaultMapper : public Mapper { public: DefaultMapper(); + DefaultMapper(EntryResolverPtr users); DefaultMapper(EntryResolverPtr users, EntryResolverPtr groups); Transport mapFileSystem(int uid, int gid) override; -- cgit v1.2.3 From a9dad33a0ea08feca098d045b2c4914eda1d5f2a Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Wed, 16 Sep 2020 01:03:27 +0100 Subject: Test the hiding mapper --- netfs/fuse/fuseMappersImpl.cpp | 5 ++++- netfs/fuse/fuseMappersImpl.h | 3 ++- netfs/unittests/testLib.cpp | 34 ++++++++++++++++++++++++++++++++++ 3 files changed, 40 insertions(+), 2 deletions(-) diff --git a/netfs/fuse/fuseMappersImpl.cpp b/netfs/fuse/fuseMappersImpl.cpp index 87266b1..d22f3a4 100644 --- a/netfs/fuse/fuseMappersImpl.cpp +++ b/netfs/fuse/fuseMappersImpl.cpp @@ -2,6 +2,9 @@ #include namespace NetFS::Client { + constexpr int MASK_EVERYTHING = ~0; + static_assert(MASK_EVERYTHING == static_cast(0xFFFFFFFF)); + HideUnknownMapperImpl::HideUnknownMapperImpl() : HideUnknownMapperImpl(std::make_shared()) { } HideUnknownMapperImpl::HideUnknownMapperImpl(EntryResolverPtr u) : @@ -20,7 +23,7 @@ namespace NetFS::Client { auto u = users->getEntry(un); auto g = groups->getEntry(gn); if (!u || !g) { - return {0, 0, 0xFFFFFFF}; + return {0, 0, MASK_EVERYTHING}; } return {static_cast(u->id), static_cast(g->id), 0}; } diff --git a/netfs/fuse/fuseMappersImpl.h b/netfs/fuse/fuseMappersImpl.h index b8e87f4..a0b1eb3 100644 --- a/netfs/fuse/fuseMappersImpl.h +++ b/netfs/fuse/fuseMappersImpl.h @@ -4,10 +4,11 @@ #include "entries.h" #include "entryResolver.h" #include +#include namespace NetFS { namespace Client { - class HideUnknownMapperImpl : public HideUnknownMapper { + class DLL_PUBLIC HideUnknownMapperImpl : public HideUnknownMapper { public: HideUnknownMapperImpl(); HideUnknownMapperImpl(EntryResolverPtr u); diff --git a/netfs/unittests/testLib.cpp b/netfs/unittests/testLib.cpp index d46b072..29167c4 100644 --- a/netfs/unittests/testLib.cpp +++ b/netfs/unittests/testLib.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include class TestEntCache : public EntCache { @@ -121,3 +122,36 @@ BOOST_AUTO_TEST_CASE(bad_mapfilesystem) } BOOST_AUTO_TEST_SUITE_END(); + +BOOST_FIXTURE_TEST_SUITE(hm, NetFS::Client::HideUnknownMapperImpl); + +BOOST_AUTO_TEST_CASE(good_maptransport) +{ + auto fs = mapTransport("root", "root"); + BOOST_CHECK_EQUAL(0, fs.uid); + BOOST_CHECK_EQUAL(0, fs.gid); + BOOST_CHECK_EQUAL(0, fs.mask); +} + +BOOST_AUTO_TEST_CASE(good_mapfs) +{ + auto tn = mapFileSystem(0, 0); + BOOST_CHECK_EQUAL("root", tn.username); + BOOST_CHECK_EQUAL("root", tn.groupname); +} + +BOOST_AUTO_TEST_CASE(bad_maptransport) +{ + BOOST_CHECK_EQUAL(mapTransport("root", "").mask, ~0); + BOOST_CHECK_EQUAL(mapTransport("", "root").mask, ~0); + BOOST_CHECK_EQUAL(mapTransport("", "").mask, ~0); +} + +BOOST_AUTO_TEST_CASE(bad_mapfilesystem) +{ + BOOST_REQUIRE_THROW(mapFileSystem(0, -1), NetFS::SystemError); + BOOST_REQUIRE_THROW(mapFileSystem(-1, 0), NetFS::SystemError); + BOOST_REQUIRE_THROW(mapFileSystem(-1, -1), NetFS::SystemError); +} + +BOOST_AUTO_TEST_SUITE_END(); -- cgit v1.2.3 From 777724a09ba4000ec077154b4f13c77d8c875d63 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Sun, 20 Sep 2020 15:53:29 +0100 Subject: Add the MaskUnknown mapper --- netfs/fuse/fuseMappers.ice | 7 +++++++ netfs/fuse/fuseMappersImpl.cpp | 42 ++++++++++++++++++++++++++++++++++++++++++ netfs/fuse/fuseMappersImpl.h | 14 ++++++++++++++ netfs/unittests/testLib.cpp | 42 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 105 insertions(+) diff --git a/netfs/fuse/fuseMappers.ice b/netfs/fuse/fuseMappers.ice index 6945eec..582aa16 100644 --- a/netfs/fuse/fuseMappers.ice +++ b/netfs/fuse/fuseMappers.ice @@ -7,6 +7,13 @@ module NetFS { local class HideUnknownMapper extends Mapping::Mapper { }; + ["slicer:implementation:NetFS.Client.MaskUnknownMapperImpl"] + local class MaskUnknownMapper extends Mapping::Mapper { + string UnknownUser = "nobody"; + string UnknownGroup = "nogroup"; + int MaskUser = 0700; + int MaskGroup = 0070; + }; }; }; diff --git a/netfs/fuse/fuseMappersImpl.cpp b/netfs/fuse/fuseMappersImpl.cpp index d22f3a4..4aa2789 100644 --- a/netfs/fuse/fuseMappersImpl.cpp +++ b/netfs/fuse/fuseMappersImpl.cpp @@ -38,4 +38,46 @@ namespace NetFS::Client { } return {u->name, g->name, 0}; } + MaskUnknownMapperImpl::MaskUnknownMapperImpl() : MaskUnknownMapperImpl(std::make_shared()) { } + + MaskUnknownMapperImpl::MaskUnknownMapperImpl(EntryResolverPtr u) : + MaskUnknownMapperImpl(std::move(u), std::make_shared(u)) + { + } + + MaskUnknownMapperImpl::MaskUnknownMapperImpl(EntryResolverPtr u, EntryResolverPtr g) : + users(std::move(u)), groups(std::move(g)) + { + } + + 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, MaskUser); + auto g = apply(groups, gn, UnknownGroup, MaskGroup); + return {static_cast(u->id), static_cast(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}; + } } diff --git a/netfs/fuse/fuseMappersImpl.h b/netfs/fuse/fuseMappersImpl.h index a0b1eb3..41d78b8 100644 --- a/netfs/fuse/fuseMappersImpl.h +++ b/netfs/fuse/fuseMappersImpl.h @@ -21,6 +21,20 @@ namespace NetFS { EntryResolverPtr users; EntryResolverPtr groups; }; + + class DLL_PUBLIC MaskUnknownMapperImpl : public MaskUnknownMapper { + public: + MaskUnknownMapperImpl(); + MaskUnknownMapperImpl(EntryResolverPtr u); + MaskUnknownMapperImpl(EntryResolverPtr u, EntryResolverPtr g); + + Mapping::Transport mapFileSystem(int uid, int gid) override; + Mapping::FileSystem mapTransport(const std::string & un, const std::string & gn) override; + + protected: + EntryResolverPtr users; + EntryResolverPtr groups; + }; } } diff --git a/netfs/unittests/testLib.cpp b/netfs/unittests/testLib.cpp index 29167c4..c99f582 100644 --- a/netfs/unittests/testLib.cpp +++ b/netfs/unittests/testLib.cpp @@ -155,3 +155,45 @@ BOOST_AUTO_TEST_CASE(bad_mapfilesystem) } BOOST_AUTO_TEST_SUITE_END(); + +BOOST_FIXTURE_TEST_SUITE(mm, NetFS::Client::MaskUnknownMapperImpl); + +BOOST_AUTO_TEST_CASE(good_maptransport) +{ + auto fs = mapTransport("root", "root"); + BOOST_CHECK_EQUAL(0, fs.uid); + BOOST_CHECK_EQUAL(0, fs.gid); + BOOST_CHECK_EQUAL(0, fs.mask); +} + +BOOST_AUTO_TEST_CASE(good_mapfs) +{ + auto tn = mapFileSystem(0, 0); + BOOST_CHECK_EQUAL("root", tn.username); + BOOST_CHECK_EQUAL("root", tn.groupname); +} + +BOOST_AUTO_TEST_CASE(bad_maptransport) +{ + BOOST_CHECK_EQUAL(mapTransport("root", "").mask, 0070); + BOOST_CHECK_EQUAL(mapTransport("", "root").mask, 0700); + BOOST_CHECK_EQUAL(mapTransport("", "").mask, 0770); +} + +BOOST_AUTO_TEST_CASE(bad_maptransport_badfallback) +{ + UnknownUser = "not existing"; + UnknownGroup = "not existing"; + BOOST_REQUIRE_THROW(mapTransport("root", ""), NetFS::SystemError); + BOOST_REQUIRE_THROW(mapTransport("", "root"), NetFS::SystemError); + BOOST_REQUIRE_THROW(mapTransport("", ""), NetFS::SystemError); +} + +BOOST_AUTO_TEST_CASE(bad_mapfilesystem) +{ + BOOST_REQUIRE_THROW(mapFileSystem(0, -1), NetFS::SystemError); + BOOST_REQUIRE_THROW(mapFileSystem(-1, 0), NetFS::SystemError); + BOOST_REQUIRE_THROW(mapFileSystem(-1, -1), NetFS::SystemError); +} + +BOOST_AUTO_TEST_SUITE_END(); -- cgit v1.2.3 From a615da850d89ecd785a6a43e07527932637f8a2f Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Sun, 20 Sep 2020 16:10:50 +0100 Subject: Common base for mappers --- netfs/fuse/fuseMappersImpl.cpp | 23 ----------------------- netfs/fuse/fuseMappersImpl.h | 21 +++++---------------- netfs/lib/baseMapper.cpp | 13 +++++++++++++ netfs/lib/baseMapper.h | 23 +++++++++++++++++++++++ netfs/lib/defaultMapper.cpp | 13 ------------- netfs/lib/defaultMapper.h | 11 +++-------- 6 files changed, 44 insertions(+), 60 deletions(-) create mode 100644 netfs/lib/baseMapper.cpp create mode 100644 netfs/lib/baseMapper.h diff --git a/netfs/fuse/fuseMappersImpl.cpp b/netfs/fuse/fuseMappersImpl.cpp index 4aa2789..5bde752 100644 --- a/netfs/fuse/fuseMappersImpl.cpp +++ b/netfs/fuse/fuseMappersImpl.cpp @@ -5,18 +5,6 @@ namespace NetFS::Client { constexpr int MASK_EVERYTHING = ~0; static_assert(MASK_EVERYTHING == static_cast(0xFFFFFFFF)); - HideUnknownMapperImpl::HideUnknownMapperImpl() : HideUnknownMapperImpl(std::make_shared()) { } - - HideUnknownMapperImpl::HideUnknownMapperImpl(EntryResolverPtr u) : - HideUnknownMapperImpl(std::move(u), std::make_shared(u)) - { - } - - HideUnknownMapperImpl::HideUnknownMapperImpl(EntryResolverPtr u, EntryResolverPtr g) : - users(std::move(u)), groups(std::move(g)) - { - } - Mapping::FileSystem HideUnknownMapperImpl::mapTransport(const std::string & un, const std::string & gn) { @@ -38,17 +26,6 @@ namespace NetFS::Client { } return {u->name, g->name, 0}; } - MaskUnknownMapperImpl::MaskUnknownMapperImpl() : MaskUnknownMapperImpl(std::make_shared()) { } - - MaskUnknownMapperImpl::MaskUnknownMapperImpl(EntryResolverPtr u) : - MaskUnknownMapperImpl(std::move(u), std::make_shared(u)) - { - } - - MaskUnknownMapperImpl::MaskUnknownMapperImpl(EntryResolverPtr u, EntryResolverPtr g) : - users(std::move(u)), groups(std::move(g)) - { - } Mapping::FileSystem MaskUnknownMapperImpl::mapTransport(const std::string & un, const std::string & gn) diff --git a/netfs/fuse/fuseMappersImpl.h b/netfs/fuse/fuseMappersImpl.h index 41d78b8..2bcf579 100644 --- a/netfs/fuse/fuseMappersImpl.h +++ b/netfs/fuse/fuseMappersImpl.h @@ -1,6 +1,7 @@ #ifndef NETFS_MAPPING_CLIENTIMPL_H #define NETFS_MAPPING_CLIENTIMPL_H +#include "baseMapper.h" #include "entries.h" #include "entryResolver.h" #include @@ -8,32 +9,20 @@ namespace NetFS { namespace Client { - class DLL_PUBLIC HideUnknownMapperImpl : public HideUnknownMapper { + class DLL_PUBLIC HideUnknownMapperImpl : public HideUnknownMapper, Mapping::BaseMapper { public: - HideUnknownMapperImpl(); - HideUnknownMapperImpl(EntryResolverPtr u); - HideUnknownMapperImpl(EntryResolverPtr u, EntryResolverPtr g); + using BaseMapper::BaseMapper; Mapping::Transport mapFileSystem(int uid, int gid) override; Mapping::FileSystem mapTransport(const std::string & un, const std::string & gn) override; - - protected: - EntryResolverPtr users; - EntryResolverPtr groups; }; - class DLL_PUBLIC MaskUnknownMapperImpl : public MaskUnknownMapper { + class DLL_PUBLIC MaskUnknownMapperImpl : public MaskUnknownMapper, Mapping::BaseMapper { public: - MaskUnknownMapperImpl(); - MaskUnknownMapperImpl(EntryResolverPtr u); - MaskUnknownMapperImpl(EntryResolverPtr u, EntryResolverPtr g); + using BaseMapper::BaseMapper; Mapping::Transport mapFileSystem(int uid, int gid) override; Mapping::FileSystem mapTransport(const std::string & un, const std::string & gn) override; - - protected: - EntryResolverPtr users; - EntryResolverPtr groups; }; } } diff --git a/netfs/lib/baseMapper.cpp b/netfs/lib/baseMapper.cpp new file mode 100644 index 0000000..c3518e4 --- /dev/null +++ b/netfs/lib/baseMapper.cpp @@ -0,0 +1,13 @@ +#include "baseMapper.h" +#include "entCache.h" + +namespace NetFS::Mapping { + BaseMapper::BaseMapper() : BaseMapper(std::make_shared()) { } + + BaseMapper::BaseMapper(EntryResolverPtr u) : BaseMapper(std::move(u), std::make_shared(u)) { } + + BaseMapper::BaseMapper(EntryResolverPtr u, EntryResolverPtr g) : + users(std::move(u)), groups(std::move(g)) + { + } +} diff --git a/netfs/lib/baseMapper.h b/netfs/lib/baseMapper.h new file mode 100644 index 0000000..c3bd46e --- /dev/null +++ b/netfs/lib/baseMapper.h @@ -0,0 +1,23 @@ +#ifndef NETFS_MAPPING_BASEIMPL_H +#define NETFS_MAPPING_BASEIMPL_H + +#include "entries.h" +#include "entryResolver.h" +#include + +namespace NetFS { + namespace Mapping { + class BaseMapper { + public: + BaseMapper(); + BaseMapper(EntryResolverPtr users); + BaseMapper(EntryResolverPtr users, EntryResolverPtr groups); + + protected: + EntryResolverPtr users; + EntryResolverPtr groups; + }; + } +} + +#endif diff --git a/netfs/lib/defaultMapper.cpp b/netfs/lib/defaultMapper.cpp index d20f7ba..c57f340 100644 --- a/netfs/lib/defaultMapper.cpp +++ b/netfs/lib/defaultMapper.cpp @@ -1,20 +1,7 @@ #include "defaultMapper.h" -#include "entCache.h" #include namespace NetFS::Mapping { - DefaultMapper::DefaultMapper() : DefaultMapper(std::make_shared()) { } - - DefaultMapper::DefaultMapper(EntryResolverPtr u) : - DefaultMapper(std::move(u), std::make_shared(u)) - { - } - - DefaultMapper::DefaultMapper(EntryResolverPtr u, EntryResolverPtr g) : - users(std::move(u)), groups(std::move(g)) - { - } - FileSystem DefaultMapper::mapTransport(const std::string & un, const std::string & gn) { diff --git a/netfs/lib/defaultMapper.h b/netfs/lib/defaultMapper.h index 5a5c335..9f063a8 100644 --- a/netfs/lib/defaultMapper.h +++ b/netfs/lib/defaultMapper.h @@ -1,24 +1,19 @@ #ifndef NETFS_MAPPING_DEFAULTIMPL_H #define NETFS_MAPPING_DEFAULTIMPL_H +#include "baseMapper.h" #include "entries.h" #include "entryResolver.h" #include namespace NetFS { namespace Mapping { - class DefaultMapper : public Mapper { + class DefaultMapper : public Mapper, BaseMapper { public: - DefaultMapper(); - DefaultMapper(EntryResolverPtr users); - DefaultMapper(EntryResolverPtr users, EntryResolverPtr groups); + using BaseMapper::BaseMapper; Transport mapFileSystem(int uid, int gid) override; FileSystem mapTransport(const std::string & un, const std::string & gn) override; - - protected: - EntryResolverPtr users; - EntryResolverPtr groups; }; } } -- cgit v1.2.3 From 0721b2cb0e63c6968c8bda00df1ff0018cad6e4f Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Sun, 20 Sep 2020 16:11:09 +0100 Subject: Move not template functions out of impl.h --- netfs/lib/entCache.cpp | 42 ++++++++++++++++++++++++++++++++++++++++++ netfs/lib/entCache.impl.h | 42 ------------------------------------------ 2 files changed, 42 insertions(+), 42 deletions(-) diff --git a/netfs/lib/entCache.cpp b/netfs/lib/entCache.cpp index e1a20a5..6f6d6eb 100644 --- a/netfs/lib/entCache.cpp +++ b/netfs/lib/entCache.cpp @@ -3,3 +3,45 @@ template class EntCache; template class EntCache; + +const int BUFLEN = 8196; + +void +UserEntCache::fillCache() const noexcept +{ + Lock(lock); + setpwent(); + idcache->clear(); + std::array buf {}; + struct passwd pwbuf { + }, *pwp; + while (getpwent_r(&pwbuf, buf.data(), buf.size(), &pwp) == 0) { + idcache->insert(std::make_shared(pwp->pw_uid, pwp->pw_name, pwp->pw_gid)); + } + endpwent(); + time(&fillTime); +} + +GroupEntCache::GroupEntCache(EntryResolverPtr u) : users(std::move(u)) { } + +void +GroupEntCache::fillCache() const noexcept +{ + Lock(lock); + setgrent(); + std::array buf {}; + idcache->clear(); + struct group grpbuf { + }, *grp; + while (getgrent_r(&grpbuf, buf.data(), buf.size(), &grp) == 0) { + auto g = std::make_shared(grp->gr_gid, grp->gr_name); + for (auto member = grp->gr_mem; *member; member++) { + if (auto ent = users->getEntry(*member)) { + g->members.insert(ent->id); + } + } + idcache->insert(std::move(g)); + } + endgrent(); + time(&fillTime); +} diff --git a/netfs/lib/entCache.impl.h b/netfs/lib/entCache.impl.h index 1d7bbc7..5e6289e 100644 --- a/netfs/lib/entCache.impl.h +++ b/netfs/lib/entCache.impl.h @@ -51,46 +51,4 @@ EntCache::getEntryNoFill(const key_t & key) const noexcept return nullptr; } -const int BUFLEN = 8196; - -void -UserEntCache::fillCache() const noexcept -{ - Lock(lock); - setpwent(); - idcache->clear(); - std::array buf {}; - struct passwd pwbuf { - }, *pwp; - while (getpwent_r(&pwbuf, buf.data(), buf.size(), &pwp) == 0) { - idcache->insert(std::make_shared(pwp->pw_uid, pwp->pw_name, pwp->pw_gid)); - } - endpwent(); - time(&fillTime); -} - -GroupEntCache::GroupEntCache(EntryResolverPtr u) : users(std::move(u)) { } - -void -GroupEntCache::fillCache() const noexcept -{ - Lock(lock); - setgrent(); - std::array buf {}; - idcache->clear(); - struct group grpbuf { - }, *grp; - while (getgrent_r(&grpbuf, buf.data(), buf.size(), &grp) == 0) { - auto g = std::make_shared(grp->gr_gid, grp->gr_name); - for (auto member = grp->gr_mem; *member; member++) { - if (auto ent = users->getEntry(*member)) { - g->members.insert(ent->id); - } - } - idcache->insert(std::move(g)); - } - endgrent(); - time(&fillTime); -} - #endif -- cgit v1.2.3 From 015916c14997b355d63a7189380fe89ae9bbe3bd Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Sun, 20 Sep 2020 20:01:05 +0100 Subject: Support for configuring new mappers in fuse client --- netfs/fuse/fuseApp.cpp | 16 +++++++++--- netfs/fuse/fuseConfig.ice | 3 ++- netfs/fuse/fuseMappers.ice | 12 ++++++--- netfs/fuse/fuseMappersImpl.cpp | 18 ++++++++++++-- netfs/fuse/fuseMappersImpl.h | 3 +++ netfs/ice/mapper.ice | 1 + netfs/unittests/Jamfile.jam | 2 ++ netfs/unittests/defaultFuseHide.xml | 15 ++++++++++++ netfs/unittests/defaultFuseMask.xml | 20 +++++++++++++++ netfs/unittests/testFuse.cpp | 49 +++++++++++++++++++++++++++++++++++++ 10 files changed, 128 insertions(+), 11 deletions(-) create mode 100644 netfs/unittests/defaultFuseHide.xml create mode 100644 netfs/unittests/defaultFuseMask.xml diff --git a/netfs/fuse/fuseApp.cpp b/netfs/fuse/fuseApp.cpp index ff1585a..04602aa 100644 --- a/netfs/fuse/fuseApp.cpp +++ b/netfs/fuse/fuseApp.cpp @@ -79,11 +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(); + if (!fcr->Mapper) { + fcr->Mapper = std::make_shared(); } BOOST_ASSERT(fcr); - converter.mapper = fcr->mapper; + converter.mapper = fcr->Mapper; return this; } @@ -118,10 +118,18 @@ NetFS::FuseApp::configureFromUri(const std::string & uriString) } }; set("async", r->Async); - setWith("mapper", r->mapper, [](auto && m) -> NetFS::Mapping::MapperPtr { + setWith("mapper", r->Mapper, [&set, &setWith](auto && m) -> NetFS::Mapping::MapperPtr { if (m == "hide") { return std::make_shared(); } + else if (m == "mask") { + auto mi = std::make_shared(); + 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; diff --git a/netfs/fuse/fuseConfig.ice b/netfs/fuse/fuseConfig.ice index 2d2bf9f..ea489ac 100644 --- a/netfs/fuse/fuseConfig.ice +++ b/netfs/fuse/fuseConfig.ice @@ -22,7 +22,8 @@ module NetFS { ["slicer:name:async"] bool Async = false; - Mapping::Mapper mapper; + ["slicer:name:mapper"] + Mapping::Mapper Mapper; }; ["slicer:key:name","slicer:value:resource","slicer:item:resource"] diff --git a/netfs/fuse/fuseMappers.ice b/netfs/fuse/fuseMappers.ice index 582aa16..0eb5ea5 100644 --- a/netfs/fuse/fuseMappers.ice +++ b/netfs/fuse/fuseMappers.ice @@ -3,16 +3,20 @@ ["slicer:include:fuseMappersImpl.h"] module NetFS { module Client { - ["slicer:implementation:NetFS.Client.HideUnknownMapperImpl"] + ["slicer:implementation:NetFS.Client.HideUnknownMapperImpl","slicer:typename:hide"] local class HideUnknownMapper extends Mapping::Mapper { }; - ["slicer:implementation:NetFS.Client.MaskUnknownMapperImpl"] + ["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"; - int MaskUser = 0700; - int MaskGroup = 0070; + ["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 index 5bde752..c7fef9e 100644 --- a/netfs/fuse/fuseMappersImpl.cpp +++ b/netfs/fuse/fuseMappersImpl.cpp @@ -42,8 +42,8 @@ namespace NetFS::Client { } return e; }; - auto u = apply(users, un, UnknownUser, MaskUser); - auto g = apply(groups, gn, UnknownGroup, MaskGroup); + auto u = apply(users, un, UnknownUser, UserMask); + auto g = apply(groups, gn, UnknownGroup, GroupMask); return {static_cast(u->id), static_cast(g->id), mask}; } @@ -57,4 +57,18 @@ namespace NetFS::Client { } 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 index 2bcf579..fd9e2aa 100644 --- a/netfs/fuse/fuseMappersImpl.h +++ b/netfs/fuse/fuseMappersImpl.h @@ -9,6 +9,9 @@ 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; diff --git a/netfs/ice/mapper.ice b/netfs/ice/mapper.ice index d2f31e8..505b53a 100644 --- a/netfs/ice/mapper.ice +++ b/netfs/ice/mapper.ice @@ -19,6 +19,7 @@ module NetFS { int mask; }; + ["slicer:typename:default","slicer:typeid:type"] local class Mapper { Transport mapFileSystem(int uid, int gid) throws SystemError; FileSystem mapTransport(string un, string gn) throws SystemError; diff --git a/netfs/unittests/Jamfile.jam b/netfs/unittests/Jamfile.jam index 18abadd..8d9efc3 100644 --- a/netfs/unittests/Jamfile.jam +++ b/netfs/unittests/Jamfile.jam @@ -77,6 +77,8 @@ run testLib.cpp run testFuse.cpp : -- : defaultDaemon.xml + defaultFuseHide.xml + defaultFuseMask.xml : BOOST_TEST_DYN_LINK boost_utf diff --git a/netfs/unittests/defaultFuseHide.xml b/netfs/unittests/defaultFuseHide.xml new file mode 100644 index 0000000..098a597 --- /dev/null +++ b/netfs/unittests/defaultFuseHide.xml @@ -0,0 +1,15 @@ + + + + + testvol + + testvol + + overridden + + + + + + diff --git a/netfs/unittests/defaultFuseMask.xml b/netfs/unittests/defaultFuseMask.xml new file mode 100644 index 0000000..5d45a53 --- /dev/null +++ b/netfs/unittests/defaultFuseMask.xml @@ -0,0 +1,20 @@ + + + + + testvol + + testvol + + overridden + + + uu + ug + 0100 + 0010 + + + + + diff --git a/netfs/unittests/testFuse.cpp b/netfs/unittests/testFuse.cpp index ded7077..0ad9335 100644 --- a/netfs/unittests/testFuse.cpp +++ b/netfs/unittests/testFuse.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include #include @@ -152,3 +153,51 @@ BOOST_AUTO_TEST_CASE(url_params_2) auto fcs = NetFS::FuseApp::configureFromUri("tcp://localhost/foo?0&async=0"); BOOST_CHECK_EQUAL(fcs->Async, false); } + +BOOST_AUTO_TEST_CASE(url_params_hide) +{ + auto fcs = NetFS::FuseApp::configureFromUri("tcp://localhost/foo?mapper=hide"); + BOOST_REQUIRE(fcs->Mapper); + BOOST_REQUIRE(std::dynamic_pointer_cast(fcs->Mapper)); +} + +BOOST_AUTO_TEST_CASE(url_params_mask_default) +{ + auto fcs = NetFS::FuseApp::configureFromUri("tcp://localhost/foo?mapper=mask"); + BOOST_REQUIRE(fcs->Mapper); + auto mapper = std::dynamic_pointer_cast(fcs->Mapper); + BOOST_REQUIRE(mapper); +} + +BOOST_AUTO_TEST_CASE(url_params_mask_nondefault) +{ + auto fcs = NetFS::FuseApp::configureFromUri( + "tcp://localhost/" + "foo?mapper=mask&mapper.unknownuser=uu&mapper.unknowngroup=ug&mapper.usermask=0100&mapper.groupmask=0010"); + BOOST_REQUIRE(fcs->Mapper); + auto mapper = std::dynamic_pointer_cast(fcs->Mapper); + BOOST_REQUIRE(mapper); + BOOST_CHECK_EQUAL(mapper->UnknownUser, "uu"); + BOOST_CHECK_EQUAL(mapper->UnknownGroup, "ug"); + BOOST_CHECK_EQUAL(mapper->UserMask, 0100); + BOOST_CHECK_EQUAL(mapper->GroupMask, 0010); +} + +BOOST_AUTO_TEST_CASE(config_file_hide) +{ + auto fcs = NetFS::FuseApp::configureFromFile(rootDir / "defaultFuseHide.xml", "testvol"); + BOOST_REQUIRE(fcs->Mapper); + BOOST_REQUIRE(std::dynamic_pointer_cast(fcs->Mapper)); +} + +BOOST_AUTO_TEST_CASE(config_file_mask) +{ + auto fcs = NetFS::FuseApp::configureFromFile(rootDir / "defaultFuseMask.xml", "testvol"); + BOOST_REQUIRE(fcs->Mapper); + auto mapper = std::dynamic_pointer_cast(fcs->Mapper); + BOOST_REQUIRE(mapper); + BOOST_CHECK_EQUAL(mapper->UnknownUser, "uu"); + BOOST_CHECK_EQUAL(mapper->UnknownGroup, "ug"); + BOOST_CHECK_EQUAL(mapper->UserMask, 0100); + BOOST_CHECK_EQUAL(mapper->GroupMask, 0010); +} -- cgit v1.2.3 From 7e940c94ac0598ada54c53149b17f3c385b89794 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Mon, 20 Sep 2021 11:39:39 +0100 Subject: Bump to C++20, required by new Slicer --- Jamroot.jam | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Jamroot.jam b/Jamroot.jam index af15ca5..61c7d8b 100644 --- a/Jamroot.jam +++ b/Jamroot.jam @@ -11,7 +11,7 @@ variant coverage : debug ; project : requirements ICE_CPP11_MAPPING - 17 + 20 hidden "-Wl,-z,defs,--warn-once,--gc-sections" release:on -- cgit v1.2.3