mirror of https://gitee.com/bigwinds/arangodb
Merge branch 'devel' of github.com:arangodb/ArangoDB into devel
This commit is contained in:
commit
d3cc9981b8
17
CHANGELOG
17
CHANGELOG
|
@ -1,6 +1,23 @@
|
||||||
v2.7.0 (XXXX-XX-XX)
|
v2.7.0 (XXXX-XX-XX)
|
||||||
-------------------
|
-------------------
|
||||||
|
|
||||||
|
* IMPORTANT CHANGE: when starting arangod, the server will drop the process
|
||||||
|
privileges to the specified values in options `--server.uid` and `--server.gid`
|
||||||
|
instantly after parsing the startup options.
|
||||||
|
|
||||||
|
That means when either `--server.uid` or `--server.gid` are set, the privilege
|
||||||
|
change may happen earlier at startup. This may prevent binding the server to
|
||||||
|
and endpoint with a port number lower than 1024, if the user has no privileges
|
||||||
|
for that. Previous versions of ArangoDB changed the privileges later, so some
|
||||||
|
startup actions were still carried out under the invoking user (i.e. likely
|
||||||
|
*root* when started via init.d or system scripts) and especially binding to
|
||||||
|
low ports was still possible there.
|
||||||
|
|
||||||
|
The default privileges for user *arangodb* will not be sufficient for binding
|
||||||
|
to port numbers lower than 1024. To have an ArangoDB 2.7 bind to a port number
|
||||||
|
lower than 1024, it needs to be started with either a different privileged user,
|
||||||
|
or the privileges of the *arangodb* user have to raised manually beforehand.
|
||||||
|
|
||||||
* added AQL optimizer rule `patch-update-statements`
|
* added AQL optimizer rule `patch-update-statements`
|
||||||
|
|
||||||
* Linux startup scripts and systemd configuration for arangod now try to
|
* Linux startup scripts and systemd configuration for arangod now try to
|
||||||
|
|
|
@ -100,11 +100,9 @@ ApplicationServer::ApplicationServer (std::string const& name, std::string const
|
||||||
_userConfigFile(),
|
_userConfigFile(),
|
||||||
_systemConfigFile(),
|
_systemConfigFile(),
|
||||||
_uid(),
|
_uid(),
|
||||||
_realUid(0),
|
_numericUid(0),
|
||||||
_effectiveUid(0),
|
|
||||||
_gid(),
|
_gid(),
|
||||||
_realGid(0),
|
_numericGid(0),
|
||||||
_effectiveGid(0),
|
|
||||||
_logApplicationName("arangod"),
|
_logApplicationName("arangod"),
|
||||||
_logFacility(""),
|
_logFacility(""),
|
||||||
_logLevel("info"),
|
_logLevel("info"),
|
||||||
|
@ -123,9 +121,6 @@ ApplicationServer::ApplicationServer (std::string const& name, std::string const
|
||||||
_randomGenerator(3),
|
_randomGenerator(3),
|
||||||
#endif
|
#endif
|
||||||
_finishedCondition() {
|
_finishedCondition() {
|
||||||
#ifndef _WIN32
|
|
||||||
storeRealPrivileges();
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -422,7 +417,7 @@ bool ApplicationServer::parse (int argc,
|
||||||
// .............................................................................
|
// .............................................................................
|
||||||
|
|
||||||
extractPrivileges();
|
extractPrivileges();
|
||||||
dropPrivileges();
|
dropPrivilegesPermanently();
|
||||||
|
|
||||||
// .............................................................................
|
// .............................................................................
|
||||||
// setup logging
|
// setup logging
|
||||||
|
@ -538,8 +533,6 @@ void ApplicationServer::start () {
|
||||||
pthread_sigmask(SIG_SETMASK, &all, 0);
|
pthread_sigmask(SIG_SETMASK, &all, 0);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
raisePrivileges();
|
|
||||||
|
|
||||||
// start all startable features
|
// start all startable features
|
||||||
for (vector<ApplicationFeature*>::iterator i = _features.begin(); i != _features.end(); ++i) {
|
for (vector<ApplicationFeature*>::iterator i = _features.begin(); i != _features.end(); ++i) {
|
||||||
ApplicationFeature* feature = *i;
|
ApplicationFeature* feature = *i;
|
||||||
|
@ -567,8 +560,6 @@ void ApplicationServer::start () {
|
||||||
|
|
||||||
LOG_TRACE("opened server feature '%s'", feature->getName().c_str());
|
LOG_TRACE("opened server feature '%s'", feature->getName().c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
dropPrivilegesPermanently();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -630,66 +621,85 @@ void ApplicationServer::stop () {
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief raise the privileges
|
/// @brief extract the privileges to use
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
void ApplicationServer::raisePrivileges () {
|
void ApplicationServer::extractPrivileges() {
|
||||||
|
|
||||||
// first UID
|
|
||||||
#ifdef TRI_HAVE_SETUID
|
|
||||||
|
|
||||||
if (_effectiveUid != _realUid) {
|
|
||||||
int res = seteuid(_realUid);
|
|
||||||
|
|
||||||
if (res != 0) {
|
|
||||||
LOG_FATAL_AND_EXIT("cannot set uid '%s': %s", _uid.c_str(), strerror(errno));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// then GID (because we are raising)
|
|
||||||
#ifdef TRI_HAVE_SETGID
|
#ifdef TRI_HAVE_SETGID
|
||||||
|
|
||||||
if (_effectiveGid != _realGid) {
|
if (_gid.empty()) {
|
||||||
int res = setegid(_realGid);
|
_numericGid = getgid();
|
||||||
|
|
||||||
if (res != 0) {
|
|
||||||
LOG_FATAL_AND_EXIT("cannot set gid %d: %s", (int) _effectiveGid, strerror(errno));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
int gidNumber = TRI_Int32String(_gid.c_str());
|
||||||
|
|
||||||
|
if (TRI_errno() == TRI_ERROR_NO_ERROR && gidNumber >= 0) {
|
||||||
|
|
||||||
|
#ifdef TRI_HAVE_GETGRGID
|
||||||
|
group* g = getgrgid(gidNumber);
|
||||||
|
|
||||||
|
if (g == 0) {
|
||||||
|
LOG_FATAL_AND_EXIT("unknown numeric gid '%s'", _gid.c_str());
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
#ifdef TRI_HAVE_GETGRNAM
|
||||||
|
string name = _gid;
|
||||||
|
group* g = getgrnam(name.c_str());
|
||||||
|
|
||||||
|
if (g != 0) {
|
||||||
|
gidNumber = g->gr_gid;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
LOG_FATAL_AND_EXIT("cannot convert groupname '%s' to numeric gid", _gid.c_str());
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
LOG_FATAL_AND_EXIT("cannot convert groupname '%s' to numeric gid", _gid.c_str());
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
_numericGid = gidNumber;
|
||||||
/// @brief drops the privileges
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
void ApplicationServer::dropPrivileges () {
|
|
||||||
|
|
||||||
// first GID
|
|
||||||
#ifdef TRI_HAVE_SETGID
|
|
||||||
|
|
||||||
if (_effectiveGid != _realGid) {
|
|
||||||
int res = setegid(_effectiveGid);
|
|
||||||
|
|
||||||
if (res != 0) {
|
|
||||||
LOG_FATAL_AND_EXIT("cannot set gid %d: %s", (int) _effectiveGid, strerror(errno));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// then UID (because we are dropping)
|
|
||||||
#ifdef TRI_HAVE_SETUID
|
#ifdef TRI_HAVE_SETUID
|
||||||
|
|
||||||
if (_effectiveUid != _realUid) {
|
if (_uid.empty()) {
|
||||||
int res = seteuid(_effectiveUid);
|
_numericUid = getuid();
|
||||||
|
|
||||||
if (res != 0) {
|
|
||||||
LOG_FATAL_AND_EXIT("cannot set uid %s: %s", _uid.c_str(), strerror(errno));
|
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
int uidNumber = TRI_Int32String(_uid.c_str());
|
||||||
|
|
||||||
|
if (TRI_errno() == TRI_ERROR_NO_ERROR) {
|
||||||
|
|
||||||
|
#ifdef TRI_HAVE_GETPWUID
|
||||||
|
passwd* p = getpwuid(uidNumber);
|
||||||
|
|
||||||
|
if (p == 0) {
|
||||||
|
LOG_FATAL_AND_EXIT("unknown numeric uid '%s'", _uid.c_str());
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
#ifdef TRI_HAVE_GETPWNAM
|
||||||
|
string name = _uid;
|
||||||
|
passwd* p = getpwnam(name.c_str());
|
||||||
|
|
||||||
|
if (p != 0) {
|
||||||
|
uidNumber = p->pw_uid;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
LOG_FATAL_AND_EXIT("cannot convert username '%s' to numeric uid", _uid.c_str());
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
LOG_FATAL_AND_EXIT("cannot convert username '%s' to numeric uid", _uid.c_str());
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
_numericUid = uidNumber;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -700,32 +710,32 @@ void ApplicationServer::dropPrivileges () {
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
void ApplicationServer::dropPrivilegesPermanently () {
|
void ApplicationServer::dropPrivilegesPermanently () {
|
||||||
raisePrivileges();
|
|
||||||
|
|
||||||
// clear all supplementary groups
|
// clear all supplementary groups
|
||||||
#if defined(TRI_HAVE_INITGROUPS) && defined(TRI_HAVE_SETGID) && defined(TRI_HAVE_SETUID)
|
#if defined(TRI_HAVE_INITGROUPS) && defined(TRI_HAVE_SETGID) && defined(TRI_HAVE_SETUID)
|
||||||
|
|
||||||
struct passwd* pwent = getpwuid(_effectiveUid);
|
if (! _gid.empty() && ! _uid.empty()) {
|
||||||
|
struct passwd* pwent = getpwuid(_numericUid);
|
||||||
|
|
||||||
if (pwent != nullptr) {
|
if (pwent != nullptr) {
|
||||||
initgroups(pwent->pw_name, _effectiveGid);
|
initgroups(pwent->pw_name, _numericGid);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
// first GID
|
// first GID
|
||||||
#ifdef TRI_HAVE_SETGID
|
#ifdef TRI_HAVE_SETGID
|
||||||
|
|
||||||
if (_effectiveGid != _realGid) {
|
if (! _gid.empty()) {
|
||||||
LOG_INFO("permanently changing the gid to %d", (int) _effectiveGid);
|
LOG_INFO("permanently changing the gid to %d", (int) _numericGid);
|
||||||
|
|
||||||
int res = setgid(_effectiveGid);
|
int res = setgid(_numericGid);
|
||||||
|
|
||||||
if (res != 0) {
|
if (res != 0) {
|
||||||
LOG_FATAL_AND_EXIT("cannot set gid %d: %s", (int) _effectiveGid, strerror(errno));
|
LOG_FATAL_AND_EXIT("cannot set gid %d: %s", (int) _numericGid, strerror(errno));
|
||||||
}
|
}
|
||||||
|
|
||||||
_realGid = _effectiveGid;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -733,35 +743,19 @@ void ApplicationServer::dropPrivilegesPermanently () {
|
||||||
// then UID (because we are dropping)
|
// then UID (because we are dropping)
|
||||||
#ifdef TRI_HAVE_SETUID
|
#ifdef TRI_HAVE_SETUID
|
||||||
|
|
||||||
if (_effectiveUid != _realUid) {
|
if (! _uid.empty()) {
|
||||||
LOG_INFO("permanently changing the uid to %d", (int) _effectiveUid);
|
LOG_INFO("permanently changing the uid to %d", (int) _numericUid);
|
||||||
|
|
||||||
int res = setuid(_effectiveUid);
|
int res = setuid(_numericUid);
|
||||||
|
|
||||||
if (res != 0) {
|
if (res != 0) {
|
||||||
LOG_FATAL_AND_EXIT("cannot set uid '%s': %s", _uid.c_str(), strerror(errno));
|
LOG_FATAL_AND_EXIT("cannot set uid '%s': %s", _uid.c_str(), strerror(errno));
|
||||||
}
|
}
|
||||||
|
|
||||||
_realUid = _effectiveUid;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
/// @brief saves the logging privileges
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
void ApplicationServer::storeRealPrivileges () {
|
|
||||||
#ifdef TRI_HAVE_SETGID
|
|
||||||
_realGid = getgid();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef TRI_HAVE_SETUID
|
|
||||||
_realUid = getuid();
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// --SECTION-- protected methods
|
// --SECTION-- protected methods
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
@ -1023,91 +1017,6 @@ bool ApplicationServer::readConfigurationFile () {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
/// @brief extract the privileges to use
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
void ApplicationServer::extractPrivileges() {
|
|
||||||
|
|
||||||
#ifdef TRI_HAVE_SETGID
|
|
||||||
|
|
||||||
if (_gid.empty()) {
|
|
||||||
_effectiveGid = getgid();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
int gidNumber = TRI_Int32String(_gid.c_str());
|
|
||||||
|
|
||||||
if (TRI_errno() == TRI_ERROR_NO_ERROR && gidNumber >= 0) {
|
|
||||||
|
|
||||||
#ifdef TRI_HAVE_GETGRGID
|
|
||||||
group* g = getgrgid(gidNumber);
|
|
||||||
|
|
||||||
if (g == 0) {
|
|
||||||
LOG_FATAL_AND_EXIT("unknown numeric gid '%s'", _gid.c_str());
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
#ifdef TRI_HAVE_GETGRNAM
|
|
||||||
string name = _gid;
|
|
||||||
group* g = getgrnam(name.c_str());
|
|
||||||
|
|
||||||
if (g != 0) {
|
|
||||||
gidNumber = g->gr_gid;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
LOG_FATAL_AND_EXIT("cannot convert groupname '%s' to numeric gid", _gid.c_str());
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
LOG_FATAL_AND_EXIT("cannot convert groupname '%s' to numeric gid", _gid.c_str());
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
_effectiveGid = gidNumber;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef TRI_HAVE_SETUID
|
|
||||||
|
|
||||||
if (_uid.empty()) {
|
|
||||||
_effectiveUid = getuid();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
int uidNumber = TRI_Int32String(_uid.c_str());
|
|
||||||
|
|
||||||
if (TRI_errno() == TRI_ERROR_NO_ERROR) {
|
|
||||||
|
|
||||||
#ifdef TRI_HAVE_GETPWUID
|
|
||||||
passwd* p = getpwuid(uidNumber);
|
|
||||||
|
|
||||||
if (p == 0) {
|
|
||||||
LOG_FATAL_AND_EXIT("unknown numeric uid '%s'", _uid.c_str());
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
#ifdef TRI_HAVE_GETPWNAM
|
|
||||||
string name = _uid;
|
|
||||||
passwd* p = getpwnam(name.c_str());
|
|
||||||
|
|
||||||
if (p != 0) {
|
|
||||||
uidNumber = p->pw_uid;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
LOG_FATAL_AND_EXIT("cannot convert username '%s' to numeric uid", _uid.c_str());
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
LOG_FATAL_AND_EXIT("cannot convert username '%s' to numeric uid", _uid.c_str());
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
_effectiveUid = uidNumber;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// --SECTION-- END-OF-FILE
|
// --SECTION-- END-OF-FILE
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
|
@ -174,16 +174,10 @@ namespace triagens {
|
||||||
void stop ();
|
void stop ();
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief raises the privileges
|
/// @brief extracts the privileges from the command-line
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
void raisePrivileges ();
|
void extractPrivileges ();
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
/// @brief drops the privileges
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
void dropPrivileges ();
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief drops the privileges permanently
|
/// @brief drops the privileges permanently
|
||||||
|
@ -221,18 +215,6 @@ namespace triagens {
|
||||||
|
|
||||||
bool readConfigurationFile ();
|
bool readConfigurationFile ();
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
/// @brief extracts the real privileges
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
void storeRealPrivileges ();
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
/// @brief extracts the privileges from the command-line
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
void extractPrivileges ();
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// --SECTION-- private variables
|
// --SECTION-- private variables
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
@ -432,16 +414,10 @@ namespace triagens {
|
||||||
std::string _uid;
|
std::string _uid;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief real uid
|
/// @brief numeric uid
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
TRI_uid_t _realUid;
|
TRI_uid_t _numericUid;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
/// @brief effective uid
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
TRI_uid_t _effectiveUid;
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief the group id to use for the process
|
/// @brief the group id to use for the process
|
||||||
|
@ -462,17 +438,11 @@ namespace triagens {
|
||||||
|
|
||||||
std::string _gid;
|
std::string _gid;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief real gid
|
/// @brief numeric gid
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
TRI_gid_t _realGid;
|
TRI_gid_t _numericGid;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
/// @brief effective gid
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
TRI_gid_t _effectiveGid;
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief log application name
|
/// @brief log application name
|
||||||
|
|
Loading…
Reference in New Issue