Merge lp:~racb/ubuntu/precise/apache2/988819 into lp:ubuntu/precise/apache2
- Precise (12.04)
- 988819
- Merge into precise
Proposed by
Robie Basak
Status: | Merged |
---|---|
Merge reported by: | Martin Pitt |
Merged at revision: | not available |
Proposed branch: | lp:~racb/ubuntu/precise/apache2/988819 |
Merge into: | lp:ubuntu/precise/apache2 |
Diff against target: |
773 lines (+641/-35) 6 files modified
.pc/083_dlopen_search_path/modules/mappers/mod_so.c (+434/-0) .pc/applied-patches (+1/-0) debian/changelog (+9/-0) debian/patches/083_dlopen_search_path (+152/-0) debian/patches/series (+1/-0) modules/mappers/mod_so.c (+44/-35) |
To merge this branch: | bzr merge lp:~racb/ubuntu/precise/apache2/988819 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
James Page | Approve | ||
Ubuntu branches | Pending | ||
Review via email: mp+109379@code.launchpad.net |
Commit message
Description of the change
To post a comment you must log in.
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === added directory '.pc/083_dlopen_search_path' | |||
2 | === added directory '.pc/083_dlopen_search_path/modules' | |||
3 | === added directory '.pc/083_dlopen_search_path/modules/mappers' | |||
4 | === added file '.pc/083_dlopen_search_path/modules/mappers/mod_so.c' | |||
5 | --- .pc/083_dlopen_search_path/modules/mappers/mod_so.c 1970-01-01 00:00:00 +0000 | |||
6 | +++ .pc/083_dlopen_search_path/modules/mappers/mod_so.c 2012-06-08 15:02:19 +0000 | |||
7 | @@ -0,0 +1,434 @@ | |||
8 | 1 | /* Licensed to the Apache Software Foundation (ASF) under one or more | ||
9 | 2 | * contributor license agreements. See the NOTICE file distributed with | ||
10 | 3 | * this work for additional information regarding copyright ownership. | ||
11 | 4 | * The ASF licenses this file to You under the Apache License, Version 2.0 | ||
12 | 5 | * (the "License"); you may not use this file except in compliance with | ||
13 | 6 | * the License. You may obtain a copy of the License at | ||
14 | 7 | * | ||
15 | 8 | * http://www.apache.org/licenses/LICENSE-2.0 | ||
16 | 9 | * | ||
17 | 10 | * Unless required by applicable law or agreed to in writing, software | ||
18 | 11 | * distributed under the License is distributed on an "AS IS" BASIS, | ||
19 | 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
20 | 13 | * See the License for the specific language governing permissions and | ||
21 | 14 | * limitations under the License. | ||
22 | 15 | */ | ||
23 | 16 | |||
24 | 17 | /* | ||
25 | 18 | * This module is used to load Apache modules at runtime. This means that the | ||
26 | 19 | * server functionality can be extended without recompiling and even without | ||
27 | 20 | * taking the server down at all. Only a HUP or AP_SIG_GRACEFUL signal | ||
28 | 21 | * needs to be sent to the server to reload the dynamically loaded modules. | ||
29 | 22 | * | ||
30 | 23 | * To use, you'll first need to build your module as a shared library, then | ||
31 | 24 | * update your configuration (httpd.conf) to get the Apache core to load the | ||
32 | 25 | * module at start-up. | ||
33 | 26 | * | ||
34 | 27 | * The easiest way to build a module as a shared library is to use the | ||
35 | 28 | * `SharedModule' command in the Configuration file, instead of `AddModule'. | ||
36 | 29 | * You should also change the file extension from `.o' to `.so'. So, for | ||
37 | 30 | * example, to build the status module as a shared library edit Configuration | ||
38 | 31 | * and change | ||
39 | 32 | * AddModule modules/standard/mod_status.o | ||
40 | 33 | * to | ||
41 | 34 | * SharedModule modules/standard/mod_status.so | ||
42 | 35 | * | ||
43 | 36 | * Run Configure and make. Now Apache's httpd binary will _not_ include | ||
44 | 37 | * mod_status. Instead a shared object called mod_status.so will be build, in | ||
45 | 38 | * the modules/standard directory. You can build most of the modules as shared | ||
46 | 39 | * libraries like this. | ||
47 | 40 | * | ||
48 | 41 | * To use the shared module, move the .so file(s) into an appropriate | ||
49 | 42 | * directory. You might like to create a directory called "modules" under you | ||
50 | 43 | * server root for this (e.g. /usr/local/httpd/modules). | ||
51 | 44 | * | ||
52 | 45 | * Then edit your conf/httpd.conf file, and add LoadModule lines. For | ||
53 | 46 | * example | ||
54 | 47 | * LoadModule status_module modules/mod_status.so | ||
55 | 48 | * | ||
56 | 49 | * The first argument is the module's structure name (look at the end of the | ||
57 | 50 | * module source to find this). The second option is the path to the module | ||
58 | 51 | * file, relative to the server root. Put these directives right at the top | ||
59 | 52 | * of your httpd.conf file. | ||
60 | 53 | * | ||
61 | 54 | * Now you can start Apache. A message will be logged at "debug" level to your | ||
62 | 55 | * error_log to confirm that the module(s) are loaded (use "LogLevel debug" | ||
63 | 56 | * directive to get these log messages). | ||
64 | 57 | * | ||
65 | 58 | * If you edit the LoadModule directives while the server is live you can get | ||
66 | 59 | * Apache to re-load the modules by sending it a HUP or AP_SIG_GRACEFUL | ||
67 | 60 | * signal as normal. You can use this to dynamically change the capability | ||
68 | 61 | * of your server without bringing it down. | ||
69 | 62 | * | ||
70 | 63 | * Because currently there is only limited builtin support in the Configure | ||
71 | 64 | * script for creating the shared library files (`.so'), please consult your | ||
72 | 65 | * vendors cc(1), ld(1) and dlopen(3) manpages to find out the appropriate | ||
73 | 66 | * compiler and linker flags and insert them manually into the Configuration | ||
74 | 67 | * file under CFLAGS_SHLIB, LDFLAGS_SHLIB and LDFLAGS_SHLIB_EXPORT. | ||
75 | 68 | * | ||
76 | 69 | * If you still have problems figuring out the flags both try the paper | ||
77 | 70 | * http://developer.netscape.com/library/documentation/enterprise | ||
78 | 71 | * /unix/svrplug.htm#1013807 | ||
79 | 72 | * or install a Perl 5 interpreter on your platform and then run the command | ||
80 | 73 | * | ||
81 | 74 | * $ perl -V:usedl -V:ccdlflags -V:cccdlflags -V:lddlflags | ||
82 | 75 | * | ||
83 | 76 | * This gives you what type of dynamic loading Perl 5 uses on your platform | ||
84 | 77 | * and which compiler and linker flags Perl 5 uses to create the shared object | ||
85 | 78 | * files. | ||
86 | 79 | * | ||
87 | 80 | * Another location where you can find useful hints is the `ltconfig' script | ||
88 | 81 | * of the GNU libtool 1.2 package. Search for your platform name inside the | ||
89 | 82 | * various "case" constructs. | ||
90 | 83 | * | ||
91 | 84 | */ | ||
92 | 85 | |||
93 | 86 | #include "apr.h" | ||
94 | 87 | #include "apr_dso.h" | ||
95 | 88 | #include "apr_strings.h" | ||
96 | 89 | #include "apr_errno.h" | ||
97 | 90 | |||
98 | 91 | #define CORE_PRIVATE | ||
99 | 92 | #include "ap_config.h" | ||
100 | 93 | #include "httpd.h" | ||
101 | 94 | #include "http_config.h" | ||
102 | 95 | #include "http_log.h" | ||
103 | 96 | #include "http_core.h" | ||
104 | 97 | |||
105 | 98 | #include "mod_so.h" | ||
106 | 99 | |||
107 | 100 | module AP_MODULE_DECLARE_DATA so_module; | ||
108 | 101 | |||
109 | 102 | |||
110 | 103 | /* | ||
111 | 104 | * Server configuration to keep track of actually | ||
112 | 105 | * loaded modules and the corresponding module name. | ||
113 | 106 | */ | ||
114 | 107 | |||
115 | 108 | typedef struct so_server_conf { | ||
116 | 109 | apr_array_header_t *loaded_modules; | ||
117 | 110 | } so_server_conf; | ||
118 | 111 | |||
119 | 112 | static void *so_sconf_create(apr_pool_t *p, server_rec *s) | ||
120 | 113 | { | ||
121 | 114 | so_server_conf *soc; | ||
122 | 115 | |||
123 | 116 | soc = (so_server_conf *)apr_pcalloc(p, sizeof(so_server_conf)); | ||
124 | 117 | soc->loaded_modules = apr_array_make(p, DYNAMIC_MODULE_LIMIT, | ||
125 | 118 | sizeof(ap_module_symbol_t)); | ||
126 | 119 | |||
127 | 120 | return (void *)soc; | ||
128 | 121 | } | ||
129 | 122 | |||
130 | 123 | #ifndef NO_DLOPEN | ||
131 | 124 | |||
132 | 125 | /* | ||
133 | 126 | * This is the cleanup for a loaded shared object. It unloads the module. | ||
134 | 127 | * This is called as a cleanup function from the core. | ||
135 | 128 | */ | ||
136 | 129 | |||
137 | 130 | static apr_status_t unload_module(void *data) | ||
138 | 131 | { | ||
139 | 132 | ap_module_symbol_t *modi = (ap_module_symbol_t*)data; | ||
140 | 133 | |||
141 | 134 | /* only unload if module information is still existing */ | ||
142 | 135 | if (modi->modp == NULL) | ||
143 | 136 | return APR_SUCCESS; | ||
144 | 137 | |||
145 | 138 | /* remove the module pointer from the core structure */ | ||
146 | 139 | ap_remove_loaded_module(modi->modp); | ||
147 | 140 | |||
148 | 141 | /* destroy the module information */ | ||
149 | 142 | modi->modp = NULL; | ||
150 | 143 | modi->name = NULL; | ||
151 | 144 | return APR_SUCCESS; | ||
152 | 145 | } | ||
153 | 146 | |||
154 | 147 | /* | ||
155 | 148 | * This is called for the directive LoadModule and actually loads | ||
156 | 149 | * a shared object file into the address space of the server process. | ||
157 | 150 | */ | ||
158 | 151 | |||
159 | 152 | static const char *load_module(cmd_parms *cmd, void *dummy, | ||
160 | 153 | const char *modname, const char *filename) | ||
161 | 154 | { | ||
162 | 155 | apr_dso_handle_t *modhandle; | ||
163 | 156 | apr_dso_handle_sym_t modsym; | ||
164 | 157 | module *modp; | ||
165 | 158 | const char *szModuleFile = ap_server_root_relative(cmd->pool, filename); | ||
166 | 159 | so_server_conf *sconf; | ||
167 | 160 | ap_module_symbol_t *modi; | ||
168 | 161 | ap_module_symbol_t *modie; | ||
169 | 162 | int i; | ||
170 | 163 | const char *error; | ||
171 | 164 | |||
172 | 165 | /* we need to setup this value for dummy to make sure that we don't try | ||
173 | 166 | * to add a non-existant tree into the build when we return to | ||
174 | 167 | * execute_now. | ||
175 | 168 | */ | ||
176 | 169 | *(ap_directive_t **)dummy = NULL; | ||
177 | 170 | |||
178 | 171 | if (!szModuleFile) { | ||
179 | 172 | return apr_pstrcat(cmd->pool, "Invalid LoadModule path ", | ||
180 | 173 | filename, NULL); | ||
181 | 174 | } | ||
182 | 175 | |||
183 | 176 | /* | ||
184 | 177 | * check for already existing module | ||
185 | 178 | * If it already exists, we have nothing to do | ||
186 | 179 | * Check both dynamically-loaded modules and statically-linked modules. | ||
187 | 180 | */ | ||
188 | 181 | sconf = (so_server_conf *)ap_get_module_config(cmd->server->module_config, | ||
189 | 182 | &so_module); | ||
190 | 183 | modie = (ap_module_symbol_t *)sconf->loaded_modules->elts; | ||
191 | 184 | for (i = 0; i < sconf->loaded_modules->nelts; i++) { | ||
192 | 185 | modi = &modie[i]; | ||
193 | 186 | if (modi->name != NULL && strcmp(modi->name, modname) == 0) { | ||
194 | 187 | ap_log_perror(APLOG_MARK, APLOG_WARNING, 0, | ||
195 | 188 | cmd->pool, "module %s is already loaded, skipping", | ||
196 | 189 | modname); | ||
197 | 190 | return NULL; | ||
198 | 191 | } | ||
199 | 192 | } | ||
200 | 193 | |||
201 | 194 | for (i = 0; ap_preloaded_modules[i]; i++) { | ||
202 | 195 | const char *preload_name; | ||
203 | 196 | apr_size_t preload_len; | ||
204 | 197 | apr_size_t thismod_len; | ||
205 | 198 | |||
206 | 199 | modp = ap_preloaded_modules[i]; | ||
207 | 200 | |||
208 | 201 | /* make sure we're comparing apples with apples | ||
209 | 202 | * make sure name of preloaded module is mod_FOO.c | ||
210 | 203 | * make sure name of structure being loaded is FOO_module | ||
211 | 204 | */ | ||
212 | 205 | |||
213 | 206 | if (memcmp(modp->name, "mod_", 4)) { | ||
214 | 207 | continue; | ||
215 | 208 | } | ||
216 | 209 | |||
217 | 210 | preload_name = modp->name + strlen("mod_"); | ||
218 | 211 | preload_len = strlen(preload_name) - 2; | ||
219 | 212 | |||
220 | 213 | if (strlen(modname) <= strlen("_module")) { | ||
221 | 214 | continue; | ||
222 | 215 | } | ||
223 | 216 | thismod_len = strlen(modname) - strlen("_module"); | ||
224 | 217 | if (strcmp(modname + thismod_len, "_module")) { | ||
225 | 218 | continue; | ||
226 | 219 | } | ||
227 | 220 | |||
228 | 221 | if (thismod_len != preload_len) { | ||
229 | 222 | continue; | ||
230 | 223 | } | ||
231 | 224 | |||
232 | 225 | if (!memcmp(modname, preload_name, preload_len)) { | ||
233 | 226 | return apr_pstrcat(cmd->pool, "module ", modname, | ||
234 | 227 | " is built-in and can't be loaded", | ||
235 | 228 | NULL); | ||
236 | 229 | } | ||
237 | 230 | } | ||
238 | 231 | |||
239 | 232 | modi = apr_array_push(sconf->loaded_modules); | ||
240 | 233 | modi->name = modname; | ||
241 | 234 | |||
242 | 235 | /* | ||
243 | 236 | * Load the file into the Apache address space | ||
244 | 237 | */ | ||
245 | 238 | if (apr_dso_load(&modhandle, szModuleFile, cmd->pool) != APR_SUCCESS) { | ||
246 | 239 | char my_error[256]; | ||
247 | 240 | |||
248 | 241 | return apr_pstrcat(cmd->pool, "Cannot load ", szModuleFile, | ||
249 | 242 | " into server: ", | ||
250 | 243 | apr_dso_error(modhandle, my_error, sizeof(my_error)), | ||
251 | 244 | NULL); | ||
252 | 245 | } | ||
253 | 246 | ap_log_perror(APLOG_MARK, APLOG_DEBUG, 0, cmd->pool, | ||
254 | 247 | "loaded module %s", modname); | ||
255 | 248 | |||
256 | 249 | /* | ||
257 | 250 | * Retrieve the pointer to the module structure through the module name: | ||
258 | 251 | * First with the hidden variant (prefix `AP_') and then with the plain | ||
259 | 252 | * symbol name. | ||
260 | 253 | */ | ||
261 | 254 | if (apr_dso_sym(&modsym, modhandle, modname) != APR_SUCCESS) { | ||
262 | 255 | char my_error[256]; | ||
263 | 256 | |||
264 | 257 | return apr_pstrcat(cmd->pool, "Can't locate API module structure `", | ||
265 | 258 | modname, "' in file ", szModuleFile, ": ", | ||
266 | 259 | apr_dso_error(modhandle, my_error, sizeof(my_error)), | ||
267 | 260 | NULL); | ||
268 | 261 | } | ||
269 | 262 | modp = (module*) modsym; | ||
270 | 263 | modp->dynamic_load_handle = (apr_dso_handle_t *)modhandle; | ||
271 | 264 | modi->modp = modp; | ||
272 | 265 | |||
273 | 266 | /* | ||
274 | 267 | * Make sure the found module structure is really a module structure | ||
275 | 268 | * | ||
276 | 269 | */ | ||
277 | 270 | if (modp->magic != MODULE_MAGIC_COOKIE) { | ||
278 | 271 | return apr_psprintf(cmd->pool, "API module structure '%s' in file %s " | ||
279 | 272 | "is garbled - expected signature %08lx but saw " | ||
280 | 273 | "%08lx - perhaps this is not an Apache module DSO, " | ||
281 | 274 | "or was compiled for a different Apache version?", | ||
282 | 275 | modname, szModuleFile, | ||
283 | 276 | MODULE_MAGIC_COOKIE, modp->magic); | ||
284 | 277 | } | ||
285 | 278 | |||
286 | 279 | /* | ||
287 | 280 | * Add this module to the Apache core structures | ||
288 | 281 | */ | ||
289 | 282 | error = ap_add_loaded_module(modp, cmd->pool); | ||
290 | 283 | if (error) { | ||
291 | 284 | return error; | ||
292 | 285 | } | ||
293 | 286 | |||
294 | 287 | /* | ||
295 | 288 | * Register a cleanup in the config apr_pool_t (normally pconf). When | ||
296 | 289 | * we do a restart (or shutdown) this cleanup will cause the | ||
297 | 290 | * shared object to be unloaded. | ||
298 | 291 | */ | ||
299 | 292 | apr_pool_cleanup_register(cmd->pool, modi, unload_module, apr_pool_cleanup_null); | ||
300 | 293 | |||
301 | 294 | /* | ||
302 | 295 | * Finally we need to run the configuration process for the module | ||
303 | 296 | */ | ||
304 | 297 | ap_single_module_configure(cmd->pool, cmd->server, modp); | ||
305 | 298 | |||
306 | 299 | return NULL; | ||
307 | 300 | } | ||
308 | 301 | |||
309 | 302 | /* | ||
310 | 303 | * This implements the LoadFile directive and loads an arbitrary | ||
311 | 304 | * shared object file into the adress space of the server process. | ||
312 | 305 | */ | ||
313 | 306 | |||
314 | 307 | static const char *load_file(cmd_parms *cmd, void *dummy, const char *filename) | ||
315 | 308 | { | ||
316 | 309 | apr_dso_handle_t *handle; | ||
317 | 310 | const char *file; | ||
318 | 311 | |||
319 | 312 | file = ap_server_root_relative(cmd->pool, filename); | ||
320 | 313 | |||
321 | 314 | if (!file) { | ||
322 | 315 | return apr_pstrcat(cmd->pool, "Invalid LoadFile path ", | ||
323 | 316 | filename, NULL); | ||
324 | 317 | } | ||
325 | 318 | |||
326 | 319 | if (apr_dso_load(&handle, file, cmd->pool) != APR_SUCCESS) { | ||
327 | 320 | char my_error[256]; | ||
328 | 321 | |||
329 | 322 | return apr_pstrcat(cmd->pool, "Cannot load ", filename, | ||
330 | 323 | " into server: ", | ||
331 | 324 | apr_dso_error(handle, my_error, sizeof(my_error)), | ||
332 | 325 | NULL); | ||
333 | 326 | } | ||
334 | 327 | |||
335 | 328 | ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, NULL, | ||
336 | 329 | "loaded file %s", filename); | ||
337 | 330 | |||
338 | 331 | return NULL; | ||
339 | 332 | } | ||
340 | 333 | |||
341 | 334 | static module *ap_find_loaded_module_symbol(server_rec *s, const char *modname) | ||
342 | 335 | { | ||
343 | 336 | so_server_conf *sconf; | ||
344 | 337 | ap_module_symbol_t *modi; | ||
345 | 338 | ap_module_symbol_t *modie; | ||
346 | 339 | int i; | ||
347 | 340 | |||
348 | 341 | sconf = (so_server_conf *)ap_get_module_config(s->module_config, | ||
349 | 342 | &so_module); | ||
350 | 343 | modie = (ap_module_symbol_t *)sconf->loaded_modules->elts; | ||
351 | 344 | |||
352 | 345 | for (i = 0; i < sconf->loaded_modules->nelts; i++) { | ||
353 | 346 | modi = &modie[i]; | ||
354 | 347 | if (modi->name != NULL && strcmp(modi->name, modname) == 0) { | ||
355 | 348 | return modi->modp; | ||
356 | 349 | } | ||
357 | 350 | } | ||
358 | 351 | return NULL; | ||
359 | 352 | } | ||
360 | 353 | |||
361 | 354 | static void dump_loaded_modules(apr_pool_t *p, server_rec *s) | ||
362 | 355 | { | ||
363 | 356 | ap_module_symbol_t *modie; | ||
364 | 357 | ap_module_symbol_t *modi; | ||
365 | 358 | so_server_conf *sconf; | ||
366 | 359 | int i; | ||
367 | 360 | apr_file_t *out = NULL; | ||
368 | 361 | |||
369 | 362 | if (!ap_exists_config_define("DUMP_MODULES")) { | ||
370 | 363 | return; | ||
371 | 364 | } | ||
372 | 365 | |||
373 | 366 | apr_file_open_stdout(&out, p); | ||
374 | 367 | |||
375 | 368 | apr_file_printf(out, "Loaded Modules:\n"); | ||
376 | 369 | |||
377 | 370 | sconf = (so_server_conf *)ap_get_module_config(s->module_config, | ||
378 | 371 | &so_module); | ||
379 | 372 | for (i = 0; ; i++) { | ||
380 | 373 | modi = &ap_prelinked_module_symbols[i]; | ||
381 | 374 | if (modi->name != NULL) { | ||
382 | 375 | apr_file_printf(out, " %s (static)\n", modi->name); | ||
383 | 376 | } | ||
384 | 377 | else { | ||
385 | 378 | break; | ||
386 | 379 | } | ||
387 | 380 | } | ||
388 | 381 | |||
389 | 382 | modie = (ap_module_symbol_t *)sconf->loaded_modules->elts; | ||
390 | 383 | for (i = 0; i < sconf->loaded_modules->nelts; i++) { | ||
391 | 384 | modi = &modie[i]; | ||
392 | 385 | if (modi->name != NULL) { | ||
393 | 386 | apr_file_printf(out, " %s (shared)\n", modi->name); | ||
394 | 387 | } | ||
395 | 388 | } | ||
396 | 389 | } | ||
397 | 390 | |||
398 | 391 | #else /* not NO_DLOPEN */ | ||
399 | 392 | |||
400 | 393 | static const char *load_file(cmd_parms *cmd, void *dummy, const char *filename) | ||
401 | 394 | { | ||
402 | 395 | ap_log_perror(APLOG_MARK, APLOG_STARTUP, 0, cmd->pool, | ||
403 | 396 | "WARNING: LoadFile not supported on this platform"); | ||
404 | 397 | return NULL; | ||
405 | 398 | } | ||
406 | 399 | |||
407 | 400 | static const char *load_module(cmd_parms *cmd, void *dummy, | ||
408 | 401 | const char *modname, const char *filename) | ||
409 | 402 | { | ||
410 | 403 | ap_log_perror(APLOG_MARK, APLOG_STARTUP, 0, cmd->pool, | ||
411 | 404 | "WARNING: LoadModule not supported on this platform"); | ||
412 | 405 | return NULL; | ||
413 | 406 | } | ||
414 | 407 | |||
415 | 408 | #endif /* NO_DLOPEN */ | ||
416 | 409 | |||
417 | 410 | static void register_hooks(apr_pool_t *p) | ||
418 | 411 | { | ||
419 | 412 | #ifndef NO_DLOPEN | ||
420 | 413 | APR_REGISTER_OPTIONAL_FN(ap_find_loaded_module_symbol); | ||
421 | 414 | ap_hook_test_config(dump_loaded_modules, NULL, NULL, APR_HOOK_MIDDLE); | ||
422 | 415 | #endif | ||
423 | 416 | } | ||
424 | 417 | |||
425 | 418 | static const command_rec so_cmds[] = { | ||
426 | 419 | AP_INIT_TAKE2("LoadModule", load_module, NULL, RSRC_CONF | EXEC_ON_READ, | ||
427 | 420 | "a module name and the name of a shared object file to load it from"), | ||
428 | 421 | AP_INIT_ITERATE("LoadFile", load_file, NULL, RSRC_CONF | EXEC_ON_READ, | ||
429 | 422 | "shared object file or library to load into the server at runtime"), | ||
430 | 423 | { NULL } | ||
431 | 424 | }; | ||
432 | 425 | |||
433 | 426 | module AP_MODULE_DECLARE_DATA so_module = { | ||
434 | 427 | STANDARD20_MODULE_STUFF, | ||
435 | 428 | NULL, /* create per-dir config */ | ||
436 | 429 | NULL, /* merge per-dir config */ | ||
437 | 430 | so_sconf_create, /* server config */ | ||
438 | 431 | NULL, /* merge server config */ | ||
439 | 432 | so_cmds, /* command apr_table_t */ | ||
440 | 433 | register_hooks /* register hooks */ | ||
441 | 434 | }; | ||
442 | 0 | 435 | ||
443 | === modified file '.pc/applied-patches' | |||
444 | --- .pc/applied-patches 2012-02-01 21:49:04 +0000 | |||
445 | +++ .pc/applied-patches 2012-06-08 15:02:19 +0000 | |||
446 | @@ -21,5 +21,6 @@ | |||
447 | 21 | 077_CacheIgnoreURLSessionIdentifiers | 21 | 077_CacheIgnoreURLSessionIdentifiers |
448 | 22 | 079_polish_translation | 22 | 079_polish_translation |
449 | 23 | 082_ab_num_requests | 23 | 082_ab_num_requests |
450 | 24 | 083_dlopen_search_path | ||
451 | 24 | 099_config_guess_sub_update | 25 | 099_config_guess_sub_update |
452 | 25 | 201_build_suexec-custom | 26 | 201_build_suexec-custom |
453 | 26 | 27 | ||
454 | === modified file 'debian/changelog' | |||
455 | --- debian/changelog 2012-02-12 20:06:35 +0000 | |||
456 | +++ debian/changelog 2012-06-08 15:02:19 +0000 | |||
457 | @@ -1,3 +1,12 @@ | |||
458 | 1 | apache2 (2.2.22-1ubuntu1.1) precise-proposed; urgency=low | ||
459 | 2 | |||
460 | 3 | * debian/patches/083_dlopen_search_path: use dlopen() search path to | ||
461 | 4 | enable modules that use multiarch, such as libapache2-modsecurity. | ||
462 | 5 | These modules can now use no path and apache2 will be able to find | ||
463 | 6 | them (LP: #988819). | ||
464 | 7 | |||
465 | 8 | -- Robie Basak <robie.basak@ubuntu.com> Fri, 08 Jun 2012 15:45:02 +0100 | ||
466 | 9 | |||
467 | 1 | apache2 (2.2.22-1ubuntu1) precise; urgency=low | 10 | apache2 (2.2.22-1ubuntu1) precise; urgency=low |
468 | 2 | 11 | ||
469 | 3 | * Merge from Debian testing. Remaining changes: | 12 | * Merge from Debian testing. Remaining changes: |
470 | 4 | 13 | ||
471 | === added file 'debian/patches/083_dlopen_search_path' | |||
472 | --- debian/patches/083_dlopen_search_path 1970-01-01 00:00:00 +0000 | |||
473 | +++ debian/patches/083_dlopen_search_path 2012-06-08 15:02:19 +0000 | |||
474 | @@ -0,0 +1,152 @@ | |||
475 | 1 | Backport r1332378 from upstream trunk: | ||
476 | 2 | |||
477 | 3 | If a filename without slashes is specified for LoadFile or | ||
478 | 4 | LoadModule and the file cannot be found in the server root directory, | ||
479 | 5 | try to use the standard dlopen() search path. | ||
480 | 6 | |||
481 | 7 | git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1332378 13f79535-47bb-0310-9956-ffa450edef68 | ||
482 | 8 | |||
483 | 9 | Author: Stefan Fritsch | ||
484 | 10 | Origin: upstream, http://svn.apache.org/viewvc?view=revision&revision=1332378 | ||
485 | 11 | Bug-Debian: http://bugs.debian.org/670247 | ||
486 | 12 | Bug-Ubuntu: https://launchpad.net/bugs/988819 | ||
487 | 13 | Last-Update: 2012-06-08 | ||
488 | 14 | |||
489 | 15 | --- | ||
490 | 16 | modules/mappers/mod_so.c | 77 ++++++++++++++++++++++++++-------------------- | ||
491 | 17 | 1 file changed, 43 insertions(+), 34 deletions(-) | ||
492 | 18 | |||
493 | 19 | diff --git a/modules/mappers/mod_so.c b/modules/mappers/mod_so.c | ||
494 | 20 | index 2d4a54c..6a9fdae 100644 | ||
495 | 21 | --- a/modules/mappers/mod_so.c | ||
496 | 22 | +++ b/modules/mappers/mod_so.c | ||
497 | 23 | @@ -144,6 +144,37 @@ static apr_status_t unload_module(void *data) | ||
498 | 24 | return APR_SUCCESS; | ||
499 | 25 | } | ||
500 | 26 | |||
501 | 27 | +static const char *dso_load(cmd_parms *cmd, apr_dso_handle_t **modhandlep, | ||
502 | 28 | + const char *filename, const char **used_filename) | ||
503 | 29 | +{ | ||
504 | 30 | + int retry = 0; | ||
505 | 31 | + const char *fullname = ap_server_root_relative(cmd->temp_pool, filename); | ||
506 | 32 | + char my_error[256]; | ||
507 | 33 | + if (filename != NULL && ap_strchr_c(filename, '/') == NULL) { | ||
508 | 34 | + /* retry on error without path to use dlopen()'s search path */ | ||
509 | 35 | + retry = 1; | ||
510 | 36 | + } | ||
511 | 37 | + | ||
512 | 38 | + if (fullname == NULL && !retry) { | ||
513 | 39 | + return apr_psprintf(cmd->temp_pool, "Invalid %s path %s", | ||
514 | 40 | + cmd->cmd->name, filename); | ||
515 | 41 | + } | ||
516 | 42 | + *used_filename = fullname; | ||
517 | 43 | + if (apr_dso_load(modhandlep, fullname, cmd->pool) == APR_SUCCESS) { | ||
518 | 44 | + return NULL; | ||
519 | 45 | + } | ||
520 | 46 | + if (retry) { | ||
521 | 47 | + *used_filename = filename; | ||
522 | 48 | + if (apr_dso_load(modhandlep, filename, cmd->pool) == APR_SUCCESS) | ||
523 | 49 | + return NULL; | ||
524 | 50 | + } | ||
525 | 51 | + | ||
526 | 52 | + return apr_pstrcat(cmd->temp_pool, "Cannot load ", filename, | ||
527 | 53 | + " into server: ", | ||
528 | 54 | + apr_dso_error(*modhandlep, my_error, sizeof(my_error)), | ||
529 | 55 | + NULL); | ||
530 | 56 | +} | ||
531 | 57 | + | ||
532 | 58 | /* | ||
533 | 59 | * This is called for the directive LoadModule and actually loads | ||
534 | 60 | * a shared object file into the address space of the server process. | ||
535 | 61 | @@ -155,7 +186,7 @@ static const char *load_module(cmd_parms *cmd, void *dummy, | ||
536 | 62 | apr_dso_handle_t *modhandle; | ||
537 | 63 | apr_dso_handle_sym_t modsym; | ||
538 | 64 | module *modp; | ||
539 | 65 | - const char *szModuleFile = ap_server_root_relative(cmd->pool, filename); | ||
540 | 66 | + const char *module_file; | ||
541 | 67 | so_server_conf *sconf; | ||
542 | 68 | ap_module_symbol_t *modi; | ||
543 | 69 | ap_module_symbol_t *modie; | ||
544 | 70 | @@ -168,11 +199,6 @@ static const char *load_module(cmd_parms *cmd, void *dummy, | ||
545 | 71 | */ | ||
546 | 72 | *(ap_directive_t **)dummy = NULL; | ||
547 | 73 | |||
548 | 74 | - if (!szModuleFile) { | ||
549 | 75 | - return apr_pstrcat(cmd->pool, "Invalid LoadModule path ", | ||
550 | 76 | - filename, NULL); | ||
551 | 77 | - } | ||
552 | 78 | - | ||
553 | 79 | /* | ||
554 | 80 | * check for already existing module | ||
555 | 81 | * If it already exists, we have nothing to do | ||
556 | 82 | @@ -235,16 +261,11 @@ static const char *load_module(cmd_parms *cmd, void *dummy, | ||
557 | 83 | /* | ||
558 | 84 | * Load the file into the Apache address space | ||
559 | 85 | */ | ||
560 | 86 | - if (apr_dso_load(&modhandle, szModuleFile, cmd->pool) != APR_SUCCESS) { | ||
561 | 87 | - char my_error[256]; | ||
562 | 88 | - | ||
563 | 89 | - return apr_pstrcat(cmd->pool, "Cannot load ", szModuleFile, | ||
564 | 90 | - " into server: ", | ||
565 | 91 | - apr_dso_error(modhandle, my_error, sizeof(my_error)), | ||
566 | 92 | - NULL); | ||
567 | 93 | - } | ||
568 | 94 | + error = dso_load(cmd, &modhandle, filename, &module_file); | ||
569 | 95 | + if (error) | ||
570 | 96 | + return error; | ||
571 | 97 | ap_log_perror(APLOG_MARK, APLOG_DEBUG, 0, cmd->pool, | ||
572 | 98 | - "loaded module %s", modname); | ||
573 | 99 | + "loaded module %s from %s", modname, module_file); | ||
574 | 100 | |||
575 | 101 | /* | ||
576 | 102 | * Retrieve the pointer to the module structure through the module name: | ||
577 | 103 | @@ -255,7 +276,7 @@ static const char *load_module(cmd_parms *cmd, void *dummy, | ||
578 | 104 | char my_error[256]; | ||
579 | 105 | |||
580 | 106 | return apr_pstrcat(cmd->pool, "Can't locate API module structure `", | ||
581 | 107 | - modname, "' in file ", szModuleFile, ": ", | ||
582 | 108 | + modname, "' in file ", module_file, ": ", | ||
583 | 109 | apr_dso_error(modhandle, my_error, sizeof(my_error)), | ||
584 | 110 | NULL); | ||
585 | 111 | } | ||
586 | 112 | @@ -272,7 +293,7 @@ static const char *load_module(cmd_parms *cmd, void *dummy, | ||
587 | 113 | "is garbled - expected signature %08lx but saw " | ||
588 | 114 | "%08lx - perhaps this is not an Apache module DSO, " | ||
589 | 115 | "or was compiled for a different Apache version?", | ||
590 | 116 | - modname, szModuleFile, | ||
591 | 117 | + modname, module_file, | ||
592 | 118 | MODULE_MAGIC_COOKIE, modp->magic); | ||
593 | 119 | } | ||
594 | 120 | |||
595 | 121 | @@ -307,26 +328,14 @@ static const char *load_module(cmd_parms *cmd, void *dummy, | ||
596 | 122 | static const char *load_file(cmd_parms *cmd, void *dummy, const char *filename) | ||
597 | 123 | { | ||
598 | 124 | apr_dso_handle_t *handle; | ||
599 | 125 | - const char *file; | ||
600 | 126 | - | ||
601 | 127 | - file = ap_server_root_relative(cmd->pool, filename); | ||
602 | 128 | + const char *used_file, *error; | ||
603 | 129 | |||
604 | 130 | - if (!file) { | ||
605 | 131 | - return apr_pstrcat(cmd->pool, "Invalid LoadFile path ", | ||
606 | 132 | - filename, NULL); | ||
607 | 133 | - } | ||
608 | 134 | - | ||
609 | 135 | - if (apr_dso_load(&handle, file, cmd->pool) != APR_SUCCESS) { | ||
610 | 136 | - char my_error[256]; | ||
611 | 137 | - | ||
612 | 138 | - return apr_pstrcat(cmd->pool, "Cannot load ", filename, | ||
613 | 139 | - " into server: ", | ||
614 | 140 | - apr_dso_error(handle, my_error, sizeof(my_error)), | ||
615 | 141 | - NULL); | ||
616 | 142 | - } | ||
617 | 143 | + error = dso_load(cmd, &handle, filename, &used_file); | ||
618 | 144 | + if (error) | ||
619 | 145 | + return error; | ||
620 | 146 | |||
621 | 147 | ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, NULL, | ||
622 | 148 | - "loaded file %s", filename); | ||
623 | 149 | + "loaded file %s", used_file); | ||
624 | 150 | |||
625 | 151 | return NULL; | ||
626 | 152 | } | ||
627 | 0 | 153 | ||
628 | === modified file 'debian/patches/series' | |||
629 | --- debian/patches/series 2012-02-01 21:49:04 +0000 | |||
630 | +++ debian/patches/series 2012-06-08 15:02:19 +0000 | |||
631 | @@ -21,6 +21,7 @@ | |||
632 | 21 | 077_CacheIgnoreURLSessionIdentifiers | 21 | 077_CacheIgnoreURLSessionIdentifiers |
633 | 22 | 079_polish_translation | 22 | 079_polish_translation |
634 | 23 | 082_ab_num_requests | 23 | 082_ab_num_requests |
635 | 24 | 083_dlopen_search_path | ||
636 | 24 | 099_config_guess_sub_update | 25 | 099_config_guess_sub_update |
637 | 25 | 201_build_suexec-custom | 26 | 201_build_suexec-custom |
638 | 26 | # The patch below must not be applied by quilt at extraction time. It depends | 27 | # The patch below must not be applied by quilt at extraction time. It depends |
639 | 27 | 28 | ||
640 | === modified file 'modules/mappers/mod_so.c' | |||
641 | --- modules/mappers/mod_so.c 2009-08-04 11:02:34 +0000 | |||
642 | +++ modules/mappers/mod_so.c 2012-06-08 15:02:19 +0000 | |||
643 | @@ -144,6 +144,37 @@ | |||
644 | 144 | return APR_SUCCESS; | 144 | return APR_SUCCESS; |
645 | 145 | } | 145 | } |
646 | 146 | 146 | ||
647 | 147 | static const char *dso_load(cmd_parms *cmd, apr_dso_handle_t **modhandlep, | ||
648 | 148 | const char *filename, const char **used_filename) | ||
649 | 149 | { | ||
650 | 150 | int retry = 0; | ||
651 | 151 | const char *fullname = ap_server_root_relative(cmd->temp_pool, filename); | ||
652 | 152 | char my_error[256]; | ||
653 | 153 | if (filename != NULL && ap_strchr_c(filename, '/') == NULL) { | ||
654 | 154 | /* retry on error without path to use dlopen()'s search path */ | ||
655 | 155 | retry = 1; | ||
656 | 156 | } | ||
657 | 157 | |||
658 | 158 | if (fullname == NULL && !retry) { | ||
659 | 159 | return apr_psprintf(cmd->temp_pool, "Invalid %s path %s", | ||
660 | 160 | cmd->cmd->name, filename); | ||
661 | 161 | } | ||
662 | 162 | *used_filename = fullname; | ||
663 | 163 | if (apr_dso_load(modhandlep, fullname, cmd->pool) == APR_SUCCESS) { | ||
664 | 164 | return NULL; | ||
665 | 165 | } | ||
666 | 166 | if (retry) { | ||
667 | 167 | *used_filename = filename; | ||
668 | 168 | if (apr_dso_load(modhandlep, filename, cmd->pool) == APR_SUCCESS) | ||
669 | 169 | return NULL; | ||
670 | 170 | } | ||
671 | 171 | |||
672 | 172 | return apr_pstrcat(cmd->temp_pool, "Cannot load ", filename, | ||
673 | 173 | " into server: ", | ||
674 | 174 | apr_dso_error(*modhandlep, my_error, sizeof(my_error)), | ||
675 | 175 | NULL); | ||
676 | 176 | } | ||
677 | 177 | |||
678 | 147 | /* | 178 | /* |
679 | 148 | * This is called for the directive LoadModule and actually loads | 179 | * This is called for the directive LoadModule and actually loads |
680 | 149 | * a shared object file into the address space of the server process. | 180 | * a shared object file into the address space of the server process. |
681 | @@ -155,7 +186,7 @@ | |||
682 | 155 | apr_dso_handle_t *modhandle; | 186 | apr_dso_handle_t *modhandle; |
683 | 156 | apr_dso_handle_sym_t modsym; | 187 | apr_dso_handle_sym_t modsym; |
684 | 157 | module *modp; | 188 | module *modp; |
686 | 158 | const char *szModuleFile = ap_server_root_relative(cmd->pool, filename); | 189 | const char *module_file; |
687 | 159 | so_server_conf *sconf; | 190 | so_server_conf *sconf; |
688 | 160 | ap_module_symbol_t *modi; | 191 | ap_module_symbol_t *modi; |
689 | 161 | ap_module_symbol_t *modie; | 192 | ap_module_symbol_t *modie; |
690 | @@ -168,11 +199,6 @@ | |||
691 | 168 | */ | 199 | */ |
692 | 169 | *(ap_directive_t **)dummy = NULL; | 200 | *(ap_directive_t **)dummy = NULL; |
693 | 170 | 201 | ||
694 | 171 | if (!szModuleFile) { | ||
695 | 172 | return apr_pstrcat(cmd->pool, "Invalid LoadModule path ", | ||
696 | 173 | filename, NULL); | ||
697 | 174 | } | ||
698 | 175 | |||
699 | 176 | /* | 202 | /* |
700 | 177 | * check for already existing module | 203 | * check for already existing module |
701 | 178 | * If it already exists, we have nothing to do | 204 | * If it already exists, we have nothing to do |
702 | @@ -235,16 +261,11 @@ | |||
703 | 235 | /* | 261 | /* |
704 | 236 | * Load the file into the Apache address space | 262 | * Load the file into the Apache address space |
705 | 237 | */ | 263 | */ |
714 | 238 | if (apr_dso_load(&modhandle, szModuleFile, cmd->pool) != APR_SUCCESS) { | 264 | error = dso_load(cmd, &modhandle, filename, &module_file); |
715 | 239 | char my_error[256]; | 265 | if (error) |
716 | 240 | 266 | return error; | |
709 | 241 | return apr_pstrcat(cmd->pool, "Cannot load ", szModuleFile, | ||
710 | 242 | " into server: ", | ||
711 | 243 | apr_dso_error(modhandle, my_error, sizeof(my_error)), | ||
712 | 244 | NULL); | ||
713 | 245 | } | ||
717 | 246 | ap_log_perror(APLOG_MARK, APLOG_DEBUG, 0, cmd->pool, | 267 | ap_log_perror(APLOG_MARK, APLOG_DEBUG, 0, cmd->pool, |
719 | 247 | "loaded module %s", modname); | 268 | "loaded module %s from %s", modname, module_file); |
720 | 248 | 269 | ||
721 | 249 | /* | 270 | /* |
722 | 250 | * Retrieve the pointer to the module structure through the module name: | 271 | * Retrieve the pointer to the module structure through the module name: |
723 | @@ -255,7 +276,7 @@ | |||
724 | 255 | char my_error[256]; | 276 | char my_error[256]; |
725 | 256 | 277 | ||
726 | 257 | return apr_pstrcat(cmd->pool, "Can't locate API module structure `", | 278 | return apr_pstrcat(cmd->pool, "Can't locate API module structure `", |
728 | 258 | modname, "' in file ", szModuleFile, ": ", | 279 | modname, "' in file ", module_file, ": ", |
729 | 259 | apr_dso_error(modhandle, my_error, sizeof(my_error)), | 280 | apr_dso_error(modhandle, my_error, sizeof(my_error)), |
730 | 260 | NULL); | 281 | NULL); |
731 | 261 | } | 282 | } |
732 | @@ -272,7 +293,7 @@ | |||
733 | 272 | "is garbled - expected signature %08lx but saw " | 293 | "is garbled - expected signature %08lx but saw " |
734 | 273 | "%08lx - perhaps this is not an Apache module DSO, " | 294 | "%08lx - perhaps this is not an Apache module DSO, " |
735 | 274 | "or was compiled for a different Apache version?", | 295 | "or was compiled for a different Apache version?", |
737 | 275 | modname, szModuleFile, | 296 | modname, module_file, |
738 | 276 | MODULE_MAGIC_COOKIE, modp->magic); | 297 | MODULE_MAGIC_COOKIE, modp->magic); |
739 | 277 | } | 298 | } |
740 | 278 | 299 | ||
741 | @@ -307,26 +328,14 @@ | |||
742 | 307 | static const char *load_file(cmd_parms *cmd, void *dummy, const char *filename) | 328 | static const char *load_file(cmd_parms *cmd, void *dummy, const char *filename) |
743 | 308 | { | 329 | { |
744 | 309 | apr_dso_handle_t *handle; | 330 | apr_dso_handle_t *handle; |
762 | 310 | const char *file; | 331 | const char *used_file, *error; |
763 | 311 | 332 | ||
764 | 312 | file = ap_server_root_relative(cmd->pool, filename); | 333 | error = dso_load(cmd, &handle, filename, &used_file); |
765 | 313 | 334 | if (error) | |
766 | 314 | if (!file) { | 335 | return error; |
750 | 315 | return apr_pstrcat(cmd->pool, "Invalid LoadFile path ", | ||
751 | 316 | filename, NULL); | ||
752 | 317 | } | ||
753 | 318 | |||
754 | 319 | if (apr_dso_load(&handle, file, cmd->pool) != APR_SUCCESS) { | ||
755 | 320 | char my_error[256]; | ||
756 | 321 | |||
757 | 322 | return apr_pstrcat(cmd->pool, "Cannot load ", filename, | ||
758 | 323 | " into server: ", | ||
759 | 324 | apr_dso_error(handle, my_error, sizeof(my_error)), | ||
760 | 325 | NULL); | ||
761 | 326 | } | ||
767 | 327 | 336 | ||
768 | 328 | ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, NULL, | 337 | ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, NULL, |
770 | 329 | "loaded file %s", filename); | 338 | "loaded file %s", used_file); |
771 | 330 | 339 | ||
772 | 331 | return NULL; | 340 | return NULL; |
773 | 332 | } | 341 | } |
Uploaded to -proposed