diff options
author | Benedikt Boehm <hollow@gentoo.org> | 2009-07-05 17:19:57 +0000 |
---|---|---|
committer | Benedikt Boehm <hollow@gentoo.org> | 2009-07-05 17:19:57 +0000 |
commit | 01b154dd0401767753f8b44b567ca27c638b59ca (patch) | |
tree | fe4f0af326c6fa2993295108dc9f79a1e0e30f20 | |
parent | update itk patch, remove obsolete libtool patch (diff) | |
download | apache-01b154dd0401767753f8b44b567ca27c638b59ca.tar.gz apache-01b154dd0401767753f8b44b567ca27c638b59ca.tar.bz2 apache-01b154dd0401767753f8b44b567ca27c638b59ca.zip |
new patches and some config fixes
-rw-r--r-- | 2.2/conf/modules.d/45_mod_dav.conf | 2 | ||||
-rwxr-xr-x | 2.2/init/apache2.initd | 4 | ||||
-rw-r--r-- | 2.2/patches/05_all_fix_graceful_multiple_listeners.patch | 42 | ||||
-rw-r--r-- | 2.2/patches/06_all_CVE-2009-1191.patch | 37 | ||||
-rw-r--r-- | 2.2/patches/07_all_CVE-2009-1195.patch | 136 | ||||
-rw-r--r-- | 2.2/patches/08_all_CVE-2009-1890.patch | 38 | ||||
-rw-r--r-- | 2.2/patches/21_all_itk_20090114.patch (renamed from 2.2/patches/21_all_itk_20080727.patch) | 315 |
7 files changed, 478 insertions, 96 deletions
diff --git a/2.2/conf/modules.d/45_mod_dav.conf b/2.2/conf/modules.d/45_mod_dav.conf index b15ca01..be3654b 100644 --- a/2.2/conf/modules.d/45_mod_dav.conf +++ b/2.2/conf/modules.d/45_mod_dav.conf @@ -45,7 +45,7 @@ Alias /uploads "/var/www/uploads" BrowserMatch "Microsoft Data Access Internet Publishing Provider" redirect-carefully BrowserMatch "MS FrontPage" redirect-carefully BrowserMatch "^WebDrive" redirect-carefully -BrowserMatch "^WebDAVFS/1.[012345]" redirect-carefully +BrowserMatch "^WebDAVFS/1.[012345678]" redirect-carefully BrowserMatch "^gnome-vfs/1.0" redirect-carefully BrowserMatch "^XML Spy" redirect-carefully BrowserMatch "^Dreamweaver-WebDAV-SCM1" redirect-carefully diff --git a/2.2/init/apache2.initd b/2.2/init/apache2.initd index 5eaf675..b6e001e 100755 --- a/2.2/init/apache2.initd +++ b/2.2/init/apache2.initd @@ -61,7 +61,7 @@ start() { ebegin "Starting ${SVCNAME}" ${APACHE2} ${APACHE2_OPTS} -k start - let i=0 + i=0 while [ ! -e "${PIDFILE}" ] && [ $i -lt ${TIMEOUT} ]; do sleep 1 && i=$(expr $i + 1) done @@ -76,7 +76,7 @@ stop() { ebegin "Stopping ${SVCNAME}" ${APACHE2} ${APACHE2_OPTS} -k stop - let i=0 + i=0 while pidof "${APACHE2}" >/dev/null && [ $i -lt ${TIMEOUT} ]; do sleep 1 && i=$(expr $i + 1) done diff --git a/2.2/patches/05_all_fix_graceful_multiple_listeners.patch b/2.2/patches/05_all_fix_graceful_multiple_listeners.patch new file mode 100644 index 0000000..6ed9de1 --- /dev/null +++ b/2.2/patches/05_all_fix_graceful_multiple_listeners.patch @@ -0,0 +1,42 @@ +--- httpd/httpd/branches/2.2.x/server/mpm/prefork/prefork.c 2009/01/31 20:53:11 739607 ++++ httpd/httpd/branches/2.2.x/server/mpm/prefork/prefork.c 2009/01/31 20:54:55 739608 +@@ -577,19 +577,27 @@ + apr_int32_t numdesc; + const apr_pollfd_t *pdesc; + +- /* timeout == -1 == wait forever */ +- status = apr_pollset_poll(pollset, -1, &numdesc, &pdesc); ++ /* check for termination first so we don't sleep for a while in ++ * poll if already signalled ++ */ ++ if (one_process && shutdown_pending) { ++ SAFE_ACCEPT(accept_mutex_off()); ++ return; ++ } ++ else if (die_now) { ++ /* In graceful stop/restart; drop the mutex ++ * and terminate the child. */ ++ SAFE_ACCEPT(accept_mutex_off()); ++ clean_child_exit(0); ++ } ++ /* timeout == 10 seconds to avoid a hang at graceful restart/stop ++ * caused by the closing of sockets by the signal handler ++ */ ++ status = apr_pollset_poll(pollset, apr_time_from_sec(10), ++ &numdesc, &pdesc); + if (status != APR_SUCCESS) { +- if (APR_STATUS_IS_EINTR(status)) { +- if (one_process && shutdown_pending) { +- return; +- } +- else if (die_now) { +- /* In graceful stop/restart; drop the mutex +- * and terminate the child. */ +- SAFE_ACCEPT(accept_mutex_off()); +- clean_child_exit(0); +- } ++ if (APR_STATUS_IS_TIMEUP(status) || ++ APR_STATUS_IS_EINTR(status)) { + continue; + } + /* Single Unix documents select as returning errnos diff --git a/2.2/patches/06_all_CVE-2009-1191.patch b/2.2/patches/06_all_CVE-2009-1191.patch new file mode 100644 index 0000000..cbb790a --- /dev/null +++ b/2.2/patches/06_all_CVE-2009-1191.patch @@ -0,0 +1,37 @@ +Index: modules/proxy/mod_proxy_ajp.c +=================================================================== +--- modules/proxy/mod_proxy_ajp.c (Revision 763379) ++++ modules/proxy/mod_proxy_ajp.c (Arbeitskopie) +@@ -307,21 +307,17 @@ + "proxy: read zero bytes, expecting" + " %" APR_OFF_T_FMT " bytes", + content_length); +- status = ajp_send_data_msg(conn->sock, msg, 0); +- if (status != APR_SUCCESS) { +- /* We had a failure: Close connection to backend */ +- conn->close++; +- ap_log_error(APLOG_MARK, APLOG_ERR, status, r->server, +- "proxy: send failed to %pI (%s)", +- conn->worker->cp->addr, +- conn->worker->hostname); +- return HTTP_INTERNAL_SERVER_ERROR; +- } +- else { +- /* Client send zero bytes with C-L > 0 +- */ +- return HTTP_BAD_REQUEST; +- } ++ /* ++ * We can only get here if the client closed the connection ++ * to us without sending the body. ++ * Now the connection is in the wrong state on the backend. ++ * Sending an empty data msg doesn't help either as it does ++ * not move this connection to the correct state on the backend ++ * for later resusage by the next request again. ++ * Close it to clean things up. ++ */ ++ conn->close++; ++ return HTTP_BAD_REQUEST; + } + } + diff --git a/2.2/patches/07_all_CVE-2009-1195.patch b/2.2/patches/07_all_CVE-2009-1195.patch new file mode 100644 index 0000000..14a6dba --- /dev/null +++ b/2.2/patches/07_all_CVE-2009-1195.patch @@ -0,0 +1,136 @@ +Index: server/config.c +=================================================================== +--- server/config.c (revision 773036) ++++ server/config.c (working copy) +@@ -1510,7 +1510,7 @@ + parms.temp_pool = ptemp; + parms.server = s; + parms.override = (RSRC_CONF | OR_ALL) & ~(OR_AUTHCFG | OR_LIMIT); +- parms.override_opts = OPT_ALL | OPT_INCNOEXEC | OPT_SYM_OWNER | OPT_MULTI; ++ parms.override_opts = OPT_ALL | OPT_SYM_OWNER | OPT_MULTI; + + parms.config_file = ap_pcfg_open_custom(p, "-c/-C directives", + &arr_parms, NULL, +@@ -1617,7 +1617,7 @@ + parms.temp_pool = ptemp; + parms.server = s; + parms.override = (RSRC_CONF | OR_ALL) & ~(OR_AUTHCFG | OR_LIMIT); +- parms.override_opts = OPT_ALL | OPT_INCNOEXEC | OPT_SYM_OWNER | OPT_MULTI; ++ parms.override_opts = OPT_ALL | OPT_SYM_OWNER | OPT_MULTI; + + rv = ap_pcfg_openfile(&cfp, p, fname); + if (rv != APR_SUCCESS) { +@@ -1755,7 +1755,7 @@ + parms.temp_pool = ptemp; + parms.server = s; + parms.override = (RSRC_CONF | OR_ALL) & ~(OR_AUTHCFG | OR_LIMIT); +- parms.override_opts = OPT_ALL | OPT_INCNOEXEC | OPT_SYM_OWNER | OPT_MULTI; ++ parms.override_opts = OPT_ALL | OPT_SYM_OWNER | OPT_MULTI; + parms.limited = -1; + + errmsg = ap_walk_config(conftree, &parms, s->lookup_defaults); +Index: server/core.c +=================================================================== +--- server/core.c (revision 773036) ++++ server/core.c (working copy) +@@ -108,8 +108,7 @@ + conf->opts = dir ? OPT_UNSET : OPT_UNSET|OPT_ALL; + conf->opts_add = conf->opts_remove = OPT_NONE; + conf->override = dir ? OR_UNSET : OR_UNSET|OR_ALL; +- conf->override_opts = OPT_UNSET | OPT_ALL | OPT_INCNOEXEC | OPT_SYM_OWNER +- | OPT_MULTI; ++ conf->override_opts = OPT_UNSET | OPT_ALL | OPT_SYM_OWNER | OPT_MULTI; + + conf->content_md5 = 2; + conf->accept_path_info = 3; +@@ -242,8 +241,15 @@ + conf->opts_remove = (conf->opts_remove & ~new->opts_add) + | new->opts_remove; + conf->opts = (conf->opts & ~conf->opts_remove) | conf->opts_add; +- if ((base->opts & OPT_INCNOEXEC) && (new->opts & OPT_INCLUDES)) { +- conf->opts = (conf->opts & ~OPT_INCNOEXEC) | OPT_INCLUDES; ++ ++ /* If Includes was enabled with exec in the base config, but ++ * was enabled without exec in the new config, then disable ++ * exec in the merged set. */ ++ if (((base->opts & (OPT_INCLUDES|OPT_INC_WITH_EXEC)) ++ == (OPT_INCLUDES|OPT_INC_WITH_EXEC)) ++ && ((new->opts & (OPT_INCLUDES|OPT_INC_WITH_EXEC)) ++ == OPT_INCLUDES)) { ++ conf->opts &= ~OPT_INC_WITH_EXEC; + } + } + else { +@@ -1304,10 +1310,12 @@ + opt = OPT_INDEXES; + } + else if (!strcasecmp(w, "Includes")) { +- opt = OPT_INCLUDES; ++ /* If Includes is permitted, both Includes and ++ * IncludesNOEXEC may be changed. */ ++ opt = (OPT_INCLUDES | OPT_INC_WITH_EXEC); + } + else if (!strcasecmp(w, "IncludesNOEXEC")) { +- opt = (OPT_INCLUDES | OPT_INCNOEXEC); ++ opt = OPT_INCLUDES; + } + else if (!strcasecmp(w, "FollowSymLinks")) { + opt = OPT_SYM_LINKS; +@@ -1428,10 +1436,10 @@ + opt = OPT_INDEXES; + } + else if (!strcasecmp(w, "Includes")) { +- opt = OPT_INCLUDES; ++ opt = (OPT_INCLUDES | OPT_INC_WITH_EXEC); + } + else if (!strcasecmp(w, "IncludesNOEXEC")) { +- opt = (OPT_INCLUDES | OPT_INCNOEXEC); ++ opt = OPT_INCLUDES; + } + else if (!strcasecmp(w, "FollowSymLinks")) { + opt = OPT_SYM_LINKS; +Index: modules/filters/mod_include.c +=================================================================== +--- modules/filters/mod_include.c (revision 773036) ++++ modules/filters/mod_include.c (working copy) +@@ -3574,7 +3574,7 @@ + intern->seen_eos = 0; + intern->state = PARSE_PRE_HEAD; + ctx->flags = (SSI_FLAG_PRINTING | SSI_FLAG_COND_TRUE); +- if (ap_allow_options(r) & OPT_INCNOEXEC) { ++ if ((ap_allow_options(r) & OPT_INC_WITH_EXEC) == 0) { + ctx->flags |= SSI_FLAG_NO_EXEC; + } + intern->accessenable = conf->accessenable; +Index: include/http_core.h +=================================================================== +--- include/http_core.h (revision 773036) ++++ include/http_core.h (working copy) +@@ -65,7 +65,7 @@ + #define OPT_NONE 0 + /** Indexes directive */ + #define OPT_INDEXES 1 +-/** Includes directive */ ++/** SSI is enabled without exec= permission */ + #define OPT_INCLUDES 2 + /** FollowSymLinks directive */ + #define OPT_SYM_LINKS 4 +@@ -73,14 +73,14 @@ + #define OPT_EXECCGI 8 + /** directive unset */ + #define OPT_UNSET 16 +-/** IncludesNOEXEC directive */ +-#define OPT_INCNOEXEC 32 ++/** SSI exec= permission is permitted, iff OPT_INCLUDES is also set */ ++#define OPT_INC_WITH_EXEC 32 + /** SymLinksIfOwnerMatch directive */ + #define OPT_SYM_OWNER 64 + /** MultiViews directive */ + #define OPT_MULTI 128 + /** All directives */ +-#define OPT_ALL (OPT_INDEXES|OPT_INCLUDES|OPT_SYM_LINKS|OPT_EXECCGI) ++#define OPT_ALL (OPT_INDEXES|OPT_INCLUDES|OPT_INC_WITH_EXEC|OPT_SYM_LINKS|OPT_EXECCGI) + /** @} */ + + /** + diff --git a/2.2/patches/08_all_CVE-2009-1890.patch b/2.2/patches/08_all_CVE-2009-1890.patch new file mode 100644 index 0000000..672c82b --- /dev/null +++ b/2.2/patches/08_all_CVE-2009-1890.patch @@ -0,0 +1,38 @@ +--- httpd/httpd/trunk/modules/proxy/mod_proxy_http.c 2009/07/02 13:37:39 790586 ++++ httpd/httpd/trunk/modules/proxy/mod_proxy_http.c 2009/07/02 13:41:18 790587 +@@ -427,10 +427,16 @@ + apr_off_t bytes_streamed = 0; + + if (old_cl_val) { ++ char *endstr; ++ + add_cl(p, bucket_alloc, header_brigade, old_cl_val); +- if (APR_SUCCESS != (status = apr_strtoff(&cl_val, old_cl_val, NULL, +- 0))) { +- return HTTP_INTERNAL_SERVER_ERROR; ++ status = apr_strtoff(&cl_val, old_cl_val, &endstr, 10); ++ ++ if (status || *endstr || endstr == old_cl_val || cl_val < 0) { ++ ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r, ++ "proxy: could not parse request Content-Length (%s)", ++ old_cl_val); ++ return HTTP_BAD_REQUEST; + } + } + terminate_headers(bucket_alloc, header_brigade); +@@ -463,8 +469,13 @@ + * + * Prevents HTTP Response Splitting. + */ +- if (bytes_streamed > cl_val) +- continue; ++ if (bytes_streamed > cl_val) { ++ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, ++ "proxy: read more bytes of request body than expected " ++ "(got %" APR_OFF_T_FMT ", expected %" APR_OFF_T_FMT ")", ++ bytes_streamed, cl_val); ++ return HTTP_INTERNAL_SERVER_ERROR; ++ } + + if (header_brigade) { + /* we never sent the header brigade, so go ahead and diff --git a/2.2/patches/21_all_itk_20080727.patch b/2.2/patches/21_all_itk_20090114.patch index a9580eb..3a346cc 100644 --- a/2.2/patches/21_all_itk_20080727.patch +++ b/2.2/patches/21_all_itk_20090114.patch @@ -1,23 +1,26 @@ -unchanged: ---- apache2.2/server/mpm/experimental/itk/Makefile.in -+++ apache2.2/server/mpm/experimental/itk/Makefile.in +Index: httpd-2.2.11/server/mpm/experimental/itk/Makefile.in +=================================================================== +--- /dev/null ++++ httpd-2.2.11/server/mpm/experimental/itk/Makefile.in @@ -0,0 +1,5 @@ + +LTLIBRARY_NAME = libitk.la +LTLIBRARY_SOURCES = itk.c + +include $(top_srcdir)/build/ltlib.mk -unchanged: ---- apache2.2/server/mpm/experimental/itk/config.m4 -+++ apache2.2/server/mpm/experimental/itk/config.m4 2007-01-29 21:03:57.000000000 +0100 +Index: httpd-2.2.11/server/mpm/experimental/itk/config.m4 +=================================================================== +--- /dev/null ++++ httpd-2.2.11/server/mpm/experimental/itk/config.m4 @@ -0,0 +1,3 @@ +if test "$MPM_NAME" = "itk" ; then + APACHE_FAST_OUTPUT(server/mpm/$MPM_SUBDIR_NAME/Makefile) +fi -diff -u apache2.2/server/mpm/experimental/itk/itk.c apache2.2/server/mpm/experimental/itk/itk.c ---- apache2.2/server/mpm/experimental/itk/itk.c -+++ apache2.2/server/mpm/experimental/itk/itk.c -@@ -0,0 +1,1704 @@ +Index: httpd-2.2.11/server/mpm/experimental/itk/itk.c +=================================================================== +--- /dev/null ++++ httpd-2.2.11/server/mpm/experimental/itk/itk.c +@@ -0,0 +1,1740 @@ +/* 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. @@ -33,7 +36,10 @@ diff -u apache2.2/server/mpm/experimental/itk/itk.c apache2.2/server/mpm/experim + * See the License for the specific language governing permissions and + * limitations under the License. + * -+ * Portions copyright 2005-2007 Steinar H. Gunderson <sgunderson@bigfoot.com>. ++ * Portions copyright 2005-2009 Steinar H. Gunderson <sgunderson@bigfoot.com>. ++ * Licensed under the same terms as the rest of Apache. ++ * ++ * Portions copyright 2008 Knut Auvor Grythe <knut@auvor.no>. + * Licensed under the same terms as the rest of Apache. + */ + @@ -45,8 +51,8 @@ diff -u apache2.2/server/mpm/experimental/itk/itk.c apache2.2/server/mpm/experim + +# define _DBG(text,par...) \ + ap_log_error(APLOG_MARK, APLOG_WARNING, 0, NULL, \ -+ "(itkmpm: pid=%d uid=%d) %s(): " text, \ -+ getpid(), getuid(), __FUNCTION__, par) ++ "(itkmpm: pid=%d uid=%d, gid=%d) %s(): " text, \ ++ getpid(), getuid(), getgid(), __FUNCTION__, par) + +#define APR_WANT_STDIO +#define APR_WANT_STRFUNC @@ -69,7 +75,7 @@ diff -u apache2.2/server/mpm/experimental/itk/itk.c apache2.2/server/mpm/experim +#include "http_config.h" +#include "http_core.h" /* for get_remote_host */ +#include "http_connection.h" -+#include "http_protocol.h" /* for ap_hook_post_read_request */ ++#include "http_request.h" /* for ap_hook_post_perdir_config */ +#include "scoreboard.h" +#include "ap_mpm.h" +#include "unixd.h" @@ -172,16 +178,20 @@ diff -u apache2.2/server/mpm/experimental/itk/itk.c apache2.2/server/mpm/experim +#endif /* TPF */ + +static volatile int die_now = 0; -+static volatile int listeners_closed = 0; -+static int active_connection = 0; ++ ++#define UNSET_NICE_VALUE 100 ++ ++typedef struct ++{ ++ uid_t uid; ++ gid_t gid; ++ char *username; ++ int nice_value; ++} itk_per_dir_conf; + +typedef struct +{ -+ uid_t uid; -+ gid_t gid; -+ char *username; -+ int max_clients_vhost; -+ int nice_value; ++ int max_clients_vhost; +} itk_server_conf; + +module AP_MODULE_DECLARE_DATA mpm_itk_module; @@ -376,10 +386,7 @@ diff -u apache2.2/server/mpm/experimental/itk/itk.c apache2.2/server/mpm/experim + +static void stop_listening(int sig) +{ -+ if (active_connection) { -+ ap_close_listeners(); -+ listeners_closed = 1; -+ } ++ ap_close_listeners(); + + /* For a graceful stop, we want the child to exit when done */ + die_now = 1; @@ -529,7 +536,8 @@ diff -u apache2.2/server/mpm/experimental/itk/itk.c apache2.2/server/mpm/experim + cap_value_t suidcaps[] = { + CAP_SETUID, + CAP_SETGID, -+ CAP_SYS_NICE ++ CAP_DAC_READ_SEARCH, ++ CAP_SYS_NICE, + }; +#endif + @@ -606,7 +614,10 @@ diff -u apache2.2/server/mpm/experimental/itk/itk.c apache2.2/server/mpm/experim + + bucket_alloc = apr_bucket_alloc_create(pchild); + -+ while (!die_now) { ++ /* die_now is set when AP_SIG_GRACEFUL is received in the child; ++ * shutdown_pending is set when SIGTERM is received when running ++ * in single process mode. */ ++ while (!die_now && !shutdown_pending) { + conn_rec *current_conn; + void *csd; + @@ -640,11 +651,6 @@ diff -u apache2.2/server/mpm/experimental/itk/itk.c apache2.2/server/mpm/experim + apr_int32_t numdesc; + const apr_pollfd_t *pdesc; + -+ if (die_now) { -+ status = !APR_SUCCESS; -+ goto unlock; -+ } -+ + /* timeout == -1 == wait forever */ + status = apr_pollset_poll(pollset, -1, &numdesc, &pdesc); + if (status != APR_SUCCESS) { @@ -652,6 +658,12 @@ diff -u apache2.2/server/mpm/experimental/itk/itk.c apache2.2/server/mpm/experim + if (one_process && shutdown_pending) { + return; + } ++ else if (die_now) { ++ /* In graceful stop/restart; drop the mutex ++ * and terminate the child. */ ++ SAFE_ACCEPT(accept_mutex_off()); ++ clean_child_exit(0); ++ } + continue; + } + /* Single Unix documents select as returning errnos @@ -662,6 +674,7 @@ diff -u apache2.2/server/mpm/experimental/itk/itk.c apache2.2/server/mpm/experim + */ + ap_log_error(APLOG_MARK, APLOG_ERR, status, + ap_server_conf, "apr_pollset_poll: (listen)"); ++ SAFE_ACCEPT(accept_mutex_off()); + clean_child_exit(1); + } + @@ -693,14 +706,8 @@ diff -u apache2.2/server/mpm/experimental/itk/itk.c apache2.2/server/mpm/experim + /* if we accept() something we don't want to die, so we have to + * defer the exit + */ -+ if (!die_now) { -+ status = lr->accept_func(&csd, lr, ptrans); -+ } -+ else { -+ status = !APR_SUCCESS; -+ } ++ status = lr->accept_func(&csd, lr, ptrans); + -+ unlock: + SAFE_ACCEPT(accept_mutex_off()); /* unlock after "accept" */ + + if (status == APR_EGENERAL) { @@ -716,14 +723,8 @@ diff -u apache2.2/server/mpm/experimental/itk/itk.c apache2.2/server/mpm/experim + * socket options, file descriptors, and read/write buffers. + */ + -+ active_connection = 1; -+ if (die_now && !listeners_closed) { -+ ap_close_listeners(); -+ listeners_closed = 1; -+ } -+ + { -+ pid_t pid = fork(); ++ pid_t pid = fork(), child_pid; + int status; + switch (pid) { + case -1: @@ -738,7 +739,11 @@ diff -u apache2.2/server/mpm/experimental/itk/itk.c apache2.2/server/mpm/experim + } + exit(0); + default: /* parent; just wait for child to be done */ -+ if (waitpid(pid, &status, 0) != pid || !WIFEXITED(status)) { ++ do { ++ child_pid = waitpid(pid, &status, 0); ++ } while (child_pid == -1 && errno == EINTR); ++ ++ if (child_pid != pid || !WIFEXITED(status)) { + if (WIFSIGNALED(status)) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, ap_server_conf, "child died with signal %u", WTERMSIG(status)); + } else if (WEXITSTATUS(status) != 0) { @@ -751,7 +756,6 @@ diff -u apache2.2/server/mpm/experimental/itk/itk.c apache2.2/server/mpm/experim + break; + } + } -+ active_connection = 0; + + /* Check the pod and the generation number after processing a + * connection so that we'll go away if a graceful restart occurred @@ -1434,13 +1438,13 @@ diff -u apache2.2/server/mpm/experimental/itk/itk.c apache2.2/server/mpm/experim + return OK; +} + -+static int itk_post_read(request_rec *r) ++static int itk_post_perdir_config(request_rec *r) +{ + uid_t wanted_uid; + gid_t wanted_gid; + const char *wanted_username; + int err = 0; -+ ++ + itk_server_conf *sconf = + (itk_server_conf *) ap_get_module_config(r->server->module_config, &mpm_itk_module); + @@ -1461,17 +1465,21 @@ diff -u apache2.2/server/mpm/experimental/itk/itk.c apache2.2/server/mpm/experim + } + } + ++ itk_per_dir_conf *dconf = ++ (itk_per_dir_conf *) ap_get_module_config(r->per_dir_config, &mpm_itk_module); ++ + strncpy(ap_scoreboard_image->servers[my_child_num][0].vhost, r->server->server_hostname, 31); + ap_scoreboard_image->servers[my_child_num][0].vhost[31] = 0; + -+ if (setpriority(PRIO_PROCESS, 0, sconf->nice_value)) { ++ if (dconf->nice_value != UNSET_NICE_VALUE && ++ setpriority(PRIO_PROCESS, 0, dconf->nice_value)) { + _DBG("setpriority(): %s", strerror(errno)); + err = 1; + } + -+ wanted_uid = sconf->uid; -+ wanted_gid = sconf->gid; -+ wanted_username = sconf->username; ++ wanted_uid = dconf->uid; ++ wanted_gid = dconf->gid; ++ wanted_username = dconf->username; + + if (wanted_uid == -1 || wanted_gid == -1) { + wanted_uid = unixd_config.user_id; @@ -1481,13 +1489,13 @@ diff -u apache2.2/server/mpm/experimental/itk/itk.c apache2.2/server/mpm/experim + + if (!err && wanted_uid != -1 && wanted_gid != -1 && (getuid() != wanted_uid || getgid() != wanted_gid)) { + if (setgid(wanted_gid)) { -+ _DBG("setgid(): %s", strerror(errno)); ++ _DBG("setgid(%d): %s", wanted_gid, strerror(errno)); + err = 1; + } else if (initgroups(wanted_username, wanted_gid)) { -+ _DBG("initgroups(): %s", strerror(errno)); ++ _DBG("initgroups(%s, %d): %s", wanted_username, wanted_gid, strerror(errno)); + err = 1; + } else if (setuid(wanted_uid)) { -+ _DBG("setuid(): %s", strerror(errno)); ++ _DBG("setuid(%d): %s", wanted_uid, strerror(errno)); + err = 1; + } + } @@ -1524,8 +1532,8 @@ diff -u apache2.2/server/mpm/experimental/itk/itk.c apache2.2/server/mpm/experim + */ + ap_hook_pre_config(itk_pre_config, NULL, NULL, APR_HOOK_REALLY_FIRST); + -+ /* set the uid as fast as possible */ -+ ap_hook_post_read_request(itk_post_read, NULL, NULL, APR_HOOK_REALLY_FIRST); ++ /* set the uid as fast as possible, but not before merging per-dit config */ ++ ap_hook_header_parser(itk_post_perdir_config, NULL, NULL, APR_HOOK_REALLY_FIRST); +} + +static const char *set_daemons_to_start(cmd_parms *cmd, void *dummy, const char *arg) @@ -1638,13 +1646,12 @@ diff -u apache2.2/server/mpm/experimental/itk/itk.c apache2.2/server/mpm/experim + return NULL; +} + -+static const char *assign_user_id (cmd_parms *cmd, void *dummy, const char *user_name, const char *group_name) ++static const char *assign_user_id (cmd_parms *cmd, void *ptr, const char *user_name, const char *group_name) +{ -+ itk_server_conf *sconf = -+ (itk_server_conf *) ap_get_module_config(cmd->server->module_config, &mpm_itk_module); -+ sconf->username = strdup(user_name); -+ sconf->uid = ap_uname2id(user_name); -+ sconf->gid = ap_gname2id(group_name); ++ itk_per_dir_conf *dconf = (itk_per_dir_conf *) ptr; ++ dconf->username = apr_pstrdup(cmd->pool, user_name); ++ dconf->uid = ap_uname2id(user_name); ++ dconf->gid = ap_gname2id(group_name); + return NULL; +} + @@ -1654,12 +1661,11 @@ diff -u apache2.2/server/mpm/experimental/itk/itk.c apache2.2/server/mpm/experim + (itk_server_conf *) ap_get_module_config(cmd->server->module_config, &mpm_itk_module); + sconf->max_clients_vhost = atoi(arg); + return NULL; -+} ++} + -+static const char *set_nice_value (cmd_parms *cmd, void *dummy, const char *arg) ++static const char *set_nice_value (cmd_parms *cmd, void *ptr, const char *arg) +{ -+ itk_server_conf *sconf = -+ (itk_server_conf *) ap_get_module_config(cmd->server->module_config, &mpm_itk_module); ++ itk_per_dir_conf *dconf = (itk_per_dir_conf *) ptr; + int nice_value = atoi(arg); + + if (nice_value < -20) { @@ -1674,7 +1680,7 @@ diff -u apache2.2/server/mpm/experimental/itk/itk.c apache2.2/server/mpm/experim + nice_value); + nice_value = 19; + } -+ sconf->nice_value = nice_value; ++ dconf->nice_value = nice_value; + return NULL; +} + @@ -1691,41 +1697,75 @@ diff -u apache2.2/server/mpm/experimental/itk/itk.c apache2.2/server/mpm/experim + "Maximum number of children alive at the same time"), +AP_INIT_TAKE1("ServerLimit", set_server_limit, NULL, RSRC_CONF, + "Maximum value of MaxClients for this run of Apache"), -+AP_INIT_TAKE2("AssignUserID", assign_user_id, NULL, RSRC_CONF, ++AP_INIT_TAKE2("AssignUserID", assign_user_id, NULL, RSRC_CONF|ACCESS_CONF, + "Tie a virtual host to a specific child process."), +AP_INIT_TAKE1("MaxClientsVHost", set_max_clients_vhost, NULL, RSRC_CONF, + "Maximum number of children alive at the same time for this virtual host."), -+AP_INIT_TAKE1("NiceValue", set_nice_value, NULL, RSRC_CONF, ++AP_INIT_TAKE1("NiceValue", set_nice_value, NULL, RSRC_CONF|ACCESS_CONF, + "Set nice value for the given vhost, from -20 (highest priority) to 19 (lowest priority)."), +AP_GRACEFUL_SHUTDOWN_TIMEOUT_COMMAND, +{ NULL } +}; + ++/* == allocate a private per-dir config structure == */ ++static void *itk_create_dir_config(apr_pool_t *p, char *dummy) ++{ ++ itk_per_dir_conf *c = (itk_per_dir_conf *) ++ apr_pcalloc(p, sizeof(itk_per_dir_conf)); ++ c->uid = c->gid = -1; ++ c->nice_value = UNSET_NICE_VALUE; ++ return c; ++} ++ ++/* == merge the parent per-dir config structure into ours == */ ++static void *itk_merge_dir_config(apr_pool_t *p, void *parent_ptr, void *child_ptr) ++{ ++ itk_per_dir_conf *c = (itk_per_dir_conf *) ++ apr_pcalloc(p, sizeof(itk_per_dir_conf)); ++ itk_per_dir_conf *parent = (itk_per_dir_conf *) parent_ptr; ++ itk_per_dir_conf *child = (itk_per_dir_conf *) child_ptr; ++ ++ if (child->username != NULL) { ++ c->username = apr_pstrdup(p, child->username); ++ c->uid = child->uid; ++ c->gid = child->gid; ++ } else if (parent->username != NULL) { ++ c->username = apr_pstrdup(p, parent->username); ++ c->uid = parent->uid; ++ c->gid = parent->gid; ++ } ++ if (child->nice_value != UNSET_NICE_VALUE) { ++ c->nice_value = child->nice_value; ++ } else { ++ c->nice_value = parent->nice_value; ++ } ++ return c; ++} ++ +/* == allocate a private server config structure == */ -+static void *itk_create_config(apr_pool_t *p, server_rec *s) ++static void *itk_create_server_config(apr_pool_t *p, server_rec *s) +{ + itk_server_conf *c = (itk_server_conf *) + apr_pcalloc(p, sizeof(itk_server_conf)); -+ c->uid = c->gid = -1; + c->max_clients_vhost = -1; -+ c->nice_value = 0; + return c; +} + +module AP_MODULE_DECLARE_DATA mpm_itk_module = { + MPM20_MODULE_STUFF, + ap_mpm_rewrite_args, /* hook to run before apache parses args */ -+ NULL, /* create per-directory config structure */ -+ NULL, /* merge per-directory config structures */ -+ itk_create_config, /* create per-server config structure */ ++ itk_create_dir_config, /* create per-directory config structure */ ++ itk_merge_dir_config, /* merge per-directory config structures */ ++ itk_create_server_config, /* create per-server config structure */ + NULL, /* merge per-server config structures */ + itk_cmds, /* command apr_table_t */ + itk_hooks, /* register hooks */ +}; -unchanged: ---- apache2.2/server/mpm/experimental/itk/mpm.h -+++ apache2.2/server/mpm/experimental/itk/mpm.h 2007-01-29 21:22:33.000000000 +0100 -@@ -0,0 +1,65 @@ +Index: httpd-2.2.11/server/mpm/experimental/itk/mpm.h +=================================================================== +--- /dev/null ++++ httpd-2.2.11/server/mpm/experimental/itk/mpm.h +@@ -0,0 +1,68 @@ +/* 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. @@ -1741,7 +1781,10 @@ unchanged: + * See the License for the specific language governing permissions and + * limitations under the License. + * -+ * Portions copyright 2005-2007 Steinar H. Gunderson <sgunderson@bigfoot.com>. ++ * Portions copyright 2005-2009 Steinar H. Gunderson <sgunderson@bigfoot.com>. ++ * Licensed under the same terms as the rest of Apache. ++ * ++ * Portions copyright 2008 Knut Auvor Grythe <knut@auvor.no>. + * Licensed under the same terms as the rest of Apache. + */ + @@ -1791,10 +1834,11 @@ unchanged: +extern server_rec *ap_server_conf; +#endif /* APACHE_MPM_ITK_H */ +/** @} */ -unchanged: ---- apache2.2/server/mpm/experimental/itk/mpm_default.h -+++ apache2.2/server/mpm/experimental/itk/mpm_default.h 2007-01-29 21:22:09.000000000 +0100 -@@ -0,0 +1,77 @@ +Index: httpd-2.2.11/server/mpm/experimental/itk/mpm_default.h +=================================================================== +--- /dev/null ++++ httpd-2.2.11/server/mpm/experimental/itk/mpm_default.h +@@ -0,0 +1,80 @@ +/* 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. @@ -1810,7 +1854,10 @@ unchanged: + * See the License for the specific language governing permissions and + * limitations under the License. + * -+ * Portions copyright 2005-2007 Steinar H. Gunderson <sgunderson@bigfoot.com>. ++ * Portions copyright 2005-2009 Steinar H. Gunderson <sgunderson@bigfoot.com>. ++ * Licensed under the same terms as the rest of Apache. ++ * ++ * Portions copyright 2008 Knut Auvor Grythe <knut@auvor.no>. + * Licensed under the same terms as the rest of Apache. + */ + @@ -1872,9 +1919,10 @@ unchanged: + +#endif /* AP_MPM_DEFAULT_H */ +/** @} */ -unchanged: ---- apache2.2/server/mpm/config.m4 2007-01-29 21:30:35.000000000 +0100 -+++ apache2.2/server/mpm/config.m4 +Index: httpd-2.2.11/server/mpm/config.m4 +=================================================================== +--- httpd-2.2.11.orig/server/mpm/config.m4 ++++ httpd-2.2.11/server/mpm/config.m4 @@ -1,7 +1,7 @@ AC_MSG_CHECKING(which MPM to use) AC_ARG_WITH(mpm, @@ -1884,7 +1932,7 @@ unchanged: APACHE_MPM=$withval ],[ if test "x$APACHE_MPM" = "x"; then -@@ -23,7 +23,7 @@ +@@ -23,7 +23,7 @@ ap_mpm_is_threaded () ap_mpm_is_experimental () { @@ -1893,7 +1941,7 @@ unchanged: return 0 else return 1 -@@ -66,6 +66,11 @@ +@@ -66,6 +66,11 @@ if ap_mpm_is_experimental; then else MPM_SUBDIR_NAME=$MPM_NAME fi @@ -1905,3 +1953,84 @@ unchanged: MPM_DIR=server/mpm/$MPM_SUBDIR_NAME MPM_LIB=$MPM_DIR/lib${MPM_NAME}.la +Index: httpd-2.2.11/include/http_request.h +=================================================================== +--- httpd-2.2.11.orig/include/http_request.h ++++ httpd-2.2.11/include/http_request.h +@@ -12,6 +12,12 @@ + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. ++ * ++ * Portions copyright 2005-2009 Steinar H. Gunderson <sgunderson@bigfoot.com>. ++ * Licensed under the same terms as the rest of Apache. ++ * ++ * Portions copyright 2008 Knut Auvor Grythe <knut@auvor.no>. ++ * Licensed under the same terms as the rest of Apache. + */ + + /** +@@ -350,6 +356,15 @@ AP_DECLARE_HOOK(int,auth_checker,(reques + */ + AP_DECLARE_HOOK(void,insert_filter,(request_rec *r)) + ++/** ++ * This hook allows modules to affect the request immediately after the ++ * per-directory configuration for the request has been generated. This allows ++ * modules to make decisions based upon the current directory configuration ++ * @param r The current request ++ * @return OK or DECLINED ++ */ ++AP_DECLARE_HOOK(int,post_perdir_config,(request_rec *r)) ++ + AP_DECLARE(int) ap_location_walk(request_rec *r); + AP_DECLARE(int) ap_directory_walk(request_rec *r); + AP_DECLARE(int) ap_file_walk(request_rec *r); +Index: httpd-2.2.11/server/request.c +=================================================================== +--- httpd-2.2.11.orig/server/request.c ++++ httpd-2.2.11/server/request.c +@@ -12,6 +12,12 @@ + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. ++ * ++ * Portions copyright 2005-2009 Steinar H. Gunderson <sgunderson@bigfoot.com>. ++ * Licensed under the same terms as the rest of Apache. ++ * ++ * Portions copyright 2008 Knut Auvor Grythe <knut@auvor.no>. ++ * Licensed under the same terms as the rest of Apache. + */ + + /* +@@ -61,6 +67,7 @@ APR_HOOK_STRUCT( + APR_HOOK_LINK(auth_checker) + APR_HOOK_LINK(insert_filter) + APR_HOOK_LINK(create_request) ++ APR_HOOK_LINK(post_perdir_config) + ) + + AP_IMPLEMENT_HOOK_RUN_FIRST(int,translate_name, +@@ -80,6 +87,8 @@ AP_IMPLEMENT_HOOK_RUN_FIRST(int,auth_che + AP_IMPLEMENT_HOOK_VOID(insert_filter, (request_rec *r), (r)) + AP_IMPLEMENT_HOOK_RUN_ALL(int, create_request, + (request_rec *r), (r), OK, DECLINED) ++AP_IMPLEMENT_HOOK_RUN_ALL(int,post_perdir_config, ++ (request_rec *r), (r), OK, DECLINED) + + + static int decl_die(int status, char *phase, request_rec *r) +@@ -158,6 +167,13 @@ AP_DECLARE(int) ap_process_request_inter + return access_status; + } + ++ /* First chance to handle the request after per-directory configuration is ++ * generated ++ */ ++ if ((access_status = ap_run_post_perdir_config(r))) { ++ return access_status; ++ } ++ + /* Only on the main request! */ + if (r->main == NULL) { + if ((access_status = ap_run_header_parser(r))) { |