diff options
author | Colm MacCarthaigh <colm@apache.org> | 2005-08-30 11:26:45 +0000 |
---|---|---|
committer | Colm MacCarthaigh <colm@apache.org> | 2005-08-30 11:26:45 +0000 |
commit | c8e6fa78af6dc3dcf342d2079740d82e95d77bd5 (patch) | |
tree | d5e44f42172ce36e381d7efb8b82f195c8477062 | |
parent | 4f1d428f25187001e75a12647b3cc940b934f47e (diff) | |
download | httpd-c8e6fa78af6dc3dcf342d2079740d82e95d77bd5.tar.gz |
Fix PR36410; Change how the get_suexec_identity hook is handled by CGID.
Instead of using mod_userdir and mod_suexec specific hacks, we now run the hook
on the httpd side of the handler.
If this is NULL, we pass on a magic empty_ugid constant, otherwise pass on the
real ugid.
On the cgid side of the equation, we add our own hook, with REALLY_FIRST, and
then order the hooks. This ensures that cgid's doer runs before any other
registered get_suexec_identity doers.
We use cgid's request config to store the ugid. If ugid == empty_ugid, we DON'T
call ap_os_create_privileged_process, because our doer would return the magic
empty_ugid constant. Having the doer return NULL is no good, because then
userdir and mod_suexec's doers would be called. Instead, we call plain old
apr_proc_create().
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@264759 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r-- | CHANGES | 3 | ||||
-rw-r--r-- | modules/generators/mod_cgid.c | 99 |
2 files changed, 47 insertions, 55 deletions
@@ -2,6 +2,9 @@ Changes with Apache 2.3.0 [Remove entries to the current 2.0 and 2.2 section below, when backported] + *) mod_cgid: run the get_suexec_identity hook within the request-handler + instead of within cgid. PR36410. [Colm MacCarthaigh] + *) Correct mod_cgid's argv[0] so that the full path can be delved by the invoked cgi application, to conform to the behavior of mod_cgi. [Pradeep Kumar S <pradeep.smani gmail.com>] diff --git a/modules/generators/mod_cgid.c b/modules/generators/mod_cgid.c index 7daad06685..e3dd4caa81 100644 --- a/modules/generators/mod_cgid.c +++ b/modules/generators/mod_cgid.c @@ -91,10 +91,20 @@ static server_rec *root_server = NULL; static apr_pool_t *root_pool = NULL; static const char *sockname; static pid_t parent_pid; +static ap_unix_identity_t empty_ugid = { -1, -1, -1 }; /* Read and discard the data in the brigade produced by a CGI script */ static void discard_script_output(apr_bucket_brigade *bb); +/* This doer will only ever be called when we are sure that we have + * a valid ugid. + */ +static ap_unix_identity_t *cgid_suexec_id_doer(const request_rec *r) +{ + return (ap_unix_identity_t *) + ap_get_module_config(r->request_config, &cgid_module); +} + /* KLUDGE --- for back-combatibility, we don't have to check ExecCGI * in ScriptAliased directories, which means we need to know if this * request came through ScriptAlias or not... so the Alias module @@ -159,15 +169,12 @@ typedef struct { * wrong cgid socket use */ int core_module_index; - int have_suexec; - int suexec_module_index; - suexec_config_t suexec_cfg; int env_count; + ap_unix_identity_t ugid; apr_size_t filename_len; apr_size_t argv0_len; apr_size_t uri_len; apr_size_t args_len; - apr_size_t mod_userdir_user_len; int loglevel; /* to stuff in server_rec */ } cgid_req_t; @@ -328,10 +335,9 @@ static apr_status_t get_req(int fd, request_rec *r, char **argv0, char ***env, cgid_req_t *req) { int i; - char *user; char **environ; - core_dir_config *temp_core; - void **dconf; + core_request_config *temp_core; + void **rconf; apr_status_t stat; r->server = apr_pcalloc(r->pool, sizeof(server_rec)); @@ -348,17 +354,13 @@ static apr_status_t get_req(int fd, request_rec *r, char **argv0, char ***env, } /* handle module indexes and such */ - dconf = (void **) apr_pcalloc(r->pool, sizeof(void *) * (total_modules + DYNAMIC_MODULE_LIMIT)); - - temp_core = (core_dir_config *)apr_palloc(r->pool, sizeof(core_module)); - dconf[req->core_module_index] = (void *)temp_core; - - if (req->have_suexec) { - dconf[req->suexec_module_index] = &req->suexec_cfg; - } - - r->per_dir_config = (ap_conf_vector_t *)dconf; + rconf = (void **) apr_pcalloc(r->pool, sizeof(void *) * (total_modules + DYNAMIC_MODULE_LIMIT)); + temp_core = (core_request_config *)apr_palloc(r->pool, sizeof(core_module)); + rconf[req->core_module_index] = (void *)temp_core; + r->request_config = (ap_conf_vector_t *)rconf; + ap_set_module_config(r->request_config, &cgid_module, (void *)&req->ugid); + /* Read the filename, argv0, uri, and args */ r->filename = apr_pcalloc(r->pool, req->filename_len + 1); *argv0 = apr_pcalloc(r->pool, req->argv0_len + 1); @@ -391,19 +393,6 @@ static apr_status_t get_req(int fd, request_rec *r, char **argv0, char ***env, } *env = environ; - /* basic notes table to avoid segfaults */ - r->notes = apr_table_make(r->pool, 1); - - /* mod_userdir requires the mod_userdir_user note */ - if (req->mod_userdir_user_len) { - user = apr_pcalloc(r->pool, req->mod_userdir_user_len + 1); /* last byte is '\0' */ - stat = sock_read(fd, user, req->mod_userdir_user_len); - if (stat != APR_SUCCESS) { - return stat; - } - apr_table_set(r->notes, "mod_userdir_user", (const char *)user); - } - #if 0 #ifdef RLIMIT_CPU sock_read(fd, &j, sizeof(int)); @@ -446,23 +435,20 @@ static apr_status_t send_req(int fd, request_rec *r, char *argv0, char **env, int req_type) { int i; - const char *user; - module *suexec_mod = ap_find_linked_module("mod_suexec.c"); cgid_req_t req = {0}; - suexec_config_t *suexec_cfg; apr_status_t stat; + ap_unix_identity_t * ugid = ap_run_get_suexec_identity(r); + if (ugid == NULL) { + req.ugid = empty_ugid; + } else { + memcpy(&req.ugid, ugid, sizeof(ap_unix_identity_t)); + } + req.req_type = req_type; req.ppid = parent_pid; req.conn_id = r->connection->id; req.core_module_index = core_module.module_index; - if (suexec_mod) { - req.have_suexec = 1; - req.suexec_module_index = suexec_mod->module_index; - suexec_cfg = ap_get_module_config(r->per_dir_config, - suexec_mod); - req.suexec_cfg = *suexec_cfg; - } for (req.env_count = 0; env[req.env_count]; req.env_count++) { continue; } @@ -470,10 +456,6 @@ static apr_status_t send_req(int fd, request_rec *r, char *argv0, char **env, req.argv0_len = strlen(argv0); req.uri_len = strlen(r->uri); req.args_len = r->args ? strlen(r->args) : 0; - user = (const char *)apr_table_get(r->notes, "mod_userdir_user"); - if (user != NULL) { - req.mod_userdir_user_len = strlen(user); - } req.loglevel = r->server->loglevel; /* Write the request header */ @@ -506,13 +488,6 @@ static apr_status_t send_req(int fd, request_rec *r, char *argv0, char **env, } } - /* send a minimal notes table */ - if (user) { - if ((stat = sock_write(fd, user, req.mod_userdir_user_len)) != APR_SUCCESS) { - return stat; - } - } - #if 0 #ifdef RLIMIT_CPU if (conf->limit_cpu) { @@ -593,6 +568,11 @@ static int cgid_server(void *data) /* Close our copy of the listening sockets */ ap_close_listeners(); + + /* cgid should use its own suexec doer */ + ap_hook_get_suexec_identity(cgid_suexec_id_doer, NULL, NULL, + APR_HOOK_REALLY_FIRST); + apr_hook_sort_all(); if ((sd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) { ap_log_error(APLOG_MARK, APLOG_ERR, errno, main_server, @@ -753,10 +733,19 @@ static int cgid_server(void *data) */ close(sd2); - rc = ap_os_create_privileged_process(r, procnew, argv0, argv, - (const char * const *)env, - procattr, ptrans); - + if (memcmp(&empty_ugid, &cgid_req.ugid, sizeof(empty_ugid))) { + /* We have a valid identity, and can be sure that + * cgid_suexec_id_doer will return a valid ugid + */ + rc = ap_os_create_privileged_process(r, procnew, argv0, argv, + (const char * const *)env, + procattr, ptrans); + } else { + rc = apr_proc_create(procnew, argv0, argv, + (const char * const *)env, + procattr, ptrans); + } + if (rc != APR_SUCCESS) { /* Bad things happened. Everyone should have cleaned up. * ap_log_rerror() won't work because the header table used by |