mirror of
https://github.com/trapexit/mergerfs.git
synced 2025-03-14 09:55:12 +08:00
stop clonepath at base directory. fixes #467
This commit is contained in:
parent
62ae871d51
commit
f48c16d162
@ -34,7 +34,6 @@ using std::vector;
|
||||
using namespace mergerfs;
|
||||
|
||||
static
|
||||
inline
|
||||
int
|
||||
_create_core(const string &fullpath,
|
||||
mode_t mode,
|
||||
@ -49,10 +48,8 @@ _create_core(const string &fullpath,
|
||||
|
||||
static
|
||||
int
|
||||
_create_core(const string &existingpath,
|
||||
const string &createpath,
|
||||
_create_core(const string &createpath,
|
||||
const char *fusepath,
|
||||
const char *fusedirpath,
|
||||
const mode_t mode,
|
||||
const mode_t umask,
|
||||
const int flags,
|
||||
@ -61,14 +58,6 @@ _create_core(const string &existingpath,
|
||||
int rv;
|
||||
string fullpath;
|
||||
|
||||
if(createpath != existingpath)
|
||||
{
|
||||
const ugid::SetRootGuard ugidGuard;
|
||||
rv = fs::clonepath(existingpath,createpath,fusedirpath);
|
||||
if(rv == -1)
|
||||
return -errno;
|
||||
}
|
||||
|
||||
fs::path::make(&createpath,fusepath,fullpath);
|
||||
|
||||
rv = _create_core(fullpath,mode,umask,flags);
|
||||
@ -111,8 +100,12 @@ _create(Policy::Func::Search searchFunc,
|
||||
if(rv == -1)
|
||||
return -errno;
|
||||
|
||||
return _create_core(*existingpaths[0],*createpaths[0],
|
||||
fusepath,fusedirpathcstr,
|
||||
rv = fs::clonepath_as_root(*existingpaths[0],*createpaths[0],fusedirpath);
|
||||
if(rv == -1)
|
||||
return -errno;
|
||||
|
||||
return _create_core(*createpaths[0],
|
||||
fusepath,
|
||||
mode,umask,flags,fh);
|
||||
}
|
||||
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include "fs_clonepath.hpp"
|
||||
#include "fs_path.hpp"
|
||||
#include "fs_xattr.hpp"
|
||||
#include "ugid.hpp"
|
||||
|
||||
using std::string;
|
||||
|
||||
@ -59,6 +60,9 @@ namespace fs
|
||||
string frompath;
|
||||
string dirname;
|
||||
|
||||
if((relative == NULL) || (relative[0] == '\0'))
|
||||
return 0;
|
||||
|
||||
dirname = relative;
|
||||
fs::path::dirname(dirname);
|
||||
if(!dirname.empty())
|
||||
@ -114,4 +118,29 @@ namespace fs
|
||||
{
|
||||
return fs::clonepath(from,to,relative.c_str());
|
||||
}
|
||||
|
||||
int
|
||||
clonepath_as_root(const string &from,
|
||||
const string &to,
|
||||
const char *relative)
|
||||
{
|
||||
if((relative == NULL) || (relative[0] == '\0'))
|
||||
return 0;
|
||||
if(from == to)
|
||||
return 0;
|
||||
|
||||
{
|
||||
const ugid::SetRootGuard ugidGuard;
|
||||
|
||||
return fs::clonepath(from,to,relative);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
clonepath_as_root(const std::string &from,
|
||||
const std::string &to,
|
||||
const std::string &relative)
|
||||
{
|
||||
return fs::clonepath_as_root(from,to,relative.c_str());
|
||||
}
|
||||
}
|
||||
|
@ -26,4 +26,11 @@ namespace fs
|
||||
int clonepath(const std::string &from,
|
||||
const std::string &to,
|
||||
const std::string &relative);
|
||||
|
||||
int clonepath_as_root(const std::string &from,
|
||||
const std::string &to,
|
||||
const char *relative);
|
||||
int clonepath_as_root(const std::string &from,
|
||||
const std::string &to,
|
||||
const std::string &relative);
|
||||
}
|
||||
|
24
src/link.cpp
24
src/link.cpp
@ -39,21 +39,12 @@ _link_create_path_core(const string &oldbasepath,
|
||||
const string &newbasepath,
|
||||
const char *oldfusepath,
|
||||
const char *newfusepath,
|
||||
const string &newfusedirpath,
|
||||
const int error)
|
||||
{
|
||||
int rv;
|
||||
string oldfullpath;
|
||||
string newfullpath;
|
||||
|
||||
if(oldbasepath != newbasepath)
|
||||
{
|
||||
const ugid::SetRootGuard ugidGuard;
|
||||
rv = fs::clonepath(newbasepath,oldbasepath,newfusedirpath);
|
||||
if(rv == -1)
|
||||
return errno;
|
||||
}
|
||||
|
||||
fs::path::make(&oldbasepath,oldfusepath,oldfullpath);
|
||||
fs::path::make(&oldbasepath,newfusepath,newfullpath);
|
||||
|
||||
@ -70,15 +61,19 @@ _link_create_path_loop(const vector<const string*> &oldbasepaths,
|
||||
const char *newfusepath,
|
||||
const string &newfusedirpath)
|
||||
{
|
||||
int rv;
|
||||
int error;
|
||||
|
||||
error = -1;
|
||||
for(size_t i = 0, ei = oldbasepaths.size(); i != ei; i++)
|
||||
{
|
||||
error = _link_create_path_core(*oldbasepaths[i],newbasepath,
|
||||
oldfusepath,newfusepath,
|
||||
newfusedirpath,
|
||||
error);
|
||||
rv = fs::clonepath_as_root(newbasepath,*oldbasepaths[i],newfusedirpath);
|
||||
if(rv == -1)
|
||||
error = error::calc(rv,error,errno);
|
||||
else
|
||||
error = _link_create_path_core(*oldbasepaths[i],newbasepath,
|
||||
oldfusepath,newfusepath,
|
||||
error);
|
||||
}
|
||||
|
||||
return -error;
|
||||
@ -143,8 +138,7 @@ _clonepath_if_would_create(Policy::Func::Search searchFunc,
|
||||
if(rv == -1)
|
||||
return -1;
|
||||
|
||||
const ugid::SetRootGuard ugidGuard;
|
||||
return fs::clonepath(*newbasepath[0],oldbasepath,newfusedirpathcstr);
|
||||
return fs::clonepath_as_root(*newbasepath[0],oldbasepath,newfusedirpathcstr);
|
||||
}
|
||||
|
||||
static
|
||||
|
@ -34,7 +34,6 @@ using std::vector;
|
||||
using namespace mergerfs;
|
||||
|
||||
static
|
||||
inline
|
||||
int
|
||||
_mkdir_core(const string &fullpath,
|
||||
mode_t mode,
|
||||
@ -48,10 +47,8 @@ _mkdir_core(const string &fullpath,
|
||||
|
||||
static
|
||||
int
|
||||
_mkdir_loop_core(const string &existingpath,
|
||||
const string &createpath,
|
||||
_mkdir_loop_core(const string &createpath,
|
||||
const char *fusepath,
|
||||
const char *fusedirpath,
|
||||
const mode_t mode,
|
||||
const mode_t umask,
|
||||
const int error)
|
||||
@ -59,14 +56,6 @@ _mkdir_loop_core(const string &existingpath,
|
||||
int rv;
|
||||
string fullpath;
|
||||
|
||||
if(createpath != existingpath)
|
||||
{
|
||||
const ugid::SetRootGuard ugidGuard;
|
||||
rv = fs::clonepath(existingpath,createpath,fusedirpath);
|
||||
if(rv == -1)
|
||||
return errno;
|
||||
}
|
||||
|
||||
fs::path::make(&createpath,fusepath,fullpath);
|
||||
|
||||
rv = _mkdir_core(fullpath,mode,umask);
|
||||
@ -83,13 +72,19 @@ _mkdir_loop(const string &existingpath,
|
||||
const mode_t mode,
|
||||
const mode_t umask)
|
||||
{
|
||||
int rv;
|
||||
int error;
|
||||
|
||||
error = -1;
|
||||
for(size_t i = 0, ei = createpaths.size(); i != ei; i++)
|
||||
{
|
||||
error = _mkdir_loop_core(existingpath,*createpaths[i],
|
||||
fusepath,fusedirpath,mode,umask,error);
|
||||
rv = fs::clonepath_as_root(existingpath,*createpaths[i],fusedirpath);
|
||||
if(rv == -1)
|
||||
error = error::calc(rv,error,errno);
|
||||
else
|
||||
error = _mkdir_loop_core(*createpaths[i],
|
||||
fusepath,
|
||||
mode,umask,error);
|
||||
}
|
||||
|
||||
return -error;
|
||||
|
@ -49,10 +49,8 @@ _mknod_core(const string &fullpath,
|
||||
|
||||
static
|
||||
int
|
||||
_mknod_loop_core(const string &existingpath,
|
||||
const string &createpath,
|
||||
_mknod_loop_core(const string &createpath,
|
||||
const char *fusepath,
|
||||
const char *fusedirpath,
|
||||
const mode_t mode,
|
||||
const mode_t umask,
|
||||
const dev_t dev,
|
||||
@ -61,14 +59,6 @@ _mknod_loop_core(const string &existingpath,
|
||||
int rv;
|
||||
string fullpath;
|
||||
|
||||
if(createpath != existingpath)
|
||||
{
|
||||
const ugid::SetRootGuard ugidGuard;
|
||||
rv = fs::clonepath(existingpath,createpath,fusedirpath);
|
||||
if(rv == -1)
|
||||
return -1;
|
||||
}
|
||||
|
||||
fs::path::make(&createpath,fusepath,fullpath);
|
||||
|
||||
rv = _mknod_core(fullpath,mode,umask,dev);
|
||||
@ -86,14 +76,19 @@ _mknod_loop(const string &existingpath,
|
||||
const mode_t umask,
|
||||
const dev_t dev)
|
||||
{
|
||||
int rv;
|
||||
int error;
|
||||
|
||||
error = -1;
|
||||
for(size_t i = 0, ei = createpaths.size(); i != ei; i++)
|
||||
{
|
||||
error = _mknod_loop_core(existingpath,*createpaths[i],
|
||||
fusepath,fusedirpath,
|
||||
mode,umask,dev,error);
|
||||
rv = fs::clonepath_as_root(existingpath,*createpaths[i],fusedirpath);
|
||||
if(rv == -1)
|
||||
error = error::calc(rv,error,errno);
|
||||
else
|
||||
error = _mknod_loop_core(*createpaths[i],
|
||||
fusepath,
|
||||
mode,umask,dev,error);
|
||||
}
|
||||
|
||||
return -error;
|
||||
|
@ -27,7 +27,6 @@
|
||||
#include "fs_path.hpp"
|
||||
#include "rv.hpp"
|
||||
#include "rwlock.hpp"
|
||||
#include "success_fail.hpp"
|
||||
#include "ugid.hpp"
|
||||
|
||||
using std::string;
|
||||
@ -57,27 +56,6 @@ _remove(const vector<string> &toremove)
|
||||
fs::remove(toremove[i]);
|
||||
}
|
||||
|
||||
static
|
||||
int
|
||||
_rename(const std::string &oldbasepath,
|
||||
const std::string &oldfullpath,
|
||||
const std::string &newbasepath,
|
||||
const std::string &newfusedirpath,
|
||||
const std::string &newfullpath)
|
||||
{
|
||||
int rv;
|
||||
|
||||
if(oldbasepath != newbasepath)
|
||||
{
|
||||
const ugid::SetRootGuard guard;
|
||||
rv = fs::clonepath(newbasepath,oldbasepath,newfusedirpath);
|
||||
if(rv == -1)
|
||||
return -1;
|
||||
}
|
||||
|
||||
return fs::rename(oldfullpath,newfullpath);
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
_rename_create_path_core(const vector<const string*> &oldbasepaths,
|
||||
@ -94,21 +72,26 @@ _rename_create_path_core(const vector<const string*> &oldbasepaths,
|
||||
string oldfullpath;
|
||||
string newfullpath;
|
||||
|
||||
fs::path::make(&oldbasepath,newfusepath,newfullpath);
|
||||
|
||||
ismember = member(oldbasepaths,oldbasepath);
|
||||
if(ismember)
|
||||
{
|
||||
fs::path::make(&oldbasepath,oldfusepath,oldfullpath);
|
||||
rv = fs::clonepath_as_root(newbasepath,oldbasepath,newfusedirpath);
|
||||
if(rv != -1)
|
||||
{
|
||||
fs::path::make(&oldbasepath,oldfusepath,oldfullpath);
|
||||
fs::path::make(&oldbasepath,newfusepath,newfullpath);
|
||||
|
||||
rv = fs::rename(oldfullpath,newfullpath);
|
||||
}
|
||||
|
||||
rv = _rename(oldbasepath,oldfullpath,
|
||||
newbasepath,newfusedirpath,newfullpath);
|
||||
error = error::calc(rv,error,errno);
|
||||
if(RENAME_FAILED(rv))
|
||||
if(rv == -1)
|
||||
tounlink.push_back(oldfullpath);
|
||||
}
|
||||
else
|
||||
{
|
||||
fs::path::make(&oldbasepath,newfusepath,newfullpath);
|
||||
|
||||
tounlink.push_back(newfullpath);
|
||||
}
|
||||
}
|
||||
@ -138,7 +121,7 @@ _rename_create_path(Policy::Func::Search searchFunc,
|
||||
if(POLICY_FAILED(rv))
|
||||
return -errno;
|
||||
|
||||
error = RENAME_FAIL;
|
||||
error = -1;
|
||||
for(size_t i = 0, ei = srcmounts.size(); i != ei; i++)
|
||||
{
|
||||
const string &oldbasepath = srcmounts[i];
|
||||
@ -150,7 +133,8 @@ _rename_create_path(Policy::Func::Search searchFunc,
|
||||
error,toremove);
|
||||
}
|
||||
|
||||
if(RENAME_SUCCEEDED(error))
|
||||
|
||||
if(error == 0)
|
||||
_remove(toremove);
|
||||
|
||||
return -error;
|
||||
@ -169,12 +153,9 @@ _clonepath(Policy::Func::Search searchFunc,
|
||||
|
||||
rv = searchFunc(srcmounts,fusedirpath.c_str(),minfreespace,srcbasepath);
|
||||
if(POLICY_FAILED(rv))
|
||||
return rv;
|
||||
return -errno;
|
||||
|
||||
{
|
||||
const ugid::SetRootGuard ugidGuard;
|
||||
fs::clonepath(*srcbasepath[0],dstbasepath,fusedirpath);
|
||||
}
|
||||
fs::clonepath_as_root(*srcbasepath[0],dstbasepath,fusedirpath);
|
||||
|
||||
return POLICY_SUCCESS;
|
||||
}
|
||||
@ -232,7 +213,7 @@ _rename_preserve_path_core(Policy::Func::Search searchFunc,
|
||||
fs::path::make(&oldbasepath,oldfusepath,oldfullpath);
|
||||
|
||||
rv = fs::rename(oldfullpath,newfullpath);
|
||||
if(RENAME_FAILED_WITH(rv,ENOENT))
|
||||
if((rv == -1) && (errno == ENOENT))
|
||||
{
|
||||
rv = _clonepath_if_would_create(searchFunc,createFunc,
|
||||
srcmounts,minfreespace,
|
||||
@ -242,7 +223,7 @@ _rename_preserve_path_core(Policy::Func::Search searchFunc,
|
||||
}
|
||||
|
||||
error = error::calc(rv,error,errno);
|
||||
if(RENAME_FAILED(rv))
|
||||
if(rv == -1)
|
||||
toremove.push_back(oldfullpath);
|
||||
}
|
||||
else
|
||||
@ -270,7 +251,7 @@ _rename_preserve_path(Policy::Func::Search searchFunc,
|
||||
if(POLICY_FAILED(rv))
|
||||
return -errno;
|
||||
|
||||
error = RENAME_FAIL;
|
||||
error = -1;
|
||||
for(size_t i = 0, ei = srcmounts.size(); i != ei; i++)
|
||||
{
|
||||
const string &oldbasepath = srcmounts[i];
|
||||
@ -282,7 +263,7 @@ _rename_preserve_path(Policy::Func::Search searchFunc,
|
||||
error,toremove);
|
||||
}
|
||||
|
||||
if(RENAME_SUCCEEDED(error))
|
||||
if(error == 0)
|
||||
_remove(toremove);
|
||||
|
||||
return -error;
|
||||
|
@ -36,24 +36,14 @@ using namespace mergerfs;
|
||||
|
||||
static
|
||||
int
|
||||
_symlink_loop_core(const string &existingpath,
|
||||
const string &newbasepath,
|
||||
_symlink_loop_core(const string &newbasepath,
|
||||
const char *oldpath,
|
||||
const char *newpath,
|
||||
const char *newdirpath,
|
||||
const int error)
|
||||
{
|
||||
int rv;
|
||||
string fullnewpath;
|
||||
|
||||
if(newbasepath != existingpath)
|
||||
{
|
||||
const ugid::SetRootGuard ugidGuard;
|
||||
rv = fs::clonepath(existingpath,newbasepath,newdirpath);
|
||||
if(rv == -1)
|
||||
return -1;
|
||||
}
|
||||
|
||||
fs::path::make(&newbasepath,newpath,fullnewpath);
|
||||
|
||||
rv = fs::symlink(oldpath,fullnewpath);
|
||||
@ -69,14 +59,20 @@ _symlink_loop(const string &existingpath,
|
||||
const char *newpath,
|
||||
const char *newdirpath)
|
||||
{
|
||||
int rv;
|
||||
int error;
|
||||
|
||||
error = -1;
|
||||
for(size_t i = 0, ei = newbasepaths.size(); i != ei; i++)
|
||||
{
|
||||
error = _symlink_loop_core(existingpath,*newbasepaths[i],
|
||||
oldpath,newpath,newdirpath,
|
||||
error);
|
||||
rv = fs::clonepath_as_root(existingpath,*newbasepaths[i],newdirpath);
|
||||
if(rv == -1)
|
||||
error = error::calc(rv,error,errno);
|
||||
else
|
||||
error = _symlink_loop_core(*newbasepaths[i],
|
||||
oldpath,
|
||||
newpath,
|
||||
error);
|
||||
}
|
||||
|
||||
return -error;
|
||||
|
15
src/ugid.cpp
15
src/ugid.cpp
@ -22,17 +22,14 @@
|
||||
#include "ugid_rwlock.icpp"
|
||||
#endif
|
||||
|
||||
namespace mergerfs
|
||||
namespace ugid
|
||||
{
|
||||
namespace ugid
|
||||
void
|
||||
initgroups(const uid_t uid,
|
||||
const gid_t gid)
|
||||
{
|
||||
void
|
||||
initgroups(const uid_t uid,
|
||||
const gid_t gid)
|
||||
{
|
||||
static __thread gid_t_cache cache = {0};
|
||||
static __thread gid_t_cache cache = {0};
|
||||
|
||||
cache.initgroups(uid,gid);
|
||||
}
|
||||
cache.initgroups(uid,gid);
|
||||
}
|
||||
}
|
||||
|
@ -21,13 +21,10 @@
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace mergerfs
|
||||
namespace ugid
|
||||
{
|
||||
namespace ugid
|
||||
{
|
||||
void init();
|
||||
void initgroups(const uid_t uid, const gid_t gid);
|
||||
}
|
||||
void init();
|
||||
void initgroups(const uid_t uid, const gid_t gid);
|
||||
}
|
||||
|
||||
#if defined __linux__ and UGID_USE_RWLOCK == 0
|
||||
|
@ -51,68 +51,64 @@
|
||||
#define GETEGID() (::syscall(SYS_getegid))
|
||||
#endif
|
||||
|
||||
|
||||
namespace mergerfs
|
||||
namespace ugid
|
||||
{
|
||||
namespace ugid
|
||||
extern __thread uid_t currentuid;
|
||||
extern __thread gid_t currentgid;
|
||||
extern __thread bool initialized;
|
||||
|
||||
struct Set
|
||||
{
|
||||
extern __thread uid_t currentuid;
|
||||
extern __thread gid_t currentgid;
|
||||
extern __thread bool initialized;
|
||||
|
||||
struct Set
|
||||
Set(const uid_t newuid,
|
||||
const gid_t newgid)
|
||||
{
|
||||
Set(const uid_t newuid,
|
||||
const gid_t newgid)
|
||||
{
|
||||
if(!initialized)
|
||||
{
|
||||
currentuid = GETEUID();
|
||||
currentgid = GETEGID();
|
||||
initialized = true;
|
||||
}
|
||||
if(!initialized)
|
||||
{
|
||||
currentuid = GETEUID();
|
||||
currentgid = GETEGID();
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
if(newuid == currentuid && newgid == currentgid)
|
||||
return;
|
||||
if(newuid == currentuid && newgid == currentgid)
|
||||
return;
|
||||
|
||||
if(currentuid != 0)
|
||||
{
|
||||
SETREUID(-1,0);
|
||||
SETREGID(-1,0);
|
||||
}
|
||||
if(currentuid != 0)
|
||||
{
|
||||
SETREUID(-1,0);
|
||||
SETREGID(-1,0);
|
||||
}
|
||||
|
||||
if(newgid)
|
||||
{
|
||||
SETREGID(-1,newgid);
|
||||
initgroups(newuid,newgid);
|
||||
}
|
||||
if(newgid)
|
||||
{
|
||||
SETREGID(-1,newgid);
|
||||
initgroups(newuid,newgid);
|
||||
}
|
||||
|
||||
if(newuid)
|
||||
SETREUID(-1,newuid);
|
||||
if(newuid)
|
||||
SETREUID(-1,newuid);
|
||||
|
||||
currentuid = newuid;
|
||||
currentgid = newgid;
|
||||
}
|
||||
};
|
||||
currentuid = newuid;
|
||||
currentgid = newgid;
|
||||
}
|
||||
};
|
||||
|
||||
struct SetRootGuard
|
||||
struct SetRootGuard
|
||||
{
|
||||
SetRootGuard() :
|
||||
prevuid(currentuid),
|
||||
prevgid(currentgid)
|
||||
{
|
||||
SetRootGuard() :
|
||||
prevuid(currentuid),
|
||||
prevgid(currentgid)
|
||||
{
|
||||
Set(0,0);
|
||||
}
|
||||
Set(0,0);
|
||||
}
|
||||
|
||||
~SetRootGuard()
|
||||
{
|
||||
Set(prevuid,prevgid);
|
||||
}
|
||||
~SetRootGuard()
|
||||
{
|
||||
Set(prevuid,prevgid);
|
||||
}
|
||||
|
||||
const uid_t prevuid;
|
||||
const gid_t prevgid;
|
||||
};
|
||||
}
|
||||
const uid_t prevuid;
|
||||
const gid_t prevgid;
|
||||
};
|
||||
}
|
||||
|
||||
#undef SETREUID
|
||||
|
@ -21,17 +21,14 @@
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace mergerfs
|
||||
namespace ugid
|
||||
{
|
||||
namespace ugid
|
||||
{
|
||||
__thread uid_t currentuid = 0;
|
||||
__thread gid_t currentgid = 0;
|
||||
__thread bool initialized = false;
|
||||
__thread uid_t currentuid = 0;
|
||||
__thread gid_t currentgid = 0;
|
||||
__thread bool initialized = false;
|
||||
|
||||
void
|
||||
init()
|
||||
{
|
||||
}
|
||||
void
|
||||
init()
|
||||
{
|
||||
}
|
||||
}
|
||||
|
@ -21,81 +21,78 @@
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
||||
namespace mergerfs
|
||||
namespace ugid
|
||||
{
|
||||
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)
|
||||
{
|
||||
extern uid_t currentuid;
|
||||
extern gid_t currentgid;
|
||||
extern pthread_rwlock_t rwlock;
|
||||
pthread_rwlock_rdlock(&rwlock);
|
||||
|
||||
static
|
||||
void
|
||||
ugid_set(const uid_t newuid,
|
||||
const gid_t newgid)
|
||||
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)
|
||||
{
|
||||
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;
|
||||
ugid_set(newuid,newgid);
|
||||
}
|
||||
|
||||
struct Set
|
||||
~Set()
|
||||
{
|
||||
Set(const uid_t newuid,
|
||||
const gid_t newgid)
|
||||
{
|
||||
ugid_set(newuid,newgid);
|
||||
}
|
||||
pthread_rwlock_unlock(&rwlock);
|
||||
}
|
||||
};
|
||||
|
||||
~Set()
|
||||
{
|
||||
pthread_rwlock_unlock(&rwlock);
|
||||
}
|
||||
};
|
||||
|
||||
struct SetRootGuard
|
||||
struct SetRootGuard
|
||||
{
|
||||
SetRootGuard() :
|
||||
prevuid(currentuid),
|
||||
prevgid(currentgid)
|
||||
{
|
||||
SetRootGuard() :
|
||||
prevuid(currentuid),
|
||||
prevgid(currentgid)
|
||||
{
|
||||
pthread_rwlock_unlock(&rwlock);
|
||||
ugid_set(0,0);
|
||||
}
|
||||
pthread_rwlock_unlock(&rwlock);
|
||||
ugid_set(0,0);
|
||||
}
|
||||
|
||||
~SetRootGuard()
|
||||
{
|
||||
pthread_rwlock_unlock(&rwlock);
|
||||
ugid_set(prevuid,prevgid);
|
||||
}
|
||||
~SetRootGuard()
|
||||
{
|
||||
pthread_rwlock_unlock(&rwlock);
|
||||
ugid_set(prevuid,prevgid);
|
||||
}
|
||||
|
||||
const uid_t prevuid;
|
||||
const gid_t prevgid;
|
||||
};
|
||||
}
|
||||
const uid_t prevuid;
|
||||
const gid_t prevgid;
|
||||
};
|
||||
}
|
||||
|
@ -21,28 +21,25 @@
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace mergerfs
|
||||
namespace ugid
|
||||
{
|
||||
namespace ugid
|
||||
uid_t currentuid;
|
||||
gid_t currentgid;
|
||||
pthread_rwlock_t rwlock;
|
||||
|
||||
void
|
||||
init()
|
||||
{
|
||||
uid_t currentuid;
|
||||
gid_t currentgid;
|
||||
pthread_rwlock_t rwlock;
|
||||
pthread_rwlockattr_t attr;
|
||||
|
||||
void
|
||||
init()
|
||||
{
|
||||
pthread_rwlockattr_t attr;
|
||||
|
||||
pthread_rwlockattr_init(&attr);
|
||||
pthread_rwlockattr_init(&attr);
|
||||
# if defined PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP
|
||||
pthread_rwlockattr_setkind_np(&attr,PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP);
|
||||
pthread_rwlockattr_setkind_np(&attr,PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP);
|
||||
# endif
|
||||
|
||||
pthread_rwlock_init(&rwlock,&attr);
|
||||
pthread_rwlock_init(&rwlock,&attr);
|
||||
|
||||
currentuid = ::geteuid();
|
||||
currentgid = ::getegid();
|
||||
}
|
||||
currentuid = ::geteuid();
|
||||
currentgid = ::getegid();
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user