1
0
Fork 0

Merge branch 'devel' of github.com:arangodb/ArangoDB into devel

This commit is contained in:
Willi Goesgens 2015-08-13 14:25:22 +02:00
commit d3cc9981b8
3 changed files with 104 additions and 208 deletions

View File

@ -1,6 +1,23 @@
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`
* Linux startup scripts and systemd configuration for arangod now try to

View File

@ -100,11 +100,9 @@ ApplicationServer::ApplicationServer (std::string const& name, std::string const
_userConfigFile(),
_systemConfigFile(),
_uid(),
_realUid(0),
_effectiveUid(0),
_numericUid(0),
_gid(),
_realGid(0),
_effectiveGid(0),
_numericGid(0),
_logApplicationName("arangod"),
_logFacility(""),
_logLevel("info"),
@ -123,9 +121,6 @@ ApplicationServer::ApplicationServer (std::string const& name, std::string const
_randomGenerator(3),
#endif
_finishedCondition() {
#ifndef _WIN32
storeRealPrivileges();
#endif
}
////////////////////////////////////////////////////////////////////////////////
@ -422,7 +417,7 @@ bool ApplicationServer::parse (int argc,
// .............................................................................
extractPrivileges();
dropPrivileges();
dropPrivilegesPermanently();
// .............................................................................
// setup logging
@ -538,8 +533,6 @@ void ApplicationServer::start () {
pthread_sigmask(SIG_SETMASK, &all, 0);
#endif
raisePrivileges();
// start all startable features
for (vector<ApplicationFeature*>::iterator i = _features.begin(); i != _features.end(); ++i) {
ApplicationFeature* feature = *i;
@ -567,8 +560,6 @@ void ApplicationServer::start () {
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
if (_effectiveGid != _realGid) {
int res = setegid(_realGid);
if (res != 0) {
LOG_FATAL_AND_EXIT("cannot set gid %d: %s", (int) _effectiveGid, strerror(errno));
}
if (_gid.empty()) {
_numericGid = 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
}
////////////////////////////////////////////////////////////////////////////////
/// @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));
}
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
}
_numericGid = gidNumber;
}
#endif
// then UID (because we are dropping)
#ifdef TRI_HAVE_SETUID
if (_effectiveUid != _realUid) {
int res = seteuid(_effectiveUid);
if (_uid.empty()) {
_numericUid = getuid();
}
else {
int uidNumber = TRI_Int32String(_uid.c_str());
if (res != 0) {
LOG_FATAL_AND_EXIT("cannot set uid %s: %s", _uid.c_str(), strerror(errno));
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
@ -700,32 +710,32 @@ void ApplicationServer::dropPrivileges () {
////////////////////////////////////////////////////////////////////////////////
void ApplicationServer::dropPrivilegesPermanently () {
raisePrivileges();
// clear all supplementary groups
#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) {
initgroups(pwent->pw_name, _effectiveGid);
if (pwent != nullptr) {
initgroups(pwent->pw_name, _numericGid);
}
}
#endif
// first GID
#ifdef TRI_HAVE_SETGID
if (_effectiveGid != _realGid) {
LOG_INFO("permanently changing the gid to %d", (int) _effectiveGid);
if (! _gid.empty()) {
LOG_INFO("permanently changing the gid to %d", (int) _numericGid);
int res = setgid(_effectiveGid);
int res = setgid(_numericGid);
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
@ -733,35 +743,19 @@ void ApplicationServer::dropPrivilegesPermanently () {
// then UID (because we are dropping)
#ifdef TRI_HAVE_SETUID
if (_effectiveUid != _realUid) {
LOG_INFO("permanently changing the uid to %d", (int) _effectiveUid);
if (! _uid.empty()) {
LOG_INFO("permanently changing the uid to %d", (int) _numericUid);
int res = setuid(_effectiveUid);
int res = setuid(_numericUid);
if (res != 0) {
LOG_FATAL_AND_EXIT("cannot set uid '%s': %s", _uid.c_str(), strerror(errno));
}
_realUid = _effectiveUid;
}
#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
// -----------------------------------------------------------------------------
@ -1023,91 +1017,6 @@ bool ApplicationServer::readConfigurationFile () {
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
// -----------------------------------------------------------------------------

View File

@ -174,16 +174,10 @@ namespace triagens {
void stop ();
////////////////////////////////////////////////////////////////////////////////
/// @brief raises the privileges
/// @brief extracts the privileges from the command-line
////////////////////////////////////////////////////////////////////////////////
void raisePrivileges ();
////////////////////////////////////////////////////////////////////////////////
/// @brief drops the privileges
////////////////////////////////////////////////////////////////////////////////
void dropPrivileges ();
void extractPrivileges ();
////////////////////////////////////////////////////////////////////////////////
/// @brief drops the privileges permanently
@ -221,18 +215,6 @@ namespace triagens {
bool readConfigurationFile ();
////////////////////////////////////////////////////////////////////////////////
/// @brief extracts the real privileges
////////////////////////////////////////////////////////////////////////////////
void storeRealPrivileges ();
////////////////////////////////////////////////////////////////////////////////
/// @brief extracts the privileges from the command-line
////////////////////////////////////////////////////////////////////////////////
void extractPrivileges ();
// -----------------------------------------------------------------------------
// --SECTION-- private variables
// -----------------------------------------------------------------------------
@ -432,16 +414,10 @@ namespace triagens {
std::string _uid;
////////////////////////////////////////////////////////////////////////////////
/// @brief real uid
/// @brief numeric uid
////////////////////////////////////////////////////////////////////////////////
TRI_uid_t _realUid;
////////////////////////////////////////////////////////////////////////////////
/// @brief effective uid
////////////////////////////////////////////////////////////////////////////////
TRI_uid_t _effectiveUid;
TRI_uid_t _numericUid;
////////////////////////////////////////////////////////////////////////////////
/// @brief the group id to use for the process
@ -461,18 +437,12 @@ namespace triagens {
////////////////////////////////////////////////////////////////////////////////
std::string _gid;
////////////////////////////////////////////////////////////////////////////////
/// @brief real gid
/////////////////////////////////////////////////////////////////////////////////
/// @brief numeric gid
////////////////////////////////////////////////////////////////////////////////
TRI_gid_t _realGid;
////////////////////////////////////////////////////////////////////////////////
/// @brief effective gid
////////////////////////////////////////////////////////////////////////////////
TRI_gid_t _effectiveGid;
TRI_gid_t _numericGid;
////////////////////////////////////////////////////////////////////////////////
/// @brief log application name