summaryrefslogtreecommitdiff
path: root/2.0
diff options
context:
space:
mode:
authorChristian Heim <phreak@gentoo.org>2007-06-02 08:31:20 +0000
committerChristian Heim <phreak@gentoo.org>2007-06-02 08:31:20 +0000
commit10e17784a97a82fce812fcef80c7884415e35b65 (patch)
treee7ca7e25d5721d14a4cdb55c1d2edcdad61e2f0c /2.0
parentUse the IP for localhost, trying to fix bug #179918. (diff)
downloadapache-10e17784a97a82fce812fcef80c7884415e35b65.tar.gz
apache-10e17784a97a82fce812fcef80c7884415e35b65.tar.bz2
apache-10e17784a97a82fce812fcef80c7884415e35b65.zip
Updated itk patch.
Diffstat (limited to '2.0')
-rw-r--r--2.0/patches/08_all_itk-0.1-droppriv.patch62
-rw-r--r--2.0/patches/08_all_itk-20070425-00.patch (renamed from 2.0/patches/08_all_itk-0.1-base.patch)381
2 files changed, 237 insertions, 206 deletions
diff --git a/2.0/patches/08_all_itk-0.1-droppriv.patch b/2.0/patches/08_all_itk-0.1-droppriv.patch
deleted file mode 100644
index f76012a..0000000
--- a/2.0/patches/08_all_itk-0.1-droppriv.patch
+++ /dev/null
@@ -1,62 +0,0 @@
-diff -ur build-tree.orig/apache2/server/mpm/config.m4 build-tree/apache2/server/mpm/config.m4
---- build-tree.orig/apache2/server/mpm/config.m4 2005-08-05 19:58:29.000000000 +0200
-+++ build-tree/apache2/server/mpm/config.m4 2005-08-05 20:01:29.000000000 +0200
-@@ -29,6 +29,8 @@
- if test "$MPM_NAME" = "leader" -o "$MPM_NAME" = "threadpool" -o "$MPM_NAME" = "perchild" -o "$MPM_NAME" = "itk"; then
- AC_MSG_WARN(You have selected an EXPERIMENTAL MPM. Be warned!)
- MPM_SUBDIR_NAME=experimental/$MPM_NAME
-+
-+ AC_CHECK_LIB(cap, cap_init)
- else
- MPM_SUBDIR_NAME=$MPM_NAME
- fi
-diff -ur build-tree.orig/apache2/server/mpm/experimental/itk/itk.c build-tree/apache2/server/mpm/experimental/itk/itk.c
---- build-tree.orig/apache2/server/mpm/experimental/itk/itk.c 2005-08-05 19:58:29.000000000 +0200
-+++ build-tree/apache2/server/mpm/experimental/itk/itk.c 2005-08-05 20:09:12.000000000 +0200
-@@ -62,6 +62,9 @@
- #ifdef HAVE_SYS_PROCESSOR_H
- #include <sys/processor.h> /* for bindprocessor() */
- #endif
-+#if HAVE_LIBCAP
-+#include <sys/capability.h>
-+#endif
-
- #include <signal.h>
- #include <sys/times.h>
-@@ -471,6 +474,13 @@
- ap_sb_handle_t *sbh;
- apr_status_t rv;
- apr_bucket_alloc_t *bucket_alloc;
-+#if HAVE_LIBCAP
-+ cap_t caps;
-+ cap_value_t suidcaps[] = {
-+ CAP_SETUID,
-+ CAP_SETGID
-+ };
-+#endif
-
- mpm_state = AP_MPMQ_STARTING; /* for benefit of any hooks that run as this
- * child initializes
-@@ -529,6 +539,22 @@
- pollset[i].reqevents = APR_POLLIN;
- }
-
-+#if HAVE_LIBCAP
-+ /* Drop as many privileges as we can. We'll still
-+ * access files with uid=0, and we can setuid() to anything, but
-+ * at least there's tons of other evilness (like loading kernel
-+ * modules) we can't do directly. (The setuid() capability will
-+ * go away automatically when we setuid() or exec() -- the former
-+ * is likely to come first.)
-+ */
-+ caps = cap_init();
-+ cap_clear(caps);
-+ cap_set_flag(caps, CAP_PERMITTED, sizeof(suidcaps)/sizeof(cap_value_t), suidcaps, CAP_SET);
-+ cap_set_flag(caps, CAP_EFFECTIVE, sizeof(suidcaps)/sizeof(cap_value_t), suidcaps, CAP_SET);
-+ cap_set_proc(caps);
-+ cap_free(caps);
-+#endif
-+
- mpm_state = AP_MPMQ_RUNNING;
-
- bucket_alloc = apr_bucket_alloc_create(pchild);
diff --git a/2.0/patches/08_all_itk-0.1-base.patch b/2.0/patches/08_all_itk-20070425-00.patch
index 842e6d8..80fcdd9 100644
--- a/2.0/patches/08_all_itk-0.1-base.patch
+++ b/2.0/patches/08_all_itk-20070425-00.patch
@@ -1,25 +1,25 @@
-diff -ruN -x configure -x '*~' -x build-tree.orig -x '*.rej' build-tree.orig/apache2/server/mpm/config.m4 build-tree/apache2/server/mpm/config.m4
---- build-tree.orig/apache2/server/mpm/config.m4 2003-03-11 08:07:52.000000000 +0100
-+++ build-tree/apache2/server/mpm/config.m4 2004-09-06 14:29:32.000000000 +0200
+unchanged:
+---
+ server/mpm/config.m4 | 9
+ server/mpm/experimental/itk/Makefile.in | 5
+ server/mpm/experimental/itk/config.m4 | 3
+ server/mpm/experimental/itk/itk.c | 1560 ++++++++++++++++++++++++++++++
+ server/mpm/experimental/itk/mpm.h | 54 +
+ server/mpm/experimental/itk/mpm_default.h | 68 +
+ 6 files changed, 1697 insertions(+), 2 deletions(-)
+
+--- a/server/mpm/config.m4
++++ b/server/mpm/config.m4
@@ -1,7 +1,7 @@
AC_MSG_CHECKING(which MPM to use)
AC_ARG_WITH(mpm,
APACHE_HELP_STRING(--with-mpm=MPM,Choose the process model for Apache to use.
- MPM={beos|worker|prefork|mpmt_os2|perchild|peruser|leader|threadpool}),[
-+ MPM={beos|worker|prefork|mpmt_os2|perchild|peruser|leader|threadpool|itk}),[
++ MPM={beos|worker|prefork|mpmt_os2|perchild|peruser|leader|threadpool,itk}),[
APACHE_MPM=$withval
],[
if test "x$APACHE_MPM" = "x"; then
-@@ -12,7 +12,7 @@
-
- apache_cv_mpm=$APACHE_MPM
-
--if test "$apache_cv_mpm" = "worker" -o "$apache_cv_mpm" = "perchild" -o "$apache_cv_mpm" = "leader" -o "$apache_cv_mpm" = "threadpool" ; then
-+if test "$apache_cv_mpm" = "worker" -o "$apache_cv_mpm" = "perchild" -o "$apache_cv_mpm" = "leader" -o "$apache_cv_mpm" = "threadpool" -o "$apache_cv_mpm" = "itk"; then
- APR_CHECK_APR_DEFINE(APR_HAS_THREADS)
-
- if test "x$ac_cv_define_APR_HAS_THREADS" = "xno"; then
-@@ -26,7 +26,7 @@
+@@ -26,12 +26,17 @@ fi
APACHE_FAST_OUTPUT(server/mpm/Makefile)
MPM_NAME=$apache_cv_mpm
@@ -28,28 +28,35 @@ diff -ruN -x configure -x '*~' -x build-tree.orig -x '*.rej' build-tree.orig/apa
AC_MSG_WARN(You have selected an EXPERIMENTAL MPM. Be warned!)
MPM_SUBDIR_NAME=experimental/$MPM_NAME
else
-diff -ruN -x configure -x '*~' -x build-tree.orig -x '*.rej' build-tree.orig/apache2/server/mpm/experimental/itk/Makefile.in build-tree/apache2/server/mpm/experimental/itk/Makefile.in
---- build-tree.orig/apache2/server/mpm/experimental/itk/Makefile.in 1970-01-01 01:00:00.000000000 +0100
-+++ build-tree/apache2/server/mpm/experimental/itk/Makefile.in 2004-09-06 14:29:32.000000000 +0200
+ MPM_SUBDIR_NAME=$MPM_NAME
+ fi
++
++if "$apache_cv_mpm" = "itk" ; then
++ AC_CHECK_LIB(cap, cap_init)
++fi
++
+ MPM_DIR=server/mpm/$MPM_SUBDIR_NAME
+ MPM_LIB=$MPM_DIR/lib${MPM_NAME}.la
+
+--- /dev/null
++++ b/server/mpm/experimental/itk/Makefile.in
@@ -0,0 +1,5 @@
+
+LTLIBRARY_NAME = libitk.la
+LTLIBRARY_SOURCES = itk.c
+
+include $(top_srcdir)/build/ltlib.mk
-diff -ruN -x configure -x '*~' -x build-tree.orig -x '*.rej' build-tree.orig/apache2/server/mpm/experimental/itk/config5.m4 build-tree/apache2/server/mpm/experimental/itk/config5.m4
---- build-tree.orig/apache2/server/mpm/experimental/itk/config5.m4 1970-01-01 01:00:00.000000000 +0100
-+++ build-tree/apache2/server/mpm/experimental/itk/config5.m4 2004-09-06 14:29:32.000000000 +0200
-@@ -0,0 +1,4 @@
-+ if test "$MPM_NAME" = "itk" ; then
-+ AC_CHECK_FUNCS(pthread_kill)
-+ APACHE_FAST_OUTPUT(server/mpm/$MPM_SUBDIR_NAME/Makefile)
-+ fi
-diff -ruN -x configure -x '*~' -x build-tree.orig -x '*.rej' build-tree.orig/apache2/server/mpm/experimental/itk/itk.c build-tree/apache2/server/mpm/experimental/itk/itk.c
---- build-tree.orig/apache2/server/mpm/experimental/itk/itk.c 1970-01-01 01:00:00.000000000 +0100
-+++ build-tree/apache2/server/mpm/experimental/itk/itk.c 2004-09-06 15:08:53.000000000 +0200
-@@ -0,0 +1,1479 @@
-+/* Copyright 1999-2004 The Apache Software Foundation
+--- /dev/null
++++ b/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
+--- /dev/null
++++ b/server/mpm/experimental/itk/itk.c
+@@ -0,0 +1,1560 @@
++/* Copyright 1999-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.
@@ -62,6 +69,9 @@ diff -ruN -x configure -x '*~' -x build-tree.orig -x '*.rej' build-tree.orig/apa
+ * 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-2007 Steinar H. Gunderson <sgunderson@bigfoot.com>.
++ * Licensed under the same terms as the rest of Apache.
+ */
+
+#include "apr.h"
@@ -72,8 +82,8 @@ diff -ruN -x configure -x '*~' -x build-tree.orig -x '*.rej' build-tree.orig/apa
+
+# define _DBG(text,par...) \
+ ap_log_error(APLOG_MARK, APLOG_WARNING, 0, NULL, \
-+ "(itkmpm: pid=%d uid=%d) %s(): " text, \
-+ getpid(), getuid(), __FUNCTION__, ##par, 0)
++ "(itkmpm: pid=%d uid=%d) %s(): " text, \
++ getpid(), getuid(), __FUNCTION__, par)
+
+#define APR_WANT_STDIO
+#define APR_WANT_STRFUNC
@@ -96,6 +106,7 @@ diff -ruN -x configure -x '*~' -x build-tree.orig -x '*.rej' build-tree.orig/apa
+#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 "scoreboard.h"
+#include "ap_mpm.h"
+#include "unixd.h"
@@ -114,6 +125,10 @@ diff -ruN -x configure -x '*~' -x build-tree.orig -x '*.rej' build-tree.orig/apa
+#include <sys/processor.h> /* for bindprocessor() */
+#endif
+
++#if HAVE_LIBCAP
++#include <sys/capability.h>
++#endif
++
+#include <signal.h>
+#include <sys/times.h>
+
@@ -201,6 +216,7 @@ diff -ruN -x configure -x '*~' -x build-tree.orig -x '*.rej' build-tree.orig/apa
+ gid_t gid;
+ char *username;
+ int max_clients_vhost;
++ int nice_value;
+} itk_server_conf;
+
+module AP_MODULE_DECLARE_DATA mpm_itk_module;
@@ -523,6 +539,15 @@ diff -ruN -x configure -x '*~' -x build-tree.orig -x '*.rej' build-tree.orig/apa
+ apr_status_t rv;
+ apr_bucket_alloc_t *bucket_alloc;
+
++#if HAVE_LIBCAP
++ cap_t caps;
++ cap_value_t suidcaps[] = {
++ CAP_SETUID,
++ CAP_SETGID,
++ CAP_SYS_NICE
++ };
++#endif
++
+ mpm_state = AP_MPMQ_STARTING; /* for benefit of any hooks that run as this
+ * child initializes
+ */
@@ -554,10 +579,6 @@ diff -ruN -x configure -x '*~' -x build-tree.orig -x '*.rej' build-tree.orig/apa
+ clean_child_exit(APEXIT_CHILDFATAL);
+ }
+
-+/* if (unixd_setup_child()) {
-+ clean_child_exit(APEXIT_CHILDFATAL);
-+ } */
-+
+ ap_run_child_init(pchild, ap_server_conf);
+
+ ap_create_sb_handle(&sbh, pchild, my_child_num, 0);
@@ -580,6 +601,22 @@ diff -ruN -x configure -x '*~' -x build-tree.orig -x '*.rej' build-tree.orig/apa
+ pollset[i].reqevents = APR_POLLIN;
+ }
+
++#if HAVE_LIBCAP
++ /* Drop as many privileges as we can. We'll still
++ * access files with uid=0, and we can setuid() to anything, but
++ * at least there's tons of other evilness (like loading kernel
++ * modules) we can't do directly. (The setuid() capability will
++ * go away automatically when we setuid() or exec() -- the former
++ * is likely to come first.)
++ */
++ caps = cap_init();
++ cap_clear(caps);
++ cap_set_flag(caps, CAP_PERMITTED, sizeof(suidcaps)/sizeof(cap_value_t), suidcaps, CAP_SET);
++ cap_set_flag(caps, CAP_EFFECTIVE, sizeof(suidcaps)/sizeof(cap_value_t), suidcaps, CAP_SET);
++ cap_set_proc(caps);
++ cap_free(caps);
++#endif
++
+ mpm_state = AP_MPMQ_RUNNING;
+
+ bucket_alloc = apr_bucket_alloc_create(pchild);
@@ -669,28 +706,36 @@ diff -ruN -x configure -x '*~' -x build-tree.orig -x '*.rej' build-tree.orig/apa
+ * We now have a connection, so set it up with the appropriate
+ * socket options, file descriptors, and read/write buffers.
+ */
-+ {
-+ pid_t pid = fork();
-+ int status;
-+ switch (pid) {
-+ case -1:
-+ ap_log_error(APLOG_MARK, APLOG_ERR, errno, NULL, "fork: Unable to fork new process");
-+ break;
-+ case 0: /* child */
-+ current_conn = ap_run_create_connection(ptrans, ap_server_conf, csd, my_child_num, sbh, bucket_alloc);
-+ if (current_conn) {
-+ ap_process_connection(current_conn, csd);
-+ ap_lingering_close(current_conn);
-+ }
-+ exit(0);
-+ default: /* parent; just wait for child to be done */
-+ if (waitpid(pid, &status, 0) != pid || !WIFEXITED(status)) {
-+ ap_log_error(APLOG_MARK, APLOG_ERR, errno, NULL, "waitpid() failed");
-+ clean_child_exit(1);
-+ }
-+ break;
-+ }
-+ }
++
++ {
++ pid_t pid = fork();
++ int status;
++ switch (pid) {
++ case -1:
++ ap_log_error(APLOG_MARK, APLOG_ERR, errno, NULL, "fork: Unable to fork new process");
++ break;
++ case 0: /* child */
++ apr_proc_mutex_child_init(&accept_mutex, ap_lock_fname, pchild);
++ current_conn = ap_run_create_connection(ptrans, ap_server_conf, csd, my_child_num, sbh, bucket_alloc);
++ if (current_conn) {
++ ap_process_connection(current_conn, csd);
++ ap_lingering_close(current_conn);
++ }
++ exit(0);
++ default: /* parent; just wait for child to be done */
++ if (waitpid(pid, &status, 0) != 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) {
++ ap_log_error(APLOG_MARK, APLOG_ERR, 0, ap_server_conf, "child exited with non-zero exit status %u", WEXITSTATUS(status));
++ } else {
++ ap_log_error(APLOG_MARK, APLOG_ERR, errno, NULL, "waitpid() failed");
++ }
++ clean_child_exit(1);
++ }
++ break;
++ }
++ }
+
+ /* Check the pod and the generation number after processing a
+ * connection so that we'll go away if a graceful restart occurred
@@ -708,9 +753,9 @@ diff -ruN -x configure -x '*~' -x build-tree.orig -x '*.rej' build-tree.orig/apa
+ die_now = 1;
+ }
+
-+ /* if we have already setuid(), die (we can't be used anyhow) */
-+ if (getuid())
-+ die_now = 1;
++ /* if we have already setuid(), die (we can't be used anyhow) */
++ if (getuid())
++ die_now = 1;
+ }
+ clean_child_exit(0);
+}
@@ -1285,54 +1330,74 @@ diff -ruN -x configure -x '*~' -x build-tree.orig -x '*.rej' build-tree.orig/apa
+
+static int itk_post_read(request_rec *r)
+{
-+ itk_server_conf *sconf =
-+ (itk_server_conf *) ap_get_module_config(r->server->module_config, &mpm_itk_module);
-+
-+ /* Enforce MaxClientsVhost. */
-+ if (sconf->max_clients_vhost > 0) {
-+ int i, num_other_servers = 0;
-+ for (i = 0; i < ap_daemons_limit; ++i) {
-+ worker_score *ws = &ap_scoreboard_image->servers[i][0];
-+ if (ws->status >= SERVER_BUSY_READ && strncmp(ws->vhost, r->server->server_hostname, 31) == 0)
-+ ++num_other_servers;
-+ }
++ 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);
++
++ /* Enforce MaxClientsVhost. */
++ if (sconf->max_clients_vhost > 0) {
++ int i, num_other_servers = 0;
++ for (i = 0; i < ap_daemons_limit; ++i) {
++ worker_score *ws = &ap_scoreboard_image->servers[i][0];
++ if (ws->status >= SERVER_BUSY_READ && strncmp(ws->vhost, r->server->server_hostname, 31) == 0)
++ ++num_other_servers;
++ }
+
-+ if (num_other_servers > sconf->max_clients_vhost) {
-+ ap_log_error(APLOG_MARK, APLOG_WARNING, 0, NULL, \
-+ "MaxClientsVhost reached for %s, refusing client.",
-+ r->server->server_hostname);
-+ return HTTP_SERVICE_UNAVAILABLE;
-+ }
-+ }
-+ 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 (sconf->uid != -1 && sconf->gid != -1 && (getuid() != sconf->uid || getgid() != sconf->gid)) {
-+ int err = 0;
-+ if (setgid(sconf->gid)) {
-+ _DBG("setgid(): %s", strerror(errno));
-+ err = 1;
-+ } else if (initgroups(sconf->username, sconf->gid)) {
-+ _DBG("initgroups(): %s", strerror(errno));
-+ err = 1;
-+ } else if (setuid(sconf->uid)) {
-+ _DBG("setuid(): %s", strerror(errno));
-+ err = 1;
-+ }
++ if (num_other_servers > sconf->max_clients_vhost) {
++ ap_log_error(APLOG_MARK, APLOG_WARNING, 0, NULL, \
++ "MaxClientsVhost reached for %s, refusing client.",
++ r->server->server_hostname);
++ return HTTP_SERVICE_UNAVAILABLE;
++ }
++ }
+
-+ /*
-+ * Most likely a case of switching uid/gid within a persistent
-+ * connection; the RFCs allow us to just close the connection
-+ * at anytime, so we excercise our right. :-)
-+ */
-+ if (err) {
-+ ap_log_error(APLOG_MARK, APLOG_WARNING, 0, NULL, \
-+ "Couldn't set uid/gid, closing connection.");
-+ ap_lingering_close(r->connection);
-+ exit(0);
-+ }
-+ }
-+ return OK;
++ 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)) {
++ _DBG("setpriority(): %s", strerror(errno));
++ err = 1;
++ }
++
++ wanted_uid = sconf->uid;
++ wanted_gid = sconf->gid;
++ wanted_username = sconf->username;
++
++ if (wanted_uid == -1 || wanted_gid == -1) {
++ wanted_uid = unixd_config.user_id;
++ wanted_gid = unixd_config.group_id;
++ wanted_username = unixd_config.user_name;
++ }
++
++ if (!err && wanted_uid != -1 && wanted_gid != -1 && (getuid() != wanted_uid || getgid() != wanted_gid)) {
++ if (setgid(wanted_gid)) {
++ _DBG("setgid(): %s", strerror(errno));
++ err = 1;
++ } else if (initgroups(wanted_username, wanted_gid)) {
++ _DBG("initgroups(): %s", strerror(errno));
++ err = 1;
++ } else if (setuid(wanted_uid)) {
++ _DBG("setuid(): %s", strerror(errno));
++ err = 1;
++ }
++ }
++
++ /*
++ * Most likely a case of switching uid/gid within a persistent
++ * connection; the RFCs allow us to just close the connection
++ * at anytime, so we excercise our right. :-)
++ */
++ if (err) {
++ ap_log_error(APLOG_MARK, APLOG_WARNING, 0, NULL, \
++ "Couldn't set uid/gid/priority, closing connection.");
++ ap_lingering_close(r->connection);
++ exit(0);
++ }
++ return OK;
+}
+
+static void itk_hooks(apr_pool_t *p)
@@ -1355,7 +1420,6 @@ diff -ruN -x configure -x '*~' -x build-tree.orig -x '*.rej' build-tree.orig/apa
+
+ /* set the uid as fast as possible */
+ ap_hook_post_read_request(itk_post_read, NULL, NULL, APR_HOOK_REALLY_FIRST);
-+
+}
+
+static const char *set_daemons_to_start(cmd_parms *cmd, void *dummy, const char *arg)
@@ -1470,22 +1534,43 @@ diff -ruN -x configure -x '*~' -x build-tree.orig -x '*.rej' build-tree.orig/apa
+
+static const char *assign_user_id (cmd_parms *cmd, void *dummy, 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);
-+ return NULL;
++ 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);
++ return NULL;
+}
+
+static const char *set_max_clients_vhost (cmd_parms *cmd, void *dummy, const char *arg)
+{
-+ itk_server_conf *sconf =
-+ (itk_server_conf *) ap_get_module_config(cmd->server->module_config, &mpm_itk_module);
-+ sconf->max_clients_vhost = atoi(arg);
-+ return NULL;
-+}
++ itk_server_conf *sconf =
++ (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)
++{
++ itk_server_conf *sconf =
++ (itk_server_conf *) ap_get_module_config(cmd->server->module_config, &mpm_itk_module);
++ int nice_value = atoi(arg);
++
++ if (nice_value < -20) {
++ ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,
++ "WARNING: NiceValue of %d is below -20, increasing NiceValue to -20.",
++ nice_value);
++ nice_value = -20;
++ }
++ else if (nice_value > 19) {
++ ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,
++ "WARNING: NiceValue of %d is above 19, lowering NiceValue to 19.",
++ nice_value);
++ nice_value = 19;
++ }
++ sconf->nice_value = nice_value;
++ return NULL;
++}
+
+static const command_rec itk_cmds[] = {
+UNIX_DAEMON_COMMANDS,
@@ -1504,35 +1589,37 @@ diff -ruN -x configure -x '*~' -x build-tree.orig -x '*.rej' build-tree.orig/apa
+ "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,
++ "Set nice value for the given vhost, from -20 (highest priority) to 19 (lowest priority)."),
+{ NULL }
+};
+
-+/* == allocate an private server config structure == */
++/* == allocate a private server config structure == */
+static void *itk_create_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;
-+ return c;
++ 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_config, /* create per-server config structure */
+ NULL, /* merge per-server config structures */
-+ itk_cmds, /* command apr_table_t */
-+ itk_hooks, /* register hooks */
++ itk_cmds, /* command apr_table_t */
++ itk_hooks, /* register hooks */
+};
-diff -ruN -x configure -x '*~' -x build-tree.orig -x '*.rej' build-tree.orig/apache2/server/mpm/experimental/itk/mpm.h build-tree/apache2/server/mpm/experimental/itk/mpm.h
---- build-tree.orig/apache2/server/mpm/experimental/itk/mpm.h 1970-01-01 01:00:00.000000000 +0100
-+++ build-tree/apache2/server/mpm/experimental/itk/mpm.h 2004-09-06 14:29:32.000000000 +0200
-@@ -0,0 +1,50 @@
-+/* Copyright 2000-2004 The Apache Software Foundation
+--- /dev/null
++++ b/server/mpm/experimental/itk/mpm.h
+@@ -0,0 +1,54 @@
++/* Copyright 2000-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.
@@ -1545,6 +1632,9 @@ diff -ruN -x configure -x '*~' -x build-tree.orig -x '*.rej' build-tree.orig/apa
+ * 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-2007 Steinar H. Gunderson <sgunderson@bigfoot.com>.
++ * Licensed under the same terms as the rest of Apache.
+ */
+
+#include "httpd.h"
@@ -1552,12 +1642,12 @@ diff -ruN -x configure -x '*~' -x build-tree.orig -x '*.rej' build-tree.orig/apa
+#include "scoreboard.h"
+#include "unixd.h"
+
-+#ifndef APACHE_MPM_PREFORK_H
-+#define APACHE_MPM_PREFORK_H
++#ifndef APACHE_MPM_ITK_H
++#define APACHE_MPM_ITK_H
+
-+#define PREFORK_MPM
++#define ITK_MPM
+
-+#define MPM_NAME "Prefork"
++#define MPM_NAME "ITK"
+
+#define AP_MPM_WANT_RECLAIM_CHILD_PROCESSES
+#define AP_MPM_WANT_WAIT_OR_TIMEOUT
@@ -1581,12 +1671,12 @@ diff -ruN -x configure -x '*~' -x build-tree.orig -x '*.rej' build-tree.orig/apa
+extern int ap_threads_per_child;
+extern int ap_max_daemons_limit;
+extern server_rec *ap_server_conf;
-+#endif /* APACHE_MPM_PREFORK_H */
-diff -ruN -x configure -x '*~' -x build-tree.orig -x '*.rej' build-tree.orig/apache2/server/mpm/experimental/itk/mpm_default.h build-tree/apache2/server/mpm/experimental/itk/mpm_default.h
---- build-tree.orig/apache2/server/mpm/experimental/itk/mpm_default.h 1970-01-01 01:00:00.000000000 +0100
-+++ build-tree/apache2/server/mpm/experimental/itk/mpm_default.h 2004-09-06 14:29:32.000000000 +0200
-@@ -0,0 +1,64 @@
-+/* Copyright 1999-2004 The Apache Software Foundation
++#endif /* APACHE_MPM_ITK_H */
+--- /dev/null
++++ b/server/mpm/experimental/itk/mpm_default.h
+@@ -0,0 +1,68 @@
++/* Copyright 1999-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.
@@ -1599,6 +1689,9 @@ diff -ruN -x configure -x '*~' -x build-tree.orig -x '*.rej' build-tree.orig/apa
+ * 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-2007 Steinar H. Gunderson <sgunderson@bigfoot.com>.
++ * Licensed under the same terms as the rest of Apache.
+ */
+
+#ifndef APACHE_MPM_DEFAULT_H