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