mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-26 17:41:59 +00:00
Move euid check back to Server.cpp.
Use getpwnam_r instead of getpwnam. Fix style.
This commit is contained in:
parent
52d18ee7c6
commit
42de08f3b9
@ -2,7 +2,11 @@
|
|||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <sys/resource.h>
|
#include <sys/resource.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <sys/types.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <pwd.h>
|
||||||
|
#include <unistd.h>
|
||||||
#include <Poco/Version.h>
|
#include <Poco/Version.h>
|
||||||
#include <Poco/DirectoryIterator.h>
|
#include <Poco/DirectoryIterator.h>
|
||||||
#include <Poco/Net/HTTPServer.h>
|
#include <Poco/Net/HTTPServer.h>
|
||||||
@ -70,6 +74,9 @@ namespace ErrorCodes
|
|||||||
extern const int EXCESSIVE_ELEMENT_IN_CONFIG;
|
extern const int EXCESSIVE_ELEMENT_IN_CONFIG;
|
||||||
extern const int INVALID_CONFIG_PARAMETER;
|
extern const int INVALID_CONFIG_PARAMETER;
|
||||||
extern const int SYSTEM_ERROR;
|
extern const int SYSTEM_ERROR;
|
||||||
|
extern const int FAILED_TO_STAT_DATA;
|
||||||
|
extern const int FAILED_TO_GETPWUID;
|
||||||
|
extern const int MISMATCHING_USERS_FOR_PROCESS_AND_DATA;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -83,6 +90,25 @@ static std::string getCanonicalPath(std::string && path)
|
|||||||
return std::move(path);
|
return std::move(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static std::string getUserName(uid_t user_id) {
|
||||||
|
/// Try to convert user id into user name.
|
||||||
|
auto buffer_size = sysconf(_SC_GETPW_R_SIZE_MAX);
|
||||||
|
if (buffer_size <= 0)
|
||||||
|
buffer_size = 32;
|
||||||
|
std::string buffer;
|
||||||
|
buffer.reserve(buffer_size);
|
||||||
|
|
||||||
|
struct passwd passwd_entry;
|
||||||
|
struct passwd * result = nullptr;
|
||||||
|
const auto error = getpwuid_r(user_id, &passwd_entry, buffer.data(), buffer_size, &result);
|
||||||
|
|
||||||
|
if (error)
|
||||||
|
throwFromErrno("Failed to find user name for " + toString(user_id), ErrorCodes::FAILED_TO_GETPWUID, error);
|
||||||
|
else if (result)
|
||||||
|
return result->pw_name;
|
||||||
|
return toString(user_id);
|
||||||
|
}
|
||||||
|
|
||||||
void Server::uninitialize()
|
void Server::uninitialize()
|
||||||
{
|
{
|
||||||
logger().information("shutting down");
|
logger().information("shutting down");
|
||||||
@ -166,6 +192,22 @@ int Server::main(const std::vector<std::string> & /*args*/)
|
|||||||
std::string path = getCanonicalPath(config().getString("path", DBMS_DEFAULT_PATH));
|
std::string path = getCanonicalPath(config().getString("path", DBMS_DEFAULT_PATH));
|
||||||
std::string default_database = config().getString("default_database", "default");
|
std::string default_database = config().getString("default_database", "default");
|
||||||
|
|
||||||
|
/// Check that the process' user id matches the owner of the data.
|
||||||
|
const auto effective_user_id = geteuid();
|
||||||
|
struct stat statbuf;
|
||||||
|
const auto effective_user = getUserName(effective_user_id);
|
||||||
|
LOG_INFO(log, "effective_user = " + effective_user);
|
||||||
|
if (stat(path.c_str(), &statbuf) == 0 && effective_user_id != statbuf.st_uid)
|
||||||
|
{
|
||||||
|
const auto effective_user = getUserName(effective_user_id);
|
||||||
|
const auto data_owner = getUserName(statbuf.st_uid);
|
||||||
|
std::string message = "Effective user of the process (" + effective_user +
|
||||||
|
") does not match the owner of the data (" + data_owner + ").";
|
||||||
|
if (effective_user_id == 0)
|
||||||
|
message += " Run under 'sudo -u " + data_owner + "'.";
|
||||||
|
throw Exception(message, ErrorCodes::MISMATCHING_USERS_FOR_PROCESS_AND_DATA);
|
||||||
|
}
|
||||||
|
|
||||||
global_context->setPath(path);
|
global_context->setPath(path);
|
||||||
|
|
||||||
/// Create directories for 'path' and for default database, if not exist.
|
/// Create directories for 'path' and for default database, if not exist.
|
||||||
@ -376,21 +418,13 @@ int Server::main(const std::vector<std::string> & /*args*/)
|
|||||||
format_schema_path.createDirectories();
|
format_schema_path.createDirectories();
|
||||||
|
|
||||||
LOG_INFO(log, "Loading metadata.");
|
LOG_INFO(log, "Loading metadata.");
|
||||||
try
|
loadMetadataSystem(*global_context);
|
||||||
{
|
/// After attaching system databases we can initialize system log.
|
||||||
loadMetadataSystem(*global_context);
|
global_context->initializeSystemLogs();
|
||||||
/// After attaching system databases we can initialize system log.
|
/// After the system database is created, attach virtual system tables (in addition to query_log and part_log)
|
||||||
global_context->initializeSystemLogs();
|
attachSystemTablesServer(*global_context->getDatabase("system"), has_zookeeper);
|
||||||
/// After the system database is created, attach virtual system tables (in addition to query_log and part_log)
|
/// Then, load remaining databases
|
||||||
attachSystemTablesServer(*global_context->getDatabase("system"), has_zookeeper);
|
loadMetadata(*global_context);
|
||||||
/// Then, load remaining databases
|
|
||||||
loadMetadata(*global_context);
|
|
||||||
}
|
|
||||||
catch (...)
|
|
||||||
{
|
|
||||||
tryLogCurrentException(log, "Caught exception while loading metadata");
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
LOG_DEBUG(log, "Loaded metadata.");
|
LOG_DEBUG(log, "Loaded metadata.");
|
||||||
|
|
||||||
global_context->setCurrentDatabase(default_database);
|
global_context->setCurrentDatabase(default_database);
|
||||||
|
@ -402,6 +402,9 @@ namespace ErrorCodes
|
|||||||
extern const int SYSTEM_ERROR = 425;
|
extern const int SYSTEM_ERROR = 425;
|
||||||
extern const int NULL_POINTER_DEREFERENCE = 426;
|
extern const int NULL_POINTER_DEREFERENCE = 426;
|
||||||
extern const int CANNOT_COMPILE_REGEXP = 427;
|
extern const int CANNOT_COMPILE_REGEXP = 427;
|
||||||
|
extern const int FAILED_TO_STAT_DATA = 428;
|
||||||
|
extern const int FAILED_TO_GETPWUID = 429;
|
||||||
|
extern const int MISMATCHING_USERS_FOR_PROCESS_AND_DATA = 430;
|
||||||
|
|
||||||
extern const int KEEPER_EXCEPTION = 999;
|
extern const int KEEPER_EXCEPTION = 999;
|
||||||
extern const int POCO_EXCEPTION = 1000;
|
extern const int POCO_EXCEPTION = 1000;
|
||||||
|
@ -14,7 +14,6 @@
|
|||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <cxxabi.h>
|
#include <cxxabi.h>
|
||||||
#include <execinfo.h>
|
#include <execinfo.h>
|
||||||
#include <pwd.h>
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#if USE_UNWIND
|
#if USE_UNWIND
|
||||||
@ -578,17 +577,6 @@ static bool tryCreateDirectories(Poco::Logger * logger, const std::string & path
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static std::string getUserName(uid_t userId) {
|
|
||||||
/// Try to convert user id into user name.
|
|
||||||
const struct passwd * result = getpwuid(userId);
|
|
||||||
if (errno)
|
|
||||||
throw Poco::SystemException("Failed to get user name for " + DB::toString(userId));
|
|
||||||
else if (result)
|
|
||||||
return result->pw_name;
|
|
||||||
return DB::toString(userId);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void BaseDaemon::reloadConfiguration()
|
void BaseDaemon::reloadConfiguration()
|
||||||
{
|
{
|
||||||
/** If the program is not run in daemon mode and 'config-file' is not specified,
|
/** If the program is not run in daemon mode and 'config-file' is not specified,
|
||||||
@ -910,28 +898,6 @@ void BaseDaemon::initialize(Application & self)
|
|||||||
umask(umask_num);
|
umask(umask_num);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string path = config().getString("path", DBMS_DEFAULT_PATH);
|
|
||||||
|
|
||||||
/// Check that the process' user id matches the owner of the data.
|
|
||||||
const auto effectiveUserId = geteuid();
|
|
||||||
struct stat statbuf;
|
|
||||||
if (stat(path.c_str(), &statbuf)) {
|
|
||||||
const auto parent = Poco::Path(path).parent().toString();
|
|
||||||
if (stat(parent.c_str(), &statbuf)) {
|
|
||||||
throw Poco::SystemException("Failed to stat data path " + parent);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (effectiveUserId != statbuf.st_uid)
|
|
||||||
{
|
|
||||||
const auto effectiveUser = getUserName(effectiveUserId);
|
|
||||||
const auto dataOwner = getUserName(statbuf.st_uid);
|
|
||||||
std::string message = "Effective user of the process (" + effectiveUser +
|
|
||||||
") does not match the owner of the data (" + dataOwner + ").";
|
|
||||||
if (effectiveUserId == 0)
|
|
||||||
message += " Run under 'sudo -u " + dataOwner + "'.";
|
|
||||||
throw Poco::SystemException(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
DB::ConfigProcessor(config_path).savePreprocessedConfig(loaded_config, "");
|
DB::ConfigProcessor(config_path).savePreprocessedConfig(loaded_config, "");
|
||||||
|
|
||||||
/// Write core dump on crash.
|
/// Write core dump on crash.
|
||||||
|
Loading…
Reference in New Issue
Block a user