Hi --

   Please find below a cumulative patch for a number of issues with
mod_fcgid; the patch should apply against CVS HEAD.  Some of these
are minor but most of them are crucial for anyone using the
FastCgiAuthenticator, FastCgiAuthorizer, and/or FastCgiAccessChecker
configuration directives.  The changes include:


1) Fix a typo in mod_fcgid.c so that FastCgiAuthorizer and
   FastCgiAuthorizerAuthoritative are defined.


2) Add per-directory configuration merging, as described in my previous
   email:

http://sourceforge.net/mailarchive/message.php?msg_name=46228B54.5060308%40pearsoncmg.com

   As an example, this allows:

<Directory />
    FastCgiAuthenticator /my/auth/fcgi
</Directory>
<Directory /public>
    FastCgiAuthenticator None
</Directory>


3) Fix a serious problem in handle_request() when using FCGI_AUTHORIZER
   role.  The existing code extracts the inode and deviceid from
   r->finfo and compares these to the inode and deviceid values
   for all available executing FastCGI processes.  If a match is found,
   then that process is used, otherwise a new one is spawned.

   The problem is that r->finfo describes the file being requested
   in the HTTP request.  In the FCGI_RESPONDER case, that file is
   the CGI script, and so the code works.  In the FCGI_AUTHORIZER case,
   though, the file in the request bears no relation to the authorizer
   script we want to execute.  For example, if access control is
   enabled on all images, then r->finfo and r->filename will describe
   whatever image the user is requesting (e.g., foo.gif).  In this
   case, the code almost never finds a match in the list of free
   FastCGI processes, and so it generates a huge number of spawn
   requests to the procmgr.  Each newly spawned process is then
   recorded using the inode and deviceid of the file that happened
   to be in the HTTP request (e.g., foo.gif), ensuring that future
   requests will also virtually never match and the process will
   never be used again.

   To fix this problem, my patch passes an auth_conf structure
   (renamed fcgid_auth_conf) to handle_request from which is can
   extract the correct inode, deviceid, etc.


4) Fix another problem in handle_request() where the same FastCGI
   process, if configured to be used in both FCGI_RESPONDER and
   FCGI_AUTHORIZER modes, will be spawned twice.  This is because
   when no wrapper_conf structure exists, the shareid value for
   the FCGI_RESPONDER role is set to 0.  However, the share_group_id
   value in all auth_conf structures is set to -1 in the same case
   (this is done by the set_authenticator_info(), etc. functions).

   Further, I'm fairly sure the use of 0 also conflicts with a valid
   wrapper_id.  In set_wrapper_config(), apr_pcalloc() is used to
   allocate the id_info structure, so the first id_info->cur_id
   and wrapper_id values should be, I think, 0.  I didn't test this
   myself.  At any rate, using -1 in handle_request() for the
   non-wrapper case means that there's a guarantee of no overlap,
   and a FastCGI process can respond to both FCGI_AUTHORIZER
   and FCGI_RESPONDER role requests.


5) Fix another problem in handle_request() where any request
   where the entire body of the FastCGI process's response was not
   read would cause the process not to be released into the
   free list until the entire request was complete.  This meant
   that a process used by the authentication phase handler, for example,
   would be retained in the busy list until the request completed,
   so it could not be reused in, for example, the authorization
   or content generation phases.

   In the normal FCGI_RESPONDER role case, handle_request() would
   call ap_pass_brigade() and when the final bucket was read
   from the FastCGI process's output, fcgid_header_bucket_read()
   would run the bucket_ctx_cleanup() function which would release
   the process back to the free list.

   However, if an error occurs, or if after reading just the HTTP
   headers with ap_scan_script_header_err_core() a redirction is
   performed, or in the FCGI_AUTHORIZER case where ap_pass_brigade()
   is never called, the FastCGI process will not be released until
   r->pool is destroyed at the end of the entire request processing
   sequence.  Anything that uses FastCGI in multiple request
   processing phases, or in sub-requests or internal redirections,
   will therefore consume more processes than necessary.

   To fix this, I moved all the IPC portions of handle_request()
   into a handle_request_ipc() sub-function, and after invoking
   handle_request_ipc(), handle_request() always runs the
   bucket_ctx_cleanup() function before returning; that function
   is a no-op if it has previously been called on the given
   fcgid_bucket_ctx structure.

Chris.

