Came across something else in testing mod_fcgid. mod_fastcgi would consider
every symbolic link to the same program as a unique program and would start it
up based on the program name and not the inode/device node. Since mod_fcgid
only was checking inode/device node, symbolic links were considered the same
as the real program. Does anybody think that is a needed behaviour? Why would
you rename the program name and still want to consider it the same program?
Either way I made a patch that can retain the old behaviour via a directive.
If it's decided that the old behaviour is unneeded I can take the directive
out and make it respect program name by default. I included the patch for
review and if every thing is cool I'll write the xml for the new directive.
Index: modules/fcgid/fcgid_pm_main.c
===================================================================
--- modules/fcgid/fcgid_pm_main.c (revision 818854)
+++ modules/fcgid/fcgid_pm_main.c (working copy)
@@ -19,6 +19,7 @@
#define CORE_PRIVATE
#include "httpd.h"
#include "http_config.h"
+#include "apr_strings.h"
#include "fcgid_pm.h"
#include "fcgid_pm_main.h"
@@ -487,6 +488,10 @@
/* Prepare to spawn */
procnode->deviceid = command->deviceid;
procnode->inode = command->inode;
+ apr_cpystrn(procnode->cgipath, command->cgipath, _POSIX_PATH_MAX);
+ if ((procnode->cgiNameOffset = (ap_strrchr_c(command->cgipath, '/') - command->cgipath)) < 0) {
+ procnode->cgiNameOffset = 0;
+ }
procnode->share_grp_id = command->share_grp_id;
procnode->virtualhost = command->virtualhost;
procnode->uid = command->uid;
@@ -561,8 +566,9 @@
/* Wait for command */
if (procmgr_peek_cmd(&command, main_server) == APR_SUCCESS) {
- if (is_spawn_allowed(main_server, &command))
+ if (is_spawn_allowed(main_server, &command)) {
fastcgi_spawn(&command, main_server, configpool);
+ }
procmgr_finish_notify(main_server);
}
Index: modules/fcgid/fcgid_conf.c
===================================================================
--- modules/fcgid/fcgid_conf.c (revision 818854)
+++ modules/fcgid/fcgid_conf.c (working copy)
@@ -81,6 +81,7 @@
* config->default_init_env = NULL;
* config->pass_headers = NULL;
* config->php_fix_pathinfo_enable = 0;
+ * config->cgi_name_significant = 0;
* config->*_set = 0;
*/
config->ipc_comm_timeout = DEFAULT_IPC_COMM_TIMEOUT;
@@ -303,6 +304,23 @@
return NULL;
}
+const char *set_cgi_name_significant(cmd_parms * cmd, void *dummy,
+ const char *arg)
+{
+ server_rec *s = cmd->server;
+ fcgid_server_conf *config =
+ ap_get_module_config(s->module_config, &fcgid_module);
+ const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
+
+ if (err != NULL) {
+ return err;
+ }
+
+ config->cgi_name_significant = atol(arg);
+ return NULL;
+ }
+
+
const char *set_socketpath(cmd_parms * cmd, void *dummy, const char *arg)
{
server_rec *s = cmd->server;
Index: modules/fcgid/fcgid_spawn_ctl.c
===================================================================
--- modules/fcgid/fcgid_spawn_ctl.c (revision 818854)
+++ modules/fcgid/fcgid_spawn_ctl.c (working copy)
@@ -17,12 +17,15 @@
#include "fcgid_spawn_ctl.h"
#include "fcgid_conf.h"
+#include "apr_strings.h"
#define REGISTER_LIFE 1
#define REGISTER_DEATH 2
struct fcgid_stat_node {
apr_ino_t inode;
dev_t deviceid;
+ char cgipath[_POSIX_PATH_MAX];
+ int cgiNameOffset;
uid_t uid;
gid_t gid;
apr_size_t share_grp_id;
@@ -57,7 +60,8 @@
&& current_node->share_grp_id == procnode->share_grp_id
&& current_node->virtualhost == procnode->virtualhost
&& current_node->uid == procnode->uid
- && current_node->gid == procnode->gid)
+ && current_node->gid == procnode->gid
+ && !(sconf->cgi_name_significant && (apr_strnatcmp (current_node->cgipath+current_node->cgiNameOffset, procnode->cgipath+procnode->cgiNameOffset) != 0)))
break;
previous_node = current_node;
}
@@ -90,6 +94,8 @@
current_node = apr_pcalloc(g_stat_pool, sizeof(*current_node));
current_node->deviceid = procnode->deviceid;
current_node->inode = procnode->inode;
+ apr_cpystrn(current_node->cgipath, procnode->cgipath, _POSIX_PATH_MAX);
+ current_node->cgiNameOffset = procnode->cgiNameOffset;
current_node->share_grp_id = procnode->share_grp_id;
current_node->virtualhost = procnode->virtualhost;
current_node->uid = procnode->uid;
@@ -146,7 +152,12 @@
struct fcgid_stat_node *current_node;
fcgid_server_conf *sconf = ap_get_module_config(main_server->module_config,
&fcgid_module);
-
+ int cgiNameOffset;
+ if ((cgiNameOffset = (ap_strrchr_c(command->cgipath, '/') - command->cgipath)) < 0) {
+ cgiNameOffset = 0;
+ }
+ char *cgipath = command->cgipath+cgiNameOffset;
+
if (!command || !g_stat_pool)
return 1;
@@ -158,7 +169,8 @@
&& current_node->share_grp_id == command->share_grp_id
&& current_node->virtualhost == command->virtualhost
&& current_node->uid == command->uid
- && current_node->gid == command->gid)
+ && current_node->gid == command->gid
+ && !(sconf->cgi_name_significant && (apr_strnatcmp (current_node->cgipath+current_node->cgiNameOffset, cgipath) != 0)))
break;
}
@@ -225,7 +237,8 @@
&& current_node->share_grp_id == procnode->share_grp_id
&& current_node->virtualhost == procnode->virtualhost
&& current_node->uid == procnode->uid
- && current_node->gid == procnode->gid)
+ && current_node->gid == procnode->gid
+ && !(sconf->cgi_name_significant && (apr_strnatcmp (current_node->cgipath+current_node->cgiNameOffset, procnode->cgipath+procnode->cgiNameOffset) != 0)))
break;
previous_node = current_node;
}
Index: modules/fcgid/fcgid_conf.h
===================================================================
--- modules/fcgid/fcgid_conf.h (revision 818854)
+++ modules/fcgid/fcgid_conf.h (working copy)
@@ -80,6 +80,7 @@
int termination_score;
int time_score;
int zombie_scan_interval;
+ int cgi_name_significant;
/* global or vhost
* scalar values have corresponding _set field to aid merging
*/
@@ -159,6 +160,9 @@
const char *set_max_request_len(cmd_parms * cmd, void *dummy,
const char *arg);
+const char *set_cgi_name_significant(cmd_parms * cmd, void *dummy,
+ const char *arg);
+
const char *set_max_mem_request_len(cmd_parms * cmd, void *dummy,
const char *arg);
Index: modules/fcgid/fcgid_proctbl.h
===================================================================
--- modules/fcgid/fcgid_proctbl.h (revision 818854)
+++ modules/fcgid/fcgid_proctbl.h (working copy)
@@ -42,6 +42,8 @@
char socket_path[_POSIX_PATH_MAX]; /* cgi application socket path */
apr_ino_t inode; /* cgi file inode */
apr_dev_t deviceid; /* cgi file device id */
+ char cgipath[_POSIX_PATH_MAX]; /* cgi file path */
+ int cgiNameOffset; /* program name in cgipath */
gid_t gid; /* for suEXEC */
uid_t uid; /* for suEXEC */
apr_size_t share_grp_id; /* cgi wrapper share group id */
Index: modules/fcgid/mod_fcgid.c
===================================================================
--- modules/fcgid/mod_fcgid.c (revision 818854)
+++ modules/fcgid/mod_fcgid.c (working copy)
@@ -684,6 +684,11 @@
AP_INIT_TAKE1("FCGIDZombieScanInterval", set_zombie_scan_interval, NULL,
RSRC_CONF,
"scan interval for zombie process"),
+ AP_INIT_TAKE1("FCGIDCGINameSignificant",
+ set_cgi_name_significant,
+ NULL, RSRC_CONF,
+ "Set 1, if program/script name makes it unique"),
+
/* The following directives are all deprecated in favor
* of a consistent use of the FCGID prefix.
Index: modules/fcgid/fcgid_bridge.c
===================================================================
--- modules/fcgid/fcgid_bridge.c (revision 818854)
+++ modules/fcgid/fcgid_bridge.c (working copy)
@@ -38,6 +38,9 @@
{
/* Scan idle list, find a node match inode, deviceid and groupid
If there is no one there, return NULL */
+
+ fcgid_server_conf *sconf = ap_get_module_config(s->module_config,
+ &fcgid_module);
fcgid_procnode *previous_node, *current_node, *next_node;
fcgid_procnode *busy_list_header, *proc_table;
apr_ino_t inode = command->inode;
@@ -46,7 +49,13 @@
gid_t gid = command->gid;
apr_size_t share_grp_id = command->share_grp_id;
const char *virtualhost = command->virtualhost;
-
+ int cgi_name_significant = sconf->cgi_name_significant;
+ int cgiNameOffset;
+ if ((cgiNameOffset = (ap_strrchr_c(command->cgipath, '/') - command->cgipath)) < 0) {
+ cgiNameOffset = 0;
+ }
+ char *cgipath = command->cgipath+cgiNameOffset;
+
proc_table = proctable_get_table_array();
previous_node = proctable_get_idle_list();
busy_list_header = proctable_get_busy_list();
@@ -60,7 +69,8 @@
&& current_node->deviceid == deviceid
&& current_node->share_grp_id == share_grp_id
&& current_node->virtualhost == virtualhost
- && current_node->uid == uid && current_node->gid == gid) {
+ && current_node->uid == uid && current_node->gid == gid
+ && !(cgi_name_significant && (apr_strnatcmp (current_node->cgipath+current_node->cgiNameOffset, cgipath) != 0))) {
/* Unlink from idle list */
previous_node->next_index = current_node->next_index;