]> granicus.if.org Git - apache/blobdiff - server/core.c
Avoid calling access control hooks for internal requests with
[apache] / server / core.c
index a17acc678125184d7f244d5d5cdcf44fc0685902..f6c987643ce5ab988536f1deb52ea6797291dcc6 100644 (file)
@@ -1,9 +1,9 @@
-/* Copyright 2001-2005 The Apache Software Foundation or its licensors, as
- * applicable.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
  *
  *     http://www.apache.org/licenses/LICENSE-2.0
  *
@@ -42,6 +42,7 @@
 #include "apr_buckets.h"
 #include "util_filter.h"
 #include "util_ebcdic.h"
+#include "util_mutex.h"
 #include "mpm.h"
 #include "mpm_common.h"
 #include "scoreboard.h"
@@ -222,8 +223,7 @@ static void *merge_core_dir_configs(apr_pool_t *a, void *basev, void *newv)
     /* Create this conf by duplicating the base, replacing elements
      * (or creating copies for merging) where new-> values exist.
      */
-    conf = (core_dir_config *)apr_palloc(a, sizeof(core_dir_config));
-    memcpy(conf, base, sizeof(core_dir_config));
+    conf = (core_dir_config *)apr_pmemdup(a, base, sizeof(core_dir_config));
 
     conf->d = new->d;
     conf->d_is_fnmatch = new->d_is_fnmatch;
