diff -ru httpd-2.2.6/os/unix/unixd.c httpd-2.2.6.new/os/unix/unixd.c --- httpd-2.2.6/os/unix/unixd.c 2006-07-12 06:38:44.000000000 +0300 +++ httpd-2.2.6.new/os/unix/unixd.c 2007-10-11 12:32:28.000000000 +0300 @@ -117,6 +117,30 @@ if (set_group_privs()) { return -1; } + + if( NULL != unixd_config.chroot_dir ) { + if(geteuid()) { + ap_log_error(APLOG_MARK, APLOG_ALERT,errno,NULL, + "Cannot chroot when not started as root"); + return -1; + } + if( chdir( unixd_config.chroot_dir ) != 0 ) { + ap_log_error(APLOG_MARK, APLOG_ALERT, errno,NULL, + "Can't chdir to %s", unixd_config.chroot_dir); + return -1; + } + if( chroot( unixd_config.chroot_dir ) != 0 ) { + ap_log_error(APLOG_MARK, APLOG_ALERT, errno,NULL, + "Can't chroot to %s", unixd_config.chroot_dir); + return -1; + } + if( chdir( "/" ) != 0 ) { + ap_log_error(APLOG_MARK, APLOG_ALERT, errno,NULL, + "Can't chdir to new root"); + return -1; + } + } + #ifdef MPE /* Only try to switch if we're running as MANAGER.SYS */ if (geteuid() == 1 && unixd_config.user_id > 1) { @@ -198,7 +222,22 @@ return NULL; } +AP_DECLARE(const char *) unixd_set_chroot_dir(cmd_parms *cmd, void *dummy, + const char *arg) +{ + const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); + if (err != NULL) { + return err; + } + if( !ap_is_directory(cmd->pool, arg) ) { + return "ChrootDir must be a valid directory"; + } + unixd_config.chroot_dir = arg; + return NULL; + +} + AP_DECLARE(void) unixd_pre_config(apr_pool_t *ptemp) { apr_finfo_t wrapper; @@ -206,6 +245,8 @@ unixd_config.user_name = DEFAULT_USER; unixd_config.user_id = ap_uname2id(DEFAULT_USER); unixd_config.group_id = ap_gname2id(DEFAULT_GROUP); + + unixd_config.chroot_dir = NULL; /* none */ /* Check for suexec */ unixd_config.suexec_enabled = 0; diff -ru httpd-2.2.6/os/unix/unixd.h httpd-2.2.6.new/os/unix/unixd.h --- httpd-2.2.6/os/unix/unixd.h 2006-07-12 06:38:44.000000000 +0300 +++ httpd-2.2.6.new/os/unix/unixd.h 2007-10-11 12:32:28.000000000 +0300 @@ -72,6 +72,7 @@ uid_t user_id; gid_t group_id; int suexec_enabled; + const char *chroot_dir; } unixd_config_rec; AP_DECLARE_DATA extern unixd_config_rec unixd_config; @@ -81,6 +82,9 @@ const char *arg); AP_DECLARE(const char *) unixd_set_group(cmd_parms *cmd, void *dummy, const char *arg); +AP_DECLARE(const char *) unixd_set_chroot_dir(cmd_parms *cmd, void *dummy, + const char *arg); + #if defined(RLIMIT_CPU) || defined(RLIMIT_DATA) || defined(RLIMIT_VMEM) || defined(RLIMIT_NPROC) || defined(RLIMIT_AS) AP_DECLARE(void) unixd_set_rlimit(cmd_parms *cmd, struct rlimit **plimit, const char *arg, const char * arg2, int type); @@ -111,7 +115,8 @@ AP_INIT_TAKE1("User", unixd_set_user, NULL, RSRC_CONF, \ "Effective user id for this server"), \ AP_INIT_TAKE1("Group", unixd_set_group, NULL, RSRC_CONF, \ - "Effective group id for this server") - + "Effective group id for this server"), \ +AP_INIT_TAKE1("ChrootDir", unixd_set_chroot_dir, NULL, RSRC_CONF, \ + "The directory to chroot(2) into") #endif /** @} */