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.

Files changed (106) hide show
  1. checksums.yaml +8 -8
  2. checksums.yaml.gz.asc +7 -7
  3. data.tar.gz.asc +7 -7
  4. data/CHANGELOG +15 -0
  5. data/CONTRIBUTORS +6 -0
  6. data/README.md +1 -1
  7. data/bin/passenger-install-apache2-module +24 -11
  8. data/bin/passenger-status +29 -14
  9. data/build/agents.rb +12 -10
  10. data/build/cxx_tests.rb +30 -30
  11. data/doc/Design and Architecture.html +1 -10
  12. data/doc/Design and Architecture.txt +1 -6
  13. data/doc/Users guide Apache.html +1 -19
  14. data/doc/Users guide Apache.txt +1 -1
  15. data/doc/Users guide Nginx.html +2 -20
  16. data/doc/Users guide Nginx.txt +2 -2
  17. data/doc/users_guide_snippets/tips.txt +0 -9
  18. data/ext/common/ApplicationPool2/ApiKey.h +158 -0
  19. data/ext/common/ApplicationPool2/BasicGroupInfo.h +81 -0
  20. data/ext/common/ApplicationPool2/BasicProcessInfo.h +106 -0
  21. data/ext/common/ApplicationPool2/Common.h +5 -44
  22. data/ext/common/ApplicationPool2/Context.h +94 -0
  23. data/ext/common/ApplicationPool2/Group.h +130 -1205
  24. data/ext/common/ApplicationPool2/Group/InitializationAndShutdown.cpp +190 -0
  25. data/ext/common/ApplicationPool2/Group/InternalUtils.cpp +329 -0
  26. data/ext/common/ApplicationPool2/Group/LifetimeAndBasics.cpp +103 -0
  27. data/ext/common/ApplicationPool2/{Pool/Debug.h → Group/Miscellaneous.cpp} +40 -38
  28. data/ext/common/ApplicationPool2/Group/OutOfBandWork.cpp +323 -0
  29. data/ext/common/ApplicationPool2/Group/ProcessListManagement.cpp +606 -0
  30. data/ext/common/ApplicationPool2/Group/SessionManagement.cpp +337 -0
  31. data/ext/common/ApplicationPool2/Group/SpawningAndRestarting.cpp +478 -0
  32. data/ext/common/ApplicationPool2/Group/StateInspection.cpp +197 -0
  33. data/ext/common/ApplicationPool2/Group/Verification.cpp +159 -0
  34. data/ext/common/ApplicationPool2/Implementation.cpp +19 -1401
  35. data/ext/common/ApplicationPool2/Options.h +5 -5
  36. data/ext/common/ApplicationPool2/Pool.h +260 -815
  37. data/ext/common/ApplicationPool2/Pool/{AnalyticsCollection.h → AnalyticsCollection.cpp} +55 -56
  38. data/ext/common/ApplicationPool2/Pool/{GarbageCollection.h → GarbageCollection.cpp} +49 -49
  39. data/ext/common/ApplicationPool2/Pool/GeneralUtils.cpp +241 -0
  40. data/ext/common/ApplicationPool2/Pool/GroupUtils.cpp +276 -0
  41. data/ext/common/ApplicationPool2/Pool/InitializationAndShutdown.cpp +145 -0
  42. data/ext/common/ApplicationPool2/Pool/Miscellaneous.cpp +244 -0
  43. data/ext/common/ApplicationPool2/Pool/ProcessUtils.cpp +330 -0
  44. data/ext/common/ApplicationPool2/Pool/StateInspection.cpp +299 -0
  45. data/ext/common/ApplicationPool2/Process.h +399 -205
  46. data/ext/common/ApplicationPool2/Session.h +70 -28
  47. data/ext/common/ApplicationPool2/Socket.h +1 -0
  48. data/ext/common/Constants.h +11 -3
  49. data/ext/common/Exceptions.h +1 -1
  50. data/ext/common/Logging.cpp +9 -4
  51. data/ext/common/Logging.h +6 -0
  52. data/ext/common/ServerKit/HttpServer.h +225 -215
  53. data/ext/common/ServerKit/Server.h +57 -57
  54. data/ext/common/SpawningKit/BackgroundIOCapturer.h +160 -0
  55. data/ext/common/SpawningKit/Config.h +107 -0
  56. data/ext/common/{ApplicationPool2 → SpawningKit}/DirectSpawner.h +17 -16
  57. data/ext/common/{ApplicationPool2 → SpawningKit}/DummySpawner.h +33 -33
  58. data/ext/common/{ApplicationPool2/SpawnerFactory.h → SpawningKit/Factory.h} +17 -17
  59. data/ext/common/{ApplicationPool2/ComponentInfo.h → SpawningKit/Options.h} +8 -21
  60. data/ext/common/SpawningKit/PipeWatcher.h +148 -0
  61. data/ext/common/{ApplicationPool2/PipeWatcher.h → SpawningKit/Result.h} +15 -33
  62. data/ext/common/{ApplicationPool2 → SpawningKit}/SmartSpawner.h +52 -57
  63. data/ext/common/{ApplicationPool2 → SpawningKit}/Spawner.h +83 -371
  64. data/ext/common/SpawningKit/UserSwitchingRules.h +265 -0
  65. data/ext/common/Utils/BufferedIO.h +24 -0
  66. data/ext/common/{ApplicationPool2/SpawnObject.h → Utils/ClassUtils.h} +24 -51
  67. data/ext/common/Utils/IOUtils.cpp +70 -0
  68. data/ext/common/Utils/IOUtils.h +19 -0
  69. data/ext/common/Utils/JsonUtils.h +113 -0
  70. data/ext/common/Utils/StrIntUtils.h +29 -0
  71. data/ext/common/Utils/json.h +1 -1
  72. data/ext/common/agents/ApiServerUtils.h +941 -0
  73. data/ext/common/agents/HelperAgent/{AdminServer.h → ApiServer.h} +163 -365
  74. data/ext/common/agents/HelperAgent/Main.cpp +86 -88
  75. data/ext/common/agents/HelperAgent/OptionParser.h +9 -10
  76. data/ext/common/agents/HelperAgent/RequestHandler/BufferBody.cpp +3 -0
  77. data/ext/common/agents/HelperAgent/RequestHandler/ForwardResponse.cpp +2 -0
  78. data/ext/common/agents/HelperAgent/RequestHandler/Hooks.cpp +1 -1
  79. data/ext/common/agents/HelperAgent/RequestHandler/SendRequest.cpp +2 -2
  80. data/ext/common/agents/LoggingAgent/ApiServer.h +279 -0
  81. data/ext/common/agents/LoggingAgent/Main.cpp +41 -51
  82. data/ext/common/agents/LoggingAgent/OptionParser.h +11 -11
  83. data/ext/common/agents/Watchdog/ApiServer.h +311 -0
  84. data/ext/common/agents/Watchdog/Main.cpp +91 -65
  85. data/helper-scripts/prespawn +2 -0
  86. data/lib/phusion_passenger.rb +1 -1
  87. data/lib/phusion_passenger/admin_tools/instance.rb +1 -1
  88. data/lib/phusion_passenger/common_library.rb +27 -14
  89. data/lib/phusion_passenger/config/{admin_command_command.rb → api_call_command.rb} +19 -16
  90. data/lib/phusion_passenger/config/detach_process_command.rb +6 -3
  91. data/lib/phusion_passenger/config/main.rb +3 -5
  92. data/lib/phusion_passenger/config/reopen_logs_command.rb +29 -7
  93. data/lib/phusion_passenger/config/restart_app_command.rb +13 -4
  94. data/lib/phusion_passenger/config/utils.rb +15 -8
  95. data/lib/phusion_passenger/constants.rb +6 -2
  96. data/lib/phusion_passenger/platform_info/apache.rb +4 -0
  97. data/lib/phusion_passenger/platform_info/apache_detector.rb +18 -3
  98. data/resources/templates/apache2/mpm_unknown.txt.erb +20 -0
  99. metadata +42 -21
  100. metadata.gz.asc +7 -7
  101. data/ext/common/ApplicationPool2/Pool/GeneralUtils.h +0 -127
  102. data/ext/common/ApplicationPool2/Pool/Inspection.h +0 -219
  103. data/ext/common/ApplicationPool2/Pool/ProcessUtils.h +0 -85
  104. data/ext/common/ApplicationPool2/SuperGroup.h +0 -706
  105. data/ext/common/agents/LoggingAgent/AdminServer.h +0 -435
  106. 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) 2014 Phusion
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 _PASSENGER_APPLICATION_POOL_SPAWNER_OBJECT_H_
26
- #define _PASSENGER_APPLICATION_POOL_SPAWNER_OBJECT_H_
25
+ #ifndef _PASSENGER_CLASS_UTILS_H_
26
+ #define _PASSENGER_CLASS_UTILS_H_
27
27
 
28
- #include <boost/noncopyable.hpp>
29
- #include <boost/move/core.hpp>
30
- #include <MemoryKit/palloc.h>
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
- ~SpawnObject() {
58
- if (pool != NULL) {
59
- psg_destroy_pool(pool);
60
- }
33
+ #define P_DEFINE_GETTER_REF(type, name) \
34
+ type &get ## name() { \
35
+ return m ## name; \
61
36
  }
62
37
 
63
- SpawnObject &operator=(BOOST_RV_REF(SpawnObject) r) {
64
- if (this != &r) {
65
- if (pool != r.pool) {
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
- } // namespace ApplicationPool2
81
- } // namespace Passenger
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 /* _PASSENGER_APPLICATION_POOL_SPAWNER_OBJECT_H_ */
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) {