[Pkg-apache-commits] [SCM] Debian packaging for apache2 (Apache HTTPD 2.x) branch, next, updated. 50d0d0f119911956b663095a8ee9502f5003931d

Stefan Fritsch sf at sfritsch.de
Sun Apr 15 10:03:43 UTC 2012


The following commit has been merged in the next branch:
commit 50d0d0f119911956b663095a8ee9502f5003931d
Author: Stefan Fritsch <sf at sfritsch.de>
Date:   Sun Apr 15 11:23:15 2012 +0200

    Re-add the ITK MPM.
    
    The build process can probably be made more elegant, but for now it
    seems to work

diff --git a/debian/apache2.NEWS b/debian/apache2.NEWS
index 3f5f39b..99942a0 100644
--- a/debian/apache2.NEWS
+++ b/debian/apache2.NEWS
@@ -14,8 +14,8 @@ apache2 (2.4.1-1) experimental; urgency=low
   provide backward compatibility.
 
   Furthermore, MPMs are simple modules now. Thus, the MPM can be changed anytime
-  by (un-)loading a specific module. Note the ITK MPM is not available anymore.
-  Be careful when upgrading. An example of changing the MPM is given below
+  by (un-)loading a specific module. Be careful when upgrading. An example of
+  changing the MPM is given below
 
   a2dismod mpm_worker
   a2enmod mpm_prefork
diff --git a/debian/apache2.postinst b/debian/apache2.postinst
index 645d2d6..fbc9178 100644
--- a/debian/apache2.postinst
+++ b/debian/apache2.postinst
@@ -173,9 +173,7 @@ enable_default_mpm()
 			;;
 
 			apache2-mpm-itk)
-				# Houston, we got a problem
-				# XXX: Maybe display a big warning?
-				mpm="mpm_prefork"
+				mpm="mpm_itk"
 			;;
 
 			*)
diff --git a/debian/changelog b/debian/changelog
index ff64b29..56d4002 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -35,6 +35,7 @@ apache2 (2.4.1-4) experimental; urgency=low
     directories. Closes: #548213
   * Change the compiled in default of DocumentRoot to /var/www by updating
     fhs_compliance.patch
+  * Re-add mpm_itk (version 2.4.1-pre01). This is still very experimental!
 
  -- Arno Töll <arno at debian.org>  Sun, 15 Apr 2012 03:14:33 +0200
 
diff --git a/debian/clean b/debian/clean
index 650d647..312c929 100644
--- a/debian/clean
+++ b/debian/clean
@@ -14,5 +14,4 @@ debian/a2query
 debian/manpages/a2query.8
 debian/manpages/dh_apache2.1
 debian/debhelper/dh_apache2
-support/suexec-custom.c
 config.nice
diff --git a/debian/config-dir/mods-available/mpm_event.load b/debian/config-dir/mods-available/mpm_event.load
index 5bb4ba4..05009c3 100644
--- a/debian/config-dir/mods-available/mpm_event.load
+++ b/debian/config-dir/mods-available/mpm_event.load
@@ -1,2 +1,2 @@
-# Conflicts: mpm_wprker mpm_prefork
+# Conflicts: mpm_wprker mpm_prefork mpm_itk
 LoadModule mpm_event_module /usr/lib/apache2/modules/mod_mpm_event.so
diff --git a/debian/config-dir/mods-available/mpm_prefork.conf b/debian/config-dir/mods-available/mpm_itk.conf
similarity index 91%
copy from debian/config-dir/mods-available/mpm_prefork.conf
copy to debian/config-dir/mods-available/mpm_itk.conf
index 300caff..31609aa 100644
--- a/debian/config-dir/mods-available/mpm_prefork.conf
+++ b/debian/config-dir/mods-available/mpm_itk.conf
@@ -1,11 +1,11 @@
-# prefork MPM
+# itk MPM
 # StartServers: number of server processes to start
 # MinSpareServers: minimum number of server processes which are kept spare
 # MaxSpareServers: maximum number of server processes which are kept spare
 # MaxRequestWorkers: maximum number of server processes allowed to start
 # MaxConnectionsPerChild: maximum number of requests a server process serves
-
-<IfModule mpm_prefork_module>
+# XXX adjust!
+<IfModule mpm_itk_module>
     StartServers             5
     MinSpareServers          5
     MaxSpareServers         10
diff --git a/debian/config-dir/mods-available/mpm_itk.load b/debian/config-dir/mods-available/mpm_itk.load
new file mode 100644
index 0000000..d9203f1
--- /dev/null
+++ b/debian/config-dir/mods-available/mpm_itk.load
@@ -0,0 +1,2 @@
+# Conflicts: mpm_event mpm_worker mpm_prefork
+LoadModule mpm_itk_module /usr/lib/apache2/modules/mod_mpm_itk.so
diff --git a/debian/config-dir/mods-available/mpm_prefork.load b/debian/config-dir/mods-available/mpm_prefork.load
index 05da7a3..3142c44 100644
--- a/debian/config-dir/mods-available/mpm_prefork.load
+++ b/debian/config-dir/mods-available/mpm_prefork.load
@@ -1,2 +1,2 @@
-# Conflicts: mpm_event mpm_worker
+# Conflicts: mpm_event mpm_worker mpm_itk
 LoadModule mpm_prefork_module /usr/lib/apache2/modules/mod_mpm_prefork.so
diff --git a/debian/config-dir/mods-available/mpm_worker.load b/debian/config-dir/mods-available/mpm_worker.load
index f9d0c4d..6357ab9 100644
--- a/debian/config-dir/mods-available/mpm_worker.load
+++ b/debian/config-dir/mods-available/mpm_worker.load
@@ -1,2 +1,2 @@
-# Conflicts: mpm_event mpm_prefork
+# Conflicts: mpm_event mpm_prefork mpm_itk
 LoadModule mpm_worker_module /usr/lib/apache2/modules/mod_mpm_worker.so
diff --git a/debian/control b/debian/control
index ed772ba..6877f3b 100644
--- a/debian/control
+++ b/debian/control
@@ -89,7 +89,14 @@ Description: transitional event MPM package for apache2
  This is a transitional package to apache2 for users of apache2-mpm-event and
  can be safely removed after the  installation is complete.
 
-#XXX: apache2-mpm-itk transitional?
+Package: apache2-mpm-itk
+Architecture: any
+Section: oldlibs
+Priority: extra
+Depends: ${misc:Depends}, apache2 (= ${binary:Version})
+Description: transitional itk MPM package for apache2
+ This is a transitional package to apache2 for users of apache2-mpm-itk and
+ can be safely removed after the installation is complete.
 
 Package: apache2.2-bin
 Architecture: any
diff --git a/debian/patches/itk/02-rename-prefork-to-itk.patch b/debian/patches/itk/02-rename-prefork-to-itk.patch
new file mode 100644
index 0000000..19c76de
--- /dev/null
+++ b/debian/patches/itk/02-rename-prefork-to-itk.patch
@@ -0,0 +1,294 @@
+Rename prefork to itk in the copy that was created in 01-copy-prefork.patch.
+
+Index: httpd-2.4.1/server/mpm/itk/config.m4
+===================================================================
+--- httpd-2.4.1.orig/server/mpm/itk/config.m4
++++ httpd-2.4.1/server/mpm/itk/config.m4
+@@ -1,7 +1,7 @@
+-AC_MSG_CHECKING(if prefork MPM supports this platform)
++AC_MSG_CHECKING(if itk MPM supports this platform)
+ if test $forking_mpms_supported != yes; then
+     AC_MSG_RESULT(no - This is not a forking platform)
+ else
+     AC_MSG_RESULT(yes)
+-    APACHE_MPM_SUPPORTED(prefork, yes, no)
++    APACHE_MPM_SUPPORTED(itk, yes, no)
+ fi
+Index: httpd-2.4.1/server/mpm/itk/config3.m4
+===================================================================
+--- httpd-2.4.1.orig/server/mpm/itk/config3.m4
++++ httpd-2.4.1/server/mpm/itk/config3.m4
+@@ -1 +1 @@
+-APACHE_MPM_MODULE(prefork, $enable_mpm_prefork)
++APACHE_MPM_MODULE(itk, $enable_mpm_itk)
+Index: httpd-2.4.1/server/mpm/itk/itk.c
+===================================================================
+--- httpd-2.4.1.orig/server/mpm/itk/itk.c
++++ httpd-2.4.1/server/mpm/itk/itk.c
+@@ -95,11 +95,11 @@ static int server_limit = 0;
+ static int mpm_state = AP_MPMQ_STARTING;
+ static ap_pod_t *pod;
+ 
+-/* data retained by prefork across load/unload of the module
++/* data retained by itk across load/unload of the module
+  * allocated on first call to pre-config hook; located on
+  * subsequent calls to pre-config hook
+  */
+-typedef struct prefork_retained_data {
++typedef struct itk_retained_data {
+     int first_server_limit;
+     int module_loads;
+     ap_generation_t my_generation;
+@@ -122,8 +122,8 @@ typedef struct prefork_retained_data {
+ #define MAX_SPAWN_RATE  (32)
+ #endif
+     int hold_off_on_exponential_spawning;
+-} prefork_retained_data;
+-static prefork_retained_data *retained;
++} itk_retained_data;
++static itk_retained_data *retained;
+ 
+ #define MPM_CHILD_PID(i) (ap_scoreboard_image->parent[i].pid)
+ 
+@@ -189,7 +189,7 @@ static void chdir_for_gprof(void)
+ #define chdir_for_gprof()
+ #endif
+ 
+-static void prefork_note_child_killed(int childnum, pid_t pid,
++static void itk_note_child_killed(int childnum, pid_t pid,
+                                       ap_generation_t gen)
+ {
+     AP_DEBUG_ASSERT(childnum != -1); /* no scoreboard squatting with this MPM */
+@@ -200,7 +200,7 @@ static void prefork_note_child_killed(in
+     ap_scoreboard_image->parent[childnum].pid = 0;
+ }
+ 
+-static void prefork_note_child_started(int slot, pid_t pid)
++static void itk_note_child_started(int slot, pid_t pid)
+ {
+     ap_scoreboard_image->parent[slot].pid = pid;
+     ap_run_child_status(ap_server_conf,
+@@ -219,7 +219,7 @@ static void clean_child_exit(int code)
+     }
+ 
+     if (one_process) {
+-        prefork_note_child_killed(/* slot */ 0, 0, 0);
++        itk_note_child_killed(/* slot */ 0, 0, 0);
+     }
+ 
+     ap_mpm_pod_close(pod);
+@@ -277,7 +277,7 @@ static void accept_mutex_off(void)
+ #define SAFE_ACCEPT(stmt) do {stmt;} while(0)
+ #endif
+ 
+-static int prefork_query(int query_code, int *result, apr_status_t *rv)
++static int itk_query(int query_code, int *result, apr_status_t *rv)
+ {
+     *rv = APR_SUCCESS;
+     switch(query_code){
+@@ -330,9 +330,9 @@ static int prefork_query(int query_code,
+     return OK;
+ }
+ 
+-static const char *prefork_get_name(void)
++static const char *itk_get_name(void)
+ {
+-    return "prefork";
++    return "itk";
+ }
+ 
+ /*****************************************************************
+@@ -735,7 +735,7 @@ static int make_child(server_rec *s, int
+         apr_signal(SIGQUIT, SIG_DFL);
+ #endif
+         apr_signal(SIGTERM, sig_term);
+-        prefork_note_child_started(slot, getpid());
++        itk_note_child_started(slot, getpid());
+         child_main(slot);
+         /* NOTREACHED */
+     }
+@@ -793,7 +793,7 @@ static int make_child(server_rec *s, int
+         child_main(slot);
+     }
+ 
+-    prefork_note_child_started(slot, pid);
++    itk_note_child_started(slot, pid);
+ 
+     return 0;
+ }
+@@ -914,7 +914,7 @@ static void perform_idle_server_maintena
+  * Executive routines.
+  */
+ 
+-static int prefork_run(apr_pool_t *_pconf, apr_pool_t *plog, server_rec *s)
++static int itk_run(apr_pool_t *_pconf, apr_pool_t *plog, server_rec *s)
+ {
+     int index;
+     int remaining_children_to_start;
+@@ -1029,7 +1029,7 @@ static int prefork_run(apr_pool_t *_pcon
+             if (child_slot >= 0) {
+                 (void) ap_update_child_status_from_indexes(child_slot, 0, SERVER_DEAD,
+                                                            (request_rec *) NULL);
+-                prefork_note_child_killed(child_slot, 0, 0);
++                itk_note_child_killed(child_slot, 0, 0);
+                 if (processed_status == APEXIT_CHILDSICK) {
+                     /* child detected a resource shortage (E[NM]FILE, ENOBUFS, etc)
+                      * cut the fork rate to the minimum
+@@ -1094,7 +1094,7 @@ static int prefork_run(apr_pool_t *_pcon
+             ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, APLOGNO(00168) "killpg SIGTERM");
+         }
+         ap_reclaim_child_processes(1, /* Start with SIGTERM */
+-                                   prefork_note_child_killed);
++                                   itk_note_child_killed);
+ 
+         /* cleanup pid file on normal shutdown */
+         ap_remove_pid(pconf, ap_pid_fname);
+@@ -1128,7 +1128,7 @@ static int prefork_run(apr_pool_t *_pcon
+         }
+ 
+         /* Allow each child which actually finished to exit */
+-        ap_relieve_child_processes(prefork_note_child_killed);
++        ap_relieve_child_processes(itk_note_child_killed);
+ 
+         /* cleanup pid file */
+         ap_remove_pid(pconf, ap_pid_fname);
+@@ -1147,7 +1147,7 @@ static int prefork_run(apr_pool_t *_pcon
+             sleep(1);
+ 
+             /* Relieve any children which have now exited */
+-            ap_relieve_child_processes(prefork_note_child_killed);
++            ap_relieve_child_processes(itk_note_child_killed);
+ 
+             active_children = 0;
+             for (index = 0; index < ap_daemons_limit; ++index) {
+@@ -1216,7 +1216,7 @@ static int prefork_run(apr_pool_t *_pcon
+             ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, APLOGNO(00172) "killpg SIGHUP");
+         }
+         ap_reclaim_child_processes(0, /* Not when just starting up */
+-                                   prefork_note_child_killed);
++                                   itk_note_child_killed);
+         ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf, APLOGNO(00173)
+                     "SIGHUP received.  Attempting to restart");
+     }
+@@ -1227,7 +1227,7 @@ static int prefork_run(apr_pool_t *_pcon
+ /* This really should be a post_config hook, but the error log is already
+  * redirected by that point, so we need to do this in the open_logs phase.
+  */
+-static int prefork_open_logs(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *s)
++static int itk_open_logs(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *s)
+ {
+     int startup = 0;
+     int level_flags = 0;
+@@ -1257,11 +1257,11 @@ static int prefork_open_logs(apr_pool_t
+     return OK;
+ }
+ 
+-static int prefork_pre_config(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp)
++static int itk_pre_config(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp)
+ {
+     int no_detach, debug, foreground;
+     apr_status_t rv;
+-    const char *userdata_key = "mpm_prefork_module";
++    const char *userdata_key = "mpm_itk_module";
+ 
+     mpm_state = AP_MPMQ_STARTING;
+ 
+@@ -1315,7 +1315,7 @@ static int prefork_pre_config(apr_pool_t
+     return OK;
+ }
+ 
+-static int prefork_check_config(apr_pool_t *p, apr_pool_t *plog,
++static int itk_check_config(apr_pool_t *p, apr_pool_t *plog,
+                                 apr_pool_t *ptemp, server_rec *s)
+ {
+     int startup = 0;
+@@ -1401,7 +1401,7 @@ static int prefork_check_config(apr_pool
+         ap_daemons_limit = 1;
+     }
+ 
+-    /* ap_daemons_to_start > ap_daemons_limit checked in prefork_run() */
++    /* ap_daemons_to_start > ap_daemons_limit checked in itk_run() */
+     if (ap_daemons_to_start < 0) {
+         if (startup) {
+             ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL, APLOGNO(00184)
+@@ -1432,12 +1432,12 @@ static int prefork_check_config(apr_pool
+         ap_daemons_min_free = 1;
+     }
+ 
+-    /* ap_daemons_max_free < ap_daemons_min_free + 1 checked in prefork_run() */
++    /* ap_daemons_max_free < ap_daemons_min_free + 1 checked in itk_run() */
+ 
+     return OK;
+ }
+ 
+-static void prefork_hooks(apr_pool_t *p)
++static void itk_hooks(apr_pool_t *p)
+ {
+     /* Our open_logs hook function must run before the core's, or stderr
+      * will be redirected to a file, and the messages won't print to the
+@@ -1445,15 +1445,15 @@ static void prefork_hooks(apr_pool_t *p)
+      */
+     static const char *const aszSucc[] = {"core.c", NULL};
+ 
+-    ap_hook_open_logs(prefork_open_logs, NULL, aszSucc, APR_HOOK_REALLY_FIRST);
++    ap_hook_open_logs(itk_open_logs, NULL, aszSucc, APR_HOOK_REALLY_FIRST);
+     /* we need to set the MPM state before other pre-config hooks use MPM query
+      * to retrieve it, so register as REALLY_FIRST
+      */
+-    ap_hook_pre_config(prefork_pre_config, NULL, NULL, APR_HOOK_REALLY_FIRST);
+-    ap_hook_check_config(prefork_check_config, NULL, NULL, APR_HOOK_MIDDLE);
+-    ap_hook_mpm(prefork_run, NULL, NULL, APR_HOOK_MIDDLE);
+-    ap_hook_mpm_query(prefork_query, NULL, NULL, APR_HOOK_MIDDLE);
+-    ap_hook_mpm_get_name(prefork_get_name, NULL, NULL, APR_HOOK_MIDDLE);
++    ap_hook_pre_config(itk_pre_config, NULL, NULL, APR_HOOK_REALLY_FIRST);
++    ap_hook_check_config(itk_check_config, NULL, NULL, APR_HOOK_MIDDLE);
++    ap_hook_mpm(itk_run, NULL, NULL, APR_HOOK_MIDDLE);
++    ap_hook_mpm_query(itk_query, NULL, NULL, APR_HOOK_MIDDLE);
++    ap_hook_mpm_get_name(itk_get_name, NULL, NULL, APR_HOOK_MIDDLE);
+ }
+ 
+ static const char *set_daemons_to_start(cmd_parms *cmd, void *dummy, const char *arg)
+@@ -1515,7 +1515,7 @@ static const char *set_server_limit (cmd
+     return NULL;
+ }
+ 
+-static const command_rec prefork_cmds[] = {
++static const command_rec itk_cmds[] = {
+ LISTEN_COMMANDS,
+ AP_INIT_TAKE1("StartServers", set_daemons_to_start, NULL, RSRC_CONF,
+               "Number of child processes launched at server startup"),
+@@ -1533,13 +1533,13 @@ AP_GRACEFUL_SHUTDOWN_TIMEOUT_COMMAND,
+ { NULL }
+ };
+ 
+-AP_DECLARE_MODULE(mpm_prefork) = {
++AP_DECLARE_MODULE(mpm_itk) = {
+     MPM20_MODULE_STUFF,
+     NULL,                       /* hook to run before apache parses args */
+     NULL,                       /* create per-directory config structure */
+     NULL,                       /* merge per-directory config structures */
+     NULL,                       /* create per-server config structure */
+     NULL,                       /* merge per-server config structures */
+-    prefork_cmds,               /* command apr_table_t */
+-    prefork_hooks,              /* register hooks */
++    itk_cmds,                   /* command apr_table_t */
++    itk_hooks,                  /* register hooks */
+ };
+Index: httpd-2.4.1/server/mpm/itk/mpm_default.h
+===================================================================
+--- httpd-2.4.1.orig/server/mpm/itk/mpm_default.h
++++ httpd-2.4.1/server/mpm/itk/mpm_default.h
+@@ -15,10 +15,10 @@
+  */
+ 
+ /**
+- * @file  prefork/mpm_default.h
+- * @brief Prefork MPM defaults
++ * @file  itk/mpm_default.h
++ * @brief ITK MPM defaults
+  *
+- * @defgroup APACHE_MPM_PREFORK Prefork MPM
++ * @defgroup APACHE_MPM_ITK Apache ITK
+  * @ingroup APACHE_INTERNAL
+  * @{
+  */
diff --git a/debian/patches/itk/03-add-mpm-to-build-system.patch b/debian/patches/itk/03-add-mpm-to-build-system.patch
new file mode 100644
index 0000000..3e8a26e
--- /dev/null
+++ b/debian/patches/itk/03-add-mpm-to-build-system.patch
@@ -0,0 +1,27 @@
+Add the new MPM to the build system as an alternative to the other MPMs.
+
+Index: httpd-2.4.1/server/mpm/config2.m4
+===================================================================
+--- httpd-2.4.1.orig/server/mpm/config2.m4
++++ httpd-2.4.1/server/mpm/config2.m4
+@@ -1,7 +1,7 @@
+ AC_MSG_CHECKING(which MPM to use by default)
+ AC_ARG_WITH(mpm,
+ APACHE_HELP_STRING(--with-mpm=MPM,Choose the process model for Apache to use by default.
+-                          MPM={event|worker|prefork|winnt}
++                          MPM={event|worker|prefork|winnt|itk}
+                           This will be statically linked as the only available MPM unless
+                           --enable-mpms-shared is also specified.
+ ),[
+Index: httpd-2.4.1/modules/arch/unix/config5.m4
+===================================================================
+--- httpd-2.4.1.orig/modules/arch/unix/config5.m4
++++ httpd-2.4.1/modules/arch/unix/config5.m4
+@@ -3,6 +3,7 @@ APACHE_MODPATH_INIT(arch/unix)
+ 
+ if ap_mpm_is_enabled "worker" \
+    || ap_mpm_is_enabled "event" \
++   || ap_mpm_is_enabled "itk" \
+    || ap_mpm_is_enabled "prefork"; then
+     unixd_mods_enable=yes
+ else
diff --git a/debian/patches/itk/05-add-copyright.patch b/debian/patches/itk/05-add-copyright.patch
new file mode 100644
index 0000000..0528ec9
--- /dev/null
+++ b/debian/patches/itk/05-add-copyright.patch
@@ -0,0 +1,36 @@
+Add copyright notices, as the next patches are going to add code.
+
+Index: httpd-2.4.1/server/mpm/itk/itk.c
+===================================================================
+--- httpd-2.4.1.orig/server/mpm/itk/itk.c
++++ httpd-2.4.1/server/mpm/itk/itk.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-2012 Steinar H. Gunderson <sgunderson at bigfoot.com>.
++ * Licensed under the same terms as the rest of Apache.
++ *
++ * Portions copyright 2008 Knut Auvor Grythe <knut at auvor.no>.
++ * Licensed under the same terms as the rest of Apache.
+  */
+ 
+ #include "apr.h"
+Index: httpd-2.4.1/server/mpm/itk/mpm_default.h
+===================================================================
+--- httpd-2.4.1.orig/server/mpm/itk/mpm_default.h
++++ httpd-2.4.1/server/mpm/itk/mpm_default.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-2012 Steinar H. Gunderson <sgunderson at bigfoot.com>.
++ * Licensed under the same terms as the rest of Apache.
++ *
++ * Portions copyright 2008 Knut Auvor Grythe <knut at auvor.no>.
++ * Licensed under the same terms as the rest of Apache.
+  */
+ 
+ /**
diff --git a/debian/patches/itk/06-hook-just-after-merging-perdir-config.patch b/debian/patches/itk/06-hook-just-after-merging-perdir-config.patch
new file mode 100644
index 0000000..802256f
--- /dev/null
+++ b/debian/patches/itk/06-hook-just-after-merging-perdir-config.patch
@@ -0,0 +1,53 @@
+Add an extra hook right after merging per-directory configuration.
+This makes sure we are able to setuid() as early as possible (that
+is, as soon as know what uid/gid to use for this location), so we
+won't run all sorts of subrequests and other stuff as root.
+
+Index: httpd-2.4.1/server/request.c
+===================================================================
+--- httpd-2.4.1.orig/server/request.c
++++ httpd-2.4.1/server/request.c
+@@ -69,6 +69,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,
+@@ -91,6 +92,21 @@ AP_IMPLEMENT_HOOK_VOID(insert_filter, (r
+ AP_IMPLEMENT_HOOK_RUN_ALL(int, create_request,
+                           (request_rec *r), (r), OK, DECLINED)
+ 
++/**
++ * 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
++ *
++ * This hook is private to mpm-itk, so it is not exposed in http_request.h.
++ *
++ * @param r The current request
++ * @return OK or DECLINED
++ */
++AP_DECLARE_HOOK(int,post_perdir_config,(request_rec *r))
++
++AP_IMPLEMENT_HOOK_RUN_ALL(int,post_perdir_config,
++                          (request_rec *r), (r), OK, DECLINED)
++
+ static int auth_internal_per_conf = 0;
+ static int auth_internal_per_conf_hooks = 0;
+ static int auth_internal_per_conf_providers = 0;
+@@ -191,6 +207,13 @@ AP_DECLARE(int) ap_process_request_inter
+         r->log = d->log;
+     }
+ 
++    /* 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))) {
diff --git a/debian/patches/itk/07-base-functionality.patch b/debian/patches/itk/07-base-functionality.patch
new file mode 100644
index 0000000..d48edbb
--- /dev/null
+++ b/debian/patches/itk/07-base-functionality.patch
@@ -0,0 +1,229 @@
+Add the base functionality of mpm_itk over prefork; parse the new configuration
+options, fork on each new connection, and setuid() as required.
+
+Index: httpd-2.4.1/server/mpm/itk/itk.c
+===================================================================
+--- httpd-2.4.1.orig/server/mpm/itk/itk.c
++++ httpd-2.4.1/server/mpm/itk/itk.c
+@@ -26,6 +26,11 @@
+ #include "apr_thread_proc.h"
+ #include "apr_signal.h"
+ 
++# define _DBG(text,par...) \
++    ap_log_error(APLOG_MARK, APLOG_WARNING, 0, NULL, \
++                "(itkmpm: pid=%d uid=%d, gid=%d) %s(): " text, \
++                getpid(), getuid(), getgid(), __FUNCTION__, par)
++
+ #define APR_WANT_STDIO
+ #define APR_WANT_STRFUNC
+ #include "apr_want.h"
+@@ -64,6 +69,9 @@
+ #include <signal.h>
+ #include <sys/times.h>
+ 
++/* Import our private hook. */
++AP_DECLARE_HOOK(int,post_perdir_config,(request_rec *r))
++
+ /* Limit on the total --- clients will be locked out if more servers than
+  * this are needed.  It is intended solely to keep the server from crashing
+  * when things get out of hand.
+@@ -153,6 +161,15 @@ static pid_t ap_my_pid; /* it seems sill
+ static pid_t parent_pid;
+ static int my_child_num;
+ 
++typedef struct
++{
++    uid_t uid;
++    gid_t gid;
++    char *username;
++} itk_per_dir_conf;
++
++module AP_MODULE_DECLARE_DATA mpm_itk_module;
++
+ #ifdef GPROF
+ /*
+  * change directory for gprof to plop the gmon.out file
+@@ -542,10 +559,6 @@ static void child_main(int child_num_arg
+         clean_child_exit(APEXIT_CHILDFATAL);
+     }
+ 
+-    if (ap_run_drop_privileges(pchild, ap_server_conf)) {
+-        clean_child_exit(APEXIT_CHILDFATAL);
+-    }
+-
+     ap_run_child_init(pchild, ap_server_conf);
+ 
+     ap_create_sb_handle(&sbh, pchild, my_child_num, 0);
+@@ -695,13 +708,40 @@ static void child_main(int child_num_arg
+          * socket options, file descriptors, and read/write buffers.
+          */
+ 
+-        current_conn = ap_run_create_connection(ptrans, ap_server_conf, csd, my_child_num, sbh, bucket_alloc);
+-        if (current_conn) {
++        {
++            pid_t pid = fork(), child_pid;
++            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) {
+ #if APR_HAS_THREADS
+-            current_conn->current_thread = thd;
++                    current_conn->current_thread = thd;
+ #endif
+-            ap_process_connection(current_conn, csd);
+-            ap_lingering_close(current_conn);
++                    ap_process_connection(current_conn, csd);
++                    ap_lingering_close(current_conn);
++                }
++                exit(0);
++            default: /* parent; just wait for child to be done */
++                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) {
++                        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
+@@ -719,6 +759,10 @@ static void child_main(int child_num_arg
+              */
+             die_now = 1;
+         }
++
++        /* if we have already setuid(), die (we can't be used anyhow) */
++        if (getuid())
++            die_now = 1;
+     }
+     apr_pool_clear(ptrans); /* kludge to avoid crash in APR reslist cleanup code */
+     clean_child_exit(0);
+@@ -1443,6 +1487,56 @@ static int itk_check_config(apr_pool_t *
+     return OK;
+ }
+ 
++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_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;
++
++    wanted_uid = dconf->uid;
++    wanted_gid = dconf->gid;
++    wanted_username = dconf->username;
++
++    if (wanted_uid == -1 || wanted_gid == -1) {
++        wanted_uid = ap_unixd_config.user_id;
++        wanted_gid = ap_unixd_config.group_id;
++        wanted_username = ap_unixd_config.user_name;
++    }
++
++    if (wanted_uid != -1 && wanted_gid != -1 && (getuid() != wanted_uid || getgid() != wanted_gid)) {
++        if (setgid(wanted_gid)) {
++            _DBG("setgid(%d): %s", wanted_gid, strerror(errno));
++            err = 1;
++        } else if (initgroups(wanted_username, wanted_gid)) {
++            _DBG("initgroups(%s, %d): %s", wanted_username, wanted_gid, strerror(errno));
++            err = 1;
++        } else if (setuid(wanted_uid)) {
++            _DBG("setuid(%d): %s", wanted_uid, 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, closing connection.");
++        ap_lingering_close(r->connection);
++        exit(0);
++    }
++    return OK;
++}
++
+ static void itk_hooks(apr_pool_t *p)
+ {
+     /* Our open_logs hook function must run before the core's, or stderr
+@@ -1460,6 +1554,9 @@ static void itk_hooks(apr_pool_t *p)
+     ap_hook_mpm(itk_run, NULL, NULL, APR_HOOK_MIDDLE);
+     ap_hook_mpm_query(itk_query, NULL, NULL, APR_HOOK_MIDDLE);
+     ap_hook_mpm_get_name(itk_get_name, NULL, NULL, APR_HOOK_MIDDLE);
++
++    /* 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)
+@@ -1521,6 +1618,21 @@ static const char *set_server_limit (cmd
+     return NULL;
+ }
+ 
++static const char *assign_user_id (cmd_parms *cmd, void *ptr, const char *user_name, const char *group_name)
++{
++    itk_per_dir_conf *dconf = (itk_per_dir_conf *) ptr;
++
++    const char *err = ap_check_cmd_context(cmd, NOT_IN_HTACCESS);
++    if (err) {
++        return err;
++    }
++
++    dconf->username = apr_pstrdup(cmd->pool, user_name);
++    dconf->uid = ap_uname2id(user_name);
++    dconf->gid = ap_gname2id(group_name);
++    return NULL;
++}
++
+ static const command_rec itk_cmds[] = {
+ LISTEN_COMMANDS,
+ AP_INIT_TAKE1("StartServers", set_daemons_to_start, NULL, RSRC_CONF,
+@@ -1535,14 +1647,25 @@ AP_INIT_TAKE1("MaxRequestWorkers", set_m
+               "Maximum number of children alive at the same time"),
+ AP_INIT_TAKE1("ServerLimit", set_server_limit, NULL, RSRC_CONF,
+               "Maximum value of MaxRequestWorkers for this run of Apache"),
++AP_INIT_TAKE2("AssignUserID", assign_user_id, NULL, RSRC_CONF|ACCESS_CONF,
++              "Tie a virtual host to a specific child process."),
+ 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;
++    return c;
++}
++
+ AP_DECLARE_MODULE(mpm_itk) = {
+     MPM20_MODULE_STUFF,
+     NULL,                       /* hook to run before apache parses args */
+-    NULL,                       /* create per-directory config structure */
++    itk_create_dir_config,      /* create per-directory config structure */
+     NULL,                       /* merge per-directory config structures */
+     NULL,                       /* create per-server config structure */
+     NULL,                       /* merge per-server config structures */
diff --git a/debian/patches/itk/08-max-clients-per-vhost.patch b/debian/patches/itk/08-max-clients-per-vhost.patch
new file mode 100644
index 0000000..8953217
--- /dev/null
+++ b/debian/patches/itk/08-max-clients-per-vhost.patch
@@ -0,0 +1,99 @@
+Enforce the per-vhost server limit. Note that this is per-vhost, not
+per-directory (since it works by reading the scoreboard), so we need to add
+per-server configuration data.
+
+Index: httpd-2.4.1/server/mpm/itk/itk.c
+===================================================================
+--- httpd-2.4.1.orig/server/mpm/itk/itk.c
++++ httpd-2.4.1/server/mpm/itk/itk.c
+@@ -168,6 +168,11 @@ typedef struct
+     char *username;
+ } itk_per_dir_conf;
+ 
++typedef struct
++{
++    int max_clients_vhost;
++} itk_server_conf;
++
+ module AP_MODULE_DECLARE_DATA mpm_itk_module;
+ 
+ #ifdef GPROF
+@@ -1493,9 +1498,29 @@ static int itk_post_perdir_config(reques
+     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);
++    itk_per_dir_conf *dconf;
++
++    /* 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;
++        }
+ 
+-    itk_per_dir_conf *dconf =
+-        (itk_per_dir_conf *) ap_get_module_config(r->per_dir_config, &mpm_itk_module);
++        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;
++        }
++    }
++
++    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;
+@@ -1633,6 +1658,14 @@ static const char *assign_user_id (cmd_p
+     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;
++}
++
+ static const command_rec itk_cmds[] = {
+ LISTEN_COMMANDS,
+ AP_INIT_TAKE1("StartServers", set_daemons_to_start, NULL, RSRC_CONF,
+@@ -1649,6 +1682,8 @@ AP_INIT_TAKE1("ServerLimit", set_server_
+               "Maximum value of MaxRequestWorkers for this run of Apache"),
+ 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_GRACEFUL_SHUTDOWN_TIMEOUT_COMMAND,
+ { NULL }
+ };
+@@ -1662,12 +1697,21 @@ static void *itk_create_dir_config(apr_p
+     return c;
+ }
+ 
++/* == allocate a private server config structure == */
++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->max_clients_vhost = -1;
++    return c;
++}
++
+ AP_DECLARE_MODULE(mpm_itk) = {
+     MPM20_MODULE_STUFF,
+     NULL,                       /* hook to run before apache parses args */
+     itk_create_dir_config,      /* create per-directory config structure */
+     NULL,                       /* merge per-directory config structures */
+-    NULL,                       /* create per-server config structure */
++    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 */
diff --git a/debian/patches/itk/09-capabilities.patch b/debian/patches/itk/09-capabilities.patch
new file mode 100644
index 0000000..e25f2c0
--- /dev/null
+++ b/debian/patches/itk/09-capabilities.patch
@@ -0,0 +1,73 @@
+Use Linux' capability system to run as a sort of "lesser root"; we drop nearly
+all root privilegies except the ability to setuid. An attacker capable of injecting
+code will still be able to run as any (normal) user on the system, but at least
+he/she cannot directly load kernel code etc.
+
+Index: httpd-2.4.1/server/mpm/config2.m4
+===================================================================
+--- httpd-2.4.1.orig/server/mpm/config2.m4
++++ httpd-2.4.1/server/mpm/config2.m4
+@@ -66,6 +66,9 @@ for i in $ap_enabled_mpms; do
+     else
+         AC_MSG_ERROR([MPM $i is not supported on this platform.])
+     fi
++    if test "$i" = "itk" ; then
++        AC_CHECK_LIB(cap, cap_init)
++    fi
+ done
+ 
+ if test $mpm_build = "shared"; then
+Index: httpd-2.4.1/server/mpm/itk/itk.c
+===================================================================
+--- httpd-2.4.1.orig/server/mpm/itk/itk.c
++++ httpd-2.4.1/server/mpm/itk/itk.c
+@@ -66,6 +66,10 @@
+ #include <sys/processor.h> /* for bindprocessor() */
+ #endif
+ 
++#if HAVE_LIBCAP
++#include <sys/capability.h>
++#endif
++
+ #include <signal.h>
+ #include <sys/times.h>
+ 
+@@ -522,6 +526,15 @@ static void child_main(int child_num_arg
+     int last_poll_idx = 0;
+     const char *lockfile;
+ 
++#if HAVE_LIBCAP
++    cap_t caps;
++    cap_value_t suidcaps[] = {
++        CAP_SETUID,
++        CAP_SETGID,
++        CAP_DAC_READ_SEARCH,
++    };
++#endif    
++
+     mpm_state = AP_MPMQ_STARTING; /* for benefit of any hooks that run as this
+                                    * child initializes
+                                    */
+@@ -596,6 +609,22 @@ static void child_main(int child_num_arg
+         lr->accept_func = ap_unixd_accept;
+     }
+ 
++#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/debian/patches/itk/10-nice.patch b/debian/patches/itk/10-nice.patch
new file mode 100644
index 0000000..c2f9c3d
--- /dev/null
+++ b/debian/patches/itk/10-nice.patch
@@ -0,0 +1,140 @@
+Support a per-location nice value. Note that since we now have two different settings
+in the per-dir configuration, we need to introduce a merge function.
+
+Index: httpd-2.4.1/server/mpm/itk/itk.c
+===================================================================
+--- httpd-2.4.1.orig/server/mpm/itk/itk.c
++++ httpd-2.4.1/server/mpm/itk/itk.c
+@@ -165,11 +165,14 @@ static pid_t ap_my_pid; /* it seems sill
+ static pid_t parent_pid;
+ static int my_child_num;
+ 
++#define UNSET_NICE_VALUE 100
++
+ typedef struct
+ {
+     uid_t uid;
+     gid_t gid;
+     char *username;
++    int nice_value;
+ } itk_per_dir_conf;
+ 
+ typedef struct
+@@ -532,6 +535,7 @@ static void child_main(int child_num_arg
+         CAP_SETUID,
+         CAP_SETGID,
+         CAP_DAC_READ_SEARCH,
++        CAP_SYS_NICE,
+     };
+ #endif    
+ 
+@@ -1554,6 +1558,12 @@ static int itk_post_perdir_config(reques
+     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 (dconf->nice_value != UNSET_NICE_VALUE &&
++        setpriority(PRIO_PROCESS, 0, dconf->nice_value)) {
++        _DBG("setpriority(): %s", strerror(errno));
++        err = 1;
++    }
++
+     wanted_uid = dconf->uid;
+     wanted_gid = dconf->gid;
+     wanted_username = dconf->username;
+@@ -1564,7 +1574,7 @@ static int itk_post_perdir_config(reques
+         wanted_username = ap_unixd_config.user_name;
+     }
+ 
+-    if (wanted_uid != -1 && wanted_gid != -1 && (getuid() != wanted_uid || getgid() != wanted_gid)) {
++    if (!err && wanted_uid != -1 && wanted_gid != -1 && (getuid() != wanted_uid || getgid() != wanted_gid)) {
+         if (setgid(wanted_gid)) {
+             _DBG("setgid(%d): %s", wanted_gid, strerror(errno));
+             err = 1;
+@@ -1584,7 +1594,7 @@ static int itk_post_perdir_config(reques
+      */
+     if (err) {
+         ap_log_error(APLOG_MARK, APLOG_WARNING, 0, NULL, \
+-            "Couldn't set uid/gid, closing connection.");
++            "Couldn't set uid/gid/priority, closing connection.");
+         ap_lingering_close(r->connection);
+         exit(0);
+     }
+@@ -1695,6 +1705,27 @@ static const char *set_max_clients_vhost
+     return NULL;
+ }
+ 
++static const char *set_nice_value (cmd_parms *cmd, void *ptr, const char *arg)
++{
++    itk_per_dir_conf *dconf = (itk_per_dir_conf *) ptr;
++    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;
++    }
++    dconf->nice_value = nice_value;
++    return NULL;
++}
++
+ static const command_rec itk_cmds[] = {
+ LISTEN_COMMANDS,
+ AP_INIT_TAKE1("StartServers", set_daemons_to_start, NULL, RSRC_CONF,
+@@ -1713,6 +1744,8 @@ AP_INIT_TAKE2("AssignUserID", assign_use
+               "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|ACCESS_CONF,
++              "Set nice value for the given vhost, from -20 (highest priority) to 19 (lowest priority)."),
+ AP_GRACEFUL_SHUTDOWN_TIMEOUT_COMMAND,
+ { NULL }
+ };
+@@ -1723,6 +1756,32 @@ static void *itk_create_dir_config(apr_p
+     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 *)
++        itk_create_dir_config(p, NULL);
++    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 = child->username;
++      c->uid = child->uid;
++      c->gid = child->gid;
++    } else {
++      c->username = 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;
+ }
+ 
+@@ -1739,7 +1798,7 @@ AP_DECLARE_MODULE(mpm_itk) = {
+     MPM20_MODULE_STUFF,
+     NULL,                       /* hook to run before apache parses args */
+     itk_create_dir_config,      /* create per-directory config structure */
+-    NULL,                       /* merge per-directory config structures */
++    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 */
diff --git a/debian/patches/itk/11-fix-htaccess-reads-for-persistent-connections.patch b/debian/patches/itk/11-fix-htaccess-reads-for-persistent-connections.patch
new file mode 100644
index 0000000..0ff554e
--- /dev/null
+++ b/debian/patches/itk/11-fix-htaccess-reads-for-persistent-connections.patch
@@ -0,0 +1,72 @@
+Fix an issue where users can sometimes get spurious 403s on persistent
+connections (the description in the comments explains the logic).
+This would particularly hit people with reverse proxies, since these
+have a higher tendency of accessing things from different vhosts in
+the same connection.
+
+Index: httpd-2.4.1/server/config.c
+===================================================================
+--- httpd-2.4.1.orig/server/config.c
++++ httpd-2.4.1/server/config.c
+@@ -68,6 +68,8 @@ AP_DECLARE_DATA apr_array_header_t *ap_s
+ 
+ AP_DECLARE_DATA ap_directive_t *ap_conftree = NULL;
+ 
++AP_DECLARE_DATA int ap_running_under_mpm_itk = 0;
++
+ APR_HOOK_STRUCT(
+            APR_HOOK_LINK(header_parser)
+            APR_HOOK_LINK(pre_config)
+@@ -2109,6 +2111,32 @@ AP_CORE_DECLARE(int) ap_parse_htaccess(a
+         else {
+             if (!APR_STATUS_IS_ENOENT(status)
+                 && !APR_STATUS_IS_ENOTDIR(status)) {
++                /*
++                 * If we are in a persistent connection, we might end up in a state
++                 * where we can no longer read .htaccess files because we have already
++                 * setuid(). This can either be because the previous request was for
++                 * another vhost (basically the same problem as when setuid() fails in
++                 * itk.c), or it can be because a .htaccess file is readable only by
++                 * root.
++                 *
++                 * In any case, we don't want to give out a 403, since the request has
++                 * a very real chance of succeeding on a fresh connection (where
++                 * presumably uid=0). Thus, we give up serving the request on this
++                 * TCP connection, and do a hard close of the socket. As long as we're
++                 * in a persistent connection (and there _should_ not be a way this
++                 * would happen on the first request in a connection, save for subrequests,
++                 * which we special-case), this is allowed, as it is what happens on
++                 * a timeout. The browser will simply open a new connection and try
++                 * again (there's of course a performance hit, though, both due to
++                 * the new connection setup and the fork() of a new server child).
++                 */
++                if (ap_running_under_mpm_itk && r->main == NULL && getuid() != 0) {
++                    ap_log_rerror(APLOG_MARK, APLOG_WARNING, status, r,
++                                  "Couldn't read %s, closing connection.",
++                                  filename);
++                    ap_lingering_close(r->connection);
++                    exit(0);
++                }
+                 ap_log_rerror(APLOG_MARK, APLOG_CRIT, status, r, APLOGNO(00529)
+                               "%s pcfg_openfile: unable to check htaccess file, "
+                               "ensure it is readable and that '%s' "
+Index: httpd-2.4.1/server/mpm/itk/itk.c
+===================================================================
+--- httpd-2.4.1.orig/server/mpm/itk/itk.c
++++ httpd-2.4.1/server/mpm/itk/itk.c
+@@ -181,6 +181,7 @@ typedef struct
+ } itk_server_conf;
+ 
+ module AP_MODULE_DECLARE_DATA mpm_itk_module;
++extern AP_DECLARE_DATA int ap_running_under_mpm_itk;
+ 
+ #ifdef GPROF
+ /*
+@@ -543,6 +544,7 @@ static void child_main(int child_num_arg
+                                    * child initializes
+                                    */
+ 
++    ap_running_under_mpm_itk = 1;
+     my_child_num = child_num_arg;
+     ap_my_pid = getpid();
+     requests_this_child = 0;
diff --git a/debian/patches/itk/99-rerun-configure.patch b/debian/patches/itk/99-rerun-configure.patch
new file mode 100644
index 0000000..028f010
--- /dev/null
+++ b/debian/patches/itk/99-rerun-configure.patch
@@ -0,0 +1,198 @@
+# the analogon of running autoheader; autoconf, which is a pain to clean up
+diff --git a/configure b/configure
+index c94d7b8..3eb397a 100755
+--- a/configure
++++ b/configure
+@@ -1946,8 +1946,8 @@ Optional Packages:
+   --with-lua=PATH         Path to the Lua 5.1 prefix
+   --with-ssl=DIR          OpenSSL base directory
+   --with-mpm=MPM          Choose the process model for Apache to use by
+-                          default. MPM={event|worker|prefork|winnt} This will
+-                          be statically linked as the only available MPM
++                          default. MPM={event|worker|prefork|winnt|itk} This
++                          will be statically linked as the only available MPM
+                           unless --enable-mpms-shared is also specified.
+   --with-module=module-type:module-file
+                           Enable module-file in the modules/<module-type>
+@@ -24988,6 +24988,27 @@ $as_echo "yes" >&6; }
+ 
+ fi
+ 
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if itk MPM supports this platform" >&5
++$as_echo_n "checking if itk MPM supports this platform... " >&6; }
++if test $forking_mpms_supported != yes; then
++    { $as_echo "$as_me:${as_lineno-$LINENO}: result: no - This is not a forking platform" >&5
++$as_echo "no - This is not a forking platform" >&6; }
++else
++    { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
++$as_echo "yes" >&6; }
++
++    if test "yes" = "yes"; then
++        eval "ap_supported_mpm_itk=shared"
++        ap_supported_shared_mpms="$ap_supported_shared_mpms itk "
++    else
++        eval "ap_supported_mpm_itk=static"
++    fi
++    if test "no" = "yes"; then
++        eval "ap_threaded_mpm_itk=yes"
++    fi
++
++fi
++
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if mpmt_os2 MPM supports this platform" >&5
+ $as_echo_n "checking if mpmt_os2 MPM supports this platform... " >&6; }
+ case $host in
+@@ -26565,6 +26586,53 @@ for i in $ap_enabled_mpms; do
+     else
+         as_fn_error $? "MPM $i is not supported on this platform." "$LINENO" 5
+     fi
++    if test "$i" = "itk" ; then
++        { $as_echo "$as_me:${as_lineno-$LINENO}: checking for cap_init in -lcap" >&5
++$as_echo_n "checking for cap_init in -lcap... " >&6; }
++if ${ac_cv_lib_cap_cap_init+:} false; then :
++  $as_echo_n "(cached) " >&6
++else
++  ac_check_lib_save_LIBS=$LIBS
++LIBS="-lcap  $LIBS"
++cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++/* end confdefs.h.  */
++
++/* Override any GCC internal prototype to avoid an error.
++   Use char because int might match the return type of a GCC
++   builtin and then its argument prototype would still apply.  */
++#ifdef __cplusplus
++extern "C"
++#endif
++char cap_init ();
++int
++main ()
++{
++return cap_init ();
++  ;
++  return 0;
++}
++_ACEOF
++if ac_fn_c_try_link "$LINENO"; then :
++  ac_cv_lib_cap_cap_init=yes
++else
++  ac_cv_lib_cap_cap_init=no
++fi
++rm -f core conftest.err conftest.$ac_objext \
++    conftest$ac_exeext conftest.$ac_ext
++LIBS=$ac_check_lib_save_LIBS
++fi
++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_cap_cap_init" >&5
++$as_echo "$ac_cv_lib_cap_cap_init" >&6; }
++if test "x$ac_cv_lib_cap_cap_init" = xyes; then :
++  cat >>confdefs.h <<_ACEOF
++#define HAVE_LIBCAP 1
++_ACEOF
++
++  LIBS="-lcap $LIBS"
++
++fi
++
++    fi
+ done
+ 
+ if test $mpm_build = "shared"; then
+@@ -26685,6 +26753,77 @@ done
+ 
+ 
+ 
++    if ap_mpm_is_enabled itk; then
++        if test -z ""; then
++            objects="itk.lo"
++        else
++            objects=""
++        fi
++
++        if test -z ""; then
++            mpmpath="server/mpm/itk"
++        else
++            mpmpath=
++        fi
++
++                test -d $mpmpath || $srcdir/build/mkdir.sh $mpmpath
++
++
++  APACHE_FAST_OUTPUT_FILES="$APACHE_FAST_OUTPUT_FILES $mpmpath/Makefile"
++
++
++        if test -z "$enable_mpm_itk"; then
++
++  if test "x$AP_LIBS" = "x"; then
++    test "x$silent" != "xyes" && echo "  setting AP_LIBS to \"\""
++    AP_LIBS=""
++  else
++    apr_addto_bugger=""
++    for i in $apr_addto_bugger; do
++      apr_addto_duplicate="0"
++      for j in $AP_LIBS; do
++        if test "x$i" = "x$j"; then
++          apr_addto_duplicate="1"
++          break
++        fi
++      done
++      if test $apr_addto_duplicate = "0"; then
++        test "x$silent" != "xyes" && echo "  adding \"$i\" to AP_LIBS"
++        AP_LIBS="$AP_LIBS $i"
++      fi
++    done
++  fi
++
++            libname="libitk.la"
++            cat >$mpmpath/modules.mk<<EOF
++$libname: $objects
++	\$(MOD_LINK) $objects
++DISTCLEAN_TARGETS = modules.mk
++static = $libname
++shared =
++EOF
++        else
++            apache_need_shared=yes
++            libname="mod_mpm_itk.la"
++            shobjects=`echo $objects | sed 's/\.lo/.slo/g'`
++            cat >$mpmpath/modules.mk<<EOF
++$libname: $shobjects
++	\$(SH_LINK) -rpath \$(libexecdir) -module -avoid-version $objects
++DISTCLEAN_TARGETS = modules.mk
++static =
++shared = $libname
++EOF
++            # add default MPM to LoadModule list
++            if test itk = $default_mpm; then
++                DSO_MODULES="$DSO_MODULES mpm_itk"
++                ENABLED_DSO_MODULES="${ENABLED_DSO_MODULES},mpm_itk"
++            fi
++        fi
++
++    fi
++
++
++
+     if ap_mpm_is_enabled prefork; then
+         if test -z ""; then
+             objects="prefork.lo"
+@@ -26923,6 +27062,7 @@ done
+ 
+ if ap_mpm_is_enabled "worker" \
+    || ap_mpm_is_enabled "event" \
++   || ap_mpm_is_enabled "itk" \
+    || ap_mpm_is_enabled "prefork"; then
+     unixd_mods_enable=yes
+ else
+diff --git a/include/ap_config_auto.h.in b/include/ap_config_auto.h.in
+index 6b6fbfa..73bb460 100644
+--- a/include/ap_config_auto.h.in
++++ b/include/ap_config_auto.h.in
+@@ -100,6 +100,9 @@
+ /* Define to 1 if you have the `kqueue' function. */
+ #undef HAVE_KQUEUE
+ 
++/* Define to 1 if you have the `cap' library (-lcap). */
++#undef HAVE_LIBCAP
++
+ /* Define to 1 if you have the <limits.h> header file. */
+ #undef HAVE_LIMITS_H
+ 
diff --git a/debian/patches/itk/README b/debian/patches/itk/README
new file mode 100644
index 0000000..7fbbeb1
--- /dev/null
+++ b/debian/patches/itk/README
@@ -0,0 +1,5 @@
+This is a prerelease version of mpm-itk against Apache 2.4.1.
+It is barely tested at all; use with caution.
+
+Follow the mpm-itk mailing list (http://lists.err.no/mailman/listinfo/mpm-itk)
+for a production 2.4 release.
diff --git a/debian/patches/itk/series b/debian/patches/itk/series
new file mode 100644
index 0000000..02d884b
--- /dev/null
+++ b/debian/patches/itk/series
@@ -0,0 +1,12 @@
+#00-fix-bug-52904.patch
+#01-copy-prefork.patch
+02-rename-prefork-to-itk.patch
+03-add-mpm-to-build-system.patch
+05-add-copyright.patch
+06-hook-just-after-merging-perdir-config.patch
+07-base-functionality.patch
+08-max-clients-per-vhost.patch
+09-capabilities.patch
+10-nice.patch
+11-fix-htaccess-reads-for-persistent-connections.patch
+99-rerun-configure.patch
diff --git a/debian/rules b/debian/rules
index 4913cdc..08357a7 100755
--- a/debian/rules
+++ b/debian/rules
@@ -13,10 +13,32 @@ AP2_CFLAGS = -pipe $(shell dpkg-buildflags --get CFLAGS)
 AP2_LDFLAGS = -Wl,--as-needed $(shell dpkg-buildflags --get LDFLAGS)
 AP2_CPPFLAGS = -DPLATFORM='\"$(LSB_RELEASE)\"' $(shell dpkg-buildflags --get CPPFLAGS)
 
-prepare-custom-suexec:
+patch: patch.stamp
+patch.stamp: 
 	cp support/suexec.c support/suexec-custom.c
 	patch -p1 < debian/patches/suexec-custom.patch
-
+	mkdir server/mpm/itk/
+	cp server/mpm/prefork/* server/mpm/itk/
+	mv server/mpm/itk/prefork.c server/mpm/itk/itk.c
+	set -ex; for p in $$(grep -v '^#' debian/patches/itk/series) ; do \
+		echo Applying $$p ... ;\
+		patch -p1 < debian/patches/itk/$$p ;\
+	done
+	touch $@
+
+unpatch:
+	if [ -e patch.stamp ] ;\
+	then \
+		set -ex ;\
+		for p in $$(grep -v '^#' debian/patches/itk/series | tac) ;\
+		do \
+			echo De-applying $$p ... ;\
+			patch -R -p1 < debian/patches/itk/$$p ;\
+		done ;\
+		rm -r server/mpm/itk ;\
+		rm support/suexec-custom.c ;\
+		rm patch.stamp ;\
+	fi
 
 clean-config-vars:
 	# Clean up config_vars.mk
@@ -46,7 +68,7 @@ generate-maintainer-scripts:
 %:
 	dh $@ --parallel --with autotools_dev
 
-override_dh_auto_configure: prepare-custom-suexec generate-maintainer-scripts
+override_dh_auto_configure: patch generate-maintainer-scripts
 	./configure --enable-layout=Debian --enable-so --with-program-name=apache2 \
 		--enable-suexec --with-suexec-caller=www-data \
 		--with-suexec-bin=/usr/lib/apache2/suexec --with-suexec-docroot=/var/www \
@@ -114,6 +136,7 @@ override_dh_strip:
 override_dh_auto_install:
 	dh_auto_install -- -j1
 
+override_dh_clean: unpatch
+	dh_clean
 
-
-.PHONY: prepare-custom-suexec generate-maintainer-scripts clean-config-vars prepare-scripts
+.PHONY: patch unpatch generate-maintainer-scripts clean-config-vars prepare-scripts

-- 
Debian packaging for apache2 (Apache HTTPD 2.x)



More information about the Pkg-apache-commits mailing list