passenger 5.0.9 → 5.0.10
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 +8 -8
- checksums.yaml.gz.asc +7 -7
- data.tar.gz.asc +7 -7
- data/CHANGELOG +15 -0
- data/CONTRIBUTORS +6 -0
- data/README.md +1 -1
- data/bin/passenger-install-apache2-module +24 -11
- data/bin/passenger-status +29 -14
- data/build/agents.rb +12 -10
- data/build/cxx_tests.rb +30 -30
- data/doc/Design and Architecture.html +1 -10
- data/doc/Design and Architecture.txt +1 -6
- data/doc/Users guide Apache.html +1 -19
- data/doc/Users guide Apache.txt +1 -1
- data/doc/Users guide Nginx.html +2 -20
- data/doc/Users guide Nginx.txt +2 -2
- data/doc/users_guide_snippets/tips.txt +0 -9
- data/ext/common/ApplicationPool2/ApiKey.h +158 -0
- data/ext/common/ApplicationPool2/BasicGroupInfo.h +81 -0
- data/ext/common/ApplicationPool2/BasicProcessInfo.h +106 -0
- data/ext/common/ApplicationPool2/Common.h +5 -44
- data/ext/common/ApplicationPool2/Context.h +94 -0
- data/ext/common/ApplicationPool2/Group.h +130 -1205
- data/ext/common/ApplicationPool2/Group/InitializationAndShutdown.cpp +190 -0
- data/ext/common/ApplicationPool2/Group/InternalUtils.cpp +329 -0
- data/ext/common/ApplicationPool2/Group/LifetimeAndBasics.cpp +103 -0
- data/ext/common/ApplicationPool2/{Pool/Debug.h → Group/Miscellaneous.cpp} +40 -38
- data/ext/common/ApplicationPool2/Group/OutOfBandWork.cpp +323 -0
- data/ext/common/ApplicationPool2/Group/ProcessListManagement.cpp +606 -0
- data/ext/common/ApplicationPool2/Group/SessionManagement.cpp +337 -0
- data/ext/common/ApplicationPool2/Group/SpawningAndRestarting.cpp +478 -0
- data/ext/common/ApplicationPool2/Group/StateInspection.cpp +197 -0
- data/ext/common/ApplicationPool2/Group/Verification.cpp +159 -0
- data/ext/common/ApplicationPool2/Implementation.cpp +19 -1401
- data/ext/common/ApplicationPool2/Options.h +5 -5
- data/ext/common/ApplicationPool2/Pool.h +260 -815
- data/ext/common/ApplicationPool2/Pool/{AnalyticsCollection.h → AnalyticsCollection.cpp} +55 -56
- data/ext/common/ApplicationPool2/Pool/{GarbageCollection.h → GarbageCollection.cpp} +49 -49
- data/ext/common/ApplicationPool2/Pool/GeneralUtils.cpp +241 -0
- data/ext/common/ApplicationPool2/Pool/GroupUtils.cpp +276 -0
- data/ext/common/ApplicationPool2/Pool/InitializationAndShutdown.cpp +145 -0
- data/ext/common/ApplicationPool2/Pool/Miscellaneous.cpp +244 -0
- data/ext/common/ApplicationPool2/Pool/ProcessUtils.cpp +330 -0
- data/ext/common/ApplicationPool2/Pool/StateInspection.cpp +299 -0
- data/ext/common/ApplicationPool2/Process.h +399 -205
- data/ext/common/ApplicationPool2/Session.h +70 -28
- data/ext/common/ApplicationPool2/Socket.h +1 -0
- data/ext/common/Constants.h +11 -3
- data/ext/common/Exceptions.h +1 -1
- data/ext/common/Logging.cpp +9 -4
- data/ext/common/Logging.h +6 -0
- data/ext/common/ServerKit/HttpServer.h +225 -215
- data/ext/common/ServerKit/Server.h +57 -57
- data/ext/common/SpawningKit/BackgroundIOCapturer.h +160 -0
- data/ext/common/SpawningKit/Config.h +107 -0
- data/ext/common/{ApplicationPool2 → SpawningKit}/DirectSpawner.h +17 -16
- data/ext/common/{ApplicationPool2 → SpawningKit}/DummySpawner.h +33 -33
- data/ext/common/{ApplicationPool2/SpawnerFactory.h → SpawningKit/Factory.h} +17 -17
- data/ext/common/{ApplicationPool2/ComponentInfo.h → SpawningKit/Options.h} +8 -21
- data/ext/common/SpawningKit/PipeWatcher.h +148 -0
- data/ext/common/{ApplicationPool2/PipeWatcher.h → SpawningKit/Result.h} +15 -33
- data/ext/common/{ApplicationPool2 → SpawningKit}/SmartSpawner.h +52 -57
- data/ext/common/{ApplicationPool2 → SpawningKit}/Spawner.h +83 -371
- data/ext/common/SpawningKit/UserSwitchingRules.h +265 -0
- data/ext/common/Utils/BufferedIO.h +24 -0
- data/ext/common/{ApplicationPool2/SpawnObject.h → Utils/ClassUtils.h} +24 -51
- data/ext/common/Utils/IOUtils.cpp +70 -0
- data/ext/common/Utils/IOUtils.h +19 -0
- data/ext/common/Utils/JsonUtils.h +113 -0
- data/ext/common/Utils/StrIntUtils.h +29 -0
- data/ext/common/Utils/json.h +1 -1
- data/ext/common/agents/ApiServerUtils.h +941 -0
- data/ext/common/agents/HelperAgent/{AdminServer.h → ApiServer.h} +163 -365
- data/ext/common/agents/HelperAgent/Main.cpp +86 -88
- data/ext/common/agents/HelperAgent/OptionParser.h +9 -10
- data/ext/common/agents/HelperAgent/RequestHandler/BufferBody.cpp +3 -0
- data/ext/common/agents/HelperAgent/RequestHandler/ForwardResponse.cpp +2 -0
- data/ext/common/agents/HelperAgent/RequestHandler/Hooks.cpp +1 -1
- data/ext/common/agents/HelperAgent/RequestHandler/SendRequest.cpp +2 -2
- data/ext/common/agents/LoggingAgent/ApiServer.h +279 -0
- data/ext/common/agents/LoggingAgent/Main.cpp +41 -51
- data/ext/common/agents/LoggingAgent/OptionParser.h +11 -11
- data/ext/common/agents/Watchdog/ApiServer.h +311 -0
- data/ext/common/agents/Watchdog/Main.cpp +91 -65
- data/helper-scripts/prespawn +2 -0
- data/lib/phusion_passenger.rb +1 -1
- data/lib/phusion_passenger/admin_tools/instance.rb +1 -1
- data/lib/phusion_passenger/common_library.rb +27 -14
- data/lib/phusion_passenger/config/{admin_command_command.rb → api_call_command.rb} +19 -16
- data/lib/phusion_passenger/config/detach_process_command.rb +6 -3
- data/lib/phusion_passenger/config/main.rb +3 -5
- data/lib/phusion_passenger/config/reopen_logs_command.rb +29 -7
- data/lib/phusion_passenger/config/restart_app_command.rb +13 -4
- data/lib/phusion_passenger/config/utils.rb +15 -8
- data/lib/phusion_passenger/constants.rb +6 -2
- data/lib/phusion_passenger/platform_info/apache.rb +4 -0
- data/lib/phusion_passenger/platform_info/apache_detector.rb +18 -3
- data/resources/templates/apache2/mpm_unknown.txt.erb +20 -0
- metadata +42 -21
- metadata.gz.asc +7 -7
- data/ext/common/ApplicationPool2/Pool/GeneralUtils.h +0 -127
- data/ext/common/ApplicationPool2/Pool/Inspection.h +0 -219
- data/ext/common/ApplicationPool2/Pool/ProcessUtils.h +0 -85
- data/ext/common/ApplicationPool2/SuperGroup.h +0 -706
- data/ext/common/agents/LoggingAgent/AdminServer.h +0 -435
- data/ext/common/agents/Watchdog/AdminServer.h +0 -432
@@ -0,0 +1,265 @@
|
|
1
|
+
/*
|
2
|
+
* Phusion Passenger - https://www.phusionpassenger.com/
|
3
|
+
* Copyright (c) 2011-2015 Phusion
|
4
|
+
*
|
5
|
+
* "Phusion Passenger" is a trademark of Hongli Lai & Ninh Bui.
|
6
|
+
*
|
7
|
+
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
8
|
+
* of this software and associated documentation files (the "Software"), to deal
|
9
|
+
* in the Software without restriction, including without limitation the rights
|
10
|
+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
11
|
+
* copies of the Software, and to permit persons to whom the Software is
|
12
|
+
* furnished to do so, subject to the following conditions:
|
13
|
+
*
|
14
|
+
* The above copyright notice and this permission notice shall be included in
|
15
|
+
* all copies or substantial portions of the Software.
|
16
|
+
*
|
17
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
18
|
+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
19
|
+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
20
|
+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
21
|
+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
22
|
+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
23
|
+
* THE SOFTWARE.
|
24
|
+
*/
|
25
|
+
#ifndef _PASSENGER_SPAWNING_KIT_USER_SWITCHING_RULES_H_
|
26
|
+
#define _PASSENGER_SPAWNING_KIT_USER_SWITCHING_RULES_H_
|
27
|
+
|
28
|
+
#include <sys/types.h>
|
29
|
+
#include <pwd.h>
|
30
|
+
#include <unistd.h>
|
31
|
+
#include <string>
|
32
|
+
#include <algorithm>
|
33
|
+
#include <boost/shared_array.hpp>
|
34
|
+
#include <oxt/backtrace.hpp>
|
35
|
+
#include <oxt/system_calls.hpp>
|
36
|
+
#include <SpawningKit/Options.h>
|
37
|
+
#include <Exceptions.h>
|
38
|
+
#include <Utils.h>
|
39
|
+
|
40
|
+
namespace Passenger {
|
41
|
+
namespace SpawningKit {
|
42
|
+
|
43
|
+
using namespace std;
|
44
|
+
using namespace boost;
|
45
|
+
using namespace oxt;
|
46
|
+
|
47
|
+
|
48
|
+
struct UserSwitchingInfo {
|
49
|
+
bool enabled;
|
50
|
+
string username;
|
51
|
+
string groupname;
|
52
|
+
string home;
|
53
|
+
string shell;
|
54
|
+
uid_t uid;
|
55
|
+
gid_t gid;
|
56
|
+
int ngroups;
|
57
|
+
shared_array<gid_t> gidset;
|
58
|
+
};
|
59
|
+
|
60
|
+
inline UserSwitchingInfo
|
61
|
+
prepareUserSwitching(const Options &options) {
|
62
|
+
TRACE_POINT();
|
63
|
+
UserSwitchingInfo info;
|
64
|
+
|
65
|
+
if (geteuid() != 0) {
|
66
|
+
struct passwd pwd, *userInfo;
|
67
|
+
long bufSize;
|
68
|
+
shared_array<char> strings;
|
69
|
+
|
70
|
+
// _SC_GETPW_R_SIZE_MAX is not a maximum:
|
71
|
+
// http://tomlee.co/2012/10/problems-with-large-linux-unix-groups-and-getgrgid_r-getgrnam_r/
|
72
|
+
bufSize = std::max<long>(1024 * 128, sysconf(_SC_GETPW_R_SIZE_MAX));
|
73
|
+
strings.reset(new char[bufSize]);
|
74
|
+
|
75
|
+
userInfo = (struct passwd *) NULL;
|
76
|
+
if (getpwuid_r(geteuid(), &pwd, strings.get(), bufSize, &userInfo) != 0
|
77
|
+
|| userInfo == (struct passwd *) NULL)
|
78
|
+
{
|
79
|
+
throw RuntimeException("Cannot get user database entry for user " +
|
80
|
+
getProcessUsername() + "; it looks like your system's " +
|
81
|
+
"user database is broken, please fix it.");
|
82
|
+
}
|
83
|
+
|
84
|
+
info.enabled = false;
|
85
|
+
info.username = userInfo->pw_name;
|
86
|
+
info.groupname = getGroupName(userInfo->pw_gid);
|
87
|
+
info.home = userInfo->pw_dir;
|
88
|
+
info.shell = userInfo->pw_shell;
|
89
|
+
info.uid = geteuid();
|
90
|
+
info.gid = getegid();
|
91
|
+
info.ngroups = 0;
|
92
|
+
return info;
|
93
|
+
}
|
94
|
+
|
95
|
+
UPDATE_TRACE_POINT();
|
96
|
+
string defaultGroup;
|
97
|
+
string startupFile = absolutizePath(options.getStartupFile(),
|
98
|
+
absolutizePath(options.appRoot));
|
99
|
+
struct passwd pwd, *userInfo;
|
100
|
+
struct group grp;
|
101
|
+
gid_t groupId = (gid_t) -1;
|
102
|
+
long pwdBufSize, grpBufSize;
|
103
|
+
shared_array<char> pwdBuf, grpBuf;
|
104
|
+
int ret;
|
105
|
+
|
106
|
+
// _SC_GETPW_R_SIZE_MAX/_SC_GETGR_R_SIZE_MAX are not maximums:
|
107
|
+
// http://tomlee.co/2012/10/problems-with-large-linux-unix-groups-and-getgrgid_r-getgrnam_r/
|
108
|
+
pwdBufSize = std::max<long>(1024 * 128, sysconf(_SC_GETPW_R_SIZE_MAX));
|
109
|
+
pwdBuf.reset(new char[pwdBufSize]);
|
110
|
+
grpBufSize = std::max<long>(1024 * 128, sysconf(_SC_GETGR_R_SIZE_MAX));
|
111
|
+
grpBuf.reset(new char[grpBufSize]);
|
112
|
+
|
113
|
+
if (options.defaultGroup.empty()) {
|
114
|
+
struct passwd *info;
|
115
|
+
struct group *group;
|
116
|
+
|
117
|
+
info = (struct passwd *) NULL;
|
118
|
+
ret = getpwnam_r(options.defaultUser.c_str(), &pwd, pwdBuf.get(),
|
119
|
+
pwdBufSize, &info);
|
120
|
+
if (ret != 0) {
|
121
|
+
info = (struct passwd *) NULL;
|
122
|
+
}
|
123
|
+
if (info == (struct passwd *) NULL) {
|
124
|
+
throw RuntimeException("Cannot get user database entry for username '" +
|
125
|
+
options.defaultUser + "'");
|
126
|
+
}
|
127
|
+
|
128
|
+
group = (struct group *) NULL;
|
129
|
+
ret = getgrgid_r(info->pw_gid, &grp, grpBuf.get(), grpBufSize, &group);
|
130
|
+
if (ret != 0) {
|
131
|
+
group = (struct group *) NULL;
|
132
|
+
}
|
133
|
+
if (group == (struct group *) NULL) {
|
134
|
+
throw RuntimeException(string("Cannot get group database entry for ") +
|
135
|
+
"the default group belonging to username '" +
|
136
|
+
options.defaultUser + "'");
|
137
|
+
}
|
138
|
+
defaultGroup = group->gr_name;
|
139
|
+
} else {
|
140
|
+
defaultGroup = options.defaultGroup;
|
141
|
+
}
|
142
|
+
|
143
|
+
UPDATE_TRACE_POINT();
|
144
|
+
userInfo = (struct passwd *) NULL;
|
145
|
+
if (!options.userSwitching) {
|
146
|
+
// Keep userInfo at NULL so that it's set to defaultUser's UID.
|
147
|
+
} else if (!options.user.empty()) {
|
148
|
+
ret = getpwnam_r(options.user.c_str(), &pwd, pwdBuf.get(),
|
149
|
+
pwdBufSize, &userInfo);
|
150
|
+
if (ret != 0) {
|
151
|
+
userInfo = (struct passwd *) NULL;
|
152
|
+
}
|
153
|
+
} else {
|
154
|
+
struct stat buf;
|
155
|
+
if (syscalls::lstat(startupFile.c_str(), &buf) == -1) {
|
156
|
+
int e = errno;
|
157
|
+
throw SystemException("Cannot lstat(\"" + startupFile +
|
158
|
+
"\")", e);
|
159
|
+
}
|
160
|
+
ret = getpwuid_r(buf.st_uid, &pwd, pwdBuf.get(),
|
161
|
+
pwdBufSize, &userInfo);
|
162
|
+
if (ret != 0) {
|
163
|
+
userInfo = (struct passwd *) NULL;
|
164
|
+
}
|
165
|
+
}
|
166
|
+
if (userInfo == (struct passwd *) NULL || userInfo->pw_uid == 0) {
|
167
|
+
userInfo = (struct passwd *) NULL;
|
168
|
+
ret = getpwnam_r(options.defaultUser.c_str(), &pwd,
|
169
|
+
pwdBuf.get(), pwdBufSize, &userInfo);
|
170
|
+
if (ret != 0) {
|
171
|
+
userInfo = (struct passwd *) NULL;
|
172
|
+
}
|
173
|
+
}
|
174
|
+
|
175
|
+
UPDATE_TRACE_POINT();
|
176
|
+
if (!options.userSwitching) {
|
177
|
+
// Keep groupId at -1 so that it's set to defaultGroup's GID.
|
178
|
+
} else if (!options.group.empty()) {
|
179
|
+
struct group *groupInfo = (struct group *) NULL;
|
180
|
+
|
181
|
+
if (options.group == "!STARTUP_FILE!") {
|
182
|
+
struct stat buf;
|
183
|
+
|
184
|
+
if (syscalls::lstat(startupFile.c_str(), &buf) == -1) {
|
185
|
+
int e = errno;
|
186
|
+
throw SystemException("Cannot lstat(\"" +
|
187
|
+
startupFile + "\")", e);
|
188
|
+
}
|
189
|
+
|
190
|
+
ret = getgrgid_r(buf.st_gid, &grp, grpBuf.get(), grpBufSize,
|
191
|
+
&groupInfo);
|
192
|
+
if (ret != 0) {
|
193
|
+
groupInfo = (struct group *) NULL;
|
194
|
+
}
|
195
|
+
if (groupInfo != NULL) {
|
196
|
+
groupId = buf.st_gid;
|
197
|
+
} else {
|
198
|
+
groupId = (gid_t) -1;
|
199
|
+
}
|
200
|
+
} else {
|
201
|
+
ret = getgrnam_r(options.group.c_str(), &grp, grpBuf.get(),
|
202
|
+
grpBufSize, &groupInfo);
|
203
|
+
if (ret != 0) {
|
204
|
+
groupInfo = (struct group *) NULL;
|
205
|
+
}
|
206
|
+
if (groupInfo != NULL) {
|
207
|
+
groupId = groupInfo->gr_gid;
|
208
|
+
} else {
|
209
|
+
groupId = (gid_t) -1;
|
210
|
+
}
|
211
|
+
}
|
212
|
+
} else if (userInfo != (struct passwd *) NULL) {
|
213
|
+
groupId = userInfo->pw_gid;
|
214
|
+
}
|
215
|
+
if (groupId == 0 || groupId == (gid_t) -1) {
|
216
|
+
groupId = lookupGid(defaultGroup);
|
217
|
+
}
|
218
|
+
|
219
|
+
UPDATE_TRACE_POINT();
|
220
|
+
if (userInfo == (struct passwd *) NULL) {
|
221
|
+
throw RuntimeException("Cannot determine a user to lower privilege to");
|
222
|
+
}
|
223
|
+
if (groupId == (gid_t) -1) {
|
224
|
+
throw RuntimeException("Cannot determine a group to lower privilege to");
|
225
|
+
}
|
226
|
+
|
227
|
+
UPDATE_TRACE_POINT();
|
228
|
+
#ifdef __APPLE__
|
229
|
+
int groups[1024];
|
230
|
+
info.ngroups = sizeof(groups) / sizeof(int);
|
231
|
+
#else
|
232
|
+
gid_t groups[1024];
|
233
|
+
info.ngroups = sizeof(groups) / sizeof(gid_t);
|
234
|
+
#endif
|
235
|
+
info.enabled = true;
|
236
|
+
info.username = userInfo->pw_name;
|
237
|
+
info.groupname = getGroupName(groupId);
|
238
|
+
info.home = userInfo->pw_dir;
|
239
|
+
info.shell = userInfo->pw_shell;
|
240
|
+
info.uid = userInfo->pw_uid;
|
241
|
+
info.gid = groupId;
|
242
|
+
#if !defined(HAVE_GETGROUPLIST) && (defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__))
|
243
|
+
#define HAVE_GETGROUPLIST
|
244
|
+
#endif
|
245
|
+
#ifdef HAVE_GETGROUPLIST
|
246
|
+
ret = getgrouplist(userInfo->pw_name, groupId,
|
247
|
+
groups, &info.ngroups);
|
248
|
+
if (ret == -1) {
|
249
|
+
int e = errno;
|
250
|
+
throw SystemException("getgrouplist() failed", e);
|
251
|
+
}
|
252
|
+
info.gidset = shared_array<gid_t>(new gid_t[info.ngroups]);
|
253
|
+
for (int i = 0; i < info.ngroups; i++) {
|
254
|
+
info.gidset[i] = groups[i];
|
255
|
+
}
|
256
|
+
#endif
|
257
|
+
|
258
|
+
return info;
|
259
|
+
}
|
260
|
+
|
261
|
+
|
262
|
+
} // namespace SpawningKit
|
263
|
+
} // namespace Passenger
|
264
|
+
|
265
|
+
#endif /* _PASSENGER_SPAWNING_KIT_USER_SWITCHING_RULES_H_ */
|
@@ -1,3 +1,27 @@
|
|
1
|
+
/*
|
2
|
+
* Phusion Passenger - https://www.phusionpassenger.com/
|
3
|
+
* Copyright (c) 2010-2015 Phusion
|
4
|
+
*
|
5
|
+
* "Phusion Passenger" is a trademark of Hongli Lai & Ninh Bui.
|
6
|
+
*
|
7
|
+
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
8
|
+
* of this software and associated documentation files (the "Software"), to deal
|
9
|
+
* in the Software without restriction, including without limitation the rights
|
10
|
+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
11
|
+
* copies of the Software, and to permit persons to whom the Software is
|
12
|
+
* furnished to do so, subject to the following conditions:
|
13
|
+
*
|
14
|
+
* The above copyright notice and this permission notice shall be included in
|
15
|
+
* all copies or substantial portions of the Software.
|
16
|
+
*
|
17
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
18
|
+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
19
|
+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
20
|
+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
21
|
+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
22
|
+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
23
|
+
* THE SOFTWARE.
|
24
|
+
*/
|
1
25
|
#ifndef _PASSENGER_BUFFERED_IO_H_
|
2
26
|
#define _PASSENGER_BUFFERED_IO_H_
|
3
27
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
/*
|
2
2
|
* Phusion Passenger - https://www.phusionpassenger.com/
|
3
|
-
* Copyright (c)
|
3
|
+
* Copyright (c) 2015 Phusion
|
4
4
|
*
|
5
5
|
* "Phusion Passenger" is a trademark of Hongli Lai & Ninh Bui.
|
6
6
|
*
|
@@ -22,62 +22,35 @@
|
|
22
22
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
23
23
|
* THE SOFTWARE.
|
24
24
|
*/
|
25
|
-
#ifndef
|
26
|
-
#define
|
25
|
+
#ifndef _PASSENGER_CLASS_UTILS_H_
|
26
|
+
#define _PASSENGER_CLASS_UTILS_H_
|
27
27
|
|
28
|
-
#
|
29
|
-
|
30
|
-
|
31
|
-
#include <ApplicationPool2/Common.h>
|
32
|
-
|
33
|
-
namespace Passenger {
|
34
|
-
namespace ApplicationPool2 {
|
35
|
-
|
36
|
-
|
37
|
-
class SpawnObject: public boost::noncopyable {
|
38
|
-
private:
|
39
|
-
BOOST_MOVABLE_BUT_NOT_COPYABLE(SpawnObject)
|
40
|
-
|
41
|
-
public:
|
42
|
-
psg_pool_t *pool;
|
43
|
-
ProcessPtr process;
|
44
|
-
|
45
|
-
SpawnObject() {
|
46
|
-
pool = psg_create_pool(PSG_DEFAULT_POOL_SIZE);
|
47
|
-
}
|
48
|
-
|
49
|
-
SpawnObject(BOOST_RV_REF(SpawnObject) r)
|
50
|
-
: pool(r.pool),
|
51
|
-
process(r.process)
|
52
|
-
{
|
53
|
-
r.pool = NULL;
|
54
|
-
r.process.reset();
|
28
|
+
#define P_DEFINE_GETTER_CONST_REF(type, name) \
|
29
|
+
const type &get ## name() const { \
|
30
|
+
return m ## name; \
|
55
31
|
}
|
56
32
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
}
|
33
|
+
#define P_DEFINE_GETTER_REF(type, name) \
|
34
|
+
type &get ## name() { \
|
35
|
+
return m ## name; \
|
61
36
|
}
|
62
37
|
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
if (pool != NULL) {
|
67
|
-
psg_destroy_pool(pool);
|
68
|
-
}
|
69
|
-
pool = r.pool;
|
70
|
-
}
|
71
|
-
r.pool = NULL;
|
72
|
-
process = r.process;
|
73
|
-
r.process.reset();
|
74
|
-
}
|
75
|
-
return *this;
|
38
|
+
#define P_DEFINE_SETTER(type, name) \
|
39
|
+
void set ## name(const type &value) { \
|
40
|
+
m ## name = value; \
|
76
41
|
}
|
77
|
-
};
|
78
42
|
|
43
|
+
#define P_PROPERTY_CONST_REF(visibility, type, name) \
|
44
|
+
public: \
|
45
|
+
P_DEFINE_GETTER_CONST_REF(type, name) \
|
46
|
+
P_DEFINE_SETTER(type, name) \
|
47
|
+
visibility: \
|
48
|
+
type m ## name
|
79
49
|
|
80
|
-
|
81
|
-
|
50
|
+
#define P_RO_PROPERTY_REF(visibility, type, name) \
|
51
|
+
public: \
|
52
|
+
P_DEFINE_GETTER_REF(type, name) \
|
53
|
+
visibility: \
|
54
|
+
type m ## name
|
82
55
|
|
83
|
-
#endif /*
|
56
|
+
#endif /* _PASSENGER_CLASS_UTILS_H_ */
|
@@ -26,6 +26,7 @@
|
|
26
26
|
#ifndef _GNU_SOURCE
|
27
27
|
// Needed for IOV_MAX on Linux:
|
28
28
|
// https://bugzilla.redhat.com/show_bug.cgi?id=165427
|
29
|
+
// Also needed for SO_PEERCRED.
|
29
30
|
#define _GNU_SOURCE
|
30
31
|
#endif
|
31
32
|
|
@@ -154,6 +155,30 @@ isLocalSocketAddress(const StaticString &address) {
|
|
154
155
|
}
|
155
156
|
}
|
156
157
|
|
158
|
+
void
|
159
|
+
setBlocking(int fd) {
|
160
|
+
int flags, ret;
|
161
|
+
|
162
|
+
do {
|
163
|
+
flags = fcntl(fd, F_GETFL);
|
164
|
+
} while (flags == -1 && errno == EINTR);
|
165
|
+
if (flags == -1) {
|
166
|
+
int e = errno;
|
167
|
+
throw SystemException("Cannot set socket to blocking mode: "
|
168
|
+
"cannot get socket flags",
|
169
|
+
e);
|
170
|
+
}
|
171
|
+
do {
|
172
|
+
ret = fcntl(fd, F_SETFL, flags & ~O_NONBLOCK);
|
173
|
+
} while (ret == -1 && errno == EINTR);
|
174
|
+
if (ret == -1) {
|
175
|
+
int e = errno;
|
176
|
+
throw SystemException("Cannot set socket to blocking mode: "
|
177
|
+
"cannot set socket flags",
|
178
|
+
e);
|
179
|
+
}
|
180
|
+
}
|
181
|
+
|
157
182
|
void
|
158
183
|
setNonBlocking(int fd) {
|
159
184
|
int flags, ret;
|
@@ -1160,6 +1185,51 @@ writeFileDescriptor(int fd, int fdToSend, unsigned long long *timeout) {
|
|
1160
1185
|
}
|
1161
1186
|
}
|
1162
1187
|
|
1188
|
+
void
|
1189
|
+
readPeerCredentials(int sock, uid_t *uid, gid_t *gid) {
|
1190
|
+
union {
|
1191
|
+
struct sockaddr genericAddress;
|
1192
|
+
struct sockaddr_un unixAddress;
|
1193
|
+
struct sockaddr_in inetAddress;
|
1194
|
+
} addr;
|
1195
|
+
socklen_t len = sizeof(addr);
|
1196
|
+
|
1197
|
+
/*
|
1198
|
+
* The functions for receiving the peer credentials are not guaranteed to
|
1199
|
+
* fail if the socket is not a Unix domain socket. For example, OS X getpeereid()
|
1200
|
+
* just returns garbage when invoked on a TCP socket. So we check here
|
1201
|
+
* whether 'sock' is a Unix domain socket.
|
1202
|
+
*/
|
1203
|
+
if (getsockname(sock, &addr.genericAddress, &len) == -1) {
|
1204
|
+
int e = errno;
|
1205
|
+
throw SystemException("Unable to autodetect socket type (getsockname() failed)", e);
|
1206
|
+
}
|
1207
|
+
if (addr.genericAddress.sa_family != AF_LOCAL) {
|
1208
|
+
throw SystemException("Cannot receive process credentials: the connection is not a Unix domain socket",
|
1209
|
+
EPROTONOSUPPORT);
|
1210
|
+
}
|
1211
|
+
|
1212
|
+
#if defined(__linux__)
|
1213
|
+
struct ucred credentials;
|
1214
|
+
socklen_t ucred_length = sizeof(struct ucred);
|
1215
|
+
|
1216
|
+
if (getsockopt(sock, SOL_SOCKET, SO_PEERCRED, &credentials, &ucred_length) != 0) {
|
1217
|
+
int e = errno;
|
1218
|
+
throw SystemException("Cannot receive process credentials over Unix domain socket", e);
|
1219
|
+
}
|
1220
|
+
|
1221
|
+
*uid = credentials.uid;
|
1222
|
+
*gid = credentials.gid;
|
1223
|
+
#elif defined(__FreeBSD__) || defined(__APPLE__)
|
1224
|
+
if (getpeereid(sock, uid, gid) == -1) {
|
1225
|
+
int e = errno;
|
1226
|
+
throw SystemException("Cannot receive process credentials over Unix domain socket", e);
|
1227
|
+
}
|
1228
|
+
#else
|
1229
|
+
throw SystemException("Cannot receive process credentials over Unix domain socket", ENOSYS);
|
1230
|
+
#endif
|
1231
|
+
}
|
1232
|
+
|
1163
1233
|
void
|
1164
1234
|
safelyClose(int fd, bool ignoreErrors) {
|
1165
1235
|
if (syscalls::close(fd) == -1) {
|