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");