#include #include "httpd.h" #include "http_config.h" #include "http_core.h" #include "http_main.h" #include "http_log.h" #ifdef EAPI #include "ap_ctx.h" #include "http_conf_globals.h" #endif #define MODULE_SIGNATURE "mod_chroot/0.5" module MODULE_VAR_EXPORT chroot_module; typedef struct { char *chroot_dir; } chroot_srv_config; #ifdef EAPI typedef struct { int initcount; } chroot_ctx_rec; #endif int chroot_init_now() { #ifndef EAPI if(getenv("APACHE_MOD_CHROOT_INIT")!=NULL) { unsetenv("APACHE_MOD_CHROOT_INIT"); return 1; } else { setenv("APACHE_MOD_CHROOT_INIT", "", 0); return 0; } #else chroot_ctx_rec *m; m=(chroot_ctx_rec *)ap_ctx_get(ap_global_ctx, "chroot_module"); if(m->initcount==0) { m->initcount=1; return 0; } else return 1; #endif } void chroot_init_ctx() { #ifdef EAPI chroot_ctx_rec *m; pool *p; m=ap_ctx_get(ap_global_ctx, "chroot_module"); if(m==NULL) { p=ap_make_sub_pool(NULL); m=ap_palloc(p, sizeof(chroot_ctx_rec)); m->initcount=0; ap_ctx_set(ap_global_ctx, "chroot_module", m); } return; #else unsetenv("__APACHE_MOD_CHROOT_INIT"); #endif } void chroot_init(server_rec *s, pool *p) { chroot_srv_config *cfg = (chroot_srv_config *)ap_get_module_config(s->module_config, &chroot_module); ap_add_version_component(MODULE_SIGNATURE); if(cfg->chroot_dir==NULL) return; chroot_init_ctx(); if(chroot_init_now()) { if(chroot(cfg->chroot_dir)<0) { ap_log_error(APLOG_MARK, APLOG_ERR, s, "chroot to %s failed.", cfg->chroot_dir); return; } if(chdir("/")<0) { ap_log_error(APLOG_MARK, APLOG_ERR, s, "chdir to / failed."); return; } #ifndef EAPI ap_log_error(APLOG_MARK, APLOG_NOTICE | APLOG_NOERRNO, s, "mod_chroot: changed root to %s (environment magic).", cfg->chroot_dir); #else ap_log_error(APLOG_MARK, APLOG_NOTICE | APLOG_NOERRNO, s, "mod_chroot: changed root to %s (EAPI mode).", cfg->chroot_dir); #endif } } static void *chroot_create_srv_config(pool *p, server_rec *s) { chroot_srv_config *cfg = (chroot_srv_config *)ap_pcalloc(p, sizeof(chroot_srv_config)); if(cfg==NULL) return NULL; chroot_init_ctx(); cfg->chroot_dir=NULL; return cfg; } static const char *cmd_chroot_dir(cmd_parms *cmd, void *dummy, char *p1) { chroot_srv_config *cfg = (chroot_srv_config *)ap_get_module_config(cmd->server->module_config, &chroot_module); if(!ap_is_directory(p1)) return "Chroot to something that is not a directory"; cfg->chroot_dir = p1; return NULL; } static const command_rec chroot_cmds[] = { { "ChrootDir", cmd_chroot_dir, NULL, RSRC_CONF, TAKE1, "path to a new root directory" }, { NULL } }; module MODULE_VAR_EXPORT chroot_module = { STANDARD_MODULE_STUFF, chroot_init, NULL, /* create per-dir config structures */ NULL, /* merge per-dir config structures */ chroot_create_srv_config, /* create per-server config structures */ NULL, /* merge per-server config structures */ chroot_cmds, /* table of config file commands */ NULL, /* [#8] MIME-typed-dispatched handlers */ NULL, /* [#1] URI to filename translation */ NULL, /* [#4] validate user id from request */ NULL, /* [#5] check if the user is ok _here_ */ NULL, /* [#3] check access by host address */ NULL, /* [#6] determine MIME type */ NULL, /* [#7] pre-run fixups */ NULL, /* [#9] log a transaction */ NULL, /* [#2] header parser */ NULL, /* child_init */ NULL, /* child_exit */ NULL /* [#0] post read-request */ };