make changing credentials opportunistic + per thread setgroups cache

closes #129,#131
This commit is contained in:
Antonio SJ Musumeci 2015-09-08 15:56:02 -04:00
parent b194272e39
commit 3163258a33
31 changed files with 380 additions and 168 deletions

View File

@ -65,6 +65,8 @@ FLOCK = $(shell $(CPPFIND) "fuse_fs_flock")
READ_BUF = $(shell $(CPPFIND) "fuse_fs_read_buf")
WRITE_BUF = $(shell $(CPPFIND) "fuse_fs_write_buf")
UGID_USE_RWLOCK = 0
OPTS = -O2
SRC = $(wildcard src/*.cpp)
OBJ = $(SRC:src/%.cpp=obj/%.o)
@ -74,6 +76,7 @@ MANPAGE = $(TARGET).1
FUSE_CFLAGS = $(shell $(PKGCONFIG) --cflags fuse)
CFLAGS = -g -Wall \
$(OPTS) \
-Wno-unused-result \
$(FUSE_CFLAGS) \
-DFUSE_USE_VERSION=26 \
-MMD \
@ -81,7 +84,8 @@ CFLAGS = -g -Wall \
-DFALLOCATE=$(FALLOCATE) \
-DFLOCK=$(FLOCK) \
-DREAD_BUF=$(READ_BUF) \
-DWRITE_BUF=$(WRITE_BUF)
-DWRITE_BUF=$(WRITE_BUF) \
-DUGID_USE_RWLOCK=$(UGID_USE_RWLOCK)
LDFLAGS = $(shell $(PKGCONFIG) fuse --libs)
PREFIX = /usr/local

View File

@ -74,10 +74,10 @@ namespace mergerfs
access(const char *fusepath,
int mask)
{
const fuse_context *fc = fuse_get_context();
const Config &config = Config::get(fc);
const ugid::SetResetGuard ugid(fc->uid,fc->gid);
const rwlock::ReadGuard readlock(&config.srcmountslock);
const fuse_context *fc = fuse_get_context();
const Config &config = Config::get(fc);
const ugid::Set ugid(fc->uid,fc->gid);
const rwlock::ReadGuard readlock(&config.srcmountslock);
return _access(config.access,
config.srcmounts,

View File

@ -74,10 +74,10 @@ namespace mergerfs
chmod(const char *fusepath,
mode_t mode)
{
const fuse_context *fc = fuse_get_context();
const Config &config = Config::get(fc);
const ugid::SetResetGuard ugid(fc->uid,fc->gid);
const rwlock::ReadGuard readlock(&config.srcmountslock);
const fuse_context *fc = fuse_get_context();
const Config &config = Config::get(fc);
const ugid::Set ugid(fc->uid,fc->gid);
const rwlock::ReadGuard readlock(&config.srcmountslock);
return _chmod(config.chmod,
config.srcmounts,

View File

@ -78,10 +78,10 @@ namespace mergerfs
uid_t uid,
gid_t gid)
{
const fuse_context *fc = fuse_get_context();
const Config &config = Config::get(fc);
const ugid::SetResetGuard ugid(fc->uid,fc->gid);
const rwlock::ReadGuard readlock(&config.srcmountslock);
const fuse_context *fc = fuse_get_context();
const Config &config = Config::get(fc);
const ugid::Set ugid(fc->uid,fc->gid);
const rwlock::ReadGuard readlock(&config.srcmountslock);
return _chown(config.chown,
config.srcmounts,

View File

@ -40,6 +40,7 @@
using std::string;
using std::vector;
using mergerfs::Policy;
using namespace mergerfs;
static
int
@ -69,7 +70,7 @@ _create(Policy::Func::Search searchFunc,
if(createpath[0] != existingpath[0])
{
const mergerfs::ugid::SetResetGuard ugid(0,0);
const ugid::SetRootGuard ugidGuard;
fs::clonepath(existingpath[0],createpath[0],dirname);
}
@ -93,10 +94,10 @@ namespace mergerfs
mode_t mode,
fuse_file_info *fileinfo)
{
const fuse_context *fc = fuse_get_context();
const Config &config = Config::get(fc);
const ugid::SetResetGuard ugid(fc->uid,fc->gid);
const rwlock::ReadGuard readlock(&config.srcmountslock);
const fuse_context *fc = fuse_get_context();
const Config &config = Config::get(fc);
const ugid::Set ugid(fc->uid,fc->gid);
const rwlock::ReadGuard readlock(&config.srcmountslock);
return _create(config.getattr,
config.create,

View File

@ -100,8 +100,8 @@ namespace mergerfs
if(fusepath == config.controlfile)
return _getattr_controlfile(*st);
const ugid::SetResetGuard ugid(fc->uid,fc->gid);
const rwlock::ReadGuard readlock(&config.srcmountslock);
const ugid::Set ugid(fc->uid,fc->gid);
const rwlock::ReadGuard readlock(&config.srcmountslock);
return _getattr(config.getattr,
config.srcmounts,

View File

@ -303,8 +303,8 @@ namespace mergerfs
buf,
count);
const ugid::SetResetGuard ugid(fc->uid,fc->gid);
const rwlock::ReadGuard readlock(&config.srcmountslock);
const ugid::Set ugid(fc->uid,fc->gid);
const rwlock::ReadGuard readlock(&config.srcmountslock);
return _getxattr(config.getxattr,
config.srcmounts,

View File

@ -25,6 +25,7 @@
#include <fuse.h>
#include "config.hpp"
#include "ugid.hpp"
namespace mergerfs
{
@ -33,6 +34,8 @@ namespace mergerfs
void *
init(fuse_conn_info *conn)
{
ugid::init();
#ifdef FUSE_CAP_ASYNC_READ
conn->want |= FUSE_CAP_ASYNC_READ;
#endif

View File

@ -98,10 +98,10 @@ _ioctl_dir(const string &fusepath,
const int cmd,
void *data)
{
const fuse_context *fc = fuse_get_context();
const Config &config = Config::get(fc);
const ugid::SetResetGuard ugid(fc->uid,fc->gid);
const rwlock::ReadGuard readlock(&config.srcmountslock);
const fuse_context *fc = fuse_get_context();
const Config &config = Config::get(fc);
const ugid::Set ugid(fc->uid,fc->gid);
const rwlock::ReadGuard readlock(&config.srcmountslock);
return _ioctl_dir_base(config.getattr,
config.srcmounts,

View File

@ -38,6 +38,7 @@
using std::string;
using std::vector;
using mergerfs::Policy;
using namespace mergerfs;
static
int
@ -64,7 +65,7 @@ _single_link(Policy::Func::Search searchFunc,
return -1;
{
const mergerfs::ugid::SetResetGuard ugid(0,0);
const ugid::SetRootGuard ugidGuard;
fs::clonepath(foundpath[0],base,newpathdir);
}
@ -110,10 +111,10 @@ namespace mergerfs
link(const char *from,
const char *to)
{
const fuse_context *fc = fuse_get_context();
const Config &config = Config::get(fc);
const ugid::SetResetGuard ugid(fc->uid,fc->gid);
const rwlock::ReadGuard readlock(&config.srcmountslock);
const fuse_context *fc = fuse_get_context();
const Config &config = Config::get(fc);
const ugid::Set ugid(fc->uid,fc->gid);
const rwlock::ReadGuard readlock(&config.srcmountslock);
return _link(config.getattr,
config.link,

View File

@ -117,8 +117,8 @@ namespace mergerfs
if(fusepath == config.controlfile)
return _listxattr_controlfile(list,size);
const ugid::SetResetGuard ugid(fc->uid,fc->gid);
const rwlock::ReadGuard readlock(&config.srcmountslock);
const ugid::Set ugid(fc->uid,fc->gid);
const rwlock::ReadGuard readlock(&config.srcmountslock);
return _listxattr(config.listxattr,
config.srcmounts,

View File

@ -39,6 +39,7 @@
using std::string;
using std::vector;
using mergerfs::Policy;
using namespace mergerfs;
static
int
@ -72,7 +73,7 @@ _mkdir(Policy::Func::Search searchFunc,
if(createpath != existingpath[0])
{
const mergerfs::ugid::SetResetGuard ugid(0,0);
const ugid::SetRootGuard ugidGuard;
fs::clonepath(existingpath[0],createpath,dirname);
}
@ -94,10 +95,10 @@ namespace mergerfs
mkdir(const char *fusepath,
mode_t mode)
{
const fuse_context *fc = fuse_get_context();
const Config &config = Config::get(fc);
const ugid::SetResetGuard ugid(fc->uid,fc->gid);
const rwlock::ReadGuard readlock(&config.srcmountslock);
const fuse_context *fc = fuse_get_context();
const Config &config = Config::get(fc);
const ugid::Set ugid(fc->uid,fc->gid);
const rwlock::ReadGuard readlock(&config.srcmountslock);
return _mkdir(config.getattr,
config.mkdir,

View File

@ -40,7 +40,7 @@
using std::string;
using std::vector;
using mergerfs::Policy;
using namespace mergerfs;
static
int
@ -74,7 +74,7 @@ _mknod(Policy::Func::Search searchFunc,
if(createpath != existingpath[0])
{
const mergerfs::ugid::SetResetGuard ugid(0,0);
const ugid::SetRootGuard ugidGuard;
fs::clonepath(existingpath[0],createpath,dirname);
}
@ -97,10 +97,10 @@ namespace mergerfs
mode_t mode,
dev_t rdev)
{
const fuse_context *fc = fuse_get_context();
const Config &config = Config::get(fc);
const ugid::SetResetGuard ugid(fc->uid,fc->gid);
const rwlock::ReadGuard readlock(&config.srcmountslock);
const fuse_context *fc = fuse_get_context();
const Config &config = Config::get(fc);
const ugid::Set ugid(fc->uid,fc->gid);
const rwlock::ReadGuard readlock(&config.srcmountslock);
return _mknod(config.getattr,
config.mknod,

View File

@ -76,10 +76,10 @@ namespace mergerfs
open(const char *fusepath,
fuse_file_info *fileinfo)
{
const fuse_context *fc = fuse_get_context();
const Config &config = Config::get(fc);
const ugid::SetResetGuard ugid(fc->uid,fc->gid);
const rwlock::ReadGuard readlock(&config.srcmountslock);
const fuse_context *fc = fuse_get_context();
const Config &config = Config::get(fc);
const ugid::Set ugid(fc->uid,fc->gid);
const rwlock::ReadGuard readlock(&config.srcmountslock);
return _open(config.open,
config.srcmounts,

View File

@ -96,10 +96,10 @@ namespace mergerfs
off_t offset,
fuse_file_info *fi)
{
const fuse_context *fc = fuse_get_context();
const Config &config = Config::get(fc);
const ugid::SetResetGuard ugid(fc->uid,fc->gid);
const rwlock::ReadGuard readlock(&config.srcmountslock);
const fuse_context *fc = fuse_get_context();
const Config &config = Config::get(fc);
const ugid::Set ugid(fc->uid,fc->gid);
const rwlock::ReadGuard readlock(&config.srcmountslock);
return _readdir(config.srcmounts,
fusepath,

View File

@ -75,10 +75,10 @@ namespace mergerfs
char *buf,
size_t size)
{
const fuse_context *fc = fuse_get_context();
const Config &config = Config::get(fc);
const ugid::SetResetGuard ugid(fc->uid,fc->gid);
const rwlock::ReadGuard readlock(&config.srcmountslock);
const fuse_context *fc = fuse_get_context();
const Config &config = Config::get(fc);
const ugid::Set ugid(fc->uid,fc->gid);
const rwlock::ReadGuard readlock(&config.srcmountslock);
return _readlink(config.readlink,
config.srcmounts,

View File

@ -87,8 +87,8 @@ namespace mergerfs
if(fusepath == config.controlfile)
return -ENOTSUP;
const ugid::SetResetGuard ugid(fc->uid,fc->gid);
const rwlock::ReadGuard readlock(&config.srcmountslock);
const ugid::Set ugid(fc->uid,fc->gid);
const rwlock::ReadGuard readlock(&config.srcmountslock);
return _removexattr(config.removexattr,
config.srcmounts,

View File

@ -130,10 +130,10 @@ namespace mergerfs
rename(const char *oldpath,
const char *newpath)
{
const fuse_context *fc = fuse_get_context();
const Config &config = Config::get(fc);
const ugid::SetResetGuard ugid(fc->uid,fc->gid);
const rwlock::ReadGuard readlock(&config.srcmountslock);
const fuse_context *fc = fuse_get_context();
const Config &config = Config::get(fc);
const ugid::Set ugid(fc->uid,fc->gid);
const rwlock::ReadGuard readlock(&config.srcmountslock);
return _rename(config.getattr,
config.rename,

View File

@ -73,10 +73,10 @@ namespace mergerfs
int
rmdir(const char *fusepath)
{
const fuse_context *fc = fuse_get_context();
const Config &config = Config::get(fc);
const ugid::SetResetGuard ugid(fc->uid,fc->gid);
const rwlock::ReadGuard readguard(&config.srcmountslock);
const fuse_context *fc = fuse_get_context();
const Config &config = Config::get(fc);
const ugid::Set ugid(fc->uid,fc->gid);
const rwlock::ReadGuard readguard(&config.srcmountslock);
return _rmdir(config.rmdir,
config.srcmounts,

View File

@ -323,8 +323,8 @@ namespace mergerfs
flags);
}
const ugid::SetResetGuard ugid(fc->uid,fc->gid);
const rwlock::ReadGuard readlock(&config.srcmountslock);
const ugid::Set ugid(fc->uid,fc->gid);
const rwlock::ReadGuard readlock(&config.srcmountslock);
return _setxattr(config.setxattr,
config.srcmounts,

View File

@ -124,10 +124,10 @@ namespace mergerfs
statfs(const char *fusepath,
struct statvfs *stat)
{
const fuse_context *fc = fuse_get_context();
const Config &config = Config::get(fc);
const ugid::SetResetGuard ugid(fc->uid,fc->gid);
const rwlock::ReadGuard readlock(&config.srcmountslock);
const fuse_context *fc = fuse_get_context();
const Config &config = Config::get(fc);
const ugid::Set ugid(fc->uid,fc->gid);
const rwlock::ReadGuard readlock(&config.srcmountslock);
return _statfs(config.srcmounts,
*stat);

View File

@ -77,10 +77,10 @@ namespace mergerfs
symlink(const char *oldpath,
const char *newpath)
{
const fuse_context *fc = fuse_get_context();
const Config &config = Config::get(fc);
const ugid::SetResetGuard ugid(fc->uid,fc->gid);
const rwlock::ReadGuard readlock(&config.srcmountslock);
const fuse_context *fc = fuse_get_context();
const Config &config = Config::get(fc);
const ugid::Set ugid(fc->uid,fc->gid);
const rwlock::ReadGuard readlock(&config.srcmountslock);
return _symlink(config.symlink,
config.srcmounts,

View File

@ -77,10 +77,10 @@ namespace mergerfs
truncate(const char *fusepath,
off_t size)
{
const fuse_context *fc = fuse_get_context();
const Config &config = Config::get(fc);
const ugid::SetResetGuard ugid(fc->uid,fc->gid);
const rwlock::ReadGuard readlock(&config.srcmountslock);
const fuse_context *fc = fuse_get_context();
const Config &config = Config::get(fc);
const ugid::Set ugid(fc->uid,fc->gid);
const rwlock::ReadGuard readlock(&config.srcmountslock);
return _truncate(config.truncate,
config.srcmounts,

View File

@ -22,10 +22,65 @@
THE SOFTWARE.
*/
#include "ugid.hpp"
#include <stdlib.h>
#include <sys/types.h>
#include <pwd.h>
#include <grp.h>
#include <unistd.h>
#if defined __linux__
#elif defined __APPLE__
#include <vector>
#include <map>
typedef std::vector<gid_t> gid_t_vector;
typedef std::map<uid_t,gid_t_vector> gid_t_cache;
#if defined __linux__ and UGID_USE_RWLOCK == 0
#include "ugid_linux.ipp"
#else
pthread_mutex_t mergerfs::ugid::SetResetGuard::lock = PTHREAD_MUTEX_INITIALIZER;
#include "ugid_rwlock.ipp"
#endif
namespace mergerfs
{
namespace ugid
{
static
inline
void
prime_cache(const uid_t uid,
const gid_t gid,
gid_t_vector &gidlist)
{
int rv;
char buf[4096];
struct passwd pwd;
struct passwd *pwdrv;
rv = getpwuid_r(uid,&pwd,buf,sizeof(buf),&pwdrv);
if(pwdrv != NULL && rv == 0)
{
int count;
count = 0;
rv = ::getgrouplist(pwd.pw_name,gid,NULL,&count);
gidlist.resize(count);
rv = ::getgrouplist(pwd.pw_name,gid,&gidlist[0],&count);
if(rv == -1)
gidlist.resize(1,gid);
}
}
void
initgroups(const uid_t uid,
const gid_t gid)
{
static __thread gid_t_cache cache;
gid_t_vector &gidlist = cache[uid];
if(gidlist.empty())
prime_cache(uid,gid,gidlist);
setgroups(gidlist);
}
}
}

View File

@ -25,12 +25,27 @@
#ifndef __UGID_HPP__
#define __UGID_HPP__
#if defined __linux__
#include <sys/types.h>
#include <unistd.h>
#include <vector>
typedef std::vector<gid_t> gid_t_vector;
namespace mergerfs
{
namespace ugid
{
void init();
void initgroups(const uid_t uid, const gid_t gid);
void setgroups(const gid_t_vector &gidlist);
}
}
#if defined __linux__ and UGID_USE_RWLOCK == 0
#include "ugid_linux.hpp"
#elif defined __APPLE__
#include "ugid_osx.hpp"
#else
#include "ugid_mutex.hpp"
#include "ugid_rwlock.hpp"
#endif
#endif /* __UGID_HPP__ */

View File

@ -27,38 +27,71 @@
#include <unistd.h>
#include <sys/syscall.h>
#include <grp.h>
#include <pwd.h>
#include <map>
#include <vector>
namespace mergerfs
{
namespace ugid
{
struct SetResetGuard
extern __thread uid_t currentuid;
extern __thread gid_t currentgid;
extern __thread bool initialized;
struct Set
{
SetResetGuard(const uid_t _newuid,
const gid_t _newgid)
Set(const uid_t newuid,
const gid_t newgid)
{
olduid = ::syscall(SYS_geteuid);
oldgid = ::syscall(SYS_getegid);
newuid = _newuid;
newgid = _newgid;
if(!initialized)
{
currentuid = ::syscall(SYS_geteuid);
currentgid = ::syscall(SYS_getegid);
initialized = true;
}
if(newgid != oldgid)
::syscall(SYS_setregid,-1,newgid);
if(newuid != olduid)
if(newuid == currentuid && newgid == currentgid)
return;
if(currentuid != 0)
{
::syscall(SYS_setreuid,-1,0);
::syscall(SYS_setregid,-1,0);
}
if(newgid)
{
::syscall(SYS_setregid,-1,newgid);
initgroups(newuid,newgid);
}
if(newuid)
::syscall(SYS_setreuid,-1,newuid);
}
~SetResetGuard()
currentuid = newuid;
currentgid = newgid;
}
};
struct SetRootGuard
{
SetRootGuard() :
prevuid(currentuid),
prevgid(currentgid)
{
if(olduid != newuid)
::syscall(SYS_setreuid,-1,olduid);
if(oldgid != newgid)
::syscall(SYS_setregid,-1,oldgid);
Set(0,0);
}
uid_t olduid;
gid_t oldgid;
uid_t newuid;
gid_t newgid;
~SetRootGuard()
{
Set(prevuid,prevgid);
}
const uid_t prevuid;
const gid_t prevgid;
};
}
}

