X-Git-Url: http://git.home-dn.net/?p=manu%2Fsuphp.git;a=blobdiff_plain;f=src%2FAPI_Linux.cpp;h=9ba08905581004127401340176396e1a1b21db06;hp=97c1e902902b49acdd16e209ae344ecdc4d0d0dc;hb=849f4a7977b5780eacae8fad7a078d05f4a615ee;hpb=b0eaa3f1fbf491fdc8a3044cf20754f14254338a diff --git a/src/API_Linux.cpp b/src/API_Linux.cpp index 97c1e90..9ba0890 100644 --- a/src/API_Linux.cpp +++ b/src/API_Linux.cpp @@ -1,5 +1,5 @@ /* - suPHP - (c)2002-2005 Sebastian Marsching + suPHP - (c)2002-2008 Sebastian Marsching This file is part of suPHP. @@ -48,31 +48,31 @@ bool suPHP::API_Linux::isSymlink(const std::string path) const throw (SystemException) { struct stat temp; if (lstat(path.c_str(), &temp) == -1) { - throw SystemException(std::string("Could not stat \"") - + path + "\": " - + ::strerror(errno), __FILE__, __LINE__); + throw SystemException(std::string("Could not stat \"") + + path + "\": " + + ::strerror(errno), __FILE__, __LINE__); } if ((temp.st_mode & S_IFLNK) == S_IFLNK) { - return true; + return true; } else { - return false; + return false; } } std::string suPHP::API_Linux::readSymlink(const std::string path) const throw (SystemException) { char buf[1024] = {0}; if (::readlink(path.c_str(), buf, 1023) == -1) { - throw SystemException(std::string("Could not read symlink \"") - + path + "\": " - + ::strerror(errno), __FILE__, __LINE__); + throw SystemException(std::string("Could not read symlink \"") + + path + "\": " + + ::strerror(errno), __FILE__, __LINE__); } if (buf[0] == '/') { - return std::string(buf); + return std::string(buf); } else { - if (path.rfind('/') == std::string::npos) - return std::string(buf); - return path.substr(0, path.rfind('/') + 1) + std::string(buf); + if (path.rfind('/') == std::string::npos) + return std::string(buf); + return path.substr(0, path.rfind('/') + 1) + std::string(buf); } } @@ -80,12 +80,12 @@ Environment suPHP::API_Linux::getProcessEnvironment() { Environment env; char **entry = ::environ; while (*entry != NULL) { - std::string estr = std::string(*entry); - int eqpos = estr.find("="); - std::string name = estr.substr(0, eqpos); - std::string content = estr.substr(eqpos + 1); - env.putVar(name, content); - entry++; + std::string estr = std::string(*entry); + int eqpos = estr.find("="); + std::string name = estr.substr(0, eqpos); + std::string content = estr.substr(eqpos + 1); + env.putVar(name, content); + entry++; } return env; } @@ -94,8 +94,8 @@ UserInfo suPHP::API_Linux::getUserInfo(const std::string username) throw (LookupException) { struct passwd *tmpuser = ::getpwnam(username.c_str()); if (tmpuser == NULL) { - throw LookupException(std::string("Could not lookup username \"") - + username + "\"", __FILE__, __LINE__); + throw LookupException(std::string("Could not lookup username \"") + + username + "\"", __FILE__, __LINE__); } return UserInfo(tmpuser->pw_uid); } @@ -108,8 +108,8 @@ GroupInfo suPHP::API_Linux::getGroupInfo(const std::string groupname) throw (LookupException) { struct group *tmpgroup = ::getgrnam(groupname.c_str()); if (tmpgroup == NULL) { - throw LookupException(std::string("Could not lookup groupname \"") - + groupname + "\"", __FILE__, __LINE__); + throw LookupException(std::string("Could not lookup groupname \"") + + groupname + "\"", __FILE__, __LINE__); } return GroupInfo(tmpgroup->gr_gid); } @@ -140,7 +140,7 @@ GroupInfo suPHP::API_Linux::getRealProcessGroup() { Logger& suPHP::API_Linux::getSystemLogger() { if (suPHP::API_Linux::logger.get() == NULL) { - suPHP::API_Linux::logger.reset(new API_Linux_Logger()); + suPHP::API_Linux::logger.reset(new API_Linux_Logger()); } return *(suPHP::API_Linux::logger); } @@ -150,26 +150,26 @@ void suPHP::API_Linux::setProcessUser(const UserInfo& user) const throw (SystemException) { // Reset supplementary groups if (::setgroups(0, NULL) == -1) { - throw SystemException(std::string("setgroups() failed: ") - + ::strerror(errno), __FILE__, __LINE__); + throw SystemException(std::string("setgroups() failed: ") + + ::strerror(errno), __FILE__, __LINE__); } try { - if (::initgroups(user.getUsername().c_str(), - user.getGroupInfo().getGid()) - == -1) { - throw SystemException(std::string("initgroups() failed: ") - + ::strerror(errno), __FILE__, __LINE__); - } + if (::initgroups(user.getUsername().c_str(), + user.getGroupInfo().getGid()) + == -1) { + throw SystemException(std::string("initgroups() failed: ") + + ::strerror(errno), __FILE__, __LINE__); + } } catch (LookupException &e) { - // Ignore this exception - // If we have a UID, which does not exist in /etc/passwd - // we simply cannot use supplementary groups + // Ignore this exception + // If we have a UID, which does not exist in /etc/passwd + // we simply cannot use supplementary groups } if (::setuid(user.getUid()) == -1) { - throw SystemException(std::string("setuid() failed: ") - + ::strerror(errno), __FILE__, __LINE__); + throw SystemException(std::string("setuid() failed: ") + + ::strerror(errno), __FILE__, __LINE__); } } @@ -177,8 +177,8 @@ void suPHP::API_Linux::setProcessUser(const UserInfo& user) const void suPHP::API_Linux::setProcessGroup(const GroupInfo& group) const throw (SystemException) { if (::setgid(group.getGid()) == -1) { - throw SystemException(std::string("setgid() failed: ") - + ::strerror(errno), __FILE__, __LINE__); + throw SystemException(std::string("setgid() failed: ") + + ::strerror(errno), __FILE__, __LINE__); } } @@ -186,9 +186,9 @@ std::string suPHP::API_Linux::UserInfo_getUsername(const UserInfo& uinfo) const throw (LookupException) { struct passwd *tmpuser = ::getpwuid(uinfo.getUid()); if (tmpuser == NULL) { - throw LookupException(std::string("Could not lookup UID ") - + Util::intToStr(uinfo.getUid()), - __FILE__, __LINE__); + throw LookupException(std::string("Could not lookup UID ") + + Util::intToStr(uinfo.getUid()), + __FILE__, __LINE__); } return std::string(tmpuser->pw_name); } @@ -198,37 +198,49 @@ GroupInfo suPHP::API_Linux::UserInfo_getGroupInfo(const UserInfo& uinfo) const struct passwd *tmpuser = NULL; tmpuser = getpwuid(uinfo.getUid()); if (tmpuser == NULL) { - throw LookupException(std::string("Could not lookup UID ") - + Util::intToStr(uinfo.getUid()), - __FILE__, __LINE__); + throw LookupException(std::string("Could not lookup UID ") + + Util::intToStr(uinfo.getUid()), + __FILE__, __LINE__); } return GroupInfo(tmpuser->pw_gid); } +std::string suPHP::API_Linux::UserInfo_getHomeDirectory(const UserInfo& uinfo) const + throw (LookupException) { + struct passwd *tmpuser = NULL; + tmpuser = getpwuid(uinfo.getUid()); + if (tmpuser == NULL) { + throw LookupException(std::string("Could not lookup UID ") + + Util::intToStr(uinfo.getUid()), + __FILE__, __LINE__); + } + return tmpuser->pw_dir; +} + bool suPHP::API_Linux::UserInfo_isSuperUser(const UserInfo& uinfo) const { if (uinfo.getUid() == 0) - return true; + return true; else - return false; + return false; } std::string suPHP::API_Linux::GroupInfo_getGroupname(const GroupInfo& ginfo) const throw (LookupException) { struct group *tmpgroup = ::getgrgid(ginfo.getGid()); if (tmpgroup == NULL) { - throw LookupException(std::string("Could not lookup GID ") - + Util::intToStr(ginfo.getGid()), - __FILE__, __LINE__); + throw LookupException(std::string("Could not lookup GID ") + + Util::intToStr(ginfo.getGid()), + __FILE__, __LINE__); } return std::string(tmpgroup->gr_name); } bool suPHP::API_Linux::File_exists(const File& file) const { struct stat dummy; - if (::stat(file.getPath().c_str(), &dummy) == 0) - return true; + if (::lstat(file.getPath().c_str(), &dummy) == 0) + return true; else - return false; + return false; } std::string suPHP::API_Linux::File_getRealPath(const File& file) const @@ -238,65 +250,65 @@ std::string suPHP::API_Linux::File_getRealPath(const File& file) const bool failed = true; if ((currentpath.size() == 0) || (currentpath.at(0) != '/')) { - currentpath = this->getCwd() + std::string("/") + currentpath; + currentpath = this->getCwd() + std::string("/") + currentpath; } // Limit iterations to avoid infinite symlink loops for (int i=0; i<512; i++) { - // If nothing is left, we have finished - if (currentpath.size() == 0) { - resolvedpath = ("/" + resolvedpath); - failed = false; - break; - } - - if (this->isSymlink(currentpath)) { - currentpath = this->readSymlink(currentpath); - } else { - // We know last part is not a symlink, so it is resolved - std::string part1 = - currentpath.substr(0, currentpath.rfind('/')); - std::string part2 = - currentpath.substr(currentpath.rfind('/')+1); - currentpath = part1; - if (resolvedpath.size() == 0) - resolvedpath = part2; - else - resolvedpath = part2 + "/" + resolvedpath; - } + // If nothing is left, we have finished + if (currentpath.size() == 0) { + resolvedpath = ("/" + resolvedpath); + failed = false; + break; + } + + if (this->isSymlink(currentpath)) { + currentpath = this->readSymlink(currentpath); + } else { + // We know last part is not a symlink, so it is resolved + std::string part1 = + currentpath.substr(0, currentpath.rfind('/')); + std::string part2 = + currentpath.substr(currentpath.rfind('/')+1); + currentpath = part1; + if (resolvedpath.size() == 0) + resolvedpath = part2; + else + resolvedpath = part2 + "/" + resolvedpath; + } } if (failed) { - throw SystemException("Could not resolve path \"" + - file.getPath() + "\"", __FILE__, __LINE__); + throw SystemException("Could not resolve path \"" + + file.getPath() + "\"", __FILE__, __LINE__); } while (resolvedpath.find("/./") != std::string::npos) { - int pos = resolvedpath.find("/./"); - resolvedpath = resolvedpath.substr(0, pos) - + resolvedpath.substr(pos + 2); + int pos = resolvedpath.find("/./"); + resolvedpath = resolvedpath.substr(0, pos) + + resolvedpath.substr(pos + 2); } while (resolvedpath.find("/../") != std::string::npos) { - int pos = resolvedpath.find("/../"); - int pos2 = resolvedpath.rfind('/', pos-1); - resolvedpath = resolvedpath.substr(0, pos2) - + resolvedpath.substr(pos + 3); + int pos = resolvedpath.find("/../"); + int pos2 = resolvedpath.rfind('/', pos-1); + resolvedpath = resolvedpath.substr(0, pos2) + + resolvedpath.substr(pos + 3); } if (resolvedpath.find("/..", resolvedpath.size() - 3) - != std::string::npos) { - resolvedpath = resolvedpath.substr(0, resolvedpath.size() - 3); - resolvedpath = resolvedpath.substr(0, resolvedpath.rfind('/')); + != std::string::npos) { + resolvedpath = resolvedpath.substr(0, resolvedpath.size() - 3); + resolvedpath = resolvedpath.substr(0, resolvedpath.rfind('/')); } if (resolvedpath.find("/.", resolvedpath.size() - 2) - != std::string::npos) { - resolvedpath = resolvedpath.substr(0, resolvedpath.size() - 2); + != std::string::npos) { + resolvedpath = resolvedpath.substr(0, resolvedpath.size() - 2); } if (resolvedpath.size() == 0) - resolvedpath = "/"; + resolvedpath = "/"; return resolvedpath; } @@ -304,56 +316,56 @@ std::string suPHP::API_Linux::File_getRealPath(const File& file) const bool suPHP::API_Linux::File_hasPermissionBit(const File& file, FileMode perm) const throw (SystemException) { struct stat temp; - if (stat(file.getPath().c_str(), &temp) == -1) { - throw SystemException(std::string("Could not stat \"") - + file.getPath() + "\": " - + ::strerror(errno), __FILE__, __LINE__); + if (lstat(file.getPath().c_str(), &temp) == -1) { + throw SystemException(std::string("Could not stat \"") + + file.getPath() + "\": " + + ::strerror(errno), __FILE__, __LINE__); } switch (perm) { case FILEMODE_USER_READ: - if ((temp.st_mode & S_IRUSR) == S_IRUSR) - return true; - break; + if ((temp.st_mode & S_IRUSR) == S_IRUSR) + return true; + break; case FILEMODE_USER_WRITE: - if ((temp.st_mode & S_IWUSR) == S_IWUSR) - return true; - break; + if ((temp.st_mode & S_IWUSR) == S_IWUSR) + return true; + break; case FILEMODE_USER_EXEC: - if ((temp.st_mode & S_IXUSR) == S_IXUSR) - return true; - break; + if ((temp.st_mode & S_IXUSR) == S_IXUSR) + return true; + break; case FILEMODE_GROUP_READ: - if ((temp.st_mode & S_IRGRP) == S_IRGRP) - return true; - break; + if ((temp.st_mode & S_IRGRP) == S_IRGRP) + return true; + break; case FILEMODE_GROUP_WRITE: - if ((temp.st_mode & S_IWGRP) == S_IWGRP) - return true; - break; + if ((temp.st_mode & S_IWGRP) == S_IWGRP) + return true; + break; case FILEMODE_GROUP_EXEC: - if ((temp.st_mode & S_IXGRP) == S_IXGRP) - return true; - break; + if ((temp.st_mode & S_IXGRP) == S_IXGRP) + return true; + break; case FILEMODE_OTHERS_READ: - if ((temp.st_mode & S_IROTH) == S_IROTH) - return true; - break; + if ((temp.st_mode & S_IROTH) == S_IROTH) + return true; + break; case FILEMODE_OTHERS_WRITE: - if ((temp.st_mode & S_IWOTH) == S_IWOTH) - return true; - break; - + if ((temp.st_mode & S_IWOTH) == S_IWOTH) + return true; + break; + case FILEMODE_OTHERS_EXEC: - if ((temp.st_mode & S_IXOTH) == S_IXOTH) - return true; - break; + if ((temp.st_mode & S_IXOTH) == S_IXOTH) + return true; + break; } return false; @@ -362,10 +374,10 @@ bool suPHP::API_Linux::File_hasPermissionBit(const File& file, FileMode perm) UserInfo suPHP::API_Linux::File_getUser(const File& file) const throw (SystemException) { struct stat temp; - if (stat(file.getPath().c_str(), &temp) == -1) { - throw SystemException(std::string("Could not stat \"") - + file.getPath() + "\": " - + ::strerror(errno), __FILE__, __LINE__); + if (lstat(file.getPath().c_str(), &temp) == -1) { + throw SystemException(std::string("Could not stat \"") + + file.getPath() + "\": " + + ::strerror(errno), __FILE__, __LINE__); } return UserInfo(temp.st_uid); } @@ -373,17 +385,22 @@ UserInfo suPHP::API_Linux::File_getUser(const File& file) const GroupInfo suPHP::API_Linux::File_getGroup(const File& file) const throw (SystemException) { struct stat temp; - if (stat(file.getPath().c_str(), &temp) == -1) { - throw SystemException(std::string("Could not stat \"") - + file.getPath() + "\": " - + ::strerror(errno), __FILE__, __LINE__); + if (lstat(file.getPath().c_str(), &temp) == -1) { + throw SystemException(std::string("Could not stat \"") + + file.getPath() + "\": " + + ::strerror(errno), __FILE__, __LINE__); } return GroupInfo(temp.st_gid); } +bool suPHP::API_Linux::File_isSymlink(const File& file) const throw (SystemException) { + return this->isSymlink(file.getPath()); +} + + void suPHP::API_Linux::execute(std::string program, const CommandLine& cline, - const Environment& env) const + const Environment& env) const throw (SystemException) { char **sysCline = NULL; char **sysEnv = NULL; @@ -397,9 +414,9 @@ void suPHP::API_Linux::execute(std::string program, const CommandLine& cline, // Construct commandline sysCline = new char*[cline.size() + 1]; for (i=0; i::iterator pos = map.begin(); - pos != map.end(); - pos++) { - std::string var; - var = pos->first + "=" + pos->second; - *p = new char[var.size()+1]; - ::strncpy(*p, var.c_str(), var.size()+1); - p++; + pos != map.end(); + pos++) { + std::string var; + var = pos->first + "=" + pos->second; + *p = new char[var.size()+1]; + ::strncpy(*p, var.c_str(), var.size()+1); + p++; } *p = NULL; @@ -422,30 +439,30 @@ void suPHP::API_Linux::execute(std::string program, const CommandLine& cline, sysProgram = new char[program.size() + 1]; ::strncpy(sysProgram, program.c_str(), program.size()+1); if (execve(sysProgram, sysCline, sysEnv) == -1) { - throw SystemException("execve() for program \"" + program - + "\" failed: " + ::strerror(errno), - __FILE__, __LINE__); + throw SystemException("execve() for program \"" + program + + "\" failed: " + ::strerror(errno), + __FILE__, __LINE__); } // We are still here? This cannot be good.. throw SystemException("execve() for program \"" + program - + "\" failed because of unknown reason", - __FILE__, __LINE__); + + "\" failed because of unknown reason", + __FILE__, __LINE__); } std::string suPHP::API_Linux::getCwd() const throw (SystemException) { char buf[4096] = {0}; if (::getcwd(buf, 4095) == NULL) - throw SystemException(std::string("getcwd() failed: ") - + ::strerror(errno), __FILE__, __LINE__); + throw SystemException(std::string("getcwd() failed: ") + + ::strerror(errno), __FILE__, __LINE__); return std::string(buf); } void suPHP::API_Linux::setCwd(const std::string& dir) const throw (SystemException) { if(::chdir(dir.c_str())) { - throw SystemException(std::string("chdir() failed: ") - + ::strerror(errno), __FILE__, __LINE__); + throw SystemException(std::string("chdir() failed: ") + + ::strerror(errno), __FILE__, __LINE__); } } @@ -456,7 +473,7 @@ void suPHP::API_Linux::setUmask(int mode) const throw (SystemException) { void suPHP::API_Linux::chroot(const std::string& dir) const throw (SystemException) { if (::chroot(dir.c_str())) { - throw SystemException(std::string("chroot() failed: ") - + ::strerror(errno), __FILE__, __LINE__); + throw SystemException(std::string("chroot() failed: ") + + ::strerror(errno), __FILE__, __LINE__); } }