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