View File

@ -22,36 +22,32 @@
THE SOFTWARE.
*/
#include <stdlib.h>
#include <sys/types.h>
#include <sys/unistd.h>
#include <unistd.h>
#include <sys/syscall.h>
#include <vector>
typedef std::vector<gid_t> gid_t_vector;
namespace mergerfs
{
namespace ugid
{
struct SetResetGuard
__thread uid_t currentuid = 0;
__thread gid_t currentgid = 0;
__thread bool initialized = false;
void
init()
{
SetResetGuard(const uid_t _newuid,
const gid_t _newgid)
{
pthread_getugid_np(&olduid,&oldgid);
newuid = _newuid;
newgid = _newgid;
}
if(newgid != oldgid || newuid != olduid)
pthread_setugid_np(newuid,newgid);
}
~SetResetGuard()
{
if(newgid != oldgid || newuid != olduid)
pthread_setugid_np(newuid,newgid);
}
uid_t olduid;
gid_t oldgid;
uid_t newuid;
gid_t newgid;
};
int
setgroups(const gid_t_vector &gidlist)
{
return ::syscall(SYS_setgroups,gidlist.size(),&gidlist[0]);
}
}
}

107
src/ugid_rwlock.hpp Normal file
View File

@ -0,0 +1,107 @@
/*
The MIT License (MIT)
Copyright (c) 2014 Antonio SJ Musumeci <trapexit@spawn.link>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <pthread.h>
namespace mergerfs
{
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()
{
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;
};
}
}

View File

@ -22,47 +22,43 @@
THE SOFTWARE.
*/
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <pthread.h>
#include <vector>
typedef std::vector<gid_t> gid_t_vector;
namespace mergerfs
{
namespace ugid
{
struct SetResetGuard
uid_t currentuid;
gid_t currentgid;
pthread_rwlock_t rwlock;
void
init()
{
SetResetGuard(const uid_t _newuid,
const gid_t _newgid)
{
pthread_mutex_lock(&lock);
pthread_rwlockattr_t attr;
olduid = ::geteuid();
oldgid = ::getegid();
newuid = _newuid;
newgid = _newgid;
pthread_rwlockattr_init(&attr);
# if defined PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP
pthread_rwlockattr_setkind_np(&attr,PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP);
# endif
if(newgid != oldgid)
setegid(newgid);
if(newuid != olduid)
seteuid(newuid);
}
pthread_rwlock_init(&rwlock,&attr);
~SetResetGuard()
{
if(olduid != newuid)
seteuid(newuid);
if(oldgid != newgid)
setegid(newgid);
}
currentuid = ::geteuid();
currentgid = ::getegid();
}
uid_t olduid;
gid_t oldgid;
uid_t newuid;
gid_t newgid;
static pthread_mutex_t lock;
};
int
setgroups(const gid_t_vector &gidlist)
{
return ::setgroups(gidlist.size(),&gidlist[0]);
}
}
}

View File

@ -74,10 +74,10 @@ namespace mergerfs
int
unlink(const char *fusepath)
{
const fuse_context *fc = fuse_get_context();
const Config &config = Config::get(fc);
const ugid::SetResetGuard ugid(fc->uid,fc->gid);
const rwlock::ReadGuard readlock(&config.srcmountslock);
const fuse_context *fc = fuse_get_context();
const Config &config = Config::get(fc);
const ugid::Set ugid(fc->uid,fc->gid);
const rwlock::ReadGuard readlock(&config.srcmountslock);
return _unlink(config.unlink,
config.srcmounts,

View File

@ -77,10 +77,10 @@ namespace mergerfs
utimens(const char *fusepath,
const timespec ts[2])
{
const fuse_context *fc = fuse_get_context();
const Config &config = Config::get(fc);
const ugid::SetResetGuard ugid(fc->uid,fc->gid);
const rwlock::ReadGuard readlock(&config.srcmountslock);
const fuse_context *fc = fuse_get_context();
const Config &config = Config::get(fc);
const ugid::Set ugid(fc->uid,fc->gid);
const rwlock::ReadGuard readlock(&config.srcmountslock);
return _utimens(config.utimens,
config.srcmounts,