diff --git a/Makefile b/Makefile index 3686eb6f..a600e27a 100644 --- a/Makefile +++ b/Makefile @@ -65,7 +65,6 @@ OPT_FLAGS := -O0 \ $(SANITIZE) \ -fstack-protector-strong \ -Wextra \ - -Werror \ -Wno-unused-parameter \ -DDEBUG endif diff --git a/libfuse/lib/fuse_lowlevel.cpp b/libfuse/lib/fuse_lowlevel.cpp index bf580195..ad0df588 100644 --- a/libfuse/lib/fuse_lowlevel.cpp +++ b/libfuse/lib/fuse_lowlevel.cpp @@ -1737,14 +1737,14 @@ fuse_send_enomem(struct fuse_ll *f_, fuse_send_errno(f_,ch_,ENOMEM,unique_id_); } -static -void -fuse_send_einval(struct fuse_ll *f_, - struct fuse_chan *ch_, - const uint64_t unique_id_) -{ - fuse_send_errno(f_,ch_,EINVAL,unique_id_); -} +// static +// void +// fuse_send_einval(struct fuse_ll *f_, +// struct fuse_chan *ch_, +// const uint64_t unique_id_) +// { +// fuse_send_errno(f_,ch_,EINVAL,unique_id_); +// } static int @@ -1777,9 +1777,6 @@ fuse_ll_buf_process_read(struct fuse_session *se_, in = (struct fuse_in_header*)msgbuf_->mem; - if((in->uid == FUSE_INVALID_UIDGID) || (in->gid == FUSE_INVALID_UIDGID)) - return fuse_send_einval(se_->f,se_->ch,in->unique); - req = fuse_ll_alloc_req(se_->f); if(req == NULL) return fuse_send_enomem(se_->f,se_->ch,in->unique); diff --git a/src/caps.cpp b/src/caps.cpp new file mode 100644 index 00000000..72d5a4f9 --- /dev/null +++ b/src/caps.cpp @@ -0,0 +1,102 @@ +#include "caps.hpp" + +#if defined __linux__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +static +int +capset(cap_user_header_t header_, + const cap_user_data_t data_) +{ + return ::syscall(SYS_capset,header_,data_); +} + +static +int +capget(cap_user_header_t header_, + cap_user_data_t data_) +{ + return ::syscall(SYS_capget,header_,data_); +} + +static +int +capset(int cap_bit_) +{ + int rv; + struct __user_cap_header_struct header; + struct __user_cap_data_struct data[2]; + + header.version = _LINUX_CAPABILITY_VERSION_3; + header.pid = 0; + + rv = capget(&header,data); + if(rv < 0) + return rv; + + int word = cap_bit_ / 32; + int bit = cap_bit_ % 32; + + data[word].permitted |= (1 << bit); + data[word].effective |= (1 << bit); + data[word].inheritable |= (1 << bit); + + rv = capset(&header,data); + if(rv < 0) + return rv; + + return 0; +} + +int +caps::setup() +{ + int rv; + + rv = capset(CAP_DAC_OVERRIDE); + if(rv < 0) + return rv; + rv = capset(CAP_DAC_READ_SEARCH); + if(rv < 0) + return rv; + rv = capset(CAP_FOWNER); + if(rv < 0) + return rv; + rv = capset(CAP_CHOWN); + if(rv < 0) + return rv; + rv = capset(CAP_SETUID); + if(rv < 0) + return rv; + rv = capset(CAP_SETGID); + if(rv < 0) + return rv; + + rv = prctl(PR_SET_SECUREBITS, + SECBIT_KEEP_CAPS | SECBIT_NO_SETUID_FIXUP); + if(rv < 0) + return -errno; + + return 0; +} +#else +int +caps::setup() +{ + return -ENOTSUP; +} +#endif diff --git a/src/caps.hpp b/src/caps.hpp new file mode 100644 index 00000000..7ca22636 --- /dev/null +++ b/src/caps.hpp @@ -0,0 +1,6 @@ +#pragma once + +namespace caps +{ + int setup(); +} diff --git a/src/fs_attr_linux.icpp b/src/fs_attr_linux.icpp index 6133d6ed..47fd077b 100644 --- a/src/fs_attr_linux.icpp +++ b/src/fs_attr_linux.icpp @@ -31,7 +31,7 @@ using std::string; static int _get_fs_ioc_flags(const int fd, - int &flags) + int &flags) { int rv; @@ -45,7 +45,7 @@ _get_fs_ioc_flags(const int fd, static int _get_fs_ioc_flags(const string &file, - int &flags) + int &flags) { int fd; int rv; diff --git a/src/fs_clonepath.cpp b/src/fs_clonepath.cpp index 423b9d46..088b737a 100644 --- a/src/fs_clonepath.cpp +++ b/src/fs_clonepath.cpp @@ -27,6 +27,16 @@ #include "fs_xattr.hpp" #include "ugid.hpp" +#include "fs_close.hpp" +#include "fs_fstat.hpp" +#include "fs_mkdirat.hpp" +#include "fs_openat.hpp" +#include "fs_fchown.hpp" +#include "fs_fchmod.hpp" +#include "fs_futimens.hpp" + +#include "scope_guard.hpp" + static bool @@ -107,21 +117,62 @@ fs::clonepath(const fs::path &srcpath_, return 0; } + +// WORK IN PROGRESS +static int -fs::clonepath_as_root(const fs::path &srcpath_, - const fs::path &dstpath_, - const fs::path &relpath_, - const bool return_metadata_errors_) +_clonepath2(const int srcfd_, + const int dstfd_, + const fs::path &dirname_, + const bool return_metadata_errors_) { - if(relpath_.empty()) - return 0; - if(srcpath_ == dstpath_) + int rv; + int srcdirfd; + int dstdirfd; + struct stat st; + + if(dirname_.empty()) return 0; - const ugid::SetRootGuard ugid_guard; + rv = fs::mkdirat(dstfd_,dirname_,0); + if(rv < 0) + return ((rv == -EEXIST) ? 0 : rv); + + srcdirfd = fs::openat(srcfd_,dirname_,O_DIRECTORY); + if(srcdirfd < 0) + return srcdirfd; + DEFER { fs::close(srcdirfd); }; + + dstdirfd = fs::openat(dstfd_,dirname_,O_DIRECTORY); + if(dstdirfd < 0) + return dstdirfd; + DEFER { fs::close(dstdirfd); }; + + rv = fs::attr::copy(srcdirfd,dstdirfd,FS_ATTR_CLEAR_IMMUTABLE); + if(return_metadata_errors_ && (rv < 0) && !::_ignorable_error(-rv)) + return rv; + + rv = fs::xattr::copy(srcdirfd,dstdirfd); + if(return_metadata_errors_ && (rv < 0) && !::_ignorable_error(-rv)) + return rv; + + rv = fs::fstat(srcdirfd,&st); + if(rv < 0) + return rv; + if(!S_ISDIR(st.st_mode)) + return -ENOTDIR; + + rv = fs::fchown_check_on_error(dstdirfd,st); + if(rv < 0) + return rv; + + rv = fs::fchmod_check_on_error(dstdirfd,st); + if(rv < 0) + return rv; - return fs::clonepath(srcpath_, - dstpath_, - relpath_, - return_metadata_errors_); + rv = fs::futimens(dstdirfd,st); + if(rv < 0) + return rv; + + return 0; } diff --git a/src/fs_clonepath.hpp b/src/fs_clonepath.hpp index 3bd1a8c5..f5821f9d 100644 --- a/src/fs_clonepath.hpp +++ b/src/fs_clonepath.hpp @@ -25,9 +25,4 @@ namespace fs const fs::path &dstpath, const fs::path &relpath, const bool return_metadata_errors = false); - - int clonepath_as_root(const fs::path &srcpath, - const fs::path &dstpath, - const fs::path &relpath, - const bool return_metadata_errors = false); } diff --git a/src/fs_is_rofs.hpp b/src/fs_is_rofs.hpp index 22c556da..17ef7bf0 100644 --- a/src/fs_is_rofs.hpp +++ b/src/fs_is_rofs.hpp @@ -49,8 +49,6 @@ namespace fs bool is_rofs(const fs::path &path_) { - ugid::SetRootGuard const ugid; - int fd; std::string tmp_filepath; diff --git a/src/fs_mkdir_as.hpp b/src/fs_mkdir_as.hpp new file mode 100644 index 00000000..2e641101 --- /dev/null +++ b/src/fs_mkdir_as.hpp @@ -0,0 +1,50 @@ +#pragma once + +#include "fs_mkdir.hpp" + + +#if defined __linux__ +#include "ugid.hpp" + +namespace fs +{ + template + static + inline + int + mkdir_as(const ugid_t ugid_, + const T &path_, + const mode_t mode_) + { + const ugid::Set _(ugid_); + + return fs::mkdir(path_,mode_); + } +} +#elif defined __FreeBSD__ +#include "fs_lchown.hpp" + +namespace fs +{ + template + static + inline + int + mkdir_as(const ugid_t ugid_, + const T &path_,` + const mode_t mode_) + { + int rv; + + rv = fs::mkdir(path_,mode_); + if(rv < 0) + return rv; + + fs::lchown(path_,ugid_.uid,ugid_.gid); + + return 0; + } +} +#else +#error "Not Supported" +#endif diff --git a/src/fs_mkdir_as_root.hpp b/src/fs_mkdir_as_root.hpp deleted file mode 100644 index 3299ffa3..00000000 --- a/src/fs_mkdir_as_root.hpp +++ /dev/null @@ -1,35 +0,0 @@ -/* - ISC License - - Copyright (c) 2021, Antonio SJ Musumeci - - Permission to use, copy, modify, and/or distribute this software for any - purpose with or without fee is hereby granted, provided that the above - copyright notice and this permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -*/ - -#include "fs_mkdir.hpp" -#include "ugid.hpp" - -namespace fs -{ - template - static - inline - int - mkdir_as_root(const T &path_, - const mode_t mode_) - { - const ugid::SetRootGuard guard; - - return fs::mkdir(path_,mode_); - } -} diff --git a/src/fs_mkdirat.hpp b/src/fs_mkdirat.hpp new file mode 100644 index 00000000..f87f9150 --- /dev/null +++ b/src/fs_mkdirat.hpp @@ -0,0 +1,48 @@ +#pragma once + +#include "to_neg_errno.hpp" +#include "fs_path.hpp" + +#include +#include + +namespace fs +{ + static + inline + int + mkdirat(const int dirfd_, + const char *pathname_, + const mode_t mode_) + { + int rv; + + rv = ::mkdirat(dirfd_,pathname_,mode_); + + return ::to_neg_errno(rv); + } + + static + inline + int + mkdirat(const int dirfd_, + const std::string &pathname_, + const mode_t mode_) + { + return fs::mkdirat(dirfd_, + pathname_.c_str(), + mode_); + } + + static + inline + int + mkdirat(const int dirfd_, + const fs::path &pathname_, + const mode_t mode_) + { + return fs::mkdirat(dirfd_, + pathname_.c_str(), + mode_); + } +} diff --git a/src/fs_mknod_as.hpp b/src/fs_mknod_as.hpp new file mode 100644 index 00000000..2ac0c39a --- /dev/null +++ b/src/fs_mknod_as.hpp @@ -0,0 +1,50 @@ +#pragma once + +#include "fs_mknod.hpp" + + +#if defined __linux__ +#include "ugid.hpp" + +namespace fs +{ + template + static + inline + int + mknod_as(const ugid_t ugid_, + const T &path_, + const mode_t mode_, + const dev_t dev_) + { + const ugid::Set _(ugid_); + + return fs::mknod(path_,mode_,dev_); + } +} +#elif defined __FreeBSD__ +#include "fs_lchown.hpp" + +namespace fs +{ + template + static + inline + int + mknod_as(const ugid_t ugid_, + const T &path_, + const mode_t mode_, + const dev_t dev_) + { + int rv; + + rv = fs::mknod(path_,mode_,dev_); + + fs::lchown(path_,ugid_.uid,ugid_.gid); + + return rv; + } +} +#else +#error "Not Supported!" +#endif diff --git a/src/fs_movefile_and_open.cpp b/src/fs_movefile_and_open.cpp index 9a9704e8..f59103cd 100644 --- a/src/fs_movefile_and_open.cpp +++ b/src/fs_movefile_and_open.cpp @@ -137,8 +137,6 @@ fs::movefile_and_open_as_root(const Policy::Create &policy_, const fs::path &fusepath_, const int origfd_) { - const ugid::Set ugid(0,0); - return fs::movefile_and_open(policy_, branches_, branchpath_, diff --git a/src/fs_open_as.hpp b/src/fs_open_as.hpp new file mode 100644 index 00000000..2c82b8dc --- /dev/null +++ b/src/fs_open_as.hpp @@ -0,0 +1,50 @@ +#pragma once + +#include "fs_open.hpp" + + +#if defined __linux__ +#include "ugid.hpp" + +namespace fs +{ + static + inline + int + open_as(const ugid_t ugid_, + const fs::path &path_, + const int flags_, + const mode_t mode_) + { + const ugid::Set _(ugid_); + + return fs::open(path_,flags_,mode_); + } +} +#elif defined __FreeBSD__ +#include "fs_lchown.hpp" + +namespace fs +{ + static + inline + int + open_as(const ugid_t ugid_, + const fs::path &path_, + const int flags_, + const mode_t mode_) + { + int rv; + + rv = fs::open(path_,flags_,mode_); + if(rv < 0) + return rv; + + fs::fchown(rv,ugid_.uid,ugid_.gid); + + return rv; + } +} +#else +#error "Not Supported!" +#endif diff --git a/src/fs_symlink_as.hpp b/src/fs_symlink_as.hpp new file mode 100644 index 00000000..fea967c8 --- /dev/null +++ b/src/fs_symlink_as.hpp @@ -0,0 +1,48 @@ +#pragma once + +#include "fs_symlink.hpp" + + +#if defined __linux__ +#include "ugid.hpp" + +namespace fs +{ + template + static + inline + int + symlink_as(const ugid_t ugid_, + const char *target_, + const T &linkpath_) + { + const ugid::Set _(ugid_); + + return fs::symlink(target_,linkpath_); + } +} +#elif defined __FreeBSD__ +#include "fs_lchown.hpp" + + template + static + inline + int + symlink_as(const ugid_t ugid_, + const char *target_, + const T &linkpath_) + { + int rv; + + rv = fs::symlink(target_,linkpath_); + if(rv < 0) + return rv; + + fs::lchown(linkpath_,ugid_.uid,ugid_.gid); + + return 0; + } +} +#else +#error "Not Supported!" +#endif diff --git a/src/fuse_access.cpp b/src/fuse_access.cpp index ae3419c8..521b75ab 100644 --- a/src/fuse_access.cpp +++ b/src/fuse_access.cpp @@ -54,8 +54,7 @@ FUSE::access(const fuse_req_ctx_t *ctx_, const char *fusepath_, int mask_) { - const fs::path fusepath{fusepath_}; - const ugid::Set ugid(ctx_->uid,ctx_->gid); + const fs::path fusepath{fusepath_}; return ::_access(cfg.func.access.policy, cfg.branches, diff --git a/src/fuse_chmod.cpp b/src/fuse_chmod.cpp index aa3e1d59..79a8b1be 100644 --- a/src/fuse_chmod.cpp +++ b/src/fuse_chmod.cpp @@ -108,7 +108,6 @@ FUSE::chmod(const fuse_req_ctx_t *ctx_, mode_t mode_) { const fs::path fusepath{fusepath_}; - const ugid::Set ugid(ctx_->uid,ctx_->gid); return ::_chmod(fusepath,mode_); } diff --git a/src/fuse_chown.cpp b/src/fuse_chown.cpp index 2653a44e..2abb37b6 100644 --- a/src/fuse_chown.cpp +++ b/src/fuse_chown.cpp @@ -99,8 +99,7 @@ FUSE::chown(const fuse_req_ctx_t *ctx_, uid_t uid_, gid_t gid_) { - const fs::path fusepath{fusepath_}; - const ugid::Set ugid(ctx_->uid,ctx_->gid); + const fs::path fusepath{fusepath_}; return ::_chown(cfg.func.chown.policy, cfg.func.getattr.policy, diff --git a/src/fuse_create.cpp b/src/fuse_create.cpp index 253c3dc6..081628fa 100644 --- a/src/fuse_create.cpp +++ b/src/fuse_create.cpp @@ -19,11 +19,15 @@ #include "state.hpp" #include "config.hpp" +#include "fs_readlink.hpp" #include "errno.hpp" #include "fileinfo.hpp" #include "fs_acl.hpp" +#include "fs_close.hpp" #include "fs_clonepath.hpp" #include "fs_open.hpp" +#include "fs_open_as.hpp" +#include "fs_openat.hpp" #include "fs_path.hpp" #include "fuse_passthrough.hpp" #include "procfs.hpp" @@ -132,7 +136,8 @@ _config_to_ffi_flags(Config &cfg_, static int -_create_core(const fs::path &fullpath_, +_create_core(const ugid_t ugid_, + const fs::path &fullpath_, mode_t mode_, const mode_t umask_, const int flags_) @@ -140,12 +145,13 @@ _create_core(const fs::path &fullpath_, if(!fs::acl::dir_has_defaults(fullpath_)) mode_ &= ~umask_; - return fs::open(fullpath_,flags_,mode_); + return fs::open_as(ugid_,fullpath_,flags_,mode_); } static int -_create_core(const Branch *branch_, +_create_core(const ugid_t ugid_, + const Branch *branch_, const fs::path &fusepath_, fuse_file_info_t *ffi_, const mode_t mode_, @@ -157,7 +163,7 @@ _create_core(const Branch *branch_, fullpath = branch_->path / fusepath_; - rv = ::_create_core(fullpath,mode_,umask_,ffi_->flags); + rv = ::_create_core(ugid_,fullpath,mode_,umask_,ffi_->flags); if(rv < 0) return rv; @@ -170,7 +176,8 @@ _create_core(const Branch *branch_, static int -_create(const Policy::Search &searchFunc_, +_create(const ugid_t ugid_, + const Policy::Search &searchFunc_, const Policy::Create &createFunc_, const Branches &branches_, const fs::path &fusepath_, @@ -194,13 +201,14 @@ _create(const Policy::Search &searchFunc_, if(rv < 0) return rv; - rv = fs::clonepath_as_root(existingpaths[0]->path, - createpaths[0]->path, - fusedirpath); + rv = fs::clonepath(existingpaths[0]->path, + createpaths[0]->path, + fusedirpath); if(rv < 0) return rv; - return ::_create_core(createpaths[0], + return ::_create_core(ugid_, + createpaths[0], fusepath_, ffi_, mode_, @@ -225,7 +233,6 @@ _create_for_insert_lambda(const fuse_req_ctx_t *ctx_, { int rv; FileInfo *fi; - const ugid::Set ugid(ctx_->uid,ctx_->gid); ::_config_to_ffi_flags(cfg,ctx_->pid,ffi_); if(cfg.cache_writeback) @@ -233,7 +240,8 @@ _create_for_insert_lambda(const fuse_req_ctx_t *ctx_, ffi_->noflush = !::_calculate_flush(cfg.flushonclose, ffi_->flags); - rv = ::_create(cfg.func.getattr.policy, + rv = ::_create(ctx_, + cfg.func.getattr.policy, cfg.func.create.policy, cfg.branches, fusepath_, @@ -243,7 +251,8 @@ _create_for_insert_lambda(const fuse_req_ctx_t *ctx_, if(rv == -EROFS) { cfg.branches.find_and_set_mode_ro(); - rv = ::_create(cfg.func.getattr.policy, + rv = ::_create(ctx_, + cfg.func.getattr.policy, cfg.func.create.policy, cfg.branches, fusepath_, diff --git a/src/fuse_getattr.cpp b/src/fuse_getattr.cpp index 2dfe0096..6c441004 100644 --- a/src/fuse_getattr.cpp +++ b/src/fuse_getattr.cpp @@ -213,8 +213,6 @@ FUSE::getattr(const fuse_req_ctx_t *ctx_, struct stat *st_, fuse_timeouts_t *timeout_) { - const ugid::Set ugid(ctx_); - return FUSE::getattr(fusepath_,st_,timeout_); } diff --git a/src/fuse_getxattr.cpp b/src/fuse_getxattr.cpp index 5da8b12f..7e09ef4f 100644 --- a/src/fuse_getxattr.cpp +++ b/src/fuse_getxattr.cpp @@ -193,8 +193,6 @@ FUSE::getxattr(const fuse_req_ctx_t *ctx_, if(cfg.xattr.to_int()) return -cfg.xattr.to_int(); - const ugid::Set ugid(ctx_->uid,ctx_->gid); - return ::_getxattr(cfg.func.getxattr.policy, cfg.branches, fusepath, diff --git a/src/fuse_init.cpp b/src/fuse_init.cpp index 1313e0f6..3877878a 100644 --- a/src/fuse_init.cpp +++ b/src/fuse_init.cpp @@ -16,6 +16,8 @@ #include "fuse_init.hpp" +#include "caps.hpp" + #include "config.hpp" #include "fs_readahead.hpp" #include "procfs.hpp" @@ -187,7 +189,7 @@ void * FUSE::init(fuse_conn_info *conn_) { procfs::init(); - ugid::init(); + caps::setup(); cfg.readdir.initialize(); ::_want_if_capable(conn_,FUSE_CAP_ASYNC_DIO); diff --git a/src/fuse_ioctl.cpp b/src/fuse_ioctl.cpp index 28e5a086..0cfb984c 100644 --- a/src/fuse_ioctl.cpp +++ b/src/fuse_ioctl.cpp @@ -113,8 +113,7 @@ _ioctl_file(const fuse_req_ctx_t *ctx_, void *data_, uint32_t *out_bufsz_) { - FileInfo *fi = FileInfo::from_fh(ffi_->fh); - const ugid::Set ugid(ctx_); + FileInfo *fi = FileInfo::from_fh(ffi_->fh); return ::_ioctl(fi->fd,cmd_,data_,out_bufsz_); } @@ -162,8 +161,7 @@ _ioctl_dir(const fuse_req_ctx_t *ctx_, void *data_, uint32_t *out_bufsz_) { - DirInfo *di = DirInfo::from_fh(ffi_->fh); - const ugid::Set ugid(ctx_); + DirInfo *di = DirInfo::from_fh(ffi_->fh); return ::_ioctl_dir_base(cfg.func.open.policy, cfg.branches, diff --git a/src/fuse_link.cpp b/src/fuse_link.cpp index 9bbc4f7f..64be0135 100644 --- a/src/fuse_link.cpp +++ b/src/fuse_link.cpp @@ -55,7 +55,9 @@ _link_create_path_loop(const std::vector &oldbranches_, rv = fs::link(oldfullpath,newfullpath); if(rv == -ENOENT) { - rv = fs::clonepath_as_root(newbranch_->path,oldbranch->path,newfusedirpath_); + rv = fs::clonepath(newbranch_->path, + oldbranch->path, + newfusedirpath_); if(rv == 0) rv = fs::link(oldfullpath,newfullpath); } @@ -328,9 +330,8 @@ FUSE::link(const fuse_req_ctx_t *ctx_, fuse_timeouts_t *timeouts_) { int rv; - const fs::path oldpath{oldpath_}; - const fs::path newpath{newpath_}; - const ugid::Set ugid(ctx_); + const fs::path oldpath{oldpath_}; + const fs::path newpath{newpath_}; rv = ::_link(ctx_,oldpath,newpath,st_,timeouts_); if(rv == -EXDEV) diff --git a/src/fuse_listxattr.cpp b/src/fuse_listxattr.cpp index e7cadca8..7ae092ff 100644 --- a/src/fuse_listxattr.cpp +++ b/src/fuse_listxattr.cpp @@ -143,8 +143,6 @@ FUSE::listxattr(const fuse_req_ctx_t *ctx_, return -ENOSYS; } - const ugid::Set ugid(ctx_); - return ::_listxattr(cfg.func.listxattr.policy, cfg.branches, fusepath, diff --git a/src/fuse_mkdir.cpp b/src/fuse_mkdir.cpp index 883f4ac2..854ec2ce 100644 --- a/src/fuse_mkdir.cpp +++ b/src/fuse_mkdir.cpp @@ -21,7 +21,7 @@ #include "error.hpp" #include "fs_acl.hpp" #include "fs_clonepath.hpp" -#include "fs_mkdir.hpp" +#include "fs_mkdir_as.hpp" #include "fs_path.hpp" #include "policy.hpp" #include "ugid.hpp" @@ -33,19 +33,21 @@ static int -_mkdir_core(const fs::path &fullpath_, +_mkdir_core(const ugid_t ugid_, + const fs::path &fullpath_, mode_t mode_, const mode_t umask_) { if(!fs::acl::dir_has_defaults(fullpath_)) mode_ &= ~umask_; - return fs::mkdir(fullpath_,mode_); + return fs::mkdir_as(ugid_,fullpath_,mode_); } static int -_mkdir_loop_core(const fs::path &createpath_, +_mkdir_loop_core(const ugid_t ugid_, + const fs::path &createpath_, const fs::path &fusepath_, const mode_t mode_, const mode_t umask_) @@ -55,14 +57,15 @@ _mkdir_loop_core(const fs::path &createpath_, fullpath = createpath_ / fusepath_; - rv = ::_mkdir_core(fullpath,mode_,umask_); + rv = ::_mkdir_core(ugid_,fullpath,mode_,umask_); return rv; } static int -_mkdir_loop(const Branch *existingbranch_, +_mkdir_loop(const ugid_t ugid_, + const Branch *existingbranch_, const std::vector &createbranches_, const fs::path &fusepath_, const fs::path &fusedirpath_, @@ -74,16 +77,17 @@ _mkdir_loop(const Branch *existingbranch_, for(const auto &createbranch : createbranches_) { - rv = fs::clonepath_as_root(existingbranch_->path, - createbranch->path, - fusedirpath_); + rv = fs::clonepath(existingbranch_->path, + createbranch->path, + fusedirpath_); if(rv < 0) { err = rv; continue; } - err = ::_mkdir_loop_core(createbranch->path, + err = ::_mkdir_loop_core(ugid_, + createbranch->path, fusepath_, mode_, umask_); @@ -94,7 +98,8 @@ _mkdir_loop(const Branch *existingbranch_, static int -_mkdir(const Policy::Search &getattrPolicy_, +_mkdir(const ugid_t ugid_, + const Policy::Search &getattrPolicy_, const Policy::Create &mkdirPolicy_, const Branches &branches_, const fs::path &fusepath_, @@ -116,7 +121,8 @@ _mkdir(const Policy::Search &getattrPolicy_, if(rv < 0) return rv; - return ::_mkdir_loop(existingbranches[0], + return ::_mkdir_loop(ugid_, + existingbranches[0], createbranches, fusepath_, fusedirpath, @@ -130,10 +136,10 @@ FUSE::mkdir(const fuse_req_ctx_t *ctx_, mode_t mode_) { int rv; - const fs::path fusepath{fusepath_}; - const ugid::Set ugid(ctx_); + const fs::path fusepath{fusepath_}; - rv = ::_mkdir(cfg.func.getattr.policy, + rv = ::_mkdir(ctx_, + cfg.func.getattr.policy, cfg.func.mkdir.policy, cfg.branches, fusepath, @@ -142,7 +148,8 @@ FUSE::mkdir(const fuse_req_ctx_t *ctx_, if(rv == -EROFS) { cfg.branches.find_and_set_mode_ro(); - rv = ::_mkdir(cfg.func.getattr.policy, + rv = ::_mkdir(ctx_, + cfg.func.getattr.policy, cfg.func.mkdir.policy, cfg.branches, fusepath, diff --git a/src/fuse_mknod.cpp b/src/fuse_mknod.cpp index 80d4f853..a1df63f1 100644 --- a/src/fuse_mknod.cpp +++ b/src/fuse_mknod.cpp @@ -20,7 +20,7 @@ #include "errno.hpp" #include "error.hpp" #include "fs_acl.hpp" -#include "fs_mknod.hpp" +#include "fs_mknod_as.hpp" #include "fs_clonepath.hpp" #include "fs_path.hpp" #include "ugid.hpp" @@ -34,7 +34,8 @@ static inline int -_mknod_core(const fs::path &fullpath_, +_mknod_core(const ugid_t ugid_, + const fs::path &fullpath_, mode_t mode_, const mode_t umask_, const dev_t dev_) @@ -42,12 +43,13 @@ _mknod_core(const fs::path &fullpath_, if(!fs::acl::dir_has_defaults(fullpath_)) mode_ &= ~umask_; - return fs::mknod(fullpath_,mode_,dev_); + return fs::mknod_as(ugid_,fullpath_,mode_,dev_); } static int -_mknod_loop_core(const fs::path &createbranch_, +_mknod_loop_core(const ugid_t ugid_, + const fs::path &createbranch_, const fs::path &fusepath_, const mode_t mode_, const mode_t umask_, @@ -58,14 +60,15 @@ _mknod_loop_core(const fs::path &createbranch_, fullpath = createbranch_ / fusepath_; - rv = ::_mknod_core(fullpath,mode_,umask_,dev_); + rv = ::_mknod_core(ugid_,fullpath,mode_,umask_,dev_); return rv; } static int -_mknod_loop(const fs::path &existingbranch_, +_mknod_loop(const ugid_t ugid_, + const fs::path &existingbranch_, const std::vector &createbranches_, const fs::path &fusepath_, const fs::path &fusedirpath_, @@ -78,16 +81,17 @@ _mknod_loop(const fs::path &existingbranch_, for(const auto &createbranch : createbranches_) { - rv = fs::clonepath_as_root(existingbranch_, - createbranch->path, - fusedirpath_); + rv = fs::clonepath(existingbranch_, + createbranch->path, + fusedirpath_); if(rv < 0) { err = rv; continue; } - err = ::_mknod_loop_core(createbranch->path, + err = ::_mknod_loop_core(ugid_, + createbranch->path, fusepath_, mode_, umask_, @@ -99,7 +103,8 @@ _mknod_loop(const fs::path &existingbranch_, static int -_mknod(const Policy::Search &searchFunc_, +_mknod(const ugid_t ugid_, + const Policy::Search &searchFunc_, const Policy::Create &createFunc_, const Branches &branches_, const fs::path &fusepath_, @@ -122,7 +127,8 @@ _mknod(const Policy::Search &searchFunc_, if(rv < 0) return rv; - return ::_mknod_loop(existingbranches[0]->path, + return ::_mknod_loop(ugid_, + existingbranches[0]->path, createbranches, fusepath_, fusedirpath, @@ -138,10 +144,10 @@ FUSE::mknod(const fuse_req_ctx_t *ctx_, dev_t rdev_) { int rv; - const fs::path fusepath{fusepath_}; - const ugid::Set ugid(ctx_); + const fs::path fusepath{fusepath_}; - rv = ::_mknod(cfg.func.getattr.policy, + rv = ::_mknod(ctx_, + cfg.func.getattr.policy, cfg.func.mknod.policy, cfg.branches, fusepath, @@ -151,7 +157,8 @@ FUSE::mknod(const fuse_req_ctx_t *ctx_, if(rv == -EROFS) { cfg.branches.find_and_set_mode_ro(); - rv = ::_mknod(cfg.func.getattr.policy, + rv = ::_mknod(ctx_, + cfg.func.getattr.policy, cfg.func.mknod.policy, cfg.branches, fusepath, diff --git a/src/fuse_open.cpp b/src/fuse_open.cpp index 6723380a..62de6d9a 100644 --- a/src/fuse_open.cpp +++ b/src/fuse_open.cpp @@ -281,7 +281,6 @@ _open_for_insert_lambda(const fuse_req_ctx_t *ctx_, { int rv; FileInfo *fi; - const ugid::Set ugid(ctx_); ::_config_to_ffi_flags(cfg,ctx_->pid,ffi_); @@ -337,7 +336,6 @@ _open_for_update_lambda(const fuse_req_ctx_t *ctx_, State::OpenFile *of_) { int rv; - const ugid::Set ugid(ctx_); ::_config_to_ffi_flags(cfg,ctx_->pid,ffi_); diff --git a/src/fuse_passthrough.hpp b/src/fuse_passthrough.hpp index fcccf817..99f8a7ea 100644 --- a/src/fuse_passthrough.hpp +++ b/src/fuse_passthrough.hpp @@ -14,8 +14,6 @@ namespace FUSE int passthrough_open(const int fd_) { - const ugid::SetRootGuard _; - return fuse_passthrough_open(fd_); } @@ -24,8 +22,6 @@ namespace FUSE int passthrough_close(const int backing_id_) { - const ugid::SetRootGuard _; - return fuse_passthrough_close(backing_id_); } } diff --git a/src/fuse_readdir_cor.cpp b/src/fuse_readdir_cor.cpp index f61a0e61..a32c3bca 100644 --- a/src/fuse_readdir_cor.cpp +++ b/src/fuse_readdir_cor.cpp @@ -64,8 +64,6 @@ _concurrent_readdir(ThreadPool &tp_, auto func = [&,dirents_,uid_,gid_]() { - const ugid::Set ugid(uid_,gid_); - return ::_readdir(branch.path, rel_dirpath_, names, diff --git a/src/fuse_readdir_cosr.cpp b/src/fuse_readdir_cosr.cpp index c7e39a1a..0add595d 100644 --- a/src/fuse_readdir_cosr.cpp +++ b/src/fuse_readdir_cosr.cpp @@ -45,16 +45,14 @@ int _readdir(ThreadPool &tp_, const Branches::Ptr &branches_, const fs::path &rel_dirpath_, - fuse_dirents_t *dirents_, - uid_t const uid_, - gid_t const gid_) + fuse_dirents_t *dirents_) { int rv; std::vector> futures; fuse_dirents_reset(dirents_); - futures = ::_opendir(tp_,branches_,rel_dirpath_,uid_,gid_); + futures = ::_opendir(tp_,branches_,rel_dirpath_); rv = ::_readdir(futures,rel_dirpath_,dirents_); return rv; @@ -70,7 +68,5 @@ FUSE::ReadDirCOSR::operator()(const fuse_req_ctx_t *ctx_, return ::_readdir(_tp, cfg.branches, di->fusepath, - dirents_, - ctx_->uid, - ctx_->gid); + dirents_); } diff --git a/src/fuse_readdir_cosr_getdents.icpp b/src/fuse_readdir_cosr_getdents.icpp index 40e3992d..e4dcdb30 100644 --- a/src/fuse_readdir_cosr_getdents.icpp +++ b/src/fuse_readdir_cosr_getdents.icpp @@ -28,9 +28,7 @@ inline std::vector> _opendir(ThreadPool &tp_, const Branches::Ptr &branches_, - const fs::path &rel_dirpath_, - uid_t const uid_, - gid_t const gid_) + const fs::path &rel_dirpath_) { std::vector> futures; @@ -39,11 +37,10 @@ _opendir(ThreadPool &tp_, for(const auto &branch : *branches_) { auto func = - [&branch,&rel_dirpath_,uid_,gid_]() + [&branch,&rel_dirpath_]() { int fd; fs::path abs_dirpath; - const ugid::Set ugid(uid_,gid_); abs_dirpath = branch.path / rel_dirpath_; diff --git a/src/fuse_readdir_cosr_readdir.icpp b/src/fuse_readdir_cosr_readdir.icpp index ec76060e..3ff12bfc 100644 --- a/src/fuse_readdir_cosr_readdir.icpp +++ b/src/fuse_readdir_cosr_readdir.icpp @@ -37,9 +37,7 @@ inline std::vector> _opendir(ThreadPool &tp_, const Branches::Ptr &branches_, - const fs::path &rel_dirpath_, - uid_t const uid_, - gid_t const gid_) + const fs::path &rel_dirpath_) { std::vector> futures; @@ -48,11 +46,10 @@ _opendir(ThreadPool &tp_, for(const auto &branch : *branches_) { auto func = - [&branch,&rel_dirpath_,uid_,gid_]() + [&branch,&rel_dirpath_]() { DIR *dir; fs::path abs_dirpath; - const ugid::Set ugid(uid_,gid_); abs_dirpath = branch.path / rel_dirpath_; diff --git a/src/fuse_readdir_seq.cpp b/src/fuse_readdir_seq.cpp index ee27021c..370a0985 100644 --- a/src/fuse_readdir_seq.cpp +++ b/src/fuse_readdir_seq.cpp @@ -33,8 +33,7 @@ FUSE::ReadDirSeq::operator()(const fuse_req_ctx_t *ctx_, const fuse_file_info_t *ffi_, fuse_dirents_t *dirents_) { - DirInfo *di = DirInfo::from_fh(ffi_->fh); - const ugid::Set ugid(ctx_); + DirInfo *di = DirInfo::from_fh(ffi_->fh); return ::_readdir(cfg.branches, di->fusepath, diff --git a/src/fuse_readlink.cpp b/src/fuse_readlink.cpp index 989db75c..3a0123eb 100644 --- a/src/fuse_readlink.cpp +++ b/src/fuse_readlink.cpp @@ -120,8 +120,7 @@ FUSE::readlink(const fuse_req_ctx_t *ctx_, char *buf_, size_t size_) { - const fs::path fusepath{fusepath_}; - const ugid::Set ugid(ctx_); + const fs::path fusepath{fusepath_}; return ::_readlink(cfg.func.readlink.policy, cfg.branches, diff --git a/src/fuse_removexattr.cpp b/src/fuse_removexattr.cpp index 87a2dcaf..c952d98a 100644 --- a/src/fuse_removexattr.cpp +++ b/src/fuse_removexattr.cpp @@ -101,8 +101,6 @@ FUSE::removexattr(const fuse_req_ctx_t *ctx_, if(cfg.xattr.to_int()) return -cfg.xattr.to_int(); - const ugid::Set ugid(ctx_); - return ::_removexattr(cfg.func.removexattr.policy, cfg.func.getxattr.policy, cfg.branches, diff --git a/src/fuse_rename.cpp b/src/fuse_rename.cpp index 224da590..f775c2fa 100644 --- a/src/fuse_rename.cpp +++ b/src/fuse_rename.cpp @@ -21,7 +21,7 @@ #include "errno.hpp" #include "fs_clonepath.hpp" #include "fs_link.hpp" -#include "fs_mkdir_as_root.hpp" +#include "fs_mkdir_as.hpp" #include "fs_path.hpp" #include "fs_remove.hpp" #include "fs_rename.hpp" @@ -105,9 +105,9 @@ _rename_create_path(const Policy::Search &searchPolicy_, rv = fs::rename(oldfullpath,newfullpath); if(rv < 0) { - rv = fs::clonepath_as_root(newbranches[0]->path, - branch.path, - newfusepath_.parent_path()); + rv = fs::clonepath(newbranches[0]->path, + branch.path, + newfusepath_.parent_path()); if(rv >= 0) rv = fs::rename(oldfullpath,newfullpath); } @@ -209,7 +209,6 @@ _rename_exdev_rename_target(const Policy::Action &actionPolicy_, if(rv < 0) return rv; - ugid::SetRootGuard ugidGuard; for(auto &branch : obranches_) { clonesrc = branch->path; @@ -219,7 +218,7 @@ _rename_exdev_rename_target(const Policy::Action &actionPolicy_, rv = fs::clonepath(clonesrc,clonedst,oldfusepath_.parent_path()); if(rv == -ENOENT) { - fs::mkdir(clonedst,01777); + fs::mkdir_as({0,0},clonedst,01777); rv = fs::clonepath(clonesrc,clonedst,oldfusepath_.parent_path()); } @@ -355,7 +354,6 @@ FUSE::rename(const fuse_req_ctx_t *ctx_, int rv; const fs::path oldfusepath{oldfusepath_}; const fs::path newfusepath{newfusepath_}; - const ugid::Set ugid(ctx_); rv = ::_rename(oldfusepath,newfusepath); if(rv == -EXDEV) diff --git a/src/fuse_rmdir.cpp b/src/fuse_rmdir.cpp index 29b29d6f..5a7cff2e 100644 --- a/src/fuse_rmdir.cpp +++ b/src/fuse_rmdir.cpp @@ -96,7 +96,6 @@ FUSE::rmdir(const fuse_req_ctx_t *ctx_, const char *fusepath_) { const fs::path fusepath{fusepath_}; - const ugid::Set ugid(ctx_); return ::_rmdir(cfg.func.rmdir.policy, cfg.branches, diff --git a/src/fuse_setxattr.cpp b/src/fuse_setxattr.cpp index 6bbd0319..8a527b4e 100644 --- a/src/fuse_setxattr.cpp +++ b/src/fuse_setxattr.cpp @@ -194,8 +194,6 @@ _setxattr(const fuse_req_ctx_t *ctx_, if(cfg.xattr.to_int()) return -cfg.xattr.to_int(); - const ugid::Set ugid(ctx_); - return ::_setxattr(cfg.func.setxattr.policy, cfg.func.getxattr.policy, cfg.branches, diff --git a/src/fuse_statfs.cpp b/src/fuse_statfs.cpp index 2ddd343a..c230881c 100644 --- a/src/fuse_statfs.cpp +++ b/src/fuse_statfs.cpp @@ -147,7 +147,6 @@ FUSE::statfs(const fuse_req_ctx_t *ctx_, struct statvfs *st_) { const fs::path fusepath{fusepath_}; - const ugid::Set ugid(ctx_); return ::_statfs(cfg.branches, fusepath, diff --git a/src/fuse_statx_supported.icpp b/src/fuse_statx_supported.icpp index 32089583..6e99e9ef 100644 --- a/src/fuse_statx_supported.icpp +++ b/src/fuse_statx_supported.icpp @@ -213,8 +213,6 @@ FUSE::statx(const fuse_req_ctx_t *ctx_, if(Config::is_ctrl_file(fusepath)) return ::_statx_controlfile(st_); - const ugid::Set ugid(ctx_); - return ::_statx(fusepath, flags_|AT_STATX_DONT_SYNC, mask_, @@ -247,8 +245,6 @@ FUSE::statx_fh(const fuse_req_ctx_t *ctx_, FileInfo *fi = FileInfo::from_fh(fh); - const ugid::Set ugid(ctx_); - return ::_statx(fi->fusepath, flags_|AT_STATX_DONT_SYNC, mask_, diff --git a/src/fuse_symlink.cpp b/src/fuse_symlink.cpp index ae5803ce..7a18a08f 100644 --- a/src/fuse_symlink.cpp +++ b/src/fuse_symlink.cpp @@ -23,7 +23,7 @@ #include "fs_lstat.hpp" #include "fs_path.hpp" #include "fs_inode.hpp" -#include "fs_symlink.hpp" +#include "fs_symlink_as.hpp" #include "fuse_getattr.hpp" #include "ugid.hpp" @@ -35,7 +35,8 @@ static int -_symlink_loop_core(const fs::path &newbranch_, +_symlink_loop_core(const ugid_t ugid_, + const fs::path &newbranch_, const char *target_, const fs::path &linkpath_, struct stat *st_) @@ -45,7 +46,7 @@ _symlink_loop_core(const fs::path &newbranch_, fullnewpath = newbranch_ / linkpath_; - rv = fs::symlink(target_,fullnewpath); + rv = fs::symlink_as(ugid_,target_,fullnewpath); if((rv >= 0) && (st_ != NULL) && (st_->st_ino == 0)) { fs::lstat(fullnewpath,st_); @@ -60,7 +61,8 @@ _symlink_loop_core(const fs::path &newbranch_, static int -_symlink_loop(const fs::path &existingbranch_, +_symlink_loop(const ugid_t ugid_, + const fs::path &existingbranch_, const std::vector &newbranches_, const char *target_, const fs::path &linkpath_, @@ -72,13 +74,14 @@ _symlink_loop(const fs::path &existingbranch_, for(auto &newbranch :newbranches_) { - rv = fs::clonepath_as_root(existingbranch_, - newbranch->path, - newdirpath_); + rv = fs::clonepath(existingbranch_, + newbranch->path, + newdirpath_); if(rv < 0) err = rv; else - err = ::_symlink_loop_core(newbranch->path, + err = ::_symlink_loop_core(ugid_, + newbranch->path, target_, linkpath_, st_); @@ -89,7 +92,8 @@ _symlink_loop(const fs::path &existingbranch_, static int -_symlink(const Policy::Search &searchFunc_, +_symlink(const ugid_t ugid_, + const Policy::Search &searchFunc_, const Policy::Create &createFunc_, const Branches &branches_, const char *target_, @@ -111,7 +115,8 @@ _symlink(const Policy::Search &searchFunc_, if(rv < 0) return rv; - return ::_symlink_loop(existingbranches[0]->path, + return ::_symlink_loop(ugid_, + existingbranches[0]->path, newbranches, target_, linkpath_, @@ -119,22 +124,6 @@ _symlink(const Policy::Search &searchFunc_, st_); } -int -FUSE::symlink(const fuse_req_ctx_t *ctx_, - const char *target_, - const char *linkpath_, - struct stat *st_, - fuse_timeouts_t *timeouts_) -{ - const fs::path linkpath{linkpath_}; - - return FUSE::symlink(ctx_, - target_, - linkpath, - st_, - timeouts_); -} - int FUSE::symlink(const fuse_req_ctx_t *ctx_, const char *target_, @@ -143,9 +132,9 @@ FUSE::symlink(const fuse_req_ctx_t *ctx_, fuse_timeouts_t *timeouts_) { int rv; - const ugid::Set ugid(ctx_); - rv = ::_symlink(cfg.func.getattr.policy, + rv = ::_symlink(ctx_, + cfg.func.getattr.policy, cfg.func.symlink.policy, cfg.branches, target_, @@ -154,7 +143,8 @@ FUSE::symlink(const fuse_req_ctx_t *ctx_, if(rv == -EROFS) { cfg.branches.find_and_set_mode_ro(); - rv = ::_symlink(cfg.func.getattr.policy, + rv = ::_symlink(ctx_, + cfg.func.getattr.policy, cfg.func.symlink.policy, cfg.branches, target_, @@ -181,3 +171,19 @@ FUSE::symlink(const fuse_req_ctx_t *ctx_, return rv; } + +int +FUSE::symlink(const fuse_req_ctx_t *ctx_, + const char *target_, + const char *linkpath_, + struct stat *st_, + fuse_timeouts_t *timeouts_) +{ + const fs::path linkpath{linkpath_}; + + return FUSE::symlink(ctx_, + target_, + linkpath, + st_, + timeouts_); +} diff --git a/src/fuse_truncate.cpp b/src/fuse_truncate.cpp index ff0ad2f3..f3008268 100644 --- a/src/fuse_truncate.cpp +++ b/src/fuse_truncate.cpp @@ -94,8 +94,7 @@ FUSE::truncate(const fuse_req_ctx_t *ctx_, const char *fusepath_, off_t size_) { - const fs::path fusepath{fusepath_}; - const ugid::Set ugid(ctx_); + const fs::path fusepath{fusepath_}; return ::_truncate(cfg.func.truncate.policy, cfg.func.getattr.policy, diff --git a/src/fuse_unlink.cpp b/src/fuse_unlink.cpp index 144c9264..a870c930 100644 --- a/src/fuse_unlink.cpp +++ b/src/fuse_unlink.cpp @@ -68,8 +68,7 @@ int FUSE::unlink(const fuse_req_ctx_t *ctx_, const char *fusepath_) { - const fs::path fusepath{fusepath_}; - const ugid::Set ugid(ctx_); + const fs::path fusepath{fusepath_}; return ::_unlink(cfg.func.unlink.policy, cfg.branches, diff --git a/src/fuse_utimens.cpp b/src/fuse_utimens.cpp index b383b466..485a14f2 100644 --- a/src/fuse_utimens.cpp +++ b/src/fuse_utimens.cpp @@ -93,8 +93,7 @@ FUSE::utimens(const fuse_req_ctx_t *ctx_, const char *fusepath_, const timespec ts_[2]) { - const fs::path fusepath{fusepath_}; - const ugid::Set ugid(ctx_); + const fs::path fusepath{fusepath_}; return ::_utimens(cfg.func.utimens.policy, cfg.func.getattr.policy, diff --git a/src/mergerfs.cpp b/src/mergerfs.cpp index 207a3bc1..efc11709 100644 --- a/src/mergerfs.cpp +++ b/src/mergerfs.cpp @@ -18,6 +18,8 @@ #include "mergerfs_fsck.hpp" #include "mergerfs_collect_info.hpp" +#include "caps.hpp" + #include "config.hpp" #include "fs_path.hpp" #include "fs_readahead.hpp" diff --git a/src/policy_ff.cpp b/src/policy_ff.cpp index c80d1840..4d0daf54 100644 --- a/src/policy_ff.cpp +++ b/src/policy_ff.cpp @@ -16,6 +16,8 @@ #include "policy_ff.hpp" +#include "ugid.hpp" + #include "errno.hpp" #include "fs_exists.hpp" #include "fs_info.hpp" diff --git a/src/ugid.cpp b/src/ugid.cpp index 81a8ff58..cdf8b33d 100644 --- a/src/ugid.cpp +++ b/src/ugid.cpp @@ -1,33 +1,8 @@ -/* - Copyright (c) 2016, Antonio SJ Musumeci - - Permission to use, copy, modify, and/or distribute this software for any - purpose with or without fee is hereby granted, provided that the above - copyright notice and this permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -*/ - -#include "gidcache.hpp" - -#if defined __linux__ and UGID_USE_RWLOCK == 0 -#include "ugid_linux.icpp" -#else -#include "ugid_rwlock.icpp" -#endif +#include namespace ugid { - void - initgroups(const uid_t uid_, - const gid_t gid_) - { - GIDCache::initgroups(uid_,gid_); - } + thread_local uid_t currentuid = 0; + thread_local gid_t currentgid = 0; + thread_local bool initialized = false; } diff --git a/src/ugid.hpp b/src/ugid.hpp index 8adf47bb..9d42f5f6 100644 --- a/src/ugid.hpp +++ b/src/ugid.hpp @@ -16,21 +16,116 @@ #pragma once +#include "fuse_req_ctx.h" + +#include "fuse_kernel.h" + +#include +#include #include #include +#include +#include + +#include #include +#include "fuse_req_ctx.h" -namespace ugid +#include +#include + +#include + +struct ugid_t { - void init(); - void initgroups(const uid_t uid, const gid_t gid); -} + ugid_t(const uid_t uid_, + const gid_t gid_) + : uid(uid_), + gid(gid_) + { + } + + ugid_t(const fuse_req_ctx_t *ctx_) + : ugid_t(ctx_->uid,ctx_->gid) + { + } + + uid_t uid; + gid_t gid; +}; + +#if defined SYS_setreuid32 +#define SETREUID(R,E) (::syscall(SYS_setreuid32,(R),(E))) +#else +#define SETREUID(R,E) (::syscall(SYS_setreuid,(R),(E))) +#endif + +#if defined SYS_setregid32 +#define SETREGID(R,E) (::syscall(SYS_setregid32,(R),(E))) +#else +#define SETREGID(R,E) (::syscall(SYS_setregid,(R),(E))) +#endif -#if defined __linux__ and UGID_USE_RWLOCK == 0 -#pragma message "using ugid_linux.hpp" -#include "ugid_linux.hpp" +#if defined SYS_geteuid32 +#define GETEUID() (::syscall(SYS_geteuid32)) #else -#pragma message "using ugid_rwlock.hpp" -#include "ugid_rwlock.hpp" +#define GETEUID() (::syscall(SYS_geteuid)) #endif + +#if defined SYS_getegid32 +#define GETEGID() (::syscall(SYS_getegid32)) +#else +#define GETEGID() (::syscall(SYS_getegid)) +#endif + +namespace ugid +{ + extern thread_local uid_t currentuid; + extern thread_local gid_t currentgid; + extern thread_local bool initialized; + + struct Set + { + Set(const uid_t newuid_, + const gid_t newgid_) + { + uid_t newuid; + gid_t newgid; + + newuid = ((newuid_ == FUSE_INVALID_UIDGID) ? 0 : newuid_); + newgid = ((newgid_ == FUSE_INVALID_UIDGID) ? 0 : newgid_); + + if(!initialized) + { + currentuid = GETEUID(); + currentgid = GETEGID(); + initialized = true; + } + + if((newuid == currentuid) && (newgid == currentgid)) + return; + + SETREGID(-1,newgid); + SETREUID(-1,newuid); + + currentuid = newuid; + currentgid = newgid; + } + + Set(const fuse_req_ctx_t *ctx_) + : Set(ctx_->uid,ctx_->gid) + { + } + + Set(const ugid_t ugid_) + : Set(ugid_.uid,ugid_.gid) + { + } + }; +} + +#undef SETREUID +#undef SETREGID +#undef GETEUID +#undef GETEGID diff --git a/src/ugid_linux.hpp b/src/ugid_linux.hpp deleted file mode 100644 index 422904bd..00000000 --- a/src/ugid_linux.hpp +++ /dev/null @@ -1,128 +0,0 @@ -/* - Copyright (c) 2016, Antonio SJ Musumeci - - Permission to use, copy, modify, and/or distribute this software for any - purpose with or without fee is hereby granted, provided that the above - copyright notice and this permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -*/ - -#pragma once - -#include "fuse_req_ctx.h" - -#include -#include -#include -#include -#include - -#include -#include - -#include -#include - -#if defined SYS_setreuid32 -#define SETREUID(R,E) (::syscall(SYS_setreuid32,(R),(E))) -#else -#define SETREUID(R,E) (::syscall(SYS_setreuid,(R),(E))) -#endif - -#if defined SYS_setregid32 -#define SETREGID(R,E) (::syscall(SYS_setregid32,(R),(E))) -#else -#define SETREGID(R,E) (::syscall(SYS_setregid,(R),(E))) -#endif - -#if defined SYS_geteuid32 -#define GETEUID() (::syscall(SYS_geteuid32)) -#else -#define GETEUID() (::syscall(SYS_geteuid)) -#endif - -#if defined SYS_getegid32 -#define GETEGID() (::syscall(SYS_getegid32)) -#else -#define GETEGID() (::syscall(SYS_getegid)) -#endif - -namespace ugid -{ - extern thread_local uid_t currentuid; - extern thread_local gid_t currentgid; - extern thread_local bool initialized; - - struct Set - { - Set(const uid_t newuid_, - const gid_t newgid_) - { - assert((int)newuid_ != -1); - assert((int)newgid_ != -1); - - if(!initialized) - { - currentuid = GETEUID(); - currentgid = GETEGID(); - initialized = true; - } - - if((newuid_ == currentuid) && (newgid_ == currentgid)) - return; - - if(currentuid != 0) - { - SETREUID(-1,0); - SETREGID(-1,0); - } - - if(newgid_) - { - SETREGID(-1,newgid_); - ugid::initgroups(newuid_,newgid_); - } - - if(newuid_) - SETREUID(-1,newuid_); - - currentuid = newuid_; - currentgid = newgid_; - } - - Set(const fuse_req_ctx_t *ctx_) - : Set(ctx_->uid,ctx_->gid) - { - } - }; - - struct SetRootGuard - { - SetRootGuard() : - prevuid(currentuid), - prevgid(currentgid) - { - Set(0,0); - } - - ~SetRootGuard() - { - Set(prevuid,prevgid); - } - - const uid_t prevuid; - const gid_t prevgid; - }; -} - -#undef SETREUID -#undef SETREGID -#undef GETEUID -#undef GETEGID diff --git a/src/ugid_linux.icpp b/src/ugid_linux.icpp deleted file mode 100644 index bd768fe5..00000000 --- a/src/ugid_linux.icpp +++ /dev/null @@ -1,34 +0,0 @@ -/* - Copyright (c) 2016, Antonio SJ Musumeci - - Permission to use, copy, modify, and/or distribute this software for any - purpose with or without fee is hereby granted, provided that the above - copyright notice and this permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -*/ - -#include -#include -#include -#include - -#include - -namespace ugid -{ - thread_local uid_t currentuid = 0; - thread_local gid_t currentgid = 0; - thread_local bool initialized = false; - - void - init() - { - } -} diff --git a/src/ugid_rwlock.hpp b/src/ugid_rwlock.hpp deleted file mode 100644 index d0bf4fc5..00000000 --- a/src/ugid_rwlock.hpp +++ /dev/null @@ -1,106 +0,0 @@ -/* - Copyright (c) 2016, Antonio SJ Musumeci - - Permission to use, copy, modify, and/or distribute this software for any - purpose with or without fee is hereby granted, provided that the above - copyright notice and this permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -*/ - -#pragma once - -#include "fuse_req_ctx.h" - -#include -#include -#include -#include - -namespace ugid -{ - extern uid_t currentuid; - extern gid_t currentgid; - extern pthread_rwlock_t rwlock; - - static - void - ugid_set(const uid_t newuid_, - const gid_t newgid_) - { - pthread_rwlock_rdlock(&rwlock); - - if((newuid_ == currentuid) && (newgid_ == currentgid)) - return; - - pthread_rwlock_unlock(&rwlock); - pthread_rwlock_wrlock(&rwlock); - - if((newuid_ == currentuid) && (newgid_ == currentgid)) - return; - - if(currentuid != 0) - { - ::seteuid(0); - ::setegid(0); - } - - if(newgid_) - { - ::setegid(newgid_); - initgroups(newuid_,newgid_); - } - - if(newuid_) - ::seteuid(newuid_); - - currentuid = newuid_; - currentgid = newgid_; - } - - struct Set - { - Set(const uid_t newuid_, - const gid_t newgid_) - { - ugid_set(newuid_,newgid_); - } - - Set(const fuse_req_ctx_t *ctx_) - : Set(ctx_->uid,ctx_->gid) - { - - } - - ~Set() - { - pthread_rwlock_unlock(&rwlock); - } - }; - - struct SetRootGuard - { - SetRootGuard() : - prevuid(currentuid), - prevgid(currentgid) - { - pthread_rwlock_unlock(&rwlock); - ugid_set(0,0); - } - - ~SetRootGuard() - { - pthread_rwlock_unlock(&rwlock); - ugid_set(prevuid,prevgid); - } - - const uid_t prevuid; - const gid_t prevgid; - }; -} diff --git a/src/ugid_rwlock.icpp b/src/ugid_rwlock.icpp deleted file mode 100644 index 6642102d..00000000 --- a/src/ugid_rwlock.icpp +++ /dev/null @@ -1,45 +0,0 @@ -/* - Copyright (c) 2016, Antonio SJ Musumeci - - Permission to use, copy, modify, and/or distribute this software for any - purpose with or without fee is hereby granted, provided that the above - copyright notice and this permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -*/ - -#include -#include -#include -#include - -#include - -namespace ugid -{ - uid_t currentuid; - gid_t currentgid; - pthread_rwlock_t rwlock; - - void - init() - { - pthread_rwlockattr_t attr; - - pthread_rwlockattr_init(&attr); -# if defined PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP - pthread_rwlockattr_setkind_np(&attr,PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP); -# endif - - pthread_rwlock_init(&rwlock,&attr); - - currentuid = ::geteuid(); - currentgid = ::getegid(); - } -}