35 uid_t PrivilegeHelper::s_normalUid = ::geteuid();
36 gid_t PrivilegeHelper::s_normalGid = ::getegid();
38 uid_t PrivilegeHelper::s_privilegedUid = ::geteuid();
39 gid_t PrivilegeHelper::s_privilegedGid = ::getegid();
44 static const size_t MAX_GROUP_BUFFER_SIZE = 16384;
45 static const size_t MAX_PASSWD_BUFFER_SIZE = 16384;
47 static const size_t FALLBACK_GROUP_BUFFER_SIZE = 1024;
48 static const size_t FALLBACK_PASSWD_BUFFER_SIZE = 1024;
50 NFD_LOG_TRACE(
"initializing privilege helper with user \"" << userName <<
"\""
51 <<
" group \"" << groupName <<
"\"");
55 if (!groupName.empty())
57 static int groupSize = ::sysconf(_SC_GETGR_R_SIZE_MAX);
61 groupSize = FALLBACK_GROUP_BUFFER_SIZE;
64 std::vector<char> groupBuffer(groupSize);
66 struct group* groupResult = 0;
68 int errorCode = getgrnam_r(groupName.c_str(), &group,
69 &groupBuffer[0], groupSize, &groupResult);
71 while (errorCode == ERANGE)
73 if (groupBuffer.size() * 2 > MAX_GROUP_BUFFER_SIZE)
78 groupBuffer.resize(groupBuffer.size() * 2);
80 errorCode = getgrnam_r(groupName.c_str(), &group,
81 &groupBuffer[0], groupBuffer.size(), &groupResult);
84 if (errorCode != 0 || !groupResult)
89 s_normalGid = group.gr_gid;
92 if (!userName.empty())
94 static int passwdSize = ::sysconf(_SC_GETPW_R_SIZE_MAX);
98 passwdSize = FALLBACK_PASSWD_BUFFER_SIZE;
101 std::vector<char> passwdBuffer(passwdSize);
102 struct passwd passwd;
103 struct passwd* passwdResult = 0;
106 getpwnam_r(userName.c_str(), &passwd,
107 &passwdBuffer[0], passwdBuffer.size(), &passwdResult);
109 while (errorCode == ERANGE)
111 if (passwdBuffer.size() * 2 > MAX_PASSWD_BUFFER_SIZE)
116 passwdBuffer.resize(passwdBuffer.size() * 2);
118 errorCode = getpwnam_r(userName.c_str(), &passwd,
119 &passwdBuffer[0], passwdBuffer.size(), &passwdResult);
122 if (errorCode != 0 || !passwdResult)
127 s_normalUid = passwd.pw_uid;
135 if (::setegid(s_normalGid) != 0)
137 std::stringstream error;
138 error <<
"Failed to drop to effective gid=" << s_normalGid;
144 if (::seteuid(s_normalUid) != 0)
146 std::stringstream error;
147 error <<
"Failed to drop to effective uid=" << s_normalUid;
152 NFD_LOG_INFO(
"dropped to effective uid=" << ::geteuid() <<
" gid=" << ::getegid());
156 PrivilegeHelper::raise()
158 NFD_LOG_TRACE(
"elevating to effective uid=" << s_privilegedUid);
159 if (::seteuid(s_privilegedUid) != 0)
161 std::stringstream error;
162 error <<
"Failed to elevate to effective uid=" << s_privilegedUid;
167 NFD_LOG_TRACE(
"elevating to effective gid=" << s_privilegedGid);
168 if (::setegid(s_privilegedGid) != 0)
170 std::stringstream error;
171 error <<
"Failed to elevate to effective gid=" << s_privilegedGid;
173 throw PrivilegeHelper::Error(error.str());
175 NFD_LOG_INFO(
"elevated to effective uid=" << ::geteuid() <<
" gid=" << ::getegid());
static void runElevated(function< void()> f)
PrivilegeHelper::Error represents a serious seteuid/gid failure and should only be caught by main in ...
#define NFD_LOG_INFO(expression)
static void initialize(const std::string &userName, const std::string &groupName)
#define NFD_LOG_INIT(name)
#define NFD_LOG_TRACE(expression)