1
0
Fork 0

Merge branch 'master' of https://github.com/fceller/ArangoDB into devel

This commit is contained in:
Frank Celler 2012-07-10 18:28:19 +02:00
commit 9c92948872
17 changed files with 321 additions and 116 deletions

View File

@ -1,19 +1,30 @@
v1.x.x (2012-XX-XX)
-------------------
* fixed issue #122: arangod doesn't start if <log.file> cannot be created * fixed issue #122: arangod doesn't start if <log.file> cannot be created
* fixed issue #121: wrong collection size reported * fixed issue #121: wrong collection size reported
* fixed escaping of document data in HTML admin front end * fixed escaping of document data in HTML admin front end
* added server startup option --server.disable-admin-interface to turn off the HTML admin interface * added server startup option --server.disable-admin-interface to turn off the
HTML admin interface
* honor server startup option --database.maximal-journal-size when creating new collections without specific journalsize setting. Previously, these collections were always created with journal file sizes of 32 MB and the --database.maximal-journal-size setting was ignored * honor server startup option --database.maximal-journal-size when creating new
collections without specific journalsize setting. Previously, these
collections were always created with journal file sizes of 32 MB and the
--database.maximal-journal-size setting was ignored
* added server startup option --database.wait-for-sync to control the default
behavior
v1.0.alpha3 (2012-06-30) v1.0.alpha3 (2012-06-30)
------------------------ ------------------------
* fixed issue #116: createCollection=create option doesn't work * fixed issue #116: createCollection=create option doesn't work
* fixed issue #115: Compilation issue under OSX 10.7 Lion & 10.8 Mountain Lion (homebrew) * fixed issue #115: Compilation issue under OSX 10.7 Lion & 10.8 Mountain Lion
(homebrew)
* fixed issue #114: image not found * fixed issue #114: image not found
@ -29,7 +40,8 @@ v1.0.alpha2 (2012-06-24)
* fixed issue #103: Should we cleanup the directory structure * fixed issue #103: Should we cleanup the directory structure
* fixed issue #100: "count" attribute exists in cursor response with "count: false" * fixed issue #100: "count" attribute exists in cursor response with "count:
false"
* fixed issue #84 explain command * fixed issue #84 explain command
@ -53,7 +65,8 @@ v1.0.alpha2 (2012-06-24)
* fixed several range-related assertion failures in the AQL query optimiser * fixed several range-related assertion failures in the AQL query optimiser
* fixed AQL query optimisations for some edge cases (e.g. nested subqueries with invalid constant filter expressions) * fixed AQL query optimisations for some edge cases (e.g. nested subqueries with
invalid constant filter expressions)
v1.0.alpha1 (2012-05-28) v1.0.alpha1 (2012-05-28)

View File

@ -50,6 +50,7 @@
/// <li>@ref CommandLineArangoDisableAdminInterface "server.disable-admin-interface"</li> /// <li>@ref CommandLineArangoDisableAdminInterface "server.disable-admin-interface"</li>
/// <li>@ref CommandLineArangoDirectory "database.directory"</li> /// <li>@ref CommandLineArangoDirectory "database.directory"</li>
/// <li>@ref CommandLineArangoMaximalJournalSize "database.maximal-journal-size"</li> /// <li>@ref CommandLineArangoMaximalJournalSize "database.maximal-journal-size"</li>
/// <li>@ref CommandLineArangoWaitForSync "database.wait-for-sync"</li>
/// <li>@ref CommandLineArangoRemoveOnDrop "database.remove-on-drop"</li> /// <li>@ref CommandLineArangoRemoveOnDrop "database.remove-on-drop"</li>
/// </ul> /// </ul>
/// </li> /// </li>
@ -175,6 +176,9 @@
/// @anchor CommandLineArangoMaximalJournalSize /// @anchor CommandLineArangoMaximalJournalSize
/// @copydetails triagens::arango::ArangoServer::_defaultMaximalSize /// @copydetails triagens::arango::ArangoServer::_defaultMaximalSize
/// ///
/// @anchor CommandLineArangoWaitForSync
/// @copydetails triagens::arango::ArangoServer::_defaultWaitForSync
///
/// @anchor CommandLineArangoRemoveOnDrop /// @anchor CommandLineArangoRemoveOnDrop
/// @copydetails triagens::arango::ArangoServer::_removeOnDrop /// @copydetails triagens::arango::ArangoServer::_removeOnDrop
/// ///

