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;
 

Reply via email to