summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--netfs/fuse/fuseMappers.ice7
-rw-r--r--netfs/fuse/fuseMappersImpl.cpp42
-rw-r--r--netfs/fuse/fuseMappersImpl.h14
-rw-r--r--netfs/unittests/testLib.cpp42
4 files changed, 105 insertions, 0 deletions
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<UserEntCache>()) { }
+
+ MaskUnknownMapperImpl::MaskUnknownMapperImpl(EntryResolverPtr<User> u) :
+ MaskUnknownMapperImpl(std::move(u), std::make_shared<GroupEntCache>(u))
+ {
+ }
+
+ MaskUnknownMapperImpl::MaskUnknownMapperImpl(EntryResolverPtr<User> u, EntryResolverPtr<Group> 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<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};
+ }
}
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<User> users;
EntryResolverPtr<Group> groups;
};
+
+ class DLL_PUBLIC MaskUnknownMapperImpl : public MaskUnknownMapper {
+ public:
+ MaskUnknownMapperImpl();
+ MaskUnknownMapperImpl(EntryResolverPtr<User> u);
+ MaskUnknownMapperImpl(EntryResolverPtr<User> u, EntryResolverPtr<Group> g);
+
+ Mapping::Transport mapFileSystem(int uid, int gid) override;
+ Mapping::FileSystem mapTransport(const std::string & un, const std::string & gn) override;
+
+ protected:
+ EntryResolverPtr<User> users;
+ EntryResolverPtr<Group> 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();