summaryrefslogtreecommitdiff
path: root/netfs/fuse
diff options
context:
space:
mode:
authorDan Goodliffe <dan@randomdan.homeip.net>2021-12-15 00:20:23 +0000
committerDan Goodliffe <dan@randomdan.homeip.net>2021-12-15 00:20:23 +0000
commita38270df3ddad2ac60524a40eb986ab37e473c04 (patch)
tree2b0ff976a616fb970e62b93b3ffb52517efc1343 /netfs/fuse
parentAdd missing include (diff)
parentBump to C++20, required by new Slicer (diff)
downloadnetfs-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.jam28
-rw-r--r--netfs/fuse/fuseApp.cpp36
-rw-r--r--netfs/fuse/fuseApp.h2
-rw-r--r--netfs/fuse/fuseApp.impl.h3
-rw-r--r--netfs/fuse/fuseConfig.ice4
-rw-r--r--netfs/fuse/fuseDirs.cpp11
-rw-r--r--netfs/fuse/fuseFiles.cpp2
-rw-r--r--netfs/fuse/fuseMappers.ice23
-rw-r--r--netfs/fuse/fuseMappersImpl.cpp74
-rw-r--r--netfs/fuse/fuseMappersImpl.h33
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