===========================================================
--- fcgid_bridge.c.orig 2007-05-09 18:44:31.570622000 -0400
+++ fcgid_bridge.c      2007-05-09 19:53:22.961994000 -0400
@@ -152,7 +152,13 @@
                ctx->buffer = NULL;
        }
 
-       proc_close_ipc(main_server, &ctx->ipc);
+       /* proc_close_ipc() and ipc_handle_cleanup() do their own sanity
+        * checks, but we'll do our own anyway
+        */
+       if (ctx->ipc.ipc_handle_info) {
+               proc_close_ipc(main_server, &ctx->ipc);
+               ctx->ipc.ipc_handle_info = NULL;
+       }
 
        if (ctx->procnode) {
                /* Return procnode
@@ -267,19 +273,102 @@
 }
 
 static int
+handle_request_ipc(request_rec *r, int role,
+                                  apr_bucket_brigade *output_brigade,
+                                  fcgid_bucket_ctx *bucket_ctx, const char 
**location_ptr)
+{
+       server_rec *main_server = r->server;
+    int cond_status;
+       apr_status_t rv;
+       apr_bucket_brigade *brigade_stdout;
+       char sbuf[MAX_STRING_LEN];
+    const char *location;
+
+       /* Write output_brigade to fastcgi server */
+       if ((rv =
+                proc_write_ipc(main_server, &bucket_ctx->ipc,
+                                               output_brigade)) != 
APR_SUCCESS) {
+               ap_log_error(APLOG_MARK, APLOG_WARNING, rv, r->server,
+                                        "mod_fcgid: write data to fastcgi 
server error");
+               bucket_ctx->has_error = 1;
+               return HTTP_INTERNAL_SERVER_ERROR;
+       }
+
+       /* Create brigade */
+       brigade_stdout =
+               apr_brigade_create(r->pool, r->connection->bucket_alloc);
+       if (!brigade_stdout) {
+               ap_log_error(APLOG_MARK, APLOG_WARNING, rv, r->server,
+                                        "mod_fcgid: apr_brigade_create failed 
in "
+                                        "handle_request function");
+               return HTTP_INTERNAL_SERVER_ERROR;
+       }
+       APR_BRIGADE_INSERT_TAIL(brigade_stdout,
+                                                       
ap_bucket_fcgid_header_create(r->connection->
+                                                                               
                                  bucket_alloc,
+                                                                               
                                  bucket_ctx));
+       /*APR_BRIGADE_INSERT_TAIL(brigade_stdout, 
apr_bucket_flush_create(r->connection->bucket_alloc)); */
+
+       /* Check the script header first. If got error, return immediately */
+       if ((cond_status = ap_scan_script_header_err_core
+                (r, sbuf, getsfunc_fcgid_BRIGADE, brigade_stdout)) >= 400)
+               return cond_status;
+
+       /* Check redirect */
+       location = apr_table_get(r->headers_out, "Location");
+
+       if (location && location[0] == '/' && r->status == 200) {
+               /* This redirect needs to be a GET no matter what the original 
+                * method was. 
+                */
+               r->method = apr_pstrdup(r->pool, "GET");
+               r->method_number = M_GET;
+
+               /* We are going to ignore the message body (if any), so don't 
allow 
+                * the redirected request to think it has one. We can ignore 
+                * Transfer-Encoding, since we used REQUEST_CHUNKED_ERROR. 
+                */
+               apr_table_unset(r->headers_in, "Content-Length");
+
+               *location_ptr = location;
+               return HTTP_OK;
+       } else if (location && r->status == 200) {
+               /* XX Note that if a script wants to produce its own Redirect 
+                * body, it now has to explicitly *say* "Status: 302" 
+                */
+               return HTTP_MOVED_TEMPORARILY;
+       }
+
+       /* Now pass to output filter */
+       if (role == FCGI_RESPONDER && (rv =
+                                                                  
ap_pass_brigade(r->output_filters,
+                                                                               
                   brigade_stdout)) !=
+               APR_SUCCESS) {
+               ap_log_error(APLOG_MARK, APLOG_WARNING, rv, r->server,
+                                        "mod_fcgid: ap_pass_brigade failed in "
+                                        "handle_request function");
+               return HTTP_INTERNAL_SERVER_ERROR;
+       }
+
+       /* Return condition status */
+       return cond_status;
+}
+
+static int
 handle_request(request_rec * r, int role, const char *argv0,
+                          fcgid_auth_conf * auth_conf,
                           fcgid_wrapper_conf * wrapper_conf,
                           apr_bucket_brigade * output_brigade)
 {
-       apr_pool_t *request_pool = r->main ? r->main->pool : r->pool;
        server_rec *main_server = r->server;
        fcgid_command fcgi_request;
        fcgid_bucket_ctx *bucket_ctx;
+       apr_ino_t inode;
+       apr_dev_t deviceid;
+       apr_size_t shareid;
        int i, j, cond_status;
        apr_status_t rv;
-       apr_bucket_brigade *brigade_stdout;
-       char sbuf[MAX_STRING_LEN];
-       const char *location;
+       const char *location = NULL;
 
        if (!g_variables_inited) {
                g_connect_timeout = get_ipc_connect_timeout(r->server);
@@ -292,7 +381,7 @@
                g_variables_inited = 1;
        }
 
-       bucket_ctx = apr_pcalloc(request_pool, sizeof(*bucket_ctx));
+       bucket_ctx = apr_pcalloc(r->pool, sizeof(*bucket_ctx));
        if (!bucket_ctx) {
                ap_log_error(APLOG_MARK, APLOG_WARNING, apr_get_os_error(),
                                         r->server,
@@ -302,20 +391,26 @@
        bucket_ctx->ipc.connect_timeout = g_connect_timeout;
        bucket_ctx->ipc.communation_timeout = g_comm_timeout;
        bucket_ctx->ipc.request = r;
-       apr_pool_cleanup_register(request_pool, bucket_ctx,
+       apr_pool_cleanup_register(r->pool, bucket_ctx,
                                                          bucket_ctx_cleanup, 
apr_pool_cleanup_null);
 
+       if (role == FCGI_AUTHORIZER) {
+               argv0 = auth_conf->path;
+               inode = wrapper_conf ? wrapper_conf->inode : auth_conf->inode;
+               deviceid = wrapper_conf ? wrapper_conf->deviceid : 
auth_conf->deviceid;
+               shareid = wrapper_conf ? wrapper_conf->share_group_id
+                                                          : 
auth_conf->share_group_id;
+       } else {
+               inode = wrapper_conf ? wrapper_conf->inode : r->finfo.inode;
+               deviceid = wrapper_conf ? wrapper_conf->deviceid : 
r->finfo.device;
+               shareid = wrapper_conf ? wrapper_conf->share_group_id
+                                                          : (apr_size_t) -1;
+       }
+
        /* Try to get a connected ipc handle */
        for (i = 0; i < FCGID_REQUEST_COUNT; i++) {
                /* Apply a free process slot, send a spawn request if I can't 
get one */
                for (j = 0; j < FCGID_APPLY_TRY_COUNT; j++) {
-                       apr_ino_t inode =
-                               wrapper_conf ? wrapper_conf->inode : 
r->finfo.inode;
-                       apr_dev_t deviceid =
-                               wrapper_conf ? wrapper_conf->deviceid : 
r->finfo.device;
-                       apr_size_t shareid =
-                               wrapper_conf ? wrapper_conf->share_group_id : 0;
-
                        /* Init spawn request */
                        procmgr_init_spawn_cmd(&fcgi_request, r, argv0, 
deviceid,
                                                                   inode, 
shareid);
@@ -367,90 +462,63 @@
        bucket_ctx->active_time = bucket_ctx->procnode->last_active_time =
                apr_time_now();
 
-       /* Write output_brigade to fastcgi server */
-       if ((rv =
-                proc_write_ipc(main_server, &bucket_ctx->ipc,
-                                               output_brigade)) != 
APR_SUCCESS) {
-               ap_log_error(APLOG_MARK, APLOG_WARNING, rv, r->server,
-                                        "mod_fcgid: write data to fastcgi 
server error");
-               bucket_ctx->has_error = 1;
-               return HTTP_INTERNAL_SERVER_ERROR;
-       }
+       cond_status = handle_request_ipc(r, role, output_brigade,
+                                                                        
bucket_ctx, &location);
 
-       /* Create brigade */
-       brigade_stdout =
-               apr_brigade_create(request_pool, r->connection->bucket_alloc);
-       if (!brigade_stdout) {
+       /* Release the process ASAP.  This may already have been done in
+        * ap_pass_brigade() by fcgid_header_bucket_read(), but not in the
+        * case where handle_request_ipc() returned early without reading
+        * the body of the HTTP response.  This could be because of an error,
+        * or because it found an status code in the HTTP headers that
+        * permits us to ignore the message body.
+        *
+        * As an example, when handling a request in the FCGI_AUTHORIZER role,
+        * we don't read through to the end of the response from the process,
+        * we just read the HTTP headers.  That means each phase of the
+        * request handling sequence (e.g., authentication, authorization, etc.)
+        * will require its own process unless we make sure to always release
+        * any process we acquired regardless of whether we're reading the
+        * response body.
+        *
+        * As another example, if we perform or cause an internal redirection
+        * (for instance, by returning an error code that invokes a script
+        * handler in ap_die() because of an ErrorDocument configuration), then
+        * we must also release the process we acquired here so that it is
+        * potentially available during the next handling phase.
+        */
+
+       if ((rv = apr_pool_cleanup_run(r->pool, bucket_ctx,
+                                                                  
bucket_ctx_cleanup)) != APR_SUCCESS) {
                ap_log_error(APLOG_MARK, APLOG_WARNING, rv, r->server,
-                                        "mod_fcgid: apr_brigade_create failed 
in handle_request function");
+                                        "mod_fcgid: bucket_ctx_cleanup failed 
in "
+                                        "handle_request function");
                return HTTP_INTERNAL_SERVER_ERROR;
        }
-       APR_BRIGADE_INSERT_TAIL(brigade_stdout,
-                                                       
ap_bucket_fcgid_header_create(r->connection->
-                                                                               
                                  bucket_alloc,
-                                                                               
                                  bucket_ctx));
-       /*APR_BRIGADE_INSERT_TAIL(brigade_stdout, 
apr_bucket_flush_create(r->connection->bucket_alloc)); */
-
-       /* Check the script header first. If got error, return immediately */
-       if ((cond_status = ap_scan_script_header_err_core
-                (r, sbuf, getsfunc_fcgid_BRIGADE, brigade_stdout)) >= 400)
-               return cond_status;
-
-       /* Check redirect */
-       location = apr_table_get(r->headers_out, "Location");
-
-       if (location && location[0] == '/' && r->status == 200) {
-               /* This redirect needs to be a GET no matter what the original 
-                * method was. 
-                */
-               r->method = apr_pstrdup(r->pool, "GET");
-               r->method_number = M_GET;
-
-               /* We already read the message body (if any), so don't allow 
-                * the redirected request to think it has one. We can ignore 
-                * Transfer-Encoding, since we used REQUEST_CHUNKED_ERROR. 
-                */
-               apr_table_unset(r->headers_in, "Content-Length");
 
+       /* Perform internal redirection if necessary */
+       if (location)
                ap_internal_redirect_handler(location, r);
-               return HTTP_OK;
-       } else if (location && r->status == 200) {
-               /* XX Note that if a script wants to produce its own Redirect 
-                * body, it now has to explicitly *say* "Status: 302" 
-                */
-               return HTTP_MOVED_TEMPORARILY;
-       }
-
-       /* Now pass to output filter */
-       if (role == FCGI_RESPONDER && (rv =
-                                                                  
ap_pass_brigade(r->output_filters,
-                                                                               
                   brigade_stdout)) !=
-               APR_SUCCESS) {
-               ap_log_error(APLOG_MARK, APLOG_WARNING, rv, r->server,
-                                        "mod_fcgid: ap_pass_brigade failed in 
handle_request function");
-               return HTTP_INTERNAL_SERVER_ERROR;
-       }
 
-       /* Retrun condition status */
+       /* Return condition status */
        return cond_status;
 }
 
 int bridge_request(request_rec * r, int role, const char *argv0,
+                                  fcgid_auth_conf * auth_conf,
                                   fcgid_wrapper_conf * wrapper_conf)
 {
-       apr_pool_t *request_pool = r->main ? r->main->pool : r->pool;
        server_rec *main_server = r->server;
        apr_status_t rv = APR_SUCCESS;
        int seen_eos;
        FCGI_Header *stdin_request_header;
        apr_bucket_brigade *output_brigade;
        apr_bucket *bucket_input, *bucket_header, *bucket_eos;
-       char **envp = ap_create_environment(request_pool,
+       char **envp = ap_create_environment(r->pool,
                                                                                
r->subprocess_env);
 
        /* Create brigade for the request to fastcgi server */
        output_brigade =
-               apr_brigade_create(request_pool, r->connection->bucket_alloc);
+               apr_brigade_create(r->pool, r->connection->bucket_alloc);
        if (!output_brigade) {
                ap_log_error(APLOG_MARK, APLOG_WARNING, apr_get_os_error(),
                                         main_server,
@@ -480,7 +548,7 @@
        seen_eos = 0;
        do {
                apr_bucket_brigade *input_brigade =
-                       apr_brigade_create(request_pool,
+                       apr_brigade_create(r->pool,
                                                           
r->connection->bucket_alloc);
 
                if (!input_brigade
@@ -588,5 +656,6 @@
        APR_BRIGADE_INSERT_TAIL(output_brigade, bucket_eos);
 
        /* Bridge the request */
-       return handle_request(r, role, argv0, wrapper_conf, output_brigade);
+       return handle_request(r, role, argv0, auth_conf, wrapper_conf,
+                                                 output_brigade);
 }
--- fcgid_bridge.h.orig 2007-05-09 18:44:36.790835000 -0400
+++ fcgid_bridge.h      2007-05-09 19:04:07.370353000 -0400
@@ -8,6 +8,7 @@
 
 apr_status_t bucket_ctx_cleanup(void *thectx);
 int bridge_request(request_rec * r, int role, const char *argv0,
+                                  fcgid_auth_conf * auth_conf,
                                   fcgid_wrapper_conf * wrapper_conf);
 
 #endif
--- fcgid_conf.c.orig   2007-05-09 18:44:24.072131000 -0400
+++ fcgid_conf.c        2007-05-09 18:59:56.922046000 -0400
@@ -148,6 +148,74 @@
        return (void *) config;
 }
 
+void *merge_dir_config_value(void *base, void *overrides,
+                                                        int base_overwrite, 
int overrides_overwrite,
+                                                        int *overwrite_ptr)
+{
+       if(overrides_overwrite) {
+               *overwrite_ptr = 1;
+               return overrides;
+       } else {
+               *overwrite_ptr = base_overwrite;
+               return base;
+       }
+}
+
+void *merge_fcgid_dir_config(apr_pool_t * p, void *basev, void *overridesv)
+{
+       fcgid_dir_conf *base = (fcgid_dir_conf *) basev;
+       fcgid_dir_conf *overrides = (fcgid_dir_conf *) overridesv;
+       fcgid_dir_conf *config = apr_pcalloc(p, sizeof(fcgid_dir_conf));
+
+       config->wrapper_info_hash =
+               apr_hash_overlay(p, overrides->wrapper_info_hash,
+                                                base->wrapper_info_hash);
+
+       config->authenticator_info = (fcgid_auth_conf *)
+               merge_dir_config_value((void *) base->authenticator_info,
+                                                          (void *) 
overrides->authenticator_info,
+                                                          
base->authenticator_info_overwrite,
+                                                          
overrides->authenticator_info_overwrite,
+                                                          
&config->authenticator_info_overwrite);
+
+       config->authenticator_authoritative = *((int *)
+               merge_dir_config_value((void *) 
&base->authenticator_authoritative,
+                                                          (void *) 
&overrides->authenticator_authoritative,
+                                                          
base->authenticator_authoritative_overwrite,
+                                                          
overrides->authenticator_authoritative_overwrite,
+                                                          
&config->authenticator_authoritative_overwrite));
+
+       config->authorizer_info = (fcgid_auth_conf *)
+               merge_dir_config_value((void *) base->authorizer_info,
+                                                          (void *) 
overrides->authorizer_info,
+                                                          
base->authorizer_info_overwrite,
+                                                          
overrides->authorizer_info_overwrite,
+                                                          
&config->authorizer_info_overwrite);
+
+       config->authorizer_authoritative = *((int *)
+               merge_dir_config_value((void *) &base->authorizer_authoritative,
+                                                          (void *) 
&overrides->authorizer_authoritative,
+                                                          
base->authorizer_authoritative_overwrite,
+                                                          
overrides->authorizer_authoritative_overwrite,
+                                                          
&config->authorizer_authoritative_overwrite));
+
+       config->access_info = (fcgid_auth_conf *)
+               merge_dir_config_value((void *) base->access_info,
+                                                          (void *) 
overrides->access_info,
+                                                          
base->access_info_overwrite,
+                                                          
overrides->access_info_overwrite,
+                                                          
&config->access_info_overwrite);
+
+       config->access_authoritative = *((int *)
+               merge_dir_config_value((void *) &base->access_authoritative,
+                                                          (void *) 
&overrides->access_authoritative,
+                                                          
base->access_authoritative_overwrite,
+                                                          
overrides->access_authoritative_overwrite,
+                                                          
&config->access_authoritative_overwrite));
+
+       return (void *) config;
+}
+
 const char *set_idle_timeout(cmd_parms * cmd, void *dummy, const char *arg)
 {
        server_rec *s = cmd->server;
@@ -562,6 +630,11 @@
        apr_finfo_t finfo;
        fcgid_dir_conf *dirconfig = (fcgid_dir_conf *) config;
 
+       if(strcasecmp(authenticator, "none") == 0) {
+               dirconfig->authenticator_info_overwrite = 1;
+               return NULL;
+       }
+
        /* Is the wrapper exist? */
        if ((rv = apr_stat(&finfo, authenticator, APR_FINFO_NORM,
                                           cmd->temp_pool)) != APR_SUCCESS) {
@@ -582,6 +655,7 @@
        dirconfig->authenticator_info->inode = finfo.inode;
        dirconfig->authenticator_info->deviceid = finfo.device;
        dirconfig->authenticator_info->share_group_id = (apr_size_t) - 1;
+       dirconfig->authenticator_info_overwrite = 1;
        return NULL;
 }
 
@@ -591,10 +665,11 @@
        fcgid_dir_conf *dirconfig = (fcgid_dir_conf *) config;
 
        dirconfig->authenticator_authoritative = arg;
+       dirconfig->authenticator_authoritative_overwrite = 1;
        return NULL;
 }
 
-auth_conf *get_authenticator_info(request_rec * r, int *authoritative)
+fcgid_auth_conf *get_authenticator_info(request_rec * r, int *authoritative)
 {
        fcgid_dir_conf *config =
                ap_get_module_config(r->per_dir_config, &fcgid_module);
@@ -614,6 +689,11 @@
        apr_finfo_t finfo;
        fcgid_dir_conf *dirconfig = (fcgid_dir_conf *) config;
 
+       if(strcasecmp(authorizer, "none") == 0) {
+               dirconfig->authorizer_info_overwrite = 1;
+               return NULL;
+       }
+
        /* Is the wrapper exist? */
        if ((rv = apr_stat(&finfo, authorizer, APR_FINFO_NORM,
                                           cmd->temp_pool)) != APR_SUCCESS) {
@@ -634,6 +714,7 @@
        dirconfig->authorizer_info->inode = finfo.inode;
        dirconfig->authorizer_info->deviceid = finfo.device;
        dirconfig->authorizer_info->share_group_id = (apr_size_t) - 1;
+       dirconfig->authorizer_info_overwrite = 1;
        return NULL;
 }
 
@@ -643,10 +724,11 @@
        fcgid_dir_conf *dirconfig = (fcgid_dir_conf *) config;
 
        dirconfig->authorizer_authoritative = arg;
+       dirconfig->authorizer_authoritative_overwrite = 1;
        return NULL;
 }
 
-auth_conf *get_authorizer_info(request_rec * r, int *authoritative)
+fcgid_auth_conf *get_authorizer_info(request_rec * r, int *authoritative)
 {
        fcgid_dir_conf *config =
                ap_get_module_config(r->per_dir_config, &fcgid_module);
@@ -666,11 +748,16 @@
        apr_finfo_t finfo;
        fcgid_dir_conf *dirconfig = (fcgid_dir_conf *) config;
 
+       if(strcasecmp(access, "none") == 0) {
+               dirconfig->access_info_overwrite = 1;
+               return NULL;
+       }
+
        /* Is the wrapper exist? */
        if ((rv = apr_stat(&finfo, access, APR_FINFO_NORM,
                                           cmd->temp_pool)) != APR_SUCCESS) {
                return apr_psprintf(cmd->pool,
-                                                       "can't get authorizer 
file info: %s, errno: %d",
+                                                       "can't get access file 
info: %s, errno: %d",
                                                        access, 
apr_get_os_error());
        }
 
@@ -685,6 +772,7 @@
        dirconfig->access_info->inode = finfo.inode;
        dirconfig->access_info->deviceid = finfo.device;
        dirconfig->access_info->share_group_id = (apr_size_t) - 1;
+       dirconfig->access_info_overwrite = 1;
        return NULL;
 }
 
@@ -694,10 +782,11 @@
        fcgid_dir_conf *dirconfig = (fcgid_dir_conf *) config;
 
        dirconfig->access_authoritative = arg;
+       dirconfig->access_authoritative_overwrite = 1;
        return NULL;
 }
 
-auth_conf *get_access_info(request_rec * r, int *authoritative)
+fcgid_auth_conf *get_access_info(request_rec * r, int *authoritative)
 {
        fcgid_dir_conf *config =
                ap_get_module_config(r->per_dir_config, &fcgid_module);
--- fcgid_conf.h.orig   2007-05-09 18:44:17.821884000 -0400
+++ fcgid_conf.h        2007-05-09 18:55:37.805189000 -0400
@@ -8,7 +8,7 @@
        apr_ino_t inode;
        apr_dev_t deviceid;
        apr_size_t share_group_id;
-} auth_conf;
+} fcgid_auth_conf;
 
 typedef struct {
        char args[_POSIX_PATH_MAX];
@@ -48,16 +48,22 @@
        apr_hash_t *wrapper_info_hash;
 
        /* authenticator */
-       auth_conf *authenticator_info;
+       fcgid_auth_conf *authenticator_info;
+       int authenticator_info_overwrite;
        int authenticator_authoritative;
+       int authenticator_authoritative_overwrite;
 
        /* authorizer */
-       auth_conf *authorizer_info;
+       fcgid_auth_conf *authorizer_info;
+       int authorizer_info_overwrite;
        int authorizer_authoritative;
+       int authorizer_authoritative_overwrite;
 
        /* access check */
-       auth_conf *access_info;
+       fcgid_auth_conf *access_info;
+       int access_info_overwrite;
        int access_authoritative;
+       int access_authoritative_overwrite;
 } fcgid_dir_conf;
 
 void *create_fcgid_server_config(apr_pool_t * p, server_rec * s);
@@ -65,6 +71,7 @@
                                                                void 
*overridesv);
 
 void *create_fcgid_dir_config(apr_pool_t * p, char *dummy);
+void *merge_fcgid_dir_config(apr_pool_t * p, void *basev, void *overridesv);
 
 const char *set_idle_timeout(cmd_parms * cmd, void *dummy,
                                                         const char *arg);
@@ -155,19 +162,19 @@
                                                                   const char 
*arg);
 const char *set_authenticator_authoritative(cmd_parms * cmd,
                                                                                
        void *config, int arg);
-auth_conf *get_authenticator_info(request_rec * r, int *authoritative);
+fcgid_auth_conf *get_authenticator_info(request_rec * r, int *authoritative);
 
 const char *set_authorizer_info(cmd_parms * cmd, void *config,
                                                                const char 
*arg);
 const char *set_authorizer_authoritative(cmd_parms * cmd,
                                                                                
 void *config, int arg);
-auth_conf *get_authorizer_info(request_rec * r, int *authoritative);
+fcgid_auth_conf *get_authorizer_info(request_rec * r, int *authoritative);
 
 const char *set_access_info(cmd_parms * cmd, void *config,
                                                        const char *arg);
 const char *set_access_authoritative(cmd_parms * cmd,
                                                                         void 
*config, int arg);
-auth_conf *get_access_info(request_rec * r, int *authoritative);
+fcgid_auth_conf *get_access_info(request_rec * r, int *authoritative);
 
 const char *set_php_fix_pathinfo_enable(cmd_parms * cmd, void *dummy,
                                                                                
const char *arg);
--- mod_fcgid.c.orig    2007-03-07 20:13:27.000000000 -0500
+++ mod_fcgid.c 2007-05-09 18:54:10.714185000 -0400
@@ -154,12 +154,11 @@
        e_info.bb = NULL;
        e_info.ctx = NULL;
        e_info.next = NULL;
-       p = r->main ? r->main->pool : r->pool;
 
        /* Build the command line */
        if ((wrapper_conf = get_wrapper_info(r->filename, r))) {
                if ((rv =
-                        default_build_command(&command, &argv, r, p,
+                        default_build_command(&command, &argv, r, r->pool,
                                                                   &e_info)) != 
APR_SUCCESS) {
                        ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r,
                                                  "mod_fcgid: don't know how to 
spawn wrapper child process: %s",
@@ -167,7 +166,7 @@
                        return HTTP_INTERNAL_SERVER_ERROR;
                }
        } else if ((rv =
-                               cgi_build_command(&command, &argv, r, p,
+                               cgi_build_command(&command, &argv, r, r->pool,
                                                                  &e_info)) != 
APR_SUCCESS) {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r,
                                          "mod_fcgid: don't know how to spawn 
child process: %s",
@@ -195,7 +194,7 @@
                                                                r->connection);
 
        http_retcode =
-               bridge_request(r, FCGI_RESPONDER, command, wrapper_conf);
+               bridge_request(r, FCGI_RESPONDER, command, NULL, wrapper_conf);
        return (http_retcode == HTTP_OK ? OK : http_retcode);
 }
 
@@ -217,7 +216,7 @@
        const char *location = NULL;
        apr_table_t *saved_subprocess_env = NULL;
        fcgid_wrapper_conf *wrapper_conf;
-       auth_conf *authenticator_info;
+       fcgid_auth_conf *authenticator_info;
        int authoritative;
 
        authenticator_info = get_authenticator_info(r, &authoritative);
@@ -252,7 +251,7 @@
 
        /* Handle the request */
        res =
-               bridge_request(r, FCGI_AUTHORIZER, authenticator_info->path,
+               bridge_request(r, FCGI_AUTHORIZER, NULL, authenticator_info,
                                           wrapper_conf);
 
        /* Restore r->subprocess_env */
@@ -302,7 +301,7 @@
        const char *location = NULL;
        apr_table_t *saved_subprocess_env = NULL;
        fcgid_wrapper_conf *wrapper_conf;
-       auth_conf *authorizer_info;
+       fcgid_auth_conf *authorizer_info;
        int authoritative;
 
        authorizer_info = get_authorizer_info(r, &authoritative);
@@ -332,7 +331,7 @@
 
        /* Handle the request */
        res =
-               bridge_request(r, FCGI_AUTHORIZER, authorizer_info->path,
+               bridge_request(r, FCGI_AUTHORIZER, NULL, authorizer_info,
                                           wrapper_conf);
 
        /* Restore r->subprocess_env */
@@ -382,7 +381,7 @@
        const char *location = NULL;
        apr_table_t *saved_subprocess_env = NULL;
        fcgid_wrapper_conf *wrapper_conf;
-       auth_conf *access_info;
+       fcgid_auth_conf *access_info;
        int authoritative;
 
        access_info = get_access_info(r, &authoritative);
@@ -413,7 +412,7 @@
 
        /* Handle the request */
        res =
-               bridge_request(r, FCGI_AUTHORIZER, access_info->path,
+               bridge_request(r, FCGI_AUTHORIZER, NULL, access_info,
                                           wrapper_conf);
 
        /* Restore r->subprocess_env */
@@ -603,10 +602,10 @@
                                 set_authenticator_authoritative, NULL,
                                 ACCESS_CONF | OR_FILEINFO,
                                 "Set to 'off' to allow authentication to be 
passed along to lower modules upon failure"),
-       AP_INIT_TAKE1("FastCgiAuthenticator", set_authorizer_info, NULL,
+       AP_INIT_TAKE1("FastCgiAuthorizer", set_authorizer_info, NULL,
                                  ACCESS_CONF | OR_FILEINFO,
                                  "a absolute authorizer file path"),
-       AP_INIT_FLAG("FastCgiAuthenticatorAuthoritative",
+       AP_INIT_FLAG("FastCgiAuthorizerAuthoritative",
                                 set_authorizer_authoritative, NULL,
                                 ACCESS_CONF | OR_FILEINFO,
                                 "Set to 'off' to allow authorization to be 
passed along to lower modules upon failure"),
@@ -641,7 +640,7 @@
 module AP_MODULE_DECLARE_DATA fcgid_module = {
        STANDARD20_MODULE_STUFF,
        create_fcgid_dir_config,        /* create per-directory config 
structure */
-       NULL,                                           /* merge per-directory 
config structures */
+       merge_fcgid_dir_config,         /* merge per-directory config 
structures */
        create_fcgid_server_config,     /* create per-server config structure */
        merge_fcgid_server_config,      /* merge per-server config structures */
        fcgid_cmds,                                     /* command apr_table_t 
*/

-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
_______________________________________________
Mod-fcgid-users mailing list
Mod-fcgid-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/mod-fcgid-users

Reply via email to