@@ -269,10 +269,9 @@ static void *merge_core_dir_configs(apr_pool_t *a, void *basev, void *newv)
     else if (new->response_code_strings != NULL) {
         /* If we merge, the merge-result must have it's own array
          */
-        conf->response_code_strings = apr_palloc(a,
+        conf->response_code_strings = apr_pmemdup(a,
+            base->response_code_strings,
             sizeof(*conf->response_code_strings) * RESPONSE_CODES);
-        memcpy(conf->response_code_strings, base->response_code_strings,
-               sizeof(*conf->response_code_strings) * RESPONSE_CODES);
 
         for (i = 0; i < RESPONSE_CODES; ++i) {
             if (new->response_code_strings[i] != NULL) {
@@ -390,7 +389,7 @@ static void *merge_core_dir_configs(apr_pool_t *a, void *basev, void *newv)
         conf->etag_add =
             (conf->etag_add & (~ new->etag_remove)) | new->etag_add;
         conf->etag_remove =
-            (conf->opts_remove & (~ new->etag_add)) | new->etag_remove;
+            (conf->etag_remove & (~ new->etag_add)) | new->etag_remove;
         conf->etag_bits =
             (conf->etag_bits & (~ conf->etag_remove)) | conf->etag_add;
     }
@@ -470,8 +469,7 @@ static void *merge_core_server_configs(apr_pool_t *p, void *basev, void *virtv)
     core_server_config *virt = (core_server_config *)virtv;
     core_server_config *conf;
 
-    conf = (core_server_config *)apr_palloc(p, sizeof(core_server_config));
-    memcpy(conf, virt, sizeof(core_server_config));
+    conf = (core_server_config *)apr_pmemdup(p, virt, sizeof(core_server_config));
 
     if (!conf->access_name) {
         conf->access_name = base->access_name;
@@ -644,7 +642,8 @@ AP_DECLARE(int) ap_allow_overrides(request_rec *r)
 }
 
 /*
- * Optional function coming from mod_ident, used for looking up ident user
+ * Optional function coming from mod_authn_core, used for 
+ * retrieving the type of autorization
  */
 static APR_OPTIONAL_FN_TYPE(authn_ap_auth_type) *authn_ap_auth_type;
 
@@ -657,7 +656,8 @@ AP_DECLARE(const char *) ap_auth_type(request_rec *r)
 }
 
 /*
- * Optional function coming from mod_ident, used for looking up ident user
+ * Optional function coming from mod_authn_core, used for 
+ * retrieving the authorization realm
  */
 static APR_OPTIONAL_FN_TYPE(authn_ap_auth_name) *authn_ap_auth_name;
 
@@ -669,6 +669,20 @@ AP_DECLARE(const char *) ap_auth_name(request_rec *r)
     return NULL;
 }
 
+/*
+ * Optional function coming from mod_access_compat, used to determine how
+   access control interacts with authentication/authorization
+ */
+static APR_OPTIONAL_FN_TYPE(access_compat_ap_satisfies) *access_compat_ap_satisfies;
+
+AP_DECLARE(int) ap_satisfies(request_rec *r)
+{
+    if (access_compat_ap_satisfies) {
+        return access_compat_ap_satisfies(r);
+    }
+    return SATISFY_NOSPEC;
+}
+
 AP_DECLARE(const char *) ap_default_type(request_rec *r)
 {
     core_dir_config *conf;
@@ -1076,6 +1090,24 @@ static const char *set_access_name(cmd_parms *cmd, void *dummy,
     return NULL;
 }
 
+
+static const char *set_define(cmd_parms *cmd, void *dummy,
+                                   const char *optarg)
+{
+    char **newv;
+
+    const char *err = ap_check_cmd_context(cmd,
+                                           GLOBAL_ONLY);
+    if (err != NULL) {
+        return err;
+    }
+
+    newv = (char **)apr_array_push(ap_server_config_defines);
+    *newv = apr_pstrdup(cmd->pool, optarg);
+
+    return NULL;
+}
+
 #ifdef GPROF
 static const char *set_gprof_dir(cmd_parms *cmd, void *dummy, const char *arg)
 {
@@ -1132,6 +1164,9 @@ static const char *set_document_root(cmd_parms *cmd, void *dummy,
 
     /* Make it absolute, relative to ServerRoot */
     arg = ap_server_root_relative(cmd->pool, arg);
+    if (arg == NULL) {
+        return "DocumentRoot must be a directory";
+    }
 
     /* TODO: ap_configtestonly && ap_docrootcheck && */
     if (apr_filepath_merge((char**)&conf->ap_document_root, NULL, arg,
@@ -1315,8 +1350,8 @@ static const char *set_override(cmd_parms *cmd, void *d_, const char *l)
     /* Throw a warning if we're in <Location> or <Files> */
     if (ap_check_cmd_context(cmd, NOT_IN_LOCATION | NOT_IN_FILES)) {
         ap_log_error(APLOG_MARK, APLOG_WARNING, 0, cmd->server,
-                     "Useless use of AllowOverride in line %d.",
-                     cmd->directive->line_num);
+                     "Useless use of AllowOverride in line %d of %s.",
+                     cmd->directive->line_num, cmd->directive->filename);
     }
 
     d->override = OR_NONE;
@@ -1960,6 +1995,70 @@ static const char *filesection(cmd_parms *cmd, void *mconfig, const char *arg)
 
     return NULL;
 }
+static const char *ifsection(cmd_parms *cmd, void *mconfig, const char *arg)
+{
+    const char *errmsg;
+    const char *endp = ap_strrchr_c(arg, '>');
+    int old_overrides = cmd->override;
+    char *old_path = cmd->path;
+    core_dir_config *conf;
+    const command_rec *thiscmd = cmd->cmd;
+    core_dir_config *c = mconfig;
+    ap_conf_vector_t *new_file_conf = ap_create_per_dir_config(cmd->pool);
+    const char *err = ap_check_cmd_context(cmd, NOT_IN_LIMIT|NOT_IN_LOCATION);
+    const char *condition;
+    int expr_err = 0;
+
+    if (err != NULL) {
+        return err;
+    }
+
+    if (endp == NULL) {
+        return unclosed_directive(cmd);
+    }
+
+    arg = apr_pstrndup(cmd->pool, arg, endp - arg);
+
+    if (!arg[0]) {
+        return missing_container_arg(cmd);
+    }
+
+    //cmd->path = "*";
+    condition = ap_getword_conf(cmd->pool, &arg);
+    /* Only if not an .htaccess file */
+    if (!old_path) {
+        cmd->override = OR_ALL|ACCESS_CONF;
+    }
+
+    /* initialize our config and fetch it */
+    conf = ap_set_config_vectors(cmd->server, new_file_conf, cmd->path,
+                                 &core_module, cmd->pool);
+
+    conf->condition = ap_expr_parse(cmd->pool, condition, &expr_err);
+    if (expr_err) {
+        return "Cannot parse condition clause";
+    }
+
+    errmsg = ap_walk_config(cmd->directive->first_child, cmd, new_file_conf);
+    if (errmsg != NULL)
+        return errmsg;
+
+    conf->d = cmd->path;
+    conf->d_is_fnmatch = 0;
+    conf->r = NULL;
+
+    ap_add_file_conf(c, new_file_conf);
+
+    if (*arg != '\0') {
+        return apr_pstrcat(cmd->pool, "Multiple ", thiscmd->name,
+                           "> arguments not supported.", NULL);
+    }
+
+    cmd->path = old_path;
+    cmd->override = old_overrides;
+
+    return NULL;
+}
 
 static const char *start_ifmod(cmd_parms *cmd, void *mconfig, const char *arg)
 {
@@ -2225,20 +2324,40 @@ static const char *set_server_string_slot(cmd_parms *cmd, void *dummy,
     return NULL;
 }
 
+/*
+ * The ServerName directive takes one argument with format
+ * [scheme://]fully-qualified-domain-name[:port], for instance
+ * ServerName www.example.com
+ * ServerName www.example.com:80
+ * ServerName https://www.example.com:443
+ */
+
 static const char *server_hostname_port(cmd_parms *cmd, void *dummy, const char *arg)
 {
     const char *err = ap_check_cmd_context(cmd, NOT_IN_DIR_LOC_FILE|NOT_IN_LIMIT);
-    const char *portstr;
+    const char *portstr, *part;
+    char *scheme;
     int port;
 
     if (err != NULL) {
         return err;
     }
 
-    portstr = ap_strchr_c(arg, ':');
+    part = ap_strstr_c(arg, "://");
+
+    if (part) {
+      scheme = apr_pstrndup(cmd->pool, arg, part - arg);
+      ap_str_tolower(scheme);
+      cmd->server->server_scheme = (const char *)scheme;
+      part += 3;
+    } else {
+      part = arg;
+    }
+
+    portstr = ap_strchr_c(part, ':');
     if (portstr) {
-        cmd->server->server_hostname = apr_pstrndup(cmd->pool, arg,
-                                                    portstr - arg);
+        cmd->server->server_hostname = apr_pstrndup(cmd->pool, part,
+                                                    portstr - part);
         portstr++;
         port = atoi(portstr);
         if (port <= 0 || port >= 65536) { /* 65536 == 1<<16 */
@@ -2248,7 +2367,7 @@ static const char *server_hostname_port(cmd_parms *cmd, void *dummy, const char
         }
     }
     else {
-        cmd->server->server_hostname = apr_pstrdup(cmd->pool, arg);
+        cmd->server->server_hostname = apr_pstrdup(cmd->pool, part);
         port = 0;
     }
 
@@ -2560,7 +2679,7 @@ AP_DECLARE(const char *) ap_psignature(const char *prefix, request_rec *r)
 
     if (conf->server_signature == srv_sig_withmail) {
         return apr_pstrcat(r->pool, prefix, "<address>",
-                           ap_get_server_version(),
+                           ap_get_server_banner(),
                            " Server at <a href=\"",
                            ap_is_url(r->server->server_admin) ? "" : "mailto:",
                            ap_escape_html(r->pool, r->server->server_admin),
@@ -2570,7 +2689,7 @@ AP_DECLARE(const char *) ap_psignature(const char *prefix, request_rec *r)
                            "</address>\n", NULL);
     }
 
-    return apr_pstrcat(r->pool, prefix, "<address>", ap_get_server_version(),
+    return apr_pstrcat(r->pool, prefix, "<address>", ap_get_server_banner(),
                        " Server at ",
                        ap_escape_html(r->pool, ap_get_server_name(r)),
                        " Port ", sport,
@@ -2585,8 +2704,9 @@ AP_DECLARE(const char *) ap_psignature(const char *prefix, request_rec *r)
  * string.
  */
 
-static char *server_version = NULL;
-static int version_locked = 0;
+static char *server_banner = NULL;
+static int banner_locked = 0;
+static char *server_description = NULL;
 
 enum server_token_type {
     SrvTk_MAJOR,        /* eg: Apache/2 */
@@ -2598,11 +2718,12 @@ enum server_token_type {
 };
 static enum server_token_type ap_server_tokens = SrvTk_FULL;
 
-static apr_status_t reset_version(void *dummy)
+static apr_status_t reset_banner(void *dummy)
 {
-    version_locked = 0;
+    banner_locked = 0;
     ap_server_tokens = SrvTk_FULL;
-    server_version = NULL;
+    server_banner = NULL;
+    server_description = NULL;
     return APR_SUCCESS;
 }
 
@@ -2614,40 +2735,48 @@ AP_DECLARE(void) ap_get_server_revision(ap_version_t *version)
     version->add_string = AP_SERVER_ADD_STRING;
 }
 
-AP_DECLARE(const char *) ap_get_server_version(void)
+AP_DECLARE(const char *) ap_get_server_description(void)
 {
-    return (server_version ? server_version : AP_SERVER_BASEVERSION);
+    return server_description ? server_description :
+        AP_SERVER_BASEVERSION " (" PLATFORM ")";
+}
+
+AP_DECLARE(const char *) ap_get_server_banner(void)
+{
+    return server_banner ? server_banner : AP_SERVER_BASEVERSION;
 }
 
 AP_DECLARE(void) ap_add_version_component(apr_pool_t *pconf, const char *component)
 {
-    if (! version_locked) {
+    if (! banner_locked) {
         /*
          * If the version string is null, register our cleanup to reset the
          * pointer on pool destruction. We also know that, if NULL,
          * we are adding the original SERVER_BASEVERSION string.
          */
-        if (server_version == NULL) {
-            apr_pool_cleanup_register(pconf, NULL, reset_version,
+        if (server_banner == NULL) {
+            apr_pool_cleanup_register(pconf, NULL, reset_banner,
                                       apr_pool_cleanup_null);
-            server_version = apr_pstrdup(pconf, component);
+            server_banner = apr_pstrdup(pconf, component);
         }
         else {
             /*
              * Tack the given component identifier to the end of
              * the existing string.
              */
-            server_version = apr_pstrcat(pconf, server_version, " ",
-                                         component, NULL);
+            server_banner = apr_pstrcat(pconf, server_banner, " ",
+                                        component, NULL);
         }
     }
+    server_description = apr_pstrcat(pconf, server_description, " ",
+                                     component, NULL);
 }
 
 /*
- * This routine adds the real server base identity to the version string,
+ * This routine adds the real server base identity to the banner string,
  * and then locks out changes until the next reconfig.
  */
-static void ap_set_version(apr_pool_t *pconf)
+static void set_banner(apr_pool_t *pconf)
 {
     if (ap_server_tokens == SrvTk_PRODUCT_ONLY) {
         ap_add_version_component(pconf, AP_SERVER_BASEPRODUCT);
@@ -2666,12 +2795,13 @@ static void ap_set_version(apr_pool_t *pconf)
     }
 
     /*
-     * Lock the server_version string if we're not displaying
+     * Lock the server_banner string if we're not displaying
      * the full set of tokens
      */
     if (ap_server_tokens != SrvTk_FULL) {
-        version_locked++;
+        banner_locked++;
     }
+    server_description = AP_SERVER_BASEVERSION " (" PLATFORM ")";
 }
 
 static const char *set_serv_tokens(cmd_parms *cmd, void *dummy,
@@ -2973,7 +3103,7 @@ AP_DECLARE(int) ap_is_recursion_limit_exceeded(const request_rec *r)
                 /* uuh, too much. */
                 ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
                               "Request exceeded the limit of %d subrequest "
-                              "nesting levels due to probable confguration "
+                              "nesting levels due to probable configuration "
                               "error. Use 'LimitInternalRecursion' to increase "
                               "the limit if necessary. Use 'LogLevel debug' to "
                               "get a backtrace.", slimit);
@@ -3141,6 +3271,10 @@ AP_INIT_TAKE1("AddDefaultCharset", set_add_default_charset, NULL, OR_FILEINFO,
   "The name of the default charset to add to any Content-Type without one or 'Off' to disable"),
 AP_INIT_TAKE1("AcceptPathInfo", set_accept_path_info, NULL, OR_FILEINFO,
   "Set to on or off for PATH_INFO to be accepted by handlers, or default for the per-handler preference"),
+AP_INIT_TAKE1("Define", set_define, NULL, RSRC_CONF,
+              "Define the existance of a variable.  Same as passing -D to the command line."),
+AP_INIT_RAW_ARGS("<If", ifsection, NULL, OR_ALL,
+  "Container for directives to be conditionally applied"),
 
 /* Old resource config file commands */
 
@@ -3291,7 +3425,7 @@ AP_INIT_TAKE1("ScoreBoardFile", ap_mpm_set_scoreboard, NULL, RSRC_CONF,
 #endif
 #ifdef AP_MPM_WANT_SET_LOCKFILE
 AP_INIT_TAKE1("LockFile",  ap_mpm_set_lockfile, NULL, RSRC_CONF,
-              "The lockfile used when Apache needs to lock the accept() call"),
+              "The lockfile used when Apache needs to lock the accept() call (deprecated)"),
 #endif
 #ifdef AP_MPM_WANT_SET_MAX_REQUESTS
 AP_INIT_TAKE1("MaxRequestsPerChild", ap_mpm_set_max_requests, NULL, RSRC_CONF,
@@ -3303,7 +3437,7 @@ AP_INIT_TAKE1("CoreDumpDirectory", ap_mpm_set_coredumpdir, NULL, RSRC_CONF,
 #endif
 #ifdef AP_MPM_WANT_SET_ACCEPT_LOCK_MECH
 AP_INIT_TAKE1("AcceptMutex", ap_mpm_set_accept_lock_mech, NULL, RSRC_CONF,
-              ap_valid_accept_mutex_string),
+              AP_AVAILABLE_MUTEXES_STRING),
 #endif
 #ifdef AP_MPM_WANT_SET_MAX_MEM_FREE
 AP_INIT_TAKE1("MaxMemFree", ap_mpm_set_max_mem_free, NULL, RSRC_CONF,
@@ -3561,35 +3695,13 @@ static int default_handler(request_rec *r)
                                ap_md5digest(r->pool, fd));
             }
 
-            /* For platforms where the size of the file may be larger than
-             * that which can be stored in a single bucket (where the
-             * length field is an apr_size_t), split it into several
-             * buckets: */
-            if (sizeof(apr_off_t) > sizeof(apr_size_t)
-                && r->finfo.size > AP_MAX_SENDFILE) {
-                apr_off_t fsize = r->finfo.size;
-                e = apr_bucket_file_create(fd, 0, AP_MAX_SENDFILE, r->pool,
-                                           c->bucket_alloc);
-                while (fsize > AP_MAX_SENDFILE) {
-                    apr_bucket *ce;
-                    apr_bucket_copy(e, &ce);
-                    APR_BRIGADE_INSERT_TAIL(bb, ce);
-                    e->start += AP_MAX_SENDFILE;
-                    fsize -= AP_MAX_SENDFILE;
-                }
-                e->length = (apr_size_t)fsize; /* Resize just the last bucket */
-            }
-            else {
-                e = apr_bucket_file_create(fd, 0, (apr_size_t)r->finfo.size,
-                                           r->pool, c->bucket_alloc);
-            }
+            e = apr_brigade_insert_file(bb, fd, 0, r->finfo.size, r->pool);
 
 #if APR_HAS_MMAP
             if (d->enable_mmap == ENABLE_MMAP_OFF) {
                 (void)apr_bucket_file_enable_mmap(e, 0);
             }
 #endif
-            APR_BRIGADE_INSERT_TAIL(bb, e);
         }
 
         e = apr_bucket_eos_create(c->bucket_alloc);
@@ -3636,9 +3748,11 @@ static int core_post_config(apr_pool_t *pconf, apr_pool_t *plog, apr_pool_t *pte
     authz_ap_some_auth_required = APR_RETRIEVE_OPTIONAL_FN(authz_some_auth_required);
     authn_ap_auth_type = APR_RETRIEVE_OPTIONAL_FN(authn_ap_auth_type);
     authn_ap_auth_name = APR_RETRIEVE_OPTIONAL_FN(authn_ap_auth_name);
+    access_compat_ap_satisfies = APR_RETRIEVE_OPTIONAL_FN(access_compat_ap_satisfies);
 
-    ap_set_version(pconf);
+    set_banner(pconf);
     ap_setup_make_content_type(pconf);
+    ap_setup_auth_internal(ptemp);
     return OK;
 }
 
@@ -3776,6 +3890,7 @@ static conn_rec *core_create_conn(apr_pool_t *ptrans, server_rec *server,
     c->cs->c = c;
     c->cs->p = ptrans;
     c->cs->bucket_alloc = alloc;
+    c->clogging_input_filters = 0;
 
     return c;
 }
@@ -3848,7 +3963,6 @@ static void register_hooks(apr_pool_t *p)
     /* FIXME: I suspect we can eliminate the need for these do_nothings - Ben */
     ap_hook_type_checker(do_nothing,NULL,NULL,APR_HOOK_REALLY_LAST);
     ap_hook_fixups(core_override_type,NULL,NULL,APR_HOOK_REALLY_FIRST);
-    ap_hook_access_checker(do_nothing,NULL,NULL,APR_HOOK_REALLY_LAST);
     ap_hook_create_request(core_create_req, NULL, NULL, APR_HOOK_MIDDLE);
     APR_OPTIONAL_HOOK(proxy, create_req, core_create_proxy_req, NULL, NULL,
                       APR_HOOK_MIDDLE);