36 #ifdef NFD_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();
47 #ifdef NFD_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 group* grResult =
nullptr;
69 int errorCode = getgrnam_r(groupName.data(), &gr, groupBuffer.data(), groupBuffer.size(), &grResult);
71 while (errorCode == ERANGE) {
72 if (groupBuffer.size() * 2 > MAX_GROUP_BUFFER_SIZE)
73 throw Error(
"Cannot allocate large enough buffer for struct group");
75 groupBuffer.resize(groupBuffer.size() * 2);
76 errorCode = getgrnam_r(groupName.data(), &gr, groupBuffer.data(), groupBuffer.size(), &grResult);
79 if (errorCode != 0 || !grResult)
80 throw Error(
"Failed to get gid for \"" + groupName +
"\"");
82 s_normalGid = gr.gr_gid;
85 if (!userName.empty()) {
86 static long passwdSize = ::sysconf(_SC_GETPW_R_SIZE_MAX);
89 passwdSize = FALLBACK_PASSWD_BUFFER_SIZE;
91 std::vector<char> passwdBuffer(
static_cast<size_t>(passwdSize));
93 passwd* pwResult =
nullptr;
95 int errorCode = getpwnam_r(userName.data(), &pw, passwdBuffer.data(), passwdBuffer.size(), &pwResult);
97 while (errorCode == ERANGE) {
98 if (passwdBuffer.size() * 2 > MAX_PASSWD_BUFFER_SIZE)
99 throw Error(
"Cannot allocate large enough buffer for struct passwd");
101 passwdBuffer.resize(passwdBuffer.size() * 2);
102 errorCode = getpwnam_r(userName.data(), &pw, passwdBuffer.data(), passwdBuffer.size(), &pwResult);
105 if (errorCode != 0 || !pwResult)
106 throw Error(
"Failed to get uid for \"" + userName +
"\"");
108 s_normalUid = pw.pw_uid;
111 if (!userName.empty() || !groupName.empty()) {
112 throw Error(
"Dropping and raising privileges is not supported on this platform");
120 #ifdef NFD_HAVE_PRIVILEGE_DROP_AND_ELEVATE
121 if (::geteuid() == s_normalUid && ::getegid() == s_normalGid)
125 if (::setegid(s_normalGid) != 0)
126 throw Error(
"Failed to drop to effective gid=" + std::to_string(s_normalGid));
129 if (::seteuid(s_normalUid) != 0)
130 throw Error(
"Failed to drop to effective uid=" + std::to_string(s_normalUid));
132 NFD_LOG_INFO(
"dropped to effective uid=" << ::geteuid() <<
" gid=" << ::getegid());
134 NFD_LOG_WARN(
"Dropping privileges is not supported on this platform");
139 PrivilegeHelper::raise()
141 #ifdef NFD_HAVE_PRIVILEGE_DROP_AND_ELEVATE
142 if (::geteuid() == s_privilegedUid && ::getegid() == s_privilegedGid)
145 NFD_LOG_TRACE(
"elevating to effective uid=" << s_privilegedUid);
146 if (::seteuid(s_privilegedUid) != 0)
147 throw Error(
"Failed to elevate to effective uid=" + std::to_string(s_privilegedUid));
149 NFD_LOG_TRACE(
"elevating to effective gid=" << s_privilegedGid);
150 if (::setegid(s_privilegedGid) != 0)
151 throw Error(
"Failed to elevate to effective gid=" + std::to_string(s_privilegedGid));
153 NFD_LOG_INFO(
"elevated to effective uid=" << ::geteuid() <<
" gid=" << ::getegid());
155 NFD_LOG_WARN(
"Elevating privileges is not supported on this platform");
Indicates a serious seteuid/setegid failure.
static void initialize(const std::string &userName, const std::string &groupName)
#define NFD_LOG_INIT(name)