diff --git a/src/chown.cpp b/src/chown.cpp index 2c5ff821..2c15ffc1 100644 --- a/src/chown.cpp +++ b/src/chown.cpp @@ -101,9 +101,6 @@ namespace mergerfs const ugid::Set ugid(fc->uid,fc->gid); const rwlock::ReadGuard readlock(&config.srcmountslock); - if(config.cifs) - return 0; - return _chown(config.chown, config.srcmounts, config.minfreespace, diff --git a/src/config.cpp b/src/config.cpp index 4247beee..e0c3de3e 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -40,7 +40,6 @@ namespace mergerfs minfreespace(MINFREESPACE_DEFAULT), moveonenospc(false), direct_io(false), - cifs(false), POLICYINIT(access), POLICYINIT(chmod), POLICYINIT(chown), diff --git a/src/config.hpp b/src/config.hpp index 5aaa025a..0ec36d04 100644 --- a/src/config.hpp +++ b/src/config.hpp @@ -48,7 +48,6 @@ namespace mergerfs uint64_t minfreespace; bool moveonenospc; bool direct_io; - bool cifs; public: const Policy *policies[FuseFunc::Enum::END]; diff --git a/src/fs_base_chmod.hpp b/src/fs_base_chmod.hpp index 39692d2f..2334def1 100644 --- a/src/fs_base_chmod.hpp +++ b/src/fs_base_chmod.hpp @@ -21,6 +21,10 @@ #include +#include "fs_base_stat.hpp" + +#define MODE_BITS (S_ISUID|S_ISGID|S_ISVTX|S_IRWXU|S_IRWXG|S_IRWXO) + namespace fs { static @@ -49,6 +53,58 @@ namespace fs { return ::fchmod(fd,st.st_mode); } + + static + inline + int + chmod_check_on_error(const std::string &path, + const mode_t mode) + { + int rv; + + rv = fs::chmod(path,mode); + if(rv == -1) + { + int error; + struct stat st; + + error = errno; + rv = fs::stat(path,st); + if(rv == -1) + return -1; + + if((st.st_mode & MODE_BITS) != (mode & MODE_BITS)) + return (errno=error,-1); + } + + return 0; + } + + static + inline + int + fchmod_check_on_error(const int fd, + const struct stat &st) + { + int rv; + + rv = fs::fchmod(fd,st); + if(rv == -1) + { + int error; + struct stat tmpst; + + error = errno; + rv = fs::fstat(fd,tmpst); + if(rv == -1) + return -1; + + if((st.st_mode & MODE_BITS) != (tmpst.st_mode & MODE_BITS)) + return (errno=error,-1); + } + + return 0; + } } #endif diff --git a/src/fs_base_chown.hpp b/src/fs_base_chown.hpp index 47b01741..a17fb60b 100644 --- a/src/fs_base_chown.hpp +++ b/src/fs_base_chown.hpp @@ -25,6 +25,8 @@ #include #include +#include "fs_base_stat.hpp" + namespace fs { static @@ -56,6 +58,15 @@ namespace fs return ::lchown(path.c_str(),uid,gid); } + static + inline + int + lchown(const std::string &path, + const struct stat &st) + { + return fs::lchown(path,st.st_uid,st.st_gid); + } + static inline int @@ -74,6 +85,60 @@ namespace fs { return fs::fchown(fd,st.st_uid,st.st_gid); } + + static + inline + int + lchown_check_on_error(const std::string &path, + const struct stat &st) + { + int rv; + + rv = fs::lchown(path,st); + if(rv == -1) + { + int error; + struct stat tmpst; + + error = errno; + rv = fs::lstat(path,tmpst); + if(rv == -1) + return -1; + + if((st.st_uid != tmpst.st_uid) || + (st.st_gid != tmpst.st_gid)) + return (errno=error,-1); + } + + return 0; + } + + static + inline + int + fchown_check_on_error(const int fd, + const struct stat &st) + { + int rv; + + rv = fs::fchown(fd,st); + if(rv == -1) + { + int error; + struct stat tmpst; + + error = errno; + rv = fs::fstat(fd,tmpst); + if(rv == -1) + return -1; + + if((st.st_uid != tmpst.st_uid) || + (st.st_gid != tmpst.st_gid)) + return (errno=error,-1); + } + + return 0; + } } #endif diff --git a/src/fs_clonefile.cpp b/src/fs_clonefile.cpp index a933536e..826790b9 100644 --- a/src/fs_clonefile.cpp +++ b/src/fs_clonefile.cpp @@ -176,11 +176,11 @@ namespace fs if((rv == -1) && !ignorable_error(errno)) return -1; - rv = fs::fchown(fdout,stin); + rv = fs::fchown_check_on_error(fdout,stin); if(rv == -1) return -1; - rv = fs::fchmod(fdout,stin); + rv = fs::fchmod_check_on_error(fdout,stin); if(rv == -1) return -1; diff --git a/src/fs_clonepath.cpp b/src/fs_clonepath.cpp index 6f3cb082..f4fb32ce 100644 --- a/src/fs_clonepath.cpp +++ b/src/fs_clonepath.cpp @@ -26,10 +26,8 @@ #include "fs_clonepath.hpp" #include "fs_path.hpp" #include "fs_xattr.hpp" -#include "config.hpp" using std::string; -using mergerfs::Config; static bool @@ -61,9 +59,6 @@ namespace fs string frompath; string dirname; - const fuse_context *fc = fuse_get_context(); - const Config &config = Config::get(fc); - dirname = relative; fs::path::dirname(dirname); if(!dirname.empty()) @@ -87,7 +82,7 @@ namespace fs if(errno != EEXIST) return -1; - rv = fs::chmod(topath,st.st_mode); + rv = fs::chmod_check_on_error(topath,st.st_mode); if(rv == -1) return -1; } @@ -101,11 +96,9 @@ namespace fs if((rv == -1) && !ignorable_error(errno)) return -1; - if(!config.cifs) { - rv = fs::chown(topath,st); - if(rv == -1) - return -1; - } + rv = fs::lchown_check_on_error(topath,st); + if(rv == -1) + return -1; rv = fs::utime(topath,st); if(rv == -1) diff --git a/src/option_parser.cpp b/src/option_parser.cpp index a586e326..0ad72880 100644 --- a/src/option_parser.cpp +++ b/src/option_parser.cpp @@ -143,8 +143,6 @@ parse_and_process_arg(Config &config, return (set_default_options(*outargs),0); else if(arg == "direct_io") return (config.direct_io=true,1); - else if(arg == "cifs") - return (config.cifs=true,0); return 1; } @@ -262,8 +260,6 @@ usage(void) " on write: default false\n" " -o func.=

set function to policy

\n" " -o category.=

set functions in category to

\n" - " -o cifs disable chown command execution as CIFS\n" - " don't support it\n" << std::endl; }