diff options
Diffstat (limited to 'cpp/src')
-rw-r--r-- | cpp/src/Ice/Instance.cpp | 32 | ||||
-rw-r--r-- | cpp/src/IceGrid/Activator.cpp | 64 | ||||
-rw-r--r-- | cpp/src/IceGrid/ServerI.cpp | 17 |
3 files changed, 75 insertions, 38 deletions
diff --git a/cpp/src/Ice/Instance.cpp b/cpp/src/Ice/Instance.cpp index 936bf3cca2f..e94781b3cf1 100644 --- a/cpp/src/Ice/Instance.cpp +++ b/cpp/src/Ice/Instance.cpp @@ -1021,21 +1021,25 @@ IceInternal::Instance::Instance(const CommunicatorPtr& communicator, const Initi string newUser = _initData.properties->getProperty("Ice.ChangeUser"); if(!newUser.empty()) { - errno = 0; - struct passwd* pw = getpwnam(newUser.c_str()); - if(!pw) + struct passwd pwbuf; + vector<char> buffer(4096); // 4KB initial buffer + struct passwd *pw; + int err = getpwnam_r(newUser.c_str(), &pwbuf, &buffer[0], buffer.size(), &pw); + while(err == ERANGE && buffer.size() < 1024 * 1024) // Limit buffer to 1MB { - if(errno) - { - SyscallException ex(__FILE__, __LINE__); - ex.error = getSystemErrno(); - throw ex; - } - else - { - InitializationException ex(__FILE__, __LINE__, "Unknown user account `" + newUser + "'"); - throw ex; - } + buffer.resize(buffer.size() * 2); + } + if(err != 0) + { + Ice::SyscallException ex(__FILE__, __LINE__); + ex.error = err; + throw ex; + } + else if(pw == 0) + { + InitializationException ex(__FILE__, __LINE__); + ex.reason ="unknown user account `" + newUser + "'"; + throw ex; } if(setgid(pw->pw_gid) == -1) diff --git a/cpp/src/IceGrid/Activator.cpp b/cpp/src/IceGrid/Activator.cpp index 01e9e4a8703..e13f3ef48c9 100644 --- a/cpp/src/IceGrid/Activator.cpp +++ b/cpp/src/IceGrid/Activator.cpp @@ -38,7 +38,7 @@ #endif #if defined(__linux) || defined(__sun) || defined(_AIX) || defined(__GLIBC__) -# include <grp.h> // for initgroups +# include <grp.h> // for setgroups #endif using namespace std; @@ -631,6 +631,44 @@ Activator::activate(const string& name, return static_cast<Ice::Int>(process.pid); #else + struct passwd pwbuf; + vector<char> buffer(4096); // 4KB initial buffer size + struct passwd *pw; + int err = getpwuid_r(uid, &pwbuf, &buffer[0], buffer.size(), &pw); + while(err == ERANGE && buffer.size() < 1024 * 1024) // Limit buffer to 1MB + { + buffer.resize(buffer.size() * 2); + } + if(err != 0) + { + SyscallException ex(__FILE__, __LINE__); + ex.error = err; + throw ex; + } + else if(pw == 0) + { + ostringstream os; + os << uid; + throw string("unknown user id `" + os.str() + "'"); + } + + vector<gid_t> groups; + groups.resize(20); + int ngroups = static_cast<int>(groups.size()); +#if defined(__APPLE__) + if(getgrouplist(pw->pw_name, gid, reinterpret_cast<int*>(&groups[0]), &ngroups) < 0) +#else + if(getgrouplist(pw->pw_name, gid, &groups[0], &ngroups) < 0) +#endif + { + groups.resize(ngroups); +#if defined(__APPLE__) + getgrouplist(pw->pw_name, gid, reinterpret_cast<int*>(&groups[0]), &ngroups); +#else + getgrouplist(pw->pw_name, gid, &groups[0], &ngroups); +#endif + } + int fds[2]; if(pipe(fds) != 0) { @@ -694,33 +732,15 @@ Activator::activate(const string& name, _traceLevels); } - errno = 0; - struct passwd* pw = getpwuid(uid); - if(!pw) - { - if(errno) - { - reportChildError(getSystemErrno(), errorFds[1], "cannot read the password database", "", - _traceLevels); - } - else - { - ostringstream os; - os << uid; - reportChildError(getSystemErrno(), errorFds[1], "unknown user uid" , os.str().c_str(), - _traceLevels); - } - } - // // Don't initialize supplementary groups if we are not running as root. // - if(getuid() == 0 && initgroups(pw->pw_name, gid) == -1) + if(getuid() == 0 && setgroups(groups.size(), &groups[0]) == -1) { ostringstream os; os << pw->pw_name; - reportChildError(getSystemErrno(), errorFds[1], "cannot initialize process supplementary group access list for user", - os.str().c_str(), _traceLevels); + reportChildError(getSystemErrno(), errorFds[1], "cannot set process supplementary groups", os.str().c_str(), + _traceLevels); } if(setuid(uid) == -1) diff --git a/cpp/src/IceGrid/ServerI.cpp b/cpp/src/IceGrid/ServerI.cpp index 6168080c3dc..243a43e1519 100644 --- a/cpp/src/IceGrid/ServerI.cpp +++ b/cpp/src/IceGrid/ServerI.cpp @@ -2632,8 +2632,21 @@ ServerI::checkAndUpdateUser(const InternalServerDescriptorPtr& desc, bool /*upda // // Get the uid/gid associated with the given user. // - struct passwd* pw = getpwnam(user.c_str()); - if(!pw) + struct passwd pwbuf; + vector<char> buffer(4096); // 4KB initial buffer size + struct passwd *pw; + int err = getpwnam_r(user.c_str(), &pwbuf, &buffer[0], buffer.size(), &pw); + while(err == ERANGE && buffer.size() < 1024 * 1024) // Limit buffer to 1MB + { + buffer.resize(buffer.size() * 2); + } + if(err != 0) + { + Ice::SyscallException ex(__FILE__, __LINE__); + ex.error = err; + throw ex; + } + else if(pw == 0) { throw "unknown user account `" + user + "'"; } |