diff --git a/Documentation/Books/Users/Upgrading/UpgradingChanges30.mdpp b/Documentation/Books/Users/Upgrading/UpgradingChanges30.mdpp index 5a09b6db69..021c2898e7 100644 --- a/Documentation/Books/Users/Upgrading/UpgradingChanges30.mdpp +++ b/Documentation/Books/Users/Upgrading/UpgradingChanges30.mdpp @@ -45,7 +45,7 @@ name in AQL queries now requires quoting. The AQL optimizer rule "merge-traversal-filter" was renamed to "optimize-traversals". -!SECTION Command Line Options +!SECTION Command-line options Quite a few startup options in ArangoDB 2 were double negations (like `--server.disable-authentication false`). In ArangoDB 3 these are now expressed as @@ -82,6 +82,7 @@ in 3.0: upgrade at startup use `--database.auto-upgrade true`. To not perform it, use `--database.auto-upgrade false`. - `--check-version` has been renamed to `--database.check-version`. +- `--temp-path` has been renamed to `--temp.path`. !SUBSECTION Log verbosity, topics and output files @@ -157,9 +158,36 @@ been removed. These endpoints have been used by some ArangoDB-internal applicati and were not part of ArangoDB's public API. +!SECTION ArangoShell and client tools + +The ArangoShell (arangosh) and the other client tools bundled with ArangoDB can only +connect to an ArangoDB server of version 3.0 or higher. They will not connect to an +ArangoDB 2.8. This is because the server HTTP APIs have changed between 2.8 and 3.0, +and all client tools uses these APIs. + +In order to connect to earlier versions of ArangoDB with the client tools, an older +version of the client tools needs to be kept installed. + + +!SUBSECTION Command-line options changed + +For all client tools, the option `--server.disable-authentication` was renamed to +`--server.authentication`. Note that the meaning of the option `--server.authentication` +is the opposite of the previous `--server.disable-authentication`. + +The command-line option `--quiet` was removed from all client tools except arangosh +because it had no effect in those tools. + + +!SUBSECTION Arangobench + +In order to make its purpose more apparent, the former `arangob` client tool has +been renamed to `arangobench` in 3.0. + + !SECTION Miscellaneous changes The checksum calculation algorithm for the `collection.checksum()` method and its -corresponding REST API has changed in 3.0. Checksums calculated in 2.8 will differ -from checksums calculated with 3.0. +corresponding REST API has changed in 3.0. Checksums calculated in 3.0 will differ +from checksums calculated with 2.8 or before. diff --git a/arangod/RestServer/arangod.cpp b/arangod/RestServer/arangod.cpp index 2196b08662..9f1e0166ab 100644 --- a/arangod/RestServer/arangod.cpp +++ b/arangod/RestServer/arangod.cpp @@ -29,6 +29,7 @@ #include "ApplicationFeatures/DaemonFeature.h" #include "ApplicationFeatures/LanguageFeature.h" #include "ApplicationFeatures/NonceFeature.h" +#include "ApplicationFeatures/PrivilegeFeature.h" #include "ApplicationFeatures/ShutdownFeature.h" #include "ApplicationFeatures/SslFeature.h" #include "ApplicationFeatures/SupervisorFeature.h" @@ -121,6 +122,7 @@ int main(int argc, char* argv[]) { server.addFeature(new LoggerBufferFeature(&server)); server.addFeature(new LoggerFeature(&server, true)); server.addFeature(new NonceFeature(&server)); + server.addFeature(new PrivilegeFeature(&server)); server.addFeature(new QueryRegistryFeature(&server)); server.addFeature(new RandomFeature(&server)); server.addFeature(new RestServerFeature(&server, "arangodb")); diff --git a/arangosh/Shell/V8ShellFeature.cpp b/arangosh/Shell/V8ShellFeature.cpp index f6eefbbe95..e492619234 100644 --- a/arangosh/Shell/V8ShellFeature.cpp +++ b/arangosh/Shell/V8ShellFeature.cpp @@ -407,8 +407,10 @@ int V8ShellFeature::runShell(std::vector const& positionals) { } } - _console->printLine(""); - _console->printByeBye(); + if (!_console->quiet()) { + _console->printLine(""); + _console->printByeBye(); + } return promptError ? TRI_ERROR_INTERNAL : TRI_ERROR_NO_ERROR; } diff --git a/lib/ApplicationFeatures/ApplicationServer.cpp b/lib/ApplicationFeatures/ApplicationServer.cpp index e6dd9889de..b4a98285c0 100644 --- a/lib/ApplicationFeatures/ApplicationServer.cpp +++ b/lib/ApplicationFeatures/ApplicationServer.cpp @@ -23,6 +23,7 @@ #include "ApplicationServer.h" #include "ApplicationFeatures/ApplicationFeature.h" +#include "ApplicationFeatures/PrivilegeFeature.h" #include "Basics/StringUtils.h" #include "ProgramOptions/ArgumentParser.h" #include "Logger/Logger.h" @@ -58,7 +59,8 @@ void ApplicationServer::throwFeatureNotFoundException(std::string const& name) { "unknown feature '" + name + "'"); } -void ApplicationServer::throwFeatureNotEnabledException(std::string const& name) { +void ApplicationServer::throwFeatureNotEnabledException( + std::string const& name) { THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, "feature '" + name + "' is not enabled"); } @@ -80,11 +82,13 @@ void ApplicationServer::disableFeatures(std::vector const& names) { disableFeatures(names, false); } -void ApplicationServer::forceDisableFeatures(std::vector const& names) { +void ApplicationServer::forceDisableFeatures( + std::vector const& names) { disableFeatures(names, true); } -void ApplicationServer::disableFeatures(std::vector const& names, bool force) { +void ApplicationServer::disableFeatures(std::vector const& names, + bool force) { for (auto const& name : names) { auto feature = ApplicationServer::lookupFeature(name); @@ -329,7 +333,7 @@ void ApplicationServer::enableAutomaticFeatures() { void ApplicationServer::setupDependencies(bool failOnMissing) { LOG_TOPIC(TRACE, Logger::STARTUP) << "ApplicationServer::validateDependencies"; - + // calculate ancestors for all features for (auto& it : _features) { it.second->determineAncestors(); @@ -350,7 +354,6 @@ void ApplicationServer::setupDependencies(bool failOnMissing) { } }, true); } - // first insert all features, even the inactive ones std::vector features; @@ -498,7 +501,7 @@ void ApplicationServer::raisePrivilegesTemporarily() { THROW_ARANGO_EXCEPTION_MESSAGE( TRI_ERROR_INTERNAL, "must not raise privileges after dropping them"); } - + LOG_TOPIC(TRACE, Logger::STARTUP) << "raising privileges"; // TODO @@ -511,7 +514,7 @@ void ApplicationServer::dropPrivilegesTemporarily() { TRI_ERROR_INTERNAL, "must not try to drop privileges after dropping them"); } - + LOG_TOPIC(TRACE, Logger::STARTUP) << "dropping privileges"; // TODO @@ -524,7 +527,12 @@ void ApplicationServer::dropPrivilegesPermanently() { TRI_ERROR_INTERNAL, "must not try to drop privileges after dropping them"); } - _privilegesDropped = true; - // TODO + auto privilege = dynamic_cast(lookupFeature("Privilege")); + + if (privilege != nullptr) { + privilege->dropPrivilegesPermanently(); + } + + _privilegesDropped = true; } diff --git a/lib/ApplicationFeatures/ApplicationServer.h b/lib/ApplicationFeatures/ApplicationServer.h index 6f43af76be..cc591d8452 100644 --- a/lib/ApplicationFeatures/ApplicationServer.h +++ b/lib/ApplicationFeatures/ApplicationServer.h @@ -93,15 +93,25 @@ class ApplicationServer { public: static ApplicationServer* server; static ApplicationFeature* lookupFeature(std::string const&); - static bool isStopping() { return server != nullptr && server->_stopping.load(); } + static bool isStopping() { + return server != nullptr && server->_stopping.load(); + } - enum class FeatureState { UNINITIALIZED, INITIALIZED, VALIDATED, PREPARED, STARTED, STOPPED }; + enum class FeatureState { + UNINITIALIZED, + INITIALIZED, + VALIDATED, + PREPARED, + STARTED, + STOPPED + }; // returns the feature with the given name if known // throws otherwise - template + template static T* getFeature(std::string const& name) { - T* feature = dynamic_cast(application_features::ApplicationServer::lookupFeature(name)); + T* feature = dynamic_cast( + application_features::ApplicationServer::lookupFeature(name)); if (feature == nullptr) { throwFeatureNotFoundException(name); } @@ -110,7 +120,7 @@ class ApplicationServer { // returns the feature with the given name if known and enabled // throws otherwise - template + template static T* getEnabledFeature(std::string const& name) { T* feature = getFeature(name); if (!feature->isEnabled()) { @@ -166,11 +176,12 @@ class ApplicationServer { private: // throws an exception if a requested feature was not found static void throwFeatureNotFoundException(std::string const& name); - + // throws an exception if a requested feature is not enabled static void throwFeatureNotEnabledException(std::string const& name); - static void disableFeatures(std::vector const& names, bool force); + static void disableFeatures(std::vector const& names, + bool force); // fail and abort with the specified message void fail(std::string const& message); diff --git a/lib/ApplicationFeatures/PrivilegeFeature.cpp b/lib/ApplicationFeatures/PrivilegeFeature.cpp index 1d1849459d..10be646f7c 100644 --- a/lib/ApplicationFeatures/PrivilegeFeature.cpp +++ b/lib/ApplicationFeatures/PrivilegeFeature.cpp @@ -22,31 +22,49 @@ #include "PrivilegeFeature.h" -//YYY #warning FRANK TODO -#if 0 +#ifdef ARANGODB_HAVE_GETGRGID +#include +#endif -SslFeature::SslFeature(application_features::ApplicationServer* server) +#ifdef ARANGODB_HAVE_GETPWUID +#include +#endif + +#include "Basics/conversions.h" +#include "ProgramOptions/ProgramOptions.h" +#include "ProgramOptions/Section.h" + +using namespace arangodb; +using namespace arangodb::basics; +using namespace arangodb::options; + +PrivilegeFeature::PrivilegeFeature( + application_features::ApplicationServer* server) : ApplicationFeature(server, "Privilege") { setOptional(true); requiresElevatedPrivileges(false); startsAfter("Logger"); } -void SslFeature::collectOptions(std::shared_ptr options) { +void PrivilegeFeature::collectOptions(std::shared_ptr options) { #ifdef ARANGODB_HAVE_SETUID options->addHiddenOption("--uid", "switch to user-id after reading config files", - new UInt64Parameter(&_uid)); + new StringParameter(&_uid)); #endif #ifdef ARANGODB_HAVE_SETGID options->addHiddenOption("--gid", "switch to group-id after reading config files", - new UInt64Parameter(&_gid)); + new StringParameter(&_gid)); #endif } -void ApplicationServer::extractPrivileges() { +void PrivilegeFeature::prepare() { + extractPrivileges(); +} + +void PrivilegeFeature::extractPrivileges() { #ifdef ARANGODB_HAVE_SETGID if (_gid.empty()) { _numericGid = getgid(); @@ -121,7 +139,7 @@ void ApplicationServer::extractPrivileges() { #endif } -void ApplicationServer::dropPrivilegesPermanently() { +void PrivilegeFeature::dropPrivilegesPermanently() { #if defined(ARANGODB_HAVE_INITGROUPS) && defined(ARANGODB_HAVE_SETGID) && \ defined(ARANGODB_HAVE_SETUID) // clear all supplementary groups @@ -162,5 +180,3 @@ void ApplicationServer::dropPrivilegesPermanently() { } #endif } - -#endif diff --git a/lib/ApplicationFeatures/PrivilegeFeature.h b/lib/ApplicationFeatures/PrivilegeFeature.h index deedcc455d..37b4dc1b49 100644 --- a/lib/ApplicationFeatures/PrivilegeFeature.h +++ b/lib/ApplicationFeatures/PrivilegeFeature.h @@ -33,11 +33,20 @@ class PrivilegeFeature final : public application_features::ApplicationFeature { public: void collectOptions(std::shared_ptr) override final; void prepare() override final; - void start() override final; public: - std::string _path; - std::string _appname; + std::string _uid; + std::string _gid; + + public: + void dropPrivilegesPermanently(); + + private: + void extractPrivileges(); + + private: + TRI_uid_t _numericUid; + TRI_gid_t _numericGid; }; } diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index 2a12a182e5..83dc1f1e85 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -93,6 +93,7 @@ else () set(LIB_ARANGO_POSIX ApplicationFeatures/DaemonFeature.cpp ApplicationFeatures/PrivilegeFeature.cpp + ApplicationFeatures/PrivilegeFeature.cpp ApplicationFeatures/SupervisorFeature.cpp Basics/locks-posix.cpp Basics/memory-map-posix.cpp