36 #ifdef HAVE_PRIVILEGE_DROP_AND_ELEVATE
37 uid_t PrivilegeHelper::s_normalUid = ::geteuid();
38 gid_t PrivilegeHelper::s_normalGid = ::getegid();
40 uid_t PrivilegeHelper::s_privilegedUid = ::geteuid();
41 gid_t PrivilegeHelper::s_privilegedGid = ::getegid();
42 #endif // HAVE_PRIVILEGE_DROP_AND_ELEVATE
47 #ifdef HAVE_PRIVILEGE_DROP_AND_ELEVATE
48 static const size_t MAX_GROUP_BUFFER_SIZE = 16384;
49 static const size_t MAX_PASSWD_BUFFER_SIZE = 16384;
51 static const size_t FALLBACK_GROUP_BUFFER_SIZE = 1024;
52 static const size_t FALLBACK_PASSWD_BUFFER_SIZE = 1024;
55 <<
" group \"" << groupName <<
"\"");
59 if (!groupName.empty()) {
60 static long groupSize = ::sysconf(_SC_GETGR_R_SIZE_MAX);
63 groupSize = FALLBACK_GROUP_BUFFER_SIZE;
65 std::vector<char> groupBuffer(
static_cast<size_t>(groupSize));
67 struct group* groupResult =
nullptr;
69 int errorCode = getgrnam_r(groupName.data(), &group,
70 groupBuffer.data(), groupBuffer.size(), &groupResult);
72 while (errorCode == ERANGE) {
73 if (groupBuffer.size() * 2 > MAX_GROUP_BUFFER_SIZE)
74 throw Error(
"Cannot allocate large enough buffer for struct group");
76 groupBuffer.resize(groupBuffer.size() * 2);
77 errorCode = getgrnam_r(groupName.data(), &group,
78 groupBuffer.data(), groupBuffer.size(), &groupResult);
81 if (errorCode != 0 || !groupResult)
82 throw Error(
"Failed to get gid for \"" + groupName +
"\"");
84 s_normalGid = group.gr_gid;
87 if (!userName.empty()) {
88 static long passwdSize = ::sysconf(_SC_GETPW_R_SIZE_MAX);
91 passwdSize = FALLBACK_PASSWD_BUFFER_SIZE;
93 std::vector<char> passwdBuffer(
static_cast<size_t>(passwdSize));
95 struct passwd* passwdResult =
nullptr;
97 int errorCode = getpwnam_r(userName.data(), &passwd,
98 passwdBuffer.data(), passwdBuffer.size(), &passwdResult);
100 while (errorCode == ERANGE) {
101 if (passwdBuffer.size() * 2 > MAX_PASSWD_BUFFER_SIZE)
102 throw Error(
"Cannot allocate large enough buffer for struct passwd");
104 passwdBuffer.resize(passwdBuffer.size() * 2);
105 errorCode = getpwnam_r(userName.data(), &passwd,
106 passwdBuffer.data(), passwdBuffer.size(), &passwdResult);
109 if (errorCode != 0 || !passwdResult)
110 throw Error(
"Failed to get uid for \"" + userName +
"\"");
112 s_normalUid = passwd.pw_uid;
115 if (!userName.empty() || !groupName.empty()) {
116 throw Error(
"Dropping and raising privileges is not supported on this platform");
118 #endif // HAVE_PRIVILEGE_DROP_AND_ELEVATE
124 #ifdef HAVE_PRIVILEGE_DROP_AND_ELEVATE
125 if (::geteuid() == s_normalUid && ::getegid() == s_normalGid)
129 if (::setegid(s_normalGid) != 0)
130 throw Error(
"Failed to drop to effective gid=" +
to_string(s_normalGid));
133 if (::seteuid(s_normalUid) != 0)
134 throw Error(
"Failed to drop to effective uid=" +
to_string(s_normalUid));
136 NFD_LOG_INFO(
"dropped to effective uid=" << ::geteuid() <<
" gid=" << ::getegid());
138 NFD_LOG_WARN(
"Dropping privileges is not supported on this platform");
139 #endif // HAVE_PRIVILEGE_DROP_AND_ELEVATE
143 PrivilegeHelper::raise()
145 #ifdef HAVE_PRIVILEGE_DROP_AND_ELEVATE
146 if (::geteuid() == s_privilegedUid && ::getegid() == s_privilegedGid)
149 NFD_LOG_TRACE(
"elevating to effective uid=" << s_privilegedUid);
150 if (::seteuid(s_privilegedUid) != 0)
151 throw Error(
"Failed to elevate to effective uid=" +
to_string(s_privilegedUid));
153 NFD_LOG_TRACE(
"elevating to effective gid=" << s_privilegedGid);
154 if (::setegid(s_privilegedGid) != 0)
155 throw Error(
"Failed to elevate to effective gid=" +
to_string(s_privilegedGid));
157 NFD_LOG_INFO(
"elevated to effective uid=" << ::geteuid() <<
" gid=" << ::getegid());
159 NFD_LOG_WARN(
"Elevating privileges is not supported on this platform");
160 #endif // HAVE_PRIVILEGE_DROP_AND_ELEVATE