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

@ -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);
}
}
}