<commit_before>/*********************************************************************
*  @author <NAME>
*  @copyright (C): 2013 ACK CYFRONET AGH
*  This software is released under the MIT license
*  cited in 'LICENSE.txt'.
*********************************************************************/

#include "term_translator.h"

#include "helpers/IStorageHelper.h"
#include "helpers/storageHelperFactory.h"

#include <erl_nif.h>
#include <fuse.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/fsuid.h>
#include <pwd.h>
#include <grp.h>

#include <cstring>
#include <memory>
#include <vector>

#define BADARG enif_make_badarg(env)
#define INIT    if(!check_common_args(env, argc, argv)) \
                    return BADARG; \
                auto sh = SHFactory.getStorageHelper(get_string(env, argv[2]), get_args(env, argv[3])); \
                if(!sh) \
                    return enif_make_tuple2(env, enif_make_atom(env, "error"), enif_make_atom(env, "unknown_storage_helper")); \
                UserCTX holder(get_string(env, argv[0]), get_string(env, argv[1])); \
                if(holder.uid() == (uid_t)-1 || holder.gid() == (gid_t)-1) \
                    return enif_make_int(env, -EINVAL);

using namespace veil::cluster;
using namespace veil::helpers;

namespace veil
{
namespace cluster
{

/// RAII FS user UID/GID holder class
class UserCTX
{
public:
    UserCTX(uid_t uid, gid_t gid)
    {
        initCTX(uid, gid);
    }

    UserCTX(std::string uname, std::string gname)
    {
        initCTX(uname, gname);
    }

    ~UserCTX()
    {
        setfsuid(0);
        setfsgid(0);
    }

    uid_t uid()
    {
        return m_uid;
    }

    gid_t gid()
    {
       return m_gid;
    }

private:
    uid_t   m_uid;
    gid_t   m_gid;

    void initCTX(uid_t uid, gid_t gid)
    {
        m_uid = uid;
        m_gid = gid;

        if(uid != 0) {
            seteuid(-1);
            setegid(-1);
        }

        setfsuid(m_uid);
        setfsgid(m_gid);
    }

    void initCTX(std::string uname, std::string gname)
    {
         struct passwd *ownerInfo = getpwnam(uname.c_str()); // Static buffer, do NOT free !
         struct group  *groupInfo = getgrnam(gname.c_str()); // Static buffer, do NOT free !

         uid_t uid = (ownerInfo ? ownerInfo->pw_uid : -1);
         gid_t primary_gid = (ownerInfo ? ownerInfo->pw_gid : -1);
         gid_t gid = (groupInfo ? groupInfo->gr_gid : primary_gid);

         initCTX(uid, gid);
    }

};<commit_msg>fix user effective uid/gid setup & remove all secondary groups<commit_after>/*********************************************************************
*  @author <NAME>
*  @copyright (C): 2013 ACK CYFRONET AGH
*  This software is released under the MIT license
*  cited in 'LICENSE.txt'.
*********************************************************************/

#include "term_translator.h"

#include "helpers/IStorageHelper.h"
#include "helpers/storageHelperFactory.h"

#include <erl_nif.h>
#include <fuse.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/fsuid.h>
#include <pwd.h>
#include <grp.h>

#include <cstring>
#include <memory>
#include <vector>

#define BADARG enif_make_badarg(env)
#define INIT    if(!check_common_args(env, argc, argv)) \
                    return BADARG; \
                auto sh = SHFactory.getStorageHelper(get_string(env, argv[2]), get_args(env, argv[3])); \
                if(!sh) \
                    return enif_make_tuple2(env, enif_make_atom(env, "error"), enif_make_atom(env, "unknown_storage_helper")); \
                UserCTX holder(get_string(env, argv[0]), get_string(env, argv[1])); \
                if(holder.uid() == (uid_t)-1 || holder.gid() == (gid_t)-1) \
                    return enif_make_int(env, -EINVAL);

using namespace veil::cluster;
using namespace veil::helpers;

namespace veil
{
namespace cluster
{

/// RAII FS user UID/GID holder class
class UserCTX
{
public:
    UserCTX(uid_t uid, gid_t gid)
    {
        initCTX(uid, gid);
    }

    UserCTX(std::string uname, std::string gname)
    {
        initCTX(uname, gname);
    }

    ~UserCTX()
    {
        setfsuid(0);
        setfsgid(0);
    }

    uid_t uid()
    {
        return m_uid;
    }

    gid_t gid()
    {
       return m_gid;
    }

private:
    uid_t   m_uid;
    gid_t   m_gid;

    void initCTX(uid_t uid, gid_t gid)
    {
        m_uid = uid;
        m_gid = gid;

        if(uid != 0) {
            setgroups(0, NULL);
            setegid(-1);
            seteuid(-1);
        }

        setfsuid(m_uid);
        setfsgid(m_gid);
    }

    void initCTX(std::string uname, std::string gname)
    {
         struct passwd *ownerInfo = getpwnam(uname.c_str()); // Static buffer, do NOT free !
         struct group  *groupInfo = getgrnam(gname.c_str()); // Static buffer, do NOT free !

         uid_t uid = (ownerInfo ? ownerInfo->pw_uid : -1);
         gid_t primary_gid = (ownerInfo ? ownerInfo->pw_gid : -1);
         gid_t gid = (groupInfo ? groupInfo->gr_gid : primary_gid);

         initCTX(uid, gid);
    }

};
{'fraction_non_alphanumeric': 0.18242579123255356, 'fraction_numerical': 0.007273442107332416, 'mean_word_length': 2.525987525987526, 'pattern_counts': {'":': 0, '<': 27, '<?xml version=': 0, '>': 33, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6874824', 'n_tokens_mistral': 1838, 'n_tokens_neox': 1744, 'n_words': 380}