From 84272fde2e3851884efe2907ea1a5811beb86ca5 Mon Sep 17 00:00:00 2001 From: Siyuan Ren Date: Sun, 28 Jul 2024 12:27:29 +0800 Subject: [PATCH] Allow owner override in full format --- sources/commands.cpp | 33 +++++++++++++++++++++++++++++- sources/full_format.cpp | 14 +++++++++++++ sources/full_format.h | 10 ++++++++- sources/fuse_high_level_ops_base.h | 7 +++++++ test/test_full_format.cpp | 1 + 5 files changed, 63 insertions(+), 2 deletions(-) diff --git a/sources/commands.cpp b/sources/commands.cpp index 0220812e..94e8edeb 100644 --- a/sources/commands.cpp +++ b/sources/commands.cpp @@ -595,7 +595,24 @@ class MountCommand : public CommandBase "When enabled, securefs does not encrypt or decrypt file " "names. Use it at your own risk. No effect on full format.", cmdline()}; - + TCLAP::ValueArg uid_override{ + "", + "uid-override", + "Forces every file to be owned by this uid in the virtual filesystem. If the value is -1, " + "then no override is in place", + false, + -1, + "int", + cmdline()}; + TCLAP::ValueArg gid_override{ + "", + "gid-override", + "Forces every file to be owned by this gid in the virtual filesystem. If the value is -1, " + "then no override is in place", + false, + -1, + "int", + cmdline()}; DecryptedSecurefsParams fsparams{}; private: @@ -718,6 +735,20 @@ class MountCommand : public CommandBase [](const MountCommand& cmd) { return cmd.fsparams.size_params().iv_size(); }) .registerProvider(const MountCommand&)>( [](const MountCommand& cmd) { return cmd.fsparams.size_params().block_size(); }) + .registerProvider( + [](const MountCommand& cmd) + { + OwnerOverride result{}; + if (cmd.uid_override.getValue() != -1) + { + result.uid_override = cmd.uid_override.getValue(); + } + if (cmd.gid_override.getValue() != -1) + { + result.gid_override = cmd.gid_override.getValue(); + } + return result; + }) .registerProvider(const MountCommand&)>( [](const MountCommand& cmd) { return from_byte_string(cmd.fsparams.full_format_params().master_key()); }) diff --git a/sources/full_format.cpp b/sources/full_format.cpp index 56f190c8..abb0cd9d 100644 --- a/sources/full_format.cpp +++ b/sources/full_format.cpp @@ -44,6 +44,7 @@ int FuseHighLevelOps::vgetattr(const char* path, fuse_stat* st, const fuse_conte } FileLockGuard lg(**opened); (**opened).stat(st); + postprocess_stat(st); return 0; }; int FuseHighLevelOps::vfgetattr(const char* path, @@ -54,6 +55,7 @@ int FuseHighLevelOps::vfgetattr(const char* path, auto fp = get_file(info); FileLockGuard lg(*fp); fp->stat(st); + postprocess_stat(st); return 0; }; int FuseHighLevelOps::vopendir(const char* path, fuse_file_info* info, const fuse_context* ctx) @@ -565,4 +567,16 @@ std::optional FuseHighLevelOps::open_all(absl::string_view path) return holder; } +void FuseHighLevelOps::postprocess_stat(fuse_stat* st) +{ + if (owner_override_.uid_override.has_value()) + { + st->st_uid = *owner_override_.uid_override; + } + if (owner_override_.gid_override.has_value()) + { + st->st_gid = *owner_override_.gid_override; + } +} + } // namespace securefs::full_format diff --git a/sources/full_format.h b/sources/full_format.h index 6d4b3f9e..3f3cf5c0 100644 --- a/sources/full_format.h +++ b/sources/full_format.h @@ -62,8 +62,13 @@ class FuseHighLevelOps : public ::securefs::FuseHighLevelOpsBase INJECT(FuseHighLevelOps(OSService& root, FileTable& ft, RepoLocker& locker, + const OwnerOverride& owner_override, ANNOTATED(tCaseInsensitive, bool) case_insensitive)) - : root_(root), ft_(ft), locker_(locker), case_insensitive_(case_insensitive) + : root_(root) + , ft_(ft) + , locker_(locker) + , owner_override_(owner_override) + , case_insensitive_(case_insensitive) { } @@ -144,6 +149,7 @@ class FuseHighLevelOps : public ::securefs::FuseHighLevelOpsBase OSService& root_; FileTable& ft_; [[maybe_unused]] RepoLocker& locker_; // We only needs this to construct and destruct. + OwnerOverride owner_override_; bool case_insensitive_; private: @@ -166,5 +172,7 @@ class FuseHighLevelOps : public ::securefs::FuseHighLevelOpsBase { info->fh = reinterpret_cast(fb); } + + void postprocess_stat(fuse_stat* st); }; } // namespace securefs::full_format diff --git a/sources/fuse_high_level_ops_base.h b/sources/fuse_high_level_ops_base.h index 8b0f3458..c79ab588 100644 --- a/sources/fuse_high_level_ops_base.h +++ b/sources/fuse_high_level_ops_base.h @@ -3,8 +3,15 @@ #include "object.h" #include "platform.h" // IWYU pragma: keep +#include + namespace securefs { +struct OwnerOverride +{ + std::optional uid_override, gid_override; +}; + class FuseHighLevelOpsBase : public Object { public: diff --git a/test/test_full_format.cpp b/test/test_full_format.cpp index 08190c78..d9f3099d 100644 --- a/test/test_full_format.cpp +++ b/test/test_full_format.cpp @@ -40,6 +40,7 @@ namespace return CaseInsensitive ? Directory::DirNameComparison{&case_insensitive_compare} : Directory::DirNameComparison{&binary_compare}; }) + .registerProvider([]() { return OwnerOverride{}; }) .bindInstance(*os); } TEST_CASE("Full format test (case sensitive)")