diff --git a/src/create.cpp b/src/create.cpp index 76586a535..3b35bf45d 100644 --- a/src/create.cpp +++ b/src/create.cpp @@ -22,6 +22,7 @@ #include "config.hpp" #include "errno.hpp" #include "fileinfo.hpp" +#include "fs_acl.hpp" #include "fs_base_open.hpp" #include "fs_clonepath.hpp" #include "fs_path.hpp" @@ -30,9 +31,22 @@ using std::string; using std::vector; -using mergerfs::Policy; using namespace mergerfs; +static +inline +int +_create_core(const string &fullpath, + mode_t mode, + const mode_t umask, + const int flags) +{ + if(!fs::acl::dir_has_defaults(fullpath)) + mode &= ~umask; + + return fs::open(fullpath,flags,mode); +} + static int _create_core(const string &existingpath, @@ -40,6 +54,7 @@ _create_core(const string &existingpath, const char *fusepath, const char *fusedirpath, const mode_t mode, + const mode_t umask, const int flags, uint64_t &fh) { @@ -56,7 +71,7 @@ _create_core(const string &existingpath, fs::path::make(&createpath,fusepath,fullpath); - rv = fs::open(fullpath,flags,mode); + rv = _create_core(fullpath,mode,umask,flags); if(rv == -1) return -errno; @@ -73,6 +88,7 @@ _create(Policy::Func::Search searchFunc, const uint64_t minfreespace, const char *fusepath, const mode_t mode, + const mode_t umask, const int flags, uint64_t &fh) { @@ -97,7 +113,7 @@ _create(Policy::Func::Search searchFunc, return _create_core(*existingpaths[0],*createpaths[0], fusepath,fusedirpathcstr, - mode,flags,fh); + mode,umask,flags,fh); } namespace mergerfs @@ -119,7 +135,8 @@ namespace mergerfs config.srcmounts, config.minfreespace, fusepath, - (mode & ~fc->umask), + mode, + fc->umask, ffi->flags, ffi->fh); } diff --git a/src/fs_acl.cpp b/src/fs_acl.cpp new file mode 100644 index 000000000..65b40bb25 --- /dev/null +++ b/src/fs_acl.cpp @@ -0,0 +1,43 @@ +/* + ISC License + + 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 "fs_base_getxattr.hpp" +#include "fs_path.hpp" + +const char POSIX_ACL_DEFAULT_XATTR[] = "system.posix_acl_default"; + +namespace fs +{ + namespace acl + { + bool + dir_has_defaults(const std::string &fullpath) + { + int rv; + std::string dirpath = fullpath; + + fs::path::dirname(dirpath); + + rv = fs::lgetxattr(dirpath,POSIX_ACL_DEFAULT_XATTR,NULL,0); + + return (rv != -1); + } + } +} diff --git a/src/fs_acl.hpp b/src/fs_acl.hpp new file mode 100644 index 000000000..d0a43174e --- /dev/null +++ b/src/fs_acl.hpp @@ -0,0 +1,28 @@ +/* + ISC License + + 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 + +namespace fs +{ + namespace acl + { + bool + dir_has_defaults(const std::string &fullpath); + } +} diff --git a/src/init.cpp b/src/init.cpp index c110315f8..e030308ee 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -28,6 +28,7 @@ namespace mergerfs { ugid::init(); + conn->want |= FUSE_CAP_DONT_MASK; #ifdef FUSE_CAP_IOCTL_DIR conn->want |= FUSE_CAP_IOCTL_DIR; #endif diff --git a/src/mkdir.cpp b/src/mkdir.cpp index 83b380818..819da15d0 100644 --- a/src/mkdir.cpp +++ b/src/mkdir.cpp @@ -21,6 +21,7 @@ #include "config.hpp" #include "errno.hpp" +#include "fs_acl.hpp" #include "fs_base_mkdir.hpp" #include "fs_clonepath.hpp" #include "fs_path.hpp" @@ -30,9 +31,21 @@ using std::string; using std::vector; -using mergerfs::Policy; using namespace mergerfs; +static +inline +int +_mkdir_core(const string &fullpath, + mode_t mode, + const mode_t umask) +{ + if(!fs::acl::dir_has_defaults(fullpath)) + mode &= ~umask; + + return fs::mkdir(fullpath,mode); +} + static int _mkdir_loop_core(const string &existingpath, @@ -40,6 +53,7 @@ _mkdir_loop_core(const string &existingpath, const char *fusepath, const char *fusedirpath, const mode_t mode, + const mode_t umask, const int error) { int rv; @@ -55,7 +69,7 @@ _mkdir_loop_core(const string &existingpath, fs::path::make(&createpath,fusepath,fullpath); - rv = fs::mkdir(fullpath,mode); + rv = _mkdir_core(fullpath,mode,umask); return calc_error(rv,error,errno); } @@ -66,7 +80,8 @@ _mkdir_loop(const string &existingpath, const vector &createpaths, const char *fusepath, const char *fusedirpath, - const mode_t mode) + const mode_t mode, + const mode_t umask) { int error; @@ -74,7 +89,7 @@ _mkdir_loop(const string &existingpath, for(size_t i = 0, ei = createpaths.size(); i != ei; i++) { error = _mkdir_loop_core(existingpath,*createpaths[i], - fusepath,fusedirpath,mode,error); + fusepath,fusedirpath,mode,umask,error); } return -error; @@ -87,7 +102,8 @@ _mkdir(Policy::Func::Search searchFunc, const vector &srcmounts, const uint64_t minfreespace, const char *fusepath, - const mode_t mode) + const mode_t mode, + const mode_t umask) { int rv; string fusedirpath; @@ -108,7 +124,7 @@ _mkdir(Policy::Func::Search searchFunc, return -errno; return _mkdir_loop(*existingpaths[0],createpaths, - fusepath,fusedirpathcstr,mode); + fusepath,fusedirpathcstr,mode,umask); } namespace mergerfs @@ -129,7 +145,8 @@ namespace mergerfs config.srcmounts, config.minfreespace, fusepath, - (mode & ~fc->umask)); + mode, + fc->umask); } } } diff --git a/src/mknod.cpp b/src/mknod.cpp index 4b31954a9..db14e980b 100644 --- a/src/mknod.cpp +++ b/src/mknod.cpp @@ -21,6 +21,7 @@ #include "config.hpp" #include "errno.hpp" +#include "fs_acl.hpp" #include "fs_base_mknod.hpp" #include "fs_clonepath.hpp" #include "fs_path.hpp" @@ -32,6 +33,20 @@ using std::string; using std::vector; using namespace mergerfs; +static +inline +int +_mknod_core(const string &fullpath, + mode_t mode, + const mode_t umask, + const dev_t dev) +{ + if(!fs::acl::dir_has_defaults(fullpath)) + mode &= ~umask; + + return fs::mknod(fullpath,mode,dev); +} + static int _mknod_loop_core(const string &existingpath, @@ -39,6 +54,7 @@ _mknod_loop_core(const string &existingpath, const char *fusepath, const char *fusedirpath, const mode_t mode, + const mode_t umask, const dev_t dev, const int error) { @@ -55,7 +71,7 @@ _mknod_loop_core(const string &existingpath, fs::path::make(&createpath,fusepath,fullpath); - rv = fs::mknod(fullpath,mode,dev); + rv = _mknod_core(fullpath,mode,umask,dev); return calc_error(rv,error,errno); } @@ -67,6 +83,7 @@ _mknod_loop(const string &existingpath, const char *fusepath, const char *fusedirpath, const mode_t mode, + const mode_t umask, const dev_t dev) { int error; @@ -76,7 +93,7 @@ _mknod_loop(const string &existingpath, { error = _mknod_loop_core(existingpath,*createpaths[i], fusepath,fusedirpath, - mode,dev,error); + mode,umask,dev,error); } return -error; @@ -90,6 +107,7 @@ _mknod(Policy::Func::Search searchFunc, const uint64_t minfreespace, const char *fusepath, const mode_t mode, + const mode_t umask, const dev_t dev) { int rv; @@ -112,7 +130,7 @@ _mknod(Policy::Func::Search searchFunc, return _mknod_loop(*existingpaths[0],createpaths, fusepath,fusedirpathcstr, - mode,dev); + mode,umask,dev); } namespace mergerfs @@ -134,7 +152,8 @@ namespace mergerfs config.srcmounts, config.minfreespace, fusepath, - (mode & ~fc->umask), + mode, + fc->umask, rdev); } }