View File

@ -195,6 +195,7 @@ ArangoServer::ArangoServer (int argc, char** argv)
_removeOnDrop(true), _removeOnDrop(true),
_removeOnCompacted(true), _removeOnCompacted(true),
_defaultMaximalSize(TRI_JOURNAL_DEFAULT_MAXIMAL_SIZE), _defaultMaximalSize(TRI_JOURNAL_DEFAULT_MAXIMAL_SIZE),
_defaultWaitForSync(false),
_vocbase(0) { _vocbase(0) {
char* p; char* p;
@ -361,7 +362,7 @@ void ArangoServer::buildApplicationServer () {
// a http server // a http server
// ............................................................................. // .............................................................................
_applicationHttpServer = new ApplicationHttpServer(_applicationScheduler, _applicationDispatcher); _applicationHttpServer = new ApplicationHttpServer(_applicationServer, _applicationScheduler, _applicationDispatcher);
_applicationServer->addFeature(_applicationHttpServer); _applicationServer->addFeature(_applicationHttpServer);
// ............................................................................. // .............................................................................
@ -414,6 +415,7 @@ void ArangoServer::buildApplicationServer () {
additional["DATABASE Options:help-admin"] additional["DATABASE Options:help-admin"]
("database.remove-on-drop", &_removeOnDrop, "wipe a collection from disk after dropping") ("database.remove-on-drop", &_removeOnDrop, "wipe a collection from disk after dropping")
("database.maximal-journal-size", &_defaultMaximalSize, "default maximal journal size, can be overwritten when creating a collection") ("database.maximal-journal-size", &_defaultMaximalSize, "default maximal journal size, can be overwritten when creating a collection")
("database.wait-for-sync", &_defaultWaitForSync, "default wait-for-sync behavior, can be overwritten when creating a collection")
; ;
additional["DATABASE Options:help-devel"] additional["DATABASE Options:help-devel"]
@ -1102,6 +1104,7 @@ void ArangoServer::openDatabase () {
_vocbase->_removeOnDrop = _removeOnDrop; _vocbase->_removeOnDrop = _removeOnDrop;
_vocbase->_removeOnCompacted = _removeOnCompacted; _vocbase->_removeOnCompacted = _removeOnCompacted;
_vocbase->_defaultMaximalSize = _defaultMaximalSize; _vocbase->_defaultMaximalSize = _defaultMaximalSize;
_vocbase->_defaultWaitForSync = _defaultWaitForSync;
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////

View File

@ -392,6 +392,19 @@ namespace triagens {
uint64_t _defaultMaximalSize; uint64_t _defaultMaximalSize;
////////////////////////////////////////////////////////////////////////////////
/// @brief default journal size
///
/// @CMDOPT{--database.wait-for-size @CA{boolean}}
///
/// Default wait-for-sync value. Can be overwritten when creating a new
/// collection.
///
/// The default is @LIT{false}.
////////////////////////////////////////////////////////////////////////////////
bool _defaultWaitForSync;
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief unit tests /// @brief unit tests
/// ///

View File

@ -752,10 +752,10 @@ static v8::Handle<v8::Value> CreateVocBase (v8::Arguments const& argv, bool edge
"<properties>.journalSize too small"))); "<properties>.journalSize too small")));
} }
TRI_InitParameterCollection(&parameter, name.c_str(), (TRI_voc_size_t) s); TRI_InitParameterCollection(vocbase, &parameter, name.c_str(), (TRI_voc_size_t) s);
} }
else { else {
TRI_InitParameterCollection(&parameter, name.c_str(), vocbase->_defaultMaximalSize); TRI_InitParameterCollection(vocbase, &parameter, name.c_str(), vocbase->_defaultMaximalSize);
} }
if (p->Has(waitForSyncKey)) { if (p->Has(waitForSyncKey)) {
@ -767,7 +767,7 @@ static v8::Handle<v8::Value> CreateVocBase (v8::Arguments const& argv, bool edge
} }
} }
else { else {
TRI_InitParameterCollection(&parameter, name.c_str(), vocbase->_defaultMaximalSize); TRI_InitParameterCollection(vocbase, &parameter, name.c_str(), vocbase->_defaultMaximalSize);
} }
TRI_voc_cid_t cid = 0; TRI_voc_cid_t cid = 0;
@ -775,10 +775,12 @@ static v8::Handle<v8::Value> CreateVocBase (v8::Arguments const& argv, bool edge
// extract collection id // extract collection id
if (3 <= argv.Length()) { if (3 <= argv.Length()) {
v8::Handle<v8::Value> val = argv[2]; v8::Handle<v8::Value> val = argv[2];
if (!val->IsNull() && !val->IsUndefined()) {
// a pre-defined collection is passed when data is re-imported from a dump etc. // a pre-defined collection is passed when data is re-imported from a dump etc.
// this allows reproduction of data from different servers // this allows reproduction of data from different servers
if (! val->IsNull() && ! val->IsUndefined()) {
cid = TRI_ObjectToUInt64(argv[2]); cid = TRI_ObjectToUInt64(argv[2]);
if (cid <= 0) { if (cid <= 0) {
return scope.Close(v8::ThrowException( return scope.Close(v8::ThrowException(
TRI_CreateErrorObject(TRI_ERROR_BAD_PARAMETER, TRI_CreateErrorObject(TRI_ERROR_BAD_PARAMETER,

View File

@ -366,7 +366,8 @@ static bool CloseDataFiles (const TRI_vector_pointer_t* const files) {
/// @brief initializes a collection parameter block /// @brief initializes a collection parameter block
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
void TRI_InitParameterCollection (TRI_col_parameter_t* parameter, void TRI_InitParameterCollection (TRI_vocbase_t* vocbase,
TRI_col_parameter_t* parameter,
char const* name, char const* name,
TRI_voc_size_t maximalSize) { TRI_voc_size_t maximalSize) {
assert(parameter); assert(parameter);
@ -374,7 +375,7 @@ void TRI_InitParameterCollection (TRI_col_parameter_t* parameter,
parameter->_type = TRI_COL_TYPE_SIMPLE_DOCUMENT; parameter->_type = TRI_COL_TYPE_SIMPLE_DOCUMENT;
parameter->_waitForSync = false; parameter->_waitForSync = vocbase->_defaultWaitForSync;
parameter->_maximalSize = (maximalSize / PageSize) * PageSize; parameter->_maximalSize = (maximalSize / PageSize) * PageSize;
parameter->_isSystem = false; parameter->_isSystem = false;

View File

@ -230,7 +230,8 @@ TRI_collection_t;
/// @brief initializes a collection parameter block /// @brief initializes a collection parameter block
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
void TRI_InitParameterCollection (TRI_col_parameter_t*, void TRI_InitParameterCollection (TRI_vocbase_t* vocbase,
TRI_col_parameter_t*,
char const* name, char const* name,
TRI_voc_size_t maximalSize); TRI_voc_size_t maximalSize);

View File

@ -910,7 +910,7 @@ TRI_shaper_t* TRI_CreateVocShaper (TRI_vocbase_t* vocbase,
TRI_col_parameter_t parameter; TRI_col_parameter_t parameter;
bool ok; bool ok;
TRI_InitParameterCollection(&parameter, name, SHAPER_DATAFILE_SIZE); TRI_InitParameterCollection(vocbase, &parameter, name, SHAPER_DATAFILE_SIZE);
collection = TRI_CreateBlobCollection(vocbase, path, &parameter); collection = TRI_CreateBlobCollection(vocbase, path, &parameter);

View File

@ -719,10 +719,9 @@ static int ManifestCollectionVocBase (TRI_vocbase_t* vocbase, TRI_vocbase_col_t*
TRI_sim_collection_t* sim; TRI_sim_collection_t* sim;
TRI_col_parameter_t parameter; TRI_col_parameter_t parameter;
TRI_InitParameterCollection(&parameter, collection->_name, vocbase->_defaultMaximalSize); TRI_InitParameterCollection(vocbase, &parameter, collection->_name, vocbase->_defaultMaximalSize);
parameter._type = type; parameter._type = type;
parameter._waitForSync = false;
sim = TRI_CreateSimCollection(vocbase, vocbase->_path, &parameter, collection->_cid); sim = TRI_CreateSimCollection(vocbase, vocbase->_path, &parameter, collection->_cid);
@ -1100,6 +1099,7 @@ TRI_vocbase_t* TRI_OpenVocBase (char const* path) {
// defaults // defaults
vocbase->_removeOnDrop = true; vocbase->_removeOnDrop = true;
vocbase->_removeOnCompacted = true; vocbase->_removeOnCompacted = true;
vocbase->_defaultWaitForSync = false;
vocbase->_defaultMaximalSize = TRI_JOURNAL_DEFAULT_MAXIMAL_SIZE; vocbase->_defaultMaximalSize = TRI_JOURNAL_DEFAULT_MAXIMAL_SIZE;
// scan the database path for collections // scan the database path for collections

View File

@ -347,6 +347,7 @@ typedef struct TRI_vocbase_s {
bool _removeOnDrop; // wipe collection from disk after dropping bool _removeOnDrop; // wipe collection from disk after dropping
bool _removeOnCompacted; // wipe datafile from disk after compaction bool _removeOnCompacted; // wipe datafile from disk after compaction
bool _defaultWaitForSync;
TRI_voc_size_t _defaultMaximalSize; TRI_voc_size_t _defaultMaximalSize;
TRI_read_write_lock_t _lock; TRI_read_write_lock_t _lock;

View File

@ -116,9 +116,11 @@ ApplicationServer::ApplicationServer (string const& title, string const& version
_systemConfigFile(), _systemConfigFile(),
_systemConfigPath(), _systemConfigPath(),
_uid(), _uid(),
_loggingUid(0), _realUid(0),
_effectiveUid(0),
_gid(), _gid(),
_loggingGid(0), _realGid(0),
_effectiveGid(0),
_logApplicationName("triagens"), _logApplicationName("triagens"),
_logHostName("-"), _logHostName("-"),
_logFacility("-"), _logFacility("-"),
@ -193,24 +195,6 @@ void ApplicationServer::setUserConfigFile (string const& name) {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
void ApplicationServer::setupLogging () { void ApplicationServer::setupLogging () {
#ifdef TRI_HAVE_SETGID
gid_t gid;
#endif
#ifdef TRI_HAVE_SETUID
uid_t uid;
#endif
#ifdef TRI_HAVE_SETGID
gid = getegid();
setegid(_loggingGid);
#endif
#ifdef TRI_HAVE_SETUID
uid = geteuid();
seteuid(_loggingUid);
#endif
bool threaded = TRI_ShutdownLogging(); bool threaded = TRI_ShutdownLogging();
TRI_InitialiseLogging(threaded); TRI_InitialiseLogging(threaded);
@ -250,14 +234,6 @@ void ApplicationServer::setupLogging () {
} }
} }
TRI_CreateLogAppenderSyslog(_logPrefix, _logSyslog); TRI_CreateLogAppenderSyslog(_logPrefix, _logSyslog);
#ifdef TRI_HAVE_SETGID
setegid(gid);
#endif
#ifdef TRI_HAVE_SETUID
seteuid(uid);
#endif
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -346,8 +322,18 @@ bool ApplicationServer::parse (int argc,
exit(EXIT_SUCCESS); exit(EXIT_SUCCESS);
} }
// .............................................................................
// UID and GID
// .............................................................................
storeRealPrivileges();
extractPrivileges();
dropPrivileges();
// .............................................................................
// setup logging // setup logging
storeLoggingPrivileges(); // .............................................................................
setupLogging(); setupLogging();
// ............................................................................. // .............................................................................
@ -375,7 +361,6 @@ bool ApplicationServer::parse (int argc,
// re-set logging using the additional config file entries // re-set logging using the additional config file entries
setupLogging(); setupLogging();
// ............................................................................. // .............................................................................
// parse phase 2 // parse phase 2
// ............................................................................. // .............................................................................
@ -407,12 +392,6 @@ bool ApplicationServer::parse (int argc,
} }
} }
// .............................................................................
// now drop all privilegs
// .............................................................................
dropPriviliges();
return true; return true;
} }
@ -489,6 +468,8 @@ void ApplicationServer::start () {
LOGGER_TRACE << "opened server feature '" << feature->getName() << "'"; LOGGER_TRACE << "opened server feature '" << feature->getName() << "'";
} }
dropPrivilegesPermanently();
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -588,6 +569,124 @@ void ApplicationServer::shutdown () {
} }
} }
////////////////////////////////////////////////////////////////////////////////
/// @brief raise the privileges
////////////////////////////////////////////////////////////////////////////////
void ApplicationServer::raisePrivileges () {
#ifdef TRI_HAVE_SETGID
if (_effectiveGid != _realGid) {
int res = setegid(_realGid);
if (res != 0) {
LOGGER_FATAL << "cannot set gid '" << _effectiveGid << "', because " << strerror(errno);
TRI_ShutdownLogging();
exit(EXIT_FAILURE);
}
}
#endif
#ifdef TRI_HAVE_SETUID
if (_effectiveUid != _realUid) {
int res = seteuid(_realUid);
if (res != 0) {
LOGGER_FATAL << "cannot set uid '" << _uid << "', because " << strerror(errno);
TRI_ShutdownLogging();
exit(EXIT_FAILURE);
}
}
#endif
}
////////////////////////////////////////////////////////////////////////////////
/// @brief drops the privileges
////////////////////////////////////////////////////////////////////////////////
void ApplicationServer::dropPrivileges () {
#ifdef TRI_HAVE_SETGID
if (_effectiveGid != _realGid) {
int res = setegid(_effectiveGid);
if (res != 0) {
LOGGER_FATAL << "cannot set gid '" << _effectiveGid << "', because " << strerror(errno);
cerr << "cannot set gid '" << _effectiveGid << "', because " << strerror(errno) << endl;
TRI_ShutdownLogging();
exit(EXIT_FAILURE);
}
}
#endif
#ifdef TRI_HAVE_SETUID
if (_effectiveUid != _realUid) {
int res = seteuid(_effectiveUid);
if (res != 0) {
LOGGER_FATAL << "cannot set uid '" << _uid << "', because " << strerror(errno);
cerr << "cannot set uid '" << _uid << "', because " << strerror(errno) << endl;
TRI_ShutdownLogging();
exit(EXIT_FAILURE);
}
}
#endif
}
////////////////////////////////////////////////////////////////////////////////
/// @brief drops the privileges permanently
////////////////////////////////////////////////////////////////////////////////
void ApplicationServer::dropPrivilegesPermanently () {
raisePrivileges();
#ifdef TRI_HAVE_SETGID
if (_effectiveGid != _realGid) {
LOGGER_INFO << "permanently changing the gid to '" << _effectiveGid << "'";
int res = setgid(_effectiveGid);
if (res != 0) {
LOGGER_FATAL << "cannot set gid '" << _effectiveGid << "', because " << strerror(errno);
cerr << "cannot set gid '" << _effectiveGid << "', because " << strerror(errno) << endl;
TRI_ShutdownLogging();
exit(EXIT_FAILURE);
}
_realGid = _effectiveGid;
}
#endif
#ifdef TRI_HAVE_SETUID
if (_effectiveUid != _realUid) {
LOGGER_INFO << "permanently changing the uid to '" << _effectiveUid << "'";
int res = setuid(_effectiveUid);
if (res != 0) {
LOGGER_FATAL << "cannot set uid '" << _uid << "', because " << strerror(errno);
cerr << "cannot set uid '" << _uid << "', because " << strerror(errno) << endl;
TRI_ShutdownLogging();
exit(EXIT_FAILURE);
}
_realUid = _effectiveUid;
}
#endif
}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @} /// @}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -853,40 +952,26 @@ bool ApplicationServer::readConfigurationFile () {
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief saves the logging privileges /// @brief extract the privileges to use
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
void ApplicationServer::storeLoggingPrivileges () { void ApplicationServer::extractPrivileges() {
#ifdef TRI_HAVE_SETGID
_loggingGid = getegid();
#endif
#ifdef TRI_HAVE_SETUID
_loggingUid = geteuid();
#endif
}
////////////////////////////////////////////////////////////////////////////////
/// @brief drops the privileges
////////////////////////////////////////////////////////////////////////////////
void ApplicationServer::dropPriviliges () {
#ifdef TRI_HAVE_SETGID #ifdef TRI_HAVE_SETGID
if (! _gid.empty()) { if (_gid.empty()) {
LOGGER_TRACE << "trying to switch to group '" << _gid << "'"; _effectiveGid = getgid();
}
else {
int gidNumber = TRI_Int32String(_gid.c_str()); int gidNumber = TRI_Int32String(_gid.c_str());
if (TRI_errno() == TRI_ERROR_NO_ERROR) { if (TRI_errno() == TRI_ERROR_NO_ERROR) {
LOGGER_TRACE << "trying to switch to numeric gid '" << gidNumber << "' for '" << _gid << "'";
#ifdef TRI_HAVE_GETGRGID #ifdef TRI_HAVE_GETGRGID
group* g = getgrgid(gidNumber); group* g = getgrgid(gidNumber);
if (g == 0) { if (g == 0) {
cerr << "unknown numeric gid '" << _gid << "'" << endl;
LOGGER_FATAL << "unknown numeric gid '" << _gid << "'"; LOGGER_FATAL << "unknown numeric gid '" << _gid << "'";
TRI_ShutdownLogging(); TRI_ShutdownLogging();
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
@ -900,47 +985,41 @@ void ApplicationServer::dropPriviliges () {
if (g != 0) { if (g != 0) {
gidNumber = g->gr_gid; gidNumber = g->gr_gid;
LOGGER_TRACE << "trying to switch to numeric gid '" << gidNumber << "'";
} }
else { else {
cerr << "cannot convert groupname '" << _gid << "' to numeric gid" << endl;
LOGGER_FATAL << "cannot convert groupname '" << _gid << "' to numeric gid"; LOGGER_FATAL << "cannot convert groupname '" << _gid << "' to numeric gid";
TRI_ShutdownLogging(); TRI_ShutdownLogging();
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
#else #else
cerr << "cannot convert groupname '" << _gid << "' to numeric gid" << endl;
LOGGER_FATAL << "cannot convert groupname '" << _gid << "' to numeric gid"; LOGGER_FATAL << "cannot convert groupname '" << _gid << "' to numeric gid";
TRI_ShutdownLogging(); TRI_ShutdownLogging();
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
#endif #endif
} }
LOGGER_INFO << "changing gid to '" << gidNumber << "'"; _effectiveGid = gidNumber;
int res = setegid(gidNumber);
if (res != 0) {
LOGGER_FATAL << "cannot set gid '" << _gid << "', because " << strerror(errno);
TRI_ShutdownLogging();
exit(EXIT_FAILURE);
}
} }
#endif #endif
#ifdef TRI_HAVE_SETUID #ifdef TRI_HAVE_SETUID
if (! _uid.empty()) { if (_uid.empty()) {
LOGGER_TRACE << "trying to switch to user '" << _uid << "'"; _effectiveUid = getuid();
}
else {
int uidNumber = TRI_Int32String(_uid.c_str()); int uidNumber = TRI_Int32String(_uid.c_str());
if (TRI_errno() == TRI_ERROR_NO_ERROR) { if (TRI_errno() == TRI_ERROR_NO_ERROR) {
LOGGER_TRACE << "trying to switch to numeric uid '" << uidNumber << "' for '" << _uid << "'";
#ifdef TRI_HAVE_GETPWUID #ifdef TRI_HAVE_GETPWUID
passwd* p = getpwuid(uidNumber); passwd* p = getpwuid(uidNumber);
if (p == 0) { if (p == 0) {
cerr << "unknown numeric uid '" << _uid << "'" << endl;
LOGGER_FATAL << "unknown numeric uid '" << _uid << "'"; LOGGER_FATAL << "unknown numeric uid '" << _uid << "'";
TRI_ShutdownLogging(); TRI_ShutdownLogging();
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
@ -954,34 +1033,41 @@ void ApplicationServer::dropPriviliges () {
if (p != 0) { if (p != 0) {
uidNumber = p->pw_uid; uidNumber = p->pw_uid;
LOGGER_TRACE << "trying to switch to numeric uid '" << uidNumber << "'";
} }
else { else {
cerr << "cannot convert username '" << _uid << "' to numeric uid" << endl;
LOGGER_FATAL << "cannot convert username '" << _uid << "' to numeric uid"; LOGGER_FATAL << "cannot convert username '" << _uid << "' to numeric uid";
TRI_ShutdownLogging(); TRI_ShutdownLogging();
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
#else #else
cerr << "cannot convert username '" << _uid << "' to numeric uid" << endl;
LOGGER_FATAL << "cannot convert username '" << _uid << "' to numeric uid"; LOGGER_FATAL << "cannot convert username '" << _uid << "' to numeric uid";
TRI_ShutdownLogging(); TRI_ShutdownLogging();
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
#endif #endif
} }
LOGGER_INFO << "changing uid to '" << uidNumber << "'"; _effectiveUid = uidNumber;
int res = seteuid(uidNumber);
if (res != 0) {
LOGGER_FATAL << "cannot set uid '" << _uid << "', because " << strerror(errno);
TRI_ShutdownLogging();
exit(EXIT_FAILURE);
}
} }
#endif #endif
} }
////////////////////////////////////////////////////////////////////////////////
/// @brief saves the logging privileges
////////////////////////////////////////////////////////////////////////////////
void ApplicationServer::storeRealPrivileges () {
#ifdef TRI_HAVE_SETGID
_realGid = getgid();
#endif
#ifdef TRI_HAVE_SETUID
_realUid = getuid();
#endif
}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @} /// @}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////

View File

@ -233,6 +233,24 @@ namespace triagens {
void shutdown (); void shutdown ();
////////////////////////////////////////////////////////////////////////////////
/// @brief raises the privileges
////////////////////////////////////////////////////////////////////////////////
void raisePrivileges ();
////////////////////////////////////////////////////////////////////////////////
/// @brief drops the privileges
////////////////////////////////////////////////////////////////////////////////
void dropPrivileges ();
////////////////////////////////////////////////////////////////////////////////
/// @brief drops the privileges permanently
////////////////////////////////////////////////////////////////////////////////
void dropPrivilegesPermanently ();
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @} /// @}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -282,16 +300,16 @@ namespace triagens {
bool readConfigurationFile (); bool readConfigurationFile ();
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief saves the logging privileges /// @brief extracts the real privileges
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
void storeLoggingPrivileges (); void storeRealPrivileges ();
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief drops the privileges /// @brief extracts the privileges from the command-line
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
void dropPriviliges (); void extractPrivileges ();
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @} /// @}
@ -484,10 +502,16 @@ namespace triagens {
string _uid; string _uid;
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief uid for logging /// @brief real uid
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
uid_t _loggingUid; uid_t _realUid;
////////////////////////////////////////////////////////////////////////////////
/// @brief effective uid
////////////////////////////////////////////////////////////////////////////////
uid_t _effectiveUid;
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief the group id to use for the process /// @brief the group id to use for the process
@ -508,10 +532,16 @@ namespace triagens {
string _gid; string _gid;
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief gid for logging /// @brief real gid
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
gid_t _loggingGid; gid_t _realGid;
////////////////////////////////////////////////////////////////////////////////
/// @brief effective gid
////////////////////////////////////////////////////////////////////////////////
gid_t _effectiveGid;
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief log application name /// @brief log application name

View File

@ -51,9 +51,11 @@ using namespace std;
/// @brief constructor /// @brief constructor
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
ApplicationHttpServer::ApplicationHttpServer (ApplicationScheduler* applicationScheduler, ApplicationHttpServer::ApplicationHttpServer (ApplicationServer* applicationServer,
ApplicationScheduler* applicationScheduler,
ApplicationDispatcher* applicationDispatcher) ApplicationDispatcher* applicationDispatcher)
: ApplicationFeature("HttpServer"), : ApplicationFeature("HttpServer"),
_applicationServer(applicationServer),
_applicationScheduler(applicationScheduler), _applicationScheduler(applicationScheduler),
_applicationDispatcher(applicationDispatcher), _applicationDispatcher(applicationDispatcher),
_showPort(true), _showPort(true),
@ -253,6 +255,8 @@ HttpServer* ApplicationHttpServer::buildHttpServer (HttpServer* httpServer,
deque<AddressPort> addresses; deque<AddressPort> addresses;
addresses.insert(addresses.begin(), ports.begin(), ports.end()); addresses.insert(addresses.begin(), ports.begin(), ports.end());
_applicationServer->raisePrivileges();
while (! addresses.empty()) { while (! addresses.empty()) {
AddressPort ap = addresses[0]; AddressPort ap = addresses[0];
addresses.pop_front(); addresses.pop_front();
@ -291,6 +295,8 @@ HttpServer* ApplicationHttpServer::buildHttpServer (HttpServer* httpServer,
} }
} }
_applicationServer->dropPrivileges();
return httpServer; return httpServer;
} }

View File

@ -80,7 +80,9 @@ namespace triagens {
/// @brief constructor /// @brief constructor
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
ApplicationHttpServer (ApplicationScheduler*, ApplicationDispatcher*); ApplicationHttpServer (ApplicationServer*,
ApplicationScheduler*,
ApplicationDispatcher*);
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief destructor /// @brief destructor
@ -206,6 +208,12 @@ namespace triagens {
protected: protected:
////////////////////////////////////////////////////////////////////////////////
/// @brief application server
////////////////////////////////////////////////////////////////////////////////
ApplicationServer* _applicationServer;
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief application scheduler /// @brief application scheduler
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////

View File

@ -91,9 +91,11 @@ namespace {
/// @brief constructor /// @brief constructor
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
ApplicationHttpsServer::ApplicationHttpsServer (ApplicationScheduler* applicationScheduler, ApplicationHttpsServer::ApplicationHttpsServer (ApplicationServer* applicationServer,
ApplicationScheduler* applicationScheduler,
ApplicationDispatcher* applicationDispatcher) ApplicationDispatcher* applicationDispatcher)
: ApplicationFeature("HttpsServer"), : ApplicationFeature("HttpsServer"),
_applicationServer(applicationServer),
_applicationScheduler(applicationScheduler), _applicationScheduler(applicationScheduler),
_applicationDispatcher(applicationDispatcher), _applicationDispatcher(applicationDispatcher),
_showPort(true), _showPort(true),
@ -287,6 +289,8 @@ HttpsServer* ApplicationHttpsServer::buildHttpsServer (HttpHandlerFactory* httpH
deque<AddressPort> addresses; deque<AddressPort> addresses;
addresses.insert(addresses.begin(), ports.begin(), ports.end()); addresses.insert(addresses.begin(), ports.begin(), ports.end());
_applicationServer->raisePrivileges();
while (! addresses.empty()) { while (! addresses.empty()) {
AddressPort ap = addresses[0]; AddressPort ap = addresses[0];
addresses.pop_front(); addresses.pop_front();
@ -325,6 +329,8 @@ HttpsServer* ApplicationHttpsServer::buildHttpsServer (HttpHandlerFactory* httpH
} }
} }
_applicationServer->dropPrivileges();
return httpsServer; return httpsServer;
} }

View File

@ -82,7 +82,7 @@ namespace triagens {
/// @brief constructor /// @brief constructor
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
ApplicationHttpsServer (ApplicationScheduler*, ApplicationDispatcher*); ApplicationHttpsServer (ApplicationServer*, ApplicationScheduler*, ApplicationDispatcher*);
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief destructor /// @brief destructor
@ -194,6 +194,12 @@ namespace triagens {
protected: protected:
////////////////////////////////////////////////////////////////////////////////
/// @brief application server
////////////////////////////////////////////////////////////////////////////////
ApplicationServer* _applicationServer;
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief application scheduler /// @brief application scheduler
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////

View File

@ -334,6 +334,8 @@ void AnyServer::prepareServer () {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
int AnyServer::startupSupervisor () { int AnyServer::startupSupervisor () {
static time_t MIN_TIME_ALIVE_IN_SEC = 30;
LOGGER_INFO << "starting up in supervisor mode"; LOGGER_INFO << "starting up in supervisor mode";
string current; string current;
@ -341,10 +343,13 @@ int AnyServer::startupSupervisor () {
// main process // main process
if (result == 0) { if (result == 0) {
return 0;
} }
// child process // child process
else if (result == 1) { else if (result == 1) {
time_t startTime = time(0);
time_t t;
bool done = false; bool done = false;
result = 0; result = 0;
@ -368,10 +373,20 @@ int AnyServer::startupSupervisor () {
done = true; done = true;
} }
else { else {
LOGGER_ERROR << "child " << pid << " died of a horrible death, exit status " << WEXITSTATUS(status); t = time(0) - startTime;
LOGGER_ERROR << "child " << pid << " died a horrible death, exit status " << WEXITSTATUS(status);
if (t < MIN_TIME_ALIVE_IN_SEC) {
LOGGER_FATAL << "child only survived for " << t << " seconds, this will not work - please fix the error first";
done = true;
}
else {
done = false; done = false;
} }
} }
}
else if (WIFSIGNALED(status)) { else if (WIFSIGNALED(status)) {
switch (WTERMSIG(status)) { switch (WTERMSIG(status)) {
case 2: case 2:
@ -382,13 +397,23 @@ int AnyServer::startupSupervisor () {
break; break;
default: default:
LOGGER_ERROR << "child " << pid << " died of a horrible death, signal " << WTERMSIG(status); t = time(0) - startTime;
LOGGER_ERROR << "child " << pid << " died a horrible death, signal " << WTERMSIG(status);
if (t < MIN_TIME_ALIVE_IN_SEC) {
LOGGER_FATAL << "child only survived for " << t << " seconds, this will not work - please fix the error first";
done = true;
}
else {
done = false; done = false;
}
break; break;
} }
} }
else { else {
LOGGER_ERROR << "child " << pid << " died of a horrible death"; LOGGER_ERROR << "child " << pid << " died a horrible death, unknown cause";
done = false; done = false;
} }
} }