passenger 5.2.3 → 5.3.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of passenger might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG +13 -0
- data/CONTRIBUTORS +5 -1
- data/build/agent.rb +22 -2
- data/build/cxx_tests.rb +41 -5
- data/build/misc.rb +4 -1
- data/build/support/cxx_dependency_map.rb +1746 -908
- data/build/support/vendor/cxx_hinted_parser/CxxHintedParser.sublime-project +8 -0
- data/build/support/vendor/cxx_hinted_parser/Gemfile +5 -0
- data/build/support/vendor/cxx_hinted_parser/Gemfile.lock +30 -0
- data/{src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core → build/support/vendor/cxx_hinted_parser}/LICENSE.md +1 -1
- data/build/support/vendor/cxx_hinted_parser/README.md +95 -0
- data/build/support/vendor/cxx_hinted_parser/Rakefile +4 -0
- data/{src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_rails/lib/union_station_hooks_rails/initialize.rb → build/support/vendor/cxx_hinted_parser/lib/cxx_hinted_parser.rb} +2 -9
- data/build/support/vendor/cxx_hinted_parser/lib/cxx_hinted_parser/parser.rb +239 -0
- data/dev/ci/README.md +15 -2
- data/dev/ci/lib/set-container-envvars.sh +6 -0
- data/dev/ci/lib/setup-container.sh +4 -1
- data/dev/ci/scripts/debug-console-wrapper.sh +3 -1
- data/dev/ci/setup-host +5 -0
- data/dev/ci/tests/binaries/Jenkinsfile +105 -0
- data/dev/ci/tests/binaries/build-linux +38 -0
- data/dev/ci/tests/binaries/build-macos +40 -0
- data/dev/ci/tests/binaries/prepare-macos +38 -0
- data/dev/ci/tests/binaries/test-linux +45 -0
- data/dev/ci/tests/binaries/test-macos +38 -0
- data/dev/ci/tests/debian/Jenkinsfile +2 -2
- data/dev/ci/tests/rpm/Jenkinsfile +1 -1
- data/dev/configkit-schemas/index.json +3 -24
- data/dev/vagrant/nginx_rakefile +0 -1
- data/package.json +15 -5
- data/resources/templates/error_renderer/.editorconfig +19 -0
- data/resources/templates/error_renderer/with_details/README.md +9 -0
- data/resources/templates/error_renderer/with_details/dist/bundle.js +33 -0
- data/resources/templates/error_renderer/with_details/dist/styles.css +17 -0
- data/resources/templates/error_renderer/with_details/src/DetailsView.jsx +52 -0
- data/resources/templates/error_renderer/with_details/src/GetHelpView.jsx +61 -0
- data/resources/templates/error_renderer/with_details/src/JourneyView.css +50 -0
- data/resources/templates/error_renderer/with_details/src/JourneyView.jsx +621 -0
- data/resources/templates/error_renderer/with_details/src/PageMain.css +114 -0
- data/resources/templates/error_renderer/with_details/src/PageMain.jsx +136 -0
- data/resources/templates/error_renderer/with_details/src/ProblemDescriptionView.jsx +14 -0
- data/resources/templates/error_renderer/with_details/src/ProcessDetailsView.jsx +56 -0
- data/resources/templates/error_renderer/with_details/src/SolutionDescriptionView.css +5 -0
- data/resources/templates/error_renderer/with_details/src/SolutionDescriptionView.jsx +15 -0
- data/resources/templates/error_renderer/with_details/src/SummaryView.jsx +35 -0
- data/resources/templates/error_renderer/with_details/src/SystemComponentView.css +34 -0
- data/resources/templates/error_renderer/with_details/src/SystemComponentView.jsx +168 -0
- data/resources/templates/error_renderer/with_details/src/SystemComponentsView.css +13 -0
- data/resources/templates/error_renderer/with_details/src/SystemComponentsView.jsx +116 -0
- data/resources/templates/error_renderer/with_details/src/Tab.jsx +12 -0
- data/resources/templates/error_renderer/with_details/src/Tabs.jsx +104 -0
- data/resources/templates/error_renderer/with_details/src/bootstrap/bootstrap.css +3446 -0
- data/resources/templates/error_renderer/with_details/src/bootstrap/bootstrap.js +293 -0
- data/resources/templates/error_renderer/with_details/src/bootstrap/config.json +401 -0
- data/resources/templates/error_renderer/with_details/src/index.html.template +22 -0
- data/resources/templates/error_renderer/with_details/src/index.jsx +23 -0
- data/resources/templates/error_renderer/with_details/webpack.config.js +47 -0
- data/resources/templates/error_renderer/without_details/dist/bundle.js +1 -0
- data/resources/templates/error_renderer/without_details/dist/styles.css +1 -0
- data/resources/templates/{undisclosed_error.html.template → error_renderer/without_details/src/index.html.template} +7 -11
- data/resources/templates/error_renderer/without_details/src/index.js +1 -0
- data/resources/templates/{error_layout.css → error_renderer/without_details/src/main.css} +5 -2
- data/resources/templates/error_renderer/without_details/webpack.config.js +42 -0
- data/src/agent/AgentMain.cpp +3 -3
- data/src/agent/Core/ApplicationPool/BasicProcessInfo.h +13 -0
- data/src/agent/Core/ApplicationPool/Common.h +3 -4
- data/src/agent/Core/ApplicationPool/Context.h +27 -17
- data/src/agent/Core/ApplicationPool/Group.h +3 -1
- data/src/agent/Core/ApplicationPool/Group/InitializationAndShutdown.cpp +2 -12
- data/src/agent/Core/ApplicationPool/Group/InternalUtils.cpp +55 -10
- data/src/agent/Core/ApplicationPool/Group/LifetimeAndBasics.cpp +1 -1
- data/src/agent/Core/ApplicationPool/Group/OutOfBandWork.cpp +1 -1
- data/src/agent/Core/ApplicationPool/Group/SpawningAndRestarting.cpp +13 -6
- data/src/agent/Core/ApplicationPool/Implementation.cpp +16 -100
- data/src/agent/Core/ApplicationPool/Options.h +8 -65
- data/src/agent/Core/ApplicationPool/Pool.h +4 -21
- data/src/agent/Core/ApplicationPool/Pool/AnalyticsCollection.cpp +1 -60
- data/src/agent/Core/ApplicationPool/Pool/GeneralUtils.cpp +10 -13
- data/src/agent/Core/ApplicationPool/Pool/InitializationAndShutdown.cpp +3 -8
- data/src/agent/Core/ApplicationPool/Pool/Miscellaneous.cpp +2 -34
- data/src/agent/Core/ApplicationPool/Pool/StateInspection.cpp +1 -1
- data/src/agent/Core/ApplicationPool/Process.cpp +17 -12
- data/src/agent/Core/ApplicationPool/Process.h +146 -93
- data/src/agent/Core/ApplicationPool/Session.h +2 -2
- data/src/agent/Core/ApplicationPool/Socket.h +28 -27
- data/src/agent/Core/Config.h +1 -3
- data/src/agent/Core/ConfigChange.cpp +2 -4
- data/src/agent/Core/Controller.h +2 -8
- data/src/agent/Core/Controller/BufferBody.cpp +0 -2
- data/src/agent/Core/Controller/CheckoutSession.cpp +12 -24
- data/src/agent/Core/Controller/Config.h +1 -9
- data/src/agent/Core/Controller/ForwardResponse.cpp +0 -34
- data/src/agent/Core/Controller/Hooks.cpp +0 -7
- data/src/agent/Core/Controller/InitRequest.cpp +0 -43
- data/src/agent/Core/Controller/InitializationAndShutdown.cpp +0 -4
- data/src/agent/Core/Controller/Request.h +1 -35
- data/src/agent/Core/Controller/SendRequest.cpp +0 -32
- data/src/agent/Core/CoreMain.cpp +19 -32
- data/src/agent/Core/SpawningKit/Config.h +329 -55
- data/src/agent/Core/SpawningKit/Config/AutoGeneratedCode.h +369 -0
- data/src/agent/Core/SpawningKit/Config/AutoGeneratedCode.h.cxxcodebuilder +307 -0
- data/src/agent/Core/SpawningKit/Context.h +211 -0
- data/src/agent/Core/SpawningKit/DirectSpawner.h +112 -122
- data/src/agent/Core/SpawningKit/DummySpawner.h +59 -20
- data/src/agent/Core/SpawningKit/ErrorRenderer.h +117 -0
- data/src/agent/Core/SpawningKit/Exceptions.h +1157 -0
- data/src/agent/Core/SpawningKit/Factory.h +24 -17
- data/src/agent/Core/SpawningKit/{BackgroundIOCapturer.h → Handshake/BackgroundIOCapturer.h} +48 -18
- data/src/agent/Core/SpawningKit/Handshake/Perform.h +1650 -0
- data/src/agent/Core/SpawningKit/Handshake/Prepare.h +582 -0
- data/src/agent/Core/SpawningKit/Handshake/Session.h +91 -0
- data/src/agent/Core/SpawningKit/Handshake/WorkDir.h +100 -0
- data/src/agent/Core/SpawningKit/Journey.h +561 -0
- data/src/agent/Core/SpawningKit/PipeWatcher.h +41 -18
- data/src/agent/Core/SpawningKit/README.md +534 -0
- data/src/agent/Core/SpawningKit/Result.h +182 -7
- data/src/agent/Core/SpawningKit/Result/AutoGeneratedCode.h +69 -0
- data/src/agent/Core/SpawningKit/Result/AutoGeneratedCode.h.cxxcodebuilder +110 -0
- data/src/agent/Core/SpawningKit/SmartSpawner.h +1027 -562
- data/src/agent/Core/SpawningKit/Spawner.h +70 -1134
- data/src/agent/Core/SpawningKit/UserSwitchingRules.h +3 -33
- data/src/agent/README.md +2 -3
- data/src/agent/Shared/ApiServerUtils.h +2 -3
- data/src/agent/SpawnEnvSetupper/SpawnEnvSetupperMain.cpp +932 -0
- data/src/agent/Watchdog/Config.h +1 -3
- data/src/agent/Watchdog/WatchdogMain.cpp +2 -1
- data/src/apache2_module/ConfigGeneral/AutoGeneratedDefinitions.cpp +5 -0
- data/src/apache2_module/ConfigGeneral/AutoGeneratedManifestDefaultsInitialization.cpp +5 -0
- data/src/apache2_module/ConfigGeneral/ManifestGeneration.h +22 -13
- data/src/apache2_module/DirConfig/AutoGeneratedCreateFunction.cpp +5 -0
- data/src/apache2_module/DirConfig/AutoGeneratedHeaderSerialization.cpp +3 -0
- data/src/apache2_module/DirConfig/AutoGeneratedManifestGeneration.cpp +13 -0
- data/src/apache2_module/DirConfig/AutoGeneratedMergeFunction.cpp +7 -0
- data/src/apache2_module/DirConfig/AutoGeneratedStruct.h +13 -0
- data/src/cxx_supportlib/Constants.h +3 -1
- data/src/cxx_supportlib/Exceptions.h +0 -121
- data/src/cxx_supportlib/LoggingKit/Implementation.cpp +7 -6
- data/src/cxx_supportlib/LoggingKit/Logging.h +3 -1
- data/src/cxx_supportlib/Utils.cpp +42 -0
- data/src/cxx_supportlib/Utils.h +7 -0
- data/src/cxx_supportlib/Utils/IOUtils.cpp +58 -0
- data/src/cxx_supportlib/Utils/IOUtils.h +13 -0
- data/src/cxx_supportlib/Utils/JsonUtils.h +130 -23
- data/src/cxx_supportlib/Utils/ScopeGuard.h +9 -4
- data/src/cxx_supportlib/Utils/StrIntUtils.cpp +7 -0
- data/src/cxx_supportlib/Utils/StrIntUtils.h +1 -0
- data/src/cxx_supportlib/Utils/SystemTime.h +1 -1
- data/src/cxx_supportlib/Utils/Timer.h +1 -1
- data/src/cxx_supportlib/WebSocketCommandReverseServer.h +6 -4
- data/src/cxx_supportlib/vendor-copy/adhoc_lve.h +1 -0
- data/src/helper-scripts/node-loader.js +54 -59
- data/src/helper-scripts/rack-loader.rb +63 -60
- data/src/helper-scripts/rack-preloader.rb +125 -72
- data/src/helper-scripts/wsgi-loader.py +100 -43
- data/src/nginx_module/ConfigGeneral/AutoGeneratedDefinitions.c +120 -112
- data/src/nginx_module/ConfigGeneral/AutoGeneratedManifestDefaultsInitialization.c +15 -8
- data/src/nginx_module/ConfigGeneral/AutoGeneratedSetterFuncs.c +142 -142
- data/src/nginx_module/ConfigGeneral/ManifestGeneration.c +26 -15
- data/src/nginx_module/ConfigGeneral/ManifestGeneration.h +3 -0
- data/src/nginx_module/LocationConfig/AutoGeneratedCreateFunction.c +76 -70
- data/src/nginx_module/LocationConfig/AutoGeneratedHeaderSerialization.c +114 -99
- data/src/nginx_module/LocationConfig/AutoGeneratedManifestGeneration.c +170 -156
- data/src/nginx_module/LocationConfig/AutoGeneratedMergeFunction.c +38 -35
- data/src/nginx_module/LocationConfig/AutoGeneratedStruct.h +5 -1
- data/src/ruby_supportlib/phusion_passenger.rb +5 -5
- data/src/ruby_supportlib/phusion_passenger/admin_tools/instance.rb +14 -1
- data/src/ruby_supportlib/phusion_passenger/apache2/config_options.rb +8 -0
- data/src/ruby_supportlib/phusion_passenger/common_library.rb +0 -3
- data/src/ruby_supportlib/phusion_passenger/config/nginx_engine_compiler.rb +0 -1
- data/src/ruby_supportlib/phusion_passenger/constants.rb +2 -0
- data/src/ruby_supportlib/phusion_passenger/loader_shared_helpers.rb +646 -238
- data/src/ruby_supportlib/phusion_passenger/nginx/config_options.rb +117 -95
- data/src/ruby_supportlib/phusion_passenger/packaging.rb +0 -1
- data/src/ruby_supportlib/phusion_passenger/platform_info/depcheck_specs/apache2.rb +5 -1
- data/src/ruby_supportlib/phusion_passenger/preloader_shared_helpers.rb +92 -69
- data/src/ruby_supportlib/phusion_passenger/public_api.rb +0 -17
- data/src/ruby_supportlib/phusion_passenger/rack/thread_handler_extension.rb +0 -3
- data/src/ruby_supportlib/phusion_passenger/request_handler.rb +4 -5
- data/src/ruby_supportlib/phusion_passenger/request_handler/thread_handler.rb +0 -22
- metadata +64 -67
- data/resources/templates/error_layout.html.template +0 -86
- data/resources/templates/general_error.html.template +0 -1
- data/resources/templates/general_error_with_html.html.template +0 -1
- data/src/agent/Core/ApplicationPool/ErrorRenderer.h +0 -131
- data/src/agent/Core/SpawningKit/Options.h +0 -41
- data/src/agent/Core/UnionStation/Connection.h +0 -173
- data/src/agent/Core/UnionStation/Context.h +0 -536
- data/src/agent/Core/UnionStation/StopwatchLog.h +0 -147
- data/src/agent/Core/UnionStation/Transaction.h +0 -249
- data/src/agent/SpawnPreparer/SpawnPreparerMain.cpp +0 -208
- data/src/cxx_supportlib/UnionStationFilterSupport.cpp +0 -67
- data/src/cxx_supportlib/UnionStationFilterSupport.h +0 -1622
- data/src/nodejs_supportlib/phusion_passenger/log_express.js +0 -106
- data/src/nodejs_supportlib/phusion_passenger/log_mongodb.js +0 -202
- data/src/nodejs_supportlib/phusion_passenger/ustreporter.js +0 -227
- data/src/nodejs_supportlib/phusion_passenger/ustrouter_connector.js +0 -448
- data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/CONFIG.md +0 -37
- data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/Gemfile +0 -17
- data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/Gemfile.lock +0 -59
- data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/README-API.md +0 -5
- data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/README.md +0 -117
- data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/Rakefile +0 -115
- data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/lib/union_station_hooks_core.rb +0 -423
- data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/lib/union_station_hooks_core/api.rb +0 -238
- data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/lib/union_station_hooks_core/connection.rb +0 -67
- data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/lib/union_station_hooks_core/context.rb +0 -281
- data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/lib/union_station_hooks_core/lock.rb +0 -62
- data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/lib/union_station_hooks_core/log.rb +0 -66
- data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/lib/union_station_hooks_core/message_channel.rb +0 -157
- data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/lib/union_station_hooks_core/request_reporter.rb +0 -150
- data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/lib/union_station_hooks_core/request_reporter/basics.rb +0 -199
- data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/lib/union_station_hooks_core/request_reporter/controllers.rb +0 -187
- data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/lib/union_station_hooks_core/request_reporter/misc.rb +0 -303
- data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/lib/union_station_hooks_core/request_reporter/view_rendering.rb +0 -91
- data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/lib/union_station_hooks_core/simple_json.rb +0 -396
- data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/lib/union_station_hooks_core/spec_helper.rb +0 -279
- data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/lib/union_station_hooks_core/time_point.rb +0 -39
- data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/lib/union_station_hooks_core/transaction.rb +0 -173
- data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/lib/union_station_hooks_core/utils.rb +0 -177
- data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/lib/union_station_hooks_core/version.rb +0 -32
- data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/lib/union_station_hooks_core/version_data.rb +0 -44
- data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/ruby_versions.yml.example +0 -16
- data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/ruby_versions.yml.travis +0 -20
- data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/ruby_versions.yml.travis-with-sudo +0 -18
- data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/union_station_hooks_core.gemspec +0 -23
- data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_rails/Gemfile +0 -14
- data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_rails/Gemfile.lock +0 -45
- data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_rails/LICENSE.md +0 -19
- data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_rails/README.md +0 -104
- data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_rails/Rakefile +0 -160
- data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_rails/lib/union_station_hooks_rails.rb +0 -200
- data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_rails/lib/union_station_hooks_rails/action_controller_extension.rb +0 -45
- data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_rails/lib/union_station_hooks_rails/action_view_subscriber.rb +0 -55
- data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_rails/lib/union_station_hooks_rails/active_record_subscriber.rb +0 -41
- data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_rails/lib/union_station_hooks_rails/active_support_benchmarkable_extension.rb +0 -47
- data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_rails/lib/union_station_hooks_rails/active_support_cache_subscriber.rb +0 -79
- data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_rails/lib/union_station_hooks_rails/exception_logger.rb +0 -57
- data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_rails/lib/union_station_hooks_rails/version.rb +0 -32
- data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_rails/lib/union_station_hooks_rails/version_data.rb +0 -44
- data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_rails/union_station_hooks_rails.gemspec +0 -34
@@ -28,6 +28,7 @@
|
|
28
28
|
|
29
29
|
#include <sys/types.h>
|
30
30
|
#include <pwd.h>
|
31
|
+
#include <grp.h>
|
31
32
|
#include <unistd.h>
|
32
33
|
#include <string>
|
33
34
|
#include <algorithm>
|
@@ -36,8 +37,8 @@
|
|
36
37
|
#include <oxt/system_calls.hpp>
|
37
38
|
#include <Exceptions.h>
|
38
39
|
#include <Utils.h>
|
40
|
+
#include <Core/SpawningKit/Context.h>
|
39
41
|
#include <FileTools/PathManip.h>
|
40
|
-
#include <Core/SpawningKit/Options.h>
|
41
42
|
|
42
43
|
namespace Passenger {
|
43
44
|
namespace SpawningKit {
|
@@ -51,19 +52,15 @@ struct UserSwitchingInfo {
|
|
51
52
|
bool enabled;
|
52
53
|
string username;
|
53
54
|
string groupname;
|
54
|
-
string home;
|
55
|
-
string shell;
|
56
55
|
uid_t uid;
|
57
56
|
gid_t gid;
|
58
|
-
int ngroups;
|
59
|
-
boost::shared_array<gid_t> gidset;
|
60
57
|
|
61
58
|
struct passwd lveUserPwd, *lveUserPwdComplete;
|
62
59
|
boost::shared_array<char> lveUserPwdStrBuf;
|
63
60
|
};
|
64
61
|
|
65
62
|
inline UserSwitchingInfo
|
66
|
-
prepareUserSwitching(const
|
63
|
+
prepareUserSwitching(const AppPoolOptions &options) {
|
67
64
|
TRACE_POINT();
|
68
65
|
UserSwitchingInfo info;
|
69
66
|
|
@@ -90,11 +87,8 @@ prepareUserSwitching(const Options &options) {
|
|
90
87
|
info.enabled = false;
|
91
88
|
info.username = userInfo->pw_name;
|
92
89
|
info.groupname = getGroupName(userInfo->pw_gid);
|
93
|
-
info.home = userInfo->pw_dir;
|
94
|
-
info.shell = userInfo->pw_shell;
|
95
90
|
info.uid = geteuid();
|
96
91
|
info.gid = getegid();
|
97
|
-
info.ngroups = 0;
|
98
92
|
return info;
|
99
93
|
}
|
100
94
|
|
@@ -233,35 +227,11 @@ prepareUserSwitching(const Options &options) {
|
|
233
227
|
}
|
234
228
|
|
235
229
|
UPDATE_TRACE_POINT();
|
236
|
-
#ifdef __APPLE__
|
237
|
-
int groups[1024];
|
238
|
-
info.ngroups = sizeof(groups) / sizeof(int);
|
239
|
-
#else
|
240
|
-
gid_t groups[1024];
|
241
|
-
info.ngroups = sizeof(groups) / sizeof(gid_t);
|
242
|
-
#endif
|
243
230
|
info.enabled = true;
|
244
231
|
info.username = userInfo->pw_name;
|
245
232
|
info.groupname = getGroupName(groupId);
|
246
|
-
info.home = userInfo->pw_dir;
|
247
|
-
info.shell = userInfo->pw_shell;
|
248
233
|
info.uid = userInfo->pw_uid;
|
249
234
|
info.gid = groupId;
|
250
|
-
#if !defined(HAVE_GETGROUPLIST) && (defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__))
|
251
|
-
#define HAVE_GETGROUPLIST
|
252
|
-
#endif
|
253
|
-
#ifdef HAVE_GETGROUPLIST
|
254
|
-
ret = getgrouplist(userInfo->pw_name, groupId,
|
255
|
-
groups, &info.ngroups);
|
256
|
-
if (ret == -1) {
|
257
|
-
int e = errno;
|
258
|
-
throw SystemException("getgrouplist() failed", e);
|
259
|
-
}
|
260
|
-
info.gidset = boost::shared_array<gid_t>(new gid_t[info.ngroups]);
|
261
|
-
for (int i = 0; i < info.ngroups; i++) {
|
262
|
-
info.gidset[i] = groups[i];
|
263
|
-
}
|
264
|
-
#endif
|
265
235
|
|
266
236
|
return info;
|
267
237
|
}
|
data/src/agent/README.md
CHANGED
@@ -6,13 +6,12 @@ This directory contains the source code of the Passenger agent. The Passenger ag
|
|
6
6
|
|
7
7
|
The most important parts are:
|
8
8
|
|
9
|
-
* The Watchdog is the main Passenger process. It starts the Passenger Core
|
9
|
+
* The Watchdog is the main Passenger process. It starts the Passenger Core, and restarts them when it crashes. It also cleans everything up upon shut down.
|
10
10
|
* The Core performs most of the heavy lifting. It parses requests, spawns application processes, forwards requests to the correct process and forwards application responses back to the web server.
|
11
|
-
* The UstRouter processes Union Station data and sends them to the Union Station server.
|
12
11
|
|
13
12
|
## Minor parts
|
14
13
|
|
15
|
-
*
|
14
|
+
* SpawnEnvSetupper is a tool used internally by `Core/SpawningKit/` to spawn application processes. See the README in that directory for more information.
|
16
15
|
* SystemMetrics is a tool that shows system metrics such as CPU and memory usage. The main functionality is implemented in src/cxxUtils/SystemMetricsCollector.h. This tool is mainly useful for developing and debugging SystemMetricsCollector.h.
|
17
16
|
* TempDirToucher is a tool used internally by Passenger Standalone to keep a temporary directory's timestamp up-to-date so that it doesn't get removed by /tmp cleaner daemons.
|
18
17
|
|
@@ -27,8 +27,8 @@
|
|
27
27
|
#define _PASSENGER_API_SERVER_UTILS_H_
|
28
28
|
|
29
29
|
/**
|
30
|
-
* Utility code shared by agent/Core/ApiServer.h
|
31
|
-
*
|
30
|
+
* Utility code shared by agent/Core/ApiServer.h and agent/Watchdog/ApiServer.h.
|
31
|
+
* This code handles authentication and authorization
|
32
32
|
* of connected ApiServer clients.
|
33
33
|
*
|
34
34
|
* This file consists of the following items.
|
@@ -76,7 +76,6 @@
|
|
76
76
|
#include <Utils/BufferedIO.h>
|
77
77
|
#include <Utils/StrIntUtils.h>
|
78
78
|
#include <Utils/VariantMap.h>
|
79
|
-
#include <Core/ApplicationPool/Pool.h>
|
80
79
|
#include <Shared/ApplicationPoolApiKey.h>
|
81
80
|
|
82
81
|
namespace Passenger {
|
@@ -0,0 +1,932 @@
|
|
1
|
+
/*
|
2
|
+
* Phusion Passenger - https://www.phusionpassenger.com/
|
3
|
+
* Copyright (c) 2012-2017 Phusion Holding B.V.
|
4
|
+
*
|
5
|
+
* "Passenger", "Phusion Passenger" and "Union Station" are registered
|
6
|
+
* trademarks of Phusion Holding B.V.
|
7
|
+
*
|
8
|
+
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
9
|
+
* of this software and associated documentation files (the "Software"), to deal
|
10
|
+
* in the Software without restriction, including without limitation the rights
|
11
|
+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
12
|
+
* copies of the Software, and to permit persons to whom the Software is
|
13
|
+
* furnished to do so, subject to the following conditions:
|
14
|
+
*
|
15
|
+
* The above copyright notice and this permission notice shall be included in
|
16
|
+
* all copies or substantial portions of the Software.
|
17
|
+
*
|
18
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
19
|
+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
20
|
+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
21
|
+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
22
|
+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
23
|
+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
24
|
+
* THE SOFTWARE.
|
25
|
+
*/
|
26
|
+
|
27
|
+
/*
|
28
|
+
* For an introduction see SpawningKit's README.md, section "The SpawnEnvSetupper".
|
29
|
+
*/
|
30
|
+
|
31
|
+
#include <oxt/initialize.hpp>
|
32
|
+
#include <oxt/backtrace.hpp>
|
33
|
+
#include <boost/scoped_array.hpp>
|
34
|
+
|
35
|
+
#include <cstdio>
|
36
|
+
#include <cstdlib>
|
37
|
+
#include <cstring>
|
38
|
+
#include <cerrno>
|
39
|
+
#include <cassert>
|
40
|
+
#include <stdexcept>
|
41
|
+
#include <string>
|
42
|
+
#include <vector>
|
43
|
+
|
44
|
+
#include <sys/types.h>
|
45
|
+
#include <sys/param.h>
|
46
|
+
#include <sys/wait.h>
|
47
|
+
#include <sys/time.h>
|
48
|
+
#include <sys/resource.h>
|
49
|
+
#include <sys/stat.h>
|
50
|
+
#include <limits.h>
|
51
|
+
#include <unistd.h>
|
52
|
+
#include <pwd.h>
|
53
|
+
#include <grp.h>
|
54
|
+
#include <stdlib.h>
|
55
|
+
#include <string.h>
|
56
|
+
|
57
|
+
#include <jsoncpp/json.h>
|
58
|
+
#include <adhoc_lve.h>
|
59
|
+
|
60
|
+
#include <LoggingKit/LoggingKit.h>
|
61
|
+
#include <LoggingKit/Context.h>
|
62
|
+
#include <ProcessManagement/Spawn.h>
|
63
|
+
#include <FileTools/FileManip.h>
|
64
|
+
#include <FileTools/PathManip.h>
|
65
|
+
#include <Utils.h>
|
66
|
+
#include <Utils/IOUtils.h>
|
67
|
+
#include <Utils/StrIntUtils.h>
|
68
|
+
#include <Core/SpawningKit/Exceptions.h>
|
69
|
+
|
70
|
+
using namespace std;
|
71
|
+
using namespace Passenger;
|
72
|
+
|
73
|
+
extern "C" {
|
74
|
+
extern char **environ;
|
75
|
+
}
|
76
|
+
|
77
|
+
|
78
|
+
namespace Passenger {
|
79
|
+
namespace SpawnEnvSetupper {
|
80
|
+
|
81
|
+
enum Mode {
|
82
|
+
BEFORE_MODE,
|
83
|
+
AFTER_MODE
|
84
|
+
};
|
85
|
+
|
86
|
+
struct Context {
|
87
|
+
string workDir;
|
88
|
+
Mode mode;
|
89
|
+
Json::Value args;
|
90
|
+
SpawningKit::JourneyStep step;
|
91
|
+
};
|
92
|
+
|
93
|
+
} // namespace SpawnEnvSetupper
|
94
|
+
} // namespace Passenger
|
95
|
+
|
96
|
+
using namespace Passenger::SpawnEnvSetupper;
|
97
|
+
|
98
|
+
|
99
|
+
static Json::Value
|
100
|
+
readArgsJson(const string &workDir) {
|
101
|
+
Json::Reader reader;
|
102
|
+
Json::Value result;
|
103
|
+
string contents = readAll(workDir + "/args.json");
|
104
|
+
if (reader.parse(contents, result)) {
|
105
|
+
return result;
|
106
|
+
} else {
|
107
|
+
P_CRITICAL("Cannot parse " << workDir << "/args.json: "
|
108
|
+
<< reader.getFormattedErrorMessages());
|
109
|
+
exit(1);
|
110
|
+
// Never reached
|
111
|
+
return Json::Value();
|
112
|
+
}
|
113
|
+
}
|
114
|
+
|
115
|
+
static void
|
116
|
+
initializeLogLevel(const Json::Value &args) {
|
117
|
+
if (args.isMember("log_level")) {
|
118
|
+
LoggingKit::setLevel(LoggingKit::Level(args["log_level"].asInt()));
|
119
|
+
}
|
120
|
+
}
|
121
|
+
|
122
|
+
static bool
|
123
|
+
tryWriteFile(const StaticString &path, const StaticString &value) {
|
124
|
+
try {
|
125
|
+
createFile(path.c_str(), value);
|
126
|
+
return true;
|
127
|
+
} catch (const FileSystemException &e) {
|
128
|
+
fprintf(stderr, "Warning: %s\n", e.what());
|
129
|
+
return false;
|
130
|
+
}
|
131
|
+
}
|
132
|
+
|
133
|
+
static void
|
134
|
+
recordJourneyStepBegin(const Context &context,
|
135
|
+
SpawningKit::JourneyStep step, SpawningKit::JourneyStepState state)
|
136
|
+
{
|
137
|
+
string stepString = journeyStepToStringLowerCase(step);
|
138
|
+
string stepDir = context.workDir + "/response/steps/" + stepString;
|
139
|
+
tryWriteFile(stepDir + "/state", SpawningKit::journeyStepStateToString(state));
|
140
|
+
tryWriteFile(stepDir + "/begin_time_monotonic", doubleToString(
|
141
|
+
SystemTime::getMonotonicUsecWithGranularity<SystemTime::GRAN_10MSEC>() / 1000000.0));
|
142
|
+
}
|
143
|
+
|
144
|
+
static void
|
145
|
+
recordJourneyStepEnd(const Context &context,
|
146
|
+
SpawningKit::JourneyStep step, SpawningKit::JourneyStepState state)
|
147
|
+
{
|
148
|
+
string stepString = journeyStepToStringLowerCase(step);
|
149
|
+
string stepDir = context.workDir + "/response/steps/" + stepString;
|
150
|
+
tryWriteFile(stepDir + "/state", SpawningKit::journeyStepStateToString(state));
|
151
|
+
if (!fileExists(stepDir + "/begin_time") && !fileExists(stepDir + "/begin_time_monotonic")) {
|
152
|
+
tryWriteFile(stepDir + "/begin_time_monotonic", doubleToString(
|
153
|
+
SystemTime::getMonotonicUsecWithGranularity<SystemTime::GRAN_10MSEC>() / 1000000.0));
|
154
|
+
}
|
155
|
+
tryWriteFile(stepDir + "/end_time_monotonic", doubleToString(
|
156
|
+
SystemTime::getMonotonicUsecWithGranularity<SystemTime::GRAN_10MSEC>() / 1000000.0));
|
157
|
+
}
|
158
|
+
|
159
|
+
static void
|
160
|
+
recordErrorCategory(const string &workDir, SpawningKit::ErrorCategory category) {
|
161
|
+
string path = workDir + "/response/error/category";
|
162
|
+
tryWriteFile(path, errorCategoryToString(category));
|
163
|
+
}
|
164
|
+
|
165
|
+
static void
|
166
|
+
recordAdvancedProblemDetails(const string &workDir, const string &message) {
|
167
|
+
string path = workDir + "/response/error/advanced_problem_details";
|
168
|
+
tryWriteFile(path, message);
|
169
|
+
}
|
170
|
+
|
171
|
+
static void
|
172
|
+
recordErrorSummary(const string &workDir, const string &message,
|
173
|
+
bool isAlsoAdvancedProblemDetails)
|
174
|
+
{
|
175
|
+
string path = workDir + "/response/error/summary";
|
176
|
+
tryWriteFile(path, message);
|
177
|
+
if (isAlsoAdvancedProblemDetails) {
|
178
|
+
recordAdvancedProblemDetails(workDir, message);
|
179
|
+
}
|
180
|
+
}
|
181
|
+
|
182
|
+
static void
|
183
|
+
recordAndPrintErrorSummary(const string &workDir, const string &message,
|
184
|
+
bool isAlsoAdvancedProblemDetails)
|
185
|
+
{
|
186
|
+
fprintf(stderr, "Error: %s\n", message.c_str());
|
187
|
+
recordErrorSummary(workDir, message, isAlsoAdvancedProblemDetails);
|
188
|
+
}
|
189
|
+
|
190
|
+
static void
|
191
|
+
recordProblemDescriptionHTML(const string &workDir, const string &message) {
|
192
|
+
string path = workDir + "/response/error/problem_description.html";
|
193
|
+
tryWriteFile(path, message);
|
194
|
+
}
|
195
|
+
|
196
|
+
static void
|
197
|
+
recordSolutionDescriptionHTML(const string &workDir, const string &message) {
|
198
|
+
string path = workDir + "/response/error/solution_description.html";
|
199
|
+
tryWriteFile(path, message);
|
200
|
+
}
|
201
|
+
|
202
|
+
static void
|
203
|
+
reopenStdout(int fd) {
|
204
|
+
dup2(fd, STDOUT_FILENO);
|
205
|
+
}
|
206
|
+
|
207
|
+
static void
|
208
|
+
dumpEnvvars(const string &workDir) {
|
209
|
+
FILE *f = fopen((workDir + "/envdump/envvars").c_str(), "w");
|
210
|
+
if (f == NULL) {
|
211
|
+
fprintf(stderr, "Warning: cannot open %s/envdump/envvars for writing\n",
|
212
|
+
workDir.c_str());
|
213
|
+
return;
|
214
|
+
}
|
215
|
+
|
216
|
+
const char *command[] = {
|
217
|
+
"env",
|
218
|
+
NULL
|
219
|
+
};
|
220
|
+
SubprocessInfo info;
|
221
|
+
runCommand(command, info, true, true,
|
222
|
+
boost::bind(reopenStdout, fileno(f)));
|
223
|
+
fclose(f);
|
224
|
+
}
|
225
|
+
|
226
|
+
static void
|
227
|
+
dumpUserInfo(const string &workDir) {
|
228
|
+
FILE *f = fopen((workDir + "/envdump/user_info").c_str(), "w");
|
229
|
+
if (f == NULL) {
|
230
|
+
fprintf(stderr, "Warning: cannot open %s/envdump/user_info for writing\n",
|
231
|
+
workDir.c_str());
|
232
|
+
return;
|
233
|
+
}
|
234
|
+
|
235
|
+
const char *command[] = {
|
236
|
+
"id",
|
237
|
+
NULL
|
238
|
+
};
|
239
|
+
SubprocessInfo info;
|
240
|
+
runCommand(command, info, true, true,
|
241
|
+
boost::bind(reopenStdout, fileno(f)));
|
242
|
+
fclose(f);
|
243
|
+
}
|
244
|
+
|
245
|
+
static void
|
246
|
+
dumpUlimits(const string &workDir) {
|
247
|
+
FILE *f = fopen((workDir + "/envdump/ulimits").c_str(), "w");
|
248
|
+
if (f == NULL) {
|
249
|
+
fprintf(stderr, "Warning: cannot open %s/envdump/ulimits for writing\n",
|
250
|
+
workDir.c_str());
|
251
|
+
return;
|
252
|
+
}
|
253
|
+
|
254
|
+
// On Linux, ulimit is a shell builtin and not a command.
|
255
|
+
const char *command[] = {
|
256
|
+
"/bin/sh",
|
257
|
+
"-c",
|
258
|
+
"ulimit -a",
|
259
|
+
NULL
|
260
|
+
};
|
261
|
+
SubprocessInfo info;
|
262
|
+
runCommand(command, info, true, true,
|
263
|
+
boost::bind(reopenStdout, fileno(f)));
|
264
|
+
fclose(f);
|
265
|
+
}
|
266
|
+
|
267
|
+
static void
|
268
|
+
dumpAllEnvironmentInfo(const string &workDir) {
|
269
|
+
dumpEnvvars(workDir);
|
270
|
+
dumpUserInfo(workDir);
|
271
|
+
dumpUlimits(workDir);
|
272
|
+
}
|
273
|
+
|
274
|
+
static bool
|
275
|
+
setUlimits(const Json::Value &args) {
|
276
|
+
if (!args.isMember("file_descriptor_ulimit")) {
|
277
|
+
return false;
|
278
|
+
}
|
279
|
+
|
280
|
+
rlim_t fdLimit = (rlim_t) args["file_descriptor_ulimit"].asUInt();
|
281
|
+
struct rlimit limit;
|
282
|
+
int ret;
|
283
|
+
|
284
|
+
limit.rlim_cur = fdLimit;
|
285
|
+
limit.rlim_max = fdLimit;
|
286
|
+
do {
|
287
|
+
ret = setrlimit(RLIMIT_NOFILE, &limit);
|
288
|
+
} while (ret == -1 && errno == EINTR);
|
289
|
+
|
290
|
+
if (ret == -1) {
|
291
|
+
int e = errno;
|
292
|
+
fprintf(stderr, "Error: unable to set file descriptor ulimit to %u: %s (errno=%d)",
|
293
|
+
(unsigned int) fdLimit, strerror(e), e);
|
294
|
+
}
|
295
|
+
|
296
|
+
return ret != -1;
|
297
|
+
}
|
298
|
+
|
299
|
+
static bool
|
300
|
+
canSwitchUser(const Json::Value &args) {
|
301
|
+
return args.isMember("user") && geteuid() == 0;
|
302
|
+
}
|
303
|
+
|
304
|
+
static void
|
305
|
+
lookupUserGroup(const Context &context, uid_t *uid, struct passwd **userInfo,
|
306
|
+
gid_t *gid)
|
307
|
+
{
|
308
|
+
const Json::Value &args = context.args;
|
309
|
+
errno = 0;
|
310
|
+
*userInfo = getpwnam(args["user"].asCString());
|
311
|
+
if (*userInfo == NULL) {
|
312
|
+
int e = errno;
|
313
|
+
if (looksLikePositiveNumber(args["user"].asString())) {
|
314
|
+
fprintf(stderr,
|
315
|
+
"Warning: error looking up system user database"
|
316
|
+
" entry for user '%s': %s (errno=%d)\n",
|
317
|
+
args["user"].asCString(), strerror(e), e);
|
318
|
+
*uid = (uid_t) atoi(args["user"].asString());
|
319
|
+
} else {
|
320
|
+
recordJourneyStepEnd(context, context.step,
|
321
|
+
SpawningKit::STEP_ERRORED);
|
322
|
+
recordErrorCategory(context.workDir,
|
323
|
+
SpawningKit::OPERATING_SYSTEM_ERROR);
|
324
|
+
recordAndPrintErrorSummary(context.workDir,
|
325
|
+
"Cannot lookup up system user database entry for user '"
|
326
|
+
+ args["user"].asString() + "': " + strerror(e)
|
327
|
+
+ " (errno=" + toString(e) + ")",
|
328
|
+
true);
|
329
|
+
exit(1);
|
330
|
+
}
|
331
|
+
} else {
|
332
|
+
*uid = (*userInfo)->pw_uid;
|
333
|
+
}
|
334
|
+
|
335
|
+
errno = 0;
|
336
|
+
struct group *groupInfo = getgrnam(args["group"].asCString());
|
337
|
+
if (groupInfo == NULL) {
|
338
|
+
int e = errno;
|
339
|
+
if (looksLikePositiveNumber(args["group"].asString())) {
|
340
|
+
fprintf(stderr,
|
341
|
+
"Warning: error looking up system group database entry for group '%s':"
|
342
|
+
" %s (errno=%d)\n",
|
343
|
+
args["group"].asCString(), strerror(e), e);
|
344
|
+
*gid = (gid_t) atoi(args["group"].asString());
|
345
|
+
} else {
|
346
|
+
recordJourneyStepEnd(context, context.step,
|
347
|
+
SpawningKit::STEP_ERRORED);
|
348
|
+
recordErrorCategory(context.workDir,
|
349
|
+
SpawningKit::OPERATING_SYSTEM_ERROR);
|
350
|
+
recordAndPrintErrorSummary(context.workDir,
|
351
|
+
"Cannot lookup up system group database entry for group '"
|
352
|
+
+ args["group"].asString() + "': " + strerror(e)
|
353
|
+
+ " (errno=" + toString(e) + ")",
|
354
|
+
true);
|
355
|
+
exit(1);
|
356
|
+
}
|
357
|
+
} else {
|
358
|
+
*gid = groupInfo->gr_gid;
|
359
|
+
}
|
360
|
+
}
|
361
|
+
|
362
|
+
void
|
363
|
+
chownNewWorkDirFiles(const Context &context, uid_t uid, gid_t gid) {
|
364
|
+
chown((context.workDir + "/response/steps/subprocess_before_first_exec/state").c_str(),
|
365
|
+
uid, gid);
|
366
|
+
chown((context.workDir + "/response/steps/subprocess_before_first_exec/duration").c_str(),
|
367
|
+
uid, gid);
|
368
|
+
chown((context.workDir + "/response/steps/subprocess_spawn_env_setupper_before_shell/state").c_str(),
|
369
|
+
uid, gid);
|
370
|
+
chown((context.workDir + "/response/steps/subprocess_spawn_env_setupper_before_shell/duration").c_str(),
|
371
|
+
uid, gid);
|
372
|
+
chown((context.workDir + "/envdump/envvars").c_str(),
|
373
|
+
uid, gid);
|
374
|
+
chown((context.workDir + "/envdump/user_info").c_str(),
|
375
|
+
uid, gid);
|
376
|
+
chown((context.workDir + "/envdump/ulimits").c_str(),
|
377
|
+
uid, gid);
|
378
|
+
}
|
379
|
+
|
380
|
+
static void
|
381
|
+
enterLveJail(const Context &context, const struct passwd *userInfo) {
|
382
|
+
string lveInitErr;
|
383
|
+
adhoc_lve::LibLve &liblve = adhoc_lve::LveInitSignleton::getInstance(&lveInitErr);
|
384
|
+
|
385
|
+
if (liblve.is_error()) {
|
386
|
+
if (!lveInitErr.empty()) {
|
387
|
+
lveInitErr = ": " + lveInitErr;
|
388
|
+
}
|
389
|
+
recordJourneyStepEnd(context, context.step,
|
390
|
+
SpawningKit::STEP_ERRORED);
|
391
|
+
recordErrorCategory(context.workDir,
|
392
|
+
SpawningKit::INTERNAL_ERROR);
|
393
|
+
recordAndPrintErrorSummary(context.workDir,
|
394
|
+
"Failed to initialize LVE library: " + lveInitErr,
|
395
|
+
true);
|
396
|
+
exit(1);
|
397
|
+
}
|
398
|
+
|
399
|
+
if (!liblve.is_lve_available()) {
|
400
|
+
return;
|
401
|
+
}
|
402
|
+
|
403
|
+
string jailErr;
|
404
|
+
int ret = liblve.jail(userInfo, jailErr);
|
405
|
+
if (ret < 0) {
|
406
|
+
recordJourneyStepEnd(context, context.step,
|
407
|
+
SpawningKit::STEP_ERRORED);
|
408
|
+
recordErrorCategory(context.workDir,
|
409
|
+
SpawningKit::INTERNAL_ERROR);
|
410
|
+
recordAndPrintErrorSummary(context.workDir,
|
411
|
+
"enterLve() failed: " + jailErr,
|
412
|
+
true);
|
413
|
+
exit(1);
|
414
|
+
}
|
415
|
+
}
|
416
|
+
|
417
|
+
static void
|
418
|
+
switchGroup(const Context &context, uid_t uid, const struct passwd *userInfo, gid_t gid) {
|
419
|
+
if (userInfo != NULL) {
|
420
|
+
bool setgroupsCalled = false;
|
421
|
+
|
422
|
+
#if defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__)
|
423
|
+
#ifdef __APPLE__
|
424
|
+
int groups[1024];
|
425
|
+
int ngroups = sizeof(groups) / sizeof(int);
|
426
|
+
#else
|
427
|
+
gid_t groups[1024];
|
428
|
+
int ngroups = sizeof(groups) / sizeof(gid_t);
|
429
|
+
#endif
|
430
|
+
boost::scoped_array<gid_t> gidset;
|
431
|
+
|
432
|
+
int ret = getgrouplist(userInfo->pw_name, gid,
|
433
|
+
groups, &ngroups);
|
434
|
+
if (ret == -1) {
|
435
|
+
int e = errno;
|
436
|
+
recordJourneyStepEnd(context, context.step,
|
437
|
+
SpawningKit::STEP_ERRORED);
|
438
|
+
recordErrorCategory(context.workDir,
|
439
|
+
SpawningKit::OPERATING_SYSTEM_ERROR);
|
440
|
+
recordAndPrintErrorSummary(context.workDir,
|
441
|
+
"getgrouplist(" + string(userInfo->pw_name) + ", "
|
442
|
+
+ toString(gid) + ") failed: " + strerror(e)
|
443
|
+
+ " (errno=" + toString(e) + ")",
|
444
|
+
true);
|
445
|
+
exit(1);
|
446
|
+
}
|
447
|
+
|
448
|
+
if (ngroups <= NGROUPS_MAX) {
|
449
|
+
setgroupsCalled = true;
|
450
|
+
gidset.reset(new gid_t[ngroups]);
|
451
|
+
if (setgroups(ngroups, gidset.get()) == -1) {
|
452
|
+
int e = errno;
|
453
|
+
recordJourneyStepEnd(context, context.step,
|
454
|
+
SpawningKit::STEP_ERRORED);
|
455
|
+
recordErrorCategory(context.workDir,
|
456
|
+
SpawningKit::OPERATING_SYSTEM_ERROR);
|
457
|
+
recordAndPrintErrorSummary(context.workDir,
|
458
|
+
"setgroups(" + toString(ngroups)
|
459
|
+
+ ", ...) failed: " + strerror(e) + " (errno="
|
460
|
+
+ toString(e) + ")",
|
461
|
+
true);
|
462
|
+
exit(1);
|
463
|
+
}
|
464
|
+
}
|
465
|
+
#endif
|
466
|
+
|
467
|
+
if (!setgroupsCalled && initgroups(userInfo->pw_name, gid) == -1) {
|
468
|
+
int e = errno;
|
469
|
+
recordJourneyStepEnd(context, context.step,
|
470
|
+
SpawningKit::STEP_ERRORED);
|
471
|
+
recordErrorCategory(context.workDir,
|
472
|
+
SpawningKit::OPERATING_SYSTEM_ERROR);
|
473
|
+
recordAndPrintErrorSummary(context.workDir,
|
474
|
+
"initgroups(" + string(userInfo->pw_name)
|
475
|
+
+ ", " + toString(gid) + ") failed: " + strerror(e)
|
476
|
+
+ " (errno=" + toString(e) + ")",
|
477
|
+
true);
|
478
|
+
exit(1);
|
479
|
+
}
|
480
|
+
}
|
481
|
+
|
482
|
+
if (setgid(gid) == -1) {
|
483
|
+
int e = errno;
|
484
|
+
recordJourneyStepEnd(context, context.step,
|
485
|
+
SpawningKit::STEP_ERRORED);
|
486
|
+
recordErrorCategory(context.workDir,
|
487
|
+
SpawningKit::OPERATING_SYSTEM_ERROR);
|
488
|
+
recordAndPrintErrorSummary(context.workDir,
|
489
|
+
"setgid(" + toString(gid) + ") failed: "
|
490
|
+
+ strerror(e) + " (errno=" + toString(e) + ")",
|
491
|
+
true);
|
492
|
+
exit(1);
|
493
|
+
}
|
494
|
+
}
|
495
|
+
|
496
|
+
static void
|
497
|
+
switchUser(const Context &context, uid_t uid, const struct passwd *userInfo) {
|
498
|
+
if (setuid(uid) == -1) {
|
499
|
+
int e = errno;
|
500
|
+
recordJourneyStepEnd(context, context.step,
|
501
|
+
SpawningKit::STEP_ERRORED);
|
502
|
+
recordErrorCategory(context.workDir,
|
503
|
+
SpawningKit::OPERATING_SYSTEM_ERROR);
|
504
|
+
recordAndPrintErrorSummary(context.workDir,
|
505
|
+
"setuid(" + toString(uid) + ") failed: " + strerror(e)
|
506
|
+
+ " (errno=" + toString(e) + ")",
|
507
|
+
true);
|
508
|
+
exit(1);
|
509
|
+
}
|
510
|
+
if (userInfo != NULL) {
|
511
|
+
setenv("USER", userInfo->pw_name, 1);
|
512
|
+
setenv("LOGNAME", userInfo->pw_name, 1);
|
513
|
+
setenv("SHELL", userInfo->pw_shell, 1);
|
514
|
+
setenv("HOME", userInfo->pw_dir, 1);
|
515
|
+
} else {
|
516
|
+
unsetenv("USER");
|
517
|
+
unsetenv("LOGNAME");
|
518
|
+
unsetenv("SHELL");
|
519
|
+
unsetenv("HOME");
|
520
|
+
}
|
521
|
+
}
|
522
|
+
|
523
|
+
static string
|
524
|
+
lookupCurrentUserShell() {
|
525
|
+
struct passwd *userInfo = getpwuid(getuid());
|
526
|
+
if (userInfo == NULL) {
|
527
|
+
int e = errno;
|
528
|
+
fprintf(stderr, "Warning: cannot lookup system user database"
|
529
|
+
" entry for UID %d: %s (errno=%d)\n",
|
530
|
+
(int) getuid(), strerror(e), e);
|
531
|
+
return "/bin/sh";
|
532
|
+
} else {
|
533
|
+
return userInfo->pw_shell;
|
534
|
+
}
|
535
|
+
}
|
536
|
+
|
537
|
+
static vector<string>
|
538
|
+
inferAllParentDirectories(const string &path) {
|
539
|
+
vector<string> components, result;
|
540
|
+
|
541
|
+
split(path, '/', components);
|
542
|
+
P_ASSERT_EQ(components.front(), "");
|
543
|
+
components.erase(components.begin());
|
544
|
+
|
545
|
+
for (unsigned int i = 0; i < components.size(); i++) {
|
546
|
+
string path2;
|
547
|
+
for (unsigned int j = 0; j <= i; j++) {
|
548
|
+
path2.append("/");
|
549
|
+
path2.append(components[j]);
|
550
|
+
}
|
551
|
+
if (path2.empty()) {
|
552
|
+
path2 = "/";
|
553
|
+
}
|
554
|
+
result.push_back(path2);
|
555
|
+
}
|
556
|
+
|
557
|
+
P_ASSERT_EQ(result.back(), path);
|
558
|
+
return result;
|
559
|
+
}
|
560
|
+
|
561
|
+
static void
|
562
|
+
setCurrentWorkingDirectory(const Context &context) {
|
563
|
+
string appRoot = context.args["app_root"].asString(); // Already absolutized by HandshakePreparer
|
564
|
+
vector<string> appRootAndParentDirs = inferAllParentDirectories(appRoot);
|
565
|
+
vector<string>::const_iterator it;
|
566
|
+
int ret;
|
567
|
+
|
568
|
+
for (it = appRootAndParentDirs.begin(); it != appRootAndParentDirs.end(); it++) {
|
569
|
+
struct stat buf;
|
570
|
+
ret = stat(it->c_str(), &buf);
|
571
|
+
if (ret == -1 && errno == EACCES) {
|
572
|
+
char parent[PATH_MAX];
|
573
|
+
const char *end = strrchr(it->c_str(), '/');
|
574
|
+
memcpy(parent, it->c_str(), end - it->c_str());
|
575
|
+
parent[end - it->c_str()] = '\0';
|
576
|
+
|
577
|
+
recordJourneyStepEnd(context, context.step,
|
578
|
+
SpawningKit::STEP_ERRORED);
|
579
|
+
recordErrorCategory(context.workDir,
|
580
|
+
SpawningKit::OPERATING_SYSTEM_ERROR);
|
581
|
+
recordAndPrintErrorSummary(context.workDir,
|
582
|
+
"Directory '" + string(parent) + "' is inaccessible because of a"
|
583
|
+
" filesystem permission error.",
|
584
|
+
false);
|
585
|
+
recordProblemDescriptionHTML(context.workDir,
|
586
|
+
"<p>"
|
587
|
+
"The " PROGRAM_NAME " application server tried to start the"
|
588
|
+
" web application as user '" + escapeHTML(getProcessUsername())
|
589
|
+
+ "' and group '" + escapeHTML(getGroupName(getgid()))
|
590
|
+
+ "'. During this process, " SHORT_PROGRAM_NAME
|
591
|
+
" must be able to access its application root directory '"
|
592
|
+
+ escapeHTML(appRoot) + "'. However, the parent directory '"
|
593
|
+
+ escapeHTML(parent) + "' has wrong permissions, thereby preventing this"
|
594
|
+
" process from accessing its application root directory."
|
595
|
+
"</p>");
|
596
|
+
recordSolutionDescriptionHTML(context.workDir,
|
597
|
+
"<p class=\"sole-solution\">"
|
598
|
+
"Please fix the permissions of the directory '" + escapeHTML(appRoot)
|
599
|
+
+ "' in such a way that the directory is accessible by user '"
|
600
|
+
+ escapeHTML(getProcessUsername()) + "' and group '"
|
601
|
+
+ escapeHTML(getGroupName(getgid())) + "'."
|
602
|
+
"</p>");
|
603
|
+
exit(1);
|
604
|
+
} else if (ret == -1) {
|
605
|
+
int e = errno;
|
606
|
+
recordJourneyStepEnd(context, context.step,
|
607
|
+
SpawningKit::STEP_ERRORED);
|
608
|
+
recordErrorCategory(context.workDir,
|
609
|
+
SpawningKit::OPERATING_SYSTEM_ERROR);
|
610
|
+
recordAndPrintErrorSummary(context.workDir,
|
611
|
+
"Unable to stat() directory '" + *it + "': "
|
612
|
+
+ strerror(e) + " (errno=" + toString(e) + ")",
|
613
|
+
true);
|
614
|
+
exit(1);
|
615
|
+
}
|
616
|
+
}
|
617
|
+
|
618
|
+
ret = chdir(appRoot.c_str());
|
619
|
+
if (ret != 0) {
|
620
|
+
int e = errno;
|
621
|
+
recordJourneyStepEnd(context, context.step,
|
622
|
+
SpawningKit::STEP_ERRORED);
|
623
|
+
recordErrorCategory(context.workDir,
|
624
|
+
SpawningKit::OPERATING_SYSTEM_ERROR);
|
625
|
+
recordAndPrintErrorSummary(context.workDir,
|
626
|
+
"Unable to change working directory to '" + appRoot + "': "
|
627
|
+
+ strerror(e) + " (errno=" + toString(e) + ")",
|
628
|
+
true);
|
629
|
+
if (e == EPERM || e == EACCES) {
|
630
|
+
recordProblemDescriptionHTML(context.workDir,
|
631
|
+
"<p>The " PROGRAM_NAME " application server tried to start the"
|
632
|
+
" web application as user " + escapeHTML(getProcessUsername())
|
633
|
+
+ " and group " + escapeHTML(getGroupName(getgid()))
|
634
|
+
+ ", with a working directory of "
|
635
|
+
+ escapeHTML(appRoot) + ". However, it encountered a filesystem"
|
636
|
+
" permission error while doing this.</p>");
|
637
|
+
} else {
|
638
|
+
recordProblemDescriptionHTML(context.workDir,
|
639
|
+
"<p>The " PROGRAM_NAME " application server tried to start the"
|
640
|
+
" web application as user " + escapeHTML(getProcessUsername())
|
641
|
+
+ " and group " + escapeHTML(getGroupName(getgid()))
|
642
|
+
+ ", with a working directory of "
|
643
|
+
+ escapeHTML(appRoot) + ". However, it encountered a filesystem"
|
644
|
+
" error while doing this.</p>");
|
645
|
+
}
|
646
|
+
exit(1);
|
647
|
+
}
|
648
|
+
|
649
|
+
// The application root may contain one or more symlinks
|
650
|
+
// in its path. If the application calls getcwd(), it will
|
651
|
+
// get the resolved path.
|
652
|
+
//
|
653
|
+
// It turns out that there is no such thing as a path without
|
654
|
+
// unresolved symlinks. The shell presents a working directory with
|
655
|
+
// unresolved symlinks (which it calls the "logical working directory"),
|
656
|
+
// but that is an illusion provided by the shell. The shell reports
|
657
|
+
// the logical working directory though the PWD environment variable.
|
658
|
+
//
|
659
|
+
// See also:
|
660
|
+
// https://github.com/phusion/passenger/issues/1596#issuecomment-138154045
|
661
|
+
// http://git.savannah.gnu.org/cgit/coreutils.git/tree/src/pwd.c
|
662
|
+
// http://www.opensource.apple.com/source/shell_cmds/shell_cmds-170/pwd/pwd.c
|
663
|
+
setenv("PWD", appRoot.c_str(), 1);
|
664
|
+
}
|
665
|
+
|
666
|
+
static void
|
667
|
+
setDefaultEnvvars(const Json::Value &args) {
|
668
|
+
setenv("PYTHONUNBUFFERED", "1", 1);
|
669
|
+
|
670
|
+
setenv("NODE_PATH", args["node_libdir"].asCString(), 1);
|
671
|
+
|
672
|
+
setenv("RAILS_ENV", args["app_env"].asCString(), 1);
|
673
|
+
setenv("RACK_ENV", args["app_env"].asCString(), 1);
|
674
|
+
setenv("WSGI_ENV", args["app_env"].asCString(), 1);
|
675
|
+
setenv("NODE_ENV", args["app_env"].asCString(), 1);
|
676
|
+
setenv("PASSENGER_APP_ENV", args["app_env"].asCString(), 1);
|
677
|
+
|
678
|
+
if (args.isMember("expected_start_port")) {
|
679
|
+
setenv("PORT", toString(args["expected_start_port"].asInt()).c_str(), 1);
|
680
|
+
}
|
681
|
+
|
682
|
+
if (args["base_uri"].asString() != "/") {
|
683
|
+
setenv("RAILS_RELATIVE_URL_ROOT", args["base_uri"].asCString(), 1);
|
684
|
+
setenv("RACK_BASE_URI", args["base_uri"].asCString(), 1);
|
685
|
+
setenv("PASSENGER_BASE_URI", args["base_uri"].asCString(), 1);
|
686
|
+
} else {
|
687
|
+
unsetenv("RAILS_RELATIVE_URL_ROOT");
|
688
|
+
unsetenv("RACK_BASE_URI");
|
689
|
+
unsetenv("PASSENGER_BASE_URI");
|
690
|
+
}
|
691
|
+
}
|
692
|
+
|
693
|
+
static void
|
694
|
+
setGivenEnvVars(const Json::Value &args) {
|
695
|
+
const Json::Value &envvars = args["environment_variables"];
|
696
|
+
Json::Value::const_iterator it, end = envvars.end();
|
697
|
+
|
698
|
+
for (it = envvars.begin(); it != end; it++) {
|
699
|
+
string key = it.name();
|
700
|
+
setenv(key.c_str(), it->asCString(), 1);
|
701
|
+
}
|
702
|
+
}
|
703
|
+
|
704
|
+
static bool
|
705
|
+
shouldLoadShellEnvvars(const Json::Value &args, const string &shell) {
|
706
|
+
if (args["load_shell_envvars"].asBool()) {
|
707
|
+
string shellName = extractBaseName(shell);
|
708
|
+
bool result = shellName == "bash" || shellName == "zsh" || shellName == "ksh";
|
709
|
+
#if defined(__linux__) || defined(__APPLE__)
|
710
|
+
// On Linux, /bin/sh is usually either bash or dash, which
|
711
|
+
// supports -l.
|
712
|
+
// On macOS, it is not clear what /bin/sh is but
|
713
|
+
// it supports -l.
|
714
|
+
// This cannot be said of other platforms: for example on
|
715
|
+
// FreeBSD, /bin/sh does not support -l.
|
716
|
+
result = result || shellName == "sh";
|
717
|
+
#endif
|
718
|
+
P_DEBUG("shellName = '" << shellName << "' detected as supporting '-l': " << (result ? "true" : "false"));
|
719
|
+
return result;
|
720
|
+
} else {
|
721
|
+
return false;
|
722
|
+
}
|
723
|
+
}
|
724
|
+
|
725
|
+
static string
|
726
|
+
commandArgsToString(const vector<const char *> &commandArgs) {
|
727
|
+
vector<const char *>::const_iterator it;
|
728
|
+
string result;
|
729
|
+
|
730
|
+
for (it = commandArgs.begin(); it != commandArgs.end(); it++) {
|
731
|
+
if (*it != NULL) {
|
732
|
+
result.append(*it);
|
733
|
+
result.append(1, ' ');
|
734
|
+
}
|
735
|
+
}
|
736
|
+
|
737
|
+
return strip(result);
|
738
|
+
}
|
739
|
+
|
740
|
+
static bool
|
741
|
+
executedThroughShell(const Context &context) {
|
742
|
+
return fileExists(context.workDir + "/execute_through_os_shell");
|
743
|
+
}
|
744
|
+
|
745
|
+
static void
|
746
|
+
execNextCommand(const Context &context, const string &shell)
|
747
|
+
{
|
748
|
+
vector<const char *> commandArgs;
|
749
|
+
SpawningKit::JourneyStep nextJourneyStep;
|
750
|
+
string binShPath, binShParam;
|
751
|
+
|
752
|
+
// Note: do not try to set a process title in this function by messing with argv[0].
|
753
|
+
// https://code.google.com/p/phusion-passenger/issues/detail?id=855
|
754
|
+
|
755
|
+
if (context.mode == BEFORE_MODE) {
|
756
|
+
assert(!shell.empty());
|
757
|
+
if (shouldLoadShellEnvvars(context.args, shell)) {
|
758
|
+
nextJourneyStep = SpawningKit::SUBPROCESS_OS_SHELL;
|
759
|
+
commandArgs.push_back(shell.c_str());
|
760
|
+
if (LoggingKit::getLevel() >= LoggingKit::DEBUG3) {
|
761
|
+
commandArgs.push_back("-x");
|
762
|
+
}
|
763
|
+
commandArgs.push_back("-lc");
|
764
|
+
commandArgs.push_back("exec \"$@\"");
|
765
|
+
commandArgs.push_back("SpawnEnvSetupperShell");
|
766
|
+
|
767
|
+
// Will be used by 'spawn-env-setupper --after' to determine
|
768
|
+
// whether it should set the SUBPROCESS_OS_SHELL step to the
|
769
|
+
// PERFORMED state.
|
770
|
+
tryWriteFile(context.workDir + "/execute_through_os_shell", "");
|
771
|
+
} else {
|
772
|
+
nextJourneyStep = SpawningKit::SUBPROCESS_SPAWN_ENV_SETUPPER_AFTER_SHELL;
|
773
|
+
}
|
774
|
+
commandArgs.push_back(context.args["passenger_agent_path"].asCString());
|
775
|
+
commandArgs.push_back("spawn-env-setupper");
|
776
|
+
commandArgs.push_back(context.workDir.c_str());
|
777
|
+
commandArgs.push_back("--after");
|
778
|
+
} else {
|
779
|
+
if (context.args["starts_using_wrapper"].asBool()) {
|
780
|
+
nextJourneyStep = SpawningKit::SUBPROCESS_EXEC_WRAPPER;
|
781
|
+
} else {
|
782
|
+
nextJourneyStep = SpawningKit::SUBPROCESS_APP_LOAD_OR_EXEC;
|
783
|
+
}
|
784
|
+
if (context.args.isMember("_bin_sh_path")) {
|
785
|
+
// Used in unit tests
|
786
|
+
binShPath = context.args["_bin_sh_path"].asString();
|
787
|
+
} else {
|
788
|
+
binShPath = "/bin/sh";
|
789
|
+
}
|
790
|
+
binShParam = "exec " + context.args["start_command"].asString();
|
791
|
+
commandArgs.push_back(binShPath.c_str());
|
792
|
+
commandArgs.push_back("-c");
|
793
|
+
commandArgs.push_back(binShParam.c_str());
|
794
|
+
}
|
795
|
+
commandArgs.push_back(NULL);
|
796
|
+
|
797
|
+
recordJourneyStepEnd(context, context.step,
|
798
|
+
SpawningKit::STEP_PERFORMED);
|
799
|
+
recordJourneyStepBegin(context, nextJourneyStep,
|
800
|
+
SpawningKit::STEP_IN_PROGRESS);
|
801
|
+
|
802
|
+
execvp(commandArgs[0], (char * const *) &commandArgs[0]);
|
803
|
+
|
804
|
+
int e = errno;
|
805
|
+
recordJourneyStepEnd(context, nextJourneyStep,
|
806
|
+
SpawningKit::STEP_ERRORED);
|
807
|
+
recordErrorCategory(context.workDir, SpawningKit::OPERATING_SYSTEM_ERROR);
|
808
|
+
recordAndPrintErrorSummary(context.workDir,
|
809
|
+
"Unable to execute command '" + commandArgsToString(commandArgs)
|
810
|
+
+ "': " + strerror(e) + " (errno=" + toString(e) + ")",
|
811
|
+
true);
|
812
|
+
exit(1);
|
813
|
+
}
|
814
|
+
|
815
|
+
int
|
816
|
+
spawnEnvSetupperMain(int argc, char *argv[]) {
|
817
|
+
setvbuf(stdout, NULL, _IONBF, 0);
|
818
|
+
setvbuf(stderr, NULL, _IONBF, 0);
|
819
|
+
|
820
|
+
if (argc != 4) {
|
821
|
+
fprintf(stderr, "Usage: PassengerAgent spawn-env-setupper <workdir> <--before|--after>\n");
|
822
|
+
exit(1);
|
823
|
+
}
|
824
|
+
|
825
|
+
oxt::initialize();
|
826
|
+
oxt::setup_syscall_interruption_support();
|
827
|
+
LoggingKit::initialize();
|
828
|
+
SystemTime::initialize();
|
829
|
+
|
830
|
+
Context context;
|
831
|
+
context.workDir = argv[2];
|
832
|
+
context.mode =
|
833
|
+
(strcmp(argv[3], "--before") == 0)
|
834
|
+
? BEFORE_MODE
|
835
|
+
: AFTER_MODE;
|
836
|
+
context.step =
|
837
|
+
(context.mode == BEFORE_MODE)
|
838
|
+
? SpawningKit::SUBPROCESS_SPAWN_ENV_SETUPPER_BEFORE_SHELL
|
839
|
+
: SpawningKit::SUBPROCESS_SPAWN_ENV_SETUPPER_AFTER_SHELL;
|
840
|
+
|
841
|
+
setenv("IN_PASSENGER", "1", 1);
|
842
|
+
setenv("PASSENGER_SPAWN_WORK_DIR", context.workDir.c_str(), 1);
|
843
|
+
if (context.mode == BEFORE_MODE) {
|
844
|
+
recordJourneyStepEnd(context, SpawningKit::SUBPROCESS_BEFORE_FIRST_EXEC,
|
845
|
+
SpawningKit::STEP_PERFORMED);
|
846
|
+
}
|
847
|
+
recordJourneyStepBegin(context, context.step,
|
848
|
+
SpawningKit::STEP_IN_PROGRESS);
|
849
|
+
|
850
|
+
try {
|
851
|
+
context.args = readArgsJson(context.workDir);
|
852
|
+
bool shouldTrySwitchUser = canSwitchUser(context.args);
|
853
|
+
string shell;
|
854
|
+
|
855
|
+
initializeLogLevel(context.args);
|
856
|
+
dumpAllEnvironmentInfo(context.workDir);
|
857
|
+
|
858
|
+
if (context.mode == BEFORE_MODE) {
|
859
|
+
struct passwd *userInfo = NULL;
|
860
|
+
uid_t uid;
|
861
|
+
gid_t gid;
|
862
|
+
|
863
|
+
setDefaultEnvvars(context.args);
|
864
|
+
dumpEnvvars(context.workDir);
|
865
|
+
|
866
|
+
if (shouldTrySwitchUser) {
|
867
|
+
lookupUserGroup(context, &uid, &userInfo, &gid);
|
868
|
+
shell = userInfo->pw_shell;
|
869
|
+
} else {
|
870
|
+
shell = lookupCurrentUserShell();
|
871
|
+
}
|
872
|
+
if (setUlimits(context.args)) {
|
873
|
+
dumpUlimits(context.workDir);
|
874
|
+
}
|
875
|
+
if (shouldTrySwitchUser) {
|
876
|
+
chownNewWorkDirFiles(context, uid, gid);
|
877
|
+
|
878
|
+
enterLveJail(context, userInfo);
|
879
|
+
switchGroup(context, uid, userInfo, gid);
|
880
|
+
dumpUserInfo(context.workDir);
|
881
|
+
|
882
|
+
switchUser(context, uid, userInfo);
|
883
|
+
dumpEnvvars(context.workDir);
|
884
|
+
dumpUserInfo(context.workDir);
|
885
|
+
}
|
886
|
+
} else if (executedThroughShell(context)) {
|
887
|
+
recordJourneyStepEnd(context, SpawningKit::SUBPROCESS_OS_SHELL,
|
888
|
+
SpawningKit::STEP_PERFORMED);
|
889
|
+
} else {
|
890
|
+
recordJourneyStepEnd(context, SpawningKit::SUBPROCESS_OS_SHELL,
|
891
|
+
SpawningKit::STEP_NOT_STARTED);
|
892
|
+
}
|
893
|
+
|
894
|
+
setCurrentWorkingDirectory(context);
|
895
|
+
dumpEnvvars(context.workDir);
|
896
|
+
|
897
|
+
if (context.mode == AFTER_MODE) {
|
898
|
+
setDefaultEnvvars(context.args);
|
899
|
+
setGivenEnvVars(context.args);
|
900
|
+
dumpEnvvars(context.workDir);
|
901
|
+
}
|
902
|
+
|
903
|
+
execNextCommand(context, shell);
|
904
|
+
} catch (const oxt::tracable_exception &e) {
|
905
|
+
fprintf(stderr, "Error: %s\n%s\n",
|
906
|
+
e.what(), e.backtrace().c_str());
|
907
|
+
recordJourneyStepEnd(context, context.step,
|
908
|
+
SpawningKit::STEP_ERRORED);
|
909
|
+
recordErrorCategory(context.workDir,
|
910
|
+
SpawningKit::inferErrorCategoryFromAnotherException(
|
911
|
+
e, context.step));
|
912
|
+
recordErrorSummary(context.workDir, e.what(), true);
|
913
|
+
return 1;
|
914
|
+
} catch (const std::exception &e) {
|
915
|
+
fprintf(stderr, "Error: %s\n", e.what());
|
916
|
+
recordJourneyStepEnd(context, context.step,
|
917
|
+
SpawningKit::STEP_ERRORED);
|
918
|
+
recordErrorCategory(context.workDir,
|
919
|
+
SpawningKit::inferErrorCategoryFromAnotherException(
|
920
|
+
e, context.step));
|
921
|
+
recordErrorSummary(context.workDir, e.what(), true);
|
922
|
+
return 1;
|
923
|
+
}
|
924
|
+
|
925
|
+
// Should never be reached
|
926
|
+
recordJourneyStepEnd(context, context.step,
|
927
|
+
SpawningKit::STEP_ERRORED);
|
928
|
+
recordAndPrintErrorSummary(context.workDir,
|
929
|
+
"*** BUG IN SpawnEnvSetupper ***: end of main() reached",
|
930
|
+
true);
|
931
|
+
return 1;
|
932
|
+
}
|