https://bz.apache.org/bugzilla/show_bug.cgi?id=62061 https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=888824 Index: libapache2-mod-fcgid-2.3.9/modules/fcgid/fcgid_conf.c =================================================================== --- libapache2-mod-fcgid-2.3.9.orig/modules/fcgid/fcgid_conf.c +++ libapache2-mod-fcgid-2.3.9/modules/fcgid/fcgid_conf.c @@ -169,9 +169,15 @@ void *merge_fcgid_server_config(apr_pool return merged; } -void *create_fcgid_dir_config(apr_pool_t * p, char *dummy) +void *create_fcgid_dir_config(apr_pool_t * p, char *context) { + static int dir_id = 0; + fcgid_dir_conf *config = apr_pcalloc(p, sizeof(fcgid_dir_conf)); + ++dir_id; + + config->dir_id = dir_id; + config->context = context; config->wrapper_info_hash = apr_hash_make(p); /* config->authenticator_info = NULL; */ @@ -180,6 +186,7 @@ void *create_fcgid_dir_config(apr_pool_t config->authorizer_authoritative = 1; /* config->access_info = NULL; */ config->access_authoritative = 1; + /* config->default_init_env = NULL;*/ return (void *) config; } @@ -190,6 +197,21 @@ void *merge_fcgid_dir_config(apr_pool_t fcgid_dir_conf *merged = (fcgid_dir_conf *) apr_pmemdup(p, local, sizeof(fcgid_dir_conf)); + /* Merge environment variables */ + if (base->default_init_env == NULL) { + /* merged already set to local */ + } + else if (local->default_init_env == NULL) { + merged->default_init_env = base->default_init_env; + } + else { + merged->default_init_env = + apr_table_copy(p, base->default_init_env); + apr_table_overlap(merged->default_init_env, + local->default_init_env, + APR_OVERLAP_TABLES_SET); + } + merged->wrapper_info_hash = apr_hash_overlay(p, local->wrapper_info_hash, base->wrapper_info_hash); @@ -570,15 +592,27 @@ static void add_envvar_to_table(apr_tabl apr_table_set(t, name, value ? value : ""); } -const char *add_default_env_vars(cmd_parms * cmd, void *dummy, +const char *add_default_env_vars(cmd_parms * cmd, void *dir_config, const char *name, const char *value) { + if (cmd->path != NULL) { /* dir context (Directory / Files / Location) */ + fcgid_dir_conf *dconfig = ap_get_module_config(cmd->context, &fcgid_module); + + if (dconfig->default_init_env == NULL) + dconfig->default_init_env = apr_table_make(cmd->pool, 20); + + add_envvar_to_table(dconfig->default_init_env, cmd->pool, name, value); + + return NULL; + } + fcgid_server_conf *config = ap_get_module_config(cmd->server->module_config, &fcgid_module); if (config->default_init_env == NULL) config->default_init_env = apr_table_make(cmd->pool, 20); - + add_envvar_to_table(config->default_init_env, cmd->pool, name, value); + return NULL; } @@ -935,13 +969,17 @@ fcgid_cmd_conf *get_wrapper_info(const c return NULL; } -static int set_cmd_envvars(fcgid_cmd_env *cmdenv, apr_table_t *envvars) +static int set_cmd_envvars(fcgid_cmd_env *cmdenv, apr_table_t *envvars, apr_table_t *denvvars) { const apr_array_header_t *envvars_arr; const apr_table_entry_t *envvars_entry; int i; int overflow = 0; + if (denvvars) { /* directory environment overwrites vhost environment */ + envvars = denvvars; + } + if (envvars) { envvars_arr = apr_table_elts(envvars); envvars_entry = (apr_table_entry_t *) envvars_arr->elts; @@ -1106,7 +1144,7 @@ const char *set_cmd_options(cmd_parms *c option); } - if ((overflow = set_cmd_envvars(cmdopts->cmdenv, envvars)) != 0) { + if ((overflow = set_cmd_envvars(cmdopts->cmdenv, envvars, NULL)) != 0) { return apr_psprintf(cmd->pool, "mod_fcgid: environment variable table " "overflow; increase INITENV_CNT in fcgid_pm.h from" " %d to at least %d", @@ -1122,6 +1160,8 @@ void get_cmd_options(request_rec *r, con fcgid_cmd_options *cmdopts, fcgid_cmd_env *cmdenv) { + fcgid_dir_conf *dconf = ap_get_module_config(r->per_dir_config, &fcgid_module); + fcgid_server_conf *sconf = ap_get_module_config(r->server->module_config, &fcgid_module); fcgid_cmd_options *cmd_specific = apr_hash_get(sconf->cmdopts_hash, @@ -1149,7 +1189,7 @@ void get_cmd_options(request_rec *r, con cmdopts->min_class_process_count = sconf->min_class_process_count; cmdopts->proc_lifetime = sconf->proc_lifetime; - if ((overflow = set_cmd_envvars(cmdenv, sconf->default_init_env)) != 0) { + if ((overflow = set_cmd_envvars(cmdenv, sconf->default_init_env, dconf->default_init_env)) != 0) { ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, "mod_fcgid: %d environment variables dropped; increase " "INITENV_CNT in fcgid_pm.h from %d to at least %d", Index: libapache2-mod-fcgid-2.3.9/modules/fcgid/mod_fcgid.c =================================================================== --- libapache2-mod-fcgid-2.3.9.orig/modules/fcgid/mod_fcgid.c +++ libapache2-mod-fcgid-2.3.9/modules/fcgid/mod_fcgid.c @@ -306,6 +306,8 @@ static int fcgidsort(fcgid_procnode **e1 return cmp; if ((*e1)->vhost_id != (*e2)->vhost_id) return (*e1)->vhost_id > (*e2)->vhost_id ? 1 : -1; + if ((*e1)->dir_id != (*e2)->dir_id) + return (*e1)->dir_id > (*e2)->dir_id ? 1 : -1; if ((*e1)->diewhy != (*e2)->diewhy) return (*e1)->diewhy > (*e2)->diewhy ? 1 : -1; if ((*e1)->node_type != (*e2)->node_type) @@ -353,6 +355,7 @@ static int fcgid_status_hook(request_rec const char *last_cmdline = ""; apr_time_t now; int last_vhost_id = -1; + int last_dir_id = -1; const char *basename, *tmpbasename; fcgid_procnode *proc_table = proctable_get_table_array(); fcgid_procnode *error_list_header = proctable_get_error_list(); @@ -425,7 +428,8 @@ static int fcgid_status_hook(request_rec if (current_node->inode != last_inode || current_node->deviceid != last_deviceid || current_node->gid != last_gid || current_node->uid != last_uid || strcmp(current_node->cmdline, last_cmdline) - || current_node->vhost_id != last_vhost_id) { + || current_node->vhost_id != last_vhost_id + || current_node->dir_id != last_dir_id) { if (index != 0) ap_rputs("\n\n", r); @@ -438,8 +442,8 @@ static int fcgid_status_hook(request_rec basename++; else basename = tmpbasename; - ap_rprintf(r, "
\nProcess: %s  (%s)
\n", - basename, current_node->cmdline); + ap_rprintf(r, "
\nProcess: %s  (%s at %s)
\n", + basename, current_node->cmdline, current_node->context); /* Create a new table for this process info */ ap_rputs("\n\n" @@ -453,6 +457,7 @@ static int fcgid_status_hook(request_rec last_uid = current_node->uid; last_cmdline = current_node->cmdline; last_vhost_id = current_node->vhost_id; + last_dir_id = current_node->dir_id; } ap_rprintf(r, "", @@ -751,7 +756,7 @@ static const command_rec fcgid_cmds[] = "a fastcgi application will be killed after handling a request for BusyTimeout"), AP_INIT_RAW_ARGS("FcgidCmdOptions", set_cmd_options, NULL, RSRC_CONF, "set processing options for a FastCGI command"), - AP_INIT_TAKE12("FcgidInitialEnv", add_default_env_vars, NULL, RSRC_CONF, + AP_INIT_TAKE12("FcgidInitialEnv", add_default_env_vars, NULL, ACCESS_CONF | RSRC_CONF, "an environment variable name and optional value to pass to FastCGI."), AP_INIT_TAKE1("FcgidMaxProcessesPerClass", set_max_class_process, Index: libapache2-mod-fcgid-2.3.9/modules/fcgid/fcgid_conf.h =================================================================== --- libapache2-mod-fcgid-2.3.9.orig/modules/fcgid/fcgid_conf.h +++ libapache2-mod-fcgid-2.3.9/modules/fcgid/fcgid_conf.h @@ -130,6 +130,11 @@ typedef struct { fcgid_cmd_conf *access_info; int access_authoritative; int access_authoritative_set; + + /* context info */ + apr_table_t *default_init_env; + int dir_id; + const char *context; } fcgid_dir_conf; /* processing options which are sent to the PM with a spawn request Index: libapache2-mod-fcgid-2.3.9/modules/fcgid/fcgid_bridge.c =================================================================== --- libapache2-mod-fcgid-2.3.9.orig/modules/fcgid/fcgid_bridge.c +++ libapache2-mod-fcgid-2.3.9/modules/fcgid/fcgid_bridge.c @@ -60,6 +60,7 @@ static fcgid_procnode *apply_free_procno && current_node->deviceid == deviceid && !strcmp(current_node->cmdline, cmdline) && current_node->vhost_id == command->vhost_id + && current_node->dir_id == command->dir_id && current_node->uid == uid && current_node->gid == gid) { /* Unlink from idle list */ previous_node->next_index = current_node->next_index; @@ -140,6 +141,7 @@ static int count_busy_processes(request_ && current_node->deviceid == command->deviceid && !strcmp(current_node->cmdline, command->cmdline) && current_node->vhost_id == command->vhost_id + && current_node->dir_id == command->dir_id && current_node->uid == command->uid && current_node->gid == command->gid) { result++; Index: libapache2-mod-fcgid-2.3.9/modules/fcgid/fcgid_pm.h =================================================================== --- libapache2-mod-fcgid-2.3.9.orig/modules/fcgid/fcgid_pm.h +++ libapache2-mod-fcgid-2.3.9/modules/fcgid/fcgid_pm.h @@ -29,6 +29,8 @@ typedef struct { * module may have copied it for per-request customization */ int vhost_id; + int dir_id; + const char* context; char server_hostname[32]; /* for logging only; ok to truncate */ uid_t uid; /* For suEXEC */ gid_t gid; /* For suEXEC */ Index: libapache2-mod-fcgid-2.3.9/modules/fcgid/fcgid_pm_main.c =================================================================== --- libapache2-mod-fcgid-2.3.9.orig/modules/fcgid/fcgid_pm_main.c +++ libapache2-mod-fcgid-2.3.9/modules/fcgid/fcgid_pm_main.c @@ -563,6 +563,8 @@ fastcgi_spawn(fcgid_command * command, s apr_cpystrn(procnode->cmdline, command->cmdline, sizeof procnode->cmdline); procnode->vhost_id = command->vhost_id; + procnode->dir_id = command->dir_id; + procnode->context = command->context; procnode->uid = command->uid; procnode->gid = command->gid; procnode->start_time = procnode->last_active_time = apr_time_now(); Index: libapache2-mod-fcgid-2.3.9/modules/fcgid/fcgid_pm_unix.c =================================================================== --- libapache2-mod-fcgid-2.3.9.orig/modules/fcgid/fcgid_pm_unix.c +++ libapache2-mod-fcgid-2.3.9/modules/fcgid/fcgid_pm_unix.c @@ -426,6 +426,8 @@ void procmgr_init_spawn_cmd(fcgid_comman ap_unix_identity_t *ugid; fcgid_server_conf *sconf = ap_get_module_config(r->server->module_config, &fcgid_module); + fcgid_dir_conf *dconf = + ap_get_module_config(r->per_dir_config, &fcgid_module); /* suEXEC check */ if ((ugid = ap_run_get_suexec_identity(r))) { @@ -447,6 +449,8 @@ void procmgr_init_spawn_cmd(fcgid_comman command->deviceid = cmd_conf->deviceid; command->inode = cmd_conf->inode; command->vhost_id = sconf->vhost_id; + command->dir_id = dconf->dir_id; + command->context = dconf->context; if (r->server->server_hostname) { apr_cpystrn(command->server_hostname, r->server->server_hostname, sizeof command->server_hostname); Index: libapache2-mod-fcgid-2.3.9/modules/fcgid/fcgid_pm_win.c =================================================================== --- libapache2-mod-fcgid-2.3.9.orig/modules/fcgid/fcgid_pm_win.c +++ libapache2-mod-fcgid-2.3.9/modules/fcgid/fcgid_pm_win.c @@ -135,6 +135,8 @@ void procmgr_init_spawn_cmd(fcgid_comman { fcgid_server_conf *sconf = ap_get_module_config(r->server->module_config, &fcgid_module); + fcgid_dir_conf *dconf = + ap_get_module_config(r->per_dir_config, &fcgid_module); /* no truncation should ever occur */ AP_DEBUG_ASSERT(sizeof command->cgipath > strlen(cmd_conf->cgipath)); @@ -148,6 +150,8 @@ void procmgr_init_spawn_cmd(fcgid_comman command->gid = (gid_t) - 1; command->userdir = 0; command->vhost_id = sconf->vhost_id; + command->dir_id = dconf->dir_id; + command->context = dconf->context; if (r->server->server_hostname) { apr_cpystrn(command->server_hostname, r->server->server_hostname, sizeof command->server_hostname); Index: libapache2-mod-fcgid-2.3.9/modules/fcgid/fcgid_proctbl.h =================================================================== --- libapache2-mod-fcgid-2.3.9.orig/modules/fcgid/fcgid_proctbl.h +++ libapache2-mod-fcgid-2.3.9/modules/fcgid/fcgid_proctbl.h @@ -52,6 +52,8 @@ typedef struct { int vhost_id; /* the vhost to which this process belongs (the server_rec * addr fails with some mass-vhost mods which allocate * them per-request) */ + int dir_id; /* process class connected to dir */ + const char* context; /* dir/location of process class */ apr_time_t start_time; /* the time of this process create */ apr_time_t last_active_time; /* the time this process last active */ int requests_handled; /* number of requests process has handled */ Index: libapache2-mod-fcgid-2.3.9/modules/fcgid/fcgid_spawn_ctl.c =================================================================== --- libapache2-mod-fcgid-2.3.9.orig/modules/fcgid/fcgid_spawn_ctl.c +++ libapache2-mod-fcgid-2.3.9/modules/fcgid/fcgid_spawn_ctl.c @@ -30,6 +30,7 @@ struct fcgid_stat_node { gid_t gid; const char *cmdline; int vhost_id; + int dir_id; int score; int process_counter; int max_class_process_count; @@ -62,6 +63,7 @@ register_life_death(server_rec * main_se && current_node->deviceid == procnode->deviceid && !strcmp(current_node->cmdline, procnode->cmdline) && current_node->vhost_id == procnode->vhost_id + && current_node->dir_id == procnode->dir_id && current_node->uid == procnode->uid && current_node->gid == procnode->gid) break; @@ -80,6 +82,7 @@ register_life_death(server_rec * main_se current_node->inode = procnode->inode; current_node->cmdline = apr_pstrdup(g_stat_pool, procnode->cmdline); current_node->vhost_id = procnode->vhost_id; + current_node->dir_id = procnode->dir_id; current_node->uid = procnode->uid; current_node->gid = procnode->gid; current_node->last_stat_time = now; @@ -179,6 +182,7 @@ int is_spawn_allowed(server_rec * main_s && current_node->deviceid == command->deviceid && !strcmp(current_node->cmdline, command->cmdline) && current_node->vhost_id == command->vhost_id + && current_node->dir_id == command->dir_id && current_node->uid == command->uid && current_node->gid == command->gid) break; @@ -238,6 +242,7 @@ int is_kill_allowed(server_rec * main_se && current_node->deviceid == procnode->deviceid && !strcmp(current_node->cmdline, procnode->cmdline) && current_node->vhost_id == procnode->vhost_id + && current_node->dir_id == procnode->dir_id && current_node->uid == procnode->uid && current_node->gid == procnode->gid) break;
%" APR_PID_T_FMT "%" APR_TIME_T_FMT "%" APR_TIME_T_FMT "%d%s