1 /* Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache License, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 /*
18 * http_config.c: once was auxiliary functions for reading httpd's config
19 * file and converting filenames into a namespace
20 *
21 * Rob McCool
22 *
23 * Wall-to-wall rewrite for Apache... commands which are part of the
24 * server core can now be found next door in "http_core.c". Now contains
25 * general command loop, and functions which do bookkeeping for the new
26 * Apache config stuff (modules and configuration vectors).
27 *
28 * rst
29 *
30 */
31
32 #include "apr.h"
33 #include "apr_strings.h"
34 #include "apr_portable.h"
35 #include "apr_file_io.h"
36 #include "apr_fnmatch.h"
37
38 #define APR_WANT_STDIO
39 #define APR_WANT_STRFUNC
40 #include "apr_want.h"
41
42 #include "ap_config.h"
43 #include "httpd.h"
44 #include "http_config.h"
45 #include "http_protocol.h"
46 #include "http_core.h"
47 #include "http_log.h" /* for errors in parse_htaccess */
48 #include "http_request.h" /* for default_handler (see invoke_handler) */
49 #include "http_main.h"
50 #include "http_vhost.h"
51 #include "util_cfgtree.h"
52 #include "util_varbuf.h"
53 #include "mpm_common.h"
54
55 #define APLOG_UNSET (APLOG_NO_MODULE - 1)
56 /* we know core's module_index is 0 */
57 #undef APLOG_MODULE_INDEX
58 #define APLOG_MODULE_INDEX AP_CORE_MODULE_INDEX
59
60 AP_DECLARE_DATA const char *ap_server_argv0 = NULL;
61 AP_DECLARE_DATA const char *ap_server_root = NULL;
62 AP_DECLARE_DATA server_rec *ap_server_conf = NULL;
63 AP_DECLARE_DATA apr_pool_t *ap_pglobal = NULL;
64
65 AP_DECLARE_DATA apr_array_header_t *ap_server_pre_read_config = NULL;
66 AP_DECLARE_DATA apr_array_header_t *ap_server_post_read_config = NULL;
67 AP_DECLARE_DATA apr_array_header_t *ap_server_config_defines = NULL;
68
69 AP_DECLARE_DATA ap_directive_t *ap_conftree = NULL;
70
71 APR_HOOK_STRUCT(
72 APR_HOOK_LINK(header_parser)
73 APR_HOOK_LINK(pre_config)
74 APR_HOOK_LINK(check_config)
75 APR_HOOK_LINK(post_config)
76 APR_HOOK_LINK(open_logs)
77 APR_HOOK_LINK(child_init)
78 APR_HOOK_LINK(handler)
79 APR_HOOK_LINK(quick_handler)
80 APR_HOOK_LINK(optional_fn_retrieve)
81 APR_HOOK_LINK(test_config)
82 APR_HOOK_LINK(open_htaccess)
83 )
84
85 AP_IMPLEMENT_HOOK_RUN_ALL(int, header_parser,
86 (request_rec *r), (r), OK, DECLINED)
87
88 AP_IMPLEMENT_HOOK_RUN_ALL(int, pre_config,
89 (apr_pool_t *pconf, apr_pool_t *plog,
90 apr_pool_t *ptemp),
91 (pconf, plog, ptemp), OK, DECLINED)
92
93 AP_IMPLEMENT_HOOK_RUN_ALL(int, check_config,
94 (apr_pool_t *pconf, apr_pool_t *plog,
95 apr_pool_t *ptemp, server_rec *s),
96 (pconf, plog, ptemp, s), OK, DECLINED)
97
98 AP_IMPLEMENT_HOOK_VOID(test_config,
99 (apr_pool_t *pconf, server_rec *s),
100 (pconf, s))
101
102 AP_IMPLEMENT_HOOK_RUN_ALL(int, post_config,
103 (apr_pool_t *pconf, apr_pool_t *plog,
104 apr_pool_t *ptemp, server_rec *s),
105 (pconf, plog, ptemp, s), OK, DECLINED)
106
107 /* During the course of debugging I expanded this macro out, so
108 * rather than remove all the useful information there is in the
109 * following lines, I'm going to leave it here in case anyone
110 * else finds it useful.
111 *
112 * Ben has looked at it and thinks it correct :)
113 *
114 AP_DECLARE(int) ap_hook_post_config(ap_HOOK_post_config_t *pf,
115 const char * const *aszPre,
116 const char * const *aszSucc,
117 int nOrder)
118 {
119 ap_LINK_post_config_t *pHook;
120
121 if (!_hooks.link_post_config) {
122 _hooks.link_post_config = apr_array_make(apr_hook_global_pool, 1,
123 sizeof(ap_LINK_post_config_t));
124 apr_hook_sort_register("post_config", &_hooks.link_post_config);
125 }
126
127 pHook = apr_array_push(_hooks.link_post_config);
128 pHook->pFunc = pf;
129 pHook->aszPredecessors = aszPre;
130 pHook->aszSuccessors = aszSucc;
131 pHook->nOrder = nOrder;
132 pHook->szName = apr_hook_debug_current;
133
134 if (apr_hook_debug_enabled)
135 apr_hook_debug_show("post_config", aszPre, aszSucc);
136 }
137
138 AP_DECLARE(apr_array_header_t *) ap_hook_get_post_config(void)
139 {
140 return _hooks.link_post_config;
141 }
142
143 AP_DECLARE(int) ap_run_post_config(apr_pool_t *pconf,
144 apr_pool_t *plog,
145 apr_pool_t *ptemp,
146 server_rec *s)
147 {
148 ap_LINK_post_config_t *pHook;
149 int n;
150
151 if (!_hooks.link_post_config)
152 return;
153
154 pHook = (ap_LINK_post_config_t *)_hooks.link_post_config->elts;
155 for (n = 0; n < _hooks.link_post_config->nelts; ++n)
156 pHook[n].pFunc (pconf, plog, ptemp, s);
157 }
158 */
159
160 AP_IMPLEMENT_HOOK_RUN_ALL(int, open_logs,
161 (apr_pool_t *pconf, apr_pool_t *plog,
162 apr_pool_t *ptemp, server_rec *s),
163 (pconf, plog, ptemp, s), OK, DECLINED)
164
165 AP_IMPLEMENT_HOOK_VOID(child_init,
166 (apr_pool_t *pchild, server_rec *s),
167 (pchild, s))
168
169 AP_IMPLEMENT_HOOK_RUN_FIRST(int, handler, (request_rec *r),
170 (r), DECLINED)
171
172 AP_IMPLEMENT_HOOK_RUN_FIRST(int, quick_handler, (request_rec *r, int lookup),
173 (r, lookup), DECLINED)
174
175 AP_IMPLEMENT_HOOK_RUN_FIRST(apr_status_t, open_htaccess,
176 (request_rec *r, const char *dir_name, const char *access_name,
177 ap_configfile_t **conffile, const char **full_name),
178 (r, dir_name, access_name, conffile, full_name),
179 AP_DECLINED)
180
181 /* hooks with no args are implemented last, after disabling APR hook probes */
182 #if defined(APR_HOOK_PROBES_ENABLED)
183 #undef APR_HOOK_PROBES_ENABLED
184 #undef APR_HOOK_PROBE_ENTRY
185 #define APR_HOOK_PROBE_ENTRY(ud,ns,name,args)
186 #undef APR_HOOK_PROBE_RETURN
187 #define APR_HOOK_PROBE_RETURN(ud,ns,name,rv,args)
188 #undef APR_HOOK_PROBE_INVOKE
189 #define APR_HOOK_PROBE_INVOKE(ud,ns,name,src,args)
190 #undef APR_HOOK_PROBE_COMPLETE
191 #define APR_HOOK_PROBE_COMPLETE(ud,ns,name,src,rv,args)
192 #undef APR_HOOK_INT_DCL_UD
193 #define APR_HOOK_INT_DCL_UD
194 #endif
195 AP_IMPLEMENT_HOOK_VOID(optional_fn_retrieve, (void), ())
196
197 /****************************************************************
198 *
199 * We begin with the functions which deal with the linked list
200 * of modules which control just about all of the server operation.
201 */
202
203 /* total_modules is the number of modules that have been linked
204 * into the server.
205 */
206 static int total_modules = 0;
207
208 /* dynamic_modules is the number of modules that have been added
209 * after the pre-loaded ones have been set up. It shouldn't be larger
210 * than DYNAMIC_MODULE_LIMIT.
211 */
212 static int dynamic_modules = 0;
213
214 /* The maximum possible value for total_modules, i.e. number of static
215 * modules plus DYNAMIC_MODULE_LIMIT.
216 */
217 static int max_modules = 0;
218
219 /* The number of elements we need to alloc for config vectors. Before loading
220 * of dynamic modules, we must be liberal and set this to max_modules. After
221 * loading of dynamic modules, we can trim it down to total_modules. On
222 * restart, reset to max_modules.
223 */
224 static int conf_vector_length = 0;
225
226 static int reserved_module_slots = 0;
227
228 AP_DECLARE_DATA module *ap_top_module = NULL;
229 AP_DECLARE_DATA module **ap_loaded_modules=NULL;
230
231 static apr_hash_t *ap_config_hash = NULL;
232
233 /* a list of the module symbol names with the trailing "_module"removed */
234 static char **ap_module_short_names = NULL;
235
236 typedef int (*handler_func)(request_rec *);
237 typedef void *(*dir_maker_func)(apr_pool_t *, char *);
238 typedef void *(*merger_func)(apr_pool_t *, void *, void *);
239
240 /* A list of the merge_dir_config functions of all loaded modules, sorted
241 * by module_index.
242 * Using this list in ap_merge_per_dir_configs() is faster than following
243 * the module->next linked list because of better memory locality (resulting
244 * in better cache usage).
245 */
246 static merger_func *merger_func_cache;
247
248 /* maximum nesting level for config directories */
249 #ifndef AP_MAX_INCLUDE_DIR_DEPTH
250 #define AP_MAX_INCLUDE_DIR_DEPTH (128)
251 #endif
252
253 /* Dealing with config vectors. These are associated with per-directory,
254 * per-server, and per-request configuration, and have a void* pointer for
255 * each modules. The nature of the structure pointed to is private to the
256 * module in question... the core doesn't (and can't) know. However, there
257 * are defined interfaces which allow it to create instances of its private
258 * per-directory and per-server structures, and to merge the per-directory
259 * structures of a directory and its subdirectory (producing a new one in
260 * which the defaults applying to the base directory have been properly
261 * overridden).
262 */
263
create_empty_config(apr_pool_t * p)264 static ap_conf_vector_t *create_empty_config(apr_pool_t *p)
265 {
266 void *conf_vector = apr_pcalloc(p, sizeof(void *) * conf_vector_length);
267 return conf_vector;
268 }
269
create_default_per_dir_config(apr_pool_t * p)270 static ap_conf_vector_t *create_default_per_dir_config(apr_pool_t *p)
271 {
272 void **conf_vector = apr_pcalloc(p, sizeof(void *) * conf_vector_length);
273 module *modp;
274
275 for (modp = ap_top_module; modp; modp = modp->next) {
276 dir_maker_func df = modp->create_dir_config;
277
278 if (df)
279 conf_vector[modp->module_index] = (*df)(p, NULL);
280 }
281
282 return (ap_conf_vector_t *)conf_vector;
283 }
284
ap_merge_per_dir_configs(apr_pool_t * p,ap_conf_vector_t * base,ap_conf_vector_t * new_conf)285 AP_CORE_DECLARE(ap_conf_vector_t *) ap_merge_per_dir_configs(apr_pool_t *p,
286 ap_conf_vector_t *base,
287 ap_conf_vector_t *new_conf)
288 {
289 void **conf_vector = apr_palloc(p, sizeof(void *) * conf_vector_length);
290 void **base_vector = (void **)base;
291 void **new_vector = (void **)new_conf;
292 int i;
293
294 for (i = 0; i < total_modules; i++) {
295 if (!new_vector[i]) {
296 conf_vector[i] = base_vector[i];
297 }
298 else {
299 const merger_func df = merger_func_cache[i];
300 if (df && base_vector[i]) {
301 conf_vector[i] = (*df)(p, base_vector[i], new_vector[i]);
302 }
303 else
304 conf_vector[i] = new_vector[i];
305 }
306 }
307
308 return (ap_conf_vector_t *)conf_vector;
309 }
310
create_server_config(apr_pool_t * p,server_rec * s)311 static ap_conf_vector_t *create_server_config(apr_pool_t *p, server_rec *s)
312 {
313 void **conf_vector = apr_pcalloc(p, sizeof(void *) * conf_vector_length);
314 module *modp;
315
316 for (modp = ap_top_module; modp; modp = modp->next) {
317 if (modp->create_server_config)
318 conf_vector[modp->module_index] = (*modp->create_server_config)(p, s);
319 }
320
321 return (ap_conf_vector_t *)conf_vector;
322 }
323
merge_server_configs(apr_pool_t * p,ap_conf_vector_t * base,server_rec * virt)324 static void merge_server_configs(apr_pool_t *p, ap_conf_vector_t *base,
325 server_rec *virt)
326 {
327 /* Can reuse the 'virt' vector for the spine of it, since we don't
328 * have to deal with the moral equivalent of .htaccess files here...
329 */
330
331 void **base_vector = (void **)base;
332 void **virt_vector = (void **)virt->module_config;
333 module *modp;
334
335 for (modp = ap_top_module; modp; modp = modp->next) {
336 merger_func df = modp->merge_server_config;
337 int i = modp->module_index;
338
339 if (!virt_vector[i]) {
340 if (df && modp->create_server_config
341 && (ap_get_module_flags(modp) &
342 AP_MODULE_FLAG_ALWAYS_MERGE)) {
343 virt_vector[i] = (*modp->create_server_config)(p, virt);
344 }
345 else {
346 virt_vector[i] = base_vector[i];
347 df = NULL;
348 }
349 }
350 if (df) {
351 virt_vector[i] = (*df)(p, base_vector[i], virt_vector[i]);
352 }
353 }
354 }
355
ap_create_request_config(apr_pool_t * p)356 AP_CORE_DECLARE(ap_conf_vector_t *) ap_create_request_config(apr_pool_t *p)
357 {
358 return create_empty_config(p);
359 }
360
ap_create_conn_config(apr_pool_t * p)361 AP_CORE_DECLARE(ap_conf_vector_t *) ap_create_conn_config(apr_pool_t *p)
362 {
363 return create_empty_config(p);
364 }
365
ap_create_per_dir_config(apr_pool_t * p)366 AP_CORE_DECLARE(ap_conf_vector_t *) ap_create_per_dir_config(apr_pool_t *p)
367 {
368 return create_empty_config(p);
369 }
370
371 /* Invoke the filter_init_func for all filters with FILTERS where f->r
372 * matches R. Restricting to a matching R avoids re-running init
373 * functions for filters configured for r->main where r is a
374 * subrequest. */
invoke_filter_init(request_rec * r,ap_filter_t * filters)375 static int invoke_filter_init(request_rec *r, ap_filter_t *filters)
376 {
377 while (filters) {
378 if (filters->frec->filter_init_func && filters->r == r) {
379 int result = filters->frec->filter_init_func(filters);
380 if (result != OK) {
381 return result;
382 }
383 }
384 filters = filters->next;
385 }
386 return OK;
387 }
388
ap_invoke_handler(request_rec * r)389 AP_CORE_DECLARE(int) ap_invoke_handler(request_rec *r)
390 {
391 const char *handler;
392 const char *p;
393 int result;
394 const char *old_handler = r->handler;
395 const char *ignore;
396
397 /*
398 * The new insert_filter stage makes the most sense here. We only use
399 * it when we are going to run the request, so we must insert filters
400 * if any are available. Since the goal of this phase is to allow all
401 * modules to insert a filter if they want to, this filter returns
402 * void. I just can't see any way that this filter can reasonably
403 * fail, either your modules inserts something or it doesn't. rbb
404 */
405 ap_run_insert_filter(r);
406
407 /* Before continuing, allow each filter that is in the two chains to
408 * run their init function to let them do any magic before we could
409 * start generating data.
410 */
411 result = invoke_filter_init(r, r->input_filters);
412 if (result != OK) {
413 return result;
414 }
415 result = invoke_filter_init(r, r->output_filters);
416 if (result != OK) {
417 return result;
418 }
419
420 if (!r->handler) {
421 if (r->content_type) {
422 handler = r->content_type;
423 if ((p=ap_strchr_c(handler, ';')) != NULL) {
424 char *new_handler = (char *)apr_pmemdup(r->pool, handler,
425 p - handler + 1);
426 char *p2 = new_handler + (p - handler);
427 handler = new_handler;
428
429 /* exclude media type arguments */
430 while (p2 > handler && p2[-1] == ' ')
431 --p2; /* strip trailing spaces */
432
433 *p2='\0';
434 }
435 }
436 else {
437 handler = AP_DEFAULT_HANDLER_NAME;
438 }
439
440 r->handler = handler;
441 }
442
443 result = ap_run_handler(r);
444
445 r->handler = old_handler;
446
447 if (result == DECLINED && r->handler && r->filename) {
448 ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(00523)
449 "handler \"%s\" not found for: %s", r->handler, r->filename);
450 }
451 if ((result != OK) && (result != DONE) && (result != DECLINED) && (result != SUSPENDED)
452 && (result != AP_FILTER_ERROR) /* ap_die() knows about this specifically */
453 && !ap_is_HTTP_VALID_RESPONSE(result)) {
454 /* If a module is deliberately returning something else
455 * (request_rec in non-HTTP or proprietary extension?)
456 * let it set a note to allow it explicitly.
457 * Otherwise, a return code that is neither reserved nor HTTP
458 * is a bug, as in PR#31759.
459 */
460 ignore = apr_table_get(r->notes, "HTTP_IGNORE_RANGE");
461 if (!ignore) {
462 ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(00524)
463 "Handler for %s returned invalid result code %d",
464 r->handler, result);
465 result = HTTP_INTERNAL_SERVER_ERROR;
466 }
467 }
468
469 return result == DECLINED ? HTTP_INTERNAL_SERVER_ERROR : result;
470 }
471
ap_method_is_limited(cmd_parms * cmd,const char * method)472 AP_DECLARE(int) ap_method_is_limited(cmd_parms *cmd, const char *method)
473 {
474 int methnum;
475
476 methnum = ap_method_number_of(method);
477
478 /*
479 * A method number either hardcoded into apache or
480 * added by a module and registered.
481 */
482 if (methnum != M_INVALID) {
483 return (cmd->limited & (AP_METHOD_BIT << methnum)) ? 1 : 0;
484 }
485
486 return 0; /* not found */
487 }
488
ap_register_hooks(module * m,apr_pool_t * p)489 AP_DECLARE(void) ap_register_hooks(module *m, apr_pool_t *p)
490 {
491 if (m->register_hooks) {
492 if (getenv("SHOW_HOOKS")) {
493 printf("Registering hooks for %s\n", m->name);
494 apr_hook_debug_enabled = 1;
495 }
496
497 apr_hook_debug_current = m->name;
498 m->register_hooks(p);
499 }
500 }
501
502 static void ap_add_module_commands(module *m, apr_pool_t *p);
503
504 typedef struct ap_mod_list_struct ap_mod_list;
505 struct ap_mod_list_struct {
506 struct ap_mod_list_struct *next;
507 module *m;
508 const command_rec *cmd;
509 };
510
rebuild_conf_hash(apr_pool_t * p,int add_prelinked)511 static void rebuild_conf_hash(apr_pool_t *p, int add_prelinked)
512 {
513 module **m;
514
515 ap_config_hash = apr_hash_make(p);
516
517 apr_pool_cleanup_register(p, &ap_config_hash, ap_pool_cleanup_set_null,
518 apr_pool_cleanup_null);
519 if (add_prelinked) {
520 for (m = ap_prelinked_modules; *m != NULL; m++) {
521 ap_add_module_commands(*m, p);
522 }
523 }
524 }
525
ap_add_module_commands(module * m,apr_pool_t * p)526 static void ap_add_module_commands(module *m, apr_pool_t *p)
527 {
528 apr_pool_t *tpool;
529 ap_mod_list *mln;
530 const command_rec *cmd;
531 char *dir;
532
533 cmd = m->cmds;
534
535 if (ap_config_hash == NULL) {
536 rebuild_conf_hash(p, 0);
537 }
538
539 tpool = apr_hash_pool_get(ap_config_hash);
540
541 while (cmd && cmd->name) {
542 mln = apr_palloc(tpool, sizeof(ap_mod_list));
543 mln->cmd = cmd;
544 mln->m = m;
545 dir = apr_pstrdup(tpool, cmd->name);
546
547 ap_str_tolower(dir);
548
549 mln->next = apr_hash_get(ap_config_hash, dir, APR_HASH_KEY_STRING);
550 apr_hash_set(ap_config_hash, dir, APR_HASH_KEY_STRING, mln);
551 ++cmd;
552 }
553 }
554
555
556 /* One-time setup for precompiled modules --- NOT to be done on restart */
557
ap_add_module(module * m,apr_pool_t * p,const char * sym_name)558 AP_DECLARE(const char *) ap_add_module(module *m, apr_pool_t *p,
559 const char *sym_name)
560 {
561 ap_module_symbol_t *sym = ap_prelinked_module_symbols;
562
563 /* This could be called from a LoadModule httpd.conf command,
564 * after the file has been linked and the module structure within it
565 * teased out...
566 */
567
568 if (m->version != MODULE_MAGIC_NUMBER_MAJOR) {
569 return apr_psprintf(p, "Module \"%s\" is not compatible with this "
570 "version of Apache (found %d, need %d). Please "
571 "contact the vendor for the correct version.",
572 m->name, m->version, MODULE_MAGIC_NUMBER_MAJOR);
573 }
574
575 if (m->module_index == -1) {
576 if (dynamic_modules >= DYNAMIC_MODULE_LIMIT) {
577 return apr_psprintf(p, "Module \"%s\" could not be loaded, "
578 "because the dynamic module limit was "
579 "reached. Please increase "
580 "DYNAMIC_MODULE_LIMIT and recompile.", m->name);
581 }
582 /*
583 * If this fails some module forgot to call ap_reserve_module_slots*.
584 */
585 ap_assert(total_modules < conf_vector_length);
586
587 m->module_index = total_modules++;
588 dynamic_modules++;
589
590 }
591 else if (!sym_name) {
592 while (sym->modp != NULL) {
593 if (sym->modp == m) {
594 sym_name = sym->name;
595 break;
596 }
597 sym++;
598 }
599 }
600
601 if (m->next == NULL) {
602 m->next = ap_top_module;
603 ap_top_module = m;
604 }
605
606 if (sym_name) {
607 int len = strlen(sym_name);
608 int slen = strlen("_module");
609 if (len > slen && !strcmp(sym_name + len - slen, "_module")) {
610 len -= slen;
611 }
612
613 ap_module_short_names[m->module_index] = ap_malloc(len + 1);
614 memcpy(ap_module_short_names[m->module_index], sym_name, len);
615 ap_module_short_names[m->module_index][len] = '\0';
616 merger_func_cache[m->module_index] = m->merge_dir_config;
617 }
618
619
620 /* Some C compilers put a complete path into __FILE__, but we want
621 * only the filename (e.g. mod_includes.c). So check for path
622 * components (Unix and DOS), and remove them.
623 */
624
625 if (ap_strrchr_c(m->name, '/'))
626 m->name = 1 + ap_strrchr_c(m->name, '/');
627
628 if (ap_strrchr_c(m->name, '\\'))
629 m->name = 1 + ap_strrchr_c(m->name, '\\');
630
631 #ifdef _OSD_POSIX
632 /* __FILE__ =
633 * "*POSIX(/home/martin/apache/src/modules/standard/mod_info.c)"
634 */
635
636 /* We cannot fix the string in-place, because it's const */
637 if (m->name[strlen(m->name)-1] == ')') {
638 char *tmp = ap_malloc(strlen(m->name)); /* FIXME: memory leak, albeit a small one */
639 memcpy(tmp, m->name, strlen(m->name)-1);
640 tmp[strlen(m->name)-1] = '\0';
641 m->name = tmp;
642 }
643 #endif /*_OSD_POSIX*/
644
645 ap_add_module_commands(m, p);
646 /* FIXME: is this the right place to call this?
647 * It doesn't appear to be
648 */
649 ap_register_hooks(m, p);
650
651 return NULL;
652 }
653
654 /*
655 * remove_module undoes what add_module did. There are some caveats:
656 * when the module is removed, its slot is lost so all the current
657 * per-dir and per-server configurations are invalid. So we should
658 * only ever call this function when you are invalidating almost
659 * all our current data. I.e. when doing a restart.
660 */
661
ap_remove_module(module * m)662 AP_DECLARE(void) ap_remove_module(module *m)
663 {
664 module *modp;
665
666 modp = ap_top_module;
667 if (modp == m) {
668 /* We are the top module, special case */
669 ap_top_module = modp->next;
670 m->next = NULL;
671 }
672 else {
673 /* Not the top module, find use. When found modp will
674 * point to the module _before_ us in the list
675 */
676
677 while (modp && modp->next != m) {
678 modp = modp->next;
679 }
680
681 if (!modp) {
682 /* Uh-oh, this module doesn't exist */
683 ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL, APLOGNO(00525)
684 "Cannot remove module %s: not found in module list",
685 m->name);
686 return;
687 }
688
689 /* Eliminate us from the module list */
690 modp->next = modp->next->next;
691 }
692
693 free(ap_module_short_names[m->module_index]);
694 ap_module_short_names[m->module_index] = NULL;
695 merger_func_cache[m->module_index] = NULL;
696
697 m->module_index = -1; /* simulate being unloaded, should
698 * be unnecessary */
699 dynamic_modules--;
700 total_modules--;
701 }
702
ap_add_loaded_module(module * mod,apr_pool_t * p,const char * short_name)703 AP_DECLARE(const char *) ap_add_loaded_module(module *mod, apr_pool_t *p,
704 const char *short_name)
705 {
706 module **m;
707 const char *error;
708
709 /*
710 * Add module pointer to top of chained module list
711 */
712 error = ap_add_module(mod, p, short_name);
713 if (error) {
714 return error;
715 }
716
717 /*
718 * And module pointer to list of loaded modules
719 *
720 * Notes: 1. ap_add_module() would already complain if no more space
721 * exists for adding a dynamically loaded module
722 * 2. ap_add_module() accepts double inclusion, so we have
723 * to accept this, too.
724 */
725 for (m = ap_loaded_modules; *m != NULL; m++)
726 ;
727 *m++ = mod;
728 *m = NULL;
729
730 return NULL;
731 }
732
ap_remove_loaded_module(module * mod)733 AP_DECLARE(void) ap_remove_loaded_module(module *mod)
734 {
735 module **m;
736 module **m2;
737 int done;
738
739 /*
740 * Remove module pointer from chained module list
741 */
742 ap_remove_module(mod);
743
744 /*
745 * Remove module pointer from list of loaded modules
746 *
747 * Note: 1. We cannot determine if the module was successfully
748 * removed by ap_remove_module().
749 * 2. We have not to complain explicitly when the module
750 * is not found because ap_remove_module() did it
751 * for us already.
752 */
753 for (m = m2 = ap_loaded_modules, done = 0; *m2 != NULL; m2++) {
754 if (*m2 == mod && done == 0)
755 done = 1;
756 else
757 *m++ = *m2;
758 }
759
760 *m = NULL;
761 }
762
ap_setup_prelinked_modules(process_rec * process)763 AP_DECLARE(const char *) ap_setup_prelinked_modules(process_rec *process)
764 {
765 module **m;
766 module **m2;
767 const char *error;
768
769 apr_hook_global_pool=process->pconf;
770
771 rebuild_conf_hash(process->pconf, 0);
772
773 /*
774 * Initialise total_modules variable and module indices
775 */
776 total_modules = 0;
777 for (m = ap_preloaded_modules; *m != NULL; m++)
778 (*m)->module_index = total_modules++;
779
780 max_modules = total_modules + DYNAMIC_MODULE_LIMIT + 1;
781 conf_vector_length = max_modules;
782
783 /*
784 * Initialise list of loaded modules and short names
785 */
786 ap_loaded_modules = (module **)apr_palloc(process->pool,
787 sizeof(module *) * conf_vector_length);
788 if (!ap_module_short_names)
789 ap_module_short_names = ap_calloc(sizeof(char *), conf_vector_length);
790
791 if (!merger_func_cache)
792 merger_func_cache = ap_calloc(sizeof(merger_func), conf_vector_length);
793
794 if (ap_loaded_modules == NULL || ap_module_short_names == NULL
795 || merger_func_cache == NULL)
796 return "Ouch! Out of memory in ap_setup_prelinked_modules()!";
797
798 for (m = ap_preloaded_modules, m2 = ap_loaded_modules; *m != NULL; )
799 *m2++ = *m++;
800
801 *m2 = NULL;
802
803 /*
804 * Initialize chain of linked (=activate) modules
805 */
806 for (m = ap_prelinked_modules; *m != NULL; m++) {
807 error = ap_add_module(*m, process->pconf, NULL);
808 if (error) {
809 return error;
810 }
811 }
812
813 apr_hook_sort_all();
814
815 return NULL;
816 }
817
ap_find_module_name(module * m)818 AP_DECLARE(const char *) ap_find_module_name(module *m)
819 {
820 return m->name;
821 }
822
ap_find_module_short_name(int module_index)823 AP_DECLARE(const char *) ap_find_module_short_name(int module_index)
824 {
825 if (module_index < 0 || module_index >= conf_vector_length)
826 return NULL;
827 return ap_module_short_names[module_index];
828 }
829
ap_find_linked_module(const char * name)830 AP_DECLARE(module *) ap_find_linked_module(const char *name)
831 {
832 module *modp;
833
834 for (modp = ap_top_module; modp; modp = modp->next) {
835 if (strcmp(modp->name, name) == 0)
836 return modp;
837 }
838
839 return NULL;
840 }
841
842 /*****************************************************************
843 *
844 * Resource, access, and .htaccess config files now parsed by a common
845 * command loop.
846 *
847 * Let's begin with the basics; parsing the line and
848 * invoking the function...
849 */
850
851 #define AP_MAX_ARGC 64
852
invoke_cmd(const command_rec * cmd,cmd_parms * parms,void * mconfig,const char * args)853 static const char *invoke_cmd(const command_rec *cmd, cmd_parms *parms,
854 void *mconfig, const char *args)
855 {
856 int override_list_ok = 0;
857 char *w, *w2, *w3;
858 const char *errmsg = NULL;
859
860 /* Have we been provided a list of acceptable directives? */
861 if (parms->override_list != NULL) {
862 if (apr_table_get(parms->override_list, cmd->name) != NULL) {
863 override_list_ok = 1;
864 }
865 }
866
867 if ((parms->override & cmd->req_override) == 0 && !override_list_ok) {
868 if (parms->override & NONFATAL_OVERRIDE) {
869 ap_log_perror(APLOG_MARK, APLOG_WARNING, 0, parms->temp_pool,
870 APLOGNO(02295)
871 "%s in .htaccess forbidden by AllowOverride",
872 cmd->name);
873 return NULL;
874 }
875 else if (parms->directive && parms->directive->parent) {
876 return apr_pstrcat(parms->pool, cmd->name, " not allowed in ",
877 parms->directive->parent->directive, ">",
878 " context", NULL);
879 }
880 else {
881 return apr_pstrcat(parms->pool, cmd->name,
882 " not allowed here", NULL);
883 }
884 }
885
886 parms->info = cmd->cmd_data;
887 parms->cmd = cmd;
888
889 switch (cmd->args_how) {
890 case RAW_ARGS:
891 #ifdef RESOLVE_ENV_PER_TOKEN
892 args = ap_resolve_env(parms->pool,args);
893 #endif
894 return cmd->AP_RAW_ARGS(parms, mconfig, args);
895
896 case TAKE_ARGV:
897 {
898 char *argv[AP_MAX_ARGC];
899 int argc = 0;
900
901 do {
902 w = ap_getword_conf(parms->pool, &args);
903 if (*w == '\0' && *args == '\0') {
904 break;
905 }
906 argv[argc] = w;
907 argc++;
908 } while (argc < AP_MAX_ARGC && *args != '\0');
909
910 return cmd->AP_TAKE_ARGV(parms, mconfig, argc, argv);
911 }
912
913 case NO_ARGS:
914 if (*args != 0)
915 return apr_pstrcat(parms->pool, cmd->name, " takes no arguments",
916 NULL);
917
918 return cmd->AP_NO_ARGS(parms, mconfig);
919
920 case TAKE1:
921 w = ap_getword_conf(parms->pool, &args);
922
923 if (*w == '\0' || *args != 0)
924 return apr_pstrcat(parms->pool, cmd->name, " takes one argument",
925 cmd->errmsg ? ", " : NULL, cmd->errmsg, NULL);
926
927 return cmd->AP_TAKE1(parms, mconfig, w);
928
929 case TAKE2:
930 w = ap_getword_conf(parms->pool, &args);
931 w2 = ap_getword_conf(parms->pool, &args);
932
933 if (*w == '\0' || *w2 == '\0' || *args != 0)
934 return apr_pstrcat(parms->pool, cmd->name, " takes two arguments",
935 cmd->errmsg ? ", " : NULL, cmd->errmsg, NULL);
936
937 return cmd->AP_TAKE2(parms, mconfig, w, w2);
938
939 case TAKE12:
940 w = ap_getword_conf(parms->pool, &args);
941 w2 = ap_getword_conf(parms->pool, &args);
942
943 if (*w == '\0' || *args != 0)
944 return apr_pstrcat(parms->pool, cmd->name, " takes 1-2 arguments",
945 cmd->errmsg ? ", " : NULL, cmd->errmsg, NULL);
946
947 return cmd->AP_TAKE2(parms, mconfig, w, *w2 ? w2 : NULL);
948
949 case TAKE3:
950 w = ap_getword_conf(parms->pool, &args);
951 w2 = ap_getword_conf(parms->pool, &args);
952 w3 = ap_getword_conf(parms->pool, &args);
953
954 if (*w == '\0' || *w2 == '\0' || *w3 == '\0' || *args != 0)
955 return apr_pstrcat(parms->pool, cmd->name, " takes three arguments",
956 cmd->errmsg ? ", " : NULL, cmd->errmsg, NULL);
957
958 return cmd->AP_TAKE3(parms, mconfig, w, w2, w3);
959
960 case TAKE23:
961 w = ap_getword_conf(parms->pool, &args);
962 w2 = ap_getword_conf(parms->pool, &args);
963 w3 = *args ? ap_getword_conf(parms->pool, &args) : NULL;
964
965 if (*w == '\0' || *w2 == '\0' || *args != 0)
966 return apr_pstrcat(parms->pool, cmd->name,
967 " takes two or three arguments",
968 cmd->errmsg ? ", " : NULL, cmd->errmsg, NULL);
969
970 return cmd->AP_TAKE3(parms, mconfig, w, w2, w3);
971
972 case TAKE123:
973 w = ap_getword_conf(parms->pool, &args);
974 w2 = *args ? ap_getword_conf(parms->pool, &args) : NULL;
975 w3 = *args ? ap_getword_conf(parms->pool, &args) : NULL;
976
977 if (*w == '\0' || *args != 0)
978 return apr_pstrcat(parms->pool, cmd->name,
979 " takes one, two or three arguments",
980 cmd->errmsg ? ", " : NULL, cmd->errmsg, NULL);
981
982 return cmd->AP_TAKE3(parms, mconfig, w, w2, w3);
983
984 case TAKE13:
985 w = ap_getword_conf(parms->pool, &args);
986 w2 = *args ? ap_getword_conf(parms->pool, &args) : NULL;
987 w3 = *args ? ap_getword_conf(parms->pool, &args) : NULL;
988
989 if (*w == '\0' || (w2 && *w2 && !w3) || *args != 0)
990 return apr_pstrcat(parms->pool, cmd->name,
991 " takes one or three arguments",
992 cmd->errmsg ? ", " : NULL, cmd->errmsg, NULL);
993
994 return cmd->AP_TAKE3(parms, mconfig, w, w2, w3);
995
996 case ITERATE:
997 w = ap_getword_conf(parms->pool, &args);
998
999 if (*w == '\0')
1000 return apr_pstrcat(parms->pool, cmd->name,
1001 " requires at least one argument",
1002 cmd->errmsg ? ", " : NULL, cmd->errmsg, NULL);
1003
1004 while (*w != '\0') {
1005 errmsg = cmd->AP_TAKE1(parms, mconfig, w);
1006
1007 if (errmsg && strcmp(errmsg, DECLINE_CMD) != 0)
1008 return errmsg;
1009
1010 w = ap_getword_conf(parms->pool, &args);
1011 }
1012
1013 return errmsg;
1014
1015 case ITERATE2:
1016 w = ap_getword_conf(parms->pool, &args);
1017
1018 if (*w == '\0' || *args == 0)
1019 return apr_pstrcat(parms->pool, cmd->name,
1020 " requires at least two arguments",
1021 cmd->errmsg ? ", " : NULL, cmd->errmsg, NULL);
1022
1023 while (*(w2 = ap_getword_conf(parms->pool, &args)) != '\0') {
1024
1025 errmsg = cmd->AP_TAKE2(parms, mconfig, w, w2);
1026
1027 if (errmsg && strcmp(errmsg, DECLINE_CMD) != 0)
1028 return errmsg;
1029 }
1030
1031 return errmsg;
1032
1033 case FLAG:
1034 /*
1035 * This is safe to use temp_pool here, because the 'flag' itself is not
1036 * forwarded as-is
1037 */
1038 w = ap_getword_conf(parms->temp_pool, &args);
1039
1040 if (*w == '\0' || (ap_cstr_casecmp(w, "on") && ap_cstr_casecmp(w, "off")))
1041 return apr_pstrcat(parms->pool, cmd->name, " must be On or Off",
1042 NULL);
1043
1044 return cmd->AP_FLAG(parms, mconfig, ap_cstr_casecmp(w, "off") != 0);
1045
1046 default:
1047 return apr_pstrcat(parms->pool, cmd->name,
1048 " is improperly configured internally (server bug)",
1049 NULL);
1050 }
1051 }
1052
ap_find_command(const char * name,const command_rec * cmds)1053 AP_CORE_DECLARE(const command_rec *) ap_find_command(const char *name,
1054 const command_rec *cmds)
1055 {
1056 while (cmds->name) {
1057 if (!ap_cstr_casecmp(name, cmds->name))
1058 return cmds;
1059
1060 ++cmds;
1061 }
1062
1063 return NULL;
1064 }
1065
ap_find_command_in_modules(const char * cmd_name,module ** mod)1066 AP_CORE_DECLARE(const command_rec *) ap_find_command_in_modules(
1067 const char *cmd_name, module **mod)
1068 {
1069 const command_rec *cmdp;
1070 module *modp;
1071
1072 for (modp = *mod; modp; modp = modp->next) {
1073 if (modp->cmds && (cmdp = ap_find_command(cmd_name, modp->cmds))) {
1074 *mod = modp;
1075 return cmdp;
1076 }
1077 }
1078
1079 return NULL;
1080 }
1081
ap_set_config_vectors(server_rec * server,ap_conf_vector_t * section_vector,const char * section,module * mod,apr_pool_t * pconf)1082 AP_CORE_DECLARE(void *) ap_set_config_vectors(server_rec *server,
1083 ap_conf_vector_t *section_vector,
1084 const char *section,
1085 module *mod, apr_pool_t *pconf)
1086 {
1087 void *section_config = ap_get_module_config(section_vector, mod);
1088 void *server_config = ap_get_module_config(server->module_config, mod);
1089
1090 if (!section_config && mod->create_dir_config) {
1091 /* ### need to fix the create_dir_config functions' prototype... */
1092 section_config = (*mod->create_dir_config)(pconf, (char *)section);
1093 ap_set_module_config(section_vector, mod, section_config);
1094 }
1095
1096 if (!server_config && mod->create_server_config) {
1097 server_config = (*mod->create_server_config)(pconf, server);
1098 ap_set_module_config(server->module_config, mod, server_config);
1099 }
1100
1101 return section_config;
1102 }
1103
1104 static const char *execute_now(char *cmd_line, const char *args,
1105 cmd_parms *parms,
1106 apr_pool_t *p, apr_pool_t *ptemp,
1107 ap_directive_t **sub_tree,
1108 ap_directive_t *parent);
1109
ap_build_config_sub(apr_pool_t * p,apr_pool_t * temp_pool,const char * l,cmd_parms * parms,ap_directive_t ** current,ap_directive_t ** curr_parent,ap_directive_t ** conftree)1110 static const char *ap_build_config_sub(apr_pool_t *p, apr_pool_t *temp_pool,
1111 const char *l, cmd_parms *parms,
1112 ap_directive_t **current,
1113 ap_directive_t **curr_parent,
1114 ap_directive_t **conftree)
1115 {
1116 const char *retval = NULL;
1117 const char *args;
1118 char *cmd_name;
1119 ap_directive_t *newdir;
1120 const command_rec *cmd;
1121 ap_mod_list *ml;
1122 char *lname;
1123
1124 if (*l == '#' || *l == '\0')
1125 return NULL;
1126
1127 #if RESOLVE_ENV_PER_TOKEN
1128 args = l;
1129 #else
1130 args = ap_resolve_env(temp_pool, l);
1131 #endif
1132
1133 /* The first word is the name of a directive. We can safely use the
1134 * 'temp_pool' for it. If it matches the name of a known directive, we
1135 * can reference the string within the module if needed. Otherwise, we
1136 * can still make a copy in the 'p' pool. */
1137 cmd_name = ap_getword_conf(temp_pool, &args);
1138 if (*cmd_name == '\0') {
1139 /* Note: this branch should not occur. An empty line should have
1140 * triggered the exit further above.
1141 */
1142 return NULL;
1143 }
1144
1145 if (cmd_name[1] != '/') {
1146 char *lastc = cmd_name + strlen(cmd_name) - 1;
1147 if (*lastc == '>') {
1148 *lastc = '\0' ;
1149 }
1150 if (cmd_name[0] == '<' && *args == '\0') {
1151 args = ">";
1152 }
1153 }
1154
1155 newdir = apr_pcalloc(p, sizeof(ap_directive_t));
1156 newdir->filename = parms->config_file->name;
1157 newdir->line_num = parms->config_file->line_number;
1158 newdir->args = apr_pstrdup(p, args);
1159
1160 lname = apr_pstrdup(temp_pool, cmd_name);
1161 ap_str_tolower(lname);
1162 ml = apr_hash_get(ap_config_hash, lname, APR_HASH_KEY_STRING);
1163
1164 if (ml && (cmd = ml->cmd) != NULL) {
1165 newdir->directive = cmd->name;
1166 if (cmd->req_override & EXEC_ON_READ) {
1167 ap_directive_t *sub_tree = NULL;
1168
1169 parms->err_directive = newdir;
1170 retval = execute_now(cmd_name, args, parms, p, temp_pool,
1171 &sub_tree, *curr_parent);
1172 if (*current) {
1173 (*current)->next = sub_tree;
1174 }
1175 else {
1176 *current = sub_tree;
1177 if (*curr_parent) {
1178 (*curr_parent)->first_child = (*current);
1179 }
1180 if (*current) {
1181 (*current)->parent = (*curr_parent);
1182 }
1183 }
1184 if (*current) {
1185 if (!*conftree) {
1186 /* Before walking *current to the end of the list,
1187 * set the head to *current.
1188 */
1189 *conftree = *current;
1190 }
1191 while ((*current)->next != NULL) {
1192 (*current) = (*current)->next;
1193 (*current)->parent = (*curr_parent);
1194 }
1195 }
1196 return retval;
1197 }
1198 }
1199 else {
1200 /* No known directive found? Make a copy of what we have parsed. */
1201 newdir->directive = apr_pstrdup(p, cmd_name);
1202 }
1203
1204
1205 if (cmd_name[0] == '<') {
1206 if (cmd_name[1] != '/') {
1207 (*current) = ap_add_node(curr_parent, *current, newdir, 1);
1208 }
1209 else if (*curr_parent == NULL) {
1210 parms->err_directive = newdir;
1211 return apr_pstrcat(p, cmd_name,
1212 " without matching <", cmd_name + 2,
1213 " section", NULL);
1214 }
1215 else {
1216 char *bracket = cmd_name + strlen(cmd_name) - 1;
1217
1218 if (*bracket != '>') {
1219 parms->err_directive = newdir;
1220 return apr_pstrcat(p, cmd_name,
1221 "> directive missing closing '>'", NULL);
1222 }
1223
1224 *bracket = '\0';
1225
1226 if (ap_cstr_casecmp(cmd_name + 2,
1227 (*curr_parent)->directive + 1) != 0) {
1228 parms->err_directive = newdir;
1229 return apr_pstrcat(p, "Expected </",
1230 (*curr_parent)->directive + 1, "> but saw ",
1231 cmd_name, ">", NULL);
1232 }
1233
1234 *bracket = '>';
1235
1236 /* done with this section; move up a level */
1237 *current = *curr_parent;
1238 *curr_parent = (*current)->parent;
1239 }
1240 }
1241 else {
1242 *current = ap_add_node(curr_parent, *current, newdir, 0);
1243 }
1244
1245 return retval;
1246 }
1247
1248 #define VARBUF_INIT_LEN 200
1249 #define VARBUF_MAX_LEN (16*1024*1024)
1250
ap_build_cont_config(apr_pool_t * p,apr_pool_t * temp_pool,cmd_parms * parms,ap_directive_t ** current,ap_directive_t ** curr_parent,char * orig_directive)1251 AP_DECLARE(const char *) ap_build_cont_config(apr_pool_t *p,
1252 apr_pool_t *temp_pool,
1253 cmd_parms *parms,
1254 ap_directive_t **current,
1255 ap_directive_t **curr_parent,
1256 char *orig_directive)
1257 {
1258 char *bracket;
1259 const char *retval;
1260 ap_directive_t *sub_tree = NULL;
1261 apr_status_t rc;
1262 struct ap_varbuf vb;
1263 apr_size_t max_len = VARBUF_MAX_LEN;
1264 if (p == temp_pool)
1265 max_len = HUGE_STRING_LEN; /* lower limit for .htaccess */
1266
1267 bracket = apr_pstrcat(temp_pool, orig_directive + 1, ">", NULL);
1268 ap_varbuf_init(temp_pool, &vb, VARBUF_INIT_LEN);
1269
1270 while ((rc = ap_varbuf_cfg_getline(&vb, parms->config_file, max_len))
1271 == APR_SUCCESS) {
1272 if (!memcmp(vb.buf, "</", 2)
1273 && (ap_cstr_casecmp(vb.buf + 2, bracket) == 0)
1274 && (*curr_parent == NULL)) {
1275 break;
1276 }
1277 retval = ap_build_config_sub(p, temp_pool, vb.buf, parms, current,
1278 curr_parent, &sub_tree);
1279 if (retval != NULL)
1280 return retval;
1281
1282 if (sub_tree == NULL) {
1283 sub_tree = *curr_parent;
1284 }
1285
1286 if (sub_tree == NULL) {
1287 sub_tree = *current;
1288 }
1289 }
1290 ap_varbuf_free(&vb);
1291 if (rc != APR_EOF && rc != APR_SUCCESS)
1292 return ap_pcfg_strerror(temp_pool, parms->config_file, rc);
1293
1294 *current = sub_tree;
1295 return NULL;
1296 }
1297
ap_walk_config_sub(const ap_directive_t * current,cmd_parms * parms,ap_conf_vector_t * section_vector)1298 static const char *ap_walk_config_sub(const ap_directive_t *current,
1299 cmd_parms *parms,
1300 ap_conf_vector_t *section_vector)
1301 {
1302 const command_rec *cmd;
1303 ap_mod_list *ml;
1304 char *dir = apr_pstrdup(parms->temp_pool, current->directive);
1305
1306 ap_str_tolower(dir);
1307
1308 ml = apr_hash_get(ap_config_hash, dir, APR_HASH_KEY_STRING);
1309
1310 if (ml == NULL) {
1311 parms->err_directive = current;
1312 if (parms->override & NONFATAL_UNKNOWN) {
1313 ap_log_perror(APLOG_MARK, APLOG_WARNING, 0, parms->temp_pool,
1314 APLOGNO(02296) "Unknown directive %s "
1315 "perhaps misspelled or defined by a module "
1316 "not included in the server configuration", dir);
1317 return NULL;
1318 }
1319 else {
1320 return apr_pstrcat(parms->pool, "Invalid command '",
1321 current->directive,
1322 "', perhaps misspelled or defined by a module "
1323 "not included in the server configuration",
1324 NULL);
1325 }
1326 }
1327
1328 for ( ; ml != NULL; ml = ml->next) {
1329 void *dir_config = ap_set_config_vectors(parms->server,
1330 section_vector,
1331 parms->path,
1332 ml->m,
1333 parms->pool);
1334 const char *retval;
1335 cmd = ml->cmd;
1336
1337 /* Once was enough? */
1338 if (cmd->req_override & EXEC_ON_READ) {
1339 continue;
1340 }
1341
1342 retval = invoke_cmd(cmd, parms, dir_config, current->args);
1343
1344 if (retval != NULL && strcmp(retval, DECLINE_CMD) != 0) {
1345 /* If the directive in error has already been set, don't
1346 * replace it. Otherwise, an error inside a container
1347 * will be reported as occurring on the first line of the
1348 * container.
1349 */
1350 if (!parms->err_directive) {
1351 parms->err_directive = current;
1352 }
1353 return retval;
1354 }
1355 }
1356
1357 return NULL;
1358 }
1359
ap_walk_config(ap_directive_t * current,cmd_parms * parms,ap_conf_vector_t * section_vector)1360 AP_DECLARE(const char *) ap_walk_config(ap_directive_t *current,
1361 cmd_parms *parms,
1362 ap_conf_vector_t *section_vector)
1363 {
1364 ap_conf_vector_t *oldconfig = parms->context;
1365
1366 parms->context = section_vector;
1367
1368 /* scan through all directives, executing each one */
1369 for (; current != NULL; current = current->next) {
1370 const char *errmsg;
1371
1372 parms->directive = current;
1373
1374 /* actually parse the command and execute the correct function */
1375 errmsg = ap_walk_config_sub(current, parms, section_vector);
1376 if (errmsg != NULL) {
1377 /* restore the context (just in case) */
1378 parms->context = oldconfig;
1379 return errmsg;
1380 }
1381 }
1382
1383 parms->context = oldconfig;
1384 return NULL;
1385 }
1386
ap_build_config(cmd_parms * parms,apr_pool_t * p,apr_pool_t * temp_pool,ap_directive_t ** conftree)1387 AP_DECLARE(const char *) ap_build_config(cmd_parms *parms,
1388 apr_pool_t *p, apr_pool_t *temp_pool,
1389 ap_directive_t **conftree)
1390 {
1391 ap_directive_t *current = *conftree;
1392 ap_directive_t *curr_parent = NULL;
1393 const char *errmsg;
1394 ap_directive_t **last_ptr = NULL;
1395 apr_status_t rc;
1396 struct ap_varbuf vb;
1397 apr_size_t max_len = VARBUF_MAX_LEN;
1398 if (p == temp_pool)
1399 max_len = HUGE_STRING_LEN; /* lower limit for .htaccess */
1400
1401 ap_varbuf_init(temp_pool, &vb, VARBUF_INIT_LEN);
1402
1403 if (current != NULL) {
1404 /* If we have to traverse the whole tree again for every included
1405 * config file, the required time grows as O(n^2) with the number of
1406 * files. This can be a significant delay for large configurations.
1407 * Therefore we cache a pointer to the last node.
1408 */
1409 last_ptr = &(current->last);
1410
1411 if (last_ptr && *last_ptr) {
1412 current = *last_ptr;
1413 }
1414
1415 while (current->next) {
1416 current = current->next;
1417 }
1418
1419 if (last_ptr) {
1420 /* update cached pointer to last node */
1421 *last_ptr = current;
1422 }
1423 }
1424
1425 while ((rc = ap_varbuf_cfg_getline(&vb, parms->config_file, max_len))
1426 == APR_SUCCESS) {
1427 errmsg = ap_build_config_sub(p, temp_pool, vb.buf, parms,
1428 ¤t, &curr_parent, conftree);
1429 if (errmsg != NULL)
1430 return errmsg;
1431
1432 if (*conftree == NULL && curr_parent != NULL) {
1433 *conftree = curr_parent;
1434 }
1435
1436 if (*conftree == NULL && current != NULL) {
1437 *conftree = current;
1438 }
1439 }
1440 ap_varbuf_free(&vb);
1441 if (rc != APR_EOF && rc != APR_SUCCESS)
1442 return ap_pcfg_strerror(temp_pool, parms->config_file, rc);
1443
1444 if (curr_parent != NULL) {
1445 errmsg = "";
1446
1447 while (curr_parent != NULL) {
1448 errmsg = apr_psprintf(p, "%s%s%s:%u: %s> was not closed.",
1449 errmsg,
1450 *errmsg == '\0' ? "" : APR_EOL_STR,
1451 curr_parent->filename,
1452 curr_parent->line_num,
1453 curr_parent->directive);
1454
1455 parms->err_directive = curr_parent;
1456 curr_parent = curr_parent->parent;
1457 }
1458
1459 return errmsg;
1460 }
1461
1462 return NULL;
1463 }
1464
1465 /*
1466 * Generic command functions...
1467 */
1468
ap_set_string_slot(cmd_parms * cmd,void * struct_ptr,const char * arg)1469 AP_DECLARE_NONSTD(const char *) ap_set_string_slot(cmd_parms *cmd,
1470 void *struct_ptr,
1471 const char *arg)
1472 {
1473 int offset = (int)(long)cmd->info;
1474
1475 *(const char **)((char *)struct_ptr + offset) = arg;
1476
1477 return NULL;
1478 }
1479
ap_set_int_slot(cmd_parms * cmd,void * struct_ptr,const char * arg)1480 AP_DECLARE_NONSTD(const char *) ap_set_int_slot(cmd_parms *cmd,
1481 void *struct_ptr,
1482 const char *arg)
1483 {
1484 char *endptr;
1485 char *error_str = NULL;
1486 int offset = (int)(long)cmd->info;
1487
1488 *(int *)((char*)struct_ptr + offset) = strtol(arg, &endptr, 10);
1489
1490 if ((*arg == '\0') || (*endptr != '\0')) {
1491 error_str = apr_psprintf(cmd->pool,
1492 "Invalid value for directive %s, expected integer",
1493 cmd->directive->directive);
1494 }
1495
1496 return error_str;
1497 }
1498
ap_set_string_slot_lower(cmd_parms * cmd,void * struct_ptr,const char * arg_)1499 AP_DECLARE_NONSTD(const char *) ap_set_string_slot_lower(cmd_parms *cmd,
1500 void *struct_ptr,
1501 const char *arg_)
1502 {
1503 char *arg = apr_pstrdup(cmd->pool,arg_);
1504 int offset = (int)(long)cmd->info;
1505
1506 ap_str_tolower(arg);
1507 *(char **)((char *)struct_ptr + offset) = arg;
1508
1509 return NULL;
1510 }
1511
ap_set_flag_slot(cmd_parms * cmd,void * struct_ptr_v,int arg)1512 AP_DECLARE_NONSTD(const char *) ap_set_flag_slot(cmd_parms *cmd,
1513 void *struct_ptr_v, int arg)
1514 {
1515 int offset = (int)(long)cmd->info;
1516 char *struct_ptr = (char *)struct_ptr_v;
1517
1518 *(int *)(struct_ptr + offset) = arg ? 1 : 0;
1519
1520 return NULL;
1521 }
1522
ap_set_flag_slot_char(cmd_parms * cmd,void * struct_ptr_v,int arg)1523 AP_DECLARE_NONSTD(const char *) ap_set_flag_slot_char(cmd_parms *cmd,
1524 void *struct_ptr_v, int arg)
1525 {
1526 int offset = (int)(long)cmd->info;
1527 char *struct_ptr = (char *)struct_ptr_v;
1528
1529 *(struct_ptr + offset) = arg ? 1 : 0;
1530
1531 return NULL;
1532 }
1533
1534
ap_set_file_slot(cmd_parms * cmd,void * struct_ptr,const char * arg)1535 AP_DECLARE_NONSTD(const char *) ap_set_file_slot(cmd_parms *cmd, void *struct_ptr,
1536 const char *arg)
1537 {
1538 /* Prepend server_root to relative arg.
1539 * This allows most args to be independent of server_root,
1540 * so the server can be moved or mirrored with less pain.
1541 */
1542 const char *path;
1543 int offset = (int)(long)cmd->info;
1544
1545 path = ap_server_root_relative(cmd->pool, arg);
1546
1547 if (!path) {
1548 return apr_pstrcat(cmd->pool, cmd->cmd->name, ": Invalid file path '",
1549 arg, "'", NULL);
1550 }
1551
1552 *(const char **) ((char*)struct_ptr + offset) = path;
1553
1554 return NULL;
1555 }
1556
ap_set_deprecated(cmd_parms * cmd,void * struct_ptr,const char * arg)1557 AP_DECLARE_NONSTD(const char *) ap_set_deprecated(cmd_parms *cmd,
1558 void *struct_ptr,
1559 const char *arg)
1560 {
1561 return cmd->cmd->errmsg;
1562 }
1563
ap_reset_module_loglevels(struct ap_logconf * l,int val)1564 AP_DECLARE(void) ap_reset_module_loglevels(struct ap_logconf *l, int val)
1565 {
1566 if (l->module_levels)
1567 memset(l->module_levels, val, conf_vector_length);
1568 }
1569
ap_set_module_loglevel(apr_pool_t * pool,struct ap_logconf * l,int index,int level)1570 AP_DECLARE(void) ap_set_module_loglevel(apr_pool_t *pool, struct ap_logconf *l,
1571 int index, int level)
1572 {
1573 if (!l->module_levels) {
1574 l->module_levels = apr_palloc(pool, conf_vector_length);
1575 if (l->level == APLOG_UNSET) {
1576 ap_reset_module_loglevels(l, APLOG_UNSET);
1577 }
1578 else {
1579 ap_reset_module_loglevels(l, APLOG_NO_MODULE);
1580 }
1581 }
1582
1583 l->module_levels[index] = level;
1584 }
1585
1586 /*****************************************************************
1587 *
1588 * Reading whole config files...
1589 */
1590
1591 static cmd_parms default_parms =
1592 {NULL, 0, 0, NULL, -1, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL};
1593
ap_server_root_relative(apr_pool_t * p,const char * file)1594 AP_DECLARE(char *) ap_server_root_relative(apr_pool_t *p, const char *file)
1595 {
1596 char *newpath = NULL;
1597 apr_status_t rv;
1598 rv = apr_filepath_merge(&newpath, ap_server_root, file,
1599 APR_FILEPATH_TRUENAME, p);
1600 if (newpath && (rv == APR_SUCCESS || APR_STATUS_IS_EPATHWILD(rv)
1601 || APR_STATUS_IS_ENOENT(rv)
1602 || APR_STATUS_IS_ENOTDIR(rv))) {
1603 return newpath;
1604 }
1605 else {
1606 return NULL;
1607 }
1608 }
1609
ap_runtime_dir_relative(apr_pool_t * p,const char * file)1610 AP_DECLARE(char *) ap_runtime_dir_relative(apr_pool_t *p, const char *file)
1611 {
1612 char *newpath = NULL;
1613 apr_status_t rv;
1614 const char *runtime_dir = ap_runtime_dir ? ap_runtime_dir : ap_server_root_relative(p, DEFAULT_REL_RUNTIMEDIR);
1615
1616 rv = apr_filepath_merge(&newpath, runtime_dir, file,
1617 APR_FILEPATH_TRUENAME, p);
1618 if (newpath && (rv == APR_SUCCESS || APR_STATUS_IS_EPATHWILD(rv)
1619 || APR_STATUS_IS_ENOENT(rv)
1620 || APR_STATUS_IS_ENOTDIR(rv))) {
1621 return newpath;
1622 }
1623 else {
1624 return NULL;
1625 }
1626 }
1627
1628
ap_soak_end_container(cmd_parms * cmd,char * directive)1629 AP_DECLARE(const char *) ap_soak_end_container(cmd_parms *cmd, char *directive)
1630 {
1631 struct ap_varbuf vb;
1632 const char *args;
1633 char *cmd_name;
1634 apr_status_t rc;
1635 apr_size_t max_len = VARBUF_MAX_LEN;
1636 if (cmd->pool == cmd->temp_pool)
1637 max_len = HUGE_STRING_LEN; /* lower limit for .htaccess */
1638
1639 ap_varbuf_init(cmd->temp_pool, &vb, VARBUF_INIT_LEN);
1640
1641 while ((rc = ap_varbuf_cfg_getline(&vb, cmd->config_file, max_len))
1642 == APR_SUCCESS) {
1643 args = vb.buf;
1644
1645 cmd_name = ap_getword_conf(cmd->temp_pool, &args);
1646 if (cmd_name[0] == '<') {
1647 if (cmd_name[1] == '/') {
1648 cmd_name[strlen(cmd_name) - 1] = '\0';
1649
1650 if (ap_cstr_casecmp(cmd_name + 2, directive + 1) != 0) {
1651 return apr_pstrcat(cmd->pool, "Expected </",
1652 directive + 1, "> but saw ",
1653 cmd_name, ">", NULL);
1654 }
1655
1656 ap_varbuf_free(&vb);
1657 return NULL; /* found end of container */
1658 }
1659 else {
1660 const char *msg;
1661
1662 if (*args == '\0' && cmd_name[strlen(cmd_name) - 1] == '>') {
1663 cmd_name[strlen(cmd_name) - 1] = '\0';
1664 }
1665
1666 if ((msg = ap_soak_end_container(cmd, cmd_name)) != NULL) {
1667 return msg;
1668 }
1669 }
1670 }
1671 }
1672 if (rc != APR_EOF && rc != APR_SUCCESS)
1673 return ap_pcfg_strerror(cmd->temp_pool, cmd->config_file, rc);
1674
1675 return apr_pstrcat(cmd->pool, "Expected </",
1676 directive + 1, "> before end of configuration",
1677 NULL);
1678 }
1679
execute_now(char * cmd_line,const char * args,cmd_parms * parms,apr_pool_t * p,apr_pool_t * ptemp,ap_directive_t ** sub_tree,ap_directive_t * parent)1680 static const char *execute_now(char *cmd_line, const char *args,
1681 cmd_parms *parms,
1682 apr_pool_t *p, apr_pool_t *ptemp,
1683 ap_directive_t **sub_tree,
1684 ap_directive_t *parent)
1685 {
1686 const command_rec *cmd;
1687 ap_mod_list *ml;
1688 char *dir = apr_pstrdup(parms->temp_pool, cmd_line);
1689
1690 ap_str_tolower(dir);
1691
1692 ml = apr_hash_get(ap_config_hash, dir, APR_HASH_KEY_STRING);
1693
1694 if (ml == NULL) {
1695 return apr_pstrcat(parms->pool, "Invalid command '",
1696 cmd_line,
1697 "', perhaps misspelled or defined by a module "
1698 "not included in the server configuration",
1699 NULL);
1700 }
1701
1702 for ( ; ml != NULL; ml = ml->next) {
1703 const char *retval;
1704 cmd = ml->cmd;
1705
1706 retval = invoke_cmd(cmd, parms, sub_tree, args);
1707
1708 if (retval != NULL) {
1709 return retval;
1710 }
1711 }
1712
1713 return NULL;
1714 }
1715
1716 /* This structure and the following functions are needed for the
1717 * table-based config file reading. They are passed to the
1718 * cfg_open_custom() routine.
1719 */
1720
1721 /* Structure to be passed to cfg_open_custom(): it contains an
1722 * index which is incremented from 0 to nelts on each call to
1723 * cfg_getline() (which in turn calls arr_elts_getstr())
1724 * and an apr_array_header_t pointer for the string array.
1725 */
1726 typedef struct {
1727 apr_array_header_t *array;
1728 int curr_idx;
1729 } arr_elts_param_t;
1730
1731
1732 /* arr_elts_getstr() returns the next line from the string array. */
arr_elts_getstr(void * buf,apr_size_t bufsiz,void * param)1733 static apr_status_t arr_elts_getstr(void *buf, apr_size_t bufsiz, void *param)
1734 {
1735 arr_elts_param_t *arr_param = (arr_elts_param_t *)param;
1736 const char *elt;
1737
1738 /* End of array reached? */
1739 if (++arr_param->curr_idx > arr_param->array->nelts)
1740 return APR_EOF;
1741
1742 /* return the line */
1743 elt = ((const char **)arr_param->array->elts)[arr_param->curr_idx - 1];
1744 if (apr_cpystrn(buf, elt, bufsiz) - (char *)buf >= bufsiz - 1)
1745 return APR_ENOSPC;
1746 return APR_SUCCESS;
1747 }
1748
1749
1750 /* arr_elts_close(): dummy close routine (makes sure no more lines can be read) */
arr_elts_close(void * param)1751 static apr_status_t arr_elts_close(void *param)
1752 {
1753 arr_elts_param_t *arr_param = (arr_elts_param_t *)param;
1754
1755 arr_param->curr_idx = arr_param->array->nelts;
1756
1757 return APR_SUCCESS;
1758 }
1759
process_command_config(server_rec * s,apr_array_header_t * arr,ap_directive_t ** conftree,apr_pool_t * p,apr_pool_t * ptemp)1760 static const char *process_command_config(server_rec *s,
1761 apr_array_header_t *arr,
1762 ap_directive_t **conftree,
1763 apr_pool_t *p,
1764 apr_pool_t *ptemp)
1765 {
1766 const char *errmsg;
1767 cmd_parms parms;
1768 arr_elts_param_t arr_parms;
1769
1770 arr_parms.curr_idx = 0;
1771 arr_parms.array = arr;
1772
1773 if (ap_config_hash == NULL) {
1774 rebuild_conf_hash(s->process->pconf, 1);
1775 }
1776
1777 parms = default_parms;
1778 parms.pool = p;
1779 parms.temp_pool = ptemp;
1780 parms.server = s;
1781 parms.override = (RSRC_CONF | OR_ALL) & ~(OR_AUTHCFG | OR_LIMIT);
1782 parms.override_opts = OPT_ALL | OPT_SYM_OWNER | OPT_MULTI;
1783
1784 parms.config_file = ap_pcfg_open_custom(p, "-c/-C directives",
1785 &arr_parms, NULL,
1786 arr_elts_getstr, arr_elts_close);
1787
1788 errmsg = ap_build_config(&parms, p, ptemp, conftree);
1789 ap_cfg_closefile(parms.config_file);
1790
1791 if (errmsg) {
1792 return apr_pstrcat(p, "Syntax error in -C/-c directive: ", errmsg,
1793 NULL);
1794 }
1795
1796 return NULL;
1797 }
1798
1799 /**
1800 * Used by -D DUMP_INCLUDES to output the config file "tree".
1801 */
dump_config_name(const char * fname,apr_pool_t * p)1802 static void dump_config_name(const char *fname, apr_pool_t *p)
1803 {
1804 unsigned i, recursion, line_number;
1805 void *data;
1806 apr_file_t *out = NULL;
1807
1808 apr_file_open_stdout(&out, p);
1809
1810 /* ap_include_sentinel is defined by the core Include directive; use it to
1811 * figure out how deep in the stack we are.
1812 */
1813 apr_pool_userdata_get(&data, "ap_include_sentinel", p);
1814
1815 if (data) {
1816 recursion = *(unsigned *)data;
1817 } else {
1818 recursion = 0;
1819 }
1820
1821 /* Indent once for each level. */
1822 for (i = 0; i < (recursion + 1); ++i) {
1823 apr_file_printf(out, " ");
1824 }
1825
1826 /* ap_include_lineno is similarly defined to tell us where in the last
1827 * config file we were.
1828 */
1829 apr_pool_userdata_get(&data, "ap_include_lineno", p);
1830
1831 if (data) {
1832 line_number = *(unsigned *)data;
1833 } else {
1834 line_number = 0;
1835 }
1836
1837 /* Print the line number and the name of the parsed file. */
1838 if (line_number > 0) {
1839 apr_file_printf(out, "(%u)", line_number);
1840 } else {
1841 apr_file_printf(out, "(*)");
1842 }
1843
1844 apr_file_printf(out, " %s\n", fname);
1845 }
1846
ap_process_resource_config(server_rec * s,const char * fname,ap_directive_t ** conftree,apr_pool_t * p,apr_pool_t * ptemp)1847 AP_DECLARE(const char *) ap_process_resource_config(server_rec *s,
1848 const char *fname,
1849 ap_directive_t **conftree,
1850 apr_pool_t *p,
1851 apr_pool_t *ptemp)
1852 {
1853 ap_configfile_t *cfp;
1854 cmd_parms parms;
1855 apr_status_t rv;
1856 const char *error;
1857
1858 parms = default_parms;
1859 parms.pool = p;
1860 parms.temp_pool = ptemp;
1861 parms.server = s;
1862 parms.override = (RSRC_CONF | OR_ALL) & ~(OR_AUTHCFG | OR_LIMIT);
1863 parms.override_opts = OPT_ALL | OPT_SYM_OWNER | OPT_MULTI;
1864
1865 rv = ap_pcfg_openfile(&cfp, p, fname);
1866 if (rv != APR_SUCCESS) {
1867 return apr_psprintf(p, "Could not open configuration file %s: %pm",
1868 fname, &rv);
1869 }
1870
1871 if (ap_exists_config_define("DUMP_INCLUDES")) {
1872 dump_config_name(fname, p);
1873 }
1874
1875 parms.config_file = cfp;
1876 error = ap_build_config(&parms, p, ptemp, conftree);
1877 ap_cfg_closefile(cfp);
1878
1879 if (error) {
1880 if (parms.err_directive)
1881 return apr_psprintf(p, "Syntax error on line %d of %s: %s",
1882 parms.err_directive->line_num,
1883 parms.err_directive->filename, error);
1884 else
1885 return error;
1886 }
1887
1888 return NULL;
1889 }
1890
1891 typedef struct {
1892 server_rec *s;
1893 ap_directive_t **conftree;
1894 } configs;
1895
process_resource_config_cb(ap_dir_match_t * w,const char * fname)1896 static const char *process_resource_config_cb(ap_dir_match_t *w, const char *fname)
1897 {
1898 configs *cfgs = w->ctx;
1899 return ap_process_resource_config(cfgs->s, fname, cfgs->conftree, w->p, w->ptemp);
1900 }
1901
ap_process_fnmatch_configs(server_rec * s,const char * fname,ap_directive_t ** conftree,apr_pool_t * p,apr_pool_t * ptemp,int optional)1902 AP_DECLARE(const char *) ap_process_fnmatch_configs(server_rec *s,
1903 const char *fname,
1904 ap_directive_t **conftree,
1905 apr_pool_t *p,
1906 apr_pool_t *ptemp,
1907 int optional)
1908 {
1909 configs cfgs;
1910 ap_dir_match_t w;
1911
1912 cfgs.s = s;
1913 cfgs.conftree = conftree;
1914
1915 w.prefix = "Include/IncludeOptional: ";
1916 w.p = p;
1917 w.ptemp = ptemp;
1918 w.flags = (optional ? AP_DIR_FLAG_OPTIONAL : AP_DIR_FLAG_NONE) | AP_DIR_FLAG_RECURSIVE;
1919 w.cb = process_resource_config_cb;
1920 w.ctx = &cfgs;
1921 w.depth = 0;
1922
1923 /* don't require conf/httpd.conf if we have a -C or -c switch */
1924 if ((ap_server_pre_read_config->nelts
1925 || ap_server_post_read_config->nelts)
1926 && !(strcmp(fname, ap_server_root_relative(ptemp, SERVER_CONFIG_FILE)))) {
1927 apr_finfo_t finfo;
1928
1929 if (apr_stat(&finfo, fname, APR_FINFO_LINK | APR_FINFO_TYPE, ptemp) != APR_SUCCESS)
1930 return NULL;
1931 }
1932
1933 if (!apr_fnmatch_test(fname)) {
1934 return ap_dir_nofnmatch(&w, fname);
1935 }
1936 else {
1937 apr_status_t status;
1938 const char *rootpath, *filepath = fname;
1939
1940 /* locate the start of the directories proper */
1941 status = apr_filepath_root(&rootpath, &filepath, APR_FILEPATH_TRUENAME, ptemp);
1942
1943 /* we allow APR_SUCCESS and APR_EINCOMPLETE */
1944 if (APR_ERELATIVE == status) {
1945 return apr_pstrcat(p, "Include must have an absolute path, ", fname, NULL);
1946 }
1947 else if (APR_EBADPATH == status) {
1948 return apr_pstrcat(p, "Include has a bad path, ", fname, NULL);
1949 }
1950
1951 /* walk the filepath */
1952 return ap_dir_fnmatch(&w, rootpath, filepath);
1953 }
1954 }
1955
ap_process_config_tree(server_rec * s,ap_directive_t * conftree,apr_pool_t * p,apr_pool_t * ptemp)1956 AP_DECLARE(int) ap_process_config_tree(server_rec *s,
1957 ap_directive_t *conftree,
1958 apr_pool_t *p,
1959 apr_pool_t *ptemp)
1960 {
1961 const char *errmsg;
1962 cmd_parms parms;
1963
1964 parms = default_parms;
1965 parms.pool = p;
1966 parms.temp_pool = ptemp;
1967 parms.server = s;
1968 parms.override = (RSRC_CONF | OR_ALL) & ~(OR_AUTHCFG | OR_LIMIT);
1969 parms.override_opts = OPT_ALL | OPT_SYM_OWNER | OPT_MULTI;
1970 parms.limited = -1;
1971
1972 errmsg = ap_walk_config(conftree, &parms, s->lookup_defaults);
1973 if (errmsg) {
1974 if (parms.err_directive)
1975 ap_log_perror(APLOG_MARK, APLOG_STARTUP, 0, p, APLOGNO(00526)
1976 "Syntax error on line %d of %s:",
1977 parms.err_directive->line_num,
1978 parms.err_directive->filename);
1979 ap_log_perror(APLOG_MARK, APLOG_STARTUP, 0, p, "%s", errmsg);
1980 return HTTP_INTERNAL_SERVER_ERROR;
1981 }
1982
1983 return OK;
1984 }
1985
ap_open_htaccess(request_rec * r,const char * dir_name,const char * access_name,ap_configfile_t ** conffile,const char ** full_name)1986 apr_status_t ap_open_htaccess(request_rec *r, const char *dir_name,
1987 const char *access_name,
1988 ap_configfile_t **conffile,
1989 const char **full_name)
1990 {
1991 *full_name = ap_make_full_path(r->pool, dir_name, access_name);
1992 return ap_pcfg_openfile(conffile, r->pool, *full_name);
1993 }
1994
ap_parse_htaccess(ap_conf_vector_t ** result,request_rec * r,int override,int override_opts,apr_table_t * override_list,const char * d,const char * access_names)1995 AP_CORE_DECLARE(int) ap_parse_htaccess(ap_conf_vector_t **result,
1996 request_rec *r, int override,
1997 int override_opts, apr_table_t *override_list,
1998 const char *d, const char *access_names)
1999 {
2000 ap_configfile_t *f = NULL;
2001 cmd_parms parms;
2002 const char *filename;
2003 const struct htaccess_result *cache;
2004 struct htaccess_result *new;
2005 ap_conf_vector_t *dc = NULL;
2006 apr_status_t status;
2007
2008 /* firstly, search cache */
2009 for (cache = r->htaccess; cache != NULL; cache = cache->next) {
2010 if (cache->override == override && strcmp(cache->dir, d) == 0) {
2011 *result = cache->htaccess;
2012 return OK;
2013 }
2014 }
2015
2016 parms = default_parms;
2017 parms.override = override;
2018 parms.override_opts = override_opts;
2019 parms.override_list = override_list;
2020 parms.pool = r->pool;
2021 parms.temp_pool = r->pool;
2022 parms.server = r->server;
2023 parms.path = apr_pstrdup(r->pool, d);
2024
2025 /* loop through the access names and find the first one */
2026 while (access_names[0]) {
2027 const char *access_name = ap_getword_conf(r->pool, &access_names);
2028
2029 filename = NULL;
2030 status = ap_run_open_htaccess(r, d, access_name, &f, &filename);
2031 if (status == APR_SUCCESS) {
2032 const char *errmsg;
2033 ap_directive_t *temptree = NULL;
2034
2035 dc = ap_create_per_dir_config(r->pool);
2036
2037 parms.config_file = f;
2038 errmsg = ap_build_config(&parms, r->pool, r->pool, &temptree);
2039 if (errmsg == NULL)
2040 errmsg = ap_walk_config(temptree, &parms, dc);
2041
2042 ap_cfg_closefile(f);
2043
2044 if (errmsg) {
2045 ap_log_rerror(APLOG_MARK, APLOG_ALERT, 0, r,
2046 "%s: %s", filename, errmsg);
2047 return HTTP_INTERNAL_SERVER_ERROR;
2048 }
2049
2050 *result = dc;
2051 break;
2052 }
2053 else {
2054 if (!APR_STATUS_IS_ENOENT(status)
2055 && !APR_STATUS_IS_ENOTDIR(status)) {
2056 ap_log_rerror(APLOG_MARK, APLOG_CRIT, status, r, APLOGNO(00529)
2057 "%s pcfg_openfile: unable to check htaccess file, "
2058 "ensure it is readable and that '%s' "
2059 "is executable",
2060 filename, d);
2061 apr_table_setn(r->notes, "error-notes",
2062 "Server unable to read htaccess file, denying "
2063 "access to be safe");
2064 return HTTP_FORBIDDEN;
2065 }
2066 }
2067 }
2068
2069 /* cache it */
2070 new = apr_palloc(r->pool, sizeof(struct htaccess_result));
2071 new->dir = parms.path;
2072 new->override = override;
2073 new->override_opts = override_opts;
2074 new->htaccess = dc;
2075
2076 /* add to head of list */
2077 new->next = r->htaccess;
2078 r->htaccess = new;
2079
2080 return OK;
2081 }
2082
ap_init_virtual_host(apr_pool_t * p,const char * hostname,server_rec * main_server,server_rec ** ps)2083 AP_CORE_DECLARE(const char *) ap_init_virtual_host(apr_pool_t *p,
2084 const char *hostname,
2085 server_rec *main_server,
2086 server_rec **ps)
2087 {
2088 server_rec *s = (server_rec *) apr_pcalloc(p, sizeof(server_rec));
2089
2090 /* TODO: this crap belongs in http_core */
2091 s->process = main_server->process;
2092 s->server_admin = NULL;
2093 s->server_hostname = NULL;
2094 s->server_scheme = NULL;
2095 s->error_fname = NULL;
2096 s->timeout = 0;
2097 s->keep_alive_timeout = 0;
2098 s->keep_alive = -1;
2099 s->keep_alive_max = -1;
2100 s->error_log = main_server->error_log;
2101 s->log.level = APLOG_UNSET;
2102 s->log.module_levels = NULL;
2103 /* useful default, otherwise we get a port of 0 on redirects */
2104 s->port = main_server->port;
2105 s->next = NULL;
2106
2107 s->is_virtual = 1;
2108 s->names = apr_array_make(p, 4, sizeof(char **));
2109 s->wild_names = apr_array_make(p, 4, sizeof(char **));
2110
2111 s->module_config = create_empty_config(p);
2112 s->lookup_defaults = ap_create_per_dir_config(p);
2113
2114 s->limit_req_line = main_server->limit_req_line;
2115 s->limit_req_fieldsize = main_server->limit_req_fieldsize;
2116 s->limit_req_fields = main_server->limit_req_fields;
2117
2118 *ps = s;
2119
2120 return ap_parse_vhost_addrs(p, hostname, s);
2121 }
2122
ap_new_log_config(apr_pool_t * p,const struct ap_logconf * old)2123 AP_DECLARE(struct ap_logconf *) ap_new_log_config(apr_pool_t *p,
2124 const struct ap_logconf *old)
2125 {
2126 struct ap_logconf *l = apr_pcalloc(p, sizeof(struct ap_logconf));
2127 if (old) {
2128 l->level = old->level;
2129 if (old->module_levels) {
2130 l->module_levels =
2131 apr_pmemdup(p, old->module_levels, conf_vector_length);
2132 }
2133 }
2134 else {
2135 l->level = APLOG_UNSET;
2136 }
2137 return l;
2138 }
2139
ap_merge_log_config(const struct ap_logconf * old_conf,struct ap_logconf * new_conf)2140 AP_DECLARE(void) ap_merge_log_config(const struct ap_logconf *old_conf,
2141 struct ap_logconf *new_conf)
2142 {
2143 if (new_conf->level != APLOG_UNSET) {
2144 /* Setting the main loglevel resets all per-module log levels.
2145 * I.e. if new->level has been set, we must ignore old->module_levels.
2146 */
2147 return;
2148 }
2149
2150 new_conf->level = old_conf->level;
2151 if (new_conf->module_levels == NULL) {
2152 new_conf->module_levels = old_conf->module_levels;
2153 }
2154 else if (old_conf->module_levels != NULL) {
2155 int i;
2156 for (i = 0; i < conf_vector_length; i++) {
2157 if (new_conf->module_levels[i] == APLOG_UNSET)
2158 new_conf->module_levels[i] = old_conf->module_levels[i];
2159 }
2160 }
2161 }
2162
ap_fixup_virtual_hosts(apr_pool_t * p,server_rec * main_server)2163 AP_DECLARE(void) ap_fixup_virtual_hosts(apr_pool_t *p, server_rec *main_server)
2164 {
2165 server_rec *virt;
2166 core_dir_config *dconf =
2167 ap_get_core_module_config(main_server->lookup_defaults);
2168 dconf->log = &main_server->log;
2169
2170 for (virt = main_server->next; virt; virt = virt->next) {
2171 merge_server_configs(p, main_server->module_config, virt);
2172
2173 virt->lookup_defaults =
2174 ap_merge_per_dir_configs(p, main_server->lookup_defaults,
2175 virt->lookup_defaults);
2176
2177 if (virt->server_admin == NULL)
2178 virt->server_admin = main_server->server_admin;
2179
2180 if (virt->timeout == 0)
2181 virt->timeout = main_server->timeout;
2182
2183 if (virt->keep_alive_timeout == 0)
2184 virt->keep_alive_timeout = main_server->keep_alive_timeout;
2185
2186 if (virt->keep_alive == -1)
2187 virt->keep_alive = main_server->keep_alive;
2188
2189 if (virt->keep_alive_max == -1)
2190 virt->keep_alive_max = main_server->keep_alive_max;
2191
2192 ap_merge_log_config(&main_server->log, &virt->log);
2193
2194 dconf = ap_get_core_module_config(virt->lookup_defaults);
2195 dconf->log = &virt->log;
2196
2197 /* XXX: this is really something that should be dealt with by a
2198 * post-config api phase
2199 */
2200 ap_core_reorder_directories(p, virt);
2201 }
2202
2203 ap_core_reorder_directories(p, main_server);
2204 }
2205
2206 /*****************************************************************
2207 *
2208 * Getting *everything* configured...
2209 */
2210
init_config_globals(apr_pool_t * p)2211 static void init_config_globals(apr_pool_t *p)
2212 {
2213 /* Global virtual host hash bucket pointers. Init to null. */
2214 ap_init_vhost_config(p);
2215 }
2216
init_server_config(process_rec * process,apr_pool_t * p)2217 static server_rec *init_server_config(process_rec *process, apr_pool_t *p)
2218 {
2219 apr_status_t rv;
2220 server_rec *s = (server_rec *) apr_pcalloc(p, sizeof(server_rec));
2221
2222 apr_file_open_stderr(&s->error_log, p);
2223 s->process = process;
2224 s->port = 0;
2225 s->server_admin = DEFAULT_ADMIN;
2226 s->server_hostname = NULL;
2227 s->server_scheme = NULL;
2228 s->error_fname = DEFAULT_ERRORLOG;
2229 s->log.level = DEFAULT_LOGLEVEL;
2230 s->log.module_levels = NULL;
2231 s->limit_req_line = DEFAULT_LIMIT_REQUEST_LINE;
2232 s->limit_req_fieldsize = DEFAULT_LIMIT_REQUEST_FIELDSIZE;
2233 s->limit_req_fields = DEFAULT_LIMIT_REQUEST_FIELDS;
2234 s->timeout = apr_time_from_sec(DEFAULT_TIMEOUT);
2235 s->keep_alive_timeout = apr_time_from_sec(DEFAULT_KEEPALIVE_TIMEOUT);
2236 s->keep_alive_max = DEFAULT_KEEPALIVE;
2237 s->keep_alive = 1;
2238 s->next = NULL;
2239 s->addrs = apr_pcalloc(p, sizeof(server_addr_rec));
2240
2241 /* NOT virtual host; don't match any real network interface */
2242 rv = apr_sockaddr_info_get(&s->addrs->host_addr,
2243 NULL, APR_UNSPEC, 0, 0, p);
2244 if (rv != APR_SUCCESS) {
2245 /* should we test here for rv being an EAIERR? */
2246 ap_log_error(APLOG_MARK, APLOG_STARTUP|APLOG_CRIT, rv, NULL, APLOGNO(00530)
2247 "initialisation: bug or getaddrinfo fail");
2248 return NULL;
2249 }
2250
2251 s->addrs->host_port = 0; /* matches any port */
2252 s->addrs->virthost = ""; /* must be non-NULL */
2253 s->names = s->wild_names = NULL;
2254
2255 s->module_config = create_server_config(p, s);
2256 s->lookup_defaults = create_default_per_dir_config(p);
2257
2258 return s;
2259 }
2260
2261
reset_conf_vector_length(void * dummy)2262 static apr_status_t reset_conf_vector_length(void *dummy)
2263 {
2264 reserved_module_slots = 0;
2265 conf_vector_length = max_modules;
2266 return APR_SUCCESS;
2267 }
2268
conf_vector_length_pre_config(apr_pool_t * pconf,apr_pool_t * plog,apr_pool_t * ptemp)2269 static int conf_vector_length_pre_config(apr_pool_t *pconf, apr_pool_t *plog,
2270 apr_pool_t *ptemp)
2271 {
2272 /*
2273 * We have loaded all modules that are loaded by EXEC_ON_READ directives.
2274 * From now on we reduce the size of the config vectors to what we need,
2275 * plus what has been reserved (e.g. by mod_perl) for additional modules
2276 * loaded later on.
2277 * If max_modules is too small, ap_add_module() will abort.
2278 */
2279 if (total_modules + reserved_module_slots < max_modules) {
2280 conf_vector_length = total_modules + reserved_module_slots;
2281 }
2282 apr_pool_cleanup_register(pconf, NULL, reset_conf_vector_length,
2283 apr_pool_cleanup_null);
2284 return OK;
2285 }
2286
2287
ap_register_config_hooks(apr_pool_t * p)2288 AP_CORE_DECLARE(void) ap_register_config_hooks(apr_pool_t *p)
2289 {
2290 ap_hook_pre_config(conf_vector_length_pre_config, NULL, NULL,
2291 APR_HOOK_REALLY_LAST);
2292 }
2293
ap_read_config(process_rec * process,apr_pool_t * ptemp,const char * filename,ap_directive_t ** conftree)2294 AP_DECLARE(server_rec*) ap_read_config(process_rec *process, apr_pool_t *ptemp,
2295 const char *filename,
2296 ap_directive_t **conftree)
2297 {
2298 const char *confname, *error;
2299 apr_pool_t *p = process->pconf;
2300 server_rec *s = init_server_config(process, p);
2301 if (s == NULL) {
2302 return s;
2303 }
2304
2305 init_config_globals(p);
2306
2307 if (ap_exists_config_define("DUMP_INCLUDES")) {
2308 apr_file_t *out = NULL;
2309 apr_file_open_stdout(&out, p);
2310
2311 /* Included files will be dumped as the config is walked; print a
2312 * header.
2313 */
2314 apr_file_printf(out, "Included configuration files:\n");
2315 }
2316
2317 /* All server-wide config files now have the SAME syntax... */
2318 error = process_command_config(s, ap_server_pre_read_config, conftree,
2319 p, ptemp);
2320 if (error) {
2321 ap_log_error(APLOG_MARK, APLOG_STARTUP|APLOG_CRIT, 0, NULL, "%s: %s",
2322 ap_server_argv0, error);
2323 return NULL;
2324 }
2325
2326 /* process_command_config may change the ServerRoot so
2327 * compute this config file name afterwards.
2328 */
2329 confname = ap_server_root_relative(p, filename);
2330
2331 if (!confname) {
2332 ap_log_error(APLOG_MARK, APLOG_STARTUP|APLOG_CRIT,
2333 APR_EBADPATH, NULL, APLOGNO(00532) "Invalid config file path %s",
2334 filename);
2335 return NULL;
2336 }
2337
2338 error = ap_process_resource_config(s, confname, conftree, p, ptemp);
2339 if (error) {
2340 ap_log_error(APLOG_MARK, APLOG_STARTUP|APLOG_CRIT, 0, NULL,
2341 "%s: %s", ap_server_argv0, error);
2342 return NULL;
2343 }
2344
2345 error = ap_check_mpm();
2346 if (error) {
2347 ap_log_error(APLOG_MARK, APLOG_STARTUP|APLOG_CRIT, 0, NULL, APLOGNO(00534)
2348 "%s: Configuration error: %s", ap_server_argv0, error);
2349 return NULL;
2350 }
2351
2352 error = process_command_config(s, ap_server_post_read_config, conftree,
2353 p, ptemp);
2354
2355 if (error) {
2356 ap_log_error(APLOG_MARK, APLOG_STARTUP|APLOG_CRIT, 0, NULL, "%s: %s",
2357 ap_server_argv0, error);
2358 return NULL;
2359 }
2360
2361 return s;
2362 }
2363
ap_single_module_configure(apr_pool_t * p,server_rec * s,module * m)2364 AP_DECLARE(void) ap_single_module_configure(apr_pool_t *p, server_rec *s,
2365 module *m)
2366 {
2367 if (m->create_server_config)
2368 ap_set_module_config(s->module_config, m,
2369 (*m->create_server_config)(p, s));
2370
2371 if (m->create_dir_config)
2372 ap_set_module_config(s->lookup_defaults, m,
2373 (*m->create_dir_config)(p, NULL));
2374 }
2375
ap_run_rewrite_args(process_rec * process)2376 AP_DECLARE(void) ap_run_rewrite_args(process_rec *process)
2377 {
2378 module *m;
2379
2380 for (m = ap_top_module; m; m = m->next) {
2381 if (m->rewrite_args) {
2382 (*m->rewrite_args)(process);
2383 }
2384 }
2385 }
2386
2387 /********************************************************************
2388 * Configuration directives are restricted in terms of where they may
2389 * appear in the main configuration files and/or .htaccess files according
2390 * to the bitmask req_override in the command_rec structure.
2391 * If any of the overrides set in req_override are also allowed in the
2392 * context in which the command is read, then the command is allowed.
2393 * The context is determined as follows:
2394 *
2395 * inside *.conf --> override = (RSRC_CONF|OR_ALL)&~(OR_AUTHCFG|OR_LIMIT);
2396 * within <Directory> or <Location> --> override = OR_ALL|ACCESS_CONF;
2397 * within .htaccess --> override = AllowOverride for current directory;
2398 *
2399 * the result is, well, a rather confusing set of possibilities for when
2400 * a particular directive is allowed to be used. This procedure prints
2401 * in English where the given (pc) directive can be used.
2402 */
show_overrides(const command_rec * pc,module * pm)2403 static void show_overrides(const command_rec *pc, module *pm)
2404 {
2405 int n = 0;
2406
2407 printf("\tAllowed in *.conf ");
2408 if ((pc->req_override & (OR_OPTIONS | OR_FILEINFO | OR_INDEXES))
2409 || ((pc->req_override & RSRC_CONF)
2410 && ((pc->req_override & (ACCESS_CONF | OR_AUTHCFG | OR_LIMIT))))) {
2411 printf("anywhere");
2412 }
2413 else if (pc->req_override & RSRC_CONF) {
2414 printf("only outside <Directory>, <Files>, <Location>, or <If>");
2415 }
2416 else {
2417 printf("only inside <Directory>, <Files>, <Location>, or <If>");
2418 }
2419
2420 /* Warn if the directive is allowed inside <Directory> or .htaccess
2421 * but module doesn't support per-dir configuration
2422 */
2423 if ((pc->req_override & (OR_ALL | ACCESS_CONF)) && !pm->create_dir_config)
2424 printf(" [no per-dir config]");
2425
2426 if (pc->req_override & OR_ALL) {
2427 printf(" and in .htaccess\n\twhen AllowOverride");
2428
2429 if ((pc->req_override & OR_ALL) == OR_ALL) {
2430 printf(" isn't None");
2431 }
2432 else {
2433 printf(" includes ");
2434
2435 if (pc->req_override & OR_AUTHCFG) {
2436 if (n++)
2437 printf(" or ");
2438
2439 printf("AuthConfig");
2440 }
2441
2442 if (pc->req_override & OR_LIMIT) {
2443 if (n++)
2444 printf(" or ");
2445
2446 printf("Limit");
2447 }
2448
2449 if (pc->req_override & OR_OPTIONS) {
2450 if (n++)
2451 printf(" or ");
2452
2453 printf("Options");
2454 }
2455
2456 if (pc->req_override & OR_FILEINFO) {
2457 if (n++)
2458 printf(" or ");
2459
2460 printf("FileInfo");
2461 }
2462
2463 if (pc->req_override & OR_INDEXES) {
2464 if (n++)
2465 printf(" or ");
2466
2467 printf("Indexes");
2468 }
2469 }
2470 }
2471
2472 printf("\n");
2473 }
2474
2475 /* Show the preloaded configuration directives, the help string explaining
2476 * the directive arguments, in what module they are handled, and in
2477 * what parts of the configuration they are allowed. Used for httpd -L.
2478 */
ap_show_directives(void)2479 AP_DECLARE(void) ap_show_directives(void)
2480 {
2481 const command_rec *pc;
2482 int n;
2483
2484 for (n = 0; ap_loaded_modules[n]; ++n) {
2485 for (pc = ap_loaded_modules[n]->cmds; pc && pc->name; ++pc) {
2486 printf("%s (%s)\n", pc->name, ap_loaded_modules[n]->name);
2487
2488 if (pc->errmsg)
2489 printf("\t%s\n", pc->errmsg);
2490
2491 show_overrides(pc, ap_loaded_modules[n]);
2492 }
2493 }
2494 }
2495
2496 /* Show the preloaded module names. Used for httpd -l. */
ap_show_modules(void)2497 AP_DECLARE(void) ap_show_modules(void)
2498 {
2499 int n;
2500
2501 printf("Compiled in modules:\n");
2502 for (n = 0; ap_loaded_modules[n]; ++n)
2503 printf(" %s\n", ap_loaded_modules[n]->name);
2504 }
2505
ap_exists_directive(apr_pool_t * p,const char * name)2506 AP_DECLARE(int) ap_exists_directive(apr_pool_t *p, const char *name)
2507 {
2508 char *lname = apr_pstrdup(p, name);
2509
2510 ap_str_tolower(lname);
2511
2512 return ap_config_hash &&
2513 apr_hash_get(ap_config_hash, lname, APR_HASH_KEY_STRING) != NULL;
2514 }
2515
ap_retained_data_get(const char * key)2516 AP_DECLARE(void *) ap_retained_data_get(const char *key)
2517 {
2518 void *retained;
2519
2520 apr_pool_userdata_get((void *)&retained, key, ap_pglobal);
2521 return retained;
2522 }
2523
ap_retained_data_create(const char * key,apr_size_t size)2524 AP_DECLARE(void *) ap_retained_data_create(const char *key, apr_size_t size)
2525 {
2526 void *retained;
2527
2528 retained = apr_pcalloc(ap_pglobal, size);
2529 apr_pool_userdata_set((const void *)retained, key, apr_pool_cleanup_null, ap_pglobal);
2530 return retained;
2531 }
2532
count_directives_sub(const char * directive,ap_directive_t * current)2533 static int count_directives_sub(const char *directive, ap_directive_t *current)
2534 {
2535 int count = 0;
2536 while (current != NULL) {
2537 if (current->first_child != NULL)
2538 count += count_directives_sub(directive, current->first_child);
2539 if (ap_cstr_casecmp(current->directive, directive) == 0)
2540 count++;
2541 current = current->next;
2542 }
2543 return count;
2544 }
2545
ap_reserve_module_slots(int count)2546 AP_DECLARE(void) ap_reserve_module_slots(int count)
2547 {
2548 reserved_module_slots += count;
2549 }
2550
ap_reserve_module_slots_directive(const char * directive)2551 AP_DECLARE(void) ap_reserve_module_slots_directive(const char *directive)
2552 {
2553 ap_reserve_module_slots(count_directives_sub(directive, ap_conftree));
2554 }
2555