diff -ru apache_1.3.39/src/Configure apache_1.3.39_local/src/Configure
--- apache_1.3.39/src/Configure	2007-08-11 01:45:50.000000000 +1000
+++ apache_1.3.39_local/src/Configure	2007-11-19 16:47:52.000000000 +1100
@@ -409,8 +409,8 @@
         # This handles linux 2.2 and above (2.4, ...)
 	DEF_WANTHSREGEX=yes
 	OS='Linux'
-	CFLAGS="$CFLAGS -DLINUX=22"
-	LIBS="$LIBS -lm"
+	CFLAGS="$CFLAGS -DLINUX=22 -DCHROOT_JAIL -DUSE_LINUX_CAPABILITIES"
+	LIBS="$LIBS -lm -lcap"
 	;;
     *-GNU*)
 	DEF_WANTHSREGEX=yes
--- apache_1.3.39/src/main/http_main.c	2007-06-05 05:26:21.000000000 +1000
+++ apache_1.3.39_local/src/main/http_main.c	2007-11-20 16:02:07.000000000 +1100
@@ -13,7 +13,6 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
 /*
  * httpd.c: simple http daemon for answering WWW file requests
  *
@@ -280,6 +279,13 @@
 API_VAR_EXPORT array_header *ap_server_post_read_config=NULL;
 API_VAR_EXPORT array_header *ap_server_config_defines=NULL;
 
+#ifdef	CHROOT_JAIL
+API_VAR_EXPORT char ap_chroot_jail[MAX_STRING_LEN]="";
+#endif
+#ifdef	USE_LINUX_CAPABILITIES
+API_VAR_EXPORT	int	ap_use_linux_caps	= 0;
+#endif
+
 /* *Non*-shared http_main globals... */
 
 static server_rec *server_conf;
@@ -545,7 +551,7 @@
  *   which struct to use. We tell Apache which methods we
  *   support via HAVE_FOO_SERIALIZED_ACCEPT. We can
  *   specify the default via USE_FOO_SERIALIZED_ACCEPT
- *   (this pre-1.3.21 builds which use that at the command-
+ *   (this pre-1.3.21 builds which use that at the command- 1
  *   line during builds work as expected). Without a set
  *   method, we pick the 1st from the following order:
  *   uslock, pthread, sysvsem, fcntl, flock, os2sem, tpfcore and none.
@@ -5602,7 +5608,60 @@
 __declspec(dllexport)  
 #endif
 
-int REALMAIN(int argc, char *argv[])
+#ifdef	USE_LINUX_CAPABILITIES
+#include <sys/capability.h>
+#include <sys/prctl.h>
+
+enum	{ OUR_OK = 0, OUR_ERR = (-1) };
+static	int use_caps_to_drop_root (uid_t uid, gid_t gid){
+
+	int	result	= OUR_ERR;
+	cap_t caps;
+	if (geteuid() != 0) { /* not root */
+		return	result;
+	}
+	if (prctl(PR_SET_KEEPCAPS, 1L, 0L, 0L, 0L) != 0) {
+		ap_log_error(APLOG_MARK, APLOG_ERR, server_conf,
+		"prctl(PR_SET_KEEPCAPS, 1) failed.");
+	    exit(1);
+  	}
+	if ( setgroups(0, NULL) == -1 ) {
+		ap_log_error(APLOG_MARK, APLOG_ERR, server_conf,
+		"setgroups failed.");
+	    exit(1);
+	}
+
+	if ( setegid(gid) == -1 || seteuid(uid) == -1 ) {
+		ap_log_error(APLOG_MARK, APLOG_ERR, server_conf,
+		"setegid/seteuid to uid=%d/gid=%d failed.", uid, gid);
+		exit(1);
+  	}
+	caps = cap_from_text("cap_net_bind_service=eip");
+	if (caps == NULL) {
+		ap_log_error(APLOG_MARK, APLOG_ERR, server_conf,
+		"cap_from_text failed.");
+		exit(1);
+	}
+	if (cap_set_proc(caps) == -1) {
+		ap_log_error(APLOG_MARK, APLOG_ERR, server_conf,
+		"cap_set_proc failed.");
+		exit(1);
+	}
+	if ( setregid(gid,gid) == -1 || setreuid(uid, uid) == -1 ) {
+		ap_log_error(APLOG_MARK, APLOG_ERR, server_conf,
+		"setregid/setreuid to uid=%d/gid=%d failed.",
+                 uid, gid);
+	    exit(1);
+	}
+		
+        ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_NOTICE, server_conf,
+		"Finished setup jail: uid(%d), gid(%d)", getuid(), getgid());
+	result	= OUR_OK;
+	return	result;
+}
+# endif
+
+ REALMAIN(int argc, char *argv[])
 {
     int c;
     int sock_in;
@@ -5650,6 +5709,12 @@
 #ifdef DEBUG_SIGSTOP
 				    "Z:"
 #endif
+#ifdef CHROOT_JAIL
+				"J:"
+#endif
+#ifdef	USE_LINUX_CAPABILITIES
+				"B"
+#endif
 			)) != -1) {
 	char **new;
 	switch (c) {
@@ -5724,12 +5789,42 @@
 	    ap_configtestonly = 1;
 	    ap_docrootcheck = 0;
 	    break;
+#ifdef	CHROOT_JAIL
+	case 'J':
+	   ap_cpystrn(ap_chroot_jail, optarg, sizeof(ap_chroot_jail));
+	break;
+#endif
+#ifdef	USE_LINUX_CAPABILITIES
+	case 'B':
+	    ap_use_linux_caps = 1;
+	break;
+#endif
 	case 'h':
 	    usage(argv[0]);
 	case '?':
 	    usage(argv[0]);
 	}
     }
+#ifdef	CHROOT_JAIL
+	if (ap_chroot_jail[0] != '\0') {	/* no Jail requested */
+	int	result	= chdir (ap_chroot_jail);
+	if (result != 0) {
+		ap_log_error(APLOG_MARK, APLOG_ERR, server_conf,
+			"couldn't chdir(%s)", ap_chroot_jail);
+			exit (1);
+		}
+		result	= chroot (ap_chroot_jail);
+		if (result != 0) {
+			ap_log_error(APLOG_MARK, APLOG_ERR, server_conf,
+				"couldn't chroot(%s)", ap_chroot_jail);
+			exit (1);
+		}
+		/* goes to stderr/console */
+		ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_NOTICE,
+			server_conf,
+                        "Success chroot (%s)", ap_chroot_jail);
+	}
+# endif
 
     ap_suexec_enabled = init_suexec();
     server_conf = ap_read_config(pconf, ptrans, ap_server_confname);
@@ -5755,6 +5850,11 @@
 	ap_set_version();
 	ap_init_modules(pconf, server_conf);
 	version_locked++;
+#ifdef	USE_LINUX_CAPABILITIES
+	if (ap_use_linux_caps) {
+		use_caps_to_drop_root (ap_user_id, ap_group_id);
+	}
+#endif
 	STANDALONE_MAIN(argc, argv);
     }
 #else
@@ -5788,7 +5888,7 @@
 #else /* must be USE_SHMGET_SCOREBOARD */
             ap_scoreboard_image =
                 (scoreboard *)input_parms.child.scoreboard_heap;
-#endif
+#endif /* SCOREBOARD_FILE */
             ap_init_mutex_method(ap_default_mutex_method());
             child_main(input_parms.child.slot);